diff --git a/1.4/Assemblies/Rimworld-Animations-Patch.dll b/1.4/Assemblies/Rimworld-Animations-Patch.dll index 0dc3234..5640258 100644 Binary files a/1.4/Assemblies/Rimworld-Animations-Patch.dll and b/1.4/Assemblies/Rimworld-Animations-Patch.dll differ diff --git a/About/Changelog_v2.0.4.txt b/About/Changelog_v2.0.5.txt similarity index 72% rename from About/Changelog_v2.0.4.txt rename to About/Changelog_v2.0.5.txt index 5c79b48..aec8d7c 100644 --- a/About/Changelog_v2.0.4.txt +++ b/About/Changelog_v2.0.5.txt @@ -1,3 +1,8 @@ +Change log v 2.0.5 +- Fixed an issue with the orgasm not filling in some circumstances +- Fixed a bug with sex overdrive not applying correctly +- Fixed an issue with 'on orgasm' events not triggering correctly + Change log v 2.0.4 - Fixed a bug that was causing body parts to render over clothes diff --git a/About/Manifest.xml b/About/Manifest.xml index b07532d..262a37d 100644 --- a/About/Manifest.xml +++ b/About/Manifest.xml @@ -1,5 +1,5 @@ - 2.0.4 + 2.0.5 https://gitgud.io/AbstractConcept/rimworld-animations-patch \ No newline at end of file diff --git a/Defs/AnimationDefs/Animations_extension.xml b/Defs/AnimationDefs/Animations_extension.xml index 93f5a2f..2e94654 100644 --- a/Defs/AnimationDefs/Animations_extension.xml +++ b/Defs/AnimationDefs/Animations_extension.xml @@ -1270,7 +1270,7 @@
  • 7 - + Cum 0 0 0.475 diff --git a/Source/.vs/Rimworld-Animations-Patch/v16/.suo b/Source/.vs/Rimworld-Animations-Patch/v16/.suo index 61bcf5b..1458bba 100644 Binary files a/Source/.vs/Rimworld-Animations-Patch/v16/.suo and b/Source/.vs/Rimworld-Animations-Patch/v16/.suo differ diff --git a/Source/Scripts/Comps/CompPawnSexData.cs b/Source/Scripts/Comps/CompPawnSexData.cs index f62a9d2..5cf9346 100644 --- a/Source/Scripts/Comps/CompPawnSexData.cs +++ b/Source/Scripts/Comps/CompPawnSexData.cs @@ -7,6 +7,7 @@ using RimWorld; using Verse; using AlienRace; using UnityEngine; +using rjw; namespace Rimworld_Animations_Patch { @@ -25,11 +26,16 @@ namespace Rimworld_Animations_Patch private Pawn pawn { get { return parent as Pawn; } } private bool initialized; + // Refresh graphics on load public override void CompTick() { if (initialized == false) { pawn?.Drawer?.renderer?.graphics?.ResolveAllGraphics(); + + //if (pawn?.jobs?.curDriver is JobDriver_SexBaseInitiator && pawn.pather.Moving == false) + //{ (pawn.jobs.curDriver as JobDriver_SexBaseInitiator).Start(); } + initialized = true; } } @@ -72,7 +78,7 @@ namespace Rimworld_Animations_Patch public void UpdateBodyPartCountAndSize() { - hands = pawn?.health?.hediffSet?.GetNotMissingParts()?.Where(x => x.def.tags.Contains(BodyPartTagDefOf.ManipulationLimbCore))?.ToList(); + hands = pawn?.health?.hediffSet?.GetNotMissingParts()?.Where(x => x.def.tags.Contains(RimWorld.BodyPartTagDefOf.ManipulationLimbCore))?.ToList(); Hediff hediffPenis = pawn?.health?.hediffSet?.hediffs?.FirstOrDefault(x => x.def.defName.Contains("penis", StringComparison.OrdinalIgnoreCase) == true); sizeOfPenis = hediffPenis != null ? hediffPenis.Severity : 0f; diff --git a/Source/Scripts/Extensions/PawnExtension.cs b/Source/Scripts/Extensions/PawnExtension.cs index 61c660b..1c45ba7 100644 --- a/Source/Scripts/Extensions/PawnExtension.cs +++ b/Source/Scripts/Extensions/PawnExtension.cs @@ -105,9 +105,37 @@ namespace Rimworld_Animations_Patch { participants.AddDistinct(partner); } } - participants.AddDistinct(pawn); - participants.SortBy(x => x.GetAnimationData() != null ? x.GetAnimationData().actorID : participants.IndexOf(x)); - + participants.AddDistinct(pawn); + + // Sort participants according to actorID, if they have one + Dictionary _participants = new Dictionary(); + int c = 99; + + foreach (Pawn participant in participants) + { + ActorAnimationData data = pawn.GetAnimationData(); + + if (data != null) + { + int idx = data.actorID; + + if (_participants.ContainsKey(data.actorID)) + { DebugMode.Message("ERROR: Somehow you ended up with two actors with the same actorID"); idx = ++c; } + + _participants.Add(idx, participant); + } + + else + { _participants.Add(++c, participant); } + } + + participants = _participants.Values.ToList(); + + //ActorAnimationData data = pawn.GetAnimationData(); + //if (data != null) + + //participants.SortBy(x => x.GetAnimationData() != null ? x.GetAnimationData().actorID : participants.IndexOf(x)); + return participants; } diff --git a/Source/Scripts/Patches/HarmonyPatch_RJW.cs b/Source/Scripts/Patches/HarmonyPatch_RJW.cs index 8f3378e..2a74454 100644 --- a/Source/Scripts/Patches/HarmonyPatch_RJW.cs +++ b/Source/Scripts/Patches/HarmonyPatch_RJW.cs @@ -108,16 +108,13 @@ namespace Rimworld_Animations_Patch public static void Postfix(ref JobDriver_SexBaseInitiator __instance) { // Allow solo animations to be played - if (__instance is JobDriver_Masturbate && __instance.pawn.GetAnimationData() == null) - { PickMasturbationAnimation(__instance.pawn, __instance.Sexprops); } + if (__instance is JobDriver_Masturbate && __instance.pawn.GetAnimationData() == null) PickMasturbationAnimation(__instance.pawn, __instance.Sexprops); // Allow make out animations to be played - if (__instance.pawn.GetAnimationData() == null) - { PickMakeOutAnimation(__instance.pawn, __instance.Sexprops); } + if (__instance.pawn.GetAnimationData() == null) PickMakeOutAnimation(__instance.pawn, __instance.Sexprops); // If there is no animation to play, exit - if (__instance.pawn.GetAnimationData() == null) - { return; } + if (__instance.pawn.GetAnimationData() == null) return; // Get animation data List pawnsToAnimate = __instance.pawn.GetAllSexParticipants(); @@ -126,9 +123,7 @@ namespace Rimworld_Animations_Patch foreach (Pawn participant in pawnsToAnimate) { JobDriver_Sex jobdriver = participant.jobs.curDriver as JobDriver_Sex; - - if (jobdriver == null) - { continue; } + if (jobdriver == null) continue; // Animation timing reset jobdriver.orgasms = 0; @@ -136,7 +131,7 @@ namespace Rimworld_Animations_Patch jobdriver.ticksLeftThisToil = jobdriver.ticks_left; jobdriver.sex_ticks = orgasmTick; jobdriver.duration = jobdriver.sex_ticks; - jobdriver.orgasmstick = 0; + jobdriver.orgasmstick = 1; // Reset anchor and animation for sex toys CompThingAnimator sexToyCompThingAnimator = ((Thing)jobdriver.job.GetTarget(TargetIndex.A)).TryGetComp(); @@ -169,7 +164,7 @@ namespace Rimworld_Animations_Patch public static void PickMasturbationAnimation(Pawn pawn, SexProps sexProps = null) { if (pawn.TryGetComp() == null) - { Log.Error("Error: " + pawn.Name + " of race " + pawn.def.defName + " does not have CompBodyAnimator attached!"); return; } + { Log.Error("ERROR: " + pawn.Name + " of race " + pawn.def.defName + " does not have CompBodyAnimator attached!"); return; } pawn.TryGetComp().isAnimating = false; @@ -227,7 +222,7 @@ namespace Rimworld_Animations_Patch public static void PickMakeOutAnimation(Pawn pawn, SexProps sexProps = null) { if (pawn.TryGetComp() == null) - { Log.Error("Error: " + pawn.Name + " of race " + pawn.def.defName + " does not have CompBodyAnimator attached!"); return; } + { Log.Error("ERROR: " + pawn.Name + " of race " + pawn.def.defName + " does not have CompBodyAnimator attached!"); return; } List pawnsToAnimate = pawn.GetAllSexParticipants(); @@ -260,58 +255,41 @@ namespace Rimworld_Animations_Patch [HarmonyPatch(typeof(JobDriver_Sex), "Orgasm")] public static class HarmonyPatch_JobDriver_Sex_Orgasm { - // Stops orgasm triggering more than once per animation - public static bool Prefix(ref JobDriver_Sex __instance) + + public static void Prefix(ref JobDriver_Sex __instance, out bool __state) { - if (__instance.orgasms > 0) - { return false; } - - return true; - } - - // Causes too much trouble... - /*public static bool ParticipantsDesireMoreSex(JobDriver_Sex jobdriver) - { - List participants = jobdriver.pawn.GetAllSexParticipants(); - - float satisfaction = 0f; - - foreach (Pawn pawn in participants) - { - Need_Sex sexNeed = pawn?.needs?.TryGetNeed(); - - if (sexNeed == null) - { satisfaction += 1; continue; } - - satisfaction += sexNeed.CurLevelPercentage; - } - - return Rand.Chance(1 - satisfaction / participants.Count); + __state = __instance.sex_ticks > __instance.orgasmstick; } // Alows the starting of a new animation cycle at the end of the current one - public static void Postfix(ref JobDriver_Sex __instance) + public static void Postfix(ref JobDriver_Sex __instance, bool __state) { - if (__instance.orgasms > 0) - { __instance.sex_ticks = 0; } + if (__state || __instance.pawn.TryGetComp()?.isAnimating != true) return; - if (__instance is JobDriver_SexBaseInitiator == false || __instance is JobDriver_JoinInSex) - { return; } + DebugMode.Message(__instance.pawn.NameShortColored + " reached orgasm"); - if (__instance.Sexprops != null && (__instance.Sexprops.isRape || __instance.Sexprops.isWhoring)) - { return; } + int duration = AnimationPatchUtility.FindTrueAnimationLength(__instance.pawn, out int orgasmTick, true); + __instance.sex_ticks = duration; + __instance.duration = duration; - if (__instance.ticksLeftThisToil <= 1 && (__instance.neverendingsex || ParticipantsDesireMoreSex(__instance))) + if (__instance.neverendingsex) { - List participants = __instance.pawn.GetAllSexParticipants(); + __instance.ticks_left = duration + (duration - orgasmTick) + 1; + __instance.ticksLeftThisToil = __instance.ticks_left + 1; - if (participants.Count == 2) + List participants = __instance.pawn.GetAllSexParticipants(); + foreach (Pawn participant in participants) { - Job job = JobMaker.MakeJob(participants[0].CurJobDef, participants[0], participants[0].jobs.curJob.targetC); - participants[1].jobs.StartJob(job, JobCondition.Succeeded); + JobDriver_Sex jobDriver = participant.jobs.curDriver as JobDriver_Sex; + + if (participant != __instance.pawn && jobDriver != null) + { + jobDriver.ticks_left = duration + (duration - orgasmTick) + 1; + jobDriver.ticksLeftThisToil = jobDriver.ticks_left; + } } } - }*/ + } } [HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "End")] @@ -322,9 +300,11 @@ namespace Rimworld_Animations_Patch { if (__instance.Partner != null &&__instance.Partner.Dead == false && __instance.Partner?.jobs?.curDriver != null && __instance.Partner?.jobs?.curDriver is JobDriver_SexBaseReciever) { - foreach (Pawn participant in (__instance.Partner?.jobs.curDriver as JobDriver_SexBaseReciever).parteners) + List participants = (__instance.Partner?.jobs.curDriver as JobDriver_SexBaseReciever).parteners.ToList(); + + foreach (Pawn participant in participants) { - if (__instance.pawn != participant) + if (__instance.pawn != participant && __instance.Partner?.jobs?.curDriver is JobDriver_Sex) { participant.jobs.EndCurrentJob(JobCondition.Succeeded, false, true); } } } diff --git a/Source/Scripts/Patches/HarmonyPatch_Rimworld_Animations.cs b/Source/Scripts/Patches/HarmonyPatch_Rimworld_Animations.cs index c10ff11..ec3dfb4 100644 --- a/Source/Scripts/Patches/HarmonyPatch_Rimworld_Animations.cs +++ b/Source/Scripts/Patches/HarmonyPatch_Rimworld_Animations.cs @@ -20,8 +20,6 @@ namespace Rimworld_Animations_Patch postfix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_Rimworld_Animations), "PostFix_AnimationUtility_GenitalCheckForPawn"))); (new Harmony("Rimworld_Animations_Patch")).Patch(AccessTools.Method(AccessTools.TypeByName("Rimworld_Animations.CompBodyAnimator"), "setAnchor", new Type[] { typeof(Thing) }), prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_Rimworld_Animations), "Prefix_HarmonyPatch_CompBodyAnimator_setAnchor"))); - (new Harmony("Rimworld_Animations_Patch")).Patch(AccessTools.Method(AccessTools.TypeByName("Rimworld_Animations.HarmonyPatch_JobDriver_SexBaseInitiator_Start"), "RerollAnimations"), - postfix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_Rimworld_Animations), "Postfix_RerollAnimations"))); (new Harmony("Rimworld_Animations_Patch")).Patch(AccessTools.Method(AccessTools.TypeByName("Rimworld_Animations.HarmonyPatch_AlienRace"), "Prefix_AnimateHeadAddons"), prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_Rimworld_Animations), "Prefix_DrawAddons"))); (new Harmony("Rimworld_Animations_Patch")).Patch(AccessTools.Method(AccessTools.TypeByName("Rimworld_Animations.CompBodyAnimator"), "StartAnimation"), @@ -61,8 +59,7 @@ namespace Rimworld_Animations_Patch bool pawnInBed = pawn.IsInBed(out Building bed); - if (requiredGenitals.NullOrEmpty()) - { return; } + if (requiredGenitals.NullOrEmpty()) return; if (requiredGenitals.Contains("OneHand") && handCount < 1) { failReason = "missing hand"; __result = false; } @@ -85,25 +82,6 @@ namespace Rimworld_Animations_Patch return false; } - // Adds functionality to determine which apparel each actor should discard based on the animation they are running - public static void Postfix_RerollAnimations(Pawn pawn) - { - AnimationDef anim = pawn.GetAnimationData()?.animationDef; - - if (anim != null) - { - DebugMode.Message("Running animation: " + anim.defName); - - List pawnsToAnimate = pawn.GetAllSexParticipants(); - - foreach (Pawn participant in pawnsToAnimate) - { - int actorID = (int)AccessTools.Field(typeof(CompBodyAnimator), "actor").GetValue(participant.TryGetComp()); - DebugMode.Message("Participant " + actorID + ": " + participant.NameShortColored); - } - } - } - // Replacement patch for AlienRace to draw the body addons public static bool Prefix_DrawAddons(PawnRenderFlags renderFlags, Vector3 vector, Vector3 headOffset, Pawn pawn, Quaternion quat, Rot4 rotation) { @@ -250,5 +228,5 @@ namespace Rimworld_Animations_Patch Hair = rootLoc + YOffset_OnHead; (~ 0.029) Hat (over hair) = rootLoc + YOffset_PostHead; (~ 0.031) */ - } - } \ No newline at end of file + } +} diff --git a/Source/Scripts/Utilities/AnimationPatchUtility.cs b/Source/Scripts/Utilities/AnimationPatchUtility.cs index 14b2136..5b30654 100644 --- a/Source/Scripts/Utilities/AnimationPatchUtility.cs +++ b/Source/Scripts/Utilities/AnimationPatchUtility.cs @@ -12,7 +12,7 @@ namespace Rimworld_Animations_Patch { public static class AnimationPatchUtility { - public static int FindTrueAnimationLength(Pawn pawn, out int orgasmTick) + public static int FindTrueAnimationLength(Pawn pawn, out int orgasmTick, bool skipFirstStage = false) { orgasmTick = int.MaxValue; @@ -37,10 +37,10 @@ namespace Rimworld_Animations_Patch foreach (AnimationStage animStage in anim.animationStages) { // Legacy: skip the first stage of quickies if there's no playTimeTicksQuick values declared - if (anim.animationStages.IndexOf(animStage) == 0 && isQuickie && anim.animationStages.Any(x => x.playTimeTicksQuick >= 0) == false) - { continue; } + if (anim.animationStages.IndexOf(animStage) == 0 && isQuickie && anim.animationStages.Any(x => x.playTimeTicksQuick >= 0) == false) continue; + if (anim.animationStages.IndexOf(animStage) == 0 && skipFirstStage) continue; - int curr_tick = 0; + int curr_tick = 0; foreach (PawnKeyframe keyframe in (animStage.animationClips[actorId] as PawnAnimationClip).keyframes) { @@ -68,8 +68,9 @@ namespace Rimworld_Animations_Patch { orgasmTick = (int)(ticks * (2f + Rand.Value)); } } - return ticks; + DebugMode.Message(pawn.NameShortColored + " will orgasm at tick " + orgasmTick); + return ticks; } // Extended version of PawnHeadRotInAnimation (prevents pawn hair from getting messed up when draw in portraits) diff --git a/Source/Scripts/Utilities/ApparelAnimationUtility.cs b/Source/Scripts/Utilities/ApparelAnimationUtility.cs index f2dc2ea..e8fa0df 100644 --- a/Source/Scripts/Utilities/ApparelAnimationUtility.cs +++ b/Source/Scripts/Utilities/ApparelAnimationUtility.cs @@ -72,15 +72,12 @@ namespace Rimworld_Animations_Patch public static void DetermineApparelToKeepOn(Pawn pawn) { - if (pawn?.apparel?.WornApparel == null) - { return; } + if (pawn?.apparel?.WornApparel == null) return; foreach (Apparel apparel in pawn.apparel.WornApparel) { CompApparelVisibility comp = apparel.TryGetComp(); - - if (comp != null) - { comp.isBeingWorn = true; } + if (comp != null) comp.isBeingWorn = true; } ActorAnimationData animData = pawn.GetAnimationData(); @@ -98,14 +95,9 @@ namespace Rimworld_Animations_Patch { CompApparelVisibility comp = apparel.TryGetComp(); - if (comp == null) - { continue; } - - if (apparel.def is bondage_gear_def) - { continue; } - - if (ApparelSettings.GetRimNudeData(apparel) != null && ApparelSettings.GetRimNudeData(apparel).sexWear) - { continue; } + if (comp == null) continue; + if (apparel.def is bondage_gear_def) continue; + if (ApparelSettings.GetRimNudeData(apparel) != null && ApparelSettings.GetRimNudeData(apparel).sexWear) continue; if (clothingPreference == RJWPreferenceSettings.Clothing.Nude || undressForRitual || undressForParty) { diff --git a/Source/obj/Debug/Rimworld-Animations-Patch.csprojAssemblyReference.cache b/Source/obj/Debug/Rimworld-Animations-Patch.csprojAssemblyReference.cache index db463af..acf9a69 100644 Binary files a/Source/obj/Debug/Rimworld-Animations-Patch.csprojAssemblyReference.cache and b/Source/obj/Debug/Rimworld-Animations-Patch.csprojAssemblyReference.cache differ diff --git a/Source/obj/Debug/Rimworld-Animations-Patch.dll b/Source/obj/Debug/Rimworld-Animations-Patch.dll index 0dc3234..5640258 100644 Binary files a/Source/obj/Debug/Rimworld-Animations-Patch.dll and b/Source/obj/Debug/Rimworld-Animations-Patch.dll differ diff --git a/Source/obj/Debug/Rimworld-Animations-Patch.pdb b/Source/obj/Debug/Rimworld-Animations-Patch.pdb index 0b21887..19e108b 100644 Binary files a/Source/obj/Debug/Rimworld-Animations-Patch.pdb and b/Source/obj/Debug/Rimworld-Animations-Patch.pdb differ