Example #1
0
        public void vesselRecoverEvent(ProtoVessel v, bool unknownAsOfNow)
        {
            KCTDebug.Log("VesselRecoverEvent");
            if (!KCT_PresetManager.Instance.ActivePreset.generalSettings.Enabled)
            {
                return;
            }
            if (!v.vesselRef.isEVA)
            {
                // if (KCT_GameStates.settings.Debug && HighLogic.LoadedScene != GameScenes.TRACKSTATION && (v.wasControllable || v.protoPartSnapshots.Find(p => p.modules.Find(m => m.moduleName.ToLower() == "modulecommand") != null) != null))
                if (KCT_GameStates.recoveredVessel != null && v.vesselName == KCT_GameStates.recoveredVessel.shipName)
                {
                    //KCT_GameStates.recoveredVessel = new KCT_BuildListVessel(v);
                    //rebuy the ship if ScrapYard isn't overriding funds
                    if (!ScrapYardWrapper.OverrideFunds)
                    {
                        KCT_Utilities.SpendFunds(KCT_GameStates.recoveredVessel.cost, TransactionReasons.VesselRollout); //pay for the ship again
                    }

                    //pull all of the parts out of the inventory
                    //This is a bit funky since we grab the part id from our part, grab the inventory part out, then try to reapply that ontop of our part
                    if (ScrapYardWrapper.Available)
                    {
                        foreach (ConfigNode partNode in KCT_GameStates.recoveredVessel.ExtractedPartNodes)
                        {
                            string     id = ScrapYardWrapper.GetPartID(partNode);
                            ConfigNode inventoryVersion = ScrapYardWrapper.FindInventoryPart(id);
                            if (inventoryVersion != null)
                            {
                                //apply it to our copy of the part
                                ConfigNode ourTracker = partNode.GetNodes("MODULE").FirstOrDefault(n => string.Equals(n.GetValue("name"), "ModuleSYPartTracker", StringComparison.Ordinal));
                                if (ourTracker != null)
                                {
                                    ourTracker.SetValue("TimesRecovered", inventoryVersion.GetValue("_timesRecovered"));
                                    ourTracker.SetValue("Inventoried", inventoryVersion.GetValue("_inventoried"));
                                }
                            }
                        }


                        //process the vessel in ScrapYard
                        ScrapYardWrapper.ProcessVessel(KCT_GameStates.recoveredVessel.ExtractedPartNodes);

                        //reset the BP
                        KCT_GameStates.recoveredVessel.buildPoints = KCT_Utilities.GetBuildTime(KCT_GameStates.recoveredVessel.ExtractedPartNodes);
                    }
                    if (KCT_GameStates.recoveredVessel.type == KCT_BuildListVessel.ListType.VAB)
                    {
                        KCT_GameStates.ActiveKSC.VABWarehouse.Add(KCT_GameStates.recoveredVessel);
                    }
                    else
                    {
                        KCT_GameStates.ActiveKSC.SPHWarehouse.Add(KCT_GameStates.recoveredVessel);
                    }

                    KCT_GameStates.ActiveKSC.Recon_Rollout.Add(new KCT_Recon_Rollout(KCT_GameStates.recoveredVessel, KCT_Recon_Rollout.RolloutReconType.Recovery, KCT_GameStates.recoveredVessel.id.ToString()));
                    KCT_GameStates.recoveredVessel = null;
                }
            }
        }
