using HarmonyLib; using RimWorld; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Verse; namespace Rimworld_Animations { [HarmonyPatch(typeof(PawnRenderTree), "TryGetMatrix")] public class HarmonyPatch_PawnRenderTree { public static void Prefix(PawnRenderTree __instance, PawnRenderNode node, ref PawnDrawParms parms) { //Note: Maybe need to change this to check all ancestors if it's the head node //in case of deeper nodes in the PawnRenderTree //This code only checks for node and parent, if either are head // Change facing for all head and apparelhead nodes // So that the offset is based on body rotation, not head rotation //fixes misaligned hairs and headaddons if ((node.Props.tagDef == PawnRenderNodeTagDefOf.Head || node.Props.tagDef == PawnRenderNodeTagDefOf.ApparelHead || node?.parent?.Props?.tagDef == PawnRenderNodeTagDefOf.Head || node?.parent?.Props?.tagDef == PawnRenderNodeTagDefOf.ApparelHead) && node.tree.rootNode.AnimationWorker is AnimationWorker_KeyframesExtended rootNodeAnimationWorker) { // this is only for the Vector3 position to work right parms.facing = rootNodeAnimationWorker.facingAtTick(node.tree.AnimationTick); } } } [HarmonyPatch(typeof(PawnRenderTree), "AdjustParms")] public class HarmonyPatch_PawnRenderTree2 { public static void Prefix(PawnRenderTree __instance, ref PawnDrawParms parms) { int animationTick = __instance.AnimationTick; if (__instance.rootNode.AnimationWorker is AnimationWorker_KeyframesExtended rootAnimWorkerExtended) { //recache during facing turn if (rootAnimWorkerExtended.shouldRecache(animationTick)) { __instance.rootNode.requestRecache = true; return; } } foreach (PawnRenderNode node in __instance.rootNode.children) { if (node.AnimationWorker is AnimationWorker_KeyframesExtended animWorkerExtended) { //recache during facing turn if (animWorkerExtended.shouldRecache(animationTick)) { node.requestRecache = true; return; } } } } } }