mirror of
https://gitgud.io/c0ffeeeeeeee/rimworld-animations.git
synced 2024-08-15 00:43:45 +00:00
Compare commits
11 commits
b8b80b714e
...
487cfb5bbf
Author | SHA1 | Date | |
---|---|---|---|
|
487cfb5bbf | ||
|
15b0e2c9f6 | ||
|
c6241be3fc | ||
|
33ebba94a7 | ||
|
3743248e9a | ||
|
69793e6be1 | ||
|
6cffdfef95 | ||
|
af4851c1ef | ||
|
6a271a78fe | ||
|
06a3d90dbf | ||
|
a106fd60f1 |
19 changed files with 724 additions and 186 deletions
|
@ -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
|
||||
{
|
||||
/// <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 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;
|
||||
}
|
||||
|
|
|
@ -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<CompBodyAnimator>();
|
||||
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<CompBodyAnimator>();
|
||||
pawnRot = pawnAnimator.headFacing;
|
||||
quat = Quaternion.AngleAxis(angle: pawnAnimator.headAngle, axis: Vector3.up);
|
||||
float y = drawLoc.y;
|
||||
|
|
|
@ -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<CompBodyAnimator>().isAnimating) {
|
||||
|
||||
AnimationDef def = curPawn.TryGetComp<CompBodyAnimator>().CurrentAnimation;
|
||||
int ActorIndex = curPawn.TryGetComp<CompBodyAnimator>().ActorIndex;
|
||||
CompBodyAnimator compBodyAnimator = curPawn.TryGetComp<CompBodyAnimator>();
|
||||
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<CompBodyAnimator>().Mirror;
|
||||
|
||||
float.TryParse(listingStandard.TextEntryLabeled("X Offset: ", offsetX.ToString()), out offsetX);
|
||||
offsetX = listingStandard.Slider(offsetX, -2, 2);
|
||||
|
||||
|
|
|
@ -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<CompBodyAnimator>();
|
||||
|
||||
if (bodyAnim != null && bodyAnim.isAnimating && !portrait) {
|
||||
if (!portrait && CompBodyAnimator.IsAnimating(___pawn)) {
|
||||
|
||||
CompBodyAnimator bodyAnim = ___pawn.TryGetComp<CompBodyAnimator>();
|
||||
headFacing = bodyAnim.headFacing;
|
||||
headOrigin = new Vector3(bodyAnim.getPawnHeadPosition().x, headOrigin.y, bodyAnim.getPawnHeadPosition().z);
|
||||
quaternion = Quaternion.AngleAxis(bodyAnim.headAngle, Vector3.up);
|
||||
|
|
|
@ -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<CompBodyAnimator>().isAnimating)
|
||||
if (CompBodyAnimator.IsAnimating(__instance.pawn))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -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<CompBodyAnimator>().isAnimating)
|
||||
if (!CompBodyAnimator.IsAnimating(__instance.Partner))
|
||||
{
|
||||
__instance.pawn.TryGetComp<CompBodyAnimator>().isAnimating = false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
__result = toils.AsEnumerable();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<CompBodyAnimator>().isAnimating) {
|
||||
Pawn reciever = __instance.Target as Pawn;
|
||||
|
||||
List<Pawn> 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<Pawn> parteners = recieverJobDriver.parteners;
|
||||
|
||||
for (int i = 0; i < parteners.Count; i++) {
|
||||
|
||||
|
@ -173,13 +173,13 @@ namespace Rimworld_Animations {
|
|||
|
||||
__instance.Target.TryGetComp<CompBodyAnimator>().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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using HarmonyLib;
|
||||
/*using HarmonyLib;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -19,4 +19,4 @@ namespace Rimworld_Animations
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
|
|
@ -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<CompBodyAnimator>();
|
||||
|
||||
|
||||
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<CompBodyAnimator>().animatePawnBody(ref rootLoc, ref angle, ref bodyFacing);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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<CompBodyAnimator>() == null || !(__instance as Pawn).TryGetComp<CompBodyAnimator>().isAnimating) {
|
||||
if (!(__instance is Pawn pawn)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CompBodyAnimator.IsAnimating(pawn)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Pawn pawn = (__instance as Pawn);
|
||||
__result = pawn.TryGetComp<CompBodyAnimator>().bodyFacing;
|
||||
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<CompBodyAnimator>();
|
||||
|
||||
if (bodyAnim != null && bodyAnim.isAnimating) {
|
||||
__result = ___pawn.TryGetComp<CompBodyAnimator>().anchor + ___pawn.TryGetComp<CompBodyAnimator>().deltaPos;
|
||||
if (CompBodyAnimator.IsAnimating(___pawn)) {
|
||||
CompBodyAnimator bodyAnim = ___pawn.TryGetComp<CompBodyAnimator>();
|
||||
__result = bodyAnim.anchor + bodyAnim.deltaPos;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -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<CompBodyAnimator>() != null && ___pawn.TryGetComp<CompBodyAnimator>().isAnimating)
|
||||
if (CompBodyAnimator.IsAnimating(___pawn))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -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<CompBodyAnimator>() != null && pawn.TryGetComp<CompBodyAnimator>().isAnimating);
|
||||
return pawn.IsInvisible() || CompBodyAnimator.IsAnimating(pawn);
|
||||
}
|
||||
|
||||
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> 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
|
||||
{
|
||||
|
|
|
@ -169,11 +169,10 @@ namespace Rimworld_Animations {
|
|||
return;
|
||||
}
|
||||
|
||||
CompBodyAnimator pawnAnimator = pawn.TryGetComp<CompBodyAnimator>();
|
||||
|
||||
if (pawnAnimator == null || !pawnAnimator.isAnimating) {
|
||||
if (!CompBodyAnimator.IsAnimating(pawn)) {
|
||||
GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, drawNow);
|
||||
} else {
|
||||
CompBodyAnimator pawnAnimator = pawn.TryGetComp<CompBodyAnimator>();
|
||||
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<CompBodyAnimator>();
|
||||
if (anim.isAnimating)
|
||||
if (CompBodyAnimator.IsAnimating(pawn))
|
||||
{
|
||||
CompBodyAnimator anim = pawn.TryGetComp<CompBodyAnimator>();
|
||||
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<CompBodyAnimator>();
|
||||
|
||||
if (pawnAnimator == null || !pawnAnimator.isAnimating || portrait) {
|
||||
if (!CompBodyAnimator.IsAnimating(pawn) || portrait) {
|
||||
GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, portrait);
|
||||
}
|
||||
else {
|
||||
CompBodyAnimator pawnAnimator = pawn.TryGetComp<CompBodyAnimator>();
|
||||
Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition();
|
||||
pawnHeadPosition.x *= bodySizeFactor;
|
||||
pawnHeadPosition.x *= bodySizeFactor;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<Manifest>
|
||||
<identifier>Rimworld-Animations</identifier>
|
||||
<version>1.3.4</version>
|
||||
<version>1.3.7</version>
|
||||
</Manifest>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
|
@ -12,6 +12,7 @@
|
|||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<LangVersion>9</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
|
|
|
@ -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<CompilerGeneratedAttribute>() 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<CompBodyAnimator>();
|
||||
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<CompBodyAnimator>() 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<CompBodyAnimator>() 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<CompBodyAnimator>() == null || !pawn.TryGetComp<CompBodyAnimator>().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<AlienPartGenerator.BodyAddon> addons = alienProps.alienRace.generalSettings.alienPartGenerator.bodyAddons;
|
||||
|
@ -69,9 +179,9 @@ namespace Rimworld_Animations {
|
|||
|
||||
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);
|
||||
|
@ -110,24 +220,33 @@ namespace Rimworld_Animations {
|
|||
{
|
||||
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<CompBodyAnimator>();
|
||||
AlienPartGenerator.AlienComp comp = pawn.GetComp<AlienPartGenerator.AlienComp>();
|
||||
|
||||
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<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
|
||||
{
|
||||
{
|
||||
List<CodeInstruction> 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<CompBodyAnimator>();
|
||||
|
||||
if(anim == null)
|
||||
{
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (anim != null && !renderFlags.FlagSet(PawnRenderFlags.Portrait) && anim.isAnimating)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,465 @@
|
|||
<?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>
|
|
@ -83,6 +83,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="1.3\Defs\AnimationDefs\Animations_Dildo.xml" />
|
||||
<Content Include="1.4\Defs\AnimationDefs\Animations_Dildo.xml" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
Loading…
Add table
Add a link
Reference in a new issue