Example #1
0
        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);
                }
            }
        }
Example #2
0
        /// <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));
                }
            }
        }