@@ -8,40 +8,33 @@ namespace RealFuels.Tanks
88{
99 public partial class ModuleFuelTanks : IAnalyticTemperatureModifier , IAnalyticPreview
1010 {
11- public const string BoiloffGroupName = "RFBoiloffDebug" ;
12- public const string BoiloffGroupDisplayName = "#RF_FuelTankRF_Boiloff" ; // "RF Boiloff"
13- protected double totalTankArea ;
14- private double analyticSkinTemp ;
15- private double analyticInternalTemp ;
16- public bool SupportsBoiloff => cryoTanks . Count > 0 ;
17- private readonly Dictionary < string , double > boiloffProducts = new Dictionary < string , double > ( ) ;
11+ public const string CryogenicGroupName = "RFCryogenics" ;
12+ public const string CryogenicsGroupDisplayName = "#RF_FuelTankRF_Cryogenics" ; // "RF Cryogenics"
1813
19- public int numberOfMLILayers = 0 ; // base number of layers taken from TANK_DEFINITION configs
14+ [ KSPField ( guiActiveEditor = true , guiName = "#RF_FuelTankRF_HighlyPressurized" , groupName = guiGroupName ) ] // Highly Pressurized?
15+ public bool highlyPressurized = false ;
2016
21- [ KSPField ( isPersistant = true , guiActiveEditor = true , guiName = "#RF_FuelTankRF_MLILayers" , guiUnits = "#" , guiFormat = "F0" ) , // MLI Layers
17+ [ KSPField ( isPersistant = true , guiActive = true , guiActiveEditor = true , guiName = "#RF_FuelTankRF_MLILayers" ,
18+ groupName = CryogenicGroupName , groupDisplayName = CryogenicsGroupDisplayName , guiFormat = "F0" ) , // MLI Layers
2219 UI_FloatRange ( minValue = 0 , maxValue = 100 , stepIncrement = 1 , scene = UI_Scene . Editor ) ]
2320 public float _numberOfAddedMLILayers = 0 ; // This is the number of layers added by the player.
24- public int numberOfAddedMLILayers { get => ( int ) _numberOfAddedMLILayers ; }
21+ public int numberOfAddedMLILayers => ( int ) _numberOfAddedMLILayers ;
2522
2623 public int totalMLILayers => numberOfMLILayers + numberOfAddedMLILayers ;
2724
28- // for EngineIgnitor integration: store a public dictionary of all pressurized propellants
29- [ NonSerialized ]
30- public Dictionary < string , bool > pressurizedFuels = new Dictionary < string , bool > ( ) ;
31-
32- [ KSPField ( guiActiveEditor = true , guiName = "#RF_FuelTankRF_HighlyPressurized" ) ] // Highly Pressurized?
33- public bool highlyPressurized = false ;
25+ [ KSPField ( isPersistant = true ) ]
26+ protected double totalTankArea ;
3427
35- [ KSPField ( guiName = "#RF_FuelTankRF_WallTemp" , groupName = BoiloffGroupName , groupDisplayName = BoiloffGroupDisplayName , groupStartCollapsed = true ) ] // Wall Temp
28+ [ KSPField ( guiName = "#RF_FuelTankRF_WallTemp" , groupName = CryogenicGroupName ) ] // Wall Temp
3629 public string sWallTemp ;
3730
38- [ KSPField ( guiName = "#RF_FuelTankRF_HeatPenetration" , groupName = BoiloffGroupName ) ] // Heat Penetration
31+ [ KSPField ( guiName = "#RF_FuelTankRF_HeatPenetration" , groupName = CryogenicGroupName ) ] // Heat Penetration
3932 public string sHeatPenetration ;
4033
41- [ KSPField ( guiName = "#RF_FuelTankRF_BoiloffLoss" , groupName = BoiloffGroupName ) ] // Boil-off Loss
34+ [ KSPField ( guiName = "#RF_FuelTankRF_BoiloffLoss" , groupName = CryogenicGroupName ) ] // Boil-off Loss
4235 public string sBoiloffLoss ;
4336
44- [ KSPField ( guiName = "#RF_FuelTankRF_AnalyticCooling" , groupName = BoiloffGroupName ) ] // Analytic Cooling
37+ [ KSPField ( guiName = "#RF_FuelTankRF_AnalyticCooling" , groupName = CryogenicGroupName ) ] // Analytic Cooling
4538 public string sAnalyticCooling ;
4639
4740 private double cooling = 0 ;
@@ -55,19 +48,53 @@ public partial class ModuleFuelTanks : IAnalyticTemperatureModifier, IAnalyticPr
5548 [ KSPField ]
5649 public float MLIArealDensity = 0.000015f ;
5750
58- private static double ConductionFactors => RFSettings . Instance . globalConductionCompensation ? Math . Max ( 1.0d , PhysicsGlobals . ConductionFactor ) : 1d ;
51+ private double analyticSkinTemp ;
52+ private double analyticInternalTemp ;
53+ private readonly Dictionary < string , double > boiloffProducts = new Dictionary < string , double > ( ) ;
54+
55+ public int numberOfMLILayers = 0 ; // base number of layers taken from TANK_DEFINITION configs
56+
57+ private double boiloffMassT = 0d ;
58+ public double BoiloffMassRate => boiloffMassT ;
5959
60- public double BoiloffMassRate => boiloffMass ;
61- private double boiloffMass = 0d ;
62- private readonly List < FuelTank > cryoTanks = new List < FuelTank > ( ) ;
60+ private readonly List < FuelTank > cryoTanks = new List < FuelTank > ( ) ; // anything with maxAmount > 0 && vsp > 0
6361 private readonly List < double > lossInfo = new List < double > ( ) ;
6462 private readonly List < double > fluxInfo = new List < double > ( ) ;
6563
64+ // for EngineIgnitor integration: store a public dictionary of all pressurized propellants
65+ [ NonSerialized ]
66+ public Dictionary < string , bool > pressurizedFuels = new Dictionary < string , bool > ( ) ;
67+
6668 private FlightIntegrator _flightIntegrator ;
6769
6870 double lowestTankTemperature = 300d ;
6971
70- partial void OnLoadRF ( ConfigNode _ ) { }
72+ private static double ConductionFactors => RFSettings . Instance . globalConductionCompensation ? Math . Max ( 1.0d , PhysicsGlobals . ConductionFactor ) : 1d ;
73+ public bool SupportsBoiloff => cryoTanks . Count > 0 ;
74+ private bool IsProcedural => part . Modules . Contains ( "SSTUModularPart" ) || part . Modules . Contains ( "WingProcedural" ) ;
75+
76+ partial void OnLoadRF ( ConfigNode _ ) { }
77+
78+ partial void OnAwakeRF ( )
79+ {
80+ if ( ! HighLogic . LoadedSceneIsEditor ) return ;
81+
82+ // KSP orders PAW fields by Type.GetFields() reflection order. Because ModuleFuelTanks.cs
83+ // compiles before ModuleFuelTanksRF.cs, showUI lands before highlyPressurized. Swap them.
84+ int showUIIdx = - 1 , pressurizedIdx = - 1 ;
85+ for ( int i = 0 ; i < Fields . Count ; i ++ )
86+ {
87+ if ( Fields [ i ] . name == nameof ( showUI ) ) showUIIdx = i ;
88+ else if ( Fields [ i ] . name == nameof ( highlyPressurized ) ) pressurizedIdx = i ;
89+ }
90+
91+ if ( showUIIdx >= 0 && pressurizedIdx >= 0 && showUIIdx < pressurizedIdx )
92+ {
93+ BaseField tmp = Fields [ showUIIdx ] ;
94+ Fields [ showUIIdx ] = Fields [ pressurizedIdx ] ;
95+ Fields [ pressurizedIdx ] = tmp ;
96+ }
97+ }
7198
7299 partial void OnStartRF ( StartState _ )
73100 {
@@ -103,8 +130,6 @@ partial void OnStartRF(StartState _)
103130 GameEvents . onPartDestroyed . Add ( OnPartDestroyed ) ;
104131 }
105132
106- private bool IsProcedural => part . Modules . Contains ( "SSTUModularPart" ) || part . Modules . Contains ( "WingProcedural" ) ;
107-
108133 private void CalculateInsulation ( )
109134 {
110135 Profiler . BeginSample ( "CalculateInsulation" ) ;
@@ -150,8 +175,8 @@ partial void UpdateRF()
150175 if ( HighLogic . LoadedSceneIsFlight && ( RFSettings . Instance . debugBoilOff || RFSettings . Instance . debugBoilOffPAW ) && SupportsBoiloff &&
151176 UIPartActionController . Instance . GetItem ( part ) != null )
152177 {
153- string MLIText = totalMLILayers > 0 ? $ "{ GetMLITransferRate ( part . skinTemperature , part . temperature ) : F4 } " : Localizer . GetStringByTag ( "#RF_FuelTankRF_NoMLI" ) ; // "No MLI"
154- sWallTemp = $ "{ part . temperature : F4 } ({ MLIText } * { part . radiativeArea : F2} m2 )"; //
178+ string MLIText = totalMLILayers > 0 ? $ "{ GetMLITransferRate ( part . skinTemperature , part . temperature ) : F2 } W/m² " : Localizer . GetStringByTag ( "#RF_FuelTankRF_NoMLI" ) ; // "No MLI"
179+ sWallTemp = $ "{ part . temperature : F2 } ({ MLIText } * { part . radiativeArea : F2} m² )"; //
155180 sAnalyticCooling = Utilities . FormatFlux ( cooling ) ;
156181
157182 sHeatPenetration = "" ;
@@ -227,7 +252,7 @@ private void CalculateTankBoiloff(double deltaTime, bool analyticalMode = false,
227252 return ;
228253 }
229254
230- boiloffMass = 0d ;
255+ boiloffMassT = 0d ;
231256 lossInfo . Clear ( ) ;
232257 fluxInfo . Clear ( ) ;
233258
@@ -311,7 +336,7 @@ private void CalculateTankBoiloff(double deltaTime, bool analyticalMode = false,
311336 }
312337 }
313338
314- boiloffMass += massLost ;
339+ boiloffMassT += massLost ;
315340
316341 // subtract heat from boiloff
317342 // subtracting heat in analytic mode is tricky: Analytic flux handling is 'cheaty' and tricky to predict.
@@ -336,7 +361,7 @@ private void CalculateTankBoiloff(double deltaTime, bool analyticalMode = false,
336361 double lossAmount = tank . maxAmount * tank . loss_rate * deltaTemp * deltaTime ;
337362 lossAmount = Math . Min ( lossAmount , tankAmount ) ;
338363 tank . resource . amount -= lossAmount ;
339- boiloffMass += lossAmount * tank . density ;
364+ boiloffMassT += lossAmount * tank . density ;
340365 }
341366 }
342367 }
0 commit comments