Skip to content

Commit b8b5591

Browse files
committed
OAB stage info upgrades
- Sea Level TWR and DeltaV now more accurately calculated - VesselDeltaVCalculationMessage update skipper if it originated from vessel in flight - CelestionBodies selection formatted in a tree-like structure - Log info for SW version detection
1 parent 44d3167 commit b8b5591

File tree

5 files changed

+172
-57
lines changed

5 files changed

+172
-57
lines changed
Lines changed: 96 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using KSP.Game;
2-
using KSP.Sim.Definitions;
2+
using KSP.Sim.impl;
33

44
namespace MicroMod
55
{
@@ -16,7 +16,7 @@ internal bool GetBodies()
1616
if (this.Bodies.Count > 0)
1717
return true;
1818

19-
Dictionary<string, CelestialBodyCore> bodies = GameManager.Instance?.Game?.CelestialBodies?.GetAllBodiesData();
19+
List<CelestialBodyComponent> bodies = GameManager.Instance?.Game?.UniverseModel?.GetAllCelestialBodies();
2020

2121
if (bodies == null || bodies.Count == 0)
2222
return false;
@@ -25,37 +25,118 @@ internal bool GetBodies()
2525
{
2626
this.Bodies.Add(new CelestialBody
2727
{
28-
Name = body.Value.data.bodyName,
29-
GravityASL = body.Value.data.gravityASL,
30-
HasAtmosphere = body.Value.data.hasAtmosphere,
31-
IsHomeWorld = body.Value.data.isHomeWorld
28+
Name = body.Name,
29+
DisplayName = body.Name,
30+
GravityASL = body.gravityASL,
31+
HasAtmosphere = body.hasAtmosphere,
32+
IsHomeWorld = body.isHomeWorld,
33+
CelestialBodyComponent = body,
3234
});
3335
}
3436

37+
// Reorder and format all celestial bodies so they form a tree-like structure
38+
TryReorderBodies();
39+
3540
return true;
3641
}
3742

43+
private void TryReorderBodies()
44+
{
45+
// Grab all stars in CelestialBodies
46+
List<CelestialBodyComponent> stars = Bodies
47+
.Select(b => b.CelestialBodyComponent)
48+
.Where(c => c.IsStar)
49+
.ToList();
50+
51+
if (stars == null || stars.Count == 0)
52+
return;
53+
54+
List<CelestialBody> reorderedBodies = new();
55+
56+
// Iterate through all stars and grab all planets and moons that are orbiting them
57+
foreach (var star in stars)
58+
{
59+
reorderedBodies.AddRange(InstantiateCelestialBodies(star, 0));
60+
}
61+
62+
this.Bodies = reorderedBodies;
63+
}
64+
65+
/// <summary>
66+
/// Instantiates a list of planets and moons in the CelestialBodyComponent + bodies that are orbiting it
67+
/// </summary>
68+
/// <param name="cel"></param>
69+
/// <param name="level">Indicates how much indentation format needs to have</param>
70+
/// <returns></returns>
71+
private List<CelestialBody> InstantiateCelestialBodies (CelestialBodyComponent cel, int level)
72+
{
73+
List<CelestialBody> instantiatedBodies = new();
74+
instantiatedBodies.Add(InstantiateCelestialBody(cel, level));
75+
76+
foreach (CelestialBodyComponent body in cel.orbitingBodies)
77+
{
78+
instantiatedBodies.AddRange(InstantiateCelestialBodies(body, level + 1));
79+
}
80+
81+
return instantiatedBodies;
82+
}
83+
84+
85+
/// <summary>
86+
/// Instantiates a single CelestialBody and formats it according to level of indentation
87+
/// </summary>
88+
/// <param name="cel"></param>
89+
/// <param name="level">Indicates how much indentation format needs to have</param>
90+
/// <returns></returns>
91+
private CelestialBody InstantiateCelestialBody(CelestialBodyComponent cel, int level)
92+
{
93+
CelestialBody body = new ()
94+
{
95+
Name = cel.Name,
96+
DisplayName = cel.Name,
97+
GravityASL = cel.gravityASL,
98+
HasAtmosphere = cel.hasAtmosphere,
99+
IsHomeWorld = cel.isHomeWorld,
100+
CelestialBodyComponent = cel,
101+
};
102+
103+
if (cel.isHomeWorld)
104+
body.DisplayName = $"{body.DisplayName} *";
105+
106+
if (level > 0)
107+
{
108+
body.DisplayName = $"└ {body.DisplayName}";
109+
110+
for (int i = 0; i < level; i++)
111+
body.DisplayName = $" {body.DisplayName}";
112+
}
113+
114+
return body;
115+
}
116+
38117
/// <summary>
39118
/// Calculates what factor needs to be used for HomeWorld's TWR in order to compensate for gravity of the selected body
40119
/// </summary>
41120
/// <param name="bodyName">Name of the CelestialBody for which the TWR factor is calculated</param>
42-
/// <returns>TWR factor that needs to be multiplied with HomeWorld's TWR to get TWR at the selected body and information if target body has an atmosphere</returns>
43-
internal (double twrFactor, bool hasAtmosphere) GetTwrFactor(string bodyName)
121+
/// <returns>TWR factor that needs to be multiplied with HomeWorld's TWR to get TWR at the selected body</returns>
122+
internal double GetTwrFactor(string bodyName)
44123
{
45-
if (Bodies.Count == 0) return (0, false);
124+
if (Bodies.Count == 0) return 0;
46125
CelestialBody homeWorld = Bodies.Find(b => b.IsHomeWorld);
47126
CelestialBody targetBody = Bodies.Find(t => t.Name.ToLowerInvariant() == bodyName.ToLowerInvariant()) ?? null;
48-
if (targetBody == null) return (0, false);
127+
if (targetBody == null) return 0;
49128

50-
return (homeWorld.GravityASL / targetBody.GravityASL, targetBody.HasAtmosphere);
129+
return homeWorld.GravityASL / targetBody.GravityASL;
51130
}
52131
}
53132

