@@ -29,203 +29,71 @@ public static bool InitVeinGroups(PlanetFactory __instance, PlanetData planet)
2929 return false ;
3030 }
3131
32-
33- // [HarmonyTranspiler]
34- // [HarmonyPatch(typeof(PlanetFactory), "FlattenTerrain")]
35- // public static IEnumerable<CodeInstruction> FlattenTerrainTranspiler(IEnumerable<CodeInstruction> instructions,
36- // ILGenerator generator)
37- // {
38- // var instructionList = new List<CodeInstruction>(instructions);
39- //
40- // var intNum4 = generator.DeclareLocal(typeof(int));
41- // intNum4.SetLocalSymInfo("intNum4");
42- //
43- // for (var instructionCounter = 0; instructionCounter < instructionList.Count; instructionCounter++)
44- // if (instructionList[instructionCounter].opcode == OpCodes.Conv_I2 &&
45- // instructionCounter + 1 < instructionList.Count &&
46- // instructionList[instructionCounter + 1].opcode == OpCodes.Stloc_S &&
47- // instructionList[instructionCounter + 1].operand is LocalBuilder lb_stloc &&
48- // lb_stloc.LocalIndex == 18)
49- // {
50- // instructionList[instructionCounter] = new CodeInstruction(OpCodes.Conv_I4);
51- // instructionList[instructionCounter + 1] = new CodeInstruction(OpCodes.Stloc_S, intNum4);
52- //
53- // instructionCounter++;
54- // }
55- // else if (instructionList[instructionCounter].opcode == OpCodes.Ldloc_S &&
56- // instructionList[instructionCounter].operand is LocalBuilder lb_ldloc &&
57- // lb_ldloc.LocalIndex == 18)
58- // {
59- // instructionList[instructionCounter] = new CodeInstruction(OpCodes.Ldloc_S, intNum4);
60- // }
61- //
62- // return instructionList.AsEnumerable();
63- // }
64- [ HarmonyPrefix ]
65- [ HarmonyPatch ( typeof ( PlanetFactory ) , "FlattenTerrain" ) ]
66- public static bool FlattenTerrain ( ref int __result , ref PlanetFactory __instance , Vector3 pos , Quaternion rot , Bounds bound , float fade0 = 6f , float fade1 = 1f , bool removeVein = false , bool lift = false )
32+ // change
33+ // short num5 = (short)(planet.realRadius * 100f + 20f);
34+ // to
35+ // int newLocalVar = (int)(planet.realRadius * 100f + 20f)
36+ // assign newLocalVar to all variables which request num5
37+ [ HarmonyTranspiler , HarmonyPatch ( typeof ( PlanetFactory ) , nameof ( PlanetFactory . FlattenTerrain ) ) ]
38+ static IEnumerable < CodeInstruction > PlanetFactory_FlattenTerrain_Transpiler ( IEnumerable < CodeInstruction > instructions , ILGenerator generator )
6739 {
68- if ( __instance . tmp_levelChanges == null ) __instance . tmp_levelChanges = new Dictionary < int , int > ( ) ;
69- if ( __instance . tmp_ids == null ) __instance . tmp_ids = new int [ 4096 ] ;
70- __instance . tmp_levelChanges . Clear ( ) ;
71- Array . Clear ( __instance . tmp_ids , 0 , __instance . tmp_ids . Length ) ;
72- bound . extents = new Vector3 ( bound . extents . x , bound . extents . y + 0.5f , bound . extents . z ) ;
73- var quaternion = rot ;
74- quaternion . w = - quaternion . w ;
75- var rotation = Maths . SphericalRotation ( pos , 22.5f ) ;
76- var realRadius = __instance . planet . realRadius ;
77- var num = bound . extents . magnitude + fade0 ;
78- var num2 = num * num ;
79- var num3 = realRadius * 3.1415927f / ( __instance . planet . precision * 2f ) ;
80- var num4 = Mathf . CeilToInt ( num * 1.414f / num3 * 1.5f + 0.5f ) ;
81- Vector3 [ ] array =
82- {
83- pos ,
84- pos + rotation * ( new Vector3 ( 0f , 0f , 1.414f ) * num ) ,
85- pos + rotation * ( new Vector3 ( 0f , 0f , - 1.414f ) * num ) ,
86- pos + rotation * ( new Vector3 ( 1.414f , 0f , 0f ) * num ) ,
87- pos + rotation * ( new Vector3 ( - 1.414f , 0f , 0f ) * num ) ,
88- pos + rotation * ( new Vector3 ( 1f , 0f , 1f ) * num ) ,
89- pos + rotation * ( new Vector3 ( - 1f , 0f , - 1f ) * num ) ,
90- pos + rotation * ( new Vector3 ( 1f , 0f , - 1f ) * num ) ,
91- pos + rotation * ( new Vector3 ( - 1f , 0f , 1f ) * num )
92- } ;
93- var stride = __instance . planet . data . stride ;
94- var dataLength = __instance . planet . data . dataLength ;
95- var vertices = __instance . planet . data . vertices ;
96- var heightData = __instance . planet . data . heightData ;
97- var num5 = ( int ) ( __instance . planet . realRadius * 100f + 20f ) ; //changed short to int in both declaration and cast
98- var num6 = 0 ;
99- foreach ( var vpos in array )
40+ LocalBuilder intNum5 = generator . DeclareLocal ( typeof ( int ) ) ;
41+
42+ CodeMatcher matcher = new CodeMatcher ( instructions ) ;
43+
44+ // find codes look like (short)(A * 100f + 20f)
45+ matcher . MatchForward ( true ,
46+ new CodeMatch ( OpCodes . Ldc_R4 , 100f ) ,
47+ new CodeMatch ( OpCodes . Mul ) ,
48+ new CodeMatch ( OpCodes . Ldc_R4 , 20f ) ,
49+ new CodeMatch ( OpCodes . Add ) ,
50+ new CodeMatch ( OpCodes . Conv_I2 ) ,
51+ new CodeMatch ( OpCodes . Stloc_S )
52+ ) ;
53+
54+ if ( matcher . IsInvalid )
10055 {
101- var num7 = __instance . planet . data . QueryIndex ( vpos ) ;
102- for ( var j = - num4 ; j <= num4 ; j ++ )
103- {
104- var num8 = num7 + j * stride ;
105- if ( num8 >= 0 && num8 < dataLength )
106- for ( var k = - num4 ; k <= num4 ; k ++ )
107- {
108- var num9 = num8 + k ;
109- if ( ( ulong ) num9 < ( ulong ) dataLength && ( lift || heightData [ num9 ] > num5 ) ) //removed (short) cast from num5
110- {
111- Vector3 vector ;
112- vector . x = vertices [ num9 ] . x * realRadius ;
113- vector . y = vertices [ num9 ] . y * realRadius ;
114- vector . z = vertices [ num9 ] . z * realRadius ;
115- Vector3 vector2 ;
116- vector2 . x = vector . x - pos . x ;
117- vector2 . y = vector . y - pos . y ;
118- vector2 . z = vector . z - pos . z ;
119- if ( vector2 . x * vector2 . x + vector2 . y * vector2 . y + vector2 . z * vector2 . z < num2 && ! __instance . tmp_levelChanges . ContainsKey ( num9 ) )
120- {
121- vector = quaternion * ( vector - pos ) ;
122- if ( bound . Contains ( vector ) )
123- {
124- __instance . tmp_levelChanges [ num9 ] = 3 ;
125- }
126- else
127- {
128- var num10 = Vector3 . Distance ( bound . ClosestPoint ( vector ) , vector ) ;
129- var num11 = ( int ) ( ( fade0 - num10 ) / ( fade0 - fade1 ) * 3f + 0.5f ) ;
130- if ( num11 < 0 )
131- num11 = 0 ;
132- else if ( num11 > 3 ) num11 = 3 ;
133- var modLevel = __instance . planet . data . GetModLevel ( num9 ) ;
134- var num12 = num11 - modLevel ;
135- if ( num11 >= modLevel && num12 != 0 )
136- {
137- __instance . tmp_levelChanges [ num9 ] = num11 ;
138- var num13 = heightData [ num9 ] * 0.01f ;
139- var num14 = realRadius + 0.2f - num13 ;
140- var f = 100f * num12 * num14 * 0.3333333f ;
141- num6 += - Mathf . FloorToInt ( f ) ;
142- }
143- }
144- }
145- }
146- }
147- }
56+ GS2 . Error ( "PlanetFactory_FlattenTerrain_Transpiler: fail to find codes look like (short)(A * 100f + 20f)" ) ;
57+ return instructions ;
14858 }
14959
150- var levelized = __instance . planet . levelized ;
151- var num15 = Mathf . RoundToInt ( ( pos . magnitude - 0.2f - __instance . planet . realRadius ) / 1.3333333f ) ;
152- var num16 = num15 * 133 + num5 - 60 ;
153- foreach ( var keyValuePair in __instance . tmp_levelChanges )
154- if ( keyValuePair . Value > 0 )
155- {
156- if ( levelized )
157- {
158- if ( heightData [ keyValuePair . Key ] >= num16 )
159- {
160- if ( __instance . planet . data . GetModLevel ( keyValuePair . Key ) < 3 ) __instance . planet . data . SetModPlane ( keyValuePair . Key , num15 ) ;
161- __instance . planet . AddHeightMapModLevel ( keyValuePair . Key , keyValuePair . Value ) ;
162- }
163- }
164- else
165- {
166- __instance . planet . AddHeightMapModLevel ( keyValuePair . Key , keyValuePair . Value ) ;
167- }
168- }
60+ // index of the old varialbe
61+ int oldNum5Index = ( ( LocalBuilder ) matcher . Operand ) . LocalIndex ;
62+
63+ // assign the result of the calculation to new local variable
64+ matcher . Advance ( - 1 ) ; // move back to conv.i2
65+ matcher . SetOpcodeAndAdvance ( OpCodes . Conv_I4 ) ; // conv.i2 -> conv.i4
66+ matcher . SetAndAdvance ( OpCodes . Stloc_S , intNum5 . LocalIndex ) ; // stloc.s 13 -> stloc.s intNum5
16967
170- var flag = __instance . planet . UpdateDirtyMeshes ( ) ;
171- if ( GameMain . isRunning && flag ) __instance . RenderLocalPlanetHeightmap ( ) ;
172- var physics = __instance . planet . physics ;
173- bound . extents += new Vector3 ( 1.5f , 1.5f , 1.5f ) ;
174- var nearColliderLogic = physics . nearColliderLogic ;
175- var num17 = nearColliderLogic . GetVegetablesInAreaNonAlloc ( pos , num , __instance . tmp_ids ) ;
176- for ( var l = 0 ; l < num17 ; l ++ )
68+ // find all places reading old variable, replace them with new local variable
69+ while ( matcher . IsValid )
17770 {
178- var num18 = __instance . tmp_ids [ l ] ;
179- var vector = __instance . vegePool [ num18 ] . pos ;
180- vector = quaternion * ( vector - pos ) ;
181- if ( bound . Contains ( vector ) && __instance . vegePool [ num18 ] . protoId < 9999 ) //Edited after 0.9.25 update
71+ matcher . MatchForward ( true , new CodeMatch (
72+ instruction => instruction . opcode == OpCodes . Ldloc_S && ( ( LocalBuilder ) instruction . operand ) . LocalIndex == oldNum5Index
73+ ) ) ;
74+ if ( matcher . IsValid )
18275 {
183- if ( GameMain . gameTick > 0L )
184- {
185- VegeProto vegeProto = LDB . veges . Select ( ( int ) __instance . vegePool [ num18 ] . protoId ) ;
186- if ( vegeProto != null )
187- {
188- VFEffectEmitter . Emit ( vegeProto . MiningEffect , __instance . vegePool [ num18 ] . pos , __instance . vegePool [ num18 ] . rot ) ;
189- VFAudio . Create ( vegeProto . MiningAudio , null , __instance . vegePool [ num18 ] . pos , true , 1 , - 1 , - 1L ) ;
190- }
191- } // End 0.9.25 edit
192- __instance . RemoveVegeWithComponents ( num18 ) ;
193- }
194- else
195- {
196- var d = __instance . planet . data . QueryModifiedHeight ( __instance . vegePool [ num18 ] . pos ) - 0.03f ;
197- __instance . vegePool [ num18 ] . pos = __instance . vegePool [ num18 ] . pos . normalized * d ;
198- GameMain . gpuiManager . AlterModel ( __instance . vegePool [ num18 ] . modelIndex , __instance . vegePool [ num18 ] . modelId , num18 , __instance . vegePool [ num18 ] . pos , __instance . vegePool [ num18 ] . rot , false ) ;
76+ matcher . SetAndAdvance ( OpCodes . Ldloc_S , intNum5 . LocalIndex ) ;
19977 }
20078 }
79+
80+ // find codes look like A = new Type[1024]
81+ matcher . Start ( ) ;
82+ matcher . MatchForward ( false ,
83+ new CodeMatch ( OpCodes . Ldc_I4 , 1024 ) ,
84+ new CodeMatch ( OpCodes . Newarr ) ,
85+ new CodeMatch ( OpCodes . Stfld )
86+ ) ;
20187
202- num17 = nearColliderLogic . GetVeinsInAreaNonAlloc ( pos , num , __instance . tmp_ids ) ;
203- for ( var m = 0 ; m < num17 ; m ++ )
88+ if ( matcher . IsInvalid )
20489 {
205- var num19 = __instance . tmp_ids [ m ] ;
206- var vector = __instance . veinPool [ num19 ] . pos ;
207- if ( removeVein && bound . Contains ( vector ) )
208- {
209- __instance . RemoveVeinWithComponents ( num19 ) ;
210- }
211- else if ( vector . magnitude > __instance . planet . realRadius )
212- {
213- var d2 = __instance . planet . data . QueryModifiedHeight ( vector ) - 0.13f ;
214- __instance . veinPool [ num19 ] . pos = vector . normalized * d2 ;
215- GameMain . gpuiManager . AlterModel ( __instance . veinPool [ num19 ] . modelIndex , __instance . veinPool [ num19 ] . modelId , num19 , __instance . veinPool [ num19 ] . pos , false ) ;
216- var num20 = __instance . veinPool [ num19 ] . colliderId ;
217- var num21 = num20 >> 20 ;
218- num20 &= 1048575 ;
219- physics . colChunks [ num21 ] . colliderPool [ num20 ] . pos = __instance . veinPool [ num19 ] . pos + __instance . veinPool [ num19 ] . pos . normalized * 0.4f ;
220- physics . SetPlanetPhysicsColliderDirty ( ) ;
221- }
90+ GS2 . Error ( "PlanetFactory_FlattenTerrain_Transpiler: fail to find codes look like A = new Type[1024]" ) ;
91+ return instructions ;
22292 }
93+
94+ matcher . SetOperandAndAdvance ( 4096 ) ;
22395
224- __instance . tmp_levelChanges . Clear ( ) ;
225- Array . Clear ( __instance . tmp_ids , 0 , __instance . tmp_ids . Length ) ;
226- GameMain . gpuiManager . SyncAllGPUBuffer ( ) ;
227- __result = num6 ;
228- return false ;
96+ return matcher . InstructionEnumeration ( ) ;
22997 }
23098 }
231- }
99+ }
0 commit comments