diff --git a/1.5/Assemblies/Rimworld-Animations.dll b/1.5/Assemblies/Rimworld-Animations.dll index d859982..fc2cf06 100644 Binary files a/1.5/Assemblies/Rimworld-Animations.dll and b/1.5/Assemblies/Rimworld-Animations.dll differ diff --git a/1.5/Defs/VoiceDefs/VoiceDef_Human.xml b/1.5/Defs/VoiceDefs/VoiceDef_Human.xml new file mode 100644 index 0000000..89c2f3e --- /dev/null +++ b/1.5/Defs/VoiceDefs/VoiceDef_Human.xml @@ -0,0 +1,21 @@ + + + + Voice_HumanFemale + Human + Female + + + + + + + Voice_HumanMale + Human + Male + + + + + + diff --git a/1.5/Defs/VoiceDefs/VoiceDef_Orassan.xml b/1.5/Defs/VoiceDefs/VoiceDef_Orassan.xml new file mode 100644 index 0000000..0026987 --- /dev/null +++ b/1.5/Defs/VoiceDefs/VoiceDef_Orassan.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/1.5/Defs/VoiceDefs/VoiceTagDef.xml b/1.5/Defs/VoiceDefs/VoiceTagDef.xml new file mode 100644 index 0000000..04651dd --- /dev/null +++ b/1.5/Defs/VoiceDefs/VoiceTagDef.xml @@ -0,0 +1,6 @@ + + + + Moan + + \ No newline at end of file diff --git a/1.5/Source/Animations/AnimationWorkers/AnimationWorker_KeyframesExtended.cs b/1.5/Source/Animations/AnimationWorkers/AnimationWorker_KeyframesExtended.cs index 0b74719..3894b1a 100644 --- a/1.5/Source/Animations/AnimationWorkers/AnimationWorker_KeyframesExtended.cs +++ b/1.5/Source/Animations/AnimationWorkers/AnimationWorker_KeyframesExtended.cs @@ -22,6 +22,23 @@ namespace Rimworld_Animations return base.OffsetAtTick(tick, parms); } + public VoiceTagDef voiceAtTick(int tick) + { + + Verse.Keyframe keyframe2 = this.part.keyframes[this.part.keyframes.Count - 1]; + foreach (Verse.Keyframe keyframe in this.part.keyframes) + { + if (tick == keyframe.tick) + { + return (keyframe as ExtendedKeyframe).voice; + } + + } + + return null; + + } + public SoundDef soundAtTick(int tick) { diff --git a/1.5/Source/Animations/GroupAnimations/GroupAnimationDef.cs b/1.5/Source/Animations/GroupAnimations/GroupAnimationDef.cs index b49f14d..fb9eb43 100644 --- a/1.5/Source/Animations/GroupAnimations/GroupAnimationDef.cs +++ b/1.5/Source/Animations/GroupAnimations/GroupAnimationDef.cs @@ -52,7 +52,7 @@ namespace Rimworld_Animations { if (context.AnimationPriority() > priority) { - //get highest priority context for fitting animation + //get highest priority context for fitting animation, and its reorder priority = context.AnimationPriority(); reorder = context.AnimationReorder(); diff --git a/1.5/Source/Animations/Keyframes/ExtendedKeyframe.cs b/1.5/Source/Animations/Keyframes/ExtendedKeyframe.cs index 642fc63..4d1031e 100644 --- a/1.5/Source/Animations/Keyframes/ExtendedKeyframe.cs +++ b/1.5/Source/Animations/Keyframes/ExtendedKeyframe.cs @@ -13,6 +13,7 @@ namespace Rimworld_Animations public int? variant; public Rot4 rotation = Rot4.North; public SoundDef sound = null; + public VoiceTagDef voice = null; public bool visible = true; } } diff --git a/1.5/Source/Comps/CompExtendedAnimator.cs b/1.5/Source/Comps/CompExtendedAnimator.cs index b6172c2..d86bdbf 100644 --- a/1.5/Source/Comps/CompExtendedAnimator.cs +++ b/1.5/Source/Comps/CompExtendedAnimator.cs @@ -19,11 +19,11 @@ namespace Rimworld_Animations { private List animationQueue; private BaseExtendedAnimatorAnchor anchor; - private int? rotation; - private Vector3? offset; + private VoiceDef voice; + + private bool isAnimating = false; - public bool IsAnimating { get @@ -40,6 +40,8 @@ namespace Rimworld_Animations { } } + private Vector3? offset; + public Vector3? Offset { get @@ -52,6 +54,8 @@ namespace Rimworld_Animations { } } + private int? rotation; + public int? Rotation { get @@ -90,6 +94,15 @@ namespace Rimworld_Animations { } + public override void PostSpawnSetup(bool respawningAfterLoad) + { + if (voice == null) + { + AssignNewVoice(); + } + + } + public Vector3 getAnchor() { return anchor.getDrawPos(); @@ -184,6 +197,7 @@ namespace Rimworld_Animations { Scribe_Values.Look(ref this.animationTicks, "animations_ticks", 0); Scribe_Collections.Look(ref animationQueue, "animations_queue"); Scribe_Deep.Look(ref this.anchor, "animations_anchor"); + Scribe_Defs.Look(ref this.voice, "animations_voice"); } @@ -233,6 +247,29 @@ namespace Rimworld_Animations { } + public void AssignNewVoice() + { + //all voice options + List voiceOptions = + DefDatabase.AllDefsListForReading + .FindAll(voiceDef => voiceDef.VoiceFitsPawn(pawn)); + + //all voice options, with priority (for traitdef specific voices) + List voiceOptionsWithPriority = + voiceOptions.FindAll(voiceDef => voiceDef.takesPriority); + + if (!voiceOptionsWithPriority.NullOrEmpty()) + { + voice = voiceOptionsWithPriority.RandomElementByWeight(x => x.randomChanceFactor); + + } + else if (!voiceOptions.NullOrEmpty()) + { + voice = voiceOptions.RandomElementByWeight(x => x.randomChanceFactor); + } + + } + public void CheckAndPlaySounds() { @@ -247,9 +284,32 @@ namespace Rimworld_Animations { sound.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map)); } + //play voice sounds + VoiceTagDef voiceTag = animWorker.voiceAtTick(rootNode.tree.AnimationTick); + if (voiceTag != null) + { + if (voice != null && voice.sounds.ContainsKey(voiceTag)) + { + voice.sounds[voiceTag].PlayOneShot(new TargetInfo(pawn.Position, pawn.Map)); + } + + else if (pawn.RaceProps.Humanlike && RJWAnimationSettings.playHumanlikeVoicesAsDefault) + { + //play default voice + VoiceDef pawnDefaultVoice = (pawn.gender == Gender.Male ? VoiceDefOf.Voice_HumanMale : VoiceDefOf.Voice_HumanFemale); + if (pawnDefaultVoice.sounds.ContainsKey(voiceTag)) + { + pawnDefaultVoice.sounds[voiceTag].PlayOneShot(new TargetInfo(pawn.Position, pawn.Map)); + } + + + } + + } + } - + //check rootnodes and children if (rootNode?.children != null) { foreach (PawnRenderNode node in rootNode?.children) @@ -262,6 +322,25 @@ namespace Rimworld_Animations { sound.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map)); } + //play voice sounds + VoiceTagDef voiceTag = childrenAnimWorker.voiceAtTick(rootNode.tree.AnimationTick); + if (voiceTag != null) + { + if (voice != null && voice.sounds.ContainsKey(voiceTag)) + { + voice.sounds[voiceTag].PlayOneShot(new TargetInfo(pawn.Position, pawn.Map)); + } + else if (pawn.RaceProps.Humanlike && RJWAnimationSettings.playHumanlikeVoicesAsDefault) + { + + VoiceDef pawnDefaultVoice = (pawn.gender == Gender.Male ? VoiceDefOf.Voice_HumanMale : VoiceDefOf.Voice_HumanFemale); + if (pawnDefaultVoice.sounds.ContainsKey(voiceTag)) + { + pawnDefaultVoice.sounds[voiceTag].PlayOneShot(new TargetInfo(pawn.Position, pawn.Map)); + } + } + } + } } } @@ -269,6 +348,9 @@ namespace Rimworld_Animations { } + + + public bool AnimationMakesUseOfProp(AnimationPropDef animationProp) { // never true if not animating; anim props shouldn't be attached diff --git a/1.5/Source/Patches/RJWPatches/RJWAnimationSettings.cs b/1.5/Source/Patches/RJWPatches/RJWAnimationSettings.cs index 6cb30d2..fac9115 100644 --- a/1.5/Source/Patches/RJWPatches/RJWAnimationSettings.cs +++ b/1.5/Source/Patches/RJWPatches/RJWAnimationSettings.cs @@ -14,6 +14,9 @@ namespace Rimworld_Animations { public static bool orgasmQuiver, rapeShiver, soundOverride = true, hearts = true, controlGenitalRotation = false, PlayAnimForNonsexualActs = true; + //probably move this setting to a different mod menu if moving rjw parts of code + public static bool playHumanlikeVoicesAsDefault = true; + public static bool offsetTab = false, debugMode = false; public static float shiverIntensity = 2f; @@ -21,6 +24,7 @@ namespace Rimworld_Animations { base.ExposeData(); + Scribe_Values.Look(ref playHumanlikeVoicesAsDefault, "RJWAnimations-playHumanlikeVoicesAsDefault", true); Scribe_Values.Look(ref debugMode, "RJWAnimations-AnimsDebugMode", false); Scribe_Values.Look(ref offsetTab, "RJWAnimations-EnableOffsetTab", false); Scribe_Values.Look(ref controlGenitalRotation, "RJWAnimations-controlGenitalRotation", false); @@ -55,6 +59,7 @@ namespace Rimworld_Animations { 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.CheckboxLabeled("RimAnim_HumanlikeVoicesDefault".Translate(), ref RJWAnimationSettings.playHumanlikeVoicesAsDefault); listingStandard.Label("RimAnim_ShiverIntensity".Translate() + RJWAnimationSettings.shiverIntensity); RJWAnimationSettings.shiverIntensity = listingStandard.Slider(RJWAnimationSettings.shiverIntensity, 0.0f, 12f); diff --git a/1.5/Source/Voices/VoiceDef.cs b/1.5/Source/Voices/VoiceDef.cs new file mode 100644 index 0000000..9dd6c0d --- /dev/null +++ b/1.5/Source/Voices/VoiceDef.cs @@ -0,0 +1,39 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace Rimworld_Animations +{ + public class VoiceDef : Def + { + + public ThingDef race; + public Gender gender = Gender.None; + public List traits = new List(); + public bool takesPriority = false; + public float randomChanceFactor = 1; + + public Dictionary sounds = new Dictionary(); + + public bool VoiceFitsPawn(Pawn pawn) + { + + //doesn't match race + if (pawn.def != race) return false; + + //doesn't match gender + if (gender != Gender.None && pawn.gender != gender) return false; + + //if traits list is not empty, and pawn doesn't have any of the designated traits, doesn't match + if (!traits.Empty() && !traits.Any(trait => pawn.story.traits.HasTrait(trait))) return false; + + return true; + + } + + } +} diff --git a/1.5/Source/Voices/VoiceDefOf.cs b/1.5/Source/Voices/VoiceDefOf.cs new file mode 100644 index 0000000..e489233 --- /dev/null +++ b/1.5/Source/Voices/VoiceDefOf.cs @@ -0,0 +1,22 @@ +using RimWorld; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rimworld_Animations +{ + [DefOf] + public static class VoiceDefOf + { + static VoiceDefOf() + { + DefOfHelper.EnsureInitializedInCtor(typeof(VoiceDefOf)); + } + + public static VoiceDef Voice_HumanMale; + public static VoiceDef Voice_HumanFemale; + } +} diff --git a/1.5/Source/Voices/VoiceTagDef.cs b/1.5/Source/Voices/VoiceTagDef.cs new file mode 100644 index 0000000..3ebb678 --- /dev/null +++ b/1.5/Source/Voices/VoiceTagDef.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace Rimworld_Animations +{ + public class VoiceTagDef : Def + { + } +} diff --git a/Languages/English/Keyed/RJWAnimations-LanguageData.xml b/Languages/English/Keyed/RJWAnimations-LanguageData.xml index 95ecca6..7227181 100644 --- a/Languages/English/Keyed/RJWAnimations-LanguageData.xml +++ b/Languages/English/Keyed/RJWAnimations-LanguageData.xml @@ -11,6 +11,7 @@ Play animation for nonsexual acts (handholding, makeout) Enable Animation Manager Tab Shiver/Quiver Intensity (default 2): + Play humanlike voices by default Debug Mode @@ -19,4 +20,5 @@ Copy Offset to Clipboard Paste offset values in OffsetDef, or share in Discord + \ No newline at end of file diff --git a/Rimworld-Animations.csproj b/Rimworld-Animations.csproj index 3023dc4..619c1b1 100644 --- a/Rimworld-Animations.csproj +++ b/Rimworld-Animations.csproj @@ -134,6 +134,9 @@ + + + @@ -193,6 +196,9 @@ + + +