Skip to content

Commit

Permalink
Toggle ground station state based on selected launch site (#2395)
Browse files Browse the repository at this point in the history
  • Loading branch information
siimav authored Jul 13, 2024
1 parent 78b0c44 commit d52f6d4
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 15 deletions.
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 @@ -97,7 +97,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 @@ -540,9 +540,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 @@ -556,6 +562,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 @@ -888,6 +899,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

0 comments on commit d52f6d4

Please sign in to comment.