Skip to content

Commit

Permalink
Control Range System
Browse files Browse the repository at this point in the history
  • Loading branch information
cheese3660 committed Dec 28, 2023
1 parent e0a3138 commit 394e387
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 5 deletions.
4 changes: 3 additions & 1 deletion plugin_template/localizations/english.csv
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ Key,Type,Desc,English
WMCCModules/Pressurization/Suffocating,Text,,A Kerbal on board ""{0}"" is suffocating!
WMCCModules/Pressurization/Killed,Text,,A Kerbal on board ""{0}"" died due to lack of pressurization
WMCCModules/Pressurized,Text,,Pressurized
WMCCModules/ServiceCeiling,Text,,Service Ceiling
WMCCModules/ServiceCeiling,Text,,Service Ceiling
WMCCModules/ControlRange,Text,,Control Range
WMCCModules/IsControllable,Text,,Is Controllable?
2 changes: 1 addition & 1 deletion plugin_template/swinfo.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"name": "Where's My Crew Capsule (Modules)",
"description": "The modules used for Where's My Crew Capsule",
"source": "https://github.com/cheese3660/WMCCModules",
"version": "0.1.0",
"version": "0.2.0",
"version_check": "https://raw.githubusercontent.com/cheese3660/WMCCModules/main/plugin_template/swinfo.json",
"ksp2_version": {
"min": "0.1.5",
Expand Down
30 changes: 30 additions & 0 deletions src/WMCCModules/Modules/Data_ControlRange.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using KSP.Game.Science;
using KSP.Sim;
using KSP.Sim.Definitions;

namespace WMCCModules.Modules;

public class Data_ControlRange : ModuleData
{
public override Type ModuleType => typeof(Module_ControlRange);


public class ControlRangeDefinition
{
public List<string> RequiredTechs;
public Dictionary<string, HashSet<ScienceSitutation>> AllowedScienceSituations;
public string LocalizationKey;
}

[KSPDefinition]
public List<ControlRangeDefinition> ControlRangeDefinitions;

[KSPState] public Dictionary<string, HashSet<ScienceSitutation>> UnlockedScienceSituations;
[KSPState] public string CurrentLocalizationKey;

[LocalizedField("WMCCModules/ControlRange")] [PAMDisplayControl(SortIndex = 1)]
public ModuleProperty<string> ControlRange = new("", true);

[LocalizedField("WMCCModules/IsControllable")] [PAMDisplayControl(SortIndex = 2)]
public ModuleProperty<bool> IsControllable = new(false, true);
}
59 changes: 59 additions & 0 deletions src/WMCCModules/Modules/Module_ControlRange.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using I2.Loc;
using KSP.Game;
using KSP.Game.Science;
using KSP.Sim.Definitions;

namespace WMCCModules.Modules;

public class Module_ControlRange : PartBehaviourModule
{
public override Type PartComponentModuleType => typeof(PartComponentModule_ControlRange);
private Data_ControlRange _dataControlRange;
public override void AddDataModules()
{
base.AddDataModules();
_dataControlRange ??= new Data_ControlRange();
DataModules.TryAddUnique(_dataControlRange, out _dataControlRange);
}

public override void OnInitialize()
{
if (PartBackingMode == PartBackingModes.Flight)
{
moduleIsEnabled = true;
_dataControlRange.SetVisible(_dataControlRange.IsControllable, true);
}
else
{
_dataControlRange.SetVisible(_dataControlRange.IsControllable, false);
foreach (var definition in _dataControlRange.ControlRangeDefinitions.Where(ComputeControllability))
{
foreach (var (key, value) in definition.AllowedScienceSituations)
{
if (_dataControlRange.UnlockedScienceSituations.TryGetValue(key, out var hs))
{
hs.UnionWith(value);
}
else
{
_dataControlRange.UnlockedScienceSituations.Add(key, new HashSet<ScienceSitutation>(value));
}

_dataControlRange.CurrentLocalizationKey = definition.LocalizationKey;
}
}
}

var str = new LocalizedString(_dataControlRange.CurrentLocalizationKey).ToString() ??
_dataControlRange.CurrentLocalizationKey;
if (str == "") str = _dataControlRange.CurrentLocalizationKey;
_dataControlRange.ControlRange.SetValue(str);
}

private bool ComputeControllability(Data_ControlRange.ControlRangeDefinition definition)
{
if (!GameManager.Instance.GameModeManager.IsGameModeFeatureEnabled("SciencePoints")) return true;
var scienceManager = GameManager.Instance.Game.ScienceManager;
return definition.RequiredTechs.Count == 0 || definition.RequiredTechs.All(tech => scienceManager.IsNodeUnlocked(tech));
}
}
4 changes: 2 additions & 2 deletions src/WMCCModules/Modules/Module_Pressurization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ public class Module_Pressurization : PartBehaviourModule
[SerializeField] protected Data_Pressurization _dataPressurization;
public override Type PartComponentModuleType => typeof(PartComponentModule_Pressurization);

protected override void AddDataModules()
public override void AddDataModules()
{
base.AddDataModules();
_dataPressurization ??= new Data_Pressurization();
DataModules.TryAddUnique(_dataPressurization, out _dataPressurization);
}

protected override void OnInitialize()
public override void OnInitialize()
{
base.OnInitialize();
if (PartBackingMode == PartBackingModes.Flight)
Expand Down
43 changes: 43 additions & 0 deletions src/WMCCModules/Modules/PartComponentModule_ControlRange.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using KSP.Game.Science;
using KSP.Sim.impl;

namespace WMCCModules.Modules;

public class PartComponentModule_ControlRange : PartComponentModule
{
public override Type PartBehaviourModuleType => typeof(Module_ControlRange);
private ResearchLocation _lastResearchLocation = null;
public Data_ControlRange DataControlRange;
private PartComponentModule_Command _componentModuleCommand;
public override void OnStart(double universalTime)
{
if (!DataModules.TryGetByType(out DataControlRange))
{
WMCCModulesPlugin.Instance.SWLogger.LogError(
$"Unable to find a Data_ControlRange in the PartComponentModule_ControlRange for {Part.PartName}");
return;
}

if (!Part.TryGetModule(out _componentModuleCommand))
{
WMCCModulesPlugin.Instance.SWLogger.LogError(
$"Unable to find a PartComponentModule_Command for the PartComponentModule_ControlRange on {Part.PartName}");
}
}

public override void OnUpdate(double universalTime, double deltaUniversalTime)
{
var vessel = Part.PartOwner.SimulationObject.Vessel;
if (vessel.VesselScienceRegionSituation.ResearchLocation.Equals(_lastResearchLocation)) return;
_lastResearchLocation = vessel.VesselScienceRegionSituation.ResearchLocation;
var isControllable = false;

if (DataControlRange.UnlockedScienceSituations.TryGetValue(_lastResearchLocation.BodyName, out var hs))
{
isControllable = hs.Contains(_lastResearchLocation.ScienceSituation);
}

DataControlRange.IsControllable.SetValue(isControllable);
_componentModuleCommand.UpdateControlStatus();
}
}
23 changes: 23 additions & 0 deletions src/WMCCModules/Patches/PartComponentModule_CommandPatch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using HarmonyLib;
using KSP.Sim.Definitions;
using KSP.Sim.impl;
using WMCCModules.Modules;

namespace WMCCModules.Patches;


[HarmonyPatch(typeof(PartComponentModule_Command))]
public class PartComponentModule_CommandPatch
{
[HarmonyPatch(nameof(PartComponentModule_Command.UpdateControlStatus))]
[HarmonyPrefix]
public static bool UpdateControlStatus(PartComponentModule_Command __instance)
{
if (!__instance.Part.Modules.TryGetValue(typeof(PartComponentModule_ControlRange), out var comp)) return true;
var mcr = comp as PartComponentModule_ControlRange;
if (mcr!.DataControlRange.IsControllable.GetValue()) return true;
__instance.dataCommand.controlStatus.SetValue(CommandControlState.NoCommNetConnection);
return false;

}
}
2 changes: 1 addition & 1 deletion src/WMCCModules/WMCCModules.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<PackageReference Include="BepInEx.AssemblyPublicizer.MSBuild" Version="0.4.1" PrivateAssets="all"/>
<PackageReference Include="BepInEx.Core" Version="5.*"/>
<PackageReference Include="HarmonyX" Version="2.10.1"/>
<PackageReference Include="KerbalSpaceProgram2.GameLibs" Version="0.2.0" />
<PackageReference Include="KerbalSpaceProgram2.GameLibs" Version="0.2.0" Publicize="True"/>
<PackageReference Include="SpaceWarp" Version="1.6.0"/>
<PackageReference Include="SpaceWarp.PluginInfoProps" Version="1.*"/>
<PackageReference Include="UnityEngine.Modules" Version="2022.3.5"/>
Expand Down

0 comments on commit 394e387

Please sign in to comment.