diff --git a/1.4/Source/Comps/CompBodyAnimator.cs b/1.4/Source/Comps/CompBodyAnimator.cs
index 5d355a6..123a8aa 100644
--- a/1.4/Source/Comps/CompBodyAnimator.cs
+++ b/1.4/Source/Comps/CompBodyAnimator.cs
@@ -1,18 +1,24 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
using RimWorld;
using rjw;
using UnityEngine;
using Verse;
+using Verse.AI;
using Verse.Sound;
namespace Rimworld_Animations {
public class CompBodyAnimator : ThingComp
{
+ ///
+ /// Cache of the currently animated pawns for the very fast isAnimating checks
+ ///
+ private static readonly HashSet animatingPawns = new HashSet();
+ ///
+ /// Check if the is currently animated by this comp
+ ///
+ public static bool IsAnimating(Pawn pawn) => animatingPawns.Contains(pawn);
+
public Pawn pawn => base.parent as Pawn;
public PawnGraphicSet Graphics;
@@ -27,9 +33,11 @@ namespace Rimworld_Animations {
if (value == true) {
SexUtility.DrawNude(pawn);
+ animatingPawns.Add(pawn);
} else {
pawn.Drawer.renderer.graphics.ResolveAllGraphics();
actorsInCurrentAnimation = null;
+ animatingPawns.Remove(pawn);
}
PortraitsCache.SetDirty(pawn);
@@ -506,9 +514,15 @@ namespace Rimworld_Animations {
public bool LoopNeverending()
{
- if(pawn?.jobs?.curDriver != null &&
- (pawn.jobs.curDriver is JobDriver_Sex) && (pawn.jobs.curDriver as JobDriver_Sex).neverendingsex ||
- (pawn.jobs.curDriver is JobDriver_SexBaseReciever) && (pawn.jobs.curDriver as JobDriver_Sex).Partner?.jobs?.curDriver != null && ((pawn.jobs.curDriver as JobDriver_Sex).Partner.jobs.curDriver as JobDriver_Sex).neverendingsex)
+ JobDriver jobDriver = pawn?.jobs?.curDriver;
+ if (jobDriver == null) return false;
+
+ if (jobDriver is JobDriver_Sex sexDriver && sexDriver.neverendingsex)
+ {
+ return true;
+ }
+
+ if (jobDriver is JobDriver_SexBaseReciever sexReceiverDriver && sexReceiverDriver.Partner?.jobs?.curDriver is JobDriver_Sex partnerSexDriver && partnerSexDriver.neverendingsex)
{
return true;
}
diff --git a/1.4/Source/Extensions/PawnWoundDrawerExtension.cs b/1.4/Source/Extensions/PawnWoundDrawerExtension.cs
index 417f8ed..77594e6 100644
--- a/1.4/Source/Extensions/PawnWoundDrawerExtension.cs
+++ b/1.4/Source/Extensions/PawnWoundDrawerExtension.cs
@@ -1,9 +1,6 @@
-using System;
-using System.Collections.Generic;
-using RimWorld;
+using RimWorld;
using UnityEngine;
using Verse;
-using Rimworld_Animations;
namespace Rimworld_Animations {
@@ -17,9 +14,9 @@ namespace Rimworld_Animations {
if (!flags.FlagSet(PawnRenderFlags.Portrait) && layer == PawnOverlayDrawer.OverlayLayer.Head)
{
- CompBodyAnimator pawnAnimator = pawn.TryGetComp();
- if (pawnAnimator != null && pawnAnimator.isAnimating && pawn.Drawer.renderer.graphics.headGraphic != null)
+ if (CompBodyAnimator.IsAnimating(pawn) && pawn.Drawer.renderer.graphics.headGraphic != null)
{
+ CompBodyAnimator pawnAnimator = pawn.TryGetComp();
pawnRot = pawnAnimator.headFacing;
quat = Quaternion.AngleAxis(angle: pawnAnimator.headAngle, axis: Vector3.up);
float y = drawLoc.y;
diff --git a/1.4/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs b/1.4/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs
index a800a55..1cbc26d 100644
--- a/1.4/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs
+++ b/1.4/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections.Generic;
using Verse;
using RimWorld;
using UnityEngine;
@@ -25,14 +21,13 @@ namespace Rimworld_Animations {
listingStandard.GapLine();
- if (Find.Selector.SingleSelectedThing is Pawn) {
+ if (Find.Selector.SingleSelectedThing is Pawn curPawn) {
- Pawn curPawn = Find.Selector.SingleSelectedThing as Pawn;
+ if (CompBodyAnimator.IsAnimating(curPawn)) {
- if (curPawn.TryGetComp().isAnimating) {
-
- AnimationDef def = curPawn.TryGetComp().CurrentAnimation;
- int ActorIndex = curPawn.TryGetComp().ActorIndex;
+ CompBodyAnimator compBodyAnimator = curPawn.TryGetComp();
+ AnimationDef def = compBodyAnimator.CurrentAnimation;
+ int ActorIndex = compBodyAnimator.ActorIndex;
float offsetX = 0, offsetZ = 0, rotation = 0;
string bodyTypeDef = (curPawn.story?.bodyType != null) ? curPawn.story.bodyType.ToString() : "";
@@ -57,8 +52,6 @@ namespace Rimworld_Animations {
listingStandard.Label("Warning--You generally don't want to change human offsets, only alien offsets");
}
- bool mirrored = curPawn.TryGetComp().Mirror;
-
float.TryParse(listingStandard.TextEntryLabeled("X Offset: ", offsetX.ToString()), out offsetX);
offsetX = listingStandard.Slider(offsetX, -2, 2);
diff --git a/1.4/Source/Patches/OtherModPatches/HarmonyPatch_FacialAnimation.cs b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_FacialAnimation.cs
index 83ffd5b..59631b8 100644
--- a/1.4/Source/Patches/OtherModPatches/HarmonyPatch_FacialAnimation.cs
+++ b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_FacialAnimation.cs
@@ -23,17 +23,16 @@ namespace Rimworld_Animations {
}
}))();
}
- catch (TypeLoadException ex) {
+ catch (TypeLoadException) {
}
}
- public static bool Prefix(ref Pawn ___pawn, ref Rot4 headFacing, ref Vector3 headOrigin, ref Quaternion quaternion, ref bool portrait) {
+ public static bool Prefix(Pawn ___pawn, ref Rot4 headFacing, ref Vector3 headOrigin, ref Quaternion quaternion, bool portrait) {
- CompBodyAnimator bodyAnim = ___pawn.TryGetComp();
-
- if (bodyAnim != null && bodyAnim.isAnimating && !portrait) {
+ if (!portrait && CompBodyAnimator.IsAnimating(___pawn)) {
+ CompBodyAnimator bodyAnim = ___pawn.TryGetComp();
headFacing = bodyAnim.headFacing;
headOrigin = new Vector3(bodyAnim.getPawnHeadPosition().x, headOrigin.y, bodyAnim.getPawnHeadPosition().z);
quaternion = Quaternion.AngleAxis(bodyAnim.headAngle, Vector3.up);
diff --git a/1.4/Source/Patches/RJWPatches/HarmonyPatch_PlaySexSounds.cs b/1.4/Source/Patches/RJWPatches/HarmonyPatch_PlaySexSounds.cs
index 6544f13..25d93b9 100644
--- a/1.4/Source/Patches/RJWPatches/HarmonyPatch_PlaySexSounds.cs
+++ b/1.4/Source/Patches/RJWPatches/HarmonyPatch_PlaySexSounds.cs
@@ -1,11 +1,5 @@
using HarmonyLib;
using rjw;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Verse;
namespace Rimworld_Animations
{
@@ -14,7 +8,7 @@ namespace Rimworld_Animations
{
public static bool Prefix(JobDriver_Sex __instance)
{
- if (__instance.pawn.TryGetComp().isAnimating)
+ if (CompBodyAnimator.IsAnimating(__instance.pawn))
{
return false;
}
diff --git a/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_JoinInBed.cs b/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_JoinInBed.cs
index 18c955e..bbbb0b8 100644
--- a/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_JoinInBed.cs
+++ b/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_JoinInBed.cs
@@ -1,13 +1,9 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using HarmonyLib;
using RimWorld;
using Verse;
using rjw;
-using System.Reflection.Emit;
using Verse.AI;
namespace Rimworld_Animations
@@ -27,11 +23,7 @@ namespace Rimworld_Animations
}
return true;
-
}
-
-
-
}
[HarmonyPatch(typeof(JobDriver_JoinInBed), "MakeNewToils")]
@@ -66,19 +58,13 @@ namespace Rimworld_Animations
toils[3].AddPreTickAction(() =>
{
- if (!__instance.Partner.TryGetComp().isAnimating)
+ if (!CompBodyAnimator.IsAnimating(__instance.Partner))
{
__instance.pawn.TryGetComp().isAnimating = false;
}
});
-
__result = toils.AsEnumerable();
-
-
}
-
-
-
}
}
diff --git a/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseInitiator.cs b/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseInitiator.cs
index 00227c4..530600b 100644
--- a/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseInitiator.cs
+++ b/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseInitiator.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using HarmonyLib;
using RimWorld;
using Verse;
@@ -158,10 +156,12 @@ namespace Rimworld_Animations {
public static void Postfix(ref JobDriver_SexBaseInitiator __instance) {
- if ((__instance.Target as Pawn)?.jobs?.curDriver is JobDriver_SexBaseReciever) {
- if (__instance.pawn.TryGetComp().isAnimating) {
+ Pawn reciever = __instance.Target as Pawn;
- List parteners = ((__instance.Target as Pawn)?.jobs.curDriver as JobDriver_SexBaseReciever).parteners;
+ if (reciever?.jobs?.curDriver is JobDriver_SexBaseReciever recieverJobDriver) {
+ if (CompBodyAnimator.IsAnimating(__instance.pawn)) {
+
+ List parteners = recieverJobDriver.parteners;
for (int i = 0; i < parteners.Count; i++) {
@@ -173,13 +173,13 @@ namespace Rimworld_Animations {
__instance.Target.TryGetComp().isAnimating = false;
- if (xxx.is_human((__instance.Target as Pawn))) {
- (__instance.Target as Pawn)?.Drawer.renderer.graphics.ResolveApparelGraphics();
- PortraitsCache.SetDirty((__instance.Target as Pawn));
+ if (xxx.is_human(reciever)) {
+ reciever?.Drawer.renderer.graphics.ResolveApparelGraphics();
+ PortraitsCache.SetDirty(reciever);
}
}
- ((__instance.Target as Pawn)?.jobs.curDriver as JobDriver_SexBaseReciever).parteners.Remove(__instance.pawn);
+ recieverJobDriver?.parteners.Remove(__instance.pawn);
}
diff --git a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_HeadHair.cs b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_HeadHair.cs
index 37ba6ce..401f1b5 100644
--- a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_HeadHair.cs
+++ b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_HeadHair.cs
@@ -1,4 +1,4 @@
-using HarmonyLib;
+/*using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -19,4 +19,4 @@ namespace Rimworld_Animations
}
}
-}
+}*/
diff --git a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRenderer.cs b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRenderer.cs
index b7ff70d..518f24c 100644
--- a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRenderer.cs
+++ b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRenderer.cs
@@ -5,7 +5,6 @@ using HarmonyLib;
using RimWorld;
using Verse;
using UnityEngine;
-using System.Reflection;
using System.Reflection.Emit;
namespace Rimworld_Animations {
@@ -31,12 +30,10 @@ namespace Rimworld_Animations {
PawnGraphicSet graphics = __instance.graphics;
Pawn pawn = graphics.pawn;
- CompBodyAnimator bodyAnim = pawn.TryGetComp();
-
- if (bodyAnim != null && bodyAnim.isAnimating && pawn.Map == Find.CurrentMap)
+ if (CompBodyAnimator.IsAnimating(pawn) && pawn.Map == Find.CurrentMap)
{
- bodyAnim.animatePawnBody(ref rootLoc, ref angle, ref bodyFacing);
+ pawn.TryGetComp().animatePawnBody(ref rootLoc, ref angle, ref bodyFacing);
}
@@ -75,7 +72,7 @@ namespace Rimworld_Animations {
else
{
yield return ins[i];
- }
+ }
}
}
}
diff --git a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRotation.cs b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRotation.cs
index 7ec75a1..cf2a7d9 100644
--- a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRotation.cs
+++ b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRotation.cs
@@ -1,29 +1,23 @@
using HarmonyLib;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Verse;
namespace Rimworld_Animations {
- [HarmonyPatch(typeof(Thing), "Rotation", MethodType.Getter)]
+ [HarmonyPatch(typeof(Thing), nameof(Thing.Rotation), MethodType.Getter)]
public static class HarmonyPatch_PawnRotation {
public static bool Prefix(Thing __instance, ref Rot4 __result) {
- if(!(__instance is Pawn) || (__instance as Pawn)?.TryGetComp() == null || !(__instance as Pawn).TryGetComp().isAnimating) {
+ if (!(__instance is Pawn pawn)) {
+ return true;
+ }
+
+ if (!CompBodyAnimator.IsAnimating(pawn)) {
return true;
}
- Pawn pawn = (__instance as Pawn);
__result = pawn.TryGetComp().bodyFacing;
return false;
-
-
}
-
}
-
}
diff --git a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_Pawn_DrawTracker.cs b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_Pawn_DrawTracker.cs
index 5cdcfce..fdd3e07 100644
--- a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_Pawn_DrawTracker.cs
+++ b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_Pawn_DrawTracker.cs
@@ -1,9 +1,4 @@
using HarmonyLib;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using UnityEngine;
using Verse;
@@ -13,10 +8,9 @@ namespace Rimworld_Animations {
public static class HarmonyPatch_Pawn_DrawTracker {
public static bool Prefix(ref Pawn ___pawn, ref Vector3 __result) {
- CompBodyAnimator bodyAnim = ___pawn.TryGetComp();
-
- if (bodyAnim != null && bodyAnim.isAnimating) {
- __result = ___pawn.TryGetComp().anchor + ___pawn.TryGetComp().deltaPos;
+ if (CompBodyAnimator.IsAnimating(___pawn)) {
+ CompBodyAnimator bodyAnim = ___pawn.TryGetComp();
+ __result = bodyAnim.anchor + bodyAnim.deltaPos;
return false;
}
diff --git a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_ResolveApparelGraphics.cs b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_ResolveApparelGraphics.cs
index 0f5d978..379f85e 100644
--- a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_ResolveApparelGraphics.cs
+++ b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_ResolveApparelGraphics.cs
@@ -1,9 +1,4 @@
using HarmonyLib;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Verse;
namespace Rimworld_Animations
@@ -13,8 +8,7 @@ namespace Rimworld_Animations
{
public static bool Prefix(ref Pawn ___pawn)
{
-
- if (___pawn.TryGetComp() != null && ___pawn.TryGetComp().isAnimating)
+ if (CompBodyAnimator.IsAnimating(___pawn))
{
return false;
}
diff --git a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_SetPawnAnimatable.cs b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_SetPawnAnimatable.cs
index b8c66b8..f495bff 100644
--- a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_SetPawnAnimatable.cs
+++ b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_SetPawnAnimatable.cs
@@ -1,12 +1,6 @@
using HarmonyLib;
using RimWorld;
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Reflection.Emit;
-using System.Text;
-using System.Threading.Tasks;
-using UnityEngine;
using Verse;
namespace Rimworld_Animations
@@ -16,18 +10,16 @@ namespace Rimworld_Animations
{
static bool ClearCache(Pawn pawn)
{
- return pawn.IsInvisible() || (pawn.TryGetComp() != null && pawn.TryGetComp().isAnimating);
+ return pawn.IsInvisible() || CompBodyAnimator.IsAnimating(pawn);
}
public static IEnumerable Transpiler(IEnumerable instructions)
{
- var list = instructions.ToList();
-
foreach (CodeInstruction i in instructions)
{
- if (i.OperandIs(AccessTools.Method(typeof(PawnUtility), "IsInvisible")))
+ if (i.Calls(AccessTools.Method(typeof(PawnUtility), nameof(PawnUtility.IsInvisible))))
{
- yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PawnRenderer_RenderPawnAt_Patch), "ClearCache"));
+ yield return CodeInstruction.Call(typeof(PawnRenderer_RenderPawnAt_Patch), nameof(ClearCache));
}
else
{
diff --git a/1.4/Source/Utilities/AnimationUtility.cs b/1.4/Source/Utilities/AnimationUtility.cs
index 1ae89be..396eab3 100644
--- a/1.4/Source/Utilities/AnimationUtility.cs
+++ b/1.4/Source/Utilities/AnimationUtility.cs
@@ -169,11 +169,10 @@ namespace Rimworld_Animations {
return;
}
- CompBodyAnimator pawnAnimator = pawn.TryGetComp();
-
- if (pawnAnimator == null || !pawnAnimator.isAnimating) {
+ if (!CompBodyAnimator.IsAnimating(pawn)) {
GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, drawNow);
} else {
+ CompBodyAnimator pawnAnimator = pawn.TryGetComp();
Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition();
pawnHeadPosition.y = loc.y;
GenDraw.DrawMeshNowOrLater(MeshPool.humanlikeHeadSet.MeshAt(pawnAnimator.headFacing), pawnHeadPosition, Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up), material, true);
@@ -184,14 +183,13 @@ namespace Rimworld_Animations {
{
if (flags.FlagSet(PawnRenderFlags.Portrait)) return;
- CompBodyAnimator anim = pawn.TryGetComp();
- if (anim.isAnimating)
+ if (CompBodyAnimator.IsAnimating(pawn))
{
+ CompBodyAnimator anim = pawn.TryGetComp();
bodyFacing = anim.headFacing;
angle = anim.headAngle;
quat = Quaternion.AngleAxis(anim.headAngle, Vector3.up);
pos = anim.getPawnHeadOffset();
-
}
}
@@ -202,12 +200,12 @@ namespace Rimworld_Animations {
return;
}
- CompBodyAnimator pawnAnimator = pawn.TryGetComp();
- if (pawnAnimator == null || !pawnAnimator.isAnimating || portrait) {
+ if (!CompBodyAnimator.IsAnimating(pawn) || portrait) {
GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, portrait);
}
else {
+ CompBodyAnimator pawnAnimator = pawn.TryGetComp();
Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition();
pawnHeadPosition.x *= bodySizeFactor;
pawnHeadPosition.x *= bodySizeFactor;
diff --git a/About/Manifest.xml b/About/Manifest.xml
index 755ff76..0a6d4c7 100644
--- a/About/Manifest.xml
+++ b/About/Manifest.xml
@@ -1,5 +1,5 @@
Rimworld-Animations
- 1.3.4
+ 1.3.7
diff --git a/Patch_HumanoidAlienRaces/Patch_HumanoidAlienRaces.csproj b/Patch_HumanoidAlienRaces/Patch_HumanoidAlienRaces.csproj
index e34e96e..e495f73 100644
--- a/Patch_HumanoidAlienRaces/Patch_HumanoidAlienRaces.csproj
+++ b/Patch_HumanoidAlienRaces/Patch_HumanoidAlienRaces.csproj
@@ -1,4 +1,4 @@
-
+
@@ -12,6 +12,7 @@
v4.8
512
true
+ 9
false
diff --git a/Patch_HumanoidAlienRaces/Source/HarmonyPatch_AlienRace.cs b/Patch_HumanoidAlienRaces/Source/HarmonyPatch_AlienRace.cs
index 8ab0255..ae2a09b 100644
--- a/Patch_HumanoidAlienRaces/Source/HarmonyPatch_AlienRace.cs
+++ b/Patch_HumanoidAlienRaces/Source/HarmonyPatch_AlienRace.cs
@@ -6,52 +6,162 @@ using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
+using System.Runtime.CompilerServices;
using UnityEngine;
using Verse;
using AlienRace;
-namespace Rimworld_Animations {
-
-
+namespace Rimworld_Animations
+{
[StaticConstructorOnStartup]
public static class HarmonyPatch_AlienRace
{
+ static readonly Type AlienRace_HarmonyPatches = AccessTools.TypeByName("AlienRace.HarmonyPatches");
+
+ static readonly MethodInfo InnerDrawAddon;
+ static readonly FieldInfo AccessForPawn;
+ static readonly FieldInfo AccessForRotation;
+
static HarmonyPatch_AlienRace()
{
- (new Harmony("rjwanim")).Patch(AccessTools.Method(AccessTools.TypeByName("AlienRace.HarmonyPatches"), "DrawAddons"),
- prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_AlienRace), "Prefix_AnimateHeadAddons")));
+ AccessForPawn = null;
+ AccessForRotation = null;
+ InnerDrawAddon = AccessTools.FirstMethod(AlienRace_HarmonyPatches, (mi) =>
+ {
+ if (mi.GetCustomAttribute() is null) return false;
+ if (mi.ReturnType != typeof(void)) return false;
+ if (!mi.Name.Contains("DrawAddon")) return false;
+
+ var parameters = mi.GetParameters();
+ if (parameters.Length != 4) return false;
+ if (parameters[0].ParameterType != typeof(AlienPartGenerator.BodyAddon)) return false;
+ if (parameters[1].ParameterType != typeof(Graphic)) return false;
+ if (parameters[2].ParameterType != typeof(Vector2)) return false;
+ return true;
+ });
+
+ if (InnerDrawAddon is null)
+ {
+ Log.Error("[rjwanim] Failed to apply Alien Race patches: could not find local `DrawAddon` method.");
+ return;
+ }
+
+ // Extract the closure struct. This is passed with `ref`, so we have
+ // to also pull the element type to get rid of that.
+ var displayClassType = InnerDrawAddon.GetParameters()[3].ParameterType.GetElementType();
+
+ if (displayClassType is null)
+ {
+ Log.Error("[rjwanim] Failed to apply Alien Race patches: could not get type of `DrawAddon` closure.");
+ return;
+ }
+
+ AccessForPawn = AccessTools.Field(displayClassType, "pawn");
+
+ if (AccessForPawn is null)
+ {
+ Log.Error("[rjwanim] Failed to apply Alien Race patches: could not find field `pawn` of closure.");
+ return;
+ }
+
+ AccessForRotation = AccessTools.Field(displayClassType, "rotation");
+
+ if (AccessForRotation is null)
+ {
+ Log.Error("[rjwanim] Failed to apply Alien Race patches: could not find field `rotation` of closure.");
+ return;
+ }
+
+ // Got access to everything. It should be safe to setup the patches.
+ var harmonyInstance = new Harmony("rjwanim");
+ harmonyInstance.Patch(
+ InnerDrawAddon,
+ prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_AlienRace), nameof(Prefix_FixDrawAddonRotation))),
+ postfix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_AlienRace), nameof(Postfix_FixDrawAddonRotation)))
+ );
+ harmonyInstance.Patch(
+ AccessTools.Method(AlienRace_HarmonyPatches, "DrawAddonsFinalHook"),
+ postfix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_AlienRace), nameof(Postfix_DrawAddonsFinalHook)))
+ );
}
- /* todo: replace jank prefix with this
- public static void Prefix_DrawAddonsFinalHook(ref Pawn pawn, ref AlienPartGenerator.BodyAddon addon, ref Rot4 rot, ref Graphic graphic, ref Vector3 offsetVector, ref float angle, ref Material mat)
- {
- CompBodyAnimator animator = pawn.TryGetComp();
+ public static bool ShouldForceDrawForBody(Pawn pawn, AlienPartGenerator.BodyAddon addon)
+ {
+ if (pawn.def is not ThingDef_AlienRace alienProps) return false;
- if (animator == null || !animator.isAnimating)
- {
- return;
- }
+ if (alienProps.defName.Contains("Orassan") && addon.path.ToLower().Contains("tail"))
+ return true;
- if(addon.alignWithHead || addon.drawnInBed)
- {
- rot = animator.headFacing;
+ return false;
+ }
+
+ // The parameter `__3` is the compiler generated closure struct.
+ // Even though `__3` is a value type passed by reference, receiving it as
+ // an object boxes the underlying reference, so we don't need `ref` here.
+ // In fact, if you try to add it, RimWorld will crash outright!
+ public static void Prefix_FixDrawAddonRotation(AlienPartGenerator.BodyAddon ba, object __3, out Rot4 __state)
+ {
+ // Store the original rotation so we can restore it later.
+ __state = (Rot4)AccessForRotation.GetValue(__3);
+ if (ba is null) return;
+
+ var pawn = (Pawn)AccessForPawn.GetValue(__3);
+ if (pawn.TryGetComp() is not { } animator) return;
+ if (!animator.isAnimating) return;
+
+ var forceDrawForBody = ShouldForceDrawForBody(pawn, ba);
+
+ // Set the rotation according to the animation.
+ if ((ba.drawnInBed && !forceDrawForBody) || ba.alignWithHead)
+ AccessForRotation.SetValue(__3, animator.headFacing);
+ else
+ AccessForRotation.SetValue(__3, animator.bodyFacing);
+ }
+
+ public static void Postfix_FixDrawAddonRotation(object __3, Rot4 __state)
+ {
+ // Restore the original value, since we're in a loop and the next
+ // part may need the previous rotation. Just being safe.
+ AccessForRotation.SetValue(__3, __state);
+ }
+
+ public static void Postfix_DrawAddonsFinalHook(Pawn pawn, AlienPartGenerator.BodyAddon addon, Rot4 rot, ref Vector3 offsetVector, ref float angle)
+ {
+ if (pawn.TryGetComp() is not { } animator) return;
+ if (!animator.isAnimating) return;
+
+ var forceDrawForBody = ShouldForceDrawForBody(pawn, addon);
+
+ if ((addon.drawnInBed && !forceDrawForBody) || addon.alignWithHead)
+ {
angle = animator.headAngle;
- offsetVector += animator.deltaPos + animator.bodyAngle * animator.headBob;
-
+ offsetVector += animator.deltaPos + animator.headBob;
}
else
- {
- rot = animator.bodyFacing;
- angle = animator.bodyAngle;
+ {
+ if (AnimationSettings.controlGenitalRotation && addon.path.ToLower().Contains("penis"))
+ angle = animator.genitalAngle;
+ else
+ angle = animator.bodyAngle;
offsetVector += animator.deltaPos;
- }
-
- }
- */
+ }
+
+ if (rot == Rot4.North && addon.layerInvert)
+ {
+ offsetVector.y = -offsetVector.y;
+ }
+
+ if (rot == Rot4.East)
+ {
+ angle *= -1f;
+ offsetVector.x = -offsetVector.x;
+ }
+ }
+
public static bool Prefix_AnimateHeadAddons(PawnRenderFlags renderFlags, Vector3 vector, Vector3 headOffset, Pawn pawn, Quaternion quat, Rot4 rotation)
{
- if (renderFlags.FlagSet(PawnRenderFlags.Portrait) || pawn.TryGetComp() == null || !pawn.TryGetComp().isAnimating) return true;
+ if (renderFlags.FlagSet(PawnRenderFlags.Portrait) || !CompBodyAnimator.IsAnimating(pawn)) return true;
if (!(pawn.def is ThingDef_AlienRace alienProps) || renderFlags.FlagSet(PawnRenderFlags.Invisible)) return false;
List addons = alienProps.alienRace.generalSettings.alienPartGenerator.bodyAddons;
@@ -64,14 +174,14 @@ namespace Rimworld_Animations {
for (int i = 0; i < addons.Count; i++)
{
AlienPartGenerator.BodyAddon ba = addons[index: i];
-
+
if (!ba.CanDrawAddon(pawn: pawn)) continue;
bool forceDrawForBody = false;
if (alienProps.defName.Contains("Orassan") && ba.path.ToLower().Contains("tail"))
- {
+ {
forceDrawForBody = true;
- }
+ }
AlienPartGenerator.RotationOffset offset = ba.defaultOffsets.GetOffset((ba.drawnInBed && !forceDrawForBody) || ba.alignWithHead ? pawnAnimator.headFacing : pawnAnimator.bodyFacing);
Vector3 a = (offset != null) ? offset.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, pawn.story.headType) : Vector3.zero;
AlienPartGenerator.RotationOffset offset2 = ba.offsets.GetOffset((ba.drawnInBed && !forceDrawForBody) || ba.alignWithHead ? pawnAnimator.headFacing : pawnAnimator.bodyFacing);
@@ -97,37 +207,46 @@ namespace Rimworld_Animations {
if ((ba.drawnInBed && !forceDrawForBody) || ba.alignWithHead)
{
-
+
Quaternion addonRotation = Quaternion.AngleAxis(pawnAnimator.headAngle < 0 ? 360 - (360 % pawnAnimator.headAngle) : pawnAnimator.headAngle, Vector3.up);
GenDraw.DrawMeshNowOrLater(mesh: addonGraphic.MeshAt(rot: pawnAnimator.headFacing), loc: vector + (ba.alignWithHead ? headOffset : headOffset - addonRotation * pawn.Drawer.renderer.BaseHeadOffsetAt(pawnAnimator.headFacing)) + vector2.RotatedBy(angle: Mathf.Acos(f: Quaternion.Dot(a: Quaternion.identity, b: addonRotation)) * 2f * 57.29578f),
quat: Quaternion.AngleAxis(angle: num, axis: Vector3.up) * addonRotation, mat: addonGraphic.MatAt(rot: pawnAnimator.headFacing), renderFlags.FlagSet(PawnRenderFlags.DrawNow));
-
+
}
else
{
Quaternion addonRotation;
if (AnimationSettings.controlGenitalRotation && ba.path.ToLower().Contains("penis"))
- {
+ {
addonRotation = Quaternion.AngleAxis(pawnAnimator.genitalAngle, Vector3.up);
}
else
- {
+ {
addonRotation = Quaternion.AngleAxis(pawnAnimator.bodyAngle, Vector3.up);
}
-
+
if (AnimationSettings.controlGenitalRotation && pawnAnimator.controlGenitalAngle && ba?.hediffGraphics != null && ba.hediffGraphics.Count != 0 && ba.hediffGraphics[0]?.path != null && (ba.hediffGraphics[0].path.Contains("Penis") || ba.hediffGraphics[0].path.Contains("penis")))
{
- GenDraw.DrawMeshNowOrLater(mesh: addonGraphic.MeshAt(rot: rotation), loc: vector + (ba.alignWithHead ? headOffset : Vector3.zero) + vector2.RotatedBy(angle: Mathf.Acos(f: Quaternion.Dot(a: Quaternion.identity, b: addonRotation)) * 2f * 57.29578f),
- quat: Quaternion.AngleAxis(angle: pawnAnimator.genitalAngle, axis: Vector3.up), mat: addonGraphic.MatAt(rot: rotation), renderFlags.FlagSet(PawnRenderFlags.DrawNow));
+ GenDraw.DrawMeshNowOrLater(
+ mesh: addonGraphic.MeshAt(rot: rotation),
+ loc: vector + (ba.alignWithHead ? headOffset : Vector3.zero) + vector2.RotatedBy(angle: Mathf.Acos(f: Quaternion.Dot(a: Quaternion.identity, b: addonRotation)) * 2f * 57.29578f),
+ quat: Quaternion.AngleAxis(angle: pawnAnimator.genitalAngle, axis: Vector3.up),
+ mat: addonGraphic.MatAt(rot: rotation),
+ drawNow: renderFlags.FlagSet(PawnRenderFlags.DrawNow)
+ );
}
-
else
- {
- GenDraw.DrawMeshNowOrLater(mesh: addonGraphic.MeshAt(rot: rotation), loc: vector + (ba.alignWithHead ? headOffset : Vector3.zero) + vector2.RotatedBy(angle: Mathf.Acos(f: Quaternion.Dot(a: Quaternion.identity, b: addonRotation)) * 2f * 57.29578f),
- quat: Quaternion.AngleAxis(angle: num, axis: Vector3.up) * addonRotation, mat: addonGraphic.MatAt(rot: rotation), renderFlags.FlagSet(PawnRenderFlags.DrawNow));
+ {
+ GenDraw.DrawMeshNowOrLater(
+ mesh: addonGraphic.MeshAt(rot: rotation),
+ loc: vector + (ba.alignWithHead ? headOffset : Vector3.zero) + vector2.RotatedBy(angle: Mathf.Acos(f: Quaternion.Dot(a: Quaternion.identity, b: addonRotation)) * 2f * 57.29578f),
+ quat: Quaternion.AngleAxis(angle: num, axis: Vector3.up) * addonRotation,
+ mat: addonGraphic.MatAt(rot: rotation),
+ drawNow: renderFlags.FlagSet(PawnRenderFlags.DrawNow)
+ );
}
}
@@ -143,20 +262,20 @@ namespace Rimworld_Animations {
/*
- [HarmonyPatch(typeof(AlienRace.HarmonyPatches), "DrawAddons")]
- public static class HarmonyPatch_AlienRace {
+ [HarmonyPatch(typeof(AlienRace.HarmonyPatches), "DrawAddons")]
+ public static class HarmonyPatch_AlienRace {
public static void RenderHeadAddonInAnimation(Mesh mesh, Vector3 loc, Quaternion quat, Material mat, bool drawNow, Graphic graphic, AlienPartGenerator.BodyAddon bodyAddon, Vector3 v, Vector3 headOffset, Pawn pawn, PawnRenderFlags renderFlags, Vector3 vector, Rot4 rotation)
- {
+ {
CompBodyAnimator pawnAnimator = pawn.TryGetComp();
AlienPartGenerator.AlienComp comp = pawn.GetComp();
if (pawnAnimator != null && pawnAnimator.isAnimating)
- {
+ {
if((bodyAddon.drawnInBed || bodyAddon.alignWithHead))
- {
+ {
AlienPartGenerator.RotationOffset offset = bodyAddon.defaultOffsets.GetOffset(rotation);
Vector3 a = (offset != null) ? offset.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, comp.crownType) : Vector3.zero;
@@ -184,7 +303,7 @@ namespace Rimworld_Animations {
mat = graphic.MatAt(rot: pawnAnimator.headFacing);
}
else
- {
+ {
AlienPartGenerator.RotationOffset offset = bodyAddon.defaultOffsets.GetOffset(rotation);
Vector3 a = (offset != null) ? offset.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, comp.crownType) : Vector3.zero;
@@ -215,17 +334,17 @@ namespace Rimworld_Animations {
/*
if (pawnAnimator != null && !renderFlags.FlagSet(PawnRenderFlags.Portrait) && pawnAnimator.isAnimating && (bodyAddon.drawnInBed || bodyAddon.alignWithHead))
- {
+ {
if ((pawn.def as ThingDef_AlienRace).defName == "Alien_Orassan")
- {
+ {
orassan = true;
if(bodyAddon.path.Contains("closed"))
- {
+ {
return;
- }
+ }
if (bodyAddon.bodyPart.Contains("ear"))
@@ -239,10 +358,10 @@ namespace Rimworld_Animations {
orassanv.y += 1f;
if(bodyAddon.bodyPart.Contains("left"))
- {
+ {
orassanv.x += 0.03f;
- } else
- {
+ } else
+ {
orassanv.x -= 0.03f;
}
@@ -256,7 +375,7 @@ namespace Rimworld_Animations {
orassanv.x = 0.1f;
}
else
- {
+ {
orassanv.z -= 0.1f;
orassanv.y += 1f;
@@ -282,7 +401,7 @@ namespace Rimworld_Animations {
}
else
- {
+ {
}
@@ -291,16 +410,16 @@ namespace Rimworld_Animations {
public static IEnumerable Transpiler(IEnumerable instructions)
- {
+ {
List ins = instructions.ToList();
for (int i = 0; i < ins.Count; i++)
- {
+ {
Type[] type = new Type[] { typeof(Mesh), typeof(Vector3), typeof(Quaternion), typeof(Material), typeof(bool) };
if (ins[i].OperandIs(AccessTools.Method(typeof(GenDraw), "DrawMeshNowOrLater", type)))
- {
+ {
yield return new CodeInstruction(OpCodes.Ldloc, (object)7); //graphic
yield return new CodeInstruction(OpCodes.Ldloc, (object)4); //bodyAddon
@@ -313,28 +432,28 @@ namespace Rimworld_Animations {
yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(HarmonyPatch_AlienRace), "RenderHeadAddonInAnimation"));
- }
+ }
else
- {
+ {
yield return ins[i];
}
- }
- }
+ }
+ }
public static bool Prefix(PawnRenderFlags renderFlags, ref Vector3 vector, ref Vector3 headOffset, Pawn pawn, ref Quaternion quat, ref Rot4 rotation)
{
if(pawn == null)
- {
+ {
return true;
}
CompBodyAnimator anim = pawn.TryGetComp();
if(anim == null)
- {
+ {
return true;
- }
+ }
if (anim != null && !renderFlags.FlagSet(PawnRenderFlags.Portrait) && anim.isAnimating)
{
diff --git a/Patch_SexToysMasturbation/1.4/Defs/AnimationDefs/Animations_Dildo.xml b/Patch_SexToysMasturbation/1.4/Defs/AnimationDefs/Animations_Dildo.xml
new file mode 100644
index 0000000..dd483ea
--- /dev/null
+++ b/Patch_SexToysMasturbation/1.4/Defs/AnimationDefs/Animations_Dildo.xml
@@ -0,0 +1,465 @@
+
+
+
+ Masturbation_DildoVaginal
+ dildo masturbation
+ vagina
+ true
+
+ Masturbation
+
+
+
+
+ Human
+
+ true
+
+
+
+
+
+ Masturbating
+ true
+ 917
+ 0
+
+
+ LayingPawn
+
+
+
+ 40
+ 73.01611
+ 40.0739746
+ 0
+ 0.054543376
+ 0.112624526
+ 0
+ 3
+ 3
+
+
+
+ Slimy
+ 30
+ 76.4867554
+ 45.3887634
+ 0
+ 0.0506898165
+ 0.08564949
+ 0
+ 3
+ 3
+
+
+
+ 30
+ 78.22131
+ 48.0072327
+ 0
+ 0.039129138
+ 0.07794231
+ 0
+ 3
+ 3
+
+
+
+ 30
+ 76.4867554
+ 45.3887634
+ 0
+ 0.0506898165
+ 0.08564949
+ 0
+ 3
+ 3
+
+
+
+ 1
+ 73.01611
+ 40.0739746
+ 0
+ 0.054543376
+ 0.112624526
+ 0
+ 3
+ 3
+
+
+
+
+
+
+
+ 40
+ -0.359264076
+ -0.00901746
+ 114.011215
+
+
+
+ 30
+ -0.2783391
+ -0.0514066666
+ 81.16443
+
+
+
+ 30
+ -0.1704393
+ -0.0668209046
+ 72.8611145
+
+
+
+ 30
+ -0.2783391
+ -0.0514066666
+ 81.16443
+
+
+
+ 1
+ -0.359264076
+ -0.00901746
+ 114.011215
+
+
+
+
+
+
+ GettingIntoPosition
+ false
+ 0
+
+
+ LayingPawn
+
+
+
+ 50
+ 73.01611
+ 40.0739746
+ 0
+ 0.054543376
+ 0.112624526
+ 0
+ 3
+ 3
+
+
+ Slimy
+ 1
+ 81.65927
+ 58.8843079
+ 0
+ 0.03912908
+ 0.08950315
+ 0
+ 3
+ 3
+
+
+
+
+
+
+
+ 50
+ -0.359264076
+ -0.00901746
+ 114.011215
+
+
+
+ 1
+ -0.2899
+ -0.0282852575
+ 98.13748
+
+
+
+
+
+
+ FastMasturbation
+ true
+ 0
+ 1610
+
+
+ LayingPawn
+
+
+ 20
+ 81.65927
+ 58.8843079
+ 0
+ 0.03912908
+ 0.08950315
+ 0
+ 3
+ 3
+
+
+ Slimy
+ 25
+ 85.17255
+ 58.0615845
+ 0
+ 0.03527552
+ 0.0471138731
+ 0
+ 3
+ 3
+
+
+ 1
+ 81.65927
+ 58.8843079
+ 0
+ 0.03912908
+ 0.08950315
+ 0
+ 3
+ 3
+
+
+
+
+
+
+
+ 25
+ -0.2899
+ -0.0282852575
+ 98.13748
+
+
+
+ 20
+ -0.178146541
+ -0.01672452
+ 96.95889
+
+
+
+ 1
+ -0.2899
+ -0.0282852575
+ 98.13748
+
+
+
+
+
+
+ VeryFastMasturbation
+ true
+ 0
+ 225
+
+
+ LayingPawn
+
+
+ 6
+ 81.65927
+ 58.8843079
+ 0
+ 0.03912908
+ 0.08950315
+ 0
+ 3
+ 3
+
+
+ Slimy
+ 8
+ 85.17255
+ 58.0615845
+ 0
+ 0.03527552
+ 0.0471138731
+ 0
+ 3
+ 3
+
+
+ 1
+ 81.65927
+ 58.8843079
+ 0
+ 0.03912908
+ 0.08950315
+ 0
+ 3
+ 3
+
+
+
+
+
+
+
+ 6
+ -0.2899
+ -0.0282852575
+ 98.13748
+
+
+
+ 8
+ -0.178146541
+ -0.01672452
+ 96.95889
+
+
+
+ 1
+ -0.2899
+ -0.0282852575
+ 98.13748
+
+
+
+
+
+
+ Orgasm
+ false
+ 0
+
+
+ LayingPawn
+
+
+ Slimy
+ 6
+ 81.65927
+ 58.8843079
+ 0
+ 0.03912908
+ 0.08950315
+ 0
+ 3
+ 3
+
+
+ True
+ Cum
+ 80
+ 85.17255
+ 58.0615845
+ 0
+ 0.03527552
+ 0.0471138731
+ 0
+ 3
+ 3
+
+
+ True
+ Cum
+ 90
+ 92.15109
+ 96.34238
+ 0
+ 0.0237147212
+ 0.0432603136
+ 0
+ 3
+ 3
+
+
+ True
+ Cum
+ 70
+ 92.15109
+ 96.34238
+ 0
+ 0.0237147212
+ 0.0432603136
+ 0
+ 3
+ 3
+
+
+ 70
+ 92.15109
+ 96.34238
+ 0
+ 0.0237147212
+ 0.0432603136
+ 0
+ 3
+ 3
+
+
+ 1
+ 81.65927
+ 58.8843079
+ 0
+ 0.03912908
+ 0.08950315
+ 0
+ 3
+ 3
+
+
+
+
+
+
+
+ 6
+ -0.2899
+ -0.0282852575
+ 98.13748
+
+
+
+ 80
+ -0.178146541
+ -0.01672452
+ 96.95889
+
+
+
+ 90
+ -0.178146541
+ -0.01672452
+ 96.95889
+
+
+
+ 70
+ -0.178146541
+ -0.01672452
+ 96.95889
+
+
+
+ 70
+ -0.178146541
+ -0.01672452
+ 96.95889
+
+
+
+ 1
+ -0.2899
+ -0.0282852575
+ 98.13748
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Patch_SexToysMasturbation/Patch_SexToysMasturbation.csproj b/Patch_SexToysMasturbation/Patch_SexToysMasturbation.csproj
index 925d3d9..d274c6a 100644
--- a/Patch_SexToysMasturbation/Patch_SexToysMasturbation.csproj
+++ b/Patch_SexToysMasturbation/Patch_SexToysMasturbation.csproj
@@ -83,6 +83,7 @@
+
\ No newline at end of file