Exemple #1
0
        public ReconRollout(BuildListVessel vessel, RolloutReconType type, string id, string launchSite = "")
        {
            RRType       = type;
            AssociatedID = id;
            LaunchPadID  = string.IsNullOrEmpty(launchSite) ? vessel.LaunchSite : launchSite;   //For when we add custom launchpads
            Progress     = 0;
            BP           = MathParser.ParseReconditioningFormula(vessel, true);
            //if (type != RolloutReconType.Reconditioning)
            //BP *= KCT_PresetManager.Instance.ActivePreset.timeSettings.RolloutReconSplit;

            if (type == RolloutReconType.Reconditioning)
            {
                //BP *= (1 - KCT_PresetManager.Instance.ActivePreset.timeSettings.RolloutReconSplit);
            }
            else if (type == RolloutReconType.Rollout)
            {
                Cost = MathParser.ParseRolloutCostFormula(vessel);
            }
            else if (type == RolloutReconType.Rollback)
            {
                Progress = BP;
            }
            else if (type == RolloutReconType.Recovery)
            {
                double maxDist = SpaceCenter.Instance.cb.Radius * Math.PI;
                BP += BP * (vessel.DistanceFromKSC / maxDist);
            }
        }
Exemple #2
0
        public static double CalculateBP(double cost)
        {
            var variables = new Dictionary <string, string>()
            {
                { "C", cost.ToString() },
                { "O", PresetManager.Instance.ActivePreset.TimeSettings.OverallMultiplier.ToString() },
                { "Adm", "0" },
                { "AC", "0" },
                { "LP", "1" },
                { "MC", "0" },
                { "RD", "0" },
                { "RW", "0" },
                { "TS", "0" },
                { "SPH", "0" },
                { "VAB", "0" },
                { "Other", "0" }
            };

            double bp = MathParser.GetStandardFormulaValue("KSCUpgrade", variables);

            if (bp <= 0)
            {
                bp = 1;
            }

            return(bp);
        }
        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);
        }
Exemple #4
0
 public ReconRollout(Vessel vessel, RolloutReconType type, string id, string launchSite)
 {
     RRType       = type;
     AssociatedID = id;
     LaunchPadID  = launchSite;
     KCTDebug.Log("New recon_rollout at launchsite: " + LaunchPadID);
     Progress = 0;
     try
     {
         BP = MathParser.ParseReconditioningFormula(new BuildListVessel(vessel), true);
     }
     catch
     {
         KCTDebug.Log("Error while determining BP for recon_rollout");
     }
     if (type == RolloutReconType.Rollback)
     {
         Progress = BP;
     }
     else if (type == RolloutReconType.Recovery)
     {
         double KSCDistance = (float)SpaceCenter.Instance.GreatCircleDistance(SpaceCenter.Instance.cb.GetRelSurfaceNVector(vessel.latitude, vessel.longitude));
         double maxDist     = SpaceCenter.Instance.cb.Radius * Math.PI;
         BP += BP * (KSCDistance / maxDist);
     }
 }
Exemple #5
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;
                }
            }
        }
        /// <summary>
        /// For recovered vessels
        /// </summary>
        /// <param name="vessel"></param>
        /// <param name="listType"></param>
        public BuildListVessel(Vessel vessel, ListType listType = ListType.None)
        {
            Id = Guid.NewGuid();
            KCTPersistentID = Guid.NewGuid().ToString();
            ShipName        = vessel.vesselName;
            ShipNode        = FromInFlightVessel(vessel, listType);
            if (listType != ListType.None)
            {
                Type = listType;
            }

            Cost      = Utilities.GetTotalVesselCost(ShipNode);
            EmptyCost = Utilities.GetTotalVesselCost(ShipNode, false);
            TotalMass = 0;
            EmptyMass = 0;

            HashSet <int> stages = new HashSet <int>();

            foreach (ProtoPartSnapshot p in vessel.protoVessel.protoPartSnapshots)
            {
                stages.Add(p.inverseStageIndex);

                if (p.partPrefab != null)
                {
                    if (p.partPrefab.Modules.Contains <LaunchClamp>() || p.partPrefab.HasTag("PadInfrastructure"))
                    {
                        continue;
                    }
                }

                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)rsc.amount;
                    }
                }
            }
            CannotEarnScience = true;
            NumStages         = stages.Count;
            // FIXME ignore stageable part count and cost - it'll be fixed when we put this back in the editor.

            EffectiveCost = Utilities.GetEffectiveCost(ShipNode.GetNodes("PART").ToList());
            BuildPoints   = Utilities.GetBuildTime(EffectiveCost);
            Flag          = HighLogic.CurrentGame.flagURL;

            DistanceFromKSC = (float)SpaceCenter.Instance.GreatCircleDistance(SpaceCenter.Instance.cb.GetRelSurfaceNVector(vessel.latitude, vessel.longitude));

            RushBuildClicks   = 0;
            IntegrationPoints = MathParser.ParseIntegrationTimeFormula(this);
            IntegrationCost   = (float)MathParser.ParseIntegrationCostFormula(this);

            Progress = BuildPoints + IntegrationPoints;
        }
