static IEnumerable <CodeInstruction> UpdateTargets_Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator iL) { /* * Update search for new targets. Do not include targets that are already pending response from server. * Change: * if (!this.serving.Contains(num4) && (prebuildPool[i].itemRequired == 0 || prebuildPool[i].itemRequired <= this.player.package.GetItemCount((int)prebuildPool[i].protoId))) * * To: * if (!this.serving.Contains(num4) && !DroneManager.IsPendingBuildRequest(num4) && (prebuildPool[i].itemRequired == 0 || prebuildPool[i].itemRequired <= this.player.package.GetItemCount((int)prebuildPool[i].protoId))) */ var codeMatcher = new CodeMatcher(instructions, iL) .MatchForward(true, new CodeMatch(i => i.IsLdarg()), new CodeMatch(i => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "serving"), new CodeMatch(i => i.IsLdloc()), new CodeMatch(i => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "Contains"), new CodeMatch(OpCodes.Brtrue) ); if (codeMatcher.IsInvalid) { NebulaModel.Logger.Log.Error("MechaDroneLogic_Transpiler.UpdateTargets_Transpiler 1 failed. Mod version not compatible with game version."); return(instructions); } var num4Instruction = codeMatcher.InstructionAt(-2); var jumpInstruction = codeMatcher.Instruction; codeMatcher = codeMatcher .Advance(1) .InsertAndAdvance(num4Instruction) .InsertAndAdvance(HarmonyLib.Transpilers.EmitDelegate <Func <int, bool> >((num4) => { return(DroneManager.IsPendingBuildRequest(num4)); })) .InsertAndAdvance(jumpInstruction); /* * Make sure targets are only chosen if player is closest to the build preview * Change: * if (a.sqrMagnitude > this.sqrMinBuildAlt && sqrMagnitude <= num2) * To: * if (DroneManager.AmIClosestPlayer(ref a) && a.sqrMagnitude > this.sqrMinBuildAlt && sqrMagnitude <= num2) */ codeMatcher = codeMatcher .MatchForward(false, new CodeMatch(i => i.IsLdloc()), new CodeMatch(i => i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "get_sqrMagnitude"), new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(i => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "sqrMinBuildAlt"), new CodeMatch(OpCodes.Ble_Un) ); if (codeMatcher.IsInvalid) { NebulaModel.Logger.Log.Error("MechaDroneLogic_Transpiler.UpdateTargets_Transpiler 2 failed. Mod version not compatible with game version."); return(codeMatcher.InstructionEnumeration()); } var aOperand = codeMatcher.Instruction.operand; var jumpOperand = codeMatcher.InstructionAt(4).operand; codeMatcher = codeMatcher .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, aOperand)) .InsertAndAdvance(HarmonyLib.Transpilers.EmitDelegate <Func <Vector3, bool> >((aVar) => { return(DroneManager.AmIClosestPlayer(ref aVar)); })) .InsertAndAdvance(new CodeInstruction(OpCodes.Brfalse, jumpOperand)); /* * Insert * DroneManager.BroadcastDroneOrder(droneId, entityId, stage); * After * this.serving.Add(num3); */ codeMatcher = codeMatcher .MatchForward(true, new CodeMatch(i => i.IsLdarg()), new CodeMatch(i => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "serving"), new CodeMatch(i => i.IsLdloc()), new CodeMatch(i => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "Add"), new CodeMatch(OpCodes.Pop) ); if (codeMatcher.IsInvalid) { NebulaModel.Logger.Log.Error("MechaDroneLogic_Transpiler.UpdateTargets_Transpiler 3 failed. Mod version not compatible with game version."); return(codeMatcher.InstructionEnumeration()); } // The index from drones[j] var droneIdInstruction = codeMatcher.InstructionAt(-8); // num3 from this.serving.Add(num3); var entityIdInstruction = codeMatcher.InstructionAt(-2); // drones[j].stage = 1; var stageInstruction = new CodeInstruction(OpCodes.Ldc_I4_1); return(codeMatcher .Advance(1) .InsertAndAdvance(droneIdInstruction) .InsertAndAdvance(entityIdInstruction) .InsertAndAdvance(stageInstruction) .InsertAndAdvance(HarmonyLib.Transpilers.EmitDelegate <Action <int, int, int> >((droneId, entityId, stage) => { DroneManager.BroadcastDroneOrder(droneId, entityId, stage); })) .InstructionEnumeration()); }