diff --git a/B9PartSwitch/PartSwitch/ModuleModifierInfo.cs b/B9PartSwitch/PartSwitch/ModuleModifierInfo.cs index 910d2da5..12579353 100644 --- a/B9PartSwitch/PartSwitch/ModuleModifierInfo.cs +++ b/B9PartSwitch/PartSwitch/ModuleModifierInfo.cs @@ -139,6 +139,9 @@ public IEnumerable CreatePartModifiers(Part part, PartModule pare yield return new ModuleOutputResourceResetter(module); yield return new ModuleDataHandlerBasic(module, originalNode, dataNode, moduleDataChangedEventDetails); } + else if (module.moduleName == "ModuleFuelTanks") { + yield return new ModuleFuelTanksHandler(module, originalNode, dataNode, moduleDataChangedEventDetails); + } else yield return new ModuleDataHandlerBasic(module, originalNode, dataNode, moduleDataChangedEventDetails); } diff --git a/B9PartSwitch/PartSwitch/PartModifiers/ModuleDataHandlerBasic.cs b/B9PartSwitch/PartSwitch/PartModifiers/ModuleDataHandlerBasic.cs index db2d46a1..373579f3 100644 --- a/B9PartSwitch/PartSwitch/PartModifiers/ModuleDataHandlerBasic.cs +++ b/B9PartSwitch/PartSwitch/PartModifiers/ModuleDataHandlerBasic.cs @@ -8,7 +8,7 @@ public class ModuleDataHandlerBasic : PartModifierBase protected readonly ConfigNode originalNode; protected readonly ConfigNode dataNode; - private readonly BaseEventDetails moduleDataChangedEventDetails; + protected readonly BaseEventDetails moduleDataChangedEventDetails; public ModuleDataHandlerBasic(PartModule module, ConfigNode originalNode, ConfigNode dataNode, BaseEventDetails moduleDataChangedEventDetails) { @@ -34,16 +34,54 @@ public ModuleDataHandlerBasic(PartModule module, ConfigNode originalNode, Config public override void OnWillBeCopiedActiveSubtype() => Deactivate(); public override void OnWasCopiedActiveSubtype() => Activate(); - private void Activate() + protected virtual void Activate() { module.Load(dataNode); module.Events.Send("ModuleDataChanged", moduleDataChangedEventDetails); } - private void Deactivate() + protected virtual void Deactivate() { module.Load(originalNode); module.Events.Send("ModuleDataChanged", moduleDataChangedEventDetails); } } + + public class ModuleFuelTanksHandler : ModuleDataHandlerBasic + { + public ModuleFuelTanksHandler( + PartModule module, ConfigNode originalNode, ConfigNode dataNode, BaseEventDetails moduleDataChangedEventDetails + ) : base(module, originalNode, dataNode, moduleDataChangedEventDetails) + { } + + protected override void Activate() => applyNode(dataNode); + protected override void Deactivate() => applyNode(originalNode); + + private void applyNode(ConfigNode sourceNode) { + double volume = 0; + bool setsVolume = sourceNode.TryGetValue("volume", ref volume); + string type = null; + bool setsType = sourceNode.TryGetValue("type", ref type); + + if (setsVolume) { + // Update the tank volume by sending a volume-change event in the format that Procedural Parts uses. + // Procedural Parts reports the outside volume of the tank in cubic meters (or equivalently, + // kiloliters). ModuleFuelTanks scales the reported volume by the `tankVolumeConversion` and + // `utilization` fields to compute the available internal volume in liters. + // Since the `volume` configuration field is meant to set the available volume in liters directly, + // we need to read the scaling values and apply the inverse scaling to the value that we send. + float scaleFactor = module.Fields.GetValue("tankVolumeConversion"); + float utilization = module.Fields.GetValue("utilization"); + var evtDetails = new BaseEventDetails(BaseEventDetails.Sender.USER); + evtDetails.Set("volName", "Tankage"); + evtDetails.Set("newTotalVolume", volume * 100 / utilization / scaleFactor); + module.part.SendEvent("OnPartVolumeChanged", evtDetails, 0); + } + if (setsType) { + module.Fields.SetValue("type", type); + } + module.Events.Send("ModuleDataChanged", moduleDataChangedEventDetails); + } + } } +