Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Toggle ground station state based on selected launch site #2395

Merged
merged 2 commits into from
Jul 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 27 additions & 13 deletions Source/RP0/ModIntegrations/KSCSwitcherInterop.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

Expand All @@ -7,10 +8,12 @@ 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;
private static MethodInfo _miKSCSwGetSiteByName;
private static object _kscLoaderInstance; // this is a static singleton
private static object _sites; // instance field in KSCLoader instance but in practice is never changed after parent object creation
private static Dictionary<string, string> _groundStationNameDict = new Dictionary<string, string>();

public const string LegacyDefaultKscId = "Stock";
public const string DefaultKscId = "us_cape_canaveral";
Expand All @@ -26,14 +29,17 @@ public static bool IsKSCSwitcherInstalled
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);
var fiKSCSwInstance = t?.GetField("instance", BindingFlags.Public | BindingFlags.Static);
_kscLoaderInstance = fiKSCSwInstance?.GetValue(null);
var fiKSCSwSites = t?.GetField("Sites", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
_sites = fiKSCSwSites.GetValue(_kscLoaderInstance);

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);
_miKSCSwGetSiteByName = t?.GetMethod("GetSiteByName", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy);

if (_fiKSCSwInstance == null || _fiKSCSwSites == null || _fiKSCSwLastSite == null || _fiKSCSwDefaultSite == null)
if (_kscLoaderInstance == null || _sites == null || _fiKSCSwLastSite == null || _fiKSCSwDefaultSite == null || _miKSCSwGetSiteByName == null)
{
RP0Debug.LogError("Failed to bind to KSCSwitcher");
_isKSCSwitcherInstalled = false;
Expand All @@ -48,18 +54,26 @@ 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;
string lastSite = _fiKSCSwLastSite.GetValue(_sites) as string;

if (lastSite == string.Empty)
lastSite = _fiKSCSwDefaultSite.GetValue(sites) as string;
lastSite = _fiKSCSwDefaultSite.GetValue(_sites) as string;
return lastSite;
}

public static string GetGroundStationForKSC(string kscName)
{
if (!IsKSCSwitcherInstalled) return null;

if (!_groundStationNameDict.TryGetValue(kscName, out string groundStationName))
{
var cn = _miKSCSwGetSiteByName.Invoke(_sites, new object[] { kscName }) as ConfigNode;
groundStationName = cn?.GetValue("groundStation");
_groundStationNameDict[kscName] = groundStationName;
}

return groundStationName;
}
}
}
1 change: 1 addition & 0 deletions Source/RP0/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

[assembly: KSPAssemblyDependency("ModularFlightIntegrator", 1, 0)]
[assembly: KSPAssemblyDependency("RealFuels", 15, 7)]
[assembly: KSPAssemblyDependency("RealAntennas", 2, 4)]
[assembly: KSPAssemblyDependency("ROUtils", 1, 0, 1)]
[assembly: KSPAssemblyDependency("ClickThroughBlocker", 1, 8)]
[assembly: KSPAssemblyDependency("ContractConfigurator", 2, 6)]
Expand Down
3 changes: 3 additions & 0 deletions Source/RP0/RP0.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@
<Reference Include="ModularFlightIntegrator">
<Private>False</Private>
</Reference>
<Reference Include="RealAntennas">
<Private>False</Private>
</Reference>
<Reference Include="RealFuels">
<Private>False</Private>
</Reference>
Expand Down
3 changes: 2 additions & 1 deletion Source/RP0/SpaceCenter/LaunchComplex/LCSpaceCenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public class LCSpaceCenter : IConfigNode
public PersistentObservableList<LCConstructionProject> LCConstructions = new PersistentObservableList<LCConstructionProject>();
[Persistent]
public PersistentObservableList<FacilityUpgradeProject> FacilityUpgrades = new PersistentObservableList<FacilityUpgradeProject>();


public List<ConstructionProject> Constructions = new List<ConstructionProject>();