Exemple #7
0
        public AirlaunchPrep(BuildListVessel vessel, string id)
        {
            Direction    = PrepDirection.Mount;
            AssociatedID = id;
            Progress     = 0;

            BP   = MathParser.ParseAirlaunchTimeFormula(vessel);
            Cost = MathParser.ParseAirlaunchCostFormula(vessel);
        }
        public double GetRushCost()
        {
            if (_rushCost > -1)
            {
                return(_rushCost);
            }

            _rushCost = MathParser.ParseRushCostFormula(this);
            return(_rushCost);
        }
Exemple #9
0
        private static void RenderPointResetSection()
        {
            //TODO: Calculate the cost of resetting
            int ResetCost = (int)MathParser.GetStandardFormulaValue("UpgradeReset", new Dictionary <string, string> {
                { "N", KCTGameStates.UpgradesResetCounter.ToString() }
            });

            if (ResetCost >= 0)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label("Reset Upgrades: ");

                bool canAfford = AvailablePoints >= ResetCost;
                var  style     = canAfford ? GUI.skin.button : GetCannotAffordStyle();
                if (GUILayout.Button($"{ResetCost} Points", style, GUILayout.ExpandWidth(false)))
                {
                    if (SpentPoints > 0 && canAfford) //you have to spend some points before resetting does anything
                    {
                        KCTGameStates.ActiveKSC.VABUpgrades = new List <int>()
                        {
                            0
                        };
                        KCTGameStates.ActiveKSC.SPHUpgrades = new List <int>()
                        {
                            0
                        };
                        KCTGameStates.ActiveKSC.RDUpgrades = new List <int>()
                        {
                            0, 0
                        };
                        KCTGameStates.TechUpgradesTotal = 0;
                        foreach (KSCItem ksc in KCTGameStates.KSCs)
                        {
                            ksc.RDUpgrades[1] = 0;
                        }
                        _nodeRate       = int.MinValue;
                        _upNodeRate     = int.MinValue;
                        _researchRate   = int.MinValue;
                        _upResearchRate = int.MinValue;

                        KCTGameStates.ActiveKSC.RecalculateBuildRates();
                        KCTGameStates.ActiveKSC.RecalculateUpgradedBuildRates();

                        foreach (TechItem tech in KCTGameStates.TechList)
                        {
                            tech.UpdateBuildRate(KCTGameStates.TechList.IndexOf(tech));
                        }

                        KCTGameStates.UpgradesResetCounter++;
                    }
                }
                GUI.enabled = true;
                GUILayout.EndHorizontal();
            }
        }
Exemple #10
0
        public double UpdateBuildRate(int index)
        {
            double rate = MathParser.ParseNodeRateFormula(ScienceCost, index);

            if (rate < 0)
            {
                rate = 0;
            }
            _buildRate = rate;
            return(_buildRate);
        }
Exemple #11
0
        public double GetTotalCost()
        {
            if (Cost == 0 || EmptyCost == 0)
            {
                Cost            = Utilities.GetTotalVesselCost(ShipNode);
                EmptyCost       = Utilities.GetTotalVesselCost(ShipNode, false);
                IntegrationCost = (float)MathParser.ParseIntegrationCostFormula(this);
            }

            return(Cost + IntegrationCost);
        }