Example #2
0
        public BuildListVessel CreateCopy(bool RecalcTime)
        {
            BuildListVessel ret = new BuildListVessel(ShipName, LaunchSite, EffectiveCost, BuildPoints, IntegrationPoints, Flag, Cost, IntegrationCost, (int)GetEditorFacility())
            {
                ShipNode = ShipNode.CreateCopy()
            };

            //refresh all inventory parts to new
            foreach (var p in ret.ExtractedPartNodes)
            {
                ScrapYardWrapper.RefreshPart(p);
            }

            ret.Id = Guid.NewGuid();
            ret.KCTPersistentID = Guid.NewGuid().ToString();
            ret.TotalMass       = TotalMass;
            ret.EmptyMass       = EmptyMass;
            ret.Cost            = Cost;
            ret.IntegrationCost = IntegrationCost;
            ret.EmptyCost       = EmptyCost;
            ret.NumStageParts   = NumStageParts;
            ret.NumStages       = NumStages;
            ret.StagePartCost   = StagePartCost;
            ret.ShipSize        = ShipSize;

            if (RecalcTime)
            {
                ret.EffectiveCost     = Utilities.GetEffectiveCost(ret.ExtractedPartNodes);
                ret.BuildPoints       = Utilities.GetBuildTime(ret.EffectiveCost);
                ret.IntegrationPoints = MathParser.ParseIntegrationTimeFormula(ret);
                ret.IntegrationCost   = (float)MathParser.ParseIntegrationCostFormula(ret);
            }

            return(ret);
        }
Example #3
0
        public KCT_BuildListVessel NewCopy(bool RecalcTime)
        {
            KCT_BuildListVessel ret = new KCT_BuildListVessel(this.shipName, this.launchSite, this.buildPoints, this.flag, this.cost, (int)GetEditorFacility());

            ret.shipNode = this.shipNode.CreateCopy();

            //refresh all inventory parts to new
            for (int i = ret.ExtractedPartNodes.Count - 1; i >= 0; i--)
            {
                ConfigNode part = ret.ExtractedPartNodes[i];

                //foreach (ConfigNode part in ret.ExtractedPartNodes)
                //{
                ScrapYardWrapper.RefreshPart(part);
            }

            ret.id = Guid.NewGuid();
            if (RecalcTime)
            {
                ret.buildPoints = KCT_Utilities.GetBuildTime(ret.ExtractedPartNodes);
            }
            ret.TotalMass     = this.TotalMass;
            ret.emptyMass     = this.emptyMass;
            ret.cost          = this.cost;
            ret.emptyCost     = this.emptyCost;
            ret.numStageParts = this.numStageParts;
            ret.numStages     = this.numStages;
            ret.stagePartCost = this.stagePartCost;
            return(ret);
        }
Example #4
0
        public void VesselRecoverEvent(ProtoVessel v, bool unknownAsOfNow)
        {
            KCTDebug.Log("VesselRecoverEvent");
            if (!PresetManager.Instance.ActivePreset.GeneralSettings.Enabled)
            {
                return;
            }
            if (!KCTGameStates.IsSimulatedFlight && !v.vesselRef.isEVA)
            {
                if (KCTGameStates.RecoveredVessel != null && v.vesselName == KCTGameStates.RecoveredVessel.ShipName)
                {
                    //rebuy the ship if ScrapYard isn't overriding funds
                    if (!ScrapYardWrapper.OverrideFunds)
                    {
                        Utilities.SpendFunds(KCTGameStates.RecoveredVessel.Cost, TransactionReasons.VesselRollout);    //pay for the ship again
                    }

                    //pull all of the parts out of the inventory
                    //This is a bit funky since we grab the part id from our part, grab the inventory part out, then try to reapply that ontop of our part
                    if (ScrapYardWrapper.Available)
                    {
                        foreach (ConfigNode partNode in KCTGameStates.RecoveredVessel.ExtractedPartNodes)
                        {
                            string     id = ScrapYardWrapper.GetPartID(partNode);
                            ConfigNode inventoryVersion = ScrapYardWrapper.FindInventoryPart(id);
                            if (inventoryVersion != null)
                            {
                                //apply it to our copy of the part
                                ConfigNode ourTracker = partNode.GetNodes("MODULE").FirstOrDefault(n => string.Equals(n.GetValue("name"), "ModuleSYPartTracker", StringComparison.Ordinal));
                                if (ourTracker != null)
                                {
                                    ourTracker.SetValue("TimesRecovered", inventoryVersion.GetValue("_timesRecovered"));
                                    ourTracker.SetValue("Inventoried", inventoryVersion.GetValue("_inventoried"));
                                }
                            }
                        }

                        //process the vessel in ScrapYard
                        ScrapYardWrapper.ProcessVessel(KCTGameStates.RecoveredVessel.ExtractedPartNodes);

                        //reset the BP
                        KCTGameStates.RecoveredVessel.BuildPoints       = Utilities.GetBuildTime(KCTGameStates.RecoveredVessel.ExtractedPartNodes);
                        KCTGameStates.RecoveredVessel.IntegrationPoints = MathParser.ParseIntegrationTimeFormula(KCTGameStates.RecoveredVessel);
                    }

                    if (KCTGameStates.RecoveredVessel.Type == BuildListVessel.ListType.VAB)
                    {
                        KCTGameStates.ActiveKSC.VABWarehouse.Add(KCTGameStates.RecoveredVessel);
                    }
                    else
                    {
                        KCTGameStates.ActiveKSC.SPHWarehouse.Add(KCTGameStates.RecoveredVessel);
                    }

                    KCTGameStates.ActiveKSC.Recon_Rollout.Add(new ReconRollout(KCTGameStates.RecoveredVessel, ReconRollout.RolloutReconType.Recovery, KCTGameStates.RecoveredVessel.Id.ToString()));
                    KCTGameStates.RecoveredVessel = null;
                }
            }
        }
