fixed hair anchors

todo: fix HAR head addon anchors
This commit is contained in:
c0ffee 2021-07-22 16:04:21 -07:00
parent f8d3f3c63b
commit d6ddf0e6d0
7 changed files with 117 additions and 31 deletions

View File

@ -36,7 +36,7 @@
<Private>False</Private>
</Reference>
<Reference Include="AlienRace">
<HintPath>..\..\..\..\workshop\content\294100\839005762\1.2\Assemblies\AlienRace.dll</HintPath>
<HintPath>..\..\..\..\workshop\content\294100\839005762\1.3\Assemblies\AlienRace.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Assembly-CSharp">
@ -55,13 +55,11 @@
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="UnityEngine, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<Reference Include="UnityEngine">
<HintPath>..\..\RimWorldWin64_Data\Managed\UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<Reference Include="UnityEngine.CoreModule">
<HintPath>..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
@ -94,6 +92,7 @@
<Compile Include="Source\Patches\HarmonyPatch_DontShaveYourHead.cs" />
<Compile Include="Source\Patches\HarmonyPatch_FacialAnimation.cs" />
<Compile Include="Source\Patches\HarmonyPatch_HatsDisplaySelection.cs" />
<Compile Include="Source\Patches\HarmonyPatch_HeadHair.cs" />
<Compile Include="Source\Patches\HarmonyPatch_PawnRenderer.cs" />
<Compile Include="Source\Patches\HarmonyPatch_PawnRotation.cs" />
<Compile Include="Source\Patches\HarmonyPatch_Pawn_DrawTracker.cs" />

View File

@ -161,12 +161,15 @@ namespace Rimworld_Animations {
}
}
public static void AdjustHead(ref Quaternion quat, ref Rot4 bodyFacing, ref Vector3 pos, Pawn pawn)
public static void AdjustHead(ref Quaternion quat, ref Rot4 bodyFacing, ref Vector3 pos, ref float angle, Pawn pawn, PawnRenderFlags flags)
{
if (flags.FlagSet(PawnRenderFlags.Portrait)) return;
CompBodyAnimator anim = pawn.TryGetComp<CompBodyAnimator>();
if (anim.isAnimating)
{
bodyFacing = anim.headFacing;
angle = anim.headAngle;
quat = Quaternion.AngleAxis(anim.headAngle, Vector3.up);
pos = anim.getPawnHeadOffset();
}

View File

@ -22,6 +22,7 @@ namespace Rimworld_Animations {
prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_AlienRace), "Prefix_StopResolveAllGraphicsWhileSex")));
(new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("AlienRace.HarmonyPatches"), "DrawAddons"),
//transpiler: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_AlienRace), "Transpiler_HeadRotation")),
prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_AlienRace), "Prefix_AnimateHeadAddons")));
}
}))();
@ -39,8 +40,32 @@ namespace Rimworld_Animations {
return true;
}
public static bool Prefix_AnimateHeadAddons(bool portrait, Vector3 vector, Vector3 headOffset, Pawn pawn, Quaternion quat, Rot4 rotation, bool invisible) {
public static float RotateHeadAddon(float initialRotation, Pawn pawn)
{
return pawn.TryGetComp<CompBodyAnimator>().headAngle + initialRotation;
}
public static IEnumerable<CodeInstruction> Transpiler_HeadRotation(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> ins = instructions.ToList();
for (int i = 0; i < ins.Count; i++)
{
yield return ins[i];
if(ins[i].opcode == OpCodes.Stloc_S && ins[i].OperandIs((object)6))
{
yield return new CodeInstruction(OpCodes.Ldloc_S, (object)6);
yield return new CodeInstruction(OpCodes.Ldarg_S, (object)4);
yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(HarmonyPatch_AlienRace), "RotateHeadAddon"));
yield return new CodeInstruction(OpCodes.Stloc_S, (object)6);
}
}
}
public static bool Prefix_AnimateHeadAddons(PawnRenderFlags renderFlags, ref Vector3 vector, ref Vector3 headOffset, Pawn pawn, ref Quaternion quat, ref Rot4 rotation) {
/* old patch for 1.2
if (portrait || pawn.TryGetComp<CompBodyAnimator>() == null || !pawn.TryGetComp<CompBodyAnimator>().isAnimating) return true;
if (!(pawn.def is ThingDef_AlienRace alienProps) || invisible) return false;
@ -52,29 +77,9 @@ namespace Rimworld_Animations {
AlienPartGenerator.BodyAddon ba = addons[index: i];
if (!ba.CanDrawAddon(pawn: pawn)) continue;
AlienPartGenerator.RotationOffset offset;
if (ba.drawnInBed || ba.alignWithHead) {
offset = pawnAnimator.headFacing == Rot4.South ?
ba.offsets.south :
pawnAnimator.headFacing == Rot4.North ?
ba.offsets.north :
pawnAnimator.headFacing == Rot4.East ?
ba.offsets.east :
ba.offsets.west;
AlienPartGenerator.RotationOffset offset = ba.defaultOffsets.GetOffset((ba.drawnInBed || ba.alignWithHead) ? pawnAnimator.headFacing : rotation);
Vector3 a = (offset != null) ? offset.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, comp.crownType) : Vector3.zero;
} else {
offset = rotation == Rot4.South ?
ba.offsets.south :
rotation == Rot4.North ?
ba.offsets.north :
rotation == Rot4.East ?
ba.offsets.east :
ba.offsets.west;
}
Vector2 bodyOffset = (portrait ? offset?.portraitBodyTypes ?? offset?.bodyTypes : offset?.bodyTypes)?.FirstOrDefault(predicate: to => to.bodyType == pawn.story.bodyType)
?.offset ?? Vector2.zero;
@ -145,8 +150,59 @@ namespace Rimworld_Animations {
}
CompBodyAnimator pawnAnimator = pawn.TryGetComp<CompBodyAnimator>();
ThingDef_AlienRace thingDef_AlienRace = pawn.def as ThingDef_AlienRace;
if (thingDef_AlienRace == null || renderFlags.FlagSet(PawnRenderFlags.Invisible))
{
return false;
}
List<AlienPartGenerator.BodyAddon> bodyAddons = thingDef_AlienRace.alienRace.generalSettings.alienPartGenerator.bodyAddons;
AlienPartGenerator.AlienComp comp = pawn.GetComp<AlienPartGenerator.AlienComp>();
for (int i = 0; i < bodyAddons.Count; i++)
{
AlienPartGenerator.BodyAddon bodyAddon = bodyAddons[i];
if (bodyAddon.CanDrawAddon(pawn))
{
AlienPartGenerator.RotationOffset offset = bodyAddon.defaultOffsets.GetOffset((bodyAddon.drawnInBed || bodyAddon.alignWithHead) ? pawnAnimator.headFacing : rotation);
Vector3 a = (offset != null) ? offset.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, comp.crownType) : Vector3.zero;
AlienPartGenerator.RotationOffset offset2 = bodyAddon.offsets.GetOffset((bodyAddon.drawnInBed || bodyAddon.alignWithHead) ? pawnAnimator.headFacing : rotation);
Vector3 vector2 = a + ((offset2 != null) ? offset2.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, comp.crownType) : Vector3.zero);
vector2.y = (bodyAddon.inFrontOfBody ? (0.3f + vector2.y) : (-0.3f - vector2.y));
float num = bodyAddon.angle;
if (rotation == Rot4.North)
{
if (bodyAddon.layerInvert)
{
vector2.y = -vector2.y;
}
num = 0f;
}
if (rotation == Rot4.East)
{
num = -num;
vector2.x = -vector2.x;
}
Graphic graphic = comp.addonGraphics[i];
graphic.drawSize = ((renderFlags.FlagSet(PawnRenderFlags.Portrait) && bodyAddon.drawSizePortrait != Vector2.zero) ? bodyAddon.drawSizePortrait : bodyAddon.drawSize) * (bodyAddon.scaleWithPawnDrawsize ? (bodyAddon.alignWithHead ? (renderFlags.FlagSet(PawnRenderFlags.Portrait) ? comp.customPortraitHeadDrawSize : comp.customHeadDrawSize) : (renderFlags.FlagSet(PawnRenderFlags.Portrait) ? comp.customPortraitDrawSize : comp.customDrawSize)) : Vector2.one) * 1.5f;
GenDraw.DrawMeshNowOrLater(graphic.MeshAt(rotation), vector + (bodyAddon.alignWithHead ? headOffset : Vector3.zero) + vector2.RotatedBy(Mathf.Acos(Quaternion.Dot(Quaternion.identity, quat)) * 2f * 57.29578f), Quaternion.AngleAxis(num, Vector3.up) * quat, graphic.MatAt(rotation, null), renderFlags.FlagSet(PawnRenderFlags.DrawNow));
}
}
*/
CompBodyAnimator anim = pawn.TryGetComp<CompBodyAnimator>();
if (anim.isAnimating)
{
headOffset = anim.getPawnHeadOffset();
quat = Quaternion.AngleAxis(anim.headAngle * 5, Vector3.up);
rotation = anim.headFacing;
}
return true;
return false;
}
}
}