Exemple #12
0
        public void RecalculateBuildRates()
        {
            VABRates.Clear();
            SPHRates.Clear();
            double rate  = 0.1;
            int    index = 0;

            // These loops could clean up a little, is it intended to add a rate=0 in the loop as the last entry?
            while (rate > 0)
            {
                rate = MathParser.ParseBuildRateFormula(BuildListVessel.ListType.VAB, index, this);
                if (rate >= 0)
                {
                    VABRates.Add(rate);
                }
                index++;
            }
            rate  = 0.1;
            index = 0;
            while (rate > 0)
            {
                rate = MathParser.ParseBuildRateFormula(BuildListVessel.ListType.SPH, index, this);
                if (rate >= 0)
                {
                    SPHRates.Add(rate);
                }
                index++;
            }

            var m = StringBuilderCache.Acquire();

            m.AppendLine("VAB Rates:");
            foreach (double v in VABRates)
            {
                m.AppendLine($"{v}");
            }

            m.AppendLine("SPH Rates:");
            foreach (double v in SPHRates)
            {
                m.AppendLine($"{v}");
            }

            KCTDebug.Log(m.ToStringAndRelease());
        }
Exemple #13
0
        public double UpdateBuildRate(int index)
        {
            ForceRecalculateYearBasedRateMult();
            double rate = MathParser.ParseNodeRateFormula(ScienceCost, index);

            if (rate < 0)
            {
                rate = 0;
            }

            if (rate != 0)
            {
                rate *= YearBasedRateMult;
            }

            _buildRate = rate;
            return(_buildRate);
        }
Exemple #14
0
        public ReconRollout(BuildListVessel vessel, RolloutReconType type, string id, string launchSite = "")
        {
            RRType       = type;
            AssociatedID = id;
            if (launchSite != "") //For when we add custom launchpads
            {
                LaunchPadID = launchSite;
            }
            else
            {
                LaunchPadID = vessel.LaunchSite;
            }

            Progress = 0;
            if (type == RolloutReconType.Reconditioning)
            {
                BP = MathParser.ParseReconditioningFormula(vessel, true);
                //BP *= (1 - KCT_PresetManager.Instance.ActivePreset.timeSettings.RolloutReconSplit);
                Name = "LaunchPad Reconditioning";
            }
            else if (type == RolloutReconType.Rollout)
            {
                BP = MathParser.ParseReconditioningFormula(vessel, false);
                //BP *= KCT_PresetManager.Instance.ActivePreset.timeSettings.RolloutReconSplit;
                Name = "Vessel Rollout";
                Cost = MathParser.ParseRolloutCostFormula(vessel);
            }
            else if (type == RolloutReconType.Rollback)
            {
                BP = MathParser.ParseReconditioningFormula(vessel, false);
                //BP *= KCT_PresetManager.Instance.ActivePreset.timeSettings.RolloutReconSplit;
                Progress = BP;
                Name     = "Vessel Rollback";
            }
            else if (type == RolloutReconType.Recovery)
            {
                BP = MathParser.ParseReconditioningFormula(vessel, false);
                //BP *= KCT_PresetManager.Instance.ActivePreset.timeSettings.RolloutReconSplit;
                Name = "Vessel Recovery";
                double maxDist = SpaceCenter.Instance.cb.Radius * Math.PI;
                BP += BP * (vessel.DistanceFromKSC / maxDist);
            }
        }
Exemple #15
0
        public void RecalculateBuildRates()
        {
            VABRates.Clear();
            SPHRates.Clear();
            double rate  = 0.1;
            int    index = 0;

            while (rate > 0)
            {
                rate = MathParser.ParseBuildRateFormula(BuildListVessel.ListType.VAB, index, this);
                if (rate >= 0)
                {
                    VABRates.Add(rate);
                }
                index++;
            }
            rate  = 0.1;
            index = 0;
            while (rate > 0)
            {
                rate = MathParser.ParseBuildRateFormula(BuildListVessel.ListType.SPH, index, this);
                if (rate >= 0)
                {
                    SPHRates.Add(rate);
                }
                index++;
            }

            KCTDebug.Log("VAB Rates:");
            foreach (double v in VABRates)
            {
                KCTDebug.Log(v);
            }

            KCTDebug.Log("SPH Rates:");
            foreach (double v in SPHRates)
            {
                KCTDebug.Log(v);
            }
        }
