Skip to content

Commit

Permalink
Add background EC processing for relays
Browse files Browse the repository at this point in the history
Now HG-5, RA-2, RA-15 and RA-100 consume Electric Charge even in background. It also fixes the "No Power" bug on startup
  • Loading branch information
rockfactory committed Mar 6, 2024
1 parent 0f67de4 commit f311cb7
Show file tree
Hide file tree
Showing 14 changed files with 220 additions and 76 deletions.
7 changes: 4 additions & 3 deletions plugin_template/localizations/commnext_localizations.csv
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Key,Type,Desc,English,Italian,German,French,Spanish,Japanese,Korean,Polish,Russian,Chinese (Simplified),Portuguese (Brazil),Chinese (Traditional)
PartModules/NextRelay/Band,Text,,Band,Banda,Band,Bande,Banda,频段,대역,Przepustka,Диапазон,频段,Banda,频段
PartModules/NextRelay/SecondaryBand,Text,,Secondary Band,Banda Secondaria,Sekundärband,Bande secondaire,Banda secundaria,次要频段,보조 대역,Druga przepustka,Вторичный диапазон,次要频段,Banda secundária,次要频段
PartModules/NextRelay/Name,Text,,Signal Relay,Ripetitore di Segnale,,,,,,,,信号中继,,
PartModules/NextRelay/RelayDescription,Text,,This antenna behaves as a relay,,,,,,,,,这款天线能够中继信号,,
PartModules/NextRelay/Name,Text,,Signal Relay,Ripetitore di Segnale,Signalrelais,Relais de signal,Relé de señal,信号中继,신호 중계기,Przekaźnik sygnału,Ретранслятор,信号中继,Relé de sinal,信号中继
PartModules/NextRelay/RelayDescription,Text,,This antenna behaves as a relay,Questa antenna si comporta da ripetitore,Diese Antenne verhält sich wie ein Relais,Cette antenne se comporte comme un relais,Esta antena se comporta como un relé,此天线作为中继,이 안테나는 중계기로 작동합니다,Ta antena działa jako przekaźnik,Эта антенна работает как реле,这款天线能够中继信号,Esta antena se comporta como um relé,此天线作为中继
CommNext/UI/DistanceLabel,Text,,Distance {0},Distanza {0},Entfernung {0},Distance {0},Distancia {0},距离 {0},거리 {0},Odległość {0},Расстояние {0},距离 {0},Distância {0},距离 {0}
CommNext/UI/Powered,Text,,Powered,Alimentato,Betrieben,Alimenté,Alimentado,供电,전원 공급됨,Zasilany,Питание,供电,Alimentado,供电
CommNext/UI/SignalStrength,Text,,Signal Strength,Intensità del Segnale,Signalstärke,Force du Signal,Potencia de la Señal,信号强度,신호 세기,Siła Sygnału,Уровень сигнала,信号强度,Força do Sinal,信号强度
Expand Down Expand Up @@ -51,4 +51,5 @@ CommNext/UI/TooltipActivateBandRulers,Text,,Toggle this band rulers in Map View,
CommNext/UI/TooltipNoPowerCurrentVessel,Text,,Active vessel has no power,Il veicolo attivo non ha alimentazione,Der aktive Schiff hat keine Stromversorgung,Le vaisseau actif n'a pas d'alimentation,La nave activa no tiene energía,活动船只没有电源,활성 선박에 전원이 없습니다,Aktywny statek nie ma zasilania,Активное судно не имеет питания,活动船只没有电源,A nave ativa não tem energia,活动船只没有电源
CommNext/UI/RulersDisplayModeNone,Text,Rulers display mode: None,Disabled,Disabilitato,Deaktiviert,Désactivé,Desactivado,禁用,비활성화,Dezaktywowane,Отключено,禁用,Desativado,禁用
CommNext/UI/RulersDisplayModeRelays,Text,Rulers display mode: Relays,Only relays,Solo ripetitori,Nur Relais,Seulement les relais,Solo relés,只有中继,릴레이만,Tylko przekaźniki,Только реле,只有中继,Apenas relés,只有中继
CommNext/UI/RulersDisplayModeAll,Text,Rulers display mode: All,All,Tutti,Alle,Tous,Todos,全部,모두,Wszystkie,Все,全部,Todos,全部
CommNext/UI/RulersDisplayModeAll,Text,Rulers display mode: All,All,Tutti,Alle,Tous,Todos,全部,모두,Wszystkie,Все,全部,Todos,全部
PartModules/NextRelay/ElectricCharge,Text,,Electric charge,Carica elettrica,Strom,Charge électrique,Carga eléctrica,电荷,전기 충전,Załadunek elektryczny,Электрический заряд,电荷,Carga elétrica,电荷
8 changes: 4 additions & 4 deletions plugin_template/patches/configs/relay_module.patch
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@
@stage "setup-relays"
:parts #antenna_1v_dish_hg5 {
@include override-range($commnext-RANGE-HG5)
@include add-next-relay()
@include add-next-relay($commnext-EC-HG5)
@include add-next-modulator("DualBand")
}

