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());
                }
示例#2
0
                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());
                }