Exemple #16
0
        private static double CalcPointCost(ref int pointDelta, double maxCost, string formulaName, int gameStateIndex)
        {
            int purchasedUpgrades = KCTGameStates.PurchasedUpgrades[gameStateIndex];
            var variables         = new Dictionary <string, string>
            {
                { "N", purchasedUpgrades.ToString() }
            };
            double cumulativeCost = 0;
            double nextCost       = MathParser.GetStandardFormulaValue(formulaName, variables);

            if (nextCost < 0)
            {
                return(-1);
            }

            if (pointDelta < 0)
            {
                pointDelta = 0;
                do
                {
                    pointDelta++;
                    cumulativeCost += nextCost;
                    variables["N"]  = (purchasedUpgrades + pointDelta).ToString();
                    nextCost        = MathParser.GetStandardFormulaValue(formulaName, variables);
                }while (cumulativeCost + nextCost <= maxCost);
            }
            else
            {
                for (int i = 0; i < pointDelta; i++)
                {
                    variables["N"]  = (purchasedUpgrades + i).ToString();
                    cumulativeCost += MathParser.GetStandardFormulaValue(formulaName, variables);
                }
            }
            return(cumulativeCost);
        }
Exemple #17
0
        public void RecalculateUpgradedBuildRates()
        {
            UpVABRates.Clear();
            UpSPHRates.Clear();
            double rate  = 0.1;
            int    index = 0;

            while (rate > 0)
            {
                rate = MathParser.ParseBuildRateFormula(BuildListVessel.ListType.VAB, index, this, true);
                if (rate >= 0 && (index == 0 || VABRates[index - 1] > 0))
                {
                    UpVABRates.Add(rate);
                }
                else
                {
                    break;
                }
                index++;
            }
            rate  = 0.1;
            index = 0;
            while (rate > 0)
            {
                rate = MathParser.ParseBuildRateFormula(BuildListVessel.ListType.SPH, index, this, true);
                if (rate >= 0 && (index == 0 || SPHRates[index - 1] > 0))
                {
                    UpSPHRates.Add(rate);
                }
                else
                {
                    break;
                }
                index++;
            }
        }
Exemple #18
0
        public static double CalculateBP(double cost, SpaceCenterFacility?facilityType)
        {
            int isAdm = 0, isAC = 0, isLP = 0, isMC = 0, isRD = 0, isRW = 0, isTS = 0, isSPH = 0, isVAB = 0, isOther = 0;

            switch (facilityType)
            {
            case SpaceCenterFacility.Administration:
                isAdm = 1;
                break;

            case SpaceCenterFacility.AstronautComplex:
                isAC = 1;
                break;

            case SpaceCenterFacility.LaunchPad:
                isLP = 1;
                break;

            case SpaceCenterFacility.MissionControl:
                isMC = 1;
                break;

            case SpaceCenterFacility.ResearchAndDevelopment:
                isRD = 1;
                break;

            case SpaceCenterFacility.Runway:
                isRW = 1;
                break;

            case SpaceCenterFacility.TrackingStation:
                isTS = 1;
                break;

            case SpaceCenterFacility.SpaceplaneHangar:
                isSPH = 1;
                break;

            case SpaceCenterFacility.VehicleAssemblyBuilding:
                isVAB = 1;
                break;

            default:
                isOther = 1;
                break;
            }

            var variables = new Dictionary <string, string>()
            {
                { "C", cost.ToString() },
                { "O", PresetManager.Instance.ActivePreset.TimeSettings.OverallMultiplier.ToString() },
                { "Adm", isAdm.ToString() },
                { "AC", isAC.ToString() },
                { "LP", isLP.ToString() },
                { "MC", isMC.ToString() },
                { "RD", isRD.ToString() },
                { "RW", isRW.ToString() },
                { "TS", isTS.ToString() },
                { "SPH", isSPH.ToString() },
                { "VAB", isVAB.ToString() },
                { "Other", isOther.ToString() }
            };

            double bp = MathParser.GetStandardFormulaValue("KSCUpgrade", variables);

            if (bp <= 0)
            {
                bp = 1;
            }

            return(bp);
        }
