From dd413a9c11f721a4dea87cb87ab357ffd25cc520 Mon Sep 17 00:00:00 2001 From: Capkirk123 Date: Thu, 20 Jun 2024 17:29:43 -0400 Subject: [PATCH 01/14] Stop override RSS space threshold for the moon --- GameData/RP-1/Science/BodyScienceParams.cfg | 4 ---- 1 file changed, 4 deletions(-) diff --git a/GameData/RP-1/Science/BodyScienceParams.cfg b/GameData/RP-1/Science/BodyScienceParams.cfg index ccd7ba19846..d9ec31f2188 100644 --- a/GameData/RP-1/Science/BodyScienceParams.cfg +++ b/GameData/RP-1/Science/BodyScienceParams.cfg @@ -27,10 +27,6 @@ { %ScienceValues { - //high enough for LLO to be inside it, and for impact missions to transmit before crashing - //low enough to be appreciably harder than a simple flyby. - %spaceAltitudeThreshold = 150000 - %landedDataValue = 3.0 %inSpaceLowDataValue = 2.0 %inSpaceHighDataValue = 1.5 From 9326e9e687be5f3f8d854be20dcbe7c263c12717 Mon Sep 17 00:00:00 2001 From: NathanKell Date: Thu, 27 Jun 2024 14:56:01 -0700 Subject: [PATCH 02/14] Rewrite Ops time/efficiency prediction to match VBP version --- Source/RP0/SpaceCenter/Projects/LCOpsProject.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Source/RP0/SpaceCenter/Projects/LCOpsProject.cs b/Source/RP0/SpaceCenter/Projects/LCOpsProject.cs index 02fb9164d35..c3203c37341 100644 --- a/Source/RP0/SpaceCenter/Projects/LCOpsProject.cs +++ b/Source/RP0/SpaceCenter/Projects/LCOpsProject.cs @@ -150,17 +150,15 @@ public double GetTimeLeft() private double TimeLeftWithEfficiencyIncrease(double timeLeft) { - if (LC.Efficiency == LCEfficiency.MaxEfficiency) + if (LC.Efficiency == LCEfficiency.MaxEfficiency || timeLeft < 86400d) return timeLeft; - if (timeLeft > 86400d) + double bpDivRate = timeLeft * LC.Efficiency; + double newEff = LC.Efficiency; + double portion = LC.Engineers / (double)LC.MaxEngineers; + for (int i = 0; i < 4; ++i) { - double newEff = LC.Efficiency; - double portion = LC.Engineers / (double)LC.MaxEngineers; - for (int i = 0; i < 4; ++i) - { - timeLeft = (timeLeft * newEff) / LC.EfficiencySource.PredictWeightedEfficiency(timeLeft, portion, out newEff, LC.Efficiency); - } + timeLeft = bpDivRate / LC.EfficiencySource.PredictWeightedEfficiency(timeLeft, portion, out newEff, LC.Efficiency); } return timeLeft; } From cb960f87b097044542ff4845182a1fc931a5ce6d Mon Sep 17 00:00:00 2001 From: siimav Date: Fri, 28 Jun 2024 22:09:33 +0300 Subject: [PATCH 03/14] Fix airlaunch costs not getting reflected in budget calcs --- Source/RP0/SpaceCenter/SpaceCenterManagement.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/RP0/SpaceCenter/SpaceCenterManagement.cs b/Source/RP0/SpaceCenter/SpaceCenterManagement.cs index 3cad8836a3a..9d66217a5da 100644 --- a/Source/RP0/SpaceCenter/SpaceCenterManagement.cs +++ b/Source/RP0/SpaceCenter/SpaceCenterManagement.cs @@ -1052,7 +1052,7 @@ public double GetRolloutCostOverTime(double time) public double GetRolloutCostOverTime(double time, LCSpaceCenter ksc) { double delta = 0; - for (int i = 1; i < ksc.LaunchComplexes.Count; ++i) + for (int i = 0; i < ksc.LaunchComplexes.Count; ++i) delta += GetRolloutCostOverTime(time, ksc.LaunchComplexes[i]); return delta; From 9ab59552a07c37ed6be40beca2ee8522943dd94e Mon Sep 17 00:00:00 2001 From: siimav Date: Tue, 2 Jul 2024 13:12:59 +0300 Subject: [PATCH 04/14] Fix KSCSwitcher patch using improper KSC name --- Source/RP0/Harmony/KSCSwitcher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/RP0/Harmony/KSCSwitcher.cs b/Source/RP0/Harmony/KSCSwitcher.cs index 1270c001e24..87de274a1c6 100644 --- a/Source/RP0/Harmony/KSCSwitcher.cs +++ b/Source/RP0/Harmony/KSCSwitcher.cs @@ -21,7 +21,7 @@ internal static void Postfix_SetSite(ConfigNode KSC, bool __result) { if (__result && SpaceCenterManagement.Instance != null) { - SpaceCenterManagement.Instance.SetActiveKSC(KSC.name); + SpaceCenterManagement.Instance.SetActiveKSC(KSC.GetValue("name")); } } } From 3e16156a95c3c7631f4059d9ca7b54a69c722245 Mon Sep 17 00:00:00 2001 From: siimav <1120038+siimav@users.noreply.github.com> Date: Wed, 3 Jul 2024 18:31:30 +0300 Subject: [PATCH 05/14] Recalc build rates when needed (#2392) --- .../SpaceCenter/Projects/LCConstructionProject.cs | 1 - Source/RP0/UI/KCT/GUI_Personnel.cs | 15 ++++++--------- Source/RP0/Utilities/KCTUtilities.cs | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Source/RP0/SpaceCenter/Projects/LCConstructionProject.cs b/Source/RP0/SpaceCenter/Projects/LCConstructionProject.cs index 7ee97a49304..0f7445ce130 100644 --- a/Source/RP0/SpaceCenter/Projects/LCConstructionProject.cs +++ b/Source/RP0/SpaceCenter/Projects/LCConstructionProject.cs @@ -125,7 +125,6 @@ private void ReassignEngineers(LaunchComplex lc) if (engToAssign > 0) { KCTUtilities.ChangeEngineers(lc, engToAssign); - lc.RecalculateBuildRates(); } } } diff --git a/Source/RP0/UI/KCT/GUI_Personnel.cs b/Source/RP0/UI/KCT/GUI_Personnel.cs index a0222ce606b..33ad28fe63c 100644 --- a/Source/RP0/UI/KCT/GUI_Personnel.cs +++ b/Source/RP0/UI/KCT/GUI_Personnel.cs @@ -123,9 +123,10 @@ private static void RenderEngineersSection(bool isCostCacheInvalid) string assignStr = GetAssignText(true, currentLC, out int assignAmt); string unassignStr = GetAssignText(false, currentLC, out int unassignAmt); - bool recalc = false; ProjectType type = currentLC.LCType == LaunchComplexType.Pad ? ProjectType.VAB : ProjectType.SPH; - if (GUILayout.Button(unassignStr, GUILayout.ExpandWidth(false)) && unassignAmt > 0) { KCTUtilities.ChangeEngineers(currentLC, -unassignAmt); recalc = true; } + if (GUILayout.Button(unassignStr, GUILayout.ExpandWidth(false)) && unassignAmt > 0) + KCTUtilities.ChangeEngineers(currentLC, -unassignAmt); + if (Event.current.type == EventType.Repaint) { if (GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition)) @@ -136,7 +137,9 @@ private static void RenderEngineersSection(bool isCostCacheInvalid) GUILayout.Label($" {currentLC.Engineers:N0} ", GetLabelCenterAlignStyle(), GUILayout.ExpandWidth(false)); - if (GUILayout.Button(assignStr, GUILayout.ExpandWidth(false)) && assignAmt > 0) { KCTUtilities.ChangeEngineers(currentLC, assignAmt); recalc = true; } + if (GUILayout.Button(assignStr, GUILayout.ExpandWidth(false)) && assignAmt > 0) + KCTUtilities.ChangeEngineers(currentLC, assignAmt); + if (Event.current.type == EventType.Repaint) { if (GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition)) @@ -148,12 +151,6 @@ private static void RenderEngineersSection(bool isCostCacheInvalid) GUILayout.Label($"Max: {currentLC.MaxEngineers:N0}", GetLabelRightAlignStyle()); GUILayout.EndHorizontal(); - if (recalc) - { - currentLC.RecalculateBuildRates(); - currentLC.KSC.RecalculateBuildRates(false); - } - int assignDelta = 0; if (_currentPersonnelHover == PersonnelButtonHover.Assign) assignDelta = assignAmt; diff --git a/Source/RP0/Utilities/KCTUtilities.cs b/Source/RP0/Utilities/KCTUtilities.cs index e88d2d64f3c..1d60c6a7888 100644 --- a/Source/RP0/Utilities/KCTUtilities.cs +++ b/Source/RP0/Utilities/KCTUtilities.cs @@ -1345,7 +1345,6 @@ public static void HireStaff(bool isResearch, int workerAmount, LaunchComplex lc ChangeEngineers(ksc, workerAmount); if (lc != null) ChangeEngineers(lc, workerAmount); - ksc.RecalculateBuildRates(false); } SpaceCenterManagement.Instance.Applicants = Math.Max(0, SpaceCenterManagement.Instance.Applicants - workerAmount); if (SpaceCenterManagement.Instance.Applicants == 0) @@ -1357,6 +1356,7 @@ public static void ChangeEngineers(LaunchComplex currentLC, int delta) currentLC.Engineers += delta; SCMEvents.OnPersonnelChange.Fire(); MaintenanceHandler.Instance.ScheduleMaintenanceUpdate(); + currentLC.RecalculateBuildRates(); KCT_GUI.BuildRateForDisplay = null; } From 49b3c5fbfb010057a529b05a242042323ad1cf1c Mon Sep 17 00:00:00 2001 From: siimav Date: Fri, 5 Jul 2024 19:02:17 +0300 Subject: [PATCH 06/14] Extract KSCSwitcher integration into a separate class --- .../RP0/ModIntegrations/KSCSwitcherInterop.cs | 65 +++++++++++++++++ Source/RP0/RP0.csproj | 1 + .../RP0/SpaceCenter/SpaceCenterManagement.cs | 73 ++----------------- 3 files changed, 73 insertions(+), 66 deletions(-) create mode 100644 Source/RP0/ModIntegrations/KSCSwitcherInterop.cs diff --git a/Source/RP0/ModIntegrations/KSCSwitcherInterop.cs b/Source/RP0/ModIntegrations/KSCSwitcherInterop.cs new file mode 100644 index 00000000000..ebe26e7c7af --- /dev/null +++ b/Source/RP0/ModIntegrations/KSCSwitcherInterop.cs @@ -0,0 +1,65 @@ +using System; +using System.Linq; +using System.Reflection; + +namespace RP0 +{ + public static class KSCSwitcherInterop + { + private static bool? _isKSCSwitcherInstalled = null; + private static FieldInfo _fiKSCSwInstance; + private static FieldInfo _fiKSCSwSites; + private static FieldInfo _fiKSCSwLastSite; + private static FieldInfo _fiKSCSwDefaultSite; + + public const string LegacyDefaultKscId = "Stock"; + public const string DefaultKscId = "us_cape_canaveral"; + + public static bool IsKSCSwitcherInstalled + { + get + { + if (!_isKSCSwitcherInstalled.HasValue) + { + Assembly a = AssemblyLoader.loadedAssemblies.FirstOrDefault(la => string.Equals(la.name, "KSCSwitcher", StringComparison.OrdinalIgnoreCase))?.assembly; + _isKSCSwitcherInstalled = a != null; + if (_isKSCSwitcherInstalled.Value) + { + Type t = a.GetType("regexKSP.KSCLoader"); + _fiKSCSwInstance = t?.GetField("instance", BindingFlags.Public | BindingFlags.Static); + _fiKSCSwSites = t?.GetField("Sites", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); + + t = a.GetType("regexKSP.KSCSiteManager"); + _fiKSCSwLastSite = t?.GetField("lastSite", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); + _fiKSCSwDefaultSite = t?.GetField("defaultSite", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); + + if (_fiKSCSwInstance == null || _fiKSCSwSites == null || _fiKSCSwLastSite == null || _fiKSCSwDefaultSite == null) + { + RP0Debug.LogError("Failed to bind to KSCSwitcher"); + _isKSCSwitcherInstalled = false; + } + } + } + return _isKSCSwitcherInstalled.Value; + } + } + + public static string GetActiveRSSKSC() + { + if (!IsKSCSwitcherInstalled) return null; + + // get the LastKSC.KSCLoader.instance object + // check the Sites object (KSCSiteManager) for the lastSite, if "" then get defaultSite + + object loaderInstance = _fiKSCSwInstance.GetValue(null); + if (loaderInstance == null) + return null; + object sites = _fiKSCSwSites.GetValue(loaderInstance); + string lastSite = _fiKSCSwLastSite.GetValue(sites) as string; + + if (lastSite == string.Empty) + lastSite = _fiKSCSwDefaultSite.GetValue(sites) as string; + return lastSite; + } + } +} diff --git a/Source/RP0/RP0.csproj b/Source/RP0/RP0.csproj index dd061e7294a..fe27920834d 100644 --- a/Source/RP0/RP0.csproj +++ b/Source/RP0/RP0.csproj @@ -45,6 +45,7 @@ + diff --git a/Source/RP0/SpaceCenter/SpaceCenterManagement.cs b/Source/RP0/SpaceCenter/SpaceCenterManagement.cs index 9d66217a5da..e7e894782bd 100644 --- a/Source/RP0/SpaceCenter/SpaceCenterManagement.cs +++ b/Source/RP0/SpaceCenter/SpaceCenterManagement.cs @@ -525,7 +525,7 @@ public override void OnLoad(ConfigNode node) bool foundStockKSC = false; foreach (var ksc in KSCs) { - if (ksc.KSCName.Length > 0 && string.Equals(ksc.KSCName, _legacyDefaultKscId, StringComparison.OrdinalIgnoreCase)) + if (ksc.KSCName.Length > 0 && string.Equals(ksc.KSCName, KSCSwitcherInterop.LegacyDefaultKscId, StringComparison.OrdinalIgnoreCase)) { foundStockKSC = true; break; @@ -646,11 +646,11 @@ private bool FixVesselSatPayload(VesselProject vp) private void TryMigrateStockKSC() { - LCSpaceCenter stockKsc = KSCs.Find(k => string.Equals(k.KSCName, _legacyDefaultKscId, StringComparison.OrdinalIgnoreCase)); + LCSpaceCenter stockKsc = KSCs.Find(k => string.Equals(k.KSCName, KSCSwitcherInterop.LegacyDefaultKscId, StringComparison.OrdinalIgnoreCase)); if (KSCs.Count == 1) { // Rename the stock KSC to the new default (Cape) - stockKsc.KSCName = _defaultKscId; + stockKsc.KSCName = KSCSwitcherInterop.DefaultKscId; SetActiveKSC(stockKsc.KSCName); return; } @@ -666,7 +666,7 @@ private void TryMigrateStockKSC() int numOtherUsedKSCs = KSCs.Count(k => !k.IsEmpty && k != stockKsc); if (numOtherUsedKSCs == 0) { - string kscName = GetActiveRSSKSC() ?? _defaultKscId; + string kscName = KSCSwitcherInterop.GetActiveRSSKSC() ?? KSCSwitcherInterop.DefaultKscId; LCSpaceCenter newDefault = KSCs.Find(k => string.Equals(k.KSCName, kscName, StringComparison.OrdinalIgnoreCase)); if (newDefault != null) { @@ -679,7 +679,7 @@ private void TryMigrateStockKSC() } // Can't really do anything if there's multiple KSCs in use. - if (!IsKSCSwitcherInstalled) + if (!KSCSwitcherInterop.IsKSCSwitcherInstalled) { // Need to switch back to the legacy "Stock" KSC if KSCSwitcher isn't installed SetActiveKSC(stockKsc.KSCName); @@ -866,77 +866,18 @@ public VesselRepairProject FindRepairForVessel(Vessel v) #endregion - #region KSCSwitcher section - - private static bool? _isKSCSwitcherInstalled = null; - private static FieldInfo _fiKSCSwInstance; - private static FieldInfo _fiKSCSwSites; - private static FieldInfo _fiKSCSwLastSite; - private static FieldInfo _fiKSCSwDefaultSite; - private const string _legacyDefaultKscId = "Stock"; - private const string _defaultKscId = "us_cape_canaveral"; - - private static bool IsKSCSwitcherInstalled - { - get - { - if (!_isKSCSwitcherInstalled.HasValue) - { - Assembly a = AssemblyLoader.loadedAssemblies.FirstOrDefault(la => string.Equals(la.name, "KSCSwitcher", StringComparison.OrdinalIgnoreCase))?.assembly; - _isKSCSwitcherInstalled = a != null; - if (_isKSCSwitcherInstalled.Value) - { - Type t = a.GetType("regexKSP.KSCLoader"); - _fiKSCSwInstance = t?.GetField("instance", BindingFlags.Public | BindingFlags.Static); - _fiKSCSwSites = t?.GetField("Sites", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); - - t = a.GetType("regexKSP.KSCSiteManager"); - _fiKSCSwLastSite = t?.GetField("lastSite", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); - _fiKSCSwDefaultSite = t?.GetField("defaultSite", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); - - if (_fiKSCSwInstance == null || _fiKSCSwSites == null || _fiKSCSwLastSite == null || _fiKSCSwDefaultSite == null) - { - RP0Debug.LogError("Failed to bind to KSCSwitcher"); - _isKSCSwitcherInstalled = false; - } - } - } - return _isKSCSwitcherInstalled.Value; - } - } - - private string GetActiveRSSKSC() - { - if (!IsKSCSwitcherInstalled) return null; - - // get the LastKSC.KSCLoader.instance object - // check the Sites object (KSCSiteManager) for the lastSite, if "" then get defaultSite - - object loaderInstance = _fiKSCSwInstance.GetValue(null); - if (loaderInstance == null) - return null; - object sites = _fiKSCSwSites.GetValue(loaderInstance); - string lastSite = _fiKSCSwLastSite.GetValue(sites) as string; - - if (lastSite == string.Empty) - lastSite = _fiKSCSwDefaultSite.GetValue(sites) as string; - return lastSite; - } - - #endregion - #region KSC private void SetActiveKSCToRSS() { - string site = GetActiveRSSKSC(); + string site = KSCSwitcherInterop.GetActiveRSSKSC(); SetActiveKSC(site); } public void SetActiveKSC(string site) { if (site == null || site.Length == 0) - site = _defaultKscId; + site = KSCSwitcherInterop.DefaultKscId; if (ActiveSC == null || site != ActiveSC.KSCName) { RP0Debug.Log($"Setting active site to {site}"); From 03807d2923c67c58ace5970f286db9110edd12e2 Mon Sep 17 00:00:00 2001 From: Capkirk123 Date: Mon, 8 Jul 2024 15:13:50 -0400 Subject: [PATCH 07/14] Set supersonic jet trainer antenna to TL0 --- .../RP-1/Craft Files/SPH/Supersonic Jet Trainer.craft | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/GameData/RP-1/Craft Files/SPH/Supersonic Jet Trainer.craft b/GameData/RP-1/Craft Files/SPH/Supersonic Jet Trainer.craft index 348bfee2aeb..db4322e4bfa 100644 --- a/GameData/RP-1/Craft Files/SPH/Supersonic Jet Trainer.craft +++ b/GameData/RP-1/Craft Files/SPH/Supersonic Jet Trainer.craft @@ -1443,7 +1443,7 @@ PART isEnabled = True _enabled = True TxPower = 30 - TechLevel = 10 + TechLevel = 0 AMWTemp = 0 antennaDiameter = 0 referenceGain = 1.5 @@ -1465,15 +1465,6 @@ PART } UPGRADESAPPLIED { - upgrade = commsTL1 - upgrade = commsTL2 - upgrade = commsTL3 - upgrade = commsTL4 - upgrade = commsTL5 - upgrade = commsTL6 - upgrade = commsTL7 - upgrade = commsTL8 - upgrade = commsTL9 } } MODULE From 94e9a4ce34c7fa865bc41c746fce5b5dcf55133b Mon Sep 17 00:00:00 2001 From: siimav <1120038+siimav@users.noreply.github.com> Date: Tue, 9 Jul 2024 21:33:43 +0300 Subject: [PATCH 08/14] Remove MagiCore from netkan deps --- RP-1.netkan | 2 -- 1 file changed, 2 deletions(-) diff --git a/RP-1.netkan b/RP-1.netkan index 46178c260c3..136a6138342 100644 --- a/RP-1.netkan +++ b/RP-1.netkan @@ -29,8 +29,6 @@ depends: suppress_recommendations: true - name: RealSolarSystem suppress_recommendations: true - - name: MagiCore - suppress_recommendations: true - name: ClickThroughBlocker suppress_recommendations: true - name: ToolbarController From 98b5d74efe49e313bbca3a34db758dd6f32bc628 Mon Sep 17 00:00:00 2001 From: Clayell <125416952+Clayell@users.noreply.github.com> Date: Fri, 12 Jul 2024 20:48:54 -0400 Subject: [PATCH 09/14] Fixing descriptions (#2385) * Update RFTechLevels.cfg * Update EarlyComNetwork3-CA.cfg * Update FirstMolniyaSat-CA.cfg make AOP more clear and in line with the objectives that state it must be between 220 and 320 * Update Programs.cfg make it more clear on the reasoning behind upgrading AC to 3 * scale molniya reward by 10 to make rep and confidence more in line with normal com sat contracts * Update EarlyMolniyaSat.cfg * Update EarlyMolniyaSat.cfg * Update Programs.cfg add reminder to train crew a year before launch (proficiency takes about a year) * Update EarlyComSat-CA.cfg * Update EarlyNavSat-CA.cfg the description implied that a network was being made, which is incorrect i adapted the description from the commercial repeatable * Update SXT.json the mk-10 is the set of 3 balloons, the mk10-xl is the single large balloon * Update SXT.json * Update SXT.json --- .../Commercial Applications 1/EarlyComNetwork3-CA.cfg | 2 +- .../Contracts/Commercial Applications 1/EarlyComSat-CA.cfg | 2 +- .../Contracts/Commercial Applications 1/EarlyNavSat-CA.cfg | 2 +- .../Commercial Applications 1/FirstMolniyaSat-CA.cfg | 2 +- GameData/RP-1/Programs/Programs.cfg | 2 +- Source/Tech Tree/Parts Browser/data/SXT.json | 6 +++--- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyComNetwork3-CA.cfg b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyComNetwork3-CA.cfg index e47c60d076f..7d456a67b5c 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyComNetwork3-CA.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyComNetwork3-CA.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp - description = Program: Early Commercial Applications
Type: Required


Now that you've demonstrated the ability of satellites to relay communications via one-off launches, it's time to create a network of them to provide full coverage of the Earth.

Launch a 4-satellite communication network where the satellites are sufficiently dispersed and in high enough orbits to provide near-complete coverage of the Earth's surface.

NOTE: You may choose only the 3-satellite or 4-satellite contract.

NOTE: The satellites will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. + description = Program: Early Commercial Applications
Type: Required


Now that you've demonstrated the ability of satellites to relay communications via one-off launches, it's time to create a network of them to provide full coverage of the Earth.

Launch a 3-satellite communication network where the satellites are sufficiently dispersed and in high enough orbits to provide near-complete coverage of the Earth's surface.

NOTE: You may choose only the 3-satellite or 4-satellite contract.

NOTE: The satellites will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. synopsis = Launch a 3 satellite Communications Network diff --git a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyComSat-CA.cfg b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyComSat-CA.cfg index 8302f1f42eb..1d8ec2322e5 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyComSat-CA.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyComSat-CA.cfg @@ -4,7 +4,7 @@ CONTRACT_TYPE title = Commercial Communications Satellite (Early) group = CommApp - description = Program: Early Commercial Applications
Type: Optional


Now that satellite communications technology has been proven, launch more capable satellites to expand communication coverage further around Earth. Every major Telecom now wants their own satellite capabilities tailored to their specific needs. Launch new communications satellites with the required specifications into the specified orbits.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

The reward of this contract will slowly increase over time but will be reset to 0 after each completion.
Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_EarlyComSat
Number of Contracts Completed: @index / unlimited
+ description = Program: Early Commercial Applications
Type: Optional


Now that satellite communications technology has been proven, we need to launch more capable satellites to expand communication coverage further around Earth. Every major Telecom wants their own satellite capabilities tailored to their specific needs. Launch new communications satellites with the required specifications into the specified orbits.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

The reward of this contract will slowly increase over time but will be reset to 0 after each completion.
Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_EarlyComSat
Number of Contracts Completed: @index / unlimited
genericDescription = Put a satellite with the required amount of communications satellite payload into the desired orbit. synopsis = Launch a Communications Satellite for a customer. diff --git a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyNavSat-CA.cfg b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyNavSat-CA.cfg index dd1e71e55b8..e46ded84e6b 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyNavSat-CA.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyNavSat-CA.cfg @@ -4,7 +4,7 @@ CONTRACT_TYPE title = Commercial Navigation Satellite (Early) group = CommApp - description = Program: Early Commercial Applications
Type: Optional


The First Navigation Satellite contract proved that measuring signals from a satellite is an effective method for determining position data on the surface of the Earth. Expand on this capability to create the first rudimentary satellite-based precision location network. At least 3 satellites are required to locate a position on a sphere, with a fourth necessary to determine vertical position. Launch at least 4 more navigation satellites into polar orbits.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

The reward of this contract will slowly increase over time but will be reset to 0 after each completion.
Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_EarlyComSat
Number of Contracts Completed: @index / unlimited
+ description = Program: Early Commercial Applications
Type: Optional


Now that satellite navigation technology has been proven, we need to launch more capable satellites to expand navigation coverage further around Earth. Our customers want their own satellite capabilities tailored to their specific needs. Launch new navigation satellites with the required specifications into the specified orbits.

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer.

The reward of this contract will slowly increase over time but will be reset to 0 after each completion.
Current reward is at @rewardFactorPercent % of its nominal value. Elapsed/Expected Days: @elapsedDays / @RP0:expectedDays_EarlyComSat
Number of Contracts Completed: @index / unlimited
genericDescription = Put a satellite with the required amount of navigation satellite payload into the desired orbit. synopsis = Launch a Navigation Satellite for a customer. diff --git a/GameData/RP-1/Contracts/Commercial Applications 1/FirstMolniyaSat-CA.cfg b/GameData/RP-1/Contracts/Commercial Applications 1/FirstMolniyaSat-CA.cfg index cd1441ef0f4..31baf00a2a5 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 1/FirstMolniyaSat-CA.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 1/FirstMolniyaSat-CA.cfg @@ -5,7 +5,7 @@ CONTRACT_TYPE group = CommApp agent = Federation Aeronautique Internationale - description = Program: Early Commercial Applications
Type: Required

A Molniya orbit is a type of highly elliptical orbit with an inclination of 63.4 degrees, an argument of perigee of -90 degrees, and an orbital period of one half of a sidereal day. This keeps the satellite mostly to the northern hemisphere of the Earth. Place a satellite into a Molniya orbit.

There will be an orbit showing in the map view and tracking station. You do not have to place the satellite into this orbit, but it is instead meant to show you where your perigee and apogee should approximately be located, but more importantly, it shows the proper shape of the orbit.

Historical example: Molniya 1-1 (1,600kg, Molniya)

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. + description = Program: Early Commercial Applications
Type: Required

A Molniya orbit is a type of highly elliptical orbit with an inclination of 63.4 degrees, an argument of perigee of -90 (270) degrees, and an orbital period of one half of a sidereal day. This keeps the satellite mostly to the northern hemisphere of the Earth. Place a satellite into a Molniya orbit.

There will be an orbit showing in the map view and tracking station. You do not have to place the satellite into this orbit, but it is instead meant to show you where your perigee and apogee should approximately be located, but more importantly, it shows the proper shape of the orbit.

Historical example: Molniya 1-1 (1,600kg, Molniya)

NOTE: The satellite will be destroyed upon completion of the contract. This simulates transfer of the payload back to the customer. synopsis = Launch a satellite into a Molniya orbit diff --git a/GameData/RP-1/Programs/Programs.cfg b/GameData/RP-1/Programs/Programs.cfg index 874bb5e92c5..b77563436a7 100644 --- a/GameData/RP-1/Programs/Programs.cfg +++ b/GameData/RP-1/Programs/Programs.cfg @@ -699,7 +699,7 @@ RP0_PROGRAM name = CrewedOrbitEarly isHSF = true title = Crewed Orbit - description = Sending machines to space as a proxy for human beings was never the final goal. This program requires you to safely put astronauts into orbit and return them to the Earth, proving that humanity can survive in the most hostile environment nature has given us the opportunity to explore. + description = Sending machines to space as a proxy for human beings was never the final goal. This program requires you to safely put astronauts into orbit and return them to the Earth, proving that humanity can survive in the most hostile environment nature has given us the opportunity to explore. You will need to upgrade your Astronaut Complex to level three so you can train your astronauts for the rigors of spaceflight. Make sure you start to train your crew about a year before you launch. requirementsPrettyText = Complete one of the Early Satellites Programs objectivesPrettyText = Complete the program by putting an astronaut into orbit and returning them. nominalDurationYears = 4 diff --git a/Source/Tech Tree/Parts Browser/data/SXT.json b/Source/Tech Tree/Parts Browser/data/SXT.json index 257c2ee5617..012f7b684ec 100644 --- a/Source/Tech Tree/Parts Browser/data/SXT.json +++ b/Source/Tech Tree/Parts Browser/data/SXT.json @@ -653,7 +653,7 @@ { "name": "SXTAirbag", "title": "Mk10-XL Inflatable Airbag", - "description": "A set of inflatable balloons that can handle impacts of moderate speed on planetary surfaces. These airbags are well suited for landing small landers and probes on rough terrain when a skycrane or internal propulsion is lacking or imprecise. First used on Russian Luna landers like Luna 9, airbags served well as Mars landing systems during various missions.", + "description": "A more advanced alternative to the Mk-10 landing system. Rather stronger.", "mod": "SXT", "cost": 200, "entry_cost": 20000, @@ -676,7 +676,7 @@ { "name": "SXTAirbagSmall", "title": "Mk-10 Inflatable Airbag", - "description": "A more advanced alternative to the Mk-10 landing system. Rather stronger.", + "description": "A set of inflatable balloons that can handle impacts of moderate speed on planetary surfaces. These airbags are well suited for landing small landers and probes on rough terrain when a skycrane or internal propulsion is lacking or imprecise. First used on Russian Luna landers like Luna 9, airbags served well as Mars landing systems during various missions.", "mod": "SXT", "cost": 150, "entry_cost": 15000, @@ -1136,7 +1136,7 @@ { "name": "SXTISSHabISK30", "title": "Skylab Orbital Workshop", - "description": "Hold 8 peole with 155 days (5 months) of supplies. A large crew compartment designed for larger, more permanent space stations. Designed and launched in 1973, the Skylab orbital station was the wider space station ever. Given the 270m3 pressurised volume, there is plenty of room for all your IVA activies. It even features a orbital laboratory!", + "description": "Hold 8 peole with 155 days (5 months) of supplies. A large crew compartment designed for larger, more permanent space stations. Designed and launched in 1973, the Skylab orbital station was the widest space station ever. Given the 270m3 pressurised volume, there is plenty of room for all your IVA activies. It even features a orbital laboratory!", "mod": "SXT", "cost": 17400, "entry_cost": 200000, From 7ba2ff05e49871402c512e739af890b54c8d5e6d Mon Sep 17 00:00:00 2001 From: "Wren [Undefined]" Date: Fri, 12 Jul 2024 19:56:33 -0500 Subject: [PATCH 10/14] Parts Browser: Run queued changes in reverse (#2387) This prevents an edge case I encountered where the following occurs: - The user creates a new part, and forgets to add certain info (in my case, I forgot to check the "RP-1" box), and presses "Queue Changes" - The user edits that part - The user presses "Commit to JSON" - Operation fails, console shows exception: ``` Traceback (most recent call last): File "flask\app.py", line 2190, in wsgi_app File "flask\app.py", line 1486, in full_dispatch_request File "flask\app.py", line 1484, in full_dispatch_request File "flask\app.py", line 1469, in dispatch_request File "app.py", line 168, in commit_changes part_data.add_new_part(part) File "part_data.py", line 25, in add_new_part print(f'Adding new part with name: {new_part["name"]}') ~~~~~~~~^^^^^^^^ KeyError: 'name' ``` This is because the "edit" queued change is executed before the part is even created, causing issues. Running queued changes in reverse should prevent any issues with this in most cases, assuming the browser/frontend is sane and does not randomly order queued changes. --- Source/Tech Tree/Parts Browser/app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Tech Tree/Parts Browser/app.py b/Source/Tech Tree/Parts Browser/app.py index 97b237caf04..31b19dfedf6 100644 --- a/Source/Tech Tree/Parts Browser/app.py +++ b/Source/Tech Tree/Parts Browser/app.py @@ -145,7 +145,7 @@ def reload_data(): @app.route('/api/commit_changes', methods=['POST']) def commit_changes(): queued_changes = request.get_json() - for row_id in queued_changes['queued_changes']: + for row_id in reversed(queued_changes['queued_changes']): new_part = False part = None # if the part name changed, we need to use the old name to find it, else use the supplied name field @@ -219,4 +219,4 @@ def ecm_tree(): if __name__ == "__main__": - create_app() \ No newline at end of file + create_app() From a76d4614d93e1be03c3e40032f568ac5648a7593 Mon Sep 17 00:00:00 2001 From: Clayell <125416952+Clayell@users.noreply.github.com> Date: Fri, 12 Jul 2024 20:57:10 -0400 Subject: [PATCH 11/14] Buff Molniya repeatable contract reward (#2388) * Update RFTechLevels.cfg * Update EarlyComNetwork3-CA.cfg * Update FirstMolniyaSat-CA.cfg make AOP more clear and in line with the objectives that state it must be between 220 and 320 * Update Programs.cfg make it more clear on the reasoning behind upgrading AC to 3 * scale molniya reward by 10 to make rep and confidence more in line with normal com sat contracts * Update EarlyMolniyaSat.cfg * Update EarlyMolniyaSat.cfg * Update EarlyComNetwork3-CA.cfg * Update FirstMolniyaSat-CA.cfg * Update Programs.cfg i am not very good at github lol * Update EarlyMolniyaSat.cfg * Update Programs.cfg how did i even delete this * Update Programs.cfg * woops, wrong spot --- .../Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg index 7d8eeffba06..bc71cb59a61 100644 --- a/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg +++ b/GameData/RP-1/Contracts/Commercial Applications 1/EarlyMolniyaSat.cfg @@ -30,7 +30,7 @@ CONTRACT_TYPE advanceFunds = 0 rewardFunds = 0 rewardScience = 0 - rewardReputation = Round(55 * Pow(@EarlyMolniya/ReachOrbit/minPeA / 6000000, 0.5) * Pow((@EarlyMolniya/HasComSatPayload/minQuantity / 325), 0.5) * @rewardFactor, 1) + rewardReputation = Round(55 * Pow(@EarlyMolniya/ReachOrbit/minPeA / 6000000, 0.5) * Pow(((@EarlyMolniya/HasComSatPayload/minQuantity * 10) / 325), 0.5) * @rewardFactor, 1) // pretend to have 10x the payload to make the reward line up with comsat repeatable, which requires about the same tonnage to orbit failureReputation = 0 // was @rewardReputation failureFunds = 0 From 44a22392c4fc6b78b3eaece0769430a8dbb4452c Mon Sep 17 00:00:00 2001 From: siimav <1120038+siimav@users.noreply.github.com> Date: Sat, 13 Jul 2024 03:57:33 +0300 Subject: [PATCH 12/14] Change pad reconditioning to be independent from other LC operations (#2391) --- .../LaunchComplex/LaunchComplex.cs | 13 +- .../RP0/SpaceCenter/Projects/LCOpsProject.cs | 5 +- .../Projects/ReconRolloutProject.cs | 21 ++- .../Projects/VesselRepairProject.cs | 2 + .../RP0/SpaceCenter/SpaceCenterManagement.cs | 157 ++++++++++-------- Source/RP0/UI/KCT/GUI_Editor.cs | 6 +- Source/RP0/UI/KCT/GUI_NewLC.cs | 2 +- Source/RP0/UI/MaintenanceGUI.cs | 2 +- Source/RP0/Utilities/Formula.cs | 12 +- 9 files changed, 134 insertions(+), 86 deletions(-) diff --git a/Source/RP0/SpaceCenter/LaunchComplex/LaunchComplex.cs b/Source/RP0/SpaceCenter/LaunchComplex/LaunchComplex.cs index 3d212495a42..69e4979fc49 100644 --- a/Source/RP0/SpaceCenter/LaunchComplex/LaunchComplex.cs +++ b/Source/RP0/SpaceCenter/LaunchComplex/LaunchComplex.cs @@ -211,12 +211,13 @@ public int LaunchPadCount public bool IsEmpty => LCType == LaunchComplexType.Hangar && BuildList.Count == 0 && Warehouse.Count == 0 && Engineers == 0 && LCData.StartingHangar.Compare(this); - public bool IsActive => BuildList.Count > 0 || GetAllLCOps().Any(op => !op.IsComplete()); - public bool CanDismantle => BuildList.Count == 0 && Warehouse.Count == 0 && - !Recon_Rollout.Any(r => r.RRType != ReconRolloutProject.RolloutReconType.Reconditioning) && - VesselRepairs.Count == 0; - public bool CanModifyButton => BuildList.Count == 0 && Warehouse.Count == 0 && Recon_Rollout.Count == 0 && VesselRepairs.Count == 0; - public bool CanModifyReal => Recon_Rollout.Count == 0 && VesselRepairs.Count == 0; + public bool IsActive => BuildList.Count > 0 || GetAllLCOps().Any(op => !op.IsComplete() && op.KeepsLCActive); + public bool CanDismantle => CanModifyButton; + public bool CanModifyButton => BuildList.Count == 0 && Warehouse.Count == 0 && + !Recon_Rollout.Any(r => r.RRType != ReconRolloutProject.RolloutReconType.Reconditioning) && + VesselRepairs.Count == 0; + public bool CanModifyReal => !Recon_Rollout.Any(r => r.RRType != ReconRolloutProject.RolloutReconType.Reconditioning) && + VesselRepairs.Count == 0; public bool CanIntegrate => ProjectBPTotal == 0d; private double _projectBPTotal = -1d; diff --git a/Source/RP0/SpaceCenter/Projects/LCOpsProject.cs b/Source/RP0/SpaceCenter/Projects/LCOpsProject.cs index c3203c37341..6a706abfa1d 100644 --- a/Source/RP0/SpaceCenter/Projects/LCOpsProject.cs +++ b/Source/RP0/SpaceCenter/Projects/LCOpsProject.cs @@ -22,6 +22,7 @@ public abstract class LCOpsProject : ConfigNodePersistenceBase, ISpaceCenterProj public abstract TransactionReasonsRP0 TransactionReason { get; } protected abstract TransactionReasonsRP0 transactionReasonTime { get; } + public abstract bool KeepsLCActive { get; } public VesselProject AssociatedVP => KCTUtilities.FindVPByID(LC, AssociatedIdAsGuid); @@ -96,7 +97,7 @@ protected double GetBaseBuildRate() return _buildRate; } - protected double CalculateBuildRate(int delta) + protected virtual double CalculateBuildRate(int delta) { double rate; if (IsCapped) @@ -150,7 +151,7 @@ public double GetTimeLeft() private double TimeLeftWithEfficiencyIncrease(double timeLeft) { - if (LC.Efficiency == LCEfficiency.MaxEfficiency || timeLeft < 86400d) + if (LC.Efficiency == LCEfficiency.MaxEfficiency || timeLeft < 86400d || LC.Engineers == 0) return timeLeft; double bpDivRate = timeLeft * LC.Efficiency; diff --git a/Source/RP0/SpaceCenter/Projects/ReconRolloutProject.cs b/Source/RP0/SpaceCenter/Projects/ReconRolloutProject.cs index c577180ef75..f62d5551d73 100644 --- a/Source/RP0/SpaceCenter/Projects/ReconRolloutProject.cs +++ b/Source/RP0/SpaceCenter/Projects/ReconRolloutProject.cs @@ -88,6 +88,7 @@ public ReconRolloutProject(Vessel vessel, RolloutReconType type, string id, stri var vp = new VesselProject(vessel, ProjectType.VAB); isHumanRated = vp.humanRated; BP = Formula.GetReconditioningBP(vp); + cost = Formula.GetReconditioningCost(vp); vesselBP = vp.buildPoints; } catch @@ -126,6 +127,7 @@ public ReconRolloutProject(VesselProject vessel, RolloutReconType type, string i { case RolloutReconType.Reconditioning: BP = Formula.GetReconditioningBP(vessel); + cost = Formula.GetReconditioningCost(vessel); break; case RolloutReconType.Rollout: @@ -174,7 +176,10 @@ public void SwitchDirection() public override bool IsReversed => RRType == RolloutReconType.Rollback || RRType == RolloutReconType.AirlaunchUnmount; - public override bool HasCost => RRType == RolloutReconType.Rollout || RRType == RolloutReconType.AirlaunchMount; + public override bool HasCost => RRType == RolloutReconType.Rollout || RRType == RolloutReconType.AirlaunchMount || + RRType == RolloutReconType.Reconditioning; + + public override bool KeepsLCActive => RRType != RolloutReconType.Reconditioning; public override ProjectType GetProjectType() { @@ -183,7 +188,6 @@ public override ProjectType GetProjectType() case RolloutReconType.AirlaunchMount: case RolloutReconType.AirlaunchUnmount: return ProjectType.AirLaunch; - default: return ProjectType.Reconditioning; } @@ -193,6 +197,19 @@ public override void Load(ConfigNode node) { base.Load(node); } + + protected override double CalculateBuildRate(int delta) + { + if (RRType == RolloutReconType.Reconditioning) + { + bool isHRCapped = IsCapped && !isHumanRated && LC.IsHumanRated; + return Formula.GetReconditioningBuildRate(LC, isHRCapped); + } + else + { + return base.CalculateBuildRate(delta); + } + } } } diff --git a/Source/RP0/SpaceCenter/Projects/VesselRepairProject.cs b/Source/RP0/SpaceCenter/Projects/VesselRepairProject.cs index 5c7acce0b6b..62a75a7638a 100644 --- a/Source/RP0/SpaceCenter/Projects/VesselRepairProject.cs +++ b/Source/RP0/SpaceCenter/Projects/VesselRepairProject.cs @@ -15,6 +15,8 @@ public class VesselRepairProject : LCOpsProject protected override TransactionReasonsRP0 transactionReasonTime => TransactionReasonsRP0.RateRollout; + public override bool KeepsLCActive => false; + public override ProjectType GetProjectType() => ProjectType.VesselRepair; public VesselRepairProject() : base() diff --git a/Source/RP0/SpaceCenter/SpaceCenterManagement.cs b/Source/RP0/SpaceCenter/SpaceCenterManagement.cs index e7e894782bd..0b5c0a09401 100644 --- a/Source/RP0/SpaceCenter/SpaceCenterManagement.cs +++ b/Source/RP0/SpaceCenter/SpaceCenterManagement.cs @@ -34,6 +34,7 @@ public class SpaceCenterManagement : ScenarioModule public static bool EditorShipEditingMode = false; public static double EditorRolloutCost = 0; + public static double EditorReconditionCost = 0; public static double EditorRolloutBP = 0; public static double EditorUnlockCosts = 0; public static double EditorToolingCosts = 0; @@ -942,7 +943,7 @@ public double GetBudgetDelta(double deltaTime) double averageSubsidyPerDay = CurrencyUtils.Funds(TransactionReasonsRP0.Subsidy, MaintenanceHandler.GetAverageSubsidyForPeriod(deltaTime)) * (1d / 365.25d); double fundDelta = Math.Min(0d, MaintenanceHandler.Instance.UpkeepPerDayForDisplay + averageSubsidyPerDay) * deltaTime * (1d / 86400d) - + GetConstructionCostOverTime(deltaTime) + GetRolloutCostOverTime(deltaTime) + + GetConstructionCostOverTime(deltaTime) + GetReconRolloutCostOverTime(deltaTime) + Programs.ProgramHandler.Instance.GetDisplayProgramFunding(deltaTime); return fundDelta; @@ -980,51 +981,53 @@ public double GetConstructionCostOverTime(double time, string kscName) return 0d; } - public double GetRolloutCostOverTime(double time) + public double GetReconRolloutCostOverTime(double time) { double delta = 0; foreach (var ksc in KSCs) { - delta += GetRolloutCostOverTime(time, ksc); + delta += GetReconRolloutCostOverTime(time, ksc); } return delta; } - public double GetRolloutCostOverTime(double time, LCSpaceCenter ksc) + public double GetReconRolloutCostOverTime(double time, LCSpaceCenter ksc) { double delta = 0; for (int i = 0; i < ksc.LaunchComplexes.Count; ++i) - delta += GetRolloutCostOverTime(time, ksc.LaunchComplexes[i]); + delta += GetReconRolloutCostOverTime(time, ksc.LaunchComplexes[i]); return delta; } - public double GetRolloutCostOverTime(double time, LaunchComplex lc) + public double GetReconRolloutCostOverTime(double time, LaunchComplex lc) { double delta = 0; foreach (var rr in lc.Recon_Rollout) { - if (rr.RRType != ReconRolloutProject.RolloutReconType.Rollout && rr.RRType != ReconRolloutProject.RolloutReconType.AirlaunchMount) - continue; - - double t = rr.GetTimeLeft(); - double fac = 1d; - if (t > time) - fac = time / t; + if (rr.RRType == ReconRolloutProject.RolloutReconType.Rollout || + rr.RRType == ReconRolloutProject.RolloutReconType.Reconditioning || + rr.RRType == ReconRolloutProject.RolloutReconType.AirlaunchMount) + { + double t = rr.GetTimeLeft(); + double fac = 1d; + if (t > time) + fac = time / t; - delta += CurrencyUtils.Funds(rr.TransactionReason, -rr.cost * (1d - rr.progress / rr.BP) * fac); + delta += CurrencyUtils.Funds(rr.TransactionReason, -rr.cost * (1d - rr.progress / rr.BP) * fac); + } } return delta; } - public double GetRolloutCostOverTime(double time, string kscName) + public double GetReconRolloutCostOverTime(double time, string kscName) { foreach (var ksc in KSCs) { if (ksc.KSCName == kscName) { - return GetRolloutCostOverTime(time, ksc); + return GetReconRolloutCostOverTime(time, ksc); } } @@ -1453,6 +1456,7 @@ private void RecalculateEditorBuildTime(ShipConstruct ship) if (EditorDriver.editorFacility == EditorFacility.VAB) { EditorRolloutCost = Formula.GetRolloutCost(EditorVessel); + EditorReconditionCost = Formula.GetReconditioningCost(EditorVessel); EditorRolloutBP = Formula.GetRolloutBP(EditorVessel); } else @@ -1548,68 +1552,13 @@ public void ProgressBuildTime(double UTDiff) remainingUT = UTDiff - passes * 86400d; ++passes; } - int rushingEngs = 0; - int totalEngineers = 0; foreach (LCSpaceCenter ksc in KSCs) { - totalEngineers += ksc.Engineers; - for (int j = ksc.LaunchComplexes.Count - 1; j >= 0; j--) { LaunchComplex currentLC = ksc.LaunchComplexes[j]; - if (!currentLC.IsOperational || currentLC.Engineers == 0 || !currentLC.IsActive) - continue; - - double portionEngineers = currentLC.Engineers / (double)currentLC.MaxEngineers; - - if (currentLC.IsRushing) - rushingEngs += currentLC.Engineers; - else - { - for (int p = 0; p < passes; ++p) - { - double timestep = p == 0 ? remainingUT : 86400d; - currentLC.EfficiencySource?.IncreaseEfficiency(timestep, portionEngineers); - } - } - - double timeForBuild = UTDiff; - while (timeForBuild > 0d && currentLC.BuildList.Count > 0) - { - timeForBuild = currentLC.BuildList[0].IncrementProgress(UTDiff); - } - - for (int i = currentLC.Recon_Rollout.Count; i-- > 0;) - { - // These work in parallel so no need to track excess time - // FIXME: that's not _quite_ true, but it's close enough: when one - // completes, the others speed up, but that's hard to deal with here - // so I think we just eat the cost. - var rr = currentLC.Recon_Rollout[i]; - rr.IncrementProgress(UTDiff); - //Reset the associated launchpad id when rollback completes - Profiler.BeginSample("RP0ProgressBuildTime.ReconRollout.FindVPesselByID"); - if (rr.RRType == ReconRolloutProject.RolloutReconType.Rollback && rr.IsComplete() - && KCTUtilities.FindVPByID(rr.LC, rr.AssociatedIdAsGuid) is VesselProject vp) - { - vp.launchSiteIndex = -1; - } - Profiler.EndSample(); - } - - for (int i = currentLC.VesselRepairs.Count; i-- > 0;) - { - var vr = currentLC.VesselRepairs[i]; - vr.IncrementProgress(UTDiff); - if (vr.IsComplete() && HighLogic.LoadedSceneIsFlight && - vr.ApplyRepairs()) - { - currentLC.VesselRepairs.Remove(vr); - } - } - - currentLC.Recon_Rollout.RemoveAll(rr => rr.RRType != ReconRolloutProject.RolloutReconType.Rollout && rr.RRType != ReconRolloutProject.RolloutReconType.AirlaunchMount && rr.IsComplete()); + ProgressLCBuildTime(currentLC, UTDiff, remainingUT, passes); } for (int i = ksc.Constructions.Count; i-- > 0;) @@ -1646,6 +1595,70 @@ public void ProgressBuildTime(double UTDiff) Profiler.EndSample(); } + private static void ProgressLCBuildTime(LaunchComplex currentLC, double UTDiff, double remainingUT, int passes) + { + if (currentLC.IsOperational && currentLC.Engineers > 0 && currentLC.IsActive) + { + double portionEngineers = currentLC.Engineers / (double)currentLC.MaxEngineers; + + if (!currentLC.IsRushing) + { + for (int p = 0; p < passes; ++p) + { + double timestep = p == 0 ? remainingUT : 86400d; + currentLC.EfficiencySource?.IncreaseEfficiency(timestep, portionEngineers); + } + } + + double timeForBuild = UTDiff; + while (timeForBuild > 0d && currentLC.BuildList.Count > 0) + { + timeForBuild = currentLC.BuildList[0].IncrementProgress(UTDiff); + } + + for (int i = currentLC.Recon_Rollout.Count; i-- > 0;) + { + // These work in parallel so no need to track excess time + // FIXME: that's not _quite_ true, but it's close enough: when one + // completes, the others speed up, but that's hard to deal with here + // so I think we just eat the cost. + var rr = currentLC.Recon_Rollout[i]; + rr.IncrementProgress(UTDiff); + //Reset the associated launchpad id when rollback completes + Profiler.BeginSample("RP0ProgressBuildTime.ReconRollout.FindVPesselByID"); + if (rr.RRType == ReconRolloutProject.RolloutReconType.Rollback && rr.IsComplete() + && KCTUtilities.FindVPByID(rr.LC, rr.AssociatedIdAsGuid) is VesselProject vp) + { + vp.launchSiteIndex = -1; + } + Profiler.EndSample(); + } + + for (int i = currentLC.VesselRepairs.Count; i-- > 0;) + { + var vr = currentLC.VesselRepairs[i]; + vr.IncrementProgress(UTDiff); + if (vr.IsComplete() && HighLogic.LoadedSceneIsFlight && + vr.ApplyRepairs()) + { + currentLC.VesselRepairs.Remove(vr); + } + } + } + else + { + // Process reconditioning even for LCs that have no engineers or are inactive + for (int i = currentLC.Recon_Rollout.Count; i-- > 0;) + { + var rr = currentLC.Recon_Rollout[i]; + if (rr.RRType == ReconRolloutProject.RolloutReconType.Reconditioning) + rr.IncrementProgress(UTDiff); + } + } + + currentLC.Recon_Rollout.RemoveAll(rr => rr.RRType != ReconRolloutProject.RolloutReconType.Rollout && rr.RRType != ReconRolloutProject.RolloutReconType.AirlaunchMount && rr.IsComplete()); + } + #endregion #region Recovery diff --git a/Source/RP0/UI/KCT/GUI_Editor.cs b/Source/RP0/UI/KCT/GUI_Editor.cs index b2a646d6e64..0a79ffb9721 100644 --- a/Source/RP0/UI/KCT/GUI_Editor.cs +++ b/Source/RP0/UI/KCT/GUI_Editor.cs @@ -103,7 +103,11 @@ private static void RenderBuildMode() } if (SpaceCenterManagement.EditorRolloutCost > 0) - GUILayout.Label($"Rollout Cost: √{-CurrencyUtils.Funds(TransactionReasonsRP0.RocketRollout, -SpaceCenterManagement.EditorRolloutCost):N1}"); + { + double rolloutCost = -CurrencyUtils.Funds(TransactionReasonsRP0.RocketRollout, -SpaceCenterManagement.EditorRolloutCost); + double recondCost = -CurrencyUtils.Funds(TransactionReasonsRP0.RocketRollout, -SpaceCenterManagement.EditorReconditionCost); + GUILayout.Label(new GUIContent($"Launch Cost: √{rolloutCost:N1} + √{recondCost:N1}", "Launch costs consist of rollout + pad reconditioning")); + } bool showCredit = false; if (SpaceCenterManagement.EditorUnlockCosts > 0) diff --git a/Source/RP0/UI/KCT/GUI_NewLC.cs b/Source/RP0/UI/KCT/GUI_NewLC.cs index 2058f0a4fee..1f33a4bcb85 100644 --- a/Source/RP0/UI/KCT/GUI_NewLC.cs +++ b/Source/RP0/UI/KCT/GUI_NewLC.cs @@ -816,7 +816,7 @@ private static bool ValidateLCCreationParameters(LCData newLCData, LaunchComplex if (existingLC != null && !existingLC.CanModifyReal) { - ScreenMessages.PostScreenMessage("Please wait for any reconditioning, rollout, rollback, or recovery to complete"); + ScreenMessages.PostScreenMessage("Please wait for any rollout, rollback, or recovery to complete"); RP0Debug.Log($"Can't modify LC, recon_rollout in progress"); return false; } diff --git a/Source/RP0/UI/MaintenanceGUI.cs b/Source/RP0/UI/MaintenanceGUI.cs index 32b8aac6c23..441b5c2ea53 100644 --- a/Source/RP0/UI/MaintenanceGUI.cs +++ b/Source/RP0/UI/MaintenanceGUI.cs @@ -185,7 +185,7 @@ public void RenderSummaryTab() double rolloutCost = 0d; try { - rolloutCost = SpaceCenterManagement.Instance.GetRolloutCostOverTime(PeriodFactor * 86400d); + rolloutCost = SpaceCenterManagement.Instance.GetReconRolloutCostOverTime(PeriodFactor * 86400d); GUILayout.Label("Rollout/Airlaunch Prep", HighLogic.Skin.label, GUILayout.Width(160)); GUILayout.Label(FormatCost(rolloutCost), RightLabel, GUILayout.Width(160)); } diff --git a/Source/RP0/Utilities/Formula.cs b/Source/RP0/Utilities/Formula.cs index 4f0bf86d8ca..95708032e48 100644 --- a/Source/RP0/Utilities/Formula.cs +++ b/Source/RP0/Utilities/Formula.cs @@ -41,7 +41,6 @@ public static double GetVesselBuildRate(int index, LaunchComplex LC, bool isHuma if (index > 0 || !LC.IsOperational) return 0d; - //N = num upgrades, I = rate index, L = VAB/SPH upgrade level, R = R&D level int personnel = Math.Max(0, LC.Engineers + persDelta); if (isHumanRatedCapped) personnel = Math.Min(personnel, LC.MaxEngineersNonHR); @@ -49,6 +48,12 @@ public static double GetVesselBuildRate(int index, LaunchComplex LC, bool isHuma return personnel * _EngineerBPRate * HighLogic.CurrentGame.Parameters.CustomParams().BuildRate; } + public static double GetReconditioningBuildRate(LaunchComplex LC, bool isHumanRatedCapped) + { + int personnel = isHumanRatedCapped ? LC.MaxEngineersNonHR : LC.MaxEngineers; + return personnel * _EngineerBPRate * HighLogic.CurrentGame.Parameters.CustomParams().BuildRate; + } + public static double GetConstructionBuildRate(int index, LCSpaceCenter KSC, SpaceCenterFacility facilityType) { double rate = 1d / 86400d; @@ -104,6 +109,11 @@ public static double GetRolloutCost(VesselProject vessel) return result * 0.5d; } + public static double GetReconditioningCost(VesselProject vessel) + { + return GetRolloutCost(vessel) * 0.2; + } + public static double GetAirlaunchCost(VesselProject vessel) { if (!PresetManager.Instance.ActivePreset.GeneralSettings.Enabled) From 7ca1e8f344136075c0e20a58d3a8985210406cc7 Mon Sep 17 00:00:00 2001 From: Capkirk123 Date: Fri, 12 Jul 2024 20:58:16 -0400 Subject: [PATCH 13/14] Improve NFEX configs (#2393) --- GameData/RP-1/Tree/TREE-Parts.cfg | 61 ++++++++- .../data/Near_Future_Exploration.json | 127 +++++++++++++++++- 2 files changed, 179 insertions(+), 9 deletions(-) diff --git a/GameData/RP-1/Tree/TREE-Parts.cfg b/GameData/RP-1/Tree/TREE-Parts.cfg index 0b5fe6674bc..7e263db82b5 100644 --- a/GameData/RP-1/Tree/TREE-Parts.cfg +++ b/GameData/RP-1/Tree/TREE-Parts.cfg @@ -25759,7 +25759,7 @@ %MODULE[ModuleTagList] { tag = Instruments } } -@PART[nfex-antenna-phased-array-1]:FOR[xxxRP0] +@PART[nfex-antenna-feeder-direct-1]:FOR[xxxRP0] { %TechRequired = interplanetaryComms %cost = 10 @@ -25769,10 +25769,21 @@ %MODULE[ModuleTagList] { tag = Instruments } +} +@PART[nfex-antenna-phased-array-1]:FOR[xxxRP0] +{ + %TechRequired = improvedComms + %cost = 10 + %entryCost = 1000 + RP0conf = true + @description ^=:$: From Near Future Exploration mod + + %MODULE[ModuleTagList] { tag = Instruments } + } @PART[nfex-antenna-phased-array-2]:FOR[xxxRP0] { - %TechRequired = interplanetaryComms + %TechRequired = improvedComms %cost = 10 %entryCost = 1000 RP0conf = true @@ -25783,7 +25794,18 @@ } @PART[nfex-antenna-phased-array-3]:FOR[xxxRP0] { - %TechRequired = interplanetaryComms + %TechRequired = improvedComms + %cost = 10 + %entryCost = 1000 + RP0conf = true + @description ^=:$: From Near Future Exploration mod + + %MODULE[ModuleTagList] { tag = Instruments } + +} +@PART[nfex-antenna-phased-single-3]:FOR[xxxRP0] +{ + %TechRequired = improvedComms %cost = 10 %entryCost = 1000 RP0conf = true @@ -25890,6 +25912,39 @@ %MODULE[ModuleTagList] { tag = Instruments } +} +@PART[nfex-antenna-rover-2]:FOR[xxxRP0] +{ + %TechRequired = unlockParts + %cost = 10 + %entryCost = 1000 + RP0conf = true + @description ^=:$: From Near Future Exploration mod + + %MODULE[ModuleTagList] { tag = Instruments } + +} +@PART[nfex-antenna-rover-3]:FOR[xxxRP0] +{ + %TechRequired = improvedComms + %cost = 10 + %entryCost = 1000 + RP0conf = true + @description ^=:$: From Near Future Exploration mod + + %MODULE[ModuleTagList] { tag = Instruments } + +} +@PART[nfex-antenna-static-mini-1]:FOR[xxxRP0] +{ + %TechRequired = interplanetaryComms + %cost = 10 + %entryCost = 1000 + RP0conf = true + @description ^=:$: From Near Future Exploration mod + + %MODULE[ModuleTagList] { tag = Instruments } + } @PART[nfex-antenna-top-dish-1]:FOR[xxxRP0] { diff --git a/Source/Tech Tree/Parts Browser/data/Near_Future_Exploration.json b/Source/Tech Tree/Parts Browser/data/Near_Future_Exploration.json index bd1801a4b2d..f7e79091f49 100644 --- a/Source/Tech Tree/Parts Browser/data/Near_Future_Exploration.json +++ b/Source/Tech Tree/Parts Browser/data/Near_Future_Exploration.json @@ -23,6 +23,29 @@ "Instruments" ] }, + { + "name": "nfex-antenna-feeder-direct-1", + "title": "F-DA Direct Antenna Feed", + "description": "", + "mod": "Near Future Exploration", + "cost": "10", + "entry_cost": "1000", + "category": "COMMS", + "info": "Dish", + "year": "1961", + "technology": "interplanetaryComms", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "", + "identical_part_name": "", + "module_tags": [ + "Instruments" + ] + }, { "name": "nfex-antenna-phased-array-1", "title": "RA-X1 Phased Relay Antenna", @@ -32,8 +55,8 @@ "entry_cost": 1000, "category": "COMMS", "info": "Dish", - "year": "1961", - "technology": "interplanetaryComms", + "year": "1966", + "technology": "improvedComms", "era": "", "ro": true, "orphan": false, @@ -56,8 +79,8 @@ "entry_cost": 1000, "category": "COMMS", "info": "Dish", - "year": "1961", - "technology": "interplanetaryComms", + "year": "1966", + "technology": "improvedComms", "era": "", "ro": true, "orphan": false, @@ -80,8 +103,8 @@ "entry_cost": 1000, "category": "COMMS", "info": "Dish", - "year": "1961", - "technology": "interplanetaryComms", + "year": "1966", + "technology": "improvedComms", "era": "", "ro": true, "orphan": false, @@ -95,6 +118,29 @@ "Instruments" ] }, + { + "name": "nfex-antenna-phased-single-3", + "title": "PH-3 Phased Array Antenna Element", + "description": "", + "mod": "Near Future Exploration", + "cost": "10", + "entry_cost": "1000", + "category": "COMMS", + "info": "Dish", + "year": "1966", + "technology": "improvedComms", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "", + "identical_part_name": "", + "module_tags": [ + "Instruments" + ] + }, { "name": "nfex-antenna-reflector-giant-1", "title": "RFL-2000 Dish Reflector Array", @@ -311,6 +357,75 @@ "Instruments" ] }, + { + "name": "nfex-antenna-rover-2", + "title": "AX-5 Aerial Micro-Antenna", + "description": "", + "mod": "Near Future Exploration", + "cost": "10", + "entry_cost": "1000", + "category": "COMMS", + "info": "Omni", + "year": "0", + "technology": "unlockParts", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "", + "identical_part_name": "", + "module_tags": [ + "Instruments" + ] + }, + { + "name": "nfex-antenna-rover-3", + "title": "AX-30 High Gain Micro-Antenna", + "description": "", + "mod": "Near Future Exploration", + "cost": "10", + "entry_cost": "1000", + "category": "COMMS", + "info": "Dish", + "year": "1966", + "technology": "improvedComms", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "", + "identical_part_name": "", + "module_tags": [ + "Instruments" + ] + }, + { + "name": "nfex-antenna-static-mini-1", + "title": "DR-1 High Gain Antenna", + "description": "", + "mod": "Near Future Exploration", + "cost": "10", + "entry_cost": "1000", + "category": "COMMS", + "info": "Omni", + "year": "1961", + "technology": "interplanetaryComms", + "ro": true, + "orphan": false, + "rp0_conf": true, + "spacecraft": "", + "engine_config": "", + "upgrade": false, + "entry_cost_mods": "", + "identical_part_name": "", + "module_tags": [ + "Instruments" + ] + }, { "name": "nfex-antenna-top-dish-1", "title": "D-2 Spot Antenna", From 3512de9d830e79e7ba77fe72b657e46211a2bf8c Mon Sep 17 00:00:00 2001 From: Capkirk123 Date: Fri, 12 Jul 2024 20:59:36 -0400 Subject: [PATCH 14/14] Add support for RA TL10 (tracking station lvl 11) (#2396) --- GameData/RP-1/CustomBarnKit.cfg | 14 +++++++------- GameData/RP-1/Tree/CommsTechlevels.cfg | 6 ++++++ GameData/RP-1/Tree/EntryCostModifiers.cfg | 1 + 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/GameData/RP-1/CustomBarnKit.cfg b/GameData/RP-1/CustomBarnKit.cfg index ceacdaa5442..7c7cd042085 100644 --- a/GameData/RP-1/CustomBarnKit.cfg +++ b/GameData/RP-1/CustomBarnKit.cfg @@ -32,14 +32,14 @@ } @TRACKING { - @levels = 10 - @upgradesVisual = 1, 1, 2, 2, 2, 3, 3, 3, 3, 3 - @upgrades = 50000, 50000, 50000, 100000, 175000, 100000, 150000, 1000000, 300000, 300000 + @levels = 11 + @upgradesVisual = 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3 + @upgrades = 50000, 50000, 50000, 100000, 175000, 100000, 150000, 1000000, 300000, 300000, 300000 @unlockedSpaceObjectDiscovery = 8 - @orbitDisplayMode = 2, 3, 3, 3, 3, 3, 3, 3, 3, 3 - @patchesAheadLimit = 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 - @trackedObjectLimit = 0, 1, 2, 3, 4, 5, 6, 8, 10, -1 - @DSNRange = 4.2047e11, 8.4093e11, 1.3329e12, 4.2652e12, 1.3649e13, 4.0946e13, 1.1465e14, 3.6688e14, 5.1363e14, 8.9885e14 + @orbitDisplayMode = 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 + @patchesAheadLimit = 0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 4 + @trackedObjectLimit = 0, 1, 2, 3, 4, 5, 6, 8, 10, -1, -1 + @DSNRange = 4.2047e11, 8.4093e11, 1.3329e12, 4.2652e12, 1.3649e13, 4.0946e13, 1.1465e14, 3.6688e14, 5.1363e14, 8.9885e14, 8.9885e14 @DSNRangeCurve { key = 0 0 0 1 diff --git a/GameData/RP-1/Tree/CommsTechlevels.cfg b/GameData/RP-1/Tree/CommsTechlevels.cfg index c91ed18eceb..a10f5e6bbf0 100644 --- a/GameData/RP-1/Tree/CommsTechlevels.cfg +++ b/GameData/RP-1/Tree/CommsTechlevels.cfg @@ -52,6 +52,12 @@ %techRequired = efficientComms %description = More general improvements. Idle power: 11.7 watts. NOTE: You must purchase this upgrade here before you can use it. } +@PARTUPGRADE[commsTL10]:FOR[RP-0] +{ + %level = 10 + %techRequired = modernComms + %description = More general improvements. Arraying of 32-meter antennas improves Ka-band performance. Idle power: 9.5 watts. NOTE: You must purchase this upgrade here before you can use it. +} @PARTUPGRADE[commsTL*]:FOR[RP-0] { %title = #Comms Tech Level $level$ diff --git a/GameData/RP-1/Tree/EntryCostModifiers.cfg b/GameData/RP-1/Tree/EntryCostModifiers.cfg index 357550f1c79..a16cf142d1f 100644 --- a/GameData/RP-1/Tree/EntryCostModifiers.cfg +++ b/GameData/RP-1/Tree/EntryCostModifiers.cfg @@ -557,6 +557,7 @@ ENTRYCOSTMODS commsTL7 = 200000, commsTL6 // X-band commsTL8 = 100000, commsTL7 commsTL9 = 300000, commsTL8 // K-band + commsTL10 = 100000, commsTL9 // Omni commsOmniLevel1 = 0