diff --git a/OemLoader/MainWindow.cs b/OemLoader/MainWindow.cs index c82c2a8..ef3d125 100644 --- a/OemLoader/MainWindow.cs +++ b/OemLoader/MainWindow.cs @@ -52,13 +52,21 @@ public class MainWindow(string title) orb = Orbit.CreateFromStateCci(childCelestial, simTime, newPosition, newVelocity, orb.OrbitLineColor); } - // Go to the specified time and set the vehicle's orbit to the ephemeris orbit at that time - // (this even works backwards in time, thanks to the patch in UniversePatch!) + // Go to the specified time (thanks to UniversePatch.ApplyVehicleSolversTranspiler this works + // even for negative values of dt) var dt = simTime.Seconds() - Universe.GetElapsedSeconds(); - Universe.CompleteAndApplyPreviousOrbitSolvers(); + // This is similar to the implementation of the stock `simulate` console command, but we + // reset the simulation speed to 1x to avoid the bug in that command where the time step + // gets multiplied by the simulation speed + var step = Universe.GetJobSimStep(dt); + Universe.ApplyVehicleSolvers(); + Universe.ApplyOrbitSolvers(); Universe.ResetSimulationSpeed(); - Universe.ExecuteNextOrbitSolvers(dt); - Universe.CompleteAndApplyPreviousOrbitSolvers(); + Universe.ExecuteNextOrbitSolvers(dt, step); + Universe.ExecuteNextVehicleSolvers(dt, step); + Universe.ApplyVehicleSolvers(); + Universe.ApplyOrbitSolvers(); + // Finally, teleport the vehicle onto the orbit calculated from the ephemeris Program.ControlledVehicle.Teleport(orb, null, null); Log.Debug($"OemLoader: Jumped to time {time} from ephemeris"); } diff --git a/OemLoader/OemLoader.cs b/OemLoader/OemLoader.cs index d4e7f30..f72870e 100644 --- a/OemLoader/OemLoader.cs +++ b/OemLoader/OemLoader.cs @@ -1,6 +1,5 @@ using System.Diagnostics; using System.Reflection; -using Brutal.Numerics; using HarmonyLib; using JetBrains.Annotations; using KSA; @@ -46,13 +45,6 @@ public class OemLoader Log.Info($"OemLoader {Version} loaded"); } - [UsedImplicitly] - [StarMapAfterGui] - public void AfterGui(double dt) - { - Window.Render(); - } - [UsedImplicitly] [StarMapAllModsLoaded] public void FullyLoaded() diff --git a/OemLoader/ProgramPatch.cs b/OemLoader/ProgramPatch.cs index ed3fe01..67e6391 100644 --- a/OemLoader/ProgramPatch.cs +++ b/OemLoader/ProgramPatch.cs @@ -1,4 +1,3 @@ -using Brutal.Numerics; using HarmonyLib; using JetBrains.Annotations; using KSA; @@ -17,4 +16,15 @@ internal static class ProgramPatch { return !OemLoader.Instance?.Window.Typing ?? true; } + + // Since KSA build 4036 we need to draw our UI in the thread safe portion of the frame since we could be + // modifying vehicle state + // FIXME: when StarMap adds proper hooks into OnDrawUiThreadSafe, use that instead of this manual patch + [UsedImplicitly] + [HarmonyPatch("OnDrawUiThreadSafe")] + [HarmonyPostfix] + private static void AfterGuiThreadSafe() + { + OemLoader.Instance?.Window.Render(); + } } \ No newline at end of file diff --git a/OemLoader/UniversePatch.cs b/OemLoader/UniversePatch.cs index 88cb8c4..e106ffe 100644 --- a/OemLoader/UniversePatch.cs +++ b/OemLoader/UniversePatch.cs @@ -14,9 +14,9 @@ internal static class UniversePatch // Without this patch, Universe._achievedSpeedFraction will end up as a large negative value after attempting to // go backwards in time, and stuff will start breaking. [UsedImplicitly] - [HarmonyPatch(nameof(Universe.CompleteAndApplyPreviousOrbitSolvers))] + [HarmonyPatch(nameof(Universe.ApplyVehicleSolvers))] [HarmonyTranspiler] - private static IEnumerable CompleteAndApplyPreviousOrbitSolversTranspiler( + private static IEnumerable ApplyVehicleSolversTranspiler( IEnumerable instructions) { var matcher = new CodeMatcher(instructions);