Compare commits

...

2 Commits

25 changed files with 378 additions and 236 deletions

Binary file not shown.

View File

@ -13,25 +13,25 @@
<workerClass>Rimworld_Animations.AnimationWorker_KeyframesExtended</workerClass>
<keyframes>
<li Class="Rimworld_Animations.ExtendedKeyframe">
<offset>(1, -1, 0)</offset>
<offset>(1, 0, 0)</offset>
<tick>0</tick>
<angle>0</angle>
<rotation>North</rotation>
</li>
<li Class="Rimworld_Animations.ExtendedKeyframe">
<offset>(0, -1, 0)</offset>
<offset>(0, 0, 0)</offset>
<tick>30</tick>
<angle>15</angle>
<rotation>North</rotation>
</li>
<li Class="Rimworld_Animations.ExtendedKeyframe">
<offset>(-1, -1, 0)</offset>
<offset>(-1, 0, 0)</offset>
<tick>60</tick>
<angle>0</angle>
<rotation>North</rotation>
</li>
<li Class="Rimworld_Animations.ExtendedKeyframe">
<offset>(0, -1, 0)</offset>
<offset>(0, 0, 0)</offset>
<tick>90</tick>
<angle>-15</angle>
<rotation>North</rotation>

View File

@ -3,7 +3,6 @@
<Rimworld_Animations.GroupAnimationDef>
<defName>TestGroupAnimation1</defName>
<numActors>2</numActors>
<canMirror>True</canMirror>
<animationStages>
<li Class="Rimworld_Animations.AnimationStage_LoopRandomSelectChance">
<loops>10</loops>

View File

@ -3,11 +3,12 @@
<Rimworld_Animations.AnimationOffsetDef>
<defName>GroinToAppropriateHeight</defName>
<offsets>
<li Class="Rimworld_Animations.AnimationOffset_Single">
<li Class="Rimworld_Animations.AnimationOffset_Single" MayRequire="erdelf.HumanoidAlienRaces,dianawinters.Orassans">
<races>
<li>Alien_Orassan</li>
</races>
<offset>(0, 0, 5)</offset>
<rotation>90</rotation>
</li>
<li Class="Rimworld_Animations.AnimationOffset_BodyType">
@ -15,7 +16,7 @@
<li>Human</li>
</races>
<offsets>
<li><bodyType>Hulk</bodyType><offset>(0, 0, 0.5)</offset></li>
<li><bodyType>Hulk</bodyType><offset>(0, 0, 0.5)</offset><rotation>90</rotation></li>
<li><bodyType>Thin</bodyType><offset>(0, 0, 0.3)</offset></li>
<li><bodyType>Female</bodyType><offset>(0, 0, 0.4)</offset></li>
</offsets>

View File

@ -13,21 +13,20 @@ namespace Rimworld_Animations
public List<BaseAnimationOffset> offsets;
public Vector3 FindOffset(Pawn pawn)
public bool FindOffset(Pawn pawn, out BaseAnimationOffset offset)
{
foreach (BaseAnimationOffset animOffset in offsets)
{
if (animOffset.appliesToPawn(pawn)) {
Vector3? offset = animOffset.getOffset(pawn);
return (offset == null ? Vector3.zero : (Vector3)offset);
offset = animOffset;
return true;
}
}
return Vector3.zero;
offset = null;
return false;
}
}
}

View File

@ -18,6 +18,11 @@ namespace Rimworld_Animations
{
return offsets.Find(x => x.bodyType == pawn.story.bodyType)?.offset;
}
public override int? getRotation(Pawn pawn)
{
return offsets.Find(x => x.bodyType == pawn.story.bodyType)?.rotation;
}
}
}

View File

@ -26,5 +26,19 @@ namespace Rimworld_Animations
}
}
public override int? getRotation(Pawn pawn)
{
if (pawn.gender == Gender.Female)
{
return offsetsFemale.Find(x => x.bodyType == pawn.story.bodyType)?.rotation;
}
else
{
return offsetsMale.Find(x => x.bodyType == pawn.story.bodyType)?.rotation;
}
}
}
}

View File

@ -12,10 +12,16 @@ namespace Rimworld_Animations
{
public Vector3 offset;
public int? rotation;
public override Vector3? getOffset(Pawn pawn)
{
return offset;
}
public override int? getRotation(Pawn pawn)
{
return rotation;
}
}
}

View File

@ -15,6 +15,8 @@ namespace Rimworld_Animations
public abstract Vector3? getOffset(Pawn pawn);
public abstract int? getRotation(Pawn pawn);
public bool appliesToPawn(Pawn pawn)
{
return races.Contains(pawn.def);

View File

@ -12,6 +12,7 @@ namespace Rimworld_Animations
public class BodyTypeOffset
{
public BodyTypeDef bodyType;
public int rotation = 0;
public Vector3 offset;
}
}