@stage "setup-relays"
:parts #antenna_0v_dish_ra-2 {
@include override-range($commnext-RANGE-RA2)
@include add-next-relay()
@include add-next-relay($commnext-EC-RA2)
@include add-next-modulator("OmniBand")
}

@stage "setup-relays"
:parts #antenna_0v_dish_ra-15 {
@include override-range($commnext-RANGE-RA15)
@include add-next-relay()
@include add-next-relay($commnext-EC-RA15)
@include add-next-modulator("OmniBand")
}

@stage "setup-relays"
:parts #antenna_1v_dish_ra-100 {
@include override-range($commnext-RANGE-RA100)
@include add-next-relay()
@include add-next-relay($commnext-EC-RA100)
@include add-next-modulator("OmniBand")
}
8 changes: 6 additions & 2 deletions plugin_template/patches/libraries/_constants.patch
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
// -Relays
// Was 36G, now 2G
$commnext-RANGE-RA2: 2000000000.00;
$commnext-EC-RA2: 0.5;
// Was 86G, now 15G
$commnext-RANGE-RA15: 15000000000.00;
$commnext-EC-RA15: 1.0;
// Was 130G, now 100G
$commnext-RANGE-RA100: 100000000000.00;
$commnext-EC-RA100: 2.0;
// Stock HG-5 has 200000000.0 (200M) Make it 5M
$commnext-RANGE-HG5: 5000000.00;
$commnext-EC-HG5: 0.2;

// -Antennas
// Stock command pod has 200000000.0 (200M) range. Make it 5K
Expand All @@ -13,8 +19,6 @@ $commnext-RANGE-POD: 5000.00;
$commnext-RANGE-C16: 500000.00;
// Stock 16S has 200000000.0 (200M) range. Make it 500K
$commnext-RANGE-C16S: 500000.00;
// Stock HG-5 has 200000000.0 (200M) Make it 5M
$commnext-RANGE-HG5: 5000000.00;
// Stock DTS-M1 has 36000000000.0 (36G) range. Make it 2G
$commnext-RANGE-DTS-M1: 2000000000.00;
// Stock HG-55 has 86000000000.0 (86G) range. Make it 15G
Expand Down
9 changes: 7 additions & 2 deletions plugin_template/patches/libraries/_relay_mixins.patch
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@
}
}

