public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { FieldInfo priceBuyInfo = AccessTools.Field(typeof(RimWorld.Tradeable), "pricePlayerBuy"); FieldInfo priceSellInfo = AccessTools.Field(typeof(RimWorld.Tradeable), "pricePlayerSell"); MethodInfo AdjustPricesInfo = AccessTools.Method(typeof(BuySellCollapser), nameof(BuySellCollapser.AdjustPrices)); List <CodeInstruction> instList = instructions.ToList(); for (int i = 0; i < instList.Count; i++) { CodeInstruction inst = instList[i]; //IL_00e9: ldarg.0 // this //IL_00ea: ldarg.0 // this //IL_00eb: ldfld float32 RimWorld.Tradeable::pricePlayerBuy //IL_00f0: stfld float32 RimWorld.Tradeable::pricePlayerSell if (inst.StoresField(priceSellInfo) && instList[i - 1].LoadsField(priceBuyInfo)) { //Tradeable this, pricePlayerBuy on stack yield return(new CodeInstruction(OpCodes.Call, AdjustPricesInfo)); //AdjustPrices(Tradeable) } else { yield return(inst); } } }
/// <summary> /// TOO MUCH OF A MESS TO EXPLAIN /// </summary> /// <returns>Madness.</returns> private static IEnumerable <CodeInstruction> ReorderWidgetFromEventToInputTranspiler(IEnumerable <CodeInstruction> instructions, ILGenerator generator) { MethodInfo GetCurrent = AccessTools.Property(typeof(Event), nameof(Event.current)).GetGetMethod(); MethodInfo GetRawType = AccessTools.Property(typeof(Event), nameof(Event.rawType)).GetGetMethod(); MethodInfo NoMouseButtonsPressed = AccessTools.Method(typeof(Numbers), nameof(NoMouseButtonsPressed)); MethodInfo WasClicked = AccessTools.Method(typeof(Numbers), nameof(WasClicked)); FieldInfo released = AccessTools.Field(typeof(ReorderableWidget), "released"); bool yieldNext = true; List <CodeInstruction> instructionArr = instructions.ToList(); for (int i = 0; i < instructionArr.ToArray().Length; i++) { CodeInstruction instruction = instructionArr[i]; if (instruction.Calls(GetCurrent)) { if (instructionArr[i + 1].operand != null && instructionArr[i + 1].Calls(GetRawType)) { //L_02bc: Label1 //L_02bc: call UnityEngine.Event get_current() //L_02c1: callvirt EventType get_rawType() //L_02c6: ldc.i4.1 // => // call Input.GetMouseButtonUp(1) (or 0) yield return(new CodeInstruction(OpCodes.Nop) { labels = new List <Label> { generator.DefineLabel() } }); instruction.opcode = OpCodes.Call; instruction.operand = NoMouseButtonsPressed; instructionArr.RemoveAt(i + 1); } } if (instruction.StoresField(released)) { yield return(instruction); CodeInstruction codeInst = new CodeInstruction(OpCodes.Ldarg_2) { labels = new List <Label> { generator.DefineLabel() } }; codeInst.labels.AddRange(instructionArr[i + 1].labels); yield return(codeInst); yield return(new CodeInstruction(OpCodes.Call, WasClicked)); yieldNext = false; } if (!yieldNext && instruction.opcode == OpCodes.Ldarg_1) { yieldNext = true; } if (yieldNext) { yield return(instruction); } if (instruction.Calls(AccessTools.Method(typeof(Mouse), nameof(Mouse.IsOver)))) { yield return(new CodeInstruction(OpCodes.And)); } } }