public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            MethodInfo AndIsNotRockInfo = AccessTools.Method(typeof(InteractionSpot), nameof(InteractionSpot.AndIsNotRock));

            bool doneOnce = false;
            List <CodeInstruction> list = instructions.ToList();

            for (int i = 0; i < list.Count; i++)
            {
                CodeInstruction inst = list[i];
                yield return(inst);

                //if (thingList2[index].def.passability == Traversability.Impassable)
                //if (thingList2[index].def.passability == Traversability.Impassable && thingList2[index] is not rock)
                if (inst.LoadsConstant(2) && !doneOnce)                //Traversability.Impassable
                {
                    doneOnce = true;

                    yield return(new CodeInstruction(list[i - 5].opcode, list[i - 5].operand)); //thingList2, but no labels

                    yield return(list[i - 4]);                                                  //index

                    yield return(list[i - 3]);                                                  //thingList[index]

                    yield return(new CodeInstruction(OpCodes.Call, AndIsNotRockInfo));

                    i++;
                    yield return(new CodeInstruction(OpCodes.Brtrue, list[i].operand)
                    {
                        labels = list[i].labels
                    });
                }
            }
        }
Пример #2
0
        public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            MethodInfo SetFontInfo = AccessTools.Property(typeof(Text), "Font").GetSetMethod();

            MethodInfo DrawSurgeryOptionInfo = AccessTools.Method(typeof(SurgergyUnlimitedPawnSettings), nameof(SurgergyUnlimitedPawnSettings.DrawSurgeryOption));

            //Insert before
            //IL_0324: ldc.i4.1
            //IL_0325: call void Verse.Text::set_Font(valuetype Verse.GameFont)
            List <CodeInstruction> list = instructions.ToList();

            for (int i = 0; i < list.Count; i++)
            {
                CodeInstruction inst = list[i];

                if (i + 1 < list.Count &&
                    inst.LoadsConstant(GameFont.Small) &&
                    list[i + 1].Calls(SetFontInfo))                    //Text.Small
                {
                    //Draw pawn surgery option
                    //Rect leftRect, Pawn pawn, float curY
                    yield return(new CodeInstruction(OpCodes.Ldarg_0));

                    yield return(new CodeInstruction(OpCodes.Ldarg_1));

                    yield return(new CodeInstruction(OpCodes.Ldarga_S, 2));

                    yield return(new CodeInstruction(OpCodes.Call, DrawSurgeryOptionInfo));
                }

                yield return(inst);
            }
        }
            static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions)
            {
                // Put all the instructions in an array as we need to be able to peek forward
                CodeInstruction[] instructionArray = instructions.ToArray();

                // Get the field info for the planetCount field in the StarData class
                FieldInfo starInfo_planetCount = AccessTools.Field(typeof(StarData), "planetCount");

                // We have to skip the initializations for the following:
                // * Black hole
                // * Neutron Star
                // * White Dwarf
                // * Giant Star
                // This is due to them having fixed numbers of planets initialized and to fix would require more invasive changes
                int skipped = 0;

                // Loop through all the instructions
                for (int i = 0; i < instructionArray.Length; i++)
                {
                    // Get the current instruction
                    CodeInstruction instruction = instructionArray[i];

                    // Make sure it's not the last instruction and then check if it loads a constant
                    if (i != (instructionArray.Length - 1) && instruction.LoadsConstant())
                    {
                        // If a constant was loaded, then check if that constant is assigned to the planet count in the generator
                        if (instructionArray[i + 1].StoresField(starInfo_planetCount))
                        {
                            // We have to skip the first few assignements, detailed above with declaration of the variable
                            if (skipped < 7)
                            {
                                skipped++;
                            }
                            else
                            {
                                // If this is not one of the special cases, override the opcode of the IL instruction
                                // for the constant value to be 8 for every system
                                instruction.opcode = OpCodes.Ldc_I4_8;
                            }
                        }
                    }

                    // Add the instruction to the iEnumerable to return, modified if required
                    yield return(instruction);
                }
            }
Пример #4
0
 /// <summary>Tests if the code instruction loads an enum constant</summary>
 /// <param name="code">The <see cref="CodeInstruction"/></param>
 /// <param name="e">The enum</param>
 /// <returns>True if the instruction loads the constant</returns>
 ///
 public static bool LoadsConstant(this CodeInstruction code, Enum e)
 {
     return(code.LoadsConstant(Convert.ToInt64(e)));
 }