@mixin add-next-relay() {
@mixin add-next-relay($ec-rate) {
+Module_NextRelay {
+Data_NextRelay {
+Data_NextRelay {
RequiredResource: {
Rate: $ec-rate,
ResourceName: "ElectricCharge",
AcceptanceThreshold: 0.1
};
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/CommNext/CommNextPlugin.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Reflection;
using BepInEx;
using CommNext.Managers;
using CommNext.Modules.Relay;
using CommNext.Network;
using CommNext.Patches;
using CommNext.Rendering;
Expand Down Expand Up @@ -73,6 +74,11 @@ public override void OnInitialized()
Harmony.CreateAndPatchAll(typeof(TelemetryComponentPatches));
Harmony.CreateAndPatchAll(typeof(SimulationObjectModelPatches));

// EC Background Processing
if (PluginSettings.RelaysRequirePower.Value)
SpaceWarp.API.Parts.PartComponentModuleOverride
.RegisterModuleForBackgroundResourceProcessing<PartComponentModule_NextRelay>();

// UI
MainUIManager.Instance.Initialize();

Expand Down
65 changes: 65 additions & 0 deletions src/CommNext/Modules/Relay/Data_NextRelay.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using BepInEx.Logging;
using CommNext.Network.Bands;
using CommNext.UI;
using CommNext.Utils;
using I2.Loc;
using KSP.Game;
using KSP.Sim;
using KSP.Sim.Definitions;
using KSP.Sim.ResourceSystem;
using KSP.UI.Binding;
using UnityEngine;

Expand Down Expand Up @@ -36,6 +39,26 @@ public override void OnPartBehaviourModuleInit() { }
delegateList.Add(new OABPartData.PartInfoModuleEntry(
"",
s => LocalizedStrings.RelayDescription));

// Add resource consumption info (EC/s)
if (PluginSettings.RelaysRequirePower.Value)
delegateList.Add(new OABPartData.PartInfoModuleEntry(
LocalizationManager.GetTranslation("PartModules/Generic/Tooltip/Resources"),
_ =>
{
var subEntries = new List<OABPartData.PartInfoModuleSubEntry>
{
new(
LocalizedStrings.ElectricCharge,
PartModuleTooltipLocalization.FormatResourceRate(
RequiredResource.Rate,
PartModuleTooltipLocalization.GetTooltipResourceUnits(RequiredResource.ResourceName)
)
)
};
return subEntries;
}));

return delegateList;
}

Expand All @@ -52,4 +75,46 @@ public override void Copy(ModuleData sourceModuleData)
}

#endregion

#region Resources

public override void SetupResourceRequest(ResourceFlowRequestBroker resourceFlowRequestBroker)
{
if (!PluginSettings.RelaysRequirePower.Value) return;

var resourceIDFromName =
GameManager.Instance.Game.ResourceDefinitionDatabase.GetResourceIDFromName(RequiredResource.ResourceName);
if (resourceIDFromName == ResourceDefinitionID.InvalidID)
{
Logger.LogError($"There are no resources with name {RequiredResource.ResourceName}");
return;
}

RequestConfig = new ResourceFlowRequestCommandConfig
{
FlowResource = resourceIDFromName,
FlowDirection = FlowDirection.FLOW_OUTBOUND,
FlowUnits = 0.0
};
RequestHandle = resourceFlowRequestBroker.AllocateOrGetRequest("ModuleCommNextRelay", default);
resourceFlowRequestBroker.SetCommands(
RequestHandle,
1.0,
[RequestConfig]
);
}

// [KSPDefinition]
// [Tooltip("Whether the module consumes resources")]
// public bool UseResources = true;

public bool HasResourcesToOperate = true;

[KSPDefinition]
[Tooltip("Resource required to operate this module if it consumes resources")]
public PartModuleResourceSetting RequiredResource;

public ResourceFlowRequestCommandConfig RequestConfig;

#endregion
}
89 changes: 88 additions & 1 deletion src/CommNext/Modules/Relay/PartComponentModule_NextRelay.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using BepInEx.Logging;
using CommNext.Utils;
using KSP.Game;
using KSP.Modules;
using KSP.Sim.impl;
using KSP.Sim.ResourceSystem;

namespace CommNext.Modules.Relay;

Expand All @@ -17,8 +20,12 @@ public class PartComponentModule_NextRelay : PartComponentModule
/// </summary>
public Data_Transmitter DataTransmitter { get; private set; } = null!;

private Data_NextRelay _dataRelay;
private Data_NextRelay _dataRelay = null!;

// EC management
private FlowRequestResolutionState _returnedRequestResolutionState;
private bool _hasOutstandingRequest;
private bool _lastHasResourcesToOperate;

public override void OnStart(double universalTime)
{
Expand All @@ -30,7 +37,87 @@ public override void OnStart(double universalTime)
return;
}

// Setup the resource request. This will be applied only if the
// `RelayRequiresPower` setting is true.
_dataRelay.SetupResourceRequest(resourceFlowRequestBroker);

Part!.TryGetModuleData<PartComponentModule_DataTransmitter, Data_Transmitter>(out var dataTransmitter);
DataTransmitter = dataTransmitter;
}

public override void OnUpdate(double universalTime, double deltaUniversalTime)
{
ResourceConsumptionUpdate(deltaUniversalTime);
RefreshCommNetIfNecessary();
}

/// <summary>
/// Handles the resource consumption for the relay.
/// </summary>
private void ResourceConsumptionUpdate(double deltaTime)
{
_lastHasResourcesToOperate = _dataRelay.HasResourcesToOperate;

// 1. If the relay doesn't require power, we don't need to do anything.
if (!PluginSettings.RelaysRequirePower.Value || DifficultyUtils.HasInfinitePower)
{
// Just set resources to operate to true and return.
_dataRelay.HasResourcesToOperate = true;
if (resourceFlowRequestBroker.IsRequestActive(_dataRelay.RequestHandle))
resourceFlowRequestBroker.SetRequestInactive(_dataRelay.RequestHandle);

return;
}

// 2. If we have an outstanding request, we need to check if it was accepted.
if (_hasOutstandingRequest)
{
_returnedRequestResolutionState =
resourceFlowRequestBroker.GetRequestState(_dataRelay.RequestHandle);
_dataRelay.HasResourcesToOperate = _returnedRequestResolutionState.WasLastTickDeliveryAccepted;
}

_hasOutstandingRequest = false;

// 3. We need to align Resource request to Enabled state;
// If relay is disabled, stop active request.
// If relay is enabled, trigger request.
switch (_dataRelay.EnableRelay.GetValue())
{
case false when resourceFlowRequestBroker.IsRequestActive(_dataRelay.RequestHandle):
resourceFlowRequestBroker.SetRequestInactive(_dataRelay.RequestHandle);
// TODO Not sure about this one.
_dataRelay.HasResourcesToOperate = false;
break;

case true when resourceFlowRequestBroker.IsRequestInactive(_dataRelay.RequestHandle):
resourceFlowRequestBroker.SetRequestActive(_dataRelay.RequestHandle);
break;
}

if (!_dataRelay.EnableRelay.GetValue()) return;

// 3.1 If the relay is enabled, we need to check if we have enough resources to operate.
_dataRelay.RequestConfig.FlowUnits = (double)_dataRelay.RequiredResource.Rate;
resourceFlowRequestBroker.SetCommands(
_dataRelay.RequestHandle,
1.0,
[_dataRelay.RequestConfig]
);
_hasOutstandingRequest = true;
}

/// <summary>
/// Trigger a refresh of the CommNet node if the relay has resources to operate.
/// </summary>
private void RefreshCommNetIfNecessary()
{
if (_lastHasResourcesToOperate == _dataRelay.HasResourcesToOperate) return;

Logger.LogDebug(
$"Relay '{Part.PartOwner.DisplayName}' has resources to operate: {_dataRelay.HasResourcesToOperate}");

Part.PartOwner.SimulationObject.Telemetry.RefreshCommNetNode();
_lastHasResourcesToOperate = _dataRelay.HasResourcesToOperate;
}
}
Loading

0 comments on commit f311cb7

Please sign in to comment.