Example #5
0
        public static BuildListVessel AddVesselToPlansList(BuildListVessel blv)
        {
            ScreenMessage message;

            if (Utilities.CurrentGameIsCareer())
            {
                //Check upgrades
                //First, mass limit
                List <string> facilityChecks = blv.MeetsFacilityRequirements(true);
                if (facilityChecks.Count != 0)
                {
                    PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "editorChecksFailedPopup", "Failed editor checks!",
                                                 "Warning! This vessel did not pass the editor checks! It will still be added to the plans, but you will not be able to launch it without upgrading. Listed below are the failed checks:\n"
                                                 + string.Join("\n", facilityChecks.ToArray()), "Acknowledged", false, HighLogic.UISkin);
                }
            }
            string type = "";

            if (blv.Type == BuildListVessel.ListType.VAB)
            {
                if (KCTGameStates.ActiveKSC.VABPlans.ContainsKey(blv.ShipName))
                {
                    KCTGameStates.ActiveKSC.VABPlans.Remove(blv.ShipName);
                    message = new ScreenMessage($"[KCT] Replacing previous plan for {blv.ShipName} in the VAB Building Plans list.", 4f, ScreenMessageStyle.UPPER_CENTER);
                    ScreenMessages.PostScreenMessage(message);
                }
                KCTGameStates.ActiveKSC.VABPlans.Add(blv.ShipName, blv);
                type = "VAB";
            }
            else if (blv.Type == BuildListVessel.ListType.SPH)
            {
                if (KCTGameStates.ActiveKSC.SPHPlans.ContainsKey(blv.ShipName))
                {
                    KCTGameStates.ActiveKSC.SPHPlans.Remove(blv.ShipName);
                    message = new ScreenMessage($"[KCT] Replacing previous plan for {blv.ShipName} in the SPH Building Plans list.", 4f, ScreenMessageStyle.UPPER_CENTER);
                    ScreenMessages.PostScreenMessage(message);
                }
                KCTGameStates.ActiveKSC.SPHPlans.Add(blv.ShipName, blv);
                type = "SPH";
            }

            ScrapYardWrapper.ProcessVessel(blv.ExtractedPartNodes);

            KCTDebug.Log($"Added {blv.ShipName} to {type} build list at KSC {KCTGameStates.ActiveKSC.KSCName}. Cost: {blv.Cost}");
            KCTDebug.Log($"Launch site is {blv.LaunchSite}");
            bool   isCommonLine = PresetManager.Instance?.ActivePreset?.GeneralSettings.CommonBuildLine ?? false;
            string text         = isCommonLine ? $"Added {blv.ShipName} to build list." : $"Added {blv.ShipName} to {type} build list.";

            message = new ScreenMessage(text, 4f, ScreenMessageStyle.UPPER_CENTER);
            ScreenMessages.PostScreenMessage(message);
            return(blv);
        }