Expand All @@ -29,6 +28,8 @@ public class LCSpaceCenter : IConfigNode
public const int HangarIndex = 0;
public LaunchComplex Hangar => LaunchComplexes[HangarIndex];

public string AssociatedGroundStation => KSCSwitcherInterop.GetGroundStationForKSC(KSCName);

void added(int idx, ConstructionProject item) { Constructions.Add(item); }
void removed(int idx, ConstructionProject item) { Constructions.Remove(item); }
void updated()
Expand Down
14 changes: 13 additions & 1 deletion Source/RP0/SpaceCenter/SpaceCenterManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public static void ClearVesselEditMode()
[KSPField(isPersistant = true)] public bool DontShowFirstRunAgain = false;
#endregion

public const int VERSION = 8;
public const int VERSION = 9;
[KSPField(isPersistant = true)] public int LoadedSaveVersion = VERSION;

[KSPField(isPersistant = true)] public bool IsFirstStart = true;
Expand Down Expand Up @@ -539,9 +539,15 @@ public override void OnLoad(ConfigNode node)
// Prune bad or inactive KSCs.
for (int i = KSCs.Count; i-- > 0;)
{
bool any = false;
LCSpaceCenter ksc = KSCs[i];
if (ksc.KSCName == null || ksc.KSCName.Length == 0 || (ksc.IsEmpty && ksc != ActiveSC))
{
KSCs.RemoveAt(i);
any = true;
}

if (any) KCTUtilities.RefreshGroundStationActiveState();
}

foreach (var vp in BuildPlans.Values)
Expand All @@ -555,6 +561,11 @@ public override void OnLoad(ConfigNode node)

if (LoadedSaveVersion < VERSION)
{
if (LoadedSaveVersion < 9)
{
KCTUtilities.RefreshGroundStationActiveState();
}

// This upgrades to new payloads
// NOTE this upgrade has to come before other upgrades
// that touch ship nodes, because they will do the UpgradePipeline
Expand Down Expand Up @@ -887,6 +898,7 @@ public void SetActiveKSC(string site)
newKsc = new LCSpaceCenter(site);
newKsc.EnsureStartingLaunchComplexes();
KSCs.Add(newKsc);
KCTUtilities.RefreshGroundStationActiveState();
}

SetActiveKSC(newKsc);
Expand Down
42 changes: 42 additions & 0 deletions Source/RP0/Utilities/KCTUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using KSP.UI.Screens;
using ROUtils;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
Expand Down Expand Up @@ -1517,6 +1518,47 @@ public static void SetFacilityLevel(SpaceCenterFacility scf, int level)
}
}

public static void RefreshGroundStationActiveState()
{
var scInstance = SpaceCenterManagement.Instance;
if (scInstance == null)
{
RP0Debug.LogError("SpaceCenterManagement.Instance is null");
return;
}

if (!RealAntennas.HomeNodeTypes.initialized)
{
static IEnumerator DelayedRefreshRoutine()
{
yield return new WaitForEndOfFrame();
RefreshGroundStationActiveState_Internal();
}
scInstance.StartCoroutine(DelayedRefreshRoutine());
}
else
{
RefreshGroundStationActiveState_Internal();
}
}

private static void RefreshGroundStationActiveState_Internal()
{
if (RealAntennas.HomeNodeTypes.HomeDict.TryGetValue("LaunchSite", out List<RealAntennas.Network.RACommNetHome> lsHomes))
{
RP0Debug.Log("RefreshGroundStationActiveState");
var allActiveKSCStations = SpaceCenterManagement.Instance.KSCs.Select(ksc => ksc.AssociatedGroundStation).ToList();
foreach (RealAntennas.Network.RACommNetHome home in lsHomes)
{
home.enabled = allActiveKSCStations.Contains(home.nodeName);
}
}
else
{
RP0Debug.LogError("Failed to update RA LaunchSite active state");
}
}

private static void ClobberRACommnet()
{
var mInf = CommNetScenario.Instance?.GetType().GetMethod("ApplyTSLevelChange", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);
Expand Down
Loading