1+ using System . Reflection . Emit ;
2+ using HarmonyLib ;
3+ using KSP . Sim . impl ;
4+ using SpaceWarp . API . Logging ;
5+
6+ namespace CommunityFixes . Fix . TimeWarpThrustFix ;
7+
8+ [ Fix ( "Fixes time warp thrust rounding error." ) ]
9+ public class TimeWarpThrustFix : BaseFix
10+ {
11+ private static ILogger _logger ;
12+
13+ public override void OnInitialized ( )
14+ {
15+ _logger = Logger ;
16+ HarmonyInstance . PatchAll ( typeof ( TimeWarpThrustFix ) ) ;
17+ }
18+
19+ private static bool CheckNeedRoundingError ( double positionError , double velocityError )
20+ {
21+ var needError = positionError >= 0.01 || velocityError >= 0.01 ;
22+ if ( needError )
23+ {
24+ _logger . LogDebug ( $ "pos_err={ positionError } , vel_err={ velocityError } ") ;
25+ }
26+
27+ return false ;
28+ }
29+
30+ [ HarmonyPatch ( typeof ( VesselComponent ) , nameof ( VesselComponent . HandleOrbitalPhysicsUnderThrustStart ) ) ]
31+ [ HarmonyTranspiler ]
32+ public static IEnumerable < CodeInstruction > VesselComponent_HandleOrbitalPhysicsUnderThrustStart (
33+ IEnumerable < CodeInstruction > bodyToReplace
34+ )
35+ {
36+ var propGetSqrMagnitude = typeof ( Vector3d ) . GetProperty ( "sqrMagnitude" ) ! . GetGetMethod ( ) ;
37+ var res = TranspilerHelper . Replace (
38+ bodyToReplace ,
39+ [
40+ new TranspilerHelper . ILLookupKey { OpCode = OpCodes . Ldloca_S } ,
41+ new TranspilerHelper . ILLookupKey { OpCode = OpCodes . Call , Operand = propGetSqrMagnitude } ,
42+ new TranspilerHelper . ILLookupKey { OpCode = OpCodes . Ldc_R8 } ,
43+ new TranspilerHelper . ILLookupKey { OpCode = OpCodes . Bge_Un } ,
44+ new TranspilerHelper . ILLookupKey { OpCode = OpCodes . Ldloca_S } ,
45+ new TranspilerHelper . ILLookupKey { OpCode = OpCodes . Call , Operand = propGetSqrMagnitude } ,
46+ new TranspilerHelper . ILLookupKey { OpCode = OpCodes . Ldc_R8 } ,
47+ new TranspilerHelper . ILLookupKey { OpCode = OpCodes . Bge_Un } ,
48+ ] ,
49+ oldBody =>
50+ {
51+ var checkNeedRoundingError = CheckNeedRoundingError ;
52+ var instructions = oldBody . ToArray ( ) ;
53+ return
54+ [
55+ instructions [ 0 ] , instructions [ 1 ] ,
56+ instructions [ 4 ] , instructions [ 5 ] ,
57+ new CodeInstruction ( OpCodes . Call , checkNeedRoundingError . Method ) ,
58+ new CodeInstruction ( OpCodes . Ldc_I4_1 ) ,
59+ instructions [ 7 ] , new CodeInstruction ( OpCodes . Nop ) ,
60+ ] ;
61+ } ,
62+ 1 ..1
63+ ) ;
64+
65+ return res ;
66+ }
67+ }
0 commit comments