54133
internal class CelestialBody
55134
{
56-
public string Name;
57-
public double GravityASL;
58-
public bool HasAtmosphere;
59-
public bool IsHomeWorld;
135+
internal string Name;
136+
internal string DisplayName;
137+
internal double GravityASL;
138+
internal bool HasAtmosphere;
139+
internal bool IsHomeWorld;
140+
internal CelestialBodyComponent CelestialBodyComponent;
60141
}
61142
}

MicroEngineerProject/MicroEngineer/MicroEngineerMod.cs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using KSP.UI.Binding;
99
using KSP.Sim.DeltaV;
1010
using KSP.Messages;
11+
using KSP.Sim.impl;
1112

1213
namespace MicroMod
1314
{
@@ -63,8 +64,14 @@ public override void OnInitialized()
6364

6465
// Preserve backward compatibility with SpaceWarp 1.0.1
6566
if (MicroUtility.IsModOlderThan("SpaceWarp", 1, 1, 0))
67+
{
68+
Logger.LogInfo("Space Warp older version detected. Loading old MicroStyles.");
6669
MicroStyles.SetStylesForOldSpaceWarpSkin();
70+
}
71+
else
72+
Logger.LogInfo("Space Warp new version detected. Loading new MicroStyles.");
6773

74+
// Register Flight and OAB buttons
6875
Appbar.RegisterAppButton(
6976
"Micro Engineer",
7077
"BTN-MicroEngineerBtn",
@@ -149,8 +156,12 @@ private void GameStateLeft(MessageCenterMessage obj)
149156
/// </summary>
150157
private void RefreshStagingDataOAB(MessageCenterMessage obj)
151158
{
159+
// Check if message originated from ships in flight. If yes, return.
160+
VesselDeltaVCalculationMessage msg = (VesselDeltaVCalculationMessage)obj;
161+
if (msg.DeltaVComponent.Ship == null || !msg.DeltaVComponent.Ship.IsLaunchAssembly()) return;
162+
152163
MicroUtility.RefreshGameManager();
153-
if (MicroUtility.GameState.GameState != GameState.VehicleAssemblyBuilder) return;
164+
if (MicroUtility.GameState.GameState != GameState.VehicleAssemblyBuilder) return;
154165

155166
MicroUtility.RefreshStagesOAB();
156167

@@ -833,24 +844,23 @@ private void DrawStageInfoOAB(int windowID)
833844
GUILayout.Label(String.Format("{0:00}", ((List<DeltaVStageInfo_OAB>)stageInfoOab.EntryValue).Count - stages[stageIndex].Stage), MicroStyles.NameLabelStyle, GUILayout.Width(40));
834845
GUILayout.FlexibleSpace();
835846

836-
// We calculate what factor needs to be applied to TWR in order to compensate for different gravity of the selected celestial body
837-
// For selected bodies with atmosphere, for ASL TWR we just apply the factor to HomeWorld's (i.e. Kerbin) ASL TWR as it's a good enough approximation for now.
838-
// -> This is just an approximation because ASL TWR depends on Thrust as well which changes depending on atmospheric pressure
839-
(double factor, bool hasAtmosphere) twrFactor = _celestialBodies.GetTwrFactor(stageInfoOab.CelestialBodyForStage[celestialIndex]);
840-
841-
GUILayout.Label(String.Format("{0:N2}", stages[stageIndex].TWRVac * twrFactor.factor), MicroStyles.ValueLabelStyle, GUILayout.Width(65));
847+
// We calculate what factor needs to be applied to TWR in order to compensate for different gravity of the selected celestial body
848+
double twrFactor = _celestialBodies.GetTwrFactor(stageInfoOab.CelestialBodyForStage[celestialIndex]);
849+
GUILayout.Label(String.Format("{0:N2}", stages[stageIndex].TWRVac * twrFactor), MicroStyles.ValueLabelStyle, GUILayout.Width(65));
842850

843-
// If target body doesn't have an atmosphere, its ASL TWR is the same as Vacuum TWR
844-
GUILayout.Label(String.Format("{0:N2}", twrFactor.hasAtmosphere ? stages[stageIndex].TWRASL * twrFactor.factor : stages[stageIndex].TWRVac * twrFactor.factor), MicroStyles.ValueLabelStyle, GUILayout.Width(75));
845-
GUILayout.Label(String.Format("{0:N0}", stages[stageIndex].DeltaVASL), MicroStyles.ValueLabelStyle, GUILayout.Width(75));
851+
// Calculate Sea Level TWR and DeltaV
852+
CelestialBodyComponent cel = _celestialBodies.Bodies.Find(b => b.Name == stageInfoOab.CelestialBodyForStage[celestialIndex]).CelestialBodyComponent;
853+
GUILayout.Label(String.Format("{0:N2}", stages[stageIndex].GetTWRAtSeaLevel(cel) * twrFactor), MicroStyles.ValueLabelStyle, GUILayout.Width(75));
854+
GUILayout.Label(String.Format("{0:N0}", stages[stageIndex].GetDeltaVelAtSeaLevel(cel)), MicroStyles.ValueLabelStyle, GUILayout.Width(75));
846855
GUILayout.Label("m/s", MicroStyles.UnitLabelStyleStageOAB, GUILayout.Width(30));
856+
847857
GUILayout.Label(String.Format("{0:N0}", stages[stageIndex].DeltaVVac), MicroStyles.ValueLabelStyle, GUILayout.Width(75));
848858
GUILayout.Label("m/s", MicroStyles.UnitLabelStyleStageOAB, GUILayout.Width(30));
849859
GUILayout.Label(MicroUtility.SecondsToTimeString(stages[stageIndex].StageBurnTime, true, true), MicroStyles.ValueLabelStyle, GUILayout.Width(110));
850860
GUILayout.Space(20);
851861
GUILayout.BeginVertical();
852862
GUILayout.FlexibleSpace();
853-
if (GUILayout.Button(stageInfoOab.CelestialBodyForStage[celestialIndex], MicroStyles.CelestialSelectionBtnStyle))
863+
if (GUILayout.Button(stageInfoOab.CelestialBodyForStage[celestialIndex], MicroStyles.CelestialBodyBtnStyle))
854864
{
855865
_celestialBodySelectionStageIndex = celestialIndex;
856866
}
@@ -873,7 +883,7 @@ private void DrawCelestialBodySelection(int id)
873883

874884
foreach (var body in _celestialBodies.Bodies)
875885
{
876-
if (GUILayout.Button(body.Name))
886+
if (GUILayout.Button(body.DisplayName, MicroStyles.CelestialSelectionBtnStyle))
877887
{
878888
StageInfo_OAB stageInfoOab = (StageInfo_OAB)MicroWindows.Find(w => w.MainWindow == MainWindow.StageInfoOAB).Entries.Find(e => e.Name == "Stage Info (OAB)");
879889
stageInfoOab.CelestialBodyForStage[_celestialBodySelectionStageIndex] = body.Name;

MicroEngineerProject/MicroEngineer/MicroEntries.cs

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using KSP.Game;
2+
using KSP.Sim.DeltaV;
23
using KSP.Sim.impl;
34
using Newtonsoft.Json;
45
using static KSP.Rendering.Planets.PQSData;
@@ -1403,7 +1404,8 @@ public override void RefreshData()
14031404
ThrustVac = stage.ThrustVac,
14041405
TotalExhaustVelocityASL = stage.TotalExhaustVelocityASL,
14051406
TotalExhaustVelocityActual = stage.TotalExhaustVelocityActual,
1406-
TotalExhaustVelocityVAC = stage.TotalExhaustVelocityVAC
1407+
TotalExhaustVelocityVAC = stage.TotalExhaustVelocityVAC,
1408+
DeltaVStageInfo = stage
14071409
});
14081410
}
14091411
}
@@ -1429,32 +1431,46 @@ internal void AddNewCelestialBody(MicroCelestialBodies celestialBodies)
14291431
/// <summary>
14301432
/// Parameters for one stage
14311433
/// </summary>
1432-
public class DeltaVStageInfo_OAB
1434+
internal class DeltaVStageInfo_OAB
14331435
{
1434-
public double DeltaVActual;
1435-
public double DeltaVASL;
1436-
public double DeltaVVac;
1437-
public double DryMass;
1438-
public double EndMass;
1439-
public double FuelMass;
1440-
public double IspASL;
1441-
public double IspActual;
1442-
public double IspVac;
1443-
public int SeparationIndex;
1444-
public int Stage;
1445-
public double StageBurnTime;
1446-
public double StageMass;
1447-
public double StartMass;
1448-
public float TWRASL;
1449-
public float TWRActual;
1450-
public float TWRVac;
1451-
public float ThrustASL;
1452-
public float ThrustActual;
1453-
public float ThrustVac;
1454-
public float TotalExhaustVelocityASL;
1455-
public float TotalExhaustVelocityActual;
1456-
public float TotalExhaustVelocityVAC;
1457-
public string CelestialBody;
1436+
internal double DeltaVActual;
1437+
internal double DeltaVASL;
1438+
internal double DeltaVVac;
1439+
internal double DryMass;
1440+
internal double EndMass;
1441+
internal double FuelMass;
1442+
internal double IspASL;
1443+
internal double IspActual;
1444+
internal double IspVac;
1445+
internal int SeparationIndex;
1446+
internal int Stage;
1447+
internal double StageBurnTime;
1448+
internal double StageMass;
1449+
internal double StartMass;
1450+
internal float TWRASL;
1451+
internal float TWRActual;
1452+
internal float TWRVac;
1453+
internal float ThrustASL;
1454+
internal float ThrustActual;
1455+
internal float ThrustVac;
1456+
internal float TotalExhaustVelocityASL;
1457+
internal float TotalExhaustVelocityActual;
1458+
internal float TotalExhaustVelocityVAC;
1459+
internal DeltaVStageInfo DeltaVStageInfo;
1460+
1461+
private float GetThrustAtAltitude(double altitude, CelestialBodyComponent cel) => this.DeltaVStageInfo.EnginesActiveInStage?.Select(e => e.Engine.MaxThrustOutputAtm(atmPressure: cel.GetPressure(altitude) / 101.325))?.Sum() ?? 0;
1462+
private double GetISPAtAltitude(double altitude, CelestialBodyComponent cel)
1463+
{
1464+
float sum = 0;
1465+
foreach (DeltaVEngineInfo engInfo in this.DeltaVStageInfo.EnginesActiveInStage)
1466+
sum += engInfo.Engine.MaxThrustOutputAtm(atmPressure: cel.GetPressure(altitude) / 101.325) /
1467+
engInfo.Engine.currentEngineModeData.atmosphereCurve.Evaluate((float)cel.GetPressure(altitude) / 101.325f);
1468+
return GetThrustAtAltitude(altitude, cel) / sum;
1469+
}
1470+
private double GetDeltaVelAlt(double altitude, CelestialBodyComponent cel) => GetISPAtAltitude(altitude, cel) * 9.80665 * Math.Log(this.DeltaVStageInfo.StartMass / this.DeltaVStageInfo.EndMass);
1471+
private double GetTWRAtAltitude(double altitude, CelestialBodyComponent cel) => this.DeltaVStageInfo.TWRVac * (GetThrustAtAltitude(altitude, cel) / this.DeltaVStageInfo.ThrustVac);
1472+
internal double GetTWRAtSeaLevel(CelestialBodyComponent cel) => this.GetTWRAtAltitude(0, cel);
1473+
internal double GetDeltaVelAtSeaLevel(CelestialBodyComponent cel) => GetDeltaVelAlt(0, cel);
14581474
}
14591475
#endregion
14601476
}

