static IEnumerable <CodeInstruction> HaulBeforeSupply(IEnumerable <CodeInstruction> _codes, ILGenerator generator) { var t = new Transpiler(_codes, MethodBase.GetCurrentMethod()); var nearbyResourcesIdx = t.TryFindCodeIndex(code => code.Calls(AccessTools.Method(typeof(WorkGiver_ConstructDeliverResources), "FindAvailableNearbyResources"))); var foundResIdx = t.TryFindCodeLastIndex(nearbyResourcesIdx, code => code.opcode == OpCodes.Brfalse) + 1; var foundRes = generator.DefineLabel(); t.codes[foundResIdx].labels.Add(foundRes); var returnJobIdx = t.TryFindCodeIndex(foundResIdx, code => code.opcode == OpCodes.Ret); var jobVar = t.codes[returnJobIdx - 1].operand; t.TryInsertCodes( 0, (i, codes) => i == foundResIdx, (i, codes) => new List <CodeInstruction> { // job = _HaulBeforeSupply(pawn, (Thing) c, foundRes); new CodeInstruction(OpCodes.Ldarg_1), // Pawn pawn new CodeInstruction(OpCodes.Ldarg_2), // IConstructible c new CodeInstruction(OpCodes.Castclass, typeof(Thing)), // (Thing) c new CodeInstruction(codes[i + 1]), // Thing foundRes new CodeInstruction(codes[i + 2]), // Thing foundRes new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(WorkGiver_ConstructDeliverResources_ResourceDeliverJobFor_Patch), nameof(_HaulBeforeSupply))), new CodeInstruction(OpCodes.Stloc_S, jobVar), // if (job != null) return job; new CodeInstruction(OpCodes.Ldloc_S, jobVar), new CodeInstruction(OpCodes.Brfalse_S, foundRes), new CodeInstruction(OpCodes.Ldloc_S, jobVar), new CodeInstruction(OpCodes.Ret), }); return(t.GetFinalCodes()); }
static IEnumerable <CodeInstruction> OpportunisticJobs(IEnumerable <CodeInstruction> _codes, ILGenerator generator) { var t = new Transpiler(_codes, MethodBase.GetCurrentMethod()); var listerHaulablesIdx = t.TryFindCodeIndex(code => code.LoadsField(AccessTools.Field(typeof(Map), nameof(Map.listerHaulables)))); var skipMod = generator.DefineLabel(); t.TryInsertCodes( -3, (i, codes) => i == listerHaulablesIdx, (i, codes) => new List <CodeInstruction> { new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Pawn_JobTracker_TryOpportunisticJob_Patch), nameof(IsEnabled))), new CodeInstruction(OpCodes.Brfalse_S, skipMod), new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldarg_1), new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Patch_TryOpportunisticJob), nameof(TryOpportunisticJob))), new CodeInstruction(OpCodes.Ret), }, true); t.codes[t.MatchIdx - 3].labels.Add(skipMod); return(t.GetFinalCodes()); }