Example #6
0
        public static KCT_BuildListVessel AddVesselToPlansList(KCT_BuildListVessel blv)
        {
            ScreenMessage message;

            if (KCT_Utilities.CurrentGameIsCareer())
            {
                //Check upgrades
                //First, mass limit
                List <string> facilityChecks = blv.MeetsFacilityRequirements(true);
                if (facilityChecks.Count != 0)
                {
                    PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "editorChecksFailedPopup", "Failed editor checks!",
                                                 "Warning! This vessel did not pass the editor checks! It will still be added to the plans, but you will not be able to launch it without upgrading. Listed below are the failed checks:\n"
                                                 + string.Join("\n", facilityChecks.ToArray()), "Acknowledged", false, HighLogic.UISkin);
                }
            }
            string type = "";

            if (blv.type == KCT_BuildListVessel.ListType.VAB)
            {
                if (KCT_GameStates.ActiveKSC.VABPlans.ContainsKey(blv.shipName))
                {
                    KCT_GameStates.ActiveKSC.VABPlans.Remove(blv.shipName);
                    message = new ScreenMessage("[KCT] Replacing previous plan for " + blv.shipName + " in the VAB Building Plans list.", 4.0f, ScreenMessageStyle.UPPER_CENTER);
                    ScreenMessages.PostScreenMessage(message);
                }
                KCT_GameStates.ActiveKSC.VABPlans.Add(blv.shipName, blv);
                type = "VAB";
            }
            else if (blv.type == KCT_BuildListVessel.ListType.SPH)
            {
                if (KCT_GameStates.ActiveKSC.SPHPlans.ContainsKey(blv.shipName))
                {
                    KCT_GameStates.ActiveKSC.SPHPlans.Remove(blv.shipName);
                    message = new ScreenMessage("[KCT] Replacing previous plan for " + blv.shipName + " in the SPH Building Plans list.", 4.0f, ScreenMessageStyle.UPPER_CENTER);
                    ScreenMessages.PostScreenMessage(message);
                }
                KCT_GameStates.ActiveKSC.SPHPlans.Add(blv.shipName, blv);
                type = "SPH";
            }

            ScrapYardWrapper.ProcessVessel(blv.ExtractedPartNodes);

            KCTDebug.Log("Added " + blv.shipName + " to " + type + " build list at KSC " + KCT_GameStates.ActiveKSC.KSCName + ". Cost: " + blv.cost);
            KCTDebug.Log("Launch site is " + blv.launchSite);
            //KCTDebug.Log("Cost Breakdown (total, parts, fuel): " + blv.totalCost + ", " + blv.dryCost + ", " + blv.fuelCost);
            message = new ScreenMessage("[KCT] Added " + blv.shipName + " to " + type + " build list.", 4.0f, ScreenMessageStyle.UPPER_CENTER);
            ScreenMessages.PostScreenMessage(message);
            return(blv);
        }
Example #7
0
        private void SYReady()
        {
            if (HighLogic.LoadedSceneIsEditor && KCTGameStates.EditorShipEditingMode && KCTGameStates.EditedVessel != null)
            {
                KCTDebug.Log("Removing SY tracking of this vessel.");
                string id = ScrapYardWrapper.GetPartID(KCTGameStates.EditedVessel.ExtractedPartNodes[0]);
                ScrapYardWrapper.SetProcessedStatus(id, false);

                KCTDebug.Log("Adding parts back to inventory for editing...");
                foreach (ConfigNode partNode in KCTGameStates.EditedVessel.ExtractedPartNodes)
                {
                    if (ScrapYardWrapper.PartIsFromInventory(partNode))
                    {
                        ScrapYardWrapper.AddPartToInventory(partNode, false);
                    }
                }
            }
        }
