public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { // public static void BeginGroup(Rect position); MethodInfo BeginGroupInfo = AccessTools.Method(typeof(GUI), nameof(GUI.BeginGroup), new Type[] { typeof(Rect) }); //class Verse.ThingFilter RimWorld.StorageSettings::'filter' FieldInfo filterInfo = AccessTools.Field(typeof(StorageSettings), "filter"); MethodInfo DoThingFilterConfigWindowInfo = AccessTools.Method(typeof(ThingFilterUI), "DoThingFilterConfigWindow"); bool firstTopAreaHeight = true; List <CodeInstruction> instList = instructions.ToList(); for (int i = 0; i < instList.Count; i++) { CodeInstruction inst = instList[i]; yield return(inst); if (firstTopAreaHeight && inst.Calls(GetTopAreaHeight)) { firstTopAreaHeight = false; yield return(new CodeInstruction(OpCodes.Ldc_R4, ITab_Storage_TopAreaHeight_Patch.extraHeight)); yield return(new CodeInstruction(OpCodes.Sub)); } if (inst.Calls(BeginGroupInfo)) { yield return(new CodeInstruction(OpCodes.Ldarg_0));//ITab_Storage this yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(ITab_Storage_FillTab_Patch), nameof(DrawKanbanSettings)))); } } }
public static IEnumerable <CodeInstruction> TranspileDebugSpawn(IEnumerable <CodeInstruction> instructions) { List <CodeInstruction> instructionList = instructions.ToList(); MethodInfo randomStuffFor = AccessTools.Method(typeof(GenStuff), nameof(GenStuff.RandomStuffFor)); MethodInfo getStuffDefFromSettings = AccessTools.Method(typeof(HarmonyPatches), nameof(GetStuffDefFromSettings)); MethodInfo generateQualityRandomEqualChance = AccessTools.Method(typeof(QualityUtility), nameof(QualityUtility.GenerateQualityRandomEqualChance)); MethodInfo generateQualityFromSettings = AccessTools.Method(typeof(HarmonyPatches), nameof(GenerateQualityFromSettings)); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.opcode == OpCodes.Call) { if (instruction.Calls(randomStuffFor)) { instruction.operand = getStuffDefFromSettings; } else if (instruction.Calls(generateQualityRandomEqualChance)) { instruction.operand = generateQualityFromSettings; } } yield return(instruction); } }
public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { // public static void BeginGroup(Rect position); MethodInfo BeginGroupInfo = AccessTools.Method(typeof(GUI), nameof(GUI.BeginGroup), new Type[] { typeof(Rect) }); //class Verse.ThingFilter RimWorld.StorageSettings::'filter' FieldInfo filterInfo = AccessTools.Field(typeof(StorageSettings), "filter"); int count = 0; bool firstTopAreaHeight = true; List <CodeInstruction> instList = instructions.ToList(); for (int i = 0; i < instList.Count; i++) { CodeInstruction inst = instList[i]; //replace // settings.filter //with // RankComp.GetFilter(settings.filter, FillTab.curRank) //but there's another .filter that is Parent filter so check for .settings //IL_01f0: ldfld class RimWorld.StorageSettings RimWorld.ITab_Storage/'<>c__DisplayClass12_0'::settings //IL_01f5: ldfld class Verse.ThingFilter RimWorld.StorageSettings::'filter' //What why the ITab_Storage.\u003C\u003Ec__DisplayClass12_0 really //Soo I guess just skip it for the first call to filter in the method if (inst.LoadsField(filterInfo) && count++ > 0) { //instead of settings.filter, do RankComp.GetFilter(settings, curRank) yield return(new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(FillTab), "curRank"))); yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(RankComp), "GetFilter"))); } else { yield return(inst); } if (firstTopAreaHeight && inst.Calls(GetTopAreaHeight)) { firstTopAreaHeight = false; yield return(new CodeInstruction(OpCodes.Ldc_R4, TopAreaHeight.rankHeight)); yield return(new CodeInstruction(OpCodes.Sub)); } if (inst.Calls(BeginGroupInfo)) { yield return(new CodeInstruction(OpCodes.Ldarg_0)); //ITab_Storage this yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(FillTab), nameof(DrawRanking)))); } } }
public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator il, MethodBase mb) { IList <LocalVariableInfo> locals = mb.GetMethodBody().LocalVariables; int yIndex = locals.First(l => l.LocalType == typeof(float)).LocalIndex; MethodInfo EventCurrentInfo = AccessTools.Property(typeof(Event), "current").GetGetMethod(); MethodInfo SelPawnForGearInfo = AccessTools.Property(typeof(ITab_Pawn_Gear), "SelPawnForGear").GetGetMethod(true); MethodInfo RectWidthInfo = AccessTools.Property(typeof(Rect), "width").GetGetMethod(); MethodInfo DrawMissingThingsInfo = AccessTools.Method(typeof(FillTab_Patch), nameof(FillTab_Patch.DrawMissingThings)); //figure out what viewRect is via BeginScrollView CodeInstruction viewRectInst = null; MethodInfo BeginScrollViewInfo = AccessTools.Method(typeof(Widgets), nameof(Widgets.BeginScrollView)); List <CodeInstruction> instList = instructions.ToList(); for (int i = 0; i < instList.Count; i++) { CodeInstruction inst = instList[i]; if (inst.Calls(BeginScrollViewInfo)) { viewRectInst = instList[i - 2]; } if (inst.Calls(EventCurrentInfo)) { if (viewRectInst == null) { Verse.Log.Error("Smart Medicine Couldn't find viewRectInst, that'll mean no stock up GUI"); } else { yield return(new CodeInstruction(OpCodes.Ldarg_0)); //this yield return(new CodeInstruction(OpCodes.Call, SelPawnForGearInfo)); //this.SelPawnForGearInfo yield return(new CodeInstruction(OpCodes.Ldloca_S, yIndex)); //ref y yield return(viewRectInst); // viewrect //yield return new CodeInstruction(OpCodes.Call, RectWidthInfo);//viewRect.width //this is not working somehow yield return(new CodeInstruction(OpCodes.Call, DrawMissingThingsInfo)); //DrawMissingThings(this.pawn, ref y, viewRect) } } yield return(inst); } }
public static IEnumerable <CodeInstruction> PlaceConduitUnderHeatedFloorTranspiler(IEnumerable <CodeInstruction> instructions) { List <CodeInstruction> instructionList = instructions.ToList(); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.Calls(AccessTools.Method(type: typeof(GenSpawn), parameters: new Type[] { typeof(Thing), typeof(IntVec3), typeof(Map), typeof(Rot4), typeof(WipeMode), typeof(bool) }, name: nameof(GenSpawn.Spawn)))) { yield return(instruction); i += 2; instruction = instructionList[i]; yield return(new CodeInstruction(opcode: OpCodes.Pop)); yield return(new CodeInstruction(opcode: OpCodes.Ldarg_0)); yield return(new CodeInstruction(opcode: OpCodes.Ldloc_0)); yield return(new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(typeof(HeatedFloorsHarmony), name: nameof(HeatedFloorsHarmony.PlaceConduitUnderHeatedFloor)))); } yield return(instruction); } }
//public virtual bool TryReplaceWithSolidThing(Pawn workerPawn, out Thing createdThing, out bool jobEnded) public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { //Replace MethodInfo FirstBlockingThingInfo = AccessTools.Method(typeof(GenConstruct), "FirstBlockingThing"); List <CodeInstruction> list = instructions.ToList(); for (int i = 0; i < list.Count; i++) { CodeInstruction inst = list[i]; yield return(inst); if (inst.Calls(FirstBlockingThingInfo)) { //Frame can be made yield return(new CodeInstruction(OpCodes.Pop)); i++; yield return(new CodeInstruction(OpCodes.Br, list[i].operand) { labels = list[i].labels }); } } }
public static IEnumerable <CodeInstruction> OnCollisionEnterPostfix(IEnumerable <CodeInstruction> instructions) { List <CodeInstruction> codes = new List <CodeInstruction>(instructions); bool flag = false; for (int i = 0; i < codes.Count; i++) { CodeInstruction instruction = codes[i]; if (instruction.opcode == OpCodes.Isinst && (Type)instruction.operand == typeof(Character)) { flag = true; } if (!flag) { continue; } if (instruction.Calls(AccessTools.Method(typeof(Utils), nameof(Utils.LerpStep), new Type[] { typeof(float), typeof(float), typeof(float) }))) { // Keep the ldloc and stloc so that it's basically num = num2 / 4 CodeInstruction ldloc = codes[i - 1]; codes[i - 5] = new CodeInstruction(OpCodes.Nop); codes[i - 4] = new CodeInstruction(OpCodes.Nop); codes[i - 3] = new CodeInstruction(OpCodes.Nop); codes[i - 2] = ldloc; codes[i - 1] = new CodeInstruction(OpCodes.Ldc_R4, 4f); codes[i - 0] = new CodeInstruction(OpCodes.Div); } } return(codes.AsEnumerable()); }
public static IEnumerable<CodeInstruction> DrawCustomResearchTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator ilg) { List<CodeInstruction> instructionList = instructions.ToList(); bool flag = true; for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.Calls(AccessTools.Method(type: typeof(MainTabWindow_Research), name: "PosX")) && flag) { flag = false; Label label = ilg.DefineLabel(); yield return new CodeInstruction(opcode: OpCodes.Ldloc_S, 14); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(SRTSHelper), name: nameof(SRTSHelper.ContainedInDefProjects))); yield return new CodeInstruction(opcode: OpCodes.Brfalse, label); yield return new CodeInstruction(opcode: OpCodes.Ldloc_S, 14); yield return new CodeInstruction(opcode: OpCodes.Ldarg_0); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.PropertyGetter(type: typeof(MainTabWindow_Research), name: "CurTab")); yield return new CodeInstruction(opcode: OpCodes.Ldloc_S, 3); yield return new CodeInstruction(opcode: OpCodes.Ldloc_S, 4); yield return new CodeInstruction(opcode: OpCodes.Ldarg_0); yield return new CodeInstruction(opcode: OpCodes.Ldfld, operand: AccessTools.Field(type: typeof(MainTabWindow_Research), name: "selectedProject")); yield return new CodeInstruction(opcode: OpCodes.Ldloc_S, 13); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(SRTSHelper), name: nameof(SRTSHelper.DrawLinesCustomPrerequisites))); instruction.labels.Add(label); } yield return instruction; } }
/// <summary> /// Draw AerialVehicle textures dynamically to mimic both the AerialVehicle texture and its rotation /// </summary> /// <param name="instructions"></param> /// <param name="ilg"></param> public static IEnumerable <CodeInstruction> DrawDynamicAerialVehiclesTranspiler(IEnumerable <CodeInstruction> instructions, ILGenerator ilg) { List <CodeInstruction> instructionList = instructions.ToList(); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.Calls(AccessTools.Property(typeof(ExpandableWorldObjectsUtility), nameof(ExpandableWorldObjectsUtility.TransitionPct)).GetGetMethod())) { Label label = ilg.DefineLabel(); Label brlabel = ilg.DefineLabel(); yield return(new CodeInstruction(opcode: OpCodes.Ldloc_1)); yield return(new CodeInstruction(opcode: OpCodes.Call, AccessTools.Method(typeof(RenderHelper), nameof(RenderHelper.RenderDynamicWorldObjects)))); yield return(new CodeInstruction(opcode: OpCodes.Brfalse, label)); yield return(new CodeInstruction(opcode: OpCodes.Leave, brlabel)); for (int j = i; j < instructionList.Count; j++) { if (instructionList[j].opcode == OpCodes.Ldloca_S) { instructionList[j].labels.Add(brlabel); break; } } instruction.labels.Add(label); } yield return(instruction); } }
//Insert FilterForUrgentHediffs when counting needed medicine public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { MethodInfo SortByTendPriorityInfo = AccessTools.Method( typeof(TendUtility), nameof(TendUtility.SortByTendPriority)); MethodInfo filterMethodInfo = AccessTools.Method( typeof(GetMedicineCountToFullyHeal_Patch), nameof(FilterInjuriesForMedCount)); FieldInfo filterMethodParameter = AccessTools.Field(typeof(Medicine), "tendableHediffsInTendPriorityOrder"); List <CodeInstruction> instructionList = instructions.ToList(); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.LoadsField(filterMethodParameter)) { i++; CodeInstruction nextInstruction = instructionList[i]; if (nextInstruction.Calls(SortByTendPriorityInfo)) { //insert before the sort call yield return(new CodeInstruction(OpCodes.Ldsfld, filterMethodParameter)); yield return(new CodeInstruction(OpCodes.Call, filterMethodInfo)); } yield return(instruction); yield return(nextInstruction); } else { yield return(instruction); } } }
public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator ilg) { List <CodeInstruction> instructionList = instructions.ToList(); bool found = false; var label = ilg.DefineLabel(); var curLevelGetter = AccessTools.PropertyGetter(typeof(Need), "CurLevel"); var shouldOverride = AccessTools.Method(typeof(VanillaExpandedFramework_JobGiver_GetRest_GetPriority_Patch), "ShouldOverride"); var sleepHourFor = AccessTools.Method(typeof(VanillaExpandedFramework_JobGiver_GetRest_GetPriority_Patch), "TimeAssignmentFor"); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (!found && instruction.Calls(curLevelGetter)) { found = true; instructionList[i].labels.Add(label); yield return(new CodeInstruction(OpCodes.Ldarg_1)); yield return(new CodeInstruction(OpCodes.Call, shouldOverride)); yield return(new CodeInstruction(OpCodes.Brfalse, label)); yield return(new CodeInstruction(OpCodes.Ldarg_1)); yield return(new CodeInstruction(OpCodes.Call, sleepHourFor)); yield return(new CodeInstruction(OpCodes.Stloc_2)); } yield return(instruction); } }
//REDO (remove flag and implement more concrete transpiler) /// <summary> /// Draw pawns onboard vehicles and in vehicle caravans onto the colonist bar /// </summary> /// <param name="instructions"></param> /// <returns></returns> public static IEnumerable <CodeInstruction> CheckRecacheEntriesTranspiler(IEnumerable <CodeInstruction> instructions) { List <CodeInstruction> instructionList = instructions.ToList(); bool flag = false; for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.opcode == OpCodes.Stloc_S && ((LocalBuilder)instruction.operand).LocalIndex == 9) { flag = true; } if (flag && instruction.Calls(AccessTools.Method(typeof(PlayerPawnsDisplayOrderUtility), nameof(PlayerPawnsDisplayOrderUtility.Sort)))) { ///grab pawns from vehicle caravan and store inside list to be rendered on colonist bar yield return(new CodeInstruction(opcode: OpCodes.Ldsfld, operand: AccessTools.Field(typeof(ColonistBar), "tmpCaravans"))); yield return(new CodeInstruction(opcode: OpCodes.Ldloc_S, 9)); yield return(new CodeInstruction(opcode: OpCodes.Callvirt, operand: AccessTools.Property(typeof(List <Caravan>), "Item").GetGetMethod())); yield return(new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(typeof(CaravanHelper), nameof(CaravanHelper.ExtractPawnsFromCaravan)))); yield return(new CodeInstruction(opcode: OpCodes.Callvirt, operand: AccessTools.Method(typeof(List <Pawn>), nameof(List <Pawn> .AddRange)))); yield return(new CodeInstruction(opcode: OpCodes.Ldsfld, operand: AccessTools.Field(typeof(ColonistBar), "tmpPawns"))); } yield return(instruction); } }
/// <summary> /// Expanding Icon dynamic drawer for AerialVehicle dynamic textures /// </summary> /// <param name="instructions"></param> /// <param name="ilg"></param> public static IEnumerable <CodeInstruction> ExpandableIconDetourAerialVehicleTranspiler(IEnumerable <CodeInstruction> instructions, ILGenerator ilg) { List <CodeInstruction> instructionList = instructions.ToList(); Label jumpLabel = ilg.DefineLabel(); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.opcode == OpCodes.Ldloc_2 && instructionList[i + 1].opcode == OpCodes.Ldc_I4_1) { //Jump label, for loop instruction.labels.Add(jumpLabel); } if (instruction.Calls(AccessTools.Property(type: typeof(WorldObject), name: nameof(WorldObject.ExpandingIconColor)).GetGetMethod())) { Label label = ilg.DefineLabel(); yield return(new CodeInstruction(opcode: OpCodes.Ldloc_3)); yield return(new CodeInstruction(opcode: OpCodes.Call, AccessTools.Method(typeof(RenderHelper), nameof(RenderHelper.RenderDynamicWorldObjects)))); yield return(new CodeInstruction(opcode: OpCodes.Brfalse, label)); yield return(new CodeInstruction(opcode: OpCodes.Leave, jumpLabel)); instruction.labels.Add(label); } yield return(instruction); } }
private static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator generator) { var codes = instructions.ToList(); var finished = false; var mNumGridCells = AccessTools.PropertyGetter(typeof(CellIndices), nameof(CellIndices.NumGridCells)); var mAddFloodGlowFor = AccessTools.Method(typeof(GlowFlooder), nameof(GlowFlooder.AddFloodGlowFor)); var fMap = AccessTools.Field(typeof(GlowGrid), nameof(GlowGrid.map)); var fGlowFlooder = AccessTools.Field(typeof(Map), nameof(Map.glowFlooder)); for (int i = 0; i < codes.Count; i++) { CodeInstruction code = codes[i]; if (!finished) { if (code.Calls(mNumGridCells)) { yield return(codes[i]); yield return(new CodeInstruction(OpCodes.Pop)); yield return(new CodeInstruction(OpCodes.Ldc_I4_0)); continue; } if (i + 2 < codes.Count && codes[i].opcode == OpCodes.Ldarg_0 && codes[i + 1].opcode == OpCodes.Ldfld && codes[i + 1].OperandIs(fMap) && codes[i + 2].opcode == OpCodes.Ldfld && codes[i + 2].OperandIs(fGlowFlooder)) { i += 2; continue; } if (code.Calls(mAddFloodGlowFor)) { yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(RecalculateAllGlow_Patch), nameof(RecalculateAllGlow_Patch.AddFloodGlowFor)))); finished = true; continue; } } yield return(code); } }
//public void MouseoverReadoutOnGUI() public static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { MethodInfo DrawTextWinterShadowInfo = AccessTools.Method(typeof(GenUI), "DrawTextWinterShadow"); MethodInfo LabelInfo = AccessTools.Method(typeof(Widgets), "Label", new Type[] { typeof(Rect), typeof(string) }); MethodInfo LabelTaggedInfo = AccessTools.Method(typeof(Widgets), "Label", new Type[] { typeof(Rect), typeof(TaggedString) }); MethodInfo OpenTabInfo = AccessTools.Property(typeof(MainTabsRoot), "OpenTab").GetGetMethod(); List <CodeInstruction> instList = instructions.ToList(); for (int i = 0; i < instList.Count; i++) { CodeInstruction inst = instList[i]; //Topright winter shadow if (inst.Calls(DrawTextWinterShadowInfo)) { yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(MouseoverOnTopRight), nameof(DrawTextWinterShadowTR)))); } //Transform Widgets.Label rect else if (inst.Calls(LabelInfo)) { yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(MouseoverOnTopRight), nameof(LabelTransform)))); } else if (inst.Calls(LabelTaggedInfo)) { yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(MouseoverOnTopRight), nameof(LabelTaggedTransform)))); } else { yield return(inst); } if (inst.Calls(OpenTabInfo)) { yield return(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(MouseoverOnTopRight), nameof(FilterForOpenTab)))); // 0 != null is false } } }
/// <summary> /// Set cells in which vehicles reside as impassable to other Pawns /// </summary> /// <param name="instructions"></param> /// <param name="ilg"></param> /// <returns></returns> public static IEnumerable <CodeInstruction> PathAroundVehicles(IEnumerable <CodeInstruction> instructions, ILGenerator ilg) { List <CodeInstruction> instructionList = instructions.ToList(); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.Calls(AccessTools.Method(typeof(CellIndices), nameof(CellIndices.CellToIndex), new Type[] { typeof(int), typeof(int) }))) { Label label = ilg.DefineLabel(); Label vehicleLabel = ilg.DefineLabel(); yield return(instruction); //CALLVIRT CELLTOINDEX instruction = instructionList[++i]; yield return(instruction); //STLOC.S 38 instruction = instructionList[++i]; yield return(new CodeInstruction(opcode: OpCodes.Ldarg_0)); yield return(new CodeInstruction(opcode: OpCodes.Ldfld, operand: AccessTools.Field(typeof(PathFinder), "map"))); yield return(new CodeInstruction(opcode: OpCodes.Ldloc_S, 36)); yield return(new CodeInstruction(opcode: OpCodes.Ldloc_S, 37)); yield return(new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(typeof(PathingHelper), nameof(PathingHelper.VehicleInCell), new Type[] { typeof(Map), typeof(int), typeof(int) }))); yield return(new CodeInstruction(opcode: OpCodes.Brfalse, label)); yield return(new CodeInstruction(opcode: OpCodes.Ldc_I4_0)); yield return(new CodeInstruction(opcode: OpCodes.Br, vehicleLabel)); for (int j = i; j < instructionList.Count; j++) { CodeInstruction instruction2 = instructionList[j]; if (instruction2.opcode == OpCodes.Brfalse || instruction2.opcode == OpCodes.Brfalse_S) { instruction2.labels.Add(vehicleLabel); break; } } instruction.labels.Add(label); } yield return(instruction); } }
static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { var codes = new List <CodeInstruction>(instructions); var GetTotalNutrition_MethodInfo = typeof(EquipmentContainer).GetMethod("GetTotalNutrition"); for (int i = 4; i < codes.Count - 16; i++) { CodeInstruction ci = codes[i]; if (ci.Calls(GetTotalNutrition_MethodInfo)) { codes.RemoveRange(i - 4, 21); break; } } return(codes); }
static IEnumerable <CodeInstruction> Transpiler(IEnumerable <CodeInstruction> instructions) { var codes = new List <CodeInstruction>(instructions); var StopRecipe_MethodInfo = typeof(CraftGoal).GetMethod("StopRecipe"); for (int i = 2; i < codes.Count; i++) { CodeInstruction ci = codes[i]; if (ci.Calls(StopRecipe_MethodInfo)) { codes.RemoveRange(i - 2, 3); break; } } return(codes); }
/// <summary> /// Draw SRTS textures dynamically to mimic both the flying SRTS texture and its rotation /// </summary> /// <param name="instructions"></param> /// <param name="ilg"></param> /// <returns></returns> public static IEnumerable<CodeInstruction> DrawDynamicSRTSObjectsTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator ilg) { List<CodeInstruction> instructionList = instructions.ToList(); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.Calls(AccessTools.Property(typeof(ExpandableWorldObjectsUtility), nameof(ExpandableWorldObjectsUtility.TransitionPct)).GetGetMethod())) { Label label = ilg.DefineLabel(); Label brlabel = ilg.DefineLabel(); ///Check if TravelingTransportPod is SRTS Instance yield return new CodeInstruction(opcode: OpCodes.Ldloc_1); yield return new CodeInstruction(opcode: OpCodes.Isinst, operand: typeof(TravelingSRTS)); yield return new CodeInstruction(opcode: OpCodes.Brfalse, label); ///Check if dynamic textures mod setting is enabled yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Property(type: typeof(SRTSHelper), name: nameof(SRTSHelper.DynamicTexturesEnabled)).GetGetMethod()); yield return new CodeInstruction(opcode: OpCodes.Brfalse, label); ///Hook onto SRTS Draw method yield return new CodeInstruction(opcode: OpCodes.Ldloc_1); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(TravelingSRTS), name: nameof(TravelingSRTS.Draw))); yield return new CodeInstruction(opcode: OpCodes.Leave, brlabel); int j = i; while (j < instructionList.Count) { if (instructionList[j].opcode == OpCodes.Ldloca_S) { instructionList[j].labels.Add(brlabel); break; } j++; } instruction.labels.Add(label); } yield return instruction; } }
/// <summary> /// Modify the pseudorandom beach value used and insert custom value within the mod settings. /// </summary> /// <param name="instructions"></param> /// <returns></returns> public static IEnumerable <CodeInstruction> BeachMakerTranspiler(IEnumerable <CodeInstruction> instructions) { List <CodeInstruction> instructionList = instructions.ToList(); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.Calls(AccessTools.Property(typeof(FloatRange), nameof(FloatRange.RandomInRange)).GetGetMethod())) { i++; instruction = instructionList[i]; yield return(new CodeInstruction(opcode: OpCodes.Pop)); yield return(new CodeInstruction(opcode: OpCodes.Ldarg_0)); yield return(new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(typeof(ModSettingsHelper), nameof(ModSettingsHelper.CustomFloatBeach)))); } yield return(instruction); } }
/// <summary> /// Expanding Icon dynamic drawer for SRTS dynamic textures /// </summary> /// <param name="instructions"></param> /// <param name="ilg"></param> /// <returns></returns> public static IEnumerable<CodeInstruction> ExpandableIconDetourSRTSTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator ilg) { List<CodeInstruction> instructionList = instructions.ToList(); Label jumpLabel = ilg.DefineLabel(); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.opcode == OpCodes.Ldloc_2 && instructionList[i + 1].opcode == OpCodes.Ldc_I4_1) { ///Jump label, for loop instruction.labels.Add(jumpLabel); } if (instruction.Calls(AccessTools.Property(type: typeof(WorldObject), name: nameof(WorldObject.ExpandingIconColor)).GetGetMethod())) { Label label = ilg.DefineLabel(); ///Check if TravelingTransportPod is SRTS Instance yield return new CodeInstruction(opcode: OpCodes.Ldloc_3); yield return new CodeInstruction(opcode: OpCodes.Isinst, operand: typeof(TravelingSRTS)); yield return new CodeInstruction(opcode: OpCodes.Brfalse, label); ///Check if dynamic textures mod setting is enabled yield return new CodeInstruction(opcode: OpCodes.Pop); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Property(type: typeof(SRTSHelper), name: nameof(SRTSHelper.DynamicTexturesEnabled)).GetGetMethod()); yield return new CodeInstruction(opcode: OpCodes.Brfalse, label); ///Hook onto SRTS Draw method and continue yield return new CodeInstruction(opcode: OpCodes.Ldloc_3); yield return new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(type: typeof(TravelingSRTS), name: nameof(TravelingSRTS.Draw))); yield return new CodeInstruction(opcode: OpCodes.Br, jumpLabel); instruction.labels.Add(label); } yield return instruction; } }
/// <summary> /// Remove and replace Vehicle's info cards. Info Card is currently Work In Progress /// </summary> /// <param name="instructions"></param> /// <param name="ilg"></param> /// <returns></returns> public static IEnumerable <CodeInstruction> InfoCardVehiclesTranspiler(IEnumerable <CodeInstruction> instructions, ILGenerator ilg) { List <CodeInstruction> instructionList = instructions.ToList(); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.Calls(AccessTools.Property(typeof(Find), nameof(Find.WindowStack)).GetGetMethod())) { Label label = ilg.DefineLabel(); ///Check if pawn in question is a Boat yield return(new CodeInstruction(opcode: OpCodes.Ldarg_2)); yield return(new CodeInstruction(opcode: OpCodes.Isinst, operand: typeof(VehiclePawn))); yield return(new CodeInstruction(opcode: OpCodes.Brfalse, label)); ///Load a new object of type Dialog_InfoCard_Ship and load onto the WindowStack. Return after yield return(new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Property(typeof(Find), nameof(Find.WindowStack)).GetGetMethod())); yield return(new CodeInstruction(opcode: OpCodes.Ldarg_2)); yield return(new CodeInstruction(opcode: OpCodes.Newobj, operand: AccessTools.Constructor(typeof(Dialog_InfoCard_Vehicle), new Type[] { typeof(Thing) }))); yield return(new CodeInstruction(opcode: OpCodes.Callvirt, operand: AccessTools.Method(typeof(WindowStack), nameof(WindowStack.Add)))); yield return(new CodeInstruction(opcode: OpCodes.Ldc_I4_1)); yield return(new CodeInstruction(opcode: OpCodes.Ret)); instruction.labels.Add(label); } yield return(instruction); } }
/// <summary> /// Add FloatMenuOption(s) for Pawns towards Vehicles /// </summary> /// <param name="instructions"></param> /// <param name="ilg"></param> public static IEnumerable <CodeInstruction> AddHumanLikeOrdersLoadVehiclesTranspiler(IEnumerable <CodeInstruction> instructions, ILGenerator ilg) { List <CodeInstruction> instructionList = instructions.ToList(); for (int i = 0; i < instructionList.Count; i++) { CodeInstruction instruction = instructionList[i]; if (instruction.LoadsField(AccessTools.Field(typeof(JobDefOf), nameof(JobDefOf.GiveToPackAnimal)))) { yield return(instruction); //Ldsfld : JobDefOf::GiveToPackAnimal instruction = instructionList[++i]; Label jobLabel = ilg.DefineLabel(); yield return(new CodeInstruction(opcode: OpCodes.Ldsfld, operand: AccessTools.Field(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.makingFor)))); yield return(new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(typeof(Ext_Vehicles), nameof(Ext_Vehicles.HasVehicleInCaravan)))); yield return(new CodeInstruction(opcode: OpCodes.Brfalse, jobLabel)); yield return(new CodeInstruction(opcode: OpCodes.Pop)); yield return(new CodeInstruction(opcode: OpCodes.Ldsfld, AccessTools.Field(typeof(JobDefOf_Vehicles), nameof(JobDefOf_Vehicles.CarryItemToVehicle)))); int j = i; while (j < instructionList.Count) { j++; if (instructionList[j].opcode == OpCodes.Stfld) { instructionList[j].labels.Add(jobLabel); break; } } } if (instruction.Calls(AccessTools.Property(typeof(Lord), nameof(Lord.LordJob)).GetGetMethod())) { yield return(instruction); instruction = instructionList[++i]; Label label = ilg.DefineLabel(); Label label2 = ilg.DefineLabel(); yield return(new CodeInstruction(opcode: OpCodes.Dup)); yield return(new CodeInstruction(opcode: OpCodes.Isinst, operand: typeof(LordJob_FormAndSendVehicles))); yield return(new CodeInstruction(opcode: OpCodes.Brtrue, label)); yield return(instruction); //CASTCLASS : LordJob_FormAndSendCaravan instruction = instructionList[++i]; yield return(instruction); //STLOC_S : 50 instruction = instructionList[++i]; yield return(instruction); //LDLOC_S : 49 instruction = instructionList[++i]; yield return(instruction); //LDLOC_S : 50 instruction = instructionList[++i]; yield return(instruction); //CALL : CapacityLeft instruction = instructionList[++i]; yield return(new CodeInstruction(opcode: OpCodes.Br, label2)); yield return(new CodeInstruction(opcode: OpCodes.Pop) { labels = new List <Label> { label } }); yield return(new CodeInstruction(opcode: OpCodes.Ldloc_S, operand: 49)); yield return(new CodeInstruction(opcode: OpCodes.Ldarg_1)); yield return(new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(typeof(LordUtility), "GetLord", new Type[] { typeof(Pawn) }))); yield return(new CodeInstruction(opcode: OpCodes.Callvirt, operand: AccessTools.Property(typeof(Lord), nameof(Lord.LordJob)).GetGetMethod())); yield return(new CodeInstruction(opcode: OpCodes.Castclass, operand: typeof(LordJob_FormAndSendVehicles))); yield return(new CodeInstruction(opcode: OpCodes.Call, operand: AccessTools.Method(typeof(CaravanHelper), nameof(CaravanHelper.CapacityLeft)))); instruction.labels.Add(label2); yield return(instruction); //STFLD : capacityLeft instruction = instructionList[++i]; } yield return(instruction); } }
/// <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)); } } }