Exemple #19
0
        private static void RenderRnDSection(bool isCostCacheInvalid, KSCItem KSC)
        {
            if (Config == null)
            {
                Config = new LRTRHomeWorldParameters();
                foreach (ConfigNode stg in GameDatabase.Instance.GetConfigNodes("HOMEWORLDPARAMETERS"))
                {
                    Config.Load(stg);
                }
            }
            double secondsPerDay = Config.hoursPerDay * 3600;

            int labelDelta = _buyModifier < 0 ? AvailablePoints : _buyModifier;

            GUILayout.BeginHorizontal();
            GUILayout.Label("R&D Upgrades");
            GUILayout.Label($"+{labelDelta} Point{(labelDelta == 1 ? "" : "s")}", GUILayout.ExpandWidth(false));
            GUILayout.EndHorizontal();

            if (_researchRate == int.MinValue || isCostCacheInvalid)
            {
                _researchDelta = _buyModifier < 0 ? AvailablePoints : _buyModifier;
                var variables = new Dictionary <string, string>()
                {
                    { "N", KSC.RDUpgrades[0].ToString() },
                    { "R", Utilities.GetBuildingUpgradeLevel(SpaceCenterFacility.ResearchAndDevelopment).ToString() }
                };
                MathParser.AddCrewVariables(variables);
                _researchRate = MathParser.GetStandardFormulaValue("Research", variables);

                variables["N"]  = (KSC.RDUpgrades[0] + _researchDelta).ToString();
                _upResearchRate = MathParser.GetStandardFormulaValue("Research", variables);
            }

            if (_researchRate >= 0)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label("Research");
                GUILayout.Label($"{Math.Round(_researchRate * secondsPerDay, 2)} sci/{secondsPerDay} BP");
                if (AvailablePoints > 0)
                {
                    bool     canAfford = AvailablePoints >= _researchDelta;
                    GUIStyle style     = canAfford ? GUI.skin.button : GetCannotAffordStyle();
                    if (GUILayout.Button($"+{Math.Round((_upResearchRate - _researchRate) * secondsPerDay, 2)}", style, GUILayout.Width(45)) && canAfford)
                    {
                        KSC.RDUpgrades[0] += _researchDelta;
                        _researchRate      = int.MinValue;
                        _fundsCost         = _spentPoints = _totalPoints = int.MinValue;
                    }
                }
                GUILayout.EndHorizontal();
            }

            double days = GameSettings.KERBIN_TIME ? 4 : 1;

            if (_nodeRate == int.MinValue || isCostCacheInvalid)
            {
                _nodeDelta  = _buyModifier < 0 ? AvailablePoints : _buyModifier;
                _nodeRate   = MathParser.ParseNodeRateFormula(0);
                _upNodeRate = MathParser.ParseNodeRateFormula(0, 0, _nodeDelta);
            }

            double sci       = secondsPerDay * _nodeRate;
            double sciPerDay = sci / days;

            GUILayout.BeginHorizontal();
            GUILayout.Label("Rate");
            bool usingPerYear = false;

            if (sciPerDay > 0.1)
            {
                GUILayout.Label(Math.Round(sciPerDay * 1000) / 1000 + " sci/day");
            }
            else
            {
                //Well, looks like we need sci/year instead
                GUILayout.Label(Math.Round(sciPerDay * Config.daysPerYear * 1000) / 1000 + " sci/yr");
                usingPerYear = true;
            }
            if (_upNodeRate != _nodeRate && AvailablePoints > 0)
            {
                bool everyKSCCanUpgrade = true;
                foreach (KSCItem ksc in KCTGameStates.KSCs)
                {
                    if (TotalPoints - Utilities.GetTotalSpentUpgrades(ksc) <= 0)
                    {
                        everyKSCCanUpgrade = false;
                        break;
                    }
                }
                if (everyKSCCanUpgrade)
                {
                    double upSciPerDay = secondsPerDay * _upNodeRate / days;
                    string buttonText  = $"{Math.Round(1000 * upSciPerDay) / 1000} sci/day";
                    if (usingPerYear)
                    {
                        buttonText = $"{Math.Round(upSciPerDay * Config.daysPerYear * 1000) / 1000} sci/yr";
                    }
                    bool     canAfford = AvailablePoints >= _nodeDelta;
                    GUIStyle style     = canAfford ? GUI.skin.button : GetCannotAffordStyle();
                    if (GUILayout.Button(buttonText, style, GUILayout.ExpandWidth(false)) && canAfford)
                    {
                        KCTGameStates.TechUpgradesTotal += _nodeDelta;
                        foreach (KSCItem ksc in KCTGameStates.KSCs)
                        {
                            ksc.RDUpgrades[1] = KCTGameStates.TechUpgradesTotal;
                        }

                        _nodeRate  = _upNodeRate = int.MinValue;
                        _fundsCost = _spentPoints = _totalPoints = int.MinValue;

                        foreach (TechItem tech in KCTGameStates.TechList)
                        {
                            tech.UpdateBuildRate(KCTGameStates.TechList.IndexOf(tech));
                        }
                    }
                }
            }
            GUILayout.EndHorizontal();
        }