Example #8
0
        private void SYReady()
        {
            const string logBlockName = nameof(KCTEvents) + "." + nameof(SYReady);

            using (EntryExitLogger.EntryExitLog(logBlockName, EntryExitLoggerOptions.All))
            {
                if (HighLogic.LoadedSceneIsEditor && GameStates.EditorShipEditingMode && GameStates.editedVessel != null)
                {
                    Log.Info("Removing SY tracking of this vessel.");
                    string id = ScrapYardWrapper.GetPartID(GameStates.editedVessel.ExtractedPartNodes[0]);
                    ScrapYardWrapper.SetProcessedStatus(id, false);

                    Log.Info("Adding parts back to inventory for editing...");
                    foreach (ConfigNode partNode in GameStates.editedVessel.ExtractedPartNodes)
                    {
                        if (ScrapYardWrapper.PartIsFromInventory(partNode))
                        {
                            ScrapYardWrapper.AddPartToInventory(partNode, false);
                        }
                    }
                }
            }
        }
Example #9
0
        private static void RenderEditMode()
        {
            BuildListVessel ship = KCTGameStates.EditedVessel;

            if (_finishedShipBP < 0 && ship.IsFinished)
            {
                // If ship is finished, then both build and integration times can be refreshed with newly calculated values
                _finishedShipBP        = Utilities.GetBuildTime(ship.ExtractedPartNodes);
                ship.BuildPoints       = _finishedShipBP;
                ship.IntegrationPoints = MathParser.ParseIntegrationTimeFormula(ship);
            }

            Utilities.GetShipEditProgress(ship, out double newProgressBP, out double originalCompletionPercent, out double newCompletionPercent);
            GUILayout.Label($"Original: {Math.Max(0, Math.Round(100 * originalCompletionPercent, 2))}%");
            GUILayout.Label($"Edited: {Math.Round(100 * newCompletionPercent, 2)}%");

            BuildListVessel.ListType type = EditorLogic.fetch.launchSiteName == "LaunchPad" ? BuildListVessel.ListType.VAB : BuildListVessel.ListType.SPH;
            GUILayout.BeginHorizontal();
            GUILayout.Label("Build Time at ");
            if (BuildRateForDisplay == null)
            {
                BuildRateForDisplay = Utilities.GetBuildRate(0, type, null).ToString();
            }
            BuildRateForDisplay = GUILayout.TextField(BuildRateForDisplay, GUILayout.Width(75));
            GUILayout.Label(" BP/s:");
            List <double> rates = new List <double>();

            if (ship.Type == BuildListVessel.ListType.VAB)
            {
                rates = Utilities.GetVABBuildRates(null);
            }
            else
            {
                rates = Utilities.GetSPHBuildRates(null);
            }
            if (double.TryParse(BuildRateForDisplay, out double bR))
            {
                if (GUILayout.Button(new GUIContent("*", "Switch build line that is used for build time calculations"), GUILayout.ExpandWidth(false)))
                {
                    _rateIndexHolder = (_rateIndexHolder + 1) % rates.Count;
                    bR = rates[_rateIndexHolder];
                    BuildRateForDisplay = bR.ToString();
                }
                GUILayout.EndHorizontal();
                GUILayout.Label(MagiCore.Utilities.GetFormattedTime(Math.Abs(KCTGameStates.EditorBuildTime + KCTGameStates.EditorIntegrationTime - newProgressBP) / bR));
            }
            else
            {
                GUILayout.EndHorizontal();
                GUILayout.Label("Invalid Build Rate");
            }

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Save Edits"))
            {
                _finishedShipBP = -1;
                Utilities.SaveShipEdits(ship);
            }
            if (GUILayout.Button("Cancel Edits"))
            {
                KCTDebug.Log("Edits cancelled.");
                _finishedShipBP = -1;
                ScrapYardWrapper.ProcessVessel(KCTGameStates.EditedVessel.ExtractedPartNodes);
                KCTGameStates.ClearVesselEditMode();

                HighLogic.LoadScene(GameScenes.SPACECENTER);
            }
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Simulate"))
            {
                _finishedShipBP = -1;
                _simulationConfigPosition.height = 1;
                EditorLogic.fetch.Lock(true, true, true, "KCTGUILock");
                GUIStates.ShowSimConfig = true;

                double effCost = Utilities.GetEffectiveCost(EditorLogic.fetch.ship.Parts);
                double bp      = Utilities.GetBuildTime(effCost);
                KCTGameStates.LaunchedVessel = new BuildListVessel(EditorLogic.fetch.ship, EditorLogic.fetch.launchSiteName, effCost, bp, EditorLogic.FlagURL);
            }
            GUILayout.EndHorizontal();

            if (KCTGameStates.LaunchedVessel != null && !KCTGameStates.LaunchedVessel.AreTanksFull() &&
                GUILayout.Button("Fill Tanks"))
            {
                foreach (Part p in EditorLogic.fetch.ship.parts)
                {
                    //fill as part prefab would be filled?
                    if (Utilities.PartIsProcedural(p))
                    {
                        foreach (PartResource rsc in p.Resources)
                        {
                            if (GuiDataAndWhitelistItemsDatabase.ValidFuelRes.Contains(rsc.resourceName) && rsc.flowState)
                            {
                                rsc.amount = rsc.maxAmount;
                            }
                        }
                    }
                    else
                    {
                        foreach (PartResource rsc in p.Resources)
                        {
                            if (GuiDataAndWhitelistItemsDatabase.ValidFuelRes.Contains(rsc.resourceName) && rsc.flowState)
                            {
                                PartResource templateRsc = p.partInfo.partPrefab.Resources.FirstOrDefault(r => r.resourceName == rsc.resourceName);
                                if (templateRsc != null)
                                {
                                    rsc.amount = templateRsc.amount;
                                }
                            }
                        }
                    }
                }
            }

            RenderMergeSection(ship);
        }
