Compare commits

..

1 commit

Author SHA1 Message Date
Zsar
1a134fec8b Merge branch 'parsingFloatAsIntFix' into 'master'
fix #5 "Float parsed as Int"

Closes #5

See merge request c0ffeeeeeeee/rimworld-animations!12
2023-06-28 00:20:41 +00:00
18 changed files with 121 additions and 539 deletions

View file

@ -1,24 +1,18 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using RimWorld; using RimWorld;
using rjw; using rjw;
using UnityEngine; using UnityEngine;
using Verse; using Verse;
using Verse.AI;
using Verse.Sound; using Verse.Sound;
namespace Rimworld_Animations { namespace Rimworld_Animations {
public class CompBodyAnimator : ThingComp public class CompBodyAnimator : ThingComp
{ {
/// <summary>
/// Cache of the currently animated pawns for the very fast isAnimating checks
/// </summary>
private static readonly HashSet<Pawn> animatingPawns = new HashSet<Pawn>();
/// <summary>
/// Check if the <paramref name="pawn"/> is currently animated by this comp
/// </summary>
public static bool IsAnimating(Pawn pawn) => animatingPawns.Contains(pawn);
public Pawn pawn => base.parent as Pawn; public Pawn pawn => base.parent as Pawn;
public PawnGraphicSet Graphics; public PawnGraphicSet Graphics;
@ -33,11 +27,9 @@ namespace Rimworld_Animations {
if (value == true) { if (value == true) {
SexUtility.DrawNude(pawn); SexUtility.DrawNude(pawn);
animatingPawns.Add(pawn);
} else { } else {
pawn.Drawer.renderer.graphics.ResolveAllGraphics(); pawn.Drawer.renderer.graphics.ResolveAllGraphics();
actorsInCurrentAnimation = null; actorsInCurrentAnimation = null;
animatingPawns.Remove(pawn);
} }
PortraitsCache.SetDirty(pawn); PortraitsCache.SetDirty(pawn);
@ -514,15 +506,9 @@ namespace Rimworld_Animations {
public bool LoopNeverending() public bool LoopNeverending()
{ {
JobDriver jobDriver = pawn?.jobs?.curDriver; if(pawn?.jobs?.curDriver != null &&
if (jobDriver == null) return false; (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)
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; return true;
} }

View file

@ -1,6 +1,9 @@
using RimWorld; using System;
using System.Collections.Generic;
using RimWorld;
using UnityEngine; using UnityEngine;
using Verse; using Verse;
using Rimworld_Animations;
namespace Rimworld_Animations { namespace Rimworld_Animations {
@ -14,9 +17,9 @@ namespace Rimworld_Animations {
if (!flags.FlagSet(PawnRenderFlags.Portrait) && layer == PawnOverlayDrawer.OverlayLayer.Head) if (!flags.FlagSet(PawnRenderFlags.Portrait) && layer == PawnOverlayDrawer.OverlayLayer.Head)
{ {
if (CompBodyAnimator.IsAnimating(pawn) && pawn.Drawer.renderer.graphics.headGraphic != null) CompBodyAnimator pawnAnimator = pawn.TryGetComp<CompBodyAnimator>();
if (pawnAnimator != null && pawnAnimator.isAnimating && pawn.Drawer.renderer.graphics.headGraphic != null)
{ {
CompBodyAnimator pawnAnimator = pawn.TryGetComp<CompBodyAnimator>();
pawnRot = pawnAnimator.headFacing; pawnRot = pawnAnimator.headFacing;
quat = Quaternion.AngleAxis(angle: pawnAnimator.headAngle, axis: Vector3.up); quat = Quaternion.AngleAxis(angle: pawnAnimator.headAngle, axis: Vector3.up);
float y = drawLoc.y; float y = drawLoc.y;

View file

@ -1,4 +1,8 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse; using Verse;
using RimWorld; using RimWorld;
using UnityEngine; using UnityEngine;
@ -21,13 +25,14 @@ namespace Rimworld_Animations {
listingStandard.GapLine(); listingStandard.GapLine();
if (Find.Selector.SingleSelectedThing is Pawn curPawn) { if (Find.Selector.SingleSelectedThing is Pawn) {
if (CompBodyAnimator.IsAnimating(curPawn)) { Pawn curPawn = Find.Selector.SingleSelectedThing as Pawn;
CompBodyAnimator compBodyAnimator = curPawn.TryGetComp<CompBodyAnimator>(); if (curPawn.TryGetComp<CompBodyAnimator>().isAnimating) {
AnimationDef def = compBodyAnimator.CurrentAnimation;
int ActorIndex = compBodyAnimator.ActorIndex; AnimationDef def = curPawn.TryGetComp<CompBodyAnimator>().CurrentAnimation;
int ActorIndex = curPawn.TryGetComp<CompBodyAnimator>().ActorIndex;
float offsetX = 0, offsetZ = 0, rotation = 0; float offsetX = 0, offsetZ = 0, rotation = 0;
string bodyTypeDef = (curPawn.story?.bodyType != null) ? curPawn.story.bodyType.ToString() : ""; string bodyTypeDef = (curPawn.story?.bodyType != null) ? curPawn.story.bodyType.ToString() : "";
@ -52,6 +57,8 @@ namespace Rimworld_Animations {
listingStandard.Label("Warning--You generally don't want to change human offsets, only alien offsets"); listingStandard.Label("Warning--You generally don't want to change human offsets, only alien offsets");
} }
bool mirrored = curPawn.TryGetComp<CompBodyAnimator>().Mirror;
float.TryParse(listingStandard.TextEntryLabeled("X Offset: ", offsetX.ToString()), out offsetX); float.TryParse(listingStandard.TextEntryLabeled("X Offset: ", offsetX.ToString()), out offsetX);
offsetX = listingStandard.Slider(offsetX, -2, 2); offsetX = listingStandard.Slider(offsetX, -2, 2);

View file

@ -23,16 +23,17 @@ namespace Rimworld_Animations {
} }
}))(); }))();
} }
catch (TypeLoadException) { catch (TypeLoadException ex) {
} }
} }
public static bool Prefix(Pawn ___pawn, ref Rot4 headFacing, ref Vector3 headOrigin, ref Quaternion quaternion, bool portrait) { public static bool Prefix(ref Pawn ___pawn, ref Rot4 headFacing, ref Vector3 headOrigin, ref Quaternion quaternion, ref bool portrait) {
if (!portrait && CompBodyAnimator.IsAnimating(___pawn)) { CompBodyAnimator bodyAnim = ___pawn.TryGetComp<CompBodyAnimator>();
if (bodyAnim != null && bodyAnim.isAnimating && !portrait) {
CompBodyAnimator bodyAnim = ___pawn.TryGetComp<CompBodyAnimator>();
headFacing = bodyAnim.headFacing; headFacing = bodyAnim.headFacing;
headOrigin = new Vector3(bodyAnim.getPawnHeadPosition().x, headOrigin.y, bodyAnim.getPawnHeadPosition().z); headOrigin = new Vector3(bodyAnim.getPawnHeadPosition().x, headOrigin.y, bodyAnim.getPawnHeadPosition().z);
quaternion = Quaternion.AngleAxis(bodyAnim.headAngle, Vector3.up); quaternion = Quaternion.AngleAxis(bodyAnim.headAngle, Vector3.up);

View file

@ -1,5 +1,11 @@
using HarmonyLib; using HarmonyLib;
using rjw; using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace Rimworld_Animations namespace Rimworld_Animations
{ {
@ -8,7 +14,7 @@ namespace Rimworld_Animations
{ {
public static bool Prefix(JobDriver_Sex __instance) public static bool Prefix(JobDriver_Sex __instance)
{ {
if (CompBodyAnimator.IsAnimating(__instance.pawn)) if (__instance.pawn.TryGetComp<CompBodyAnimator>().isAnimating)
{ {
return false; return false;
} }

View file

@ -1,9 +1,13 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HarmonyLib; using HarmonyLib;
using RimWorld; using RimWorld;
using Verse; using Verse;
using rjw; using rjw;
using System.Reflection.Emit;
using Verse.AI; using Verse.AI;
namespace Rimworld_Animations namespace Rimworld_Animations
@ -23,7 +27,11 @@ namespace Rimworld_Animations
} }
return true; return true;
} }
} }
[HarmonyPatch(typeof(JobDriver_JoinInBed), "MakeNewToils")] [HarmonyPatch(typeof(JobDriver_JoinInBed), "MakeNewToils")]
@ -58,13 +66,19 @@ namespace Rimworld_Animations
toils[3].AddPreTickAction(() => toils[3].AddPreTickAction(() =>
{ {
if (!CompBodyAnimator.IsAnimating(__instance.Partner)) if (!__instance.Partner.TryGetComp<CompBodyAnimator>().isAnimating)
{ {
__instance.pawn.TryGetComp<CompBodyAnimator>().isAnimating = false; __instance.pawn.TryGetComp<CompBodyAnimator>().isAnimating = false;
} }
}); });
__result = toils.AsEnumerable(); __result = toils.AsEnumerable();
} }
} }
} }

View file

@ -1,6 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HarmonyLib; using HarmonyLib;
using RimWorld; using RimWorld;
using Verse; using Verse;
@ -156,12 +158,10 @@ namespace Rimworld_Animations {
public static void Postfix(ref JobDriver_SexBaseInitiator __instance) { public static void Postfix(ref JobDriver_SexBaseInitiator __instance) {
Pawn reciever = __instance.Target as Pawn; if ((__instance.Target as Pawn)?.jobs?.curDriver is JobDriver_SexBaseReciever) {
if (__instance.pawn.TryGetComp<CompBodyAnimator>().isAnimating) {
if (reciever?.jobs?.curDriver is JobDriver_SexBaseReciever recieverJobDriver) { List<Pawn> parteners = ((__instance.Target as Pawn)?.jobs.curDriver as JobDriver_SexBaseReciever).parteners;
if (CompBodyAnimator.IsAnimating(__instance.pawn)) {
List<Pawn> parteners = recieverJobDriver.parteners;
for (int i = 0; i < parteners.Count; i++) { for (int i = 0; i < parteners.Count; i++) {
@ -173,13 +173,13 @@ namespace Rimworld_Animations {
__instance.Target.TryGetComp<CompBodyAnimator>().isAnimating = false; __instance.Target.TryGetComp<CompBodyAnimator>().isAnimating = false;
if (xxx.is_human(reciever)) { if (xxx.is_human((__instance.Target as Pawn))) {
reciever?.Drawer.renderer.graphics.ResolveApparelGraphics(); (__instance.Target as Pawn)?.Drawer.renderer.graphics.ResolveApparelGraphics();
PortraitsCache.SetDirty(reciever); PortraitsCache.SetDirty((__instance.Target as Pawn));
} }
} }
recieverJobDriver?.parteners.Remove(__instance.pawn); ((__instance.Target as Pawn)?.jobs.curDriver as JobDriver_SexBaseReciever).parteners.Remove(__instance.pawn);
} }

View file

@ -1,4 +1,4 @@
/*using HarmonyLib; using HarmonyLib;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -19,4 +19,4 @@ namespace Rimworld_Animations
} }
} }
}*/ }

View file

@ -5,6 +5,7 @@ using HarmonyLib;
using RimWorld; using RimWorld;
using Verse; using Verse;
using UnityEngine; using UnityEngine;
using System.Reflection;
using System.Reflection.Emit; using System.Reflection.Emit;
namespace Rimworld_Animations { namespace Rimworld_Animations {
@ -30,10 +31,12 @@ namespace Rimworld_Animations {
PawnGraphicSet graphics = __instance.graphics; PawnGraphicSet graphics = __instance.graphics;
Pawn pawn = graphics.pawn; Pawn pawn = graphics.pawn;
CompBodyAnimator bodyAnim = pawn.TryGetComp<CompBodyAnimator>();
if (CompBodyAnimator.IsAnimating(pawn) && pawn.Map == Find.CurrentMap)
if (bodyAnim != null && bodyAnim.isAnimating && pawn.Map == Find.CurrentMap)
{ {
pawn.TryGetComp<CompBodyAnimator>().animatePawnBody(ref rootLoc, ref angle, ref bodyFacing); bodyAnim.animatePawnBody(ref rootLoc, ref angle, ref bodyFacing);
} }
@ -72,7 +75,7 @@ namespace Rimworld_Animations {
else else
{ {
yield return ins[i]; yield return ins[i];
} }
} }
} }
} }

View file

@ -1,23 +1,29 @@
using HarmonyLib; using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse; using Verse;
namespace Rimworld_Animations { namespace Rimworld_Animations {
[HarmonyPatch(typeof(Thing), nameof(Thing.Rotation), MethodType.Getter)] [HarmonyPatch(typeof(Thing), "Rotation", MethodType.Getter)]
public static class HarmonyPatch_PawnRotation { public static class HarmonyPatch_PawnRotation {
public static bool Prefix(Thing __instance, ref Rot4 __result) { public static bool Prefix(Thing __instance, ref Rot4 __result) {
if (!(__instance is Pawn pawn)) { if(!(__instance is Pawn) || (__instance as Pawn)?.TryGetComp<CompBodyAnimator>() == null || !(__instance as Pawn).TryGetComp<CompBodyAnimator>().isAnimating) {
return true;
}
if (!CompBodyAnimator.IsAnimating(pawn)) {
return true; return true;
} }
Pawn pawn = (__instance as Pawn);
__result = pawn.TryGetComp<CompBodyAnimator>().bodyFacing; __result = pawn.TryGetComp<CompBodyAnimator>().bodyFacing;
return false; return false;
} }
} }
} }

View file

@ -1,4 +1,9 @@
using HarmonyLib; using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using Verse; using Verse;
@ -8,9 +13,10 @@ namespace Rimworld_Animations {
public static class HarmonyPatch_Pawn_DrawTracker { public static class HarmonyPatch_Pawn_DrawTracker {
public static bool Prefix(ref Pawn ___pawn, ref Vector3 __result) { public static bool Prefix(ref Pawn ___pawn, ref Vector3 __result) {
if (CompBodyAnimator.IsAnimating(___pawn)) { CompBodyAnimator bodyAnim = ___pawn.TryGetComp<CompBodyAnimator>();
CompBodyAnimator bodyAnim = ___pawn.TryGetComp<CompBodyAnimator>();
__result = bodyAnim.anchor + bodyAnim.deltaPos; if (bodyAnim != null && bodyAnim.isAnimating) {
__result = ___pawn.TryGetComp<CompBodyAnimator>().anchor + ___pawn.TryGetComp<CompBodyAnimator>().deltaPos;
return false; return false;
} }

View file

@ -1,4 +1,9 @@
using HarmonyLib; using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse; using Verse;
namespace Rimworld_Animations namespace Rimworld_Animations
@ -8,7 +13,8 @@ namespace Rimworld_Animations
{ {
public static bool Prefix(ref Pawn ___pawn) public static bool Prefix(ref Pawn ___pawn)
{ {
if (CompBodyAnimator.IsAnimating(___pawn))
if (___pawn.TryGetComp<CompBodyAnimator>() != null && ___pawn.TryGetComp<CompBodyAnimator>().isAnimating)
{ {
return false; return false;
} }

View file

@ -1,6 +1,12 @@
using HarmonyLib; using HarmonyLib;
using RimWorld; using RimWorld;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse; using Verse;
namespace Rimworld_Animations namespace Rimworld_Animations
@ -10,16 +16,18 @@ namespace Rimworld_Animations
{ {
static bool ClearCache(Pawn pawn) static bool ClearCache(Pawn pawn)
{ {
return pawn.IsInvisible() || CompBodyAnimator.IsAnimating(pawn); return pawn.IsInvisible() || (pawn.TryGetComp<CompBodyAnimator>() != null && pawn.TryGetComp<CompBodyAnimator>().isAnimating);
} }
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{ {
var list = instructions.ToList();
foreach (CodeInstruction i in instructions) foreach (CodeInstruction i in instructions)
{ {
if (i.Calls(AccessTools.Method(typeof(PawnUtility), nameof(PawnUtility.IsInvisible)))) if (i.OperandIs(AccessTools.Method(typeof(PawnUtility), "IsInvisible")))
{ {
yield return CodeInstruction.Call(typeof(PawnRenderer_RenderPawnAt_Patch), nameof(ClearCache)); yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PawnRenderer_RenderPawnAt_Patch), "ClearCache"));
} }
else else
{ {

View file

@ -169,10 +169,11 @@ namespace Rimworld_Animations {
return; return;
} }
if (!CompBodyAnimator.IsAnimating(pawn)) { CompBodyAnimator pawnAnimator = pawn.TryGetComp<CompBodyAnimator>();
if (pawnAnimator == null || !pawnAnimator.isAnimating) {
GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, drawNow); GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, drawNow);
} else { } else {
CompBodyAnimator pawnAnimator = pawn.TryGetComp<CompBodyAnimator>();
Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition(); Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition();
pawnHeadPosition.y = loc.y; pawnHeadPosition.y = loc.y;
GenDraw.DrawMeshNowOrLater(MeshPool.humanlikeHeadSet.MeshAt(pawnAnimator.headFacing), pawnHeadPosition, Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up), material, true); GenDraw.DrawMeshNowOrLater(MeshPool.humanlikeHeadSet.MeshAt(pawnAnimator.headFacing), pawnHeadPosition, Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up), material, true);
@ -183,13 +184,14 @@ namespace Rimworld_Animations {
{ {
if (flags.FlagSet(PawnRenderFlags.Portrait)) return; if (flags.FlagSet(PawnRenderFlags.Portrait)) return;
if (CompBodyAnimator.IsAnimating(pawn)) CompBodyAnimator anim = pawn.TryGetComp<CompBodyAnimator>();
if (anim.isAnimating)
{ {
CompBodyAnimator anim = pawn.TryGetComp<CompBodyAnimator>();
bodyFacing = anim.headFacing; bodyFacing = anim.headFacing;
angle = anim.headAngle; angle = anim.headAngle;
quat = Quaternion.AngleAxis(anim.headAngle, Vector3.up); quat = Quaternion.AngleAxis(anim.headAngle, Vector3.up);
pos = anim.getPawnHeadOffset(); pos = anim.getPawnHeadOffset();
} }
} }
@ -200,12 +202,12 @@ namespace Rimworld_Animations {
return; return;
} }
CompBodyAnimator pawnAnimator = pawn.TryGetComp<CompBodyAnimator>();
if (!CompBodyAnimator.IsAnimating(pawn) || portrait) { if (pawnAnimator == null || !pawnAnimator.isAnimating || portrait) {
GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, portrait); GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, portrait);
} }
else { else {
CompBodyAnimator pawnAnimator = pawn.TryGetComp<CompBodyAnimator>();
Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition(); Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition();
pawnHeadPosition.x *= bodySizeFactor; pawnHeadPosition.x *= bodySizeFactor;
pawnHeadPosition.x *= bodySizeFactor; pawnHeadPosition.x *= bodySizeFactor;

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Manifest> <Manifest>
<identifier>Rimworld-Animations</identifier> <identifier>Rimworld-Animations</identifier>
<version>1.3.7</version> <version>1.3.4</version>
</Manifest> </Manifest>

View file

@ -51,7 +51,7 @@ namespace Rimworld_Animations {
public static bool Prefix_AnimateHeadAddons(PawnRenderFlags renderFlags, Vector3 vector, Vector3 headOffset, Pawn pawn, Quaternion quat, Rot4 rotation) public static bool Prefix_AnimateHeadAddons(PawnRenderFlags renderFlags, Vector3 vector, Vector3 headOffset, Pawn pawn, Quaternion quat, Rot4 rotation)
{ {
if (renderFlags.FlagSet(PawnRenderFlags.Portrait) || !CompBodyAnimator.IsAnimating(pawn)) return true; if (renderFlags.FlagSet(PawnRenderFlags.Portrait) || pawn.TryGetComp<CompBodyAnimator>() == null || !pawn.TryGetComp<CompBodyAnimator>().isAnimating) return true;
if (!(pawn.def is ThingDef_AlienRace alienProps) || renderFlags.FlagSet(PawnRenderFlags.Invisible)) return false; if (!(pawn.def is ThingDef_AlienRace alienProps) || renderFlags.FlagSet(PawnRenderFlags.Invisible)) return false;
List<AlienPartGenerator.BodyAddon> addons = alienProps.alienRace.generalSettings.alienPartGenerator.bodyAddons; List<AlienPartGenerator.BodyAddon> addons = alienProps.alienRace.generalSettings.alienPartGenerator.bodyAddons;

View file

@ -1,465 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<Patch_SexToysMasturbation.SexToyAnimationDef>
<defName>Masturbation_DildoVaginal</defName>
<label>dildo masturbation</label>
<requiredBodyPart>vagina</requiredBodyPart>
<sounds>true</sounds>
<sexTypes>
<li>Masturbation</li>
</sexTypes>
<actors>
<li>
<defNames>
<li>Human</li>
</defNames>
<isFucked>true</isFucked>
</li>
</actors>
<animationStages>
<li>
<stageName>Masturbating</stageName>
<isLooping>true</isLooping>
<playTimeTicks>917</playTimeTicks>
<stageIndex>0</stageIndex>
<animationClips>
<li Class="Rimworld_Animations.PawnAnimationClip">
<layer>LayingPawn</layer>
<keyframes>
<li>
<!--out-->
<tickDuration>40</tickDuration>
<bodyAngle>73.01611</bodyAngle>
<headAngle>40.0739746</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.054543376</bodyOffsetZ>
<bodyOffsetX>0.112624526</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<!--almost out-->
<soundEffect>Slimy</soundEffect>
<tickDuration>30</tickDuration>
<bodyAngle>76.4867554</bodyAngle>
<headAngle>45.3887634</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.0506898165</bodyOffsetZ>
<bodyOffsetX>0.08564949</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<!-- in -->
<tickDuration>30</tickDuration>
<bodyAngle>78.22131</bodyAngle>
<headAngle>48.0072327</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.039129138</bodyOffsetZ>
<bodyOffsetX>0.07794231</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<!--almost out-->
<tickDuration>30</tickDuration>
<bodyAngle>76.4867554</bodyAngle>
<headAngle>45.3887634</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.0506898165</bodyOffsetZ>
<bodyOffsetX>0.08564949</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<!--out-->
<tickDuration>1</tickDuration>
<bodyAngle>73.01611</bodyAngle>
<headAngle>40.0739746</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.054543376</bodyOffsetZ>
<bodyOffsetX>0.112624526</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
</keyframes>
</li>
<li Class="Rimworld_Animations.ThingAnimationClip">
<keyframes>
<li>
<!--out-->
<tickDuration>40</tickDuration>
<positionX>-0.359264076</positionX>
<positionZ>-0.00901746</positionZ>
<rotation>114.011215</rotation>
</li>
<li>
<!--almost out-->
<tickDuration>30</tickDuration>
<positionX>-0.2783391</positionX>
<positionZ>-0.0514066666</positionZ>
<rotation>81.16443</rotation>
</li>
<li>
<!--in-->
<tickDuration>30</tickDuration>
<positionX>-0.1704393</positionX>
<positionZ>-0.0668209046</positionZ>
<rotation>72.8611145</rotation>
</li>
<li>
<!--almost out-->
<tickDuration>30</tickDuration>
<positionX>-0.2783391</positionX>
<positionZ>-0.0514066666</positionZ>
<rotation>81.16443</rotation>
</li>
<li>
<!--out-->
<tickDuration>1</tickDuration>
<positionX>-0.359264076</positionX>
<positionZ>-0.00901746</positionZ>
<rotation>114.011215</rotation>
</li>
</keyframes>
</li>
</animationClips>
</li>
<li>
<stageName>GettingIntoPosition</stageName>
<isLooping>false</isLooping>
<stageIndex>0</stageIndex>
<animationClips>
<li Class="Rimworld_Animations.PawnAnimationClip">
<layer>LayingPawn</layer>
<keyframes>
<li>
<!--out-->
<tickDuration>50</tickDuration>
<bodyAngle>73.01611</bodyAngle>
<headAngle>40.0739746</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.054543376</bodyOffsetZ>
<bodyOffsetX>0.112624526</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<soundEffect>Slimy</soundEffect>
<tickDuration>1</tickDuration>
<bodyAngle>81.65927</bodyAngle>
<headAngle>58.8843079</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.03912908</bodyOffsetZ>
<bodyOffsetX>0.08950315</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
</keyframes>
</li>
<li Class="Rimworld_Animations.ThingAnimationClip">
<keyframes>
<li>
<!--out-->
<tickDuration>50</tickDuration>
<positionX>-0.359264076</positionX>
<positionZ>-0.00901746</positionZ>
<rotation>114.011215</rotation>
</li>
<li>
<!--out-->
<tickDuration>1</tickDuration>
<positionX>-0.2899</positionX>
<positionZ>-0.0282852575</positionZ>
<rotation>98.13748</rotation>
</li>
</keyframes>
</li>
</animationClips>
</li>
<li>
<stageName>FastMasturbation</stageName>
<isLooping>true</isLooping>
<stageIndex>0</stageIndex>
<playTimeTicks>1610</playTimeTicks>
<animationClips>
<li Class="Rimworld_Animations.PawnAnimationClip">
<layer>LayingPawn</layer>
<keyframes>
<li>
<tickDuration>20</tickDuration>
<bodyAngle>81.65927</bodyAngle>
<headAngle>58.8843079</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.03912908</bodyOffsetZ>
<bodyOffsetX>0.08950315</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<soundEffect>Slimy</soundEffect>
<tickDuration>25</tickDuration>
<bodyAngle>85.17255</bodyAngle>
<headAngle>58.0615845</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.03527552</bodyOffsetZ>
<bodyOffsetX>0.0471138731</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<tickDuration>1</tickDuration>
<bodyAngle>81.65927</bodyAngle>
<headAngle>58.8843079</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.03912908</bodyOffsetZ>
<bodyOffsetX>0.08950315</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
</keyframes>
</li>
<li Class="Rimworld_Animations.ThingAnimationClip">
<keyframes>
<li>
<!--out-->
<tickDuration>25</tickDuration>
<positionX>-0.2899</positionX>
<positionZ>-0.0282852575</positionZ>
<rotation>98.13748</rotation>
</li>
<li>
<!--out-->
<tickDuration>20</tickDuration>
<positionX>-0.178146541</positionX>
<positionZ>-0.01672452</positionZ>
<rotation>96.95889</rotation>
</li>
<li>
<!--out-->
<tickDuration>1</tickDuration>
<positionX>-0.2899</positionX>
<positionZ>-0.0282852575</positionZ>
<rotation>98.13748</rotation>
</li>
</keyframes>
</li>
</animationClips>
</li>
<li>
<stageName>VeryFastMasturbation</stageName>
<isLooping>true</isLooping>
<stageIndex>0</stageIndex>
<playTimeTicks>225</playTimeTicks>
<animationClips>
<li Class="Rimworld_Animations.PawnAnimationClip">
<layer>LayingPawn</layer>
<keyframes>
<li>
<tickDuration>6</tickDuration>
<bodyAngle>81.65927</bodyAngle>
<headAngle>58.8843079</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.03912908</bodyOffsetZ>
<bodyOffsetX>0.08950315</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<soundEffect>Slimy</soundEffect>
<tickDuration>8</tickDuration>
<bodyAngle>85.17255</bodyAngle>
<headAngle>58.0615845</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.03527552</bodyOffsetZ>
<bodyOffsetX>0.0471138731</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<tickDuration>1</tickDuration>
<bodyAngle>81.65927</bodyAngle>
<headAngle>58.8843079</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.03912908</bodyOffsetZ>
<bodyOffsetX>0.08950315</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
</keyframes>
</li>
<li Class="Rimworld_Animations.ThingAnimationClip">
<keyframes>
<li>
<!--out-->
<tickDuration>6</tickDuration>
<positionX>-0.2899</positionX>
<positionZ>-0.0282852575</positionZ>
<rotation>98.13748</rotation>
</li>
<li>
<!--out-->
<tickDuration>8</tickDuration>
<positionX>-0.178146541</positionX>
<positionZ>-0.01672452</positionZ>
<rotation>96.95889</rotation>
</li>
<li>
<!--out-->
<tickDuration>1</tickDuration>
<positionX>-0.2899</positionX>
<positionZ>-0.0282852575</positionZ>
<rotation>98.13748</rotation>
</li>
</keyframes>
</li>
</animationClips>
</li>
<li>
<stageName>Orgasm</stageName>
<isLooping>false</isLooping>
<stageIndex>0</stageIndex>
<animationClips>
<li Class="Rimworld_Animations.PawnAnimationClip">
<layer>LayingPawn</layer>
<keyframes>
<li>
<soundEffect>Slimy</soundEffect>
<tickDuration>6</tickDuration>
<bodyAngle>81.65927</bodyAngle>
<headAngle>58.8843079</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.03912908</bodyOffsetZ>
<bodyOffsetX>0.08950315</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<quiver>True</quiver>
<soundEffect>Cum</soundEffect>
<tickDuration>80</tickDuration>
<bodyAngle>85.17255</bodyAngle>
<headAngle>58.0615845</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.03527552</bodyOffsetZ>
<bodyOffsetX>0.0471138731</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<quiver>True</quiver>
<soundEffect>Cum</soundEffect>
<tickDuration>90</tickDuration>
<bodyAngle>92.15109</bodyAngle>
<headAngle>96.34238</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.0237147212</bodyOffsetZ>
<bodyOffsetX>0.0432603136</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<quiver>True</quiver>
<soundEffect>Cum</soundEffect>
<tickDuration>70</tickDuration>
<bodyAngle>92.15109</bodyAngle>
<headAngle>96.34238</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.0237147212</bodyOffsetZ>
<bodyOffsetX>0.0432603136</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<tickDuration>70</tickDuration>
<bodyAngle>92.15109</bodyAngle>
<headAngle>96.34238</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.0237147212</bodyOffsetZ>
<bodyOffsetX>0.0432603136</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
<li>
<tickDuration>1</tickDuration>
<bodyAngle>81.65927</bodyAngle>
<headAngle>58.8843079</headAngle>
<genitalAngle>0</genitalAngle>
<bodyOffsetZ>0.03912908</bodyOffsetZ>
<bodyOffsetX>0.08950315</bodyOffsetX>
<headBob>0</headBob>
<bodyFacing>3</bodyFacing>
<headFacing>3</headFacing>
</li>
</keyframes>
</li>
<li Class="Rimworld_Animations.ThingAnimationClip">
<keyframes>
<li>
<!--out-->
<tickDuration>6</tickDuration>
<positionX>-0.2899</positionX>
<positionZ>-0.0282852575</positionZ>
<rotation>98.13748</rotation>
</li>
<li>
<!--out-->
<tickDuration>80</tickDuration>
<positionX>-0.178146541</positionX>
<positionZ>-0.01672452</positionZ>
<rotation>96.95889</rotation>
</li>
<li>
<!--out-->
<tickDuration>90</tickDuration>
<positionX>-0.178146541</positionX>
<positionZ>-0.01672452</positionZ>
<rotation>96.95889</rotation>
</li>
<li>
<!--out-->
<tickDuration>70</tickDuration>
<positionX>-0.178146541</positionX>
<positionZ>-0.01672452</positionZ>
<rotation>96.95889</rotation>
</li>
<li>
<!--out-->
<tickDuration>70</tickDuration>
<positionX>-0.178146541</positionX>
<positionZ>-0.01672452</positionZ>
<rotation>96.95889</rotation>
</li>
<li>
<!--out-->
<tickDuration>1</tickDuration>
<positionX>-0.2899</positionX>
<positionZ>-0.0282852575</positionZ>
<rotation>98.13748</rotation>
</li>
</keyframes>
</li>
</animationClips>
</li>
</animationStages>
</Patch_SexToysMasturbation.SexToyAnimationDef>
</Defs>

View file

@ -83,7 +83,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="1.3\Defs\AnimationDefs\Animations_Dildo.xml" /> <Content Include="1.3\Defs\AnimationDefs\Animations_Dildo.xml" />
<Content Include="1.4\Defs\AnimationDefs\Animations_Dildo.xml" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>