MicroEngineerProject/MicroEngineer/MicroStyles.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public static class MicroStyles
88
public static int WindowWidth = 290;
99
public static int WindowHeight = 1440;
1010
public static int WindowWidthStageOAB = 645;
11-
public static int WindowWidthCelestialSelection = 100;
11+
//public static int WindowWidthCelestialSelection = 200;
1212

1313
public static GUISkin SpaceWarpUISkin;
1414
public static GUIStyle MainWindowStyle;
@@ -31,6 +31,7 @@ public static class MicroStyles
3131
public static GUIStyle CloseBtnStyle;
3232
public static GUIStyle CloseBtnStageOABStyle;
3333
public static GUIStyle NormalBtnStyle;
34+
public static GUIStyle CelestialBodyBtnStyle;
3435
public static GUIStyle CelestialSelectionBtnStyle;
3536
public static GUIStyle OneCharacterBtnStyle;
3637
public static GUIStyle TableHeaderLabelStyle;
@@ -84,8 +85,7 @@ public static void InitializeStyles()
8485
CelestialSelectionStyle = new GUIStyle(SpaceWarpUISkin.window)
8586
{
8687
padding = new RectOffset(8, 8, 0, 8),
87-
contentOffset = new Vector2(0, -22),
88-
fixedWidth = WindowWidthCelestialSelection
88+
contentOffset = new Vector2(0, -22)
8989
};
9090