Example #10
0
        private static void RenderEditMode()
        {
            BuildListVessel ship = KCTGameStates.EditedVessel;

            if (_finishedShipBP < 0 && ship.IsFinished)
            {
                // If ship is finished, then both build and integration times can be refreshed with newly calculated values
                _finishedShipBP        = Utilities.GetBuildTime(ship.ExtractedPartNodes);
                ship.BuildPoints       = _finishedShipBP;
                ship.IntegrationPoints = MathParser.ParseIntegrationTimeFormula(ship);
            }

            double origBP = ship.IsFinished ? _finishedShipBP : ship.BuildPoints;

            origBP += ship.IntegrationPoints;
            double buildTime  = KCTGameStates.EditorBuildTime + KCTGameStates.EditorIntegrationTime;
            double difference = Math.Abs(buildTime - origBP);
            double progress;

            if (ship.IsFinished)
            {
                progress = origBP;
            }
            else
            {
                progress = ship.Progress;
            }
            double newProgress = Math.Max(0, progress - (1.1 * difference));

            GUILayout.Label($"Original: {Math.Max(0, Math.Round(100 * (progress / origBP), 2))}%");
            GUILayout.Label($"Edited: {Math.Round(100 * newProgress / buildTime, 2)}%");

            BuildListVessel.ListType type = EditorLogic.fetch.launchSiteName == "LaunchPad" ? BuildListVessel.ListType.VAB : BuildListVessel.ListType.SPH;
            GUILayout.BeginHorizontal();
            GUILayout.Label("Build Time at ");
            if (BuildRateForDisplay == null)
            {
                BuildRateForDisplay = Utilities.GetBuildRate(0, type, null).ToString();
            }
            BuildRateForDisplay = GUILayout.TextField(BuildRateForDisplay, GUILayout.Width(75));
            GUILayout.Label(" BP/s:");
            List <double> rates = new List <double>();

            if (ship.Type == BuildListVessel.ListType.VAB)
            {
                rates = Utilities.GetVABBuildRates(null);
            }
            else
            {
                rates = Utilities.GetSPHBuildRates(null);
            }
            if (double.TryParse(BuildRateForDisplay, out double bR))
            {
                if (GUILayout.Button("*", GUILayout.ExpandWidth(false)))
                {
                    _rateIndexHolder = (_rateIndexHolder + 1) % rates.Count;
                    bR = rates[_rateIndexHolder];
                    BuildRateForDisplay = bR.ToString();
                }
                GUILayout.EndHorizontal();
                GUILayout.Label(MagiCore.Utilities.GetFormattedTime(Math.Abs(buildTime - newProgress) / bR));
            }
            else
            {
                GUILayout.EndHorizontal();
                GUILayout.Label("Invalid Build Rate");
            }

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Save Edits"))
            {
                _finishedShipBP = -1;
                Utilities.AddFunds(ship.GetTotalCost(), TransactionReasons.VesselRollout);
                BuildListVessel newShip = Utilities.AddVesselToBuildList();
                if (newShip == null)
                {
                    Utilities.SpendFunds(ship.GetTotalCost(), TransactionReasons.VesselRollout);
                    return;
                }

                ship.RemoveFromBuildList();
                newShip.Progress        = newProgress;
                newShip.RushBuildClicks = ship.RushBuildClicks;
                KCTDebug.Log($"Finished? {ship.IsFinished}");
                if (ship.IsFinished)
                {
                    newShip.CannotEarnScience = true;
                }

                GamePersistence.SaveGame("persistent", HighLogic.SaveFolder, SaveMode.OVERWRITE);

                KCTGameStates.EditorShipEditingMode = false;

                InputLockManager.RemoveControlLock("KCTEditExit");
                InputLockManager.RemoveControlLock("KCTEditLoad");
                InputLockManager.RemoveControlLock("KCTEditNew");
                InputLockManager.RemoveControlLock("KCTEditLaunch");
                EditorLogic.fetch.Unlock("KCTEditorMouseLock");
                KCTDebug.Log("Edits saved.");

                HighLogic.LoadScene(GameScenes.SPACECENTER);
            }
            if (GUILayout.Button("Cancel Edits"))
            {
                KCTDebug.Log("Edits cancelled.");
                _finishedShipBP = -1;
                KCTGameStates.EditorShipEditingMode = false;

                InputLockManager.RemoveControlLock("KCTEditExit");
                InputLockManager.RemoveControlLock("KCTEditLoad");
                InputLockManager.RemoveControlLock("KCTEditNew");
                InputLockManager.RemoveControlLock("KCTEditLaunch");
                EditorLogic.fetch.Unlock("KCTEditorMouseLock");

                ScrapYardWrapper.ProcessVessel(KCTGameStates.EditedVessel.ExtractedPartNodes);

                HighLogic.LoadScene(GameScenes.SPACECENTER);
            }
            GUILayout.EndHorizontal();
            if (KCTGameStates.LaunchedVessel != null && !KCTGameStates.LaunchedVessel.AreTanksFull() &&
                GUILayout.Button("Fill Tanks"))
            {
                foreach (Part p in EditorLogic.fetch.ship.parts)
                {
                    //fill as part prefab would be filled?
                    if (Utilities.PartIsProcedural(p))
                    {
                        foreach (PartResource rsc in p.Resources)
                        {
                            if (GuiDataAndWhitelistItemsDatabase.ValidFuelRes.Contains(rsc.resourceName) && rsc.flowState)
                            {
                                rsc.amount = rsc.maxAmount;
                            }
                        }
                    }
                    else
                    {
                        foreach (PartResource rsc in p.Resources)
                        {
                            if (GuiDataAndWhitelistItemsDatabase.ValidFuelRes.Contains(rsc.resourceName) && rsc.flowState)
                            {
                                PartResource templateRsc = p.partInfo.partPrefab.Resources.FirstOrDefault(r => r.resourceName == rsc.resourceName);
                                if (templateRsc != null)
                                {
                                    rsc.amount = templateRsc.amount;
                                }
                            }
                        }
                    }
                }
            }
        }