public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { CodeMatcher matcher = new CodeMatcher(instructions) .End() .MatchBack(false, new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(OpCodes.Ldflda, AccessTools.Field(typeof(BuildTool_BlueprintPaste), nameof(BuildTool_BlueprintPaste.cursorTarget)))); CodeMatcher matcher2 = matcher.Clone().MatchForward(false, new CodeMatch(OpCodes.Ldloc_S), new CodeMatch(OpCodes.Ldc_I4_S) , new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(BuildPreview), nameof(BuildPreview.condition)))); object previewVariable = matcher2.Operand; matcher.Advance(1); while (matcher.Opcode != OpCodes.Stloc_S) { matcher.RemoveInstruction(); } matcher.InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, previewVariable)) .InsertAndAdvance(Transpilers.EmitDelegate <Func <BuildTool_BlueprintPaste, BuildPreview, Vector3> >((tool, preview) => preview.lpos.normalized * Mathf.Min(tool.planet.realRadius * 0.025f, 20f))); return(matcher.InstructionEnumeration()); }
private static IEnumerable<CodeInstruction> FixUpdateCalcGarbage(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { var c = new CodeMatcher(instructions, generator); // Remove unnecessary new object creation that gets immediately overwritten c.MatchForward(false, new CodeMatch(OpCodes.Newobj), new CodeMatch(OpCodes.Stloc_1), new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(OpCodes.Ldfld)); if (c.IsInvalid) return instructions; return c .RemoveInstruction() .RemoveInstruction() .Instructions(); }
static IEnumerable <CodeInstruction> RefreshPreviews(IEnumerable <CodeInstruction> instructions, ILGenerator generator) { float MirrorBuildingRotation(float yaw, BlueprintBuilding building) { if (buildingsAxis.ContainsKey(building.modelIndex) && buildingsAxis[building.modelIndex] == MajorAxis.XAXIS) { return(MirrorRotation(yaw + 90f) - 90f); } return(MirrorRotation(yaw)); } CodeMatcher matcher = new CodeMatcher(instructions, generator) .MatchForward(true, new CodeMatch(OpCodes.Ldelem, typeof(Vector4)), new CodeMatch(OpCodes.Stloc_S), new CodeMatch(OpCodes.Ldloca_S)); matcher.Advance(1); object longAxisVar = matcher.Operand; while (matcher.Opcode != OpCodes.Stfld) { matcher.RemoveInstruction(); } matcher.RemoveInstructions(2); object latAxisVar = matcher.Operand; while (matcher.Opcode != OpCodes.Stfld) { matcher.RemoveInstruction(); } matcher.RemoveInstruction() .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, longAxisVar)) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, latAxisVar)) .InsertAndAdvance(Transpilers.EmitDelegate <RefAction>(MirrorArea)); matcher.MatchForward(false, new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(BlueprintUtils), nameof(BlueprintUtils.TransitionWidthAndHeight)))) .Advance(-3) .RemoveInstruction().RemoveInstruction().RemoveInstruction() .SetInstruction(Transpilers.EmitDelegate <Func <float, BlueprintBuilding, Vector2> >((yaw, building) => { float x = building.localOffset_x; float y = building.localOffset_y; if ((mirrorLat && !mirrorLong || !mirrorLat && mirrorLong) && buildingsOffsets.ContainsKey(building.modelIndex)) { Vector2 offset = buildingsOffsets[building.modelIndex]; float rotatedYaw = MirrorBuildingRotation(building.yaw, building); offset = offset.Rotate(rotatedYaw + (mirrorLong ? 180 : 0)); x += offset.x; y += offset.y; } return(BlueprintUtils.TransitionWidthAndHeight(yaw, x, y)); })); matcher.MatchForward(false, new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(BlueprintBuilding), nameof(BlueprintBuilding.yaw))) ).Advance(1) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 30)) .InsertAndAdvance(Transpilers.EmitDelegate <Func <float, BlueprintBuilding, float> >(MirrorBuildingRotation)).Advance(2); matcher.MatchForward(false, new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(BlueprintBuilding), nameof(BlueprintBuilding.yaw2))) ).Advance(1) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 30)) .InsertAndAdvance(Transpilers.EmitDelegate <Func <float, BlueprintBuilding, float> >(MirrorBuildingRotation)); matcher.MatchForward(true, new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(BuildPreview), nameof(BuildPreview.desc))), new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PrefabDesc), nameof(PrefabDesc.isInserter)))) .Advance(2); object previewVar2 = matcher.Operand; matcher.Advance(1) .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, previewVar2)) .InsertAndAdvance(Transpilers.EmitDelegate <Action <BuildPreview> >(preview => { if (preview.input != null && preview.input.desc.slotPoses.Length > preview.inputFromSlot && !preview.input.desc.isBelt) { Quaternion invRot = Quaternion.Inverse(preview.input.lrot); Vector3 slotPosition = preview.lpos - preview.input.lpos; slotPosition = invRot * slotPosition; Quaternion slotRotation = invRot * preview.lrot; for (int i = 0; i < preview.input.desc.slotPoses.Length; i++) { Pose slotPose = preview.input.desc.slotPoses[i]; if (!((slotPose.position - slotPosition).sqrMagnitude < 0.1f)) { continue; } if (!slotPose.rotation.Approximately(slotRotation)) { continue; } if (preview.inputFromSlot == i) { break; } preview.inputFromSlot = i; break; } } if (preview.output != null && preview.output.desc.slotPoses.Length > preview.outputToSlot && !preview.output.desc.isBelt) { Quaternion invRot = Quaternion.Inverse(preview.output.lrot); Vector3 slotPosition = preview.lpos2 - preview.output.lpos; slotPosition = invRot * slotPosition; Quaternion slotRotation = invRot * (preview.lrot2 * Quaternion.Euler(0f, -180f, 0f)); for (int i = 0; i < preview.output.desc.slotPoses.Length; i++) { Pose slotPose = preview.output.desc.slotPoses[i]; if (!((slotPose.position - slotPosition).sqrMagnitude < 0.1f)) { continue; } if (!slotPose.rotation.Approximately(slotRotation)) { continue; } if (preview.outputToSlot == i) { break; } preview.outputToSlot = i; break; } } })); return(matcher.InstructionEnumeration()); }