Skip to content

Commit a445d9f

Browse files
authored
Merge pull request #180 from LittleSaya/main
Update FlattenTerrain.cs
2 parents afd973b + 57d2380 commit a445d9f

File tree

1 file changed

+53
-185
lines changed

1 file changed

+53
-185
lines changed

Scripts/Patches/PlanetFactory/FlattenTerrain.cs

Lines changed: 53 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)