using System; using System.Collections.Generic; using System.Reflection; using System.Reflection.Emit; using RimWorld; using Verse; using HarmonyLib; using Verse.AI; namespace RJWSexperience.Ideology.Patches { [HarmonyPatch] static class WorkGiver_InteractAnimal_ReduceNutritionRequiredByIdeo { public static IEnumerable TargetMethods() { yield return AccessTools.Method(typeof(WorkGiver_InteractAnimal), "HasFoodToInteractAnimal"); yield return AccessTools.Method(typeof(WorkGiver_InteractAnimal), "TakeFoodForAnimalInteractJob"); yield return AccessTools.Method(typeof(WorkGiver_Tame), nameof(WorkGiver_Tame.JobOnThing)); } public static IEnumerable Transpiler(IEnumerable instructions, MethodBase original) { MethodInfo requiredNutritionPerFeed = AccessTools.Method(typeof(JobDriver_InteractAnimal), nameof(JobDriver_InteractAnimal.RequiredNutritionPerFeed)); Type thisType = typeof(WorkGiver_InteractAnimal_ReduceNutritionRequiredByIdeo); bool patched = false; foreach (var instruction in instructions) { yield return instruction; if (instruction.Calls(requiredNutritionPerFeed)) { yield return new CodeInstruction(OpCodes.Ldarg_1); yield return new CodeInstruction(OpCodes.Ldarg_2); yield return CodeInstruction.Call(thisType, nameof(IdeoFactor)); yield return new CodeInstruction(OpCodes.Mul); patched = true; } } if (!patched) { RsiLog.Error($"Transpiler patch {thisType} failed to find a call to {requiredNutritionPerFeed.DeclaringType}:" + $"{requiredNutritionPerFeed.Name} on {original.ReflectedType}:{original.Name}"); } } private static float IdeoFactor(Pawn tamer, Pawn tamee) { if (BestialityUtility.CanDoLewdAnimalWork(tamer, tamee)) { return 0.5f; } return 1f; } } [HarmonyPatch(typeof(WorkGiver_Tame), nameof(WorkGiver_Tame.JobOnThing))] static class WorkGiver_Tame_GiveLewdTameJobIfPossible { public static void Postfix(Job __result, Pawn pawn, Thing t) { if (__result?.def != JobDefOf.Tame) { return; } if (BestialityUtility.CanDoLewdAnimalWork(pawn, (Pawn)t)) { __result.def = RsiDefOf.Job.TameLewd_Feed; } } } [HarmonyPatch(typeof(WorkGiver_Train), nameof(WorkGiver_Train.JobOnThing))] static class WorkGiver_Train_GiveLewdTrainJobIfPossible { public static void Postfix(Job __result, Pawn pawn, Thing t) { if (__result?.def != JobDefOf.Train) { return; } if (BestialityUtility.CanDoLewdAnimalWork(pawn, (Pawn)t)) { __result.def = RsiDefOf.Job.TrainLewd_Feed; } } } }