rimworld-animations/1.5/Source/Patches/RimworldPatches/HarmonyPatch_PawnRenderTree.cs

108 lines
3.8 KiB
C#

using HarmonyLib;
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse;
namespace Rimworld_Animations
{
[HarmonyPatch(typeof(PawnRenderTree), "TryGetMatrix")]
public class HarmonyPatch_PawnRenderTree
{
public static bool Prefix(PawnRenderTree __instance, Dictionary<PawnRenderNodeTagDef, PawnRenderNode> ___nodesByTag, PawnRenderNode node, ref PawnDrawParms parms, ref Matrix4x4 matrix, ref bool __result)
{
/*
* Facing fix
*/
//find lowest parent that is animating, or nothing if not animating
PawnRenderNode animatingNode = node;
while (animatingNode != null
&& !(animatingNode.AnimationWorker is AnimationWorker_KeyframesExtended))
{
animatingNode = animatingNode.parent;
}
//if animating parent node found,
if (animatingNode?.AnimationWorker is AnimationWorker_KeyframesExtended animatingNodeAnimationWorker)
{
//change parm to facing to animate correctly
parms.facing = animatingNodeAnimationWorker.facingAtTick(__instance.AnimationTick);
}
/*
* Set Render Node to absolute position
*/
if (node.Props is PawnRenderNodeProperties_GraphicVariants graphicVariantProp
&& graphicVariantProp.absoluteTransform)
{
matrix = parms.matrix;
//absolute transform -- just use the node's transform, not its ancestors
node.GetTransform(parms, out Vector3 offset, out Vector3 pivot, out Quaternion quaternion, out Vector3 scale);
if (offset != Vector3.zero) matrix *= Matrix4x4.Translate(offset);
if (pivot != Vector3.zero) matrix *= Matrix4x4.Translate(pivot);
if (quaternion != Quaternion.identity) matrix *= Matrix4x4.Rotate(quaternion);
if (scale != Vector3.one) matrix *= Matrix4x4.Scale(scale);
if (pivot != Vector3.zero) matrix *= Matrix4x4.Translate(scale).inverse;
float num = node.Worker.AltitudeFor(node, parms);
if (num != 0f)
{
matrix *= Matrix4x4.Translate(Vector3.up * num);
}
__result = true;
return false;
}
return true;
}
}
//recaching
//done here because changing parms causes recaching anyway, so might as well do it here
[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 flicker on/off
if (animWorkerExtended.shouldRecache(animationTick))
{
node.requestRecache = true;
return;
}
}
}
}
}
}