View File

@ -0,0 +1,22 @@
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using UnityEngine;
namespace Rimworld_Animations
{
[HarmonyPatch(typeof(PawnRenderer), "DrawHeadHair")]
public static class HarmonyPatch_HeadHair
{
public static void Prefix(ref Vector3 headOffset, ref float angle)
{
}
}
}

View File

@ -28,6 +28,9 @@ namespace Rimworld_Animations {
[HarmonyBefore(new string[] { "showhair.kv.rw", "erdelf.HumanoidAlienRaces", "Nals.FacialAnimation" })]
public static void Prefix(PawnRenderer __instance, ref Vector3 rootLoc, ref float angle, bool renderBody, ref Rot4 bodyFacing, RotDrawMode bodyDrawType, PawnRenderFlags flags)
{
if (flags.FlagSet(PawnRenderFlags.Portrait)) return;
PawnGraphicSet graphics = __instance.graphics;
Pawn pawn = graphics.pawn;
CompBodyAnimator bodyAnim = pawn.TryGetComp<CompBodyAnimator>();
@ -54,8 +57,10 @@ namespace Rimworld_Animations {
yield return new CodeInstruction(OpCodes.Ldloca, (object)0);
yield return new CodeInstruction(OpCodes.Ldloca, (object)7);
yield return new CodeInstruction(OpCodes.Ldloca, (object)6);
yield return new CodeInstruction(OpCodes.Ldarga, (object)2);
yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(typeof(PawnRenderer), "pawn"));
yield return new CodeInstruction(OpCodes.Ldarg, (object)6);
yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(AnimationUtility), "AdjustHead"));
yield return ins[i];
//headFacing equals true

View File

@ -16,7 +16,7 @@ namespace Rimworld_Animations
{
static bool ClearCache(Pawn pawn)
{
return pawn.IsInvisible() || pawn.TryGetComp<CompBodyAnimator>().isAnimating;
return pawn.IsInvisible() || pawn.TryGetComp<CompBodyAnimator>().isAnimating;
}
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
@ -27,6 +27,7 @@ namespace Rimworld_Animations
{
if (i.OperandIs(AccessTools.Method(typeof(PawnUtility), "IsInvisible")))
{
yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PawnRenderer_RenderPawnAt_Patch), "ClearCache"));
}
else