using System; using System.Collections.Generic; using System.Linq; using HarmonyLib; using RimWorld; using Verse; using UnityEngine; using System.Reflection; using System.Reflection.Emit; using Rimworld_Animations; using rjw; namespace Rimworld_Animations_Patch { [StaticConstructorOnStartup] [HarmonyPatch(typeof(PawnRenderer), "RenderPawnInternal", new Type[] { typeof(Vector3), typeof(float), typeof(bool), typeof(Rot4), typeof(RotDrawMode), typeof(PawnRenderFlags) } )] public static class HarmonyPatch_PawnRenderer_RenderPawnInternal { public static IEnumerable Transpiler(IEnumerable instructions) { List ins = instructions.ToList(); for (int i = 0; i < instructions.Count(); i++) { bool runIns = true; // Replaces the rotation that gets passed to DrawHeadHair with one that is based the current 'true' head orientation if (i + 8 < instructions.Count() && ins[i + 8].opcode == OpCodes.Call && ins[i + 8].operand != null && ins[i + 8].OperandIs(AccessTools.DeclaredMethod(typeof(PawnRenderer), "DrawHeadHair"))) { // Get the true head rotation yield return new CodeInstruction(OpCodes.Ldarg_0); yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(typeof(PawnRenderer), "pawn")); yield return new CodeInstruction(OpCodes.Ldloc, (object)7); // local body facing yield return new CodeInstruction(OpCodes.Ldarg_S, (object)6); // renderer flags yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(AnimationPatchUtility), "PawnHeadRotInAnimation")); yield return new CodeInstruction(OpCodes.Stloc_S, (object)7); // set local body facing to true head facing // Pass this head rotation to a new DrawHeadHair call yield return new CodeInstruction(OpCodes.Ldarg_0); yield return new CodeInstruction(OpCodes.Ldarg_1); yield return new CodeInstruction(OpCodes.Ldloc_S, (object)6); yield return new CodeInstruction(OpCodes.Ldarg_2); yield return new CodeInstruction(OpCodes.Ldloc_S, (object)7); // local true head facing yield return new CodeInstruction(OpCodes.Ldloc_S, (object)7); // local true head facing yield return new CodeInstruction(OpCodes.Ldarg_S, (object)5); // bodyDrawType yield return new CodeInstruction(OpCodes.Ldarg_S, (object)6); // renderer flags yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(PawnRenderer), "DrawHeadHair")); // Skip the original call to DrawHeadHair i = i + 8; runIns = false; } if (runIns) { yield return ins[i]; } } } } [StaticConstructorOnStartup] [HarmonyPatch(typeof(PawnGraphicSet), "ResolveAllGraphics")] public static class HarmonyPatch_PawnGraphicSet_ResolveAllGraphics { public static void Postfix(PawnGraphicSet __instance) { if (__instance?.pawn?.apparel == null) { return; } if (__instance.pawn.GetAnimationData() != null) { return; } if (__instance.pawn.apparel.WornApparel.NullOrEmpty() == false) { foreach(Apparel apparel in __instance.pawn.apparel.WornApparel) { CompApparelVisibility comp = apparel.TryGetComp(); if (comp != null) { comp.isBeingWorn = true; } } } } } }