Exemple #20
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);
        }
Exemple #21
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;
                                }
                            }
                        }
                    }
                }
            }
        }
Exemple #22
0
        public BuildListVessel(ShipConstruct s, string ls, double effCost, double bP, string flagURL)
        {
            _ship    = s;
            ShipNode = s.SaveShip();
            // Override KSP sizing of the ship construct
            ShipSize = Utilities.GetShipSize(s, true);
            ShipNode.SetValue("size", KSPUtil.WriteVector(ShipSize));
            ShipName  = s.shipName;
            Cost      = Utilities.GetTotalVesselCost(ShipNode, true);
            EmptyCost = Utilities.GetTotalVesselCost(ShipNode, false);
            TotalMass = Utilities.GetShipMass(s, true, out EmptyMass, out _);

            HashSet <int> stages = new HashSet <int>();

            NumStageParts = 0;
            StagePartCost = 0d;

            foreach (Part p in s.Parts)
            {
                if (p.stagingOn)
                {
                    stages.Add(p.inverseStage);
                    ++NumStageParts;
                    StagePartCost += p.GetModuleCosts(p.partInfo.cost, ModifierStagingSituation.CURRENT) + p.partInfo.cost;
                }
            }
            NumStages = stages.Count;

            LaunchSite    = ls;
            EffectiveCost = effCost;
            BuildPoints   = bP;
            Progress      = 0;
            Flag          = flagURL;
            if (s.shipFacility == EditorFacility.VAB)
            {
                Type            = ListType.VAB;
                FacilityBuiltIn = EditorFacility.VAB;
            }
            else if (s.shipFacility == EditorFacility.SPH)
            {
                Type            = ListType.SPH;
                FacilityBuiltIn = EditorFacility.SPH;
            }
            else
            {
                Type = ListType.None;
            }
            Id = Guid.NewGuid();
            KCTPersistentID   = Guid.NewGuid().ToString();
            CannotEarnScience = false;

            //get the crew from the editorlogic
            DesiredManifest = new List <string>();
            if (CrewAssignmentDialog.Instance?.GetManifest()?.CrewCount > 0)
            {
                foreach (ProtoCrewMember crew in CrewAssignmentDialog.Instance.GetManifest().GetAllCrew(true) ?? new List <ProtoCrewMember>())
                {
                    DesiredManifest.Add(crew?.name ?? string.Empty);
                }
            }

            if (EffectiveCost == default)
            {
                // Can only happen in older saves that didn't have Effective cost persisted as a separate field
                // This code should be safe to remove after a while.
                EffectiveCost = Utilities.GetEffectiveCost(ShipNode.GetNodes("PART").ToList());
            }

            IntegrationPoints = MathParser.ParseIntegrationTimeFormula(this);
            IntegrationCost   = (float)MathParser.ParseIntegrationCostFormula(this);
        }