View File

@ -18,7 +18,7 @@ namespace Rimworld_Animations
public bool canAnimationBeUsed(List<Pawn> actors, out int reorder)
{
if (AnimationSettings.debugMode)
if (RJWAnimationSettings.debugMode)
{
Log.Message("[anims] Checking if " + defName + " is valid animation");
}
@ -51,12 +51,23 @@ namespace Rimworld_Animations
return animations;
}
public Vector3? GetOffset(int actor, Pawn pawn, int reorder = 0)
public bool GetOffset(int actor, Pawn pawn, out Vector3? position, out int? rotation, int reorder = 0)
{
position = null;
rotation = null;
//element at or default to stop errors
if (offsetDefs == null) return null;
if ((actor + reorder) % numActors >= offsetDefs.Count) return null;
return offsetDefs[(actor + reorder) % numActors].FindOffset(pawn);
if (offsetDefs == null) return false;
if ((actor + reorder) % numActors >= offsetDefs.Count) return false;
if (offsetDefs[(actor + reorder) % numActors].FindOffset(pawn, out BaseAnimationOffset animationOffset))
{
position = animationOffset.getOffset(pawn);
rotation = animationOffset.getRotation(pawn);
return true;
}
return false;
}
}
}

View File

@ -19,6 +19,7 @@ namespace Rimworld_Animations {
private List<AnimationDef> animationQueue;
private BaseExtendedAnimatorAnchor anchor;
private int? rotation;
private Vector3? offset;
private bool isAnimating = false;
@ -51,6 +52,18 @@ namespace Rimworld_Animations {
}
}
public int? Rotation
{
get
{
return rotation;
}
set
{
this.rotation = value;
}
}
public int AnimationLength
{
get
@ -68,6 +81,15 @@ namespace Rimworld_Animations {
}
}
public AnimationDef CurrentAnimation {
get
{
return IsAnimating ? animationQueue[0] : null;
}
}
public Vector3 getAnchor()
{
return anchor.getDrawPos();
@ -135,17 +157,18 @@ namespace Rimworld_Animations {
pawn.Drawer.renderer.SetAnimation(null);
}
public void PlayGroupAnimation(List<AnimationDef> groupAnimation, Vector3? offset)
public void PlayGroupAnimation(List<AnimationDef> groupAnimation, Vector3? positionOffset, int? rotationOffset)
{
this.Offset = offset;
this.Offset = positionOffset;
this.Rotation = rotationOffset;
animationQueue = groupAnimation;
PlayNextAnimation();
}
public void PlayGroupAnimation(List<AnimationDef> groupAnimation, Vector3? offset, BaseExtendedAnimatorAnchor anchor)
public void PlayGroupAnimation(List<AnimationDef> groupAnimation, Vector3? positionOffset, int? rotationOffset, BaseExtendedAnimatorAnchor anchor)
{
this.anchor = anchor;
PlayGroupAnimation(groupAnimation, offset);
PlayGroupAnimation(groupAnimation, positionOffset, rotationOffset);
}
public override void PostExposeData()

View File

@ -22,6 +22,7 @@ namespace Rimworld_Animations
public override Vector3 getDrawPos()
{
//vector3.up means stand above the thing
return thing.DrawPos;
}

View File

@ -2,12 +2,13 @@
using Verse;
using RimWorld;
using UnityEngine;
using System.Windows;
namespace Rimworld_Animations {
class MainTabWindow_OffsetConfigure : MainTabWindow
{
public override Vector2 RequestedTabSize => new Vector2(505, 380);
public override Vector2 RequestedTabSize => new Vector2(505, 500);
public override void DoWindowContents(Rect inRect) {
Rect position = new Rect(inRect.x, inRect.y, inRect.width, inRect.height);
@ -16,121 +17,167 @@ namespace Rimworld_Animations {
Listing_Standard listingStandard = new Listing_Standard();
listingStandard.Begin(position);
listingStandard.Label("Animation Manager");
listingStandard.Label("RimAnims_AnimManager".Translate());
listingStandard.GapLine();
/*
if (Find.Selector.SingleSelectedThing is Pawn curPawn) {
if (CompBodyAnimator.IsAnimating(curPawn)) {
if (Find.Selector.SingleSelectedThing is Pawn curPawn
&& curPawn.TryGetComp<CompExtendedAnimator>(out CompExtendedAnimator extendedAnimator)
&& extendedAnimator.IsAnimating)
{
//Pawn info about their body, race
Vector3 offsetPosition = extendedAnimator.Offset != null ? (Vector3)extendedAnimator.Offset : Vector3.zero;
int offsetRotation = extendedAnimator.Rotation != null ? (int)extendedAnimator.Rotation : 0;
CompBodyAnimator compBodyAnimator = curPawn.TryGetComp<CompBodyAnimator>();
AnimationDef def = compBodyAnimator.CurrentAnimation;
int ActorIndex = compBodyAnimator.ActorIndex;
float offsetX = 0, offsetZ = 0, rotation = 0;
string pawnDef = curPawn.def.defName;
string bodyTypeDef = (curPawn.story?.bodyType != null) ? curPawn.story.bodyType.ToString() : "None";
string genderDef = curPawn.gender.ToString();
string currentAnimation = extendedAnimator.CurrentAnimation != null ? extendedAnimator.CurrentAnimation.defName : "None";
string bodyTypeDef = (curPawn.story?.bodyType != null) ? curPawn.story.bodyType.ToString() : "";
listingStandard.Label(curPawn.Name + ": " + curPawn.def.defName + ", " + bodyTypeDef + ", " + genderDef + ", Animation: " + currentAnimation);
if (AnimationSettings.offsets.ContainsKey(def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex)) {
offsetX = AnimationSettings.offsets[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex].x;
offsetZ = AnimationSettings.offsets[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex].y;
} else {
AnimationSettings.offsets.Add(def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex, new Vector2(0, 0));
}
if (curPawn.def.defName == "Human")
{
listingStandard.Label("RimAnims_Warning".Translate());
}
if (AnimationSettings.rotation.ContainsKey(def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex)) {
rotation = AnimationSettings.rotation[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex];
}
else {
AnimationSettings.rotation.Add(def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex, 0);
}
float posX = offsetPosition.x, posY = offsetPosition.y, posZ = offsetPosition.z;
int rot = offsetRotation;
listingStandard.Label("Name: " + curPawn.Name + " Race: " + curPawn.def.defName + " Actor Index: " + curPawn.TryGetComp<CompBodyAnimator>().ActorIndex + " Body Type (if any): " + bodyTypeDef + " Animation: " + def.label + (curPawn.TryGetComp<CompBodyAnimator>().Mirror ? " mirrored" : ""));
float.TryParse(listingStandard.TextEntryLabeled("X: ", posX.ToString()), out posX);
posX = listingStandard.Slider(posX, -2, 2);
if(curPawn.def.defName == "Human") {
listingStandard.Label("Warning--You generally don't want to change human offsets, only alien offsets");
}
float.TryParse(listingStandard.TextEntryLabeled("Y: ", offsetPosition.y.ToString()), out posY);
posY = listingStandard.Slider(posY, -2, 2);
float.TryParse(listingStandard.TextEntryLabeled("X Offset: ", offsetX.ToString()), out offsetX);
offsetX = listingStandard.Slider(offsetX, -2, 2);
float.TryParse(listingStandard.TextEntryLabeled("Z: ", posZ.ToString()), out posZ);
posZ = listingStandard.Slider(posZ, -2, 2);
float.TryParse(listingStandard.TextEntryLabeled("Z Offset: ", offsetZ.ToString()), out offsetZ);
offsetZ = listingStandard.Slider(offsetZ, -2, 2);
int.TryParse(listingStandard.TextEntryLabeled("Rotation: ", rot.ToString()), out rot);
rot = (int)listingStandard.Slider(rot, -180, 180);
float.TryParse(listingStandard.TextEntryLabeled("Rotation: ", rotation.ToString()), out rotation);
rotation = listingStandard.Slider(rotation, -180, 180);
listingStandard.GapLine();
Vector3 newOffsetVector = new Vector3(posX, posY, posZ);
if(listingStandard.ButtonText("Reset All")) {
offsetX = 0;
offsetZ = 0;
rotation = 0;
}
string offset = "<li>";
offset += bodyTypeDef != "None" ? "<bodyType>" + bodyTypeDef + "</bodyType>" : "";
offset += newOffsetVector != Vector3.zero ? "<offset>(" + posX + ", " + posY + ", " + posZ + ")</offset>" : "";
offset += rot != 0 ? "<rotation>" + rot + "</rotation>" : "";
offset += "</li>";
listingStandard.GapLine();
listingStandard.Label("Appropriate Offset value for " + currentAnimation + ", " + pawnDef + ", " + bodyTypeDef + ", " + genderDef + ": ");
listingStandard.Label(offset);
if(listingStandard.ButtonText("Shift Actors")) {
if(AnimationSettings.debugMode) {
Log.Message("Shifting actors in animation...");
}
if (listingStandard.ButtonText("RimAnims_CopyToClipboard".Translate()))
{
for(int i = 0; i < curPawn.TryGetComp<CompBodyAnimator>().actorsInCurrentAnimation.Count; i++) {
Pawn actor = curPawn.TryGetComp<CompBodyAnimator>().actorsInCurrentAnimation[i];
actor.TryGetComp<CompBodyAnimator>()?.shiftActorPositionAndRestartAnimation();
//reset the clock time of every pawn in animation
if(actor.jobs.curDriver is rjw.JobDriver_Sex) {
(actor.jobs.curDriver as rjw.JobDriver_Sex).ticks_left = def.animationTimeTicks;
(actor.jobs.curDriver as rjw.JobDriver_Sex).ticksLeftThisToil = def.animationTimeTicks;
(actor.jobs.curDriver as rjw.JobDriver_Sex).duration = def.animationTimeTicks;
}
}
}
if (offsetX != AnimationSettings.offsets[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex].x || offsetZ != AnimationSettings.offsets[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex].y) {
AnimationSettings.offsets[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex] = new Vector2(offsetX, offsetZ);
}
if(rotation != AnimationSettings.rotation[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex]) {
AnimationSettings.rotation[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex] = rotation;
}
GUIUtility.systemCopyBuffer = offset;
}
listingStandard.Label("RimAnims_ShareSettings".Translate());
extendedAnimator.Offset = newOffsetVector;
extendedAnimator.Rotation = rot;
}
else {
else
{
listingStandard.Label("Select a pawn currently in an animation to change their offsets");
}
*/
listingStandard.End();
}
public override void PreOpen() {
base.PreOpen();
if(AnimationSettings.offsets == null) {
if (AnimationSettings.debugMode)
Log.Message("New offsets");
AnimationSettings.offsets = new Dictionary<string, Vector2>();
}
if(AnimationSettings.rotation == null) {
if (AnimationSettings.debugMode)
Log.Message("New rotation");
AnimationSettings.rotation = new Dictionary<string, float>();
}
}
public override void PostClose() {
base.PostClose();
LoadedModManager.GetMod<RJW_Animations>().WriteSettings();
}
}
}
/**
if (curPawn.TryGetComp<CompExtendedAnimator> animator) {
/*
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() : "";
if (AnimationSettings.offsets.ContainsKey(def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex)) {
offsetX = AnimationSettings.offsets[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex].x;
offsetZ = AnimationSettings.offsets[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex].y;
} else {
AnimationSettings.offsets.Add(def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex, new Vector2(0, 0));
}
if (AnimationSettings.rotation.ContainsKey(def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex)) {
rotation = AnimationSettings.rotation[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex];
}
else {
AnimationSettings.rotation.Add(def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex, 0);
}
listingStandard.Label("Name: " + curPawn.Name + " Race: " + curPawn.def.defName + " Actor Index: " + curPawn.TryGetComp<CompBodyAnimator>().ActorIndex + " Body Type (if any): " + bodyTypeDef + " Animation: " + def.label + (curPawn.TryGetComp<CompBodyAnimator>().Mirror ? " mirrored" : ""));
if(curPawn.def.defName == "Human") {
listingStandard.Label("Warning--You generally don't want to change human offsets, only alien offsets");
}
float.TryParse(listingStandard.TextEntryLabeled("X Offset: ", offsetX.ToString()), out offsetX);
offsetX = listingStandard.Slider(offsetX, -2, 2);
float.TryParse(listingStandard.TextEntryLabeled("Z Offset: ", offsetZ.ToString()), out offsetZ);
offsetZ = listingStandard.Slider(offsetZ, -2, 2);
float.TryParse(listingStandard.TextEntryLabeled("Rotation: ", rotation.ToString()), out rotation);
rotation = listingStandard.Slider(rotation, -180, 180);
if(listingStandard.ButtonText("Reset All")) {
offsetX = 0;
offsetZ = 0;
rotation = 0;
}
listingStandard.GapLine();
if(listingStandard.ButtonText("Shift Actors")) {
if(AnimationSettings.debugMode) {
Log.Message("Shifting actors in animation...");
}
for(int i = 0; i < curPawn.TryGetComp<CompBodyAnimator>().actorsInCurrentAnimation.Count; i++) {
Pawn actor = curPawn.TryGetComp<CompBodyAnimator>().actorsInCurrentAnimation[i];
actor.TryGetComp<CompBodyAnimator>()?.shiftActorPositionAndRestartAnimation();
//reset the clock time of every pawn in animation
if(actor.jobs.curDriver is rjw.JobDriver_Sex) {
(actor.jobs.curDriver as rjw.JobDriver_Sex).ticks_left = def.animationTimeTicks;
(actor.jobs.curDriver as rjw.JobDriver_Sex).ticksLeftThisToil = def.animationTimeTicks;
(actor.jobs.curDriver as rjw.JobDriver_Sex).duration = def.animationTimeTicks;
}
}
}
if (offsetX != AnimationSettings.offsets[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex].x || offsetZ != AnimationSettings.offsets[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex].y) {
AnimationSettings.offsets[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex] = new Vector2(offsetX, offsetZ);
}
if(rotation != AnimationSettings.rotation[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex]) {
AnimationSettings.rotation[def.defName + curPawn.def.defName + bodyTypeDef + ActorIndex] = rotation;
}
}
}
*/

View File

@ -16,7 +16,7 @@ namespace Rimworld_Animations {
public override void FinalizeInit() {
base.FinalizeInit();
OffsetMainButtonDefOf.OffsetManager.buttonVisible = AnimationSettings.offsetTab;
OffsetMainButtonDefOf.OffsetManager.buttonVisible = RJWAnimationSettings.offsetTab;
}

View File

@ -5,20 +5,23 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse;
namespace Rimworld_Animations
{
/*
[HarmonyPatch(typeof(JobDriver_Sex), "SexTick")]
[HarmonyPatch(typeof(JobDriver_Sex), "setup_ticks")]
public class HarmonyPatch_JobDriver_Sex
{
public static void Prefix(JobDriver_Sex __instance)
public static void Postfix(JobDriver_Sex __instance)
{
Pawn partner = __instance.Partner;
if (!RJWAnimationSettings.hearts)
{
__instance.ticks_between_hearts = int.MaxValue;
}
}
}
*/
}

View File

@ -21,7 +21,7 @@ namespace Rimworld_Animations {
}
if(!AnimationSettings.PlayAnimForNonsexualActs && NonSexualAct(__instance))
if(!RJWAnimationSettings.PlayAnimForNonsexualActs && NonSexualAct(__instance))
{
return;
}
@ -34,8 +34,6 @@ namespace Rimworld_Animations {
Pawn Target = __instance.Target as Pawn;
bool quickie = (__instance is JobDriver_SexQuick) && AnimationSettings.fastAnimForQuickie;
int preAnimDuration = __instance.duration;
@ -44,7 +42,11 @@ namespace Rimworld_Animations {
GroupAnimationDef groupAnimation = AnimationUtility.FindGroupAnimation(participants, out int reorder);
if (groupAnimation != null)
{
AnimationUtility.StartGroupAnimation(participants, groupAnimation, reorder, partner);
Thing anchor;
if (bed != null) anchor = bed;
else anchor = partner;
AnimationUtility.StartGroupAnimation(participants, groupAnimation, reorder, anchor);
int animTicks = AnimationUtility.GetAnimationLength(pawn);
foreach(Pawn participant in participants)

View File

@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using UnityEngine;
using RimWorld;
namespace Rimworld_Animations {
public class RJWAnimationSettings : ModSettings {
public static bool orgasmQuiver, rapeShiver, soundOverride = true, hearts = true, controlGenitalRotation = false,
PlayAnimForNonsexualActs = true;
public static bool offsetTab = false, debugMode = false;
public static float shiverIntensity = 2f;
public override void ExposeData() {
base.ExposeData();
Scribe_Values.Look(ref debugMode, "RJWAnimations-AnimsDebugMode", false);
Scribe_Values.Look(ref offsetTab, "RJWAnimations-EnableOffsetTab", false);
Scribe_Values.Look(ref controlGenitalRotation, "RJWAnimations-controlGenitalRotation", false);
Scribe_Values.Look(ref orgasmQuiver, "RJWAnimations-orgasmQuiver");
Scribe_Values.Look(ref rapeShiver, "RJWAnimations-rapeShiver");
Scribe_Values.Look(ref hearts, "RJWAnimation-heartsOnLovin");
Scribe_Values.Look(ref PlayAnimForNonsexualActs, "RJWAnims-PlayAnimForNonsexualActs");
Scribe_Values.Look(ref soundOverride, "RJWAnimations-rjwAnimSoundOverride", true);
Scribe_Values.Look(ref shiverIntensity, "RJWAnimations-shiverIntensity", 2f);
//todo: save offsetsByDefName
}
}
public class RJW_Animations : Mod {
public RJW_Animations(ModContentPack content) : base(content) {
GetSettings<RJWAnimationSettings>();
}
public override void DoSettingsWindowContents(Rect inRect) {
Listing_Standard listingStandard = new Listing_Standard();
listingStandard.Begin(inRect);
listingStandard.CheckboxLabeled("RimAnim_SoundOverride".Translate(), ref RJWAnimationSettings.soundOverride);
listingStandard.CheckboxLabeled("RimAnim_GenitalRotation".Translate(), ref RJWAnimationSettings.controlGenitalRotation);
listingStandard.CheckboxLabeled("RimAnim_OrgasmQuiver".Translate(), ref RJWAnimationSettings.orgasmQuiver);
listingStandard.CheckboxLabeled("RimAnim_RapeShiver".Translate(), ref RJWAnimationSettings.rapeShiver);
listingStandard.CheckboxLabeled("RimAnim_HeartsDuringLovin".Translate(), ref RJWAnimationSettings.hearts);
listingStandard.CheckboxLabeled("RimAnim_PlayNonsexual".Translate(), ref RJWAnimationSettings.PlayAnimForNonsexualActs);
listingStandard.CheckboxLabeled("RimAnim_AnimManagerTab".Translate(), ref RJWAnimationSettings.offsetTab);
listingStandard.Label("RimAnim_ShiverIntensity".Translate() + RJWAnimationSettings.shiverIntensity);
RJWAnimationSettings.shiverIntensity = listingStandard.Slider(RJWAnimationSettings.shiverIntensity, 0.0f, 12f);
listingStandard.CheckboxLabeled("RimAnim_DebugMode".Translate(), ref RJWAnimationSettings.debugMode);
listingStandard.End();
base.DoSettingsWindowContents(inRect);
}
public override void WriteSettings() {
base.WriteSettings();
OffsetMainButtonDefOf.OffsetManager.buttonVisible = RJWAnimationSettings.offsetTab;
}
public override string SettingsCategory() {
return "RimAnim_ModSettings".Translate();
}
}
}

View File

@ -7,20 +7,20 @@ namespace Rimworld_Animations {
[HarmonyPatch(typeof(Pawn_DrawTracker), "DrawPos", MethodType.Getter)]
public static class HarmonyPatch_Pawn_DrawTracker {
public static bool Prefix(ref Pawn ___pawn, ref Vector3 __result) {
CompExtendedAnimator animator = ___pawn.TryGetComp<CompExtendedAnimator>();
//switch to postfix to get pawn original height first
public static void Postfix(ref Pawn ___pawn, ref Vector3 __result) {
//align pos on top of partner, position, etc., based on animatoranchor
if (animator != null && animator.IsAnchored)
if (___pawn.TryGetComp<CompExtendedAnimator>() is CompExtendedAnimator animator
&& animator.IsAnchored)
{
__result = animator.getAnchor();
return false;
Vector3 anchor = animator.getAnchor();
//ignore y so that pawns don't clip through stuff
__result.x = anchor.x;
__result.z = anchor.z;
}
return true;
}
}
}

View File

@ -26,5 +26,25 @@ namespace Rimworld_Animations
}
}
public override void TransformRotation(PawnRenderNode node, PawnDrawParms parms, ref Quaternion rotation)
{
if (node.AnimationWorker is AnimationWorker_KeyframesExtended
&& node.tree.pawn.TryGetComp<CompExtendedAnimator>(out CompExtendedAnimator extendedAnimator)
&& extendedAnimator.IsAnimating)
{
int? pawnRotation = extendedAnimator.Rotation;
if (pawnRotation != null)
{
Quaternion additionalRotation = Quaternion.AngleAxis((int)pawnRotation, Vector3.up);
rotation *= additionalRotation;
}
}
base.TransformRotation(node, parms, ref rotation);
}
}
}

View File

@ -1,98 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using UnityEngine;
using RimWorld;
namespace Rimworld_Animations {
public class AnimationSettings : ModSettings {
public static bool orgasmQuiver, rapeShiver, soundOverride = true, hearts = true, controlGenitalRotation = false, applySemenOnAnimationOrgasm = false, fastAnimForQuickie = false,
PlayAnimForNonsexualActs = true;
public static bool offsetTab = false, debugMode = false;
public static float shiverIntensity = 2f;
public static Dictionary<string, Vector2> offsets = new Dictionary<string, Vector2>();
public static Dictionary<string, float> rotation = new Dictionary<string, float>();
public override void ExposeData() {
base.ExposeData();
Scribe_Values.Look(ref debugMode, "RJWAnimations-AnimsDebugMode", false);
Scribe_Values.Look(ref offsetTab, "RJWAnimations-EnableOffsetTab", false);
Scribe_Values.Look(ref controlGenitalRotation, "RJWAnimations-controlGenitalRotation", false);
Scribe_Values.Look(ref orgasmQuiver, "RJWAnimations-orgasmQuiver");
Scribe_Values.Look(ref fastAnimForQuickie, "RJWAnimations-fastAnimForQuickie");
Scribe_Values.Look(ref rapeShiver, "RJWAnimations-rapeShiver");
Scribe_Values.Look(ref hearts, "RJWAnimation-heartsOnLovin");
Scribe_Values.Look(ref PlayAnimForNonsexualActs, "RJWAnims-PlayAnimForNonsexualActs");
Scribe_Values.Look(ref applySemenOnAnimationOrgasm, "RJWAnimations-applySemenOnOrgasm", false);
Scribe_Values.Look(ref soundOverride, "RJWAnimations-rjwAnimSoundOverride", true);
Scribe_Values.Look(ref shiverIntensity, "RJWAnimations-shiverIntensity", 2f);
//todo: save offsetsByDefName
Scribe_Collections.Look(ref offsets, "RJWAnimations-animationOffsets");
Scribe_Collections.Look(ref rotation, "RJWAnimations-rotationOffsets");
//needs to be rewritten
//probably somewhere in options?
}
}
public class RJW_Animations : Mod {
public RJW_Animations(ModContentPack content) : base(content) {
GetSettings<AnimationSettings>();
}
public override void DoSettingsWindowContents(Rect inRect) {
Listing_Standard listingStandard = new Listing_Standard();
listingStandard.Begin(inRect);
listingStandard.CheckboxLabeled("Enable Sound Override", ref AnimationSettings.soundOverride);
listingStandard.CheckboxLabeled("Control Genital Rotation", ref AnimationSettings.controlGenitalRotation);
listingStandard.CheckboxLabeled("Play Fast Animation for Quickie", ref AnimationSettings.fastAnimForQuickie);
listingStandard.CheckboxLabeled("Apply Semen on Animation Orgasm", ref AnimationSettings.applySemenOnAnimationOrgasm);
if(AnimationSettings.applySemenOnAnimationOrgasm) {
listingStandard.Label("Recommended--turn down \"Cum on body percent\" in RJW settings to about 33%");
}
listingStandard.CheckboxLabeled("Enable Orgasm Quiver", ref AnimationSettings.orgasmQuiver);
listingStandard.CheckboxLabeled("Enable Rape Shiver", ref AnimationSettings.rapeShiver);
listingStandard.CheckboxLabeled("Enable hearts during lovin'", ref AnimationSettings.hearts);
listingStandard.CheckboxLabeled("Play animation for nonsexual acts (handholding, makeout)", ref AnimationSettings.PlayAnimForNonsexualActs);
listingStandard.CheckboxLabeled("Enable Animation Manager Tab", ref AnimationSettings.offsetTab);
listingStandard.Label("Shiver/Quiver Intensity (default 2): " + AnimationSettings.shiverIntensity);
AnimationSettings.shiverIntensity = listingStandard.Slider(AnimationSettings.shiverIntensity, 0.0f, 12f);
listingStandard.CheckboxLabeled("Debug Mode", ref AnimationSettings.debugMode);
listingStandard.End();
base.DoSettingsWindowContents(inRect);
}
public override void WriteSettings() {
base.WriteSettings();
OffsetMainButtonDefOf.OffsetManager.buttonVisible = AnimationSettings.offsetTab;
}
public override string SettingsCategory() {
return "RJW Animation Settings";
}
}
}

View File

@ -30,21 +30,21 @@ namespace Rimworld_Animations {
for (int i = 0; i < participants.Count; i++)
{
Vector3? offset = groupAnimationDef.GetOffset(i, participants[i], reorder);
groupAnimationDef.GetOffset(i, participants[i], out Vector3? position, out int? rotation, reorder);
if (anchor is Pawn pawn && pawn == participants[i])
{
List<AnimationDef> allAnimationsForPawn = groupAnimationDef.GetAllAnimationsForActor(i, seed, reorder);
participants[i].TryGetComp<CompExtendedAnimator>().PlayGroupAnimation(allAnimationsForPawn, offset);
participants[i].TryGetComp<CompExtendedAnimator>().PlayGroupAnimation(allAnimationsForPawn, position, rotation);
}
else
{
//each participant gets their own unique extendedanimatoranchor, important for scribe_deep saving
List<AnimationDef> allAnimationsForPawn = groupAnimationDef.GetAllAnimationsForActor(i, seed, reorder);
BaseExtendedAnimatorAnchor animatorAnchor = new ExtendedAnimatorAnchor_Thing(anchor);
participants[i].TryGetComp<CompExtendedAnimator>().PlayGroupAnimation(allAnimationsForPawn, offset, animatorAnchor);
participants[i].TryGetComp<CompExtendedAnimator>().PlayGroupAnimation(allAnimationsForPawn, position, rotation, animatorAnchor);
}
}
}
@ -57,8 +57,8 @@ namespace Rimworld_Animations {
for (int i = 0; i < participants.Count; i++)
{
List<AnimationDef> allAnimationsForPawn = groupAnimationDef.GetAllAnimationsForActor(i, seed, reorder);
Vector3? offset = groupAnimationDef.GetOffset(i, participants[i], reorder);
participants[i].TryGetComp<CompExtendedAnimator>().PlayGroupAnimation(allAnimationsForPawn, offset);
groupAnimationDef.GetOffset(i, participants[i], out Vector3? position, out int? rotation, reorder);
participants[i].TryGetComp<CompExtendedAnimator>().PlayGroupAnimation(allAnimationsForPawn, position, rotation);
}
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData>
<!-- Mod menu -->
<RimAnim_ModSettings>RJW Animation Settings</RimAnim_ModSettings>
<RimAnim_SoundOverride>Enable Sound Override</RimAnim_SoundOverride>
<RimAnim_GenitalRotation>Control Genital Rotation</RimAnim_GenitalRotation>
<RimAnim_OrgasmQuiver>Enable Orgasm Quiver</RimAnim_OrgasmQuiver>
<RimAnim_RapeShiver>Enable Rape Shiver</RimAnim_RapeShiver>
<RimAnim_HeartsDuringLovin>Enable hearts during lovin'</RimAnim_HeartsDuringLovin>
<RimAnim_PlayNonsexual>Play animation for nonsexual acts (handholding, makeout)</RimAnim_PlayNonsexual>
<RimAnim_AnimManagerTab>Enable Animation Manager Tab</RimAnim_AnimManagerTab>
<RimAnim_ShiverIntensity>Shiver/Quiver Intensity (default 2): </RimAnim_ShiverIntensity>
<RimAnim_DebugMode>Debug Mode</RimAnim_DebugMode>
<!-- Main Tab Window -->
<RimAnims_AnimManager>Animation Manager</RimAnims_AnimManager>
<RimAnims_Warning>Warning--You generally don't want to change human offsets, only alien offsets or animals</RimAnims_Warning>
<RimAnims_CopyToClipboard>Copy Offset to Clipboard</RimAnims_CopyToClipboard>
<RimAnims_ShareSettings>Paste offset values in OffsetDef, or share in Discord</RimAnims_ShareSettings>
</LanguageData>

View File

@ -68,6 +68,10 @@
<HintPath>..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.IMGUIModule">
<HintPath>..\..\RimWorldWin64_Data\Managed\UnityEngine.IMGUIModule.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="1.5\Source\Actors\Actor.cs" />
@ -122,7 +126,7 @@
<Compile Include="1.5\Source\PawnRenderNode\GraphicVariants\PawnRenderNode_GraphicVariants.cs" />
<Compile Include="1.5\Source\PawnRenderNode\TexPathVariants.cs" />
<Compile Include="1.5\Source\RenderSubWorkers\PawnRenderSubWorker_ChangeOffset.cs" />
<Compile Include="1.5\Source\Settings\AnimationSettings.cs" />
<Compile Include="1.5\Source\Patches\RJWPatches\RJWAnimationSettings.cs" />
<Compile Include="1.5\Source\Utilities\AnimationUtility.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
@ -187,6 +191,7 @@
<Content Include="1.5\Textures\UI\MainTab.png" />
<Content Include="About\About.xml" />
<Content Include="About\Manifest.xml" />
<Content Include="Languages\English\Keyed\RJWAnimations-LanguageData.xml" />
<Content Include="Languages\PortugueseBrazilian\DefInjected\MainButtonDef\MainButtonDef.xml" />
<Content Include="Languages\PortugueseBrazilian\DefInjected\Rimworld_Animations.AnimationDef\Animations_Beast.xml" />
<Content Include="Languages\PortugueseBrazilian\DefInjected\Rimworld_Animations.AnimationDef\Animations_Lesbian.xml" />
@ -197,6 +202,7 @@
<ItemGroup>
<Folder Include="1.5\Source\Extensions\" />
<Folder Include="1.5\Source\Patches\OtherModPatches\" />
<Folder Include="1.5\Source\Settings\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>