9191
PopoutBtnStyle = new GUIStyle(SpaceWarpUISkin.button)
@@ -175,13 +175,19 @@ public static void InitializeStyles()
175175
alignment = TextAnchor.MiddleCenter
176176
};
177177

178-
CelestialSelectionBtnStyle = new GUIStyle(SpaceWarpUISkin.button)
178+
CelestialBodyBtnStyle = new GUIStyle(SpaceWarpUISkin.button)
179179
{
180180
alignment = TextAnchor.MiddleCenter,
181181
fixedWidth = 80,
182182
fixedHeight = 20
183183
};
184184

185+
CelestialSelectionBtnStyle = new GUIStyle(SpaceWarpUISkin.button)
186+
{
187+
alignment = TextAnchor.MiddleLeft,
188+
fixedWidth = 120
189+
};
190+
185191
OneCharacterBtnStyle = new GUIStyle(SpaceWarpUISkin.button)
186192
{
187193
fixedWidth = 20,

MicroEngineerProject/MicroEngineer/MicroUtility.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ internal static (int major, int minor, int patch)? GetModVersion(string modId)
280280
if (versionNumbers.Length == 3)
281281
int.TryParse(versionNumbers[2], out patchVersion);
282282

283+
Logger.LogInfo($"Space Warp version {majorVersion}.{minorVersion}.{patchVersion} detected.");
284+
283285
return (majorVersion, minorVersion, patchVersion);
284286
}
285287
else return null;

0 commit comments

Comments
 (0)