public static IEnumerable<CodeInstruction> receiveRightClick_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator gen)
{
try
{
var codes = new List<CodeInstruction>(instructions);
for (int i = 0; i < codes.Count - 8; i++)
{
// Find any sequence matching if(Game1.player.addItemToInventoryBool(this.heldItem, false)
// which is followed by this.heldItem = null assignment if true.
if (//call class StardewValley.Farmer StardewValley.Game1::get_player()
codes[i].opcode == OpCodes.Call &&
(MethodInfo)codes[i].operand == typeof(Game1).GetProperty("player").GetGetMethod() &&
//ldarg.0
codes[i + 1].opcode == OpCodes.Ldarg_0 &&
//ldfld class StardewValley.Item StardewValley.Menus.MenuWithInventory::heldItem
codes[i + 2].opcode == OpCodes.Ldfld &&
(FieldInfo)codes[i + 2].operand == typeof(MenuWithInventory).GetField("heldItem") &&
//ldc.i4.0
codes[i + 3].opcode == OpCodes.Ldc_I4_0 &&
//callvirt instance bool StardewValley.Farmer::addItemToInventoryBool(class StardewValley.Item, bool)
codes[i + 4].opcode == OpCodes.Callvirt &&
(MethodInfo)codes[i + 4].operand == typeof(Farmer).GetMethod("addItemToInventoryBool") &&
//befalse IL_05dc || brfalse.s IL_02f0 (return)
(codes[i + 5].opcode == OpCodes.Brfalse || codes[i + 5].opcode == OpCodes.Brfalse_S) &&
//ldarg.0
codes[i + 6].opcode == OpCodes.Ldarg_0 && // INSERT NEW CODES AT THIS INDEX
//ldnull
codes[i + 7].opcode == OpCodes.Ldnull &&
//stfld class StardewValley.Item StardewValley.Menus.MenuWithInventory::heldItem
codes[i + 8].opcode == OpCodes.Stfld &&
(FieldInfo)codes[i + 8].operand == typeof(MenuWithInventory).GetField("heldItem"))
{
Monitor.Log($"Found a location to insert codes: {codes[i + 6]}", LogLevel.Debug);
// Compose the new instructions to inject
var codesToInsert = new List<CodeInstruction>
{
new CIL(OpCodes.Ldarg_0),
new CIL(OpCodes.Call, typeof(Game1).GetProperty("player").GetGetMethod()),
new CIL(OpCodes.Call, Helper.Reflection.GetMethod(
typeof(ItemGrabMenuPatches),nameof(OnAddItemCheck_Hook)).MethodInfo)
};
// Inject the instructions
codes.InsertRange(i + 6, codesToInsert);
foreach (CIL cil in codesToInsert)
{
Monitor.Log($"Inserted new OpCode: {cil}", LogLevel.Debug);
}
}
}
return codes.AsEnumerable();
}
catch (Exception ex)
{
Monitor.Log($"Failed in {nameof(receiveRightClick_Transpiler)}:\n{ex}", LogLevel.Error);
return instructions; // use original code
}
}