Skip to content

Commit

Permalink
Add option to permanently kill avionics (#2402)
Browse files Browse the repository at this point in the history
  • Loading branch information
siimav authored Aug 20, 2024
1 parent 71b2e9a commit a138792
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 19 deletions.
106 changes: 89 additions & 17 deletions Source/RP0/Avionics/ModuleAvionics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using UniLinq;
using System.Reflection;
using UnityEngine;
using RealAntennas;

namespace RP0
{
Expand Down Expand Up @@ -32,6 +33,9 @@ public class ModuleAvionics : PartModule
[KSPField(isPersistant = true)]
public bool systemEnabled = true;

[KSPField(isPersistant = true, guiActive = true, guiName = "Permanently disabled", groupName = PAWGroup, groupDisplayName = PAWGroup)]
public bool dead = false;

[KSPField]
public string techRequired = "";

Expand All @@ -52,7 +56,7 @@ public class ModuleAvionics : PartModule
protected virtual float GetInternalMassLimit() => massLimit;
protected virtual float GetEnabledkW() => enabledkW;
protected virtual float GetDisabledkW() => disabledkW;
protected virtual bool GetToggleable() => toggleable;
protected virtual bool GetToggleable() => !dead && toggleable;
internal bool TechAvailable => string.IsNullOrEmpty(techRequired) || HighLogic.CurrentGame == null || HighLogic.CurrentGame.Mode == Game.Modes.SANDBOX || ResearchAndDevelopment.GetTechnologyState(techRequired) == RDTech.State.Available;

/// <summary>
Expand All @@ -63,7 +67,7 @@ public float CurrentMassLimit
{
get
{
if (currentlyEnabled && TechAvailable && !IsLockedByInterplanetary)
if (!dead && currentlyEnabled && TechAvailable && !IsLockedByInterplanetary)
return GetInternalMassLimit();
else
return 0f;
Expand Down Expand Up @@ -103,14 +107,18 @@ protected void InitializeResourceRate()
res.rate = 0; // Disable the CommandModule consuming electric charge on init.
}

public float PowerDraw(bool onRails = false) =>
part.protoModuleCrew?.Count > 0 || (systemEnabled && !(GetToggleable() && onRails)) ?
GetEnabledkW() : GetDisabledkW();
public float GetPowerDraw(bool onRails = false)
{
if (dead) return 0;

return part.protoModuleCrew?.Count > 0 || (systemEnabled && !(GetToggleable() && onRails)) ?
GetEnabledkW() : GetDisabledkW();
}

protected void UpdateRate(bool onRails = false)
{
currentlyEnabled = systemEnabled && !(GetToggleable() && onRails);
float currentKW = PowerDraw(onRails);
float currentKW = GetPowerDraw(onRails);
ecConsumption = new KeyValuePair<string, double>(ecName, -currentKW);
currentWatts = currentKW * 1000;
// If requested, let Kerbalism handle power draw, else handle via ModuleCommand resourceHandler.
Expand All @@ -126,15 +134,18 @@ private ModuleResource FindCommandChargeResource() =>

protected virtual void SetActionsAndGui()
{
var toggleAble = GetToggleable();
Events[nameof(ToggleEvent)].guiActive = toggleAble;
Events[nameof(ToggleEvent)].guiActiveEditor = toggleAble;
bool toggleable = GetToggleable();
Events[nameof(ToggleEvent)].guiActive = toggleable;
Events[nameof(ToggleEvent)].guiActiveEditor = toggleable;
Events[nameof(ToggleEvent)].guiName = (systemEnabled ? "Shutdown" : "Activate") + " Avionics";
Events[nameof(ToggleEvent)].active = toggleAble;
Actions[nameof(ActivateAction)].active = (!systemEnabled || HighLogic.LoadedSceneIsEditor) && toggleAble;
Actions[nameof(ShutdownAction)].active = (systemEnabled || HighLogic.LoadedSceneIsEditor) && toggleAble;
Actions[nameof(ToggleAction)].active = toggleAble;
Fields[nameof(currentWatts)].guiActive = toggleAble;
Events[nameof(ToggleEvent)].active = toggleable;
Actions[nameof(ActivateAction)].active = (!systemEnabled || HighLogic.LoadedSceneIsEditor) && toggleable;
Actions[nameof(ShutdownAction)].active = (systemEnabled || HighLogic.LoadedSceneIsEditor) && toggleable;
Actions[nameof(ToggleAction)].active = toggleable;
Fields[nameof(currentWatts)].guiActive = toggleable;
Actions[nameof(KillAction)].active = !dead;
Events[nameof(KillEvent)].guiActive = !dead;
Events[nameof(KillEvent)].active = !dead;
}

protected void StageActivated(int stage)
Expand Down Expand Up @@ -166,6 +177,30 @@ protected IEnumerator CheckRenameDebris()
}
}

/// <summary>
/// Even after disabling ModuleCommand, the vessel will still have comms and be controllable through Kerbalism.
/// If all the antenna PMs are disabled then RA will make sure that the issue is fixed in a permanent way.
/// </summary>
protected void KillAntennasIfLastAvionicsDead()
{
bool anyAlive = false;
List<ModuleAvionics> avionicsModules = part.vessel.FindPartModulesImplementing<ModuleAvionics>();
foreach (ModuleAvionics am in avionicsModules)
{
anyAlive |= !am.dead;
}

if (!anyAlive)
{
List<ModuleRealAntenna> antennaModules = part.vessel.FindPartModulesImplementing<ModuleRealAntenna>();
foreach (ModuleRealAntenna mra in antennaModules)
{
if (mra.Condition != AntennaCondition.Disabled)
mra.PermanentShutdownAction(null);
}
}
}

#endregion

#region Overrides and callbacks
Expand All @@ -181,6 +216,11 @@ public override void OnAwake()
// OnStartFinished() instead of OnStart(), to let ModuleCommand configure itself first.
public override void OnStartFinished(StartState _)
{
if (dead)
{
DisableModuleCommand();
}

InitializeResourceRate();
if (!GetToggleable())
toggleable = false;
Expand Down Expand Up @@ -215,7 +255,7 @@ private void RailChange(Vessel v, bool onRails)
// Too many ways to exit a scene, so always write the Disabled power draw
public override void OnSave(ConfigNode node)
{
node.SetValue(nameof(currentWatts), PowerDraw(true) * 1000);
node.SetValue(nameof(currentWatts), GetPowerDraw(true) * 1000);
}

protected void OnDestroy()
Expand Down Expand Up @@ -256,6 +296,18 @@ public override string GetInfo()
return retStr;
}

protected void DisableModuleCommand()
{
ModuleCommand command = part.FindModuleImplementing<ModuleCommand>();
if (command != null)
{
command.enabled = false;
command.isEnabled = false;
command.moduleIsEnabled = false;
part.isControlSource = Vessel.ControlLevel.NONE;
}
}

#endregion

#region Actions and Events
Expand All @@ -264,12 +316,12 @@ public override string GetInfo()
public void ToggleEvent()
{
systemEnabled = !systemEnabled;
if (part.protoModuleCrew?.Count > 0)
if (!dead && part.protoModuleCrew?.Count > 0)
{
systemEnabled = true;
ScreenMessages.PostScreenMessage("Cannot shut down avionics while crewed");
}
else if (!GetToggleable())
else if (!dead && !GetToggleable())
{
systemEnabled = true;
ScreenMessages.PostScreenMessage("Cannot shut down avionics on this part");
Expand Down Expand Up @@ -299,6 +351,26 @@ public void ActivateAction(KSPActionParam _)
systemEnabled = false;
ToggleEvent();
}

[KSPEvent(guiActive = true, guiActiveEditor = false, guiName = "Disable Avionics permanently", groupName = PAWGroup)]
public void KillEvent()
{
var options = new DialogGUIBase[] {
new DialogGUIButton("Yes", () => KillAction(null)),
new DialogGUIButton("No", () => {})
};
var dialog = new MultiOptionDialog("ConfirmDisableAvionics", "Are you sure you want to permanently disable the avionics unit? Doing this will prevent avionics from consuming power but it will no longer provide any control either.", "Disable Avionics", HighLogic.UISkin, 300, options);
PopupDialog.SpawnPopupDialog(dialog, true, HighLogic.UISkin);
}

[KSPAction("Disable Avionics permanently")]
public void KillAction(KSPActionParam _)
{
dead = true;
DisableModuleCommand();
KillAntennasIfLastAvionicsDead();
ToggleEvent();
}
#endregion

#region Kerbalism
Expand Down
2 changes: 1 addition & 1 deletion Source/RP0/Avionics/ModuleProceduralAvionics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ internal float GetShieldedAvionicsMass(float controllableMass)
private static float GetPolynomial(float value, float exponent, float constant, float factor) => (Mathf.Pow(value, exponent) + constant) * factor;
private static float GetInversePolynomial(float value, float exponent, float constant, float factor) => Mathf.Pow(value / factor - constant, 1 / exponent);

protected override bool GetToggleable() => CurrentProceduralAvionicsTechNode.disabledPowerFactor > 0;
protected override bool GetToggleable() => !dead && CurrentProceduralAvionicsTechNode.disabledPowerFactor > 0;

protected override string GetTonnageString() => "This part can be configured to allow control of vessels up to any mass.";

Expand Down
45 changes: 45 additions & 0 deletions Source/RP0/Harmony/Vessel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using CommNet;
using HarmonyLib;

namespace RP0.Harmony
{
[HarmonyPatch(typeof(Vessel))]
internal class PatchVessel
{
[HarmonyPatch("GetControlLevel")]
internal static bool Prefix_GetControlLevel(Vessel __instance, ref Vessel.ControlLevel __result)
{
if (__instance.isEVA && __instance.crew.Count > 0)
{
if (!__instance.crew[0].inactive)
{
__result = Vessel.ControlLevel.PARTIAL_MANNED;
return false;
}
__result = Vessel.ControlLevel.NONE;
return false;
}

if (__instance.connection != null && CommNetScenario.Instance != null && CommNetScenario.CommNetEnabled)
{
__result = __instance.connection.GetControlLevel();
if (__result == Vessel.ControlLevel.NONE) return false;
}

var controlLevel = Vessel.ControlLevel.NONE;
int count = __instance.parts.Count;
while (count-- > 0)
{
Part part = __instance.parts[count];
if (part.isControlSource > controlLevel)
{
controlLevel = part.isControlSource;
}
}

if (controlLevel < __result) __result = controlLevel;

return false;
}
}
}
2 changes: 1 addition & 1 deletion Source/RP0/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

[assembly: KSPAssemblyDependency("ModularFlightIntegrator", 1, 0)]
[assembly: KSPAssemblyDependency("RealFuels", 15, 7)]
[assembly: KSPAssemblyDependency("RealAntennas", 2, 4)]
[assembly: KSPAssemblyDependency("RealAntennas", 2, 6)]
[assembly: KSPAssemblyDependency("ROUtils", 1, 0, 1)]
[assembly: KSPAssemblyDependency("ClickThroughBlocker", 1, 8)]
[assembly: KSPAssemblyDependency("ContractConfigurator", 2, 6)]
Expand Down
1 change: 1 addition & 0 deletions Source/RP0/RP0.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
<Compile Include="ConfigurableStart\Utilities.cs" />
<Compile Include="Harmony\FlightInputHandler.cs" />
<Compile Include="Harmony\ModuleRCS.cs" />
<Compile Include="Harmony\Vessel.cs" />
<Compile Include="Harmony\RealAntennas.cs" />
<Compile Include="Harmony\ROHeatshields.cs" />
<Compile Include="ModIntegrations\KSCSwitcherInterop.cs" />
Expand Down

0 comments on commit a138792

Please sign in to comment.