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(); }