diff --git a/.gitignore b/.gitignore index 4ce6fdd..1c79e0c 100644 --- a/.gitignore +++ b/.gitignore @@ -337,4 +337,14 @@ ASALocalRun/ .localhistory/ # BeatPulse healthcheck temp database -healthchecksdb \ No newline at end of file +healthchecksdb +/Source/Patches/PawnAnimationPatches/HarmonyPatch_Pawn_DrawTracker.cs +/Source/Patches/PawnAnimationPatches/HarmonyPatch_PawnRotation.cs +/Source/Patches/PawnAnimationPatches/HarmonyPatch_PawnRenderer.cs +/Source/Patches/OtherModPatches/HarmonyPatch_ShowHairWithHats.cs +/Source/Patches/OtherModPatches/HarmonyPatch_FacialAnimation.cs +/Source/Patches/OtherModPatches/HarmonyPatch_DontShaveYourHead.cs +/Source/Patches/OtherModPatches/HarmonyPatch_CSL.cs +/Source/Patches/OtherModPatches/HarmonyPatch_AlienRace.cs +/Source/Patches/ThingAnimationPatches/HarmonyPatch_ThingDrawAt.cs +/Defs/AnimationDefs/Animations_SexToys.xml diff --git a/1.1/Assemblies/0Harmony.dll b/1.1/Assemblies/0Harmony.dll deleted file mode 100644 index 947c81c..0000000 Binary files a/1.1/Assemblies/0Harmony.dll and /dev/null differ diff --git a/1.1/Assemblies/0Harmony.xml b/1.1/Assemblies/0Harmony.xml deleted file mode 100644 index 6bcea2e..0000000 --- a/1.1/Assemblies/0Harmony.xml +++ /dev/null @@ -1,2900 +0,0 @@ - - - - 0Harmony - - - - A factory to create delegate types - - - Default constructor - - - Creates a delegate type for a method - The method - The new delegate type - - - - A getter delegate type - Type that getter gets field/property value from - Type of the value that getter gets - The instance get getter uses - An delegate - - - - A setter delegate type - Type that setter sets field/property value for - Type of the value that setter sets - The instance the setter uses - The value the setter uses - An delegate - - - - A constructor delegate type - Type that constructor creates - An delegate - - - - A helper class for fast access to getters and setters - - - Creates an instantiation delegate - Type that constructor creates - The new instantiation delegate - - - - Creates an getter delegate for a property - Type that getter reads property from - Type of the property that gets accessed - The property - The new getter delegate - - - - Creates an getter delegate for a field - Type that getter reads field from - Type of the field that gets accessed - The field - The new getter delegate - - - - Creates an getter delegate for a field (with a list of possible field names) - Type that getter reads field/property from - Type of the field/property that gets accessed - A list of possible field names - The new getter delegate - - - - Creates an setter delegate - Type that setter assigns property value to - Type of the property that gets assigned - The property - The new setter delegate - - - - Creates an setter delegate for a field - Type that setter assigns field value to - Type of the field that gets assigned - The field - The new getter delegate - - - - A delegate to invoke a method - The instance - The method parameters - The method result - - - A helper class to invoke method with delegates - - - Creates a fast invocation handler from a method - The method to invoke - Controls if boxed value object is accessed/updated directly - The - - - The directBoxValueAccess option controls how value types passed by reference (e.g. ref int, out my_struct) are handled in the arguments array - passed to the fast invocation handler. - Since the arguments array is an object array, any value types contained within it are actually references to a boxed value object. - Like any other object, there can be other references to such boxed value objects, other than the reference within the arguments array. - For example, - - var val = 5; - var box = (object)val; - var arr = new object[] { box }; - handler(arr); // for a method with parameter signature: ref/out/in int - - - - - If directBoxValueAccess is true, the boxed value object is accessed (and potentially updated) directly when the handler is called, - such that all references to the boxed object reflect the potentially updated value. - In the above example, if the method associated with the handler updates the passed (boxed) value to 10, both box and arr[0] - now reflect the value 10. Note that the original val is not updated, since boxing always copies the value into the new boxed value object. - - - If directBoxValueAccess is false (default), the boxed value object in the arguments array is replaced with a "reboxed" value object, - such that potential updates to the value are reflected only in the arguments array. - In the above example, if the method associated with the handler updates the passed (boxed) value to 10, only arr[0] now reflects the value 10. - - - - - A low level memory helper - - - Mark method for no inlining (currently only works on Mono) - The method/constructor to change - - - Detours a method - The original method/constructor - The replacement method/constructor - An error string - - - - Writes a jump to memory - The memory address - Jump destination - An error string - - - - Gets the start of a method in memory - The method/constructor - [out] Details of the exception - The method start address - - - - special parameter names that can be used in prefix and postfix methods - - - Patch function helpers - - - Adds a prefix - The patch info - The owner (Harmony ID) - The annotation info - - - - Removes a prefix - The patch info - The owner (Harmony ID) - - - - Adds a postfix - The patch info - The owner (Harmony ID) - The annotation info - - - - Removes a postfix - The patch info - The owner (Harmony ID) - - - - Adds a transpiler - The patch info - The owner (Harmony ID) - The annotation info - - - - Removes a transpiler - The patch info - The owner (Harmony ID) - - - - Adds a finalizer - The patch info - The owner (Harmony ID) - The annotation info - - - - Removes a finalizer - The patch info - The owner (Harmony ID) - - - - Removes a patch method - The patch info - The patch method - - - - Sorts patch methods by their priority rules - The original method - Patches to sort - Use debug mode - The sorted patch methods - - - - Creates new replacement method with the latest patches and detours the original method - The original method - Information describing the patches - The newly created replacement method - - - - Creates a patch sorter - Array of patches that will be sorted - Use debugging - - - Sorts internal PatchSortingWrapper collection and caches the results. - After first run the result is provided from the cache. - The original method - The sorted patch methods - - - Checks if the sorter was created with the same patch list and as a result can be reused to - get the sorted order of the patches. - List of patches to check against - true if equal - - - Removes one unresolved dependency from the least important patch. - - - Outputs all unblocked patches from the waiting list to results list - - - Adds patch to both results list and handled patches set - Patch to add - - - Wrapper used over the Patch object to allow faster dependency access and - dependency removal in case of cyclic dependencies - - - Create patch wrapper object used for sorting - Patch to wrap - - - Determines how patches sort - The other patch - integer to define sort order (-1, 0, 1) - - - Determines whether patches are equal - The other patch - true if equal - - - Hash function - A hash code - - - Bidirectionally registers Patches as after dependencies - List of dependencies to register - - - Bidirectionally registers Patches as before dependencies - List of dependencies to register - - - Bidirectionally removes Patch from after dependencies - Patch to remove - - - Bidirectionally removes Patch from before dependencies - Patch to remove - - - Specifies the type of method - - - - This is a normal method - - - This is a getter - - - This is a setter - - - This is a constructor - - - This is a static constructor - - - Specifies the type of argument - - - - This is a normal argument - - - This is a reference argument (ref) - - - This is an out argument (out) - - - This is a pointer argument (&) - - - Specifies the type of patch - - - - Any patch - - - A prefix patch - - - A postfix patch - - - A transpiler - - - A finalizer - - - A reverse patch - - - Specifies the type of reverse patch - - - - Use the unmodified original method (directly from IL) - - - Use the original as it is right now including previous patches but excluding future ones - - - Specifies the type of method call dispatching mechanics - - - - Call the method using dynamic dispatching if method is virtual (including overriden) - - - This is the built-in form of late binding (a.k.a. dynamic binding) and is the default dispatching mechanic in C#. - This directly corresponds with the instruction. - - - For virtual (including overriden) methods, the instance type's most-derived/overriden implementation of the method is called. - For non-virtual (including static) methods, same behavior as : the exact specified method implementation is called. - - - Note: This is not a fully dynamic dispatch, since non-virtual (including static) methods are still called non-virtually. - A fully dynamic dispatch in C# involves using - the dynamic type - (actually a fully dynamic binding, since even the name and overload resolution happens at runtime), which does not support. - - - - - Call the method using static dispatching, regardless of whether method is virtual (including overriden) or non-virtual (including static) - - - a.k.a. non-virtual dispatching, early binding, or static binding. - This directly corresponds with the instruction. - - - For both virtual (including overriden) and non-virtual (including static) methods, the exact specified method implementation is called, without virtual/override mechanics. - - - - - The base class for all Harmony annotations (not meant to be used directly) - - - - The common information for all attributes - - - Annotation to define your Harmony patch methods - - - - An empty annotation can be used together with TargetMethod(s) - - - - An annotation that specifies a class to patch - The declaring class/type - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The argument types of the method or constructor to patch - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - An array of argument types to target overloads - Array of - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The - An array of argument types to target overloads - Array of - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - The - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - An array of argument types to target overloads - An array of - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - The - - - - An annotation that specifies a method, property or constructor to patch - The - - - - An annotation that specifies a method, property or constructor to patch - The - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The - An array of argument types to target overloads - An array of - - - - An annotation that specifies a method, property or constructor to patch - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - An array of argument types to target overloads - An array of - - - - Annotation to define the original method for delegate injection - - - - An annotation that specifies a class to patch - The declaring class/type - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The argument types of the method or constructor to patch - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - An array of argument types to target overloads - Array of - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The - An array of argument types to target overloads - Array of - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - The - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - An array of argument types to target overloads - An array of - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - The - - - - An annotation that specifies call dispatching mechanics for the delegate - The - - - - An annotation that specifies a method, property or constructor to patch - The - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The - An array of argument types to target overloads - An array of - - - - An annotation that specifies a method, property or constructor to patch - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - An array of argument types to target overloads - An array of - - - - Annotation to define your standin methods for reverse patching - - - - An annotation that specifies the type of reverse patching - The of the reverse patch - - - - A Harmony annotation to define that all methods in a class are to be patched - - - - A Harmony annotation - - - - A Harmony annotation to define patch priority - The priority - - - - A Harmony annotation - - - - A Harmony annotation to define that a patch comes before another patch - The array of harmony IDs of the other patches - - - - A Harmony annotation - - - A Harmony annotation to define that a patch comes after another patch - The array of harmony IDs of the other patches - - - - A Harmony annotation - - - A Harmony annotation to debug a patch (output uses to log to your Desktop) - - - - Specifies the Prepare function in a patch class - - - - Specifies the Cleanup function in a patch class - - - - Specifies the TargetMethod function in a patch class - - - - Specifies the TargetMethods function in a patch class - - - - Specifies the Prefix function in a patch class - - - - Specifies the Postfix function in a patch class - - - - Specifies the Transpiler function in a patch class - - - - Specifies the Finalizer function in a patch class - - - - A Harmony annotation - - - - The name of the original argument - - - - The index of the original argument - - - - The new name of the original argument - - - - An annotation to declare injected arguments by name - - - - An annotation to declare injected arguments by index - Zero-based index - - - - An annotation to declare injected arguments by renaming them - Name of the original argument - New name - - - - An annotation to declare injected arguments by index and renaming them - Zero-based index - New name - - - - An abstract wrapper around OpCode and their operands. Used by transpilers - - - - The opcode - - - - The operand - - - - All labels defined on this instruction - - - - All exception block boundaries defined on this instruction - - - - Creates a new CodeInstruction with a given opcode and optional operand - The opcode - The operand - - - - Create a full copy (including labels and exception blocks) of a CodeInstruction - The to copy - - - - Clones a CodeInstruction and resets its labels and exception blocks - A lightweight copy of this code instruction - - - - Clones a CodeInstruction, resets labels and exception blocks and sets its opcode - The opcode - A copy of this CodeInstruction with a new opcode - - - - Clones a CodeInstruction, resets labels and exception blocks and sets its operand - The operand - A copy of this CodeInstruction with a new operand - - - - Creates a CodeInstruction calling a method (CALL) - The class/type where the method is declared - The name of the method (case sensitive) - Optional parameters to target a specific overload of the method - Optional list of types that define the generic version of the method - A code instruction that calls the method matching the arguments - - - - Creates a CodeInstruction calling a method (CALL) - The target method in the form TypeFullName:MethodName, where the type name matches a form recognized by Type.GetType like Some.Namespace.Type. - Optional parameters to target a specific overload of the method - Optional list of types that define the generic version of the method - A code instruction that calls the method matching the arguments - - - - Creates a CodeInstruction calling a method (CALL) - The lambda expression using the method - - - - - Creates a CodeInstruction calling a method (CALL) - The lambda expression using the method - - - - - Creates a CodeInstruction calling a method (CALL) - The lambda expression using the method - - - - - Creates a CodeInstruction calling a method (CALL) - The lambda expression using the method - - - - - Creates a CodeInstruction loading a field (LD[S]FLD[A]) - The class/type where the field is defined - The name of the field (case sensitive) - Use address of field - - - - Creates a CodeInstruction storing to a field (ST[S]FLD) - The class/type where the field is defined - The name of the field (case sensitive) - - - - Returns a string representation of the code instruction - A string representation of the code instruction - - - - Exception block types - - - - The beginning of an exception block - - - - The beginning of a catch block - - - - The beginning of an except filter block - - - - The beginning of a fault block - - - - The beginning of a finally block - - - - The end of an exception block - - - - An exception block - - - - Block type - - - - Catch type - - - - Creates an exception block - The - The catch type - - - - The Harmony instance is the main entry to Harmony. After creating one with an unique identifier, it is used to patch and query the current application domain - - - - The unique identifier - - - - Set to true before instantiating Harmony to debug Harmony or use an environment variable to set HARMONY_DEBUG to '1' like this: cmd /C "set HARMONY_DEBUG=1 && game.exe" - This is for full debugging. To debug only specific patches, use the attribute - - - - Creates a new Harmony instance - A unique identifier (you choose your own) - A Harmony instance - - - - Searches the current assembly for Harmony annotations and uses them to create patches - - - - Creates a empty patch processor for an original method - The original method/constructor - A new instance - - - - Creates a patch class processor from an annotated class - The class/type - A new instance - - - - Creates a reverse patcher for one of your stub methods - The original method/constructor - The stand-in stub method as - A new instance - - - - Searches an assembly for Harmony annotations and uses them to create patches - The assembly - - - - Creates patches by manually specifying the methods - The original method/constructor - An optional prefix method wrapped in a object - An optional postfix method wrapped in a object - An optional transpiler method wrapped in a object - An optional finalizer method wrapped in a object - The replacement method that was created to patch the original method - - - - Patches a foreign method onto a stub method of yours and optionally applies transpilers during the process - The original method/constructor you want to duplicate - Your stub method as that will become the original. Needs to have the correct signature (either original or whatever your transpilers generates) - An optional transpiler as method that will be applied during the process - The replacement method that was created to patch the stub method - - - - Unpatches methods by patching them with zero patches. Fully unpatching is not supported. Be careful, unpatching is global - The optional Harmony ID to restrict unpatching to a specific Harmony instance - This method could be static if it wasn't for the fact that unpatching creates a new replacement method that contains your harmony ID - - - - Unpatches a method by patching it with zero patches. Fully unpatching is not supported. Be careful, unpatching is global - The original method/constructor - The - The optional Harmony ID to restrict unpatching to a specific Harmony instance - - - - Unpatches a method by patching it with zero patches. Fully unpatching is not supported. Be careful, unpatching is global - The original method/constructor - The patch method as method to remove - - - - Test for patches from a specific Harmony ID - The Harmony ID - True if patches for this ID exist - - - - Gets patch information for a given original method - The original method/constructor - The patch information as - - - - Gets the methods this instance has patched - An enumeration of original methods/constructors - - - - Gets all patched original methods in the appdomain - An enumeration of patched original methods/constructors - - - - Gets Harmony version for all active Harmony instances - [out] The current Harmony version - A dictionary containing assembly versions keyed by Harmony IDs - - - - Under Mono, HarmonyException wraps IL compile errors with detailed information about the failure - - - - Default serialization constructor (not implemented) - The info - The context - - - - Get a list of IL instructions in pairs of offset+code - A list of key/value pairs which represent an offset and the code at that offset - - - - Get a list of IL instructions without offsets - A list of - - - - Get the error offset of the errornous IL instruction - The offset - - - - Get the index of the errornous IL instruction - The index into the list of instructions or -1 if not found - - - - A wrapper around a method to use it as a patch (for example a Prefix) - - - - The original method - - - - Class/type declaring this patch - - - - Patch method name - - - - Optional patch - - - - Array of argument types of the patch method - - - - of the patch - - - - Install this patch before patches with these Harmony IDs - - - - Install this patch after patches with these Harmony IDs - - - - Reverse patch type, see - - - - Create debug output for this patch - - - - Whether to use (true) or (false) mechanics - for -attributed delegate - - - - Default constructor - - - - Creates a patch from a given method - The original method - - - - Creates a patch from a given method - The original method - The patch - A list of harmony IDs that should come after this patch - A list of harmony IDs that should come before this patch - Set to true to generate debug output - - - - Creates a patch from a given method - The patch class/type - The patch method name - The optional argument types of the patch method (for overloaded methods) - - - - Gets the names of all internal patch info fields - A list of field names - - - - Merges annotations - The list of to merge - The merged - - - - Returns a string that represents the annotation - A string representation - - - - Annotation extensions - - - - Copies annotation information - The source - The destination - - - - Clones an annotation - The to clone - A copied - - - - Merges annotations - The master - The detail - A new, merged - - - - Gets all annotations on a class/type - The class/type - A list of all - - - - Gets merged annotations on a class/type - The class/type - The merged - - - - Gets all annotations on a method - The method/constructor - A list of - - - - Gets merged annotations on a method - The method/constructor - The merged - - - - - A mutable representation of an inline signature, similar to Mono.Cecil's CallSite. - Used by the calli instruction, can be used by transpilers - - - - - See - - - - See - - - - See - - - - The list of all parameter types or function pointer signatures received by the call site - - - - The return type or function pointer signature returned by the call site - - - - Returns a string representation of the inline signature - A string representation of the inline signature - - - - - A mutable representation of a parameter type with an attached type modifier, - similar to Mono.Cecil's OptionalModifierType / RequiredModifierType and C#'s modopt / modreq - - - - - Whether this is a modopt (optional modifier type) or a modreq (required modifier type) - - - - The modifier type attached to the parameter type - - - - The modified parameter type - - - - Returns a string representation of the modifier type - A string representation of the modifier type - - - - Patch serialization - - - - Control the binding of a serialized object to a type - Specifies the assembly name of the serialized object - Specifies the type name of the serialized object - The type of the object the formatter creates a new instance of - - - - Serializes a patch info - The - The serialized data - - - - Deserialize a patch info - The serialized data - A - - - - Compare function to sort patch priorities - The patch - Zero-based index - The priority - A standard sort integer (-1, 0, 1) - - - - Serializable patch information - - - - Prefixes as an array of - - - - Postfixes as an array of - - - - Transpilers as an array of - - - - Finalizers as an array of - - - - Default constructor - - - - Returns if any of the patches wants debugging turned on - - - - Adds a prefix - - The prefix method - An owner (Harmony ID) - The priority, see - A list of Harmony IDs for prefixes that should run after this prefix - A list of Harmony IDs for prefixes that should run before this prefix - A flag that will log the replacement method via every time this prefix is used to build the replacement, even in the future - - - - Removes prefixes - The owner of the prefix or * for any prefix - - - - Adds a postfix - The postfix method - An owner (Harmony ID) - The priority, see - A list of Harmony IDs for postfixes that should run after this postfix - A list of Harmony IDs for postfixes that should run before this postfix - A flag that will log the replacement method via every time this postfix is used to build the replacement, even in the future - - - - Removes postfixes - The owner of the postfix or * for any postfix - - - - Adds a transpiler - The transpiler method - An owner (Harmony ID) - The priority, see - A list of Harmony IDs for transpilers that should run after this transpiler - A list of Harmony IDs for transpilers that should run before this transpiler - A flag that will log the replacement method via every time this patch is used to build the replacement, even in the future - - - - Removes transpilers - The owner of the transpiler or * for any transpiler - - - - Adds a finalizer - The finalizer method - An owner (Harmony ID) - The priority, see - A list of Harmony IDs for finalizers that should run after this finalizer - A list of Harmony IDs for finalizers that should run before this finalizer - A flag that will log the replacement method via every time this patch is used to build the replacement, even in the future - - - - Removes finalizers - The owner of the finalizer or * for any finalizer - - - - Removes a patch using its method - The method of the patch to remove - - - - A serializable patch - - - - Zero-based index - - - - The owner (Harmony ID) - - - - The priority, see - - - - Keep this patch before the patches indicated in the list of Harmony IDs - - - - Keep this patch after the patches indicated in the list of Harmony IDs - - - - A flag that will log the replacement method via every time this patch is used to build the replacement, even in the future - - - - The method of the static patch method - - - - Creates a patch - The method of the patch - Zero-based index - An owner (Harmony ID) - The priority, see - A list of Harmony IDs for patches that should run after this patch - A list of Harmony IDs for patches that should run before this patch - A flag that will log the replacement method via every time this patch is used to build the replacement, even in the future - - - - Get the patch method or a DynamicMethod if original patch method is a patch factory - The original method/constructor - The method of the patch - - - - Determines whether patches are equal - The other patch - true if equal - - - - Determines how patches sort - The other patch - integer to define sort order (-1, 0, 1) - - - - Hash function - A hash code - - - - A PatchClassProcessor used to turn on a class/type into patches - - - - Creates a patch class processor by pointing out a class. Similar to PatchAll() but without searching through all classes. - The Harmony instance - The class to process (need to have at least a [HarmonyPatch] attribute) - - - - Applies the patches - A list of all created replacement methods or null if patch class is not annotated - - - - A group of patches - - - - A collection of prefix - - - - A collection of postfix - - - - A collection of transpiler - - - - A collection of finalizer - - - - Gets all owners (Harmony IDs) or all known patches - The patch owners - - - - Creates a group of patches - An array of prefixes as - An array of postfixes as - An array of transpileres as - An array of finalizeres as - - - - A PatchProcessor handles patches on a method/constructor - - - - Creates an empty patch processor - The Harmony instance - The original method/constructor - - - - Adds a prefix - The prefix as a - A for chaining calls - - - - Adds a prefix - The prefix method - A for chaining calls - - - - Adds a postfix - The postfix as a - A for chaining calls - - - - Adds a postfix - The postfix method - A for chaining calls - - - - Adds a transpiler - The transpiler as a - A for chaining calls - - - - Adds a transpiler - The transpiler method - A for chaining calls - - - - Adds a finalizer - The finalizer as a - A for chaining calls - - - - Adds a finalizer - The finalizer method - A for chaining calls - - - - Gets all patched original methods in the appdomain - An enumeration of patched method/constructor - - - - Applies all registered patches - The generated replacement method - - - - Unpatches patches of a given type and/or Harmony ID - The patch type - Harmony ID or * for any - A for chaining calls - - - - Unpatches a specific patch - The method of the patch - A for chaining calls - - - - Gets patch information on an original - The original method/constructor - The patch information as - - - - Sort patch methods by their priority rules - The original method - Patches to sort - The sorted patch methods - - - - Gets Harmony version for all active Harmony instances - [out] The current Harmony version - A dictionary containing assembly version keyed by Harmony ID - - - - Creates a new empty generator to use when reading method bodies - A new - - - - Creates a new generator matching the method/constructor to use when reading method bodies - The original method/constructor to copy method information from - A new - - - - Returns the methods unmodified list of code instructions - The original method/constructor - Optionally an existing generator that will be used to create all local variables and labels contained in the result (if not specified, an internal generator is used) - A list containing all the original - - - - Returns the methods unmodified list of code instructions - The original method/constructor - A new generator that now contains all local variables and labels contained in the result - A list containing all the original - - - - Returns the methods current list of code instructions after all existing transpilers have been applied - The original method/constructor - Apply only the first count of transpilers - Optionally an existing generator that will be used to create all local variables and labels contained in the result (if not specified, an internal generator is used) - A list of - - - - Returns the methods current list of code instructions after all existing transpilers have been applied - The original method/constructor - A new generator that now contains all local variables and labels contained in the result - Apply only the first count of transpilers - A list of - - - - A low level way to read the body of a method. Used for quick searching in methods - The original method - All instructions as opcode/operand pairs - - - - A low level way to read the body of a method. Used for quick searching in methods - The original method - An existing generator that will be used to create all local variables and labels contained in the result - All instructions as opcode/operand pairs - - - - A patch priority - - - - Patch last - - - - Patch with very low priority - - - - Patch with low priority - - - - Patch with lower than normal priority - - - - Patch with normal priority - - - - Patch with higher than normal priority - - - - Patch with high priority - - - - Patch with very high priority - - - - Patch first - - - - A reverse patcher - - - - Creates a reverse patcher - The Harmony instance - The original method/constructor - Your stand-in stub method as - - - - Applies the patch - The type of patch, see - The generated replacement method - - - - A collection of commonly used transpilers - - - - A transpiler that replaces all occurrences of a given method with another one - The enumeration of to act on - Method or constructor to search for - Method or constructor to replace with - Modified enumeration of - - - - A transpiler that alters instructions that match a predicate by calling an action - The enumeration of to act on - A predicate selecting the instructions to change - An action to apply to matching instructions - Modified enumeration of - - - - A transpiler that logs a text at the beginning of the method - The instructions to act on - The log text - Modified enumeration of - - - - A helper class for reflection related functions - - - - Shortcut for to simplify the use of reflections and make it work for any access level - - - - Shortcut for to simplify the use of reflections and make it work for any access level but only within the current type - - - - Gets a type by name. Prefers a full name with namespace but falls back to the first type matching the name otherwise - The name - A type or null if not found - - - - Gets all successfully loaded types from a given assembly - The assembly - An array of types - - This calls and returns , while catching any thrown . - If such an exception is thrown, returns the successfully loaded types (, - filtered for non-null values). - - - - - Applies a function going up the type hierarchy and stops at the first non null result - Result type of func() - The class/type to start with - The evaluation function returning T - Returns the first non null result or default(T) when reaching the top level type object - - - - Applies a function going into inner types and stops at the first non null result - Generic type parameter - The class/type to start with - The evaluation function returning T - Returns the first non null result or null with no match - - - - Gets the reflection information for a directly declared field - The class/type where the field is defined - The name of the field - A field or null when type/name is null or when the field cannot be found - - - - Gets the reflection information for a field by searching the type and all its super types - The class/type where the field is defined - The name of the field (case sensitive) - A field or null when type/name is null or when the field cannot be found - - - - Gets the reflection information for a field - The class/type where the field is declared - The zero-based index of the field inside the class definition - A field or null when type is null or when the field cannot be found - - - - Gets the reflection information for a directly declared property - The class/type where the property is declared - The name of the property (case sensitive) - A property or null when type/name is null or when the property cannot be found - - - - Gets the reflection information for the getter method of a directly declared property - The class/type where the property is declared - The name of the property (case sensitive) - A method or null when type/name is null or when the property cannot be found - - - - Gets the reflection information for the setter method of a directly declared property - The class/type where the property is declared - The name of the property (case sensitive) - A method or null when type/name is null or when the property cannot be found - - - - Gets the reflection information for a property by searching the type and all its super types - The class/type - The name - A property or null when type/name is null or when the property cannot be found - - - - Gets the reflection information for the getter method of a property by searching the type and all its super types - The class/type - The name - A method or null when type/name is null or when the property cannot be found - - - - Gets the reflection information for the setter method of a property by searching the type and all its super types - The class/type - The name - A method or null when type/name is null or when the property cannot be found - - - - Gets the reflection information for a directly declared method - The class/type where the method is declared - The name of the method (case sensitive) - Optional parameters to target a specific overload of the method - Optional list of types that define the generic version of the method - A method or null when type/name is null or when the method cannot be found - - - - Gets the reflection information for a method by searching the type and all its super types - The class/type where the method is declared - The name of the method (case sensitive) - Optional parameters to target a specific overload of the method - Optional list of types that define the generic version of the method - A method or null when type/name is null or when the method cannot be found - - - - Gets the reflection information for a method by searching the type and all its super types - The target method in the form TypeFullName:MethodName, where the type name matches a form recognized by Type.GetType like Some.Namespace.Type. - Optional parameters to target a specific overload of the method - Optional list of types that define the generic version of the method - A method or null when type/name is null or when the method cannot be found - - - - Gets the names of all method that are declared in a type - The declaring class/type - A list of method names - - - - Gets the names of all method that are declared in the type of the instance - An instance of the type to search in - A list of method names - - - - Gets the names of all fields that are declared in a type - The declaring class/type - A list of field names - - - - Gets the names of all fields that are declared in the type of the instance - An instance of the type to search in - A list of field names - - - - Gets the names of all properties that are declared in a type - The declaring class/type - A list of property names - - - - Gets the names of all properties that are declared in the type of the instance - An instance of the type to search in - A list of property names - - - - Gets the type of any class member of - A member - The class/type of this member - - - - Test if a class member is actually an concrete implementation - A member - True if the member is a declared - - - - Gets the real implementation of a class member - A member - The member itself if its declared. Otherwise the member that is actually implemented in some base type - - - - Gets the reflection information for a directly declared constructor - The class/type where the constructor is declared - Optional parameters to target a specific overload of the constructor - Optional parameters to only consider static constructors - A constructor info or null when type is null or when the constructor cannot be found - - - - Gets the reflection information for a constructor by searching the type and all its super types - The class/type where the constructor is declared - Optional parameters to target a specific overload of the method - Optional parameters to only consider static constructors - A constructor info or null when type is null or when the method cannot be found - - - - Gets reflection information for all declared constructors - The class/type where the constructors are declared - Optional parameters to only consider static constructors - A list of constructor infos - - - - Gets reflection information for all declared methods - The class/type where the methods are declared - A list of methods - - - - Gets reflection information for all declared properties - The class/type where the properties are declared - A list of properties - - - - Gets reflection information for all declared fields - The class/type where the fields are declared - A list of fields - - - - Gets the return type of a method or constructor - The method/constructor - The return type - - - - Given a type, returns the first inner type matching a recursive search by name - The class/type to start searching at - The name of the inner type (case sensitive) - The inner type or null if type/name is null or if a type with that name cannot be found - - - - Given a type, returns the first inner type matching a recursive search with a predicate - The class/type to start searching at - The predicate to search with - The inner type or null if type/predicate is null or if a type with that name cannot be found - - - - Given a type, returns the first method matching a predicate - The class/type to start searching at - The predicate to search with - The method or null if type/predicate is null or if a type with that name cannot be found - - - - Given a type, returns the first constructor matching a predicate - The class/type to start searching at - The predicate to search with - The constructor info or null if type/predicate is null or if a type with that name cannot be found - - - - Given a type, returns the first property matching a predicate - The class/type to start searching at - The predicate to search with - The property or null if type/predicate is null or if a type with that name cannot be found - - - - Returns an array containing the type of each object in the given array - An array of objects - An array of types or an empty array if parameters is null (if an object is null, the type for it will be object) - - - - Creates an array of input parameters for a given method and a given set of potential inputs - The method/constructor you are planing to call - The possible input parameters in any order - An object array matching the method signature - - - - A read/writable reference to an instance field - The class the field is defined in or "object" if type cannot be accessed at compile time - The type of the field - The runtime instance to access the field (leave empty for static fields) - An readable/assignable object representing the field - - - - Creates an instance field reference - The class the field is defined in - The type of the field - The name of the field - A read and writable field reference delegate - - - - Creates an instance field reference for a specific instance - The class the field is defined in - The type of the field - The instance - The name of the field - An readable/assignable object representing the field - - - - Creates an instance field reference delegate for a private type - The type of the field - The class/type - The name of the field - A read and writable delegate - - - - Creates an instance field reference delegate for a fieldinfo - The class the field is defined in or "object" if type cannot be accessed at compile time - The type of the field - The field of the field - A read and writable delegate - - - - Creates a static field reference - The class the field is defined in or "object" if type cannot be accessed at compile time - The type of the field - The name of the field - An readable/assignable object representing the static field - - - - Creates a static field reference - The type of the field - The class/type - The name of the field - An readable/assignable object representing the static field - - - - Creates a static field reference - The class the field is defined in or "object" if type cannot be accessed at compile time - The type of the field - The field - An readable/assignable object representing the static field - - - - A read/writable reference delegate to a static field - The type of the field - An readable/assignable object representing the static field - - - - Creates a static field reference delegate - The type of the field - The field - A read and writable delegate - - - - Creates a delegate to a given method - The delegate Type - The method to create a delegate from. - - Only applies for instance methods. If null (default), returned delegate is an open (a.k.a. unbound) instance delegate - where an instance is supplied as the first argument to the delegate invocation; else, delegate is a closed (a.k.a. bound) - instance delegate where the delegate invocation always applies to the given . - - - Only applies for instance methods. If true (default) and is virtual, invocation of the delegate - calls the instance method virtually (the instance type's most-derived/overriden implementation of the method is called); - else, invocation of the delegate calls the exact specified (this is useful for calling base class methods) - Note: if false and is an interface method, an ArgumentException is thrown. - - A delegate of given to given - - - Delegate invocation is more performant and more convenient to use than - at a one-time setup cost. - - - Works for both type of static and instance methods, both open and closed (a.k.a. unbound and bound) instance methods, - and both class and struct methods. - - - - - - Creates a delegate for a given delegate definition, attributed with [] - The delegate Type, attributed with [] - - Only applies for instance methods. If null (default), returned delegate is an open (a.k.a. unbound) instance delegate - where an instance is supplied as the first argument to the delegate invocation; else, delegate is a closed (a.k.a. bound) - instance delegate where the delegate invocation always applies to the given . - - A delegate of given to the method specified via [] - attributes on - - This calls with the method and virtualCall arguments - determined from the [] attributes on , - and the given (for closed instance delegates). - - - - - Returns who called the current method - The calling method/constructor (excluding the caller) - - - - Rethrows an exception while preserving its stack trace (throw statement typically clobbers existing stack traces) - The exception to rethrow - - - - True if the current runtime is based on Mono, false otherwise (.NET) - - - - True if the current runtime is .NET Framework, false otherwise (.NET Core or Mono, although latter isn't guaranteed) - - - - True if the current runtime is .NET Core, false otherwise (Mono or .NET Framework) - - - - Throws a missing member runtime exception - The type that is involved - A list of names - - - - Gets default value for a specific type - The class/type - The default value - - - - Creates an (possibly uninitialized) instance of a given type - The class/type - The new instance - - - - Makes a deep copy of any object - The type of the instance that should be created - The original object - A copy of the original object but of type T - - - - Makes a deep copy of any object - The type of the instance that should be created - The original object - [out] The copy of the original object - Optional value transformation function (taking a field name and src/dst instances) - The optional path root to start with - - - - Makes a deep copy of any object - The original object - The type of the instance that should be created - Optional value transformation function (taking a field name and src/dst instances) - The optional path root to start with - The copy of the original object - - - - Tests if a type is a struct - The type - True if the type is a struct - - - - Tests if a type is a class - The type - True if the type is a class - - - - Tests if a type is a value type - The type - True if the type is a value type - - - - Tests if a type is an integer type - The type - True if the type represents some integer - - - - Tests if a type is a floating point type - The type - True if the type represents some floating point - - - - Tests if a type is a numerical type - The type - True if the type represents some number - - - - Tests if a type is void - The type - True if the type is void - - - - Test whether an instance is of a nullable type - Type of instance - An instance to test - True if instance is of nullable type, false if not - - - - Tests whether a type or member is static, as defined in C# - The type or member - True if the type or member is static - - - - Tests whether a type is static, as defined in C# - The type - True if the type is static - - - - Tests whether a property is static, as defined in C# - The property - True if the property is static - - - - Tests whether an event is static, as defined in C# - The event - True if the event is static - - - - Calculates a combined hash code for an enumeration of objects - The objects - The hash code - - - - General extensions for common cases - - - - Joins an enumeration with a value converter and a delimiter to a string - The inner type of the enumeration - The enumeration - An optional value converter (from T to string) - An optional delimiter - The values joined into a string - - - - Converts an array of types (for example methods arguments) into a human readable form - The array of types - A human readable description including brackets - - - - A full description of a type - The type - A human readable description - - - - A a full description of a method or a constructor without assembly details but with generics - The method/constructor - A human readable description - - - - A helper converting parameter infos to types - The array of parameter infos - An array of types - - - - A helper to access a value via key from a dictionary - The key type - The value type - The dictionary - The key - The value for the key or the default value (of T) if that key does not exist - - - - A helper to access a value via key from a dictionary with extra casting - The value type - The dictionary - The key - The value for the key or the default value (of T) if that key does not exist or cannot be cast to T - - - - Escapes Unicode and ASCII non printable characters - The string to convert - The string to convert - A string literal surrounded by - - - - Extensions for - - - - Shortcut for testing whether the operand is equal to a non-null value - The - The value - True if the operand has the same type and is equal to the value - - - - Shortcut for testing whether the operand is equal to a non-null value - The - The value - True if the operand is equal to the value - This is an optimized version of for - - - - Shortcut for code.opcode == opcode && code.OperandIs(operand) - The - The - The operand value - True if the opcode is equal to the given opcode and the operand has the same type and is equal to the given operand - - - - Shortcut for code.opcode == opcode && code.OperandIs(operand) - The - The - The operand value - True if the opcode is equal to the given opcode and the operand is equal to the given operand - This is an optimized version of for - - - - Tests for any form of Ldarg* - The - The (optional) index - True if it matches one of the variations - - - - Tests for Ldarga/Ldarga_S - The - The (optional) index - True if it matches one of the variations - - - - Tests for Starg/Starg_S - The - The (optional) index - True if it matches one of the variations - - - - Tests for any form of Ldloc* - The - The optional local variable - True if it matches one of the variations - - - - Tests for any form of Stloc* - The - The optional local variable - True if it matches one of the variations - - - - Tests if the code instruction branches - The - The label if the instruction is a branch operation or if not - True if the instruction branches - - - - Tests if the code instruction calls the method/constructor - The - The method - True if the instruction calls the method or constructor - - - - Tests if the code instruction loads a constant - The - True if the instruction loads a constant - - - - Tests if the code instruction loads an integer constant - The - The integer constant - True if the instruction loads the constant - - - - Tests if the code instruction loads a floating point constant - The - The floating point constant - True if the instruction loads the constant - - - - Tests if the code instruction loads an enum constant - The - The enum - True if the instruction loads the constant - - - - Tests if the code instruction loads a field - The - The field - Set to true if the address of the field is loaded - True if the instruction loads the field - - - - Tests if the code instruction stores a field - The - The field - True if the instruction stores this field - - - - Adds labels to the code instruction and return it - The - One or several to add - The same code instruction - - - Adds labels to the code instruction and return it - The - An enumeration of - The same code instruction - - - Extracts all labels from the code instruction and returns them - The - A list of - - - Moves all labels from the code instruction to a different one - The to move the labels from - The to move the labels to - The code instruction labels were moved from (now empty) - - - Moves all labels from a different code instruction to the current one - The to move the labels from - The to move the labels to - The code instruction that received the labels - - - Adds ExceptionBlocks to the code instruction and return it - The - One or several to add - The same code instruction - - - Adds ExceptionBlocks to the code instruction and return it - The - An enumeration of - The same code instruction - - - Extracts all ExceptionBlocks from the code instruction and returns them - The - A list of - - - Moves all ExceptionBlocks from the code instruction to a different one - The to move the ExceptionBlocks from - The to move the ExceptionBlocks to - The code instruction blocks were moved from (now empty) - - - Moves all ExceptionBlocks from a different code instruction to the current one - The to move the ExceptionBlocks from - The to move the ExceptionBlocks to - The code instruction that received the blocks - - - General extensions for collections - - - - A simple way to execute code for every element in a collection - The inner type of the collection - The collection - The action to execute - - - - A simple way to execute code for elements in a collection matching a condition - The inner type of the collection - The collection - The predicate - The action to execute - - - - A helper to add an item to a collection - The inner type of the collection - The collection - The item to add - The collection containing the item - - - - A helper to add an item to an array - The inner type of the collection - The array - The item to add - The array containing the item - - - - A helper to add items to an array - The inner type of the collection - The array - The items to add - The array containing the items - - - - General extensions for collections - - - - Tests a class member if it has an IL method body (external methods for example don't have a body) - The member to test - Returns true if the member has an IL body or false if not - - - A file log for debugging - - - - Full pathname of the log file, defaults to a file called harmony.log.txt on your Desktop - - - - The indent character. The default is tab - - - - The current indent level - - - - Changes the indentation level - The value to add to the indentation level - - - - Log a string in a buffered way. Use this method only if you are sure that FlushBuffer will be called - or else logging information is incomplete in case of a crash - The string to log - - - - Logs a list of string in a buffered way. Use this method only if you are sure that FlushBuffer will be called - or else logging information is incomplete in case of a crash - A list of strings to log (they will not be re-indented) - - - - Returns the log buffer and optionally empties it - True to empty the buffer - The buffer. - - - - Replaces the buffer with new lines - The lines to store - - - - Flushes the log buffer to disk (use in combination with LogBuffered) - - - - Log a string directly to disk. Slower method that prevents missing information in case of a crash - The string to log. - - - - Resets and deletes the log - - - - Logs some bytes as hex values - The pointer to some memory - The length of bytes to log - - - - A helper class to retrieve reflection info for non-private methods - - - - Given a lambda expression that calls a method, returns the method info - The lambda expression using the method - The method in the lambda expression - - - - Given a lambda expression that calls a method, returns the method info - The generic type - The lambda expression using the method - The method in the lambda expression - - - - Given a lambda expression that calls a method, returns the method info - The generic type - The generic result type - The lambda expression using the method - The method in the lambda expression - - - - Given a lambda expression that calls a method, returns the method info - The lambda expression using the method - The method in the lambda expression - - - - A reflection helper to read and write private elements - The result type defined by GetValue() - - - - Creates a traverse instance from an existing instance - The existing instance - - - - Gets/Sets the current value - The value to read or write - - - - A reflection helper to read and write private elements - - - - Creates a new traverse instance from a class/type - The class/type - A instance - - - - Creates a new traverse instance from a class T - The class - A instance - - - - Creates a new traverse instance from an instance - The object - A instance - - - - Creates a new traverse instance from a named type - The type name, for format see - A instance - - - - Creates a new and empty traverse instance - - - - Creates a new traverse instance from a class/type - The class/type - - - - Creates a new traverse instance from an instance - The object - - - - Gets the current value - The value - - - - Gets the current value - The type of the value - The value - - - - Invokes the current method with arguments and returns the result - The method arguments - The value returned by the method - - - - Invokes the current method with arguments and returns the result - The type of the value - The method arguments - The value returned by the method - - - - Sets a value of the current field or property - The value - The same traverse instance - - - - Gets the type of the current field or property - The type - - - - Moves the current traverse instance to a inner type - The type name - A traverse instance - - - - Moves the current traverse instance to a field - The type name - A traverse instance - - - - Moves the current traverse instance to a field - The type of the field - The type name - A traverse instance - - - - Gets all fields of the current type - A list of field names - - - - Moves the current traverse instance to a property - The type name - Optional property index - A traverse instance - - - - Moves the current traverse instance to a field - The type of the property - The type name - Optional property index - A traverse instance - - - - Gets all properties of the current type - A list of property names - - - - Moves the current traverse instance to a method - The name of the method - The arguments defining the argument types of the method overload - A traverse instance - - - - Moves the current traverse instance to a method - The name of the method - The argument types of the method - The arguments for the method - A traverse instance - - - - Gets all methods of the current type - A list of method names - - - - Checks if the current traverse instance is for a field - True if its a field - - - - Checks if the current traverse instance is for a property - True if its a property - - - - Checks if the current traverse instance is for a method - True if its a method - - - - Checks if the current traverse instance is for a type - True if its a type - - - - Iterates over all fields of the current type and executes a traverse action - Original object - The action receiving a instance for each field - - - - Iterates over all fields of the current type and executes a traverse action - Original object - Target object - The action receiving a pair of instances for each field pair - - - - Iterates over all fields of the current type and executes a traverse action - Original object - Target object - The action receiving a dot path representing the field pair and the instances - - - - Iterates over all properties of the current type and executes a traverse action - Original object - The action receiving a instance for each property - - - - Iterates over all properties of the current type and executes a traverse action - Original object - Target object - The action receiving a pair of instances for each property pair - - - - Iterates over all properties of the current type and executes a traverse action - Original object - Target object - The action receiving a dot path representing the property pair and the instances - - - - A default field action that copies fields to fields - - - - Returns a string that represents the current traverse - A string representation - - - - diff --git a/1.1/Assemblies/Rimworld-Animations.dll b/1.1/Assemblies/Rimworld-Animations.dll index 7a5e864..b2bba40 100644 Binary files a/1.1/Assemblies/Rimworld-Animations.dll and b/1.1/Assemblies/Rimworld-Animations.dll differ diff --git a/1.2/Assemblies/Rimworld-Animations.dll b/1.2/Assemblies/Rimworld-Animations.dll new file mode 100644 index 0000000..13afe5e Binary files /dev/null and b/1.2/Assemblies/Rimworld-Animations.dll differ diff --git a/Defs/AnimationDefs/AnimationDefs.rar b/1.2/Defs/AnimationDefs/AnimationDefs.rar similarity index 100% rename from Defs/AnimationDefs/AnimationDefs.rar rename to 1.2/Defs/AnimationDefs/AnimationDefs.rar diff --git a/Defs/AnimationDefs/Animations_Beast.xml b/1.2/Defs/AnimationDefs/Animations_Beast.xml similarity index 99% rename from Defs/AnimationDefs/Animations_Beast.xml rename to 1.2/Defs/AnimationDefs/Animations_Beast.xml index 8cda024..30d14fc 100644 --- a/Defs/AnimationDefs/Animations_Beast.xml +++ b/1.2/Defs/AnimationDefs/Animations_Beast.xml @@ -8,6 +8,12 @@
  • Anal
  • Vaginal
  • + + +
  • VaginalBreeding
  • +
  • AnalBreeding
  • +
    +
  • @@ -1154,6 +1160,12 @@
  • Anal
  • Vaginal
  • + + +
  • RequestVaginalBreeding
  • +
  • RequestAnalBreeding
  • +
    +
  • diff --git a/Defs/AnimationDefs/Animations_Lesbian.xml b/1.2/Defs/AnimationDefs/Animations_Lesbian.xml similarity index 99% rename from Defs/AnimationDefs/Animations_Lesbian.xml rename to 1.2/Defs/AnimationDefs/Animations_Lesbian.xml index e8da71b..56d805a 100644 --- a/Defs/AnimationDefs/Animations_Lesbian.xml +++ b/1.2/Defs/AnimationDefs/Animations_Lesbian.xml @@ -678,7 +678,26 @@
  • Oral
  • Fingering
  • +
  • Cunnilingus
  • + + +
  • Cunnilingus
  • +
  • CunnilingusF
  • +
  • CunnilingusRape
  • +
  • CunnilingusRapeF
  • + +
  • Fingering
  • +
  • FingeringF
  • +
  • FingeringRape
  • +
  • FingeringRapeF
  • + +
  • Fisting
  • +
  • FistingF
  • +
  • FistingRape
  • +
  • FistingRapeF
  • + +
  • diff --git a/Defs/AnimationDefs/Animations_Masturbate.xml b/1.2/Defs/AnimationDefs/Animations_Masturbate.xml similarity index 100% rename from Defs/AnimationDefs/Animations_Masturbate.xml rename to 1.2/Defs/AnimationDefs/Animations_Masturbate.xml diff --git a/Defs/AnimationDefs/Animations_Multi.xml b/1.2/Defs/AnimationDefs/Animations_Multi.xml similarity index 97% rename from Defs/AnimationDefs/Animations_Multi.xml rename to 1.2/Defs/AnimationDefs/Animations_Multi.xml index a5c2ba5..ce4e595 100644 --- a/Defs/AnimationDefs/Animations_Multi.xml +++ b/1.2/Defs/AnimationDefs/Animations_Multi.xml @@ -18,6 +18,7 @@
  • Human
  • + true true true @@ -25,6 +26,7 @@
  • Human
  • + true true true @@ -78,6 +80,7 @@ LayingPawn
  • + -10 30 12 -14.1 @@ -98,6 +101,7 @@ 0
  • + -10 1 12 -14.1 @@ -114,6 +118,7 @@ LayingPawn
  • + 43 27 8.7 15.1 @@ -135,6 +140,7 @@ 0
  • + 43 1 8.7 15.1 @@ -205,6 +211,7 @@ LayingPawn
  • + -10 13 12 -14.1 @@ -225,6 +232,7 @@ 0
  • + -10 1 12 -14.1 @@ -241,6 +249,7 @@ LayingPawn
  • + 43 13 8.7 15.1 @@ -262,6 +271,7 @@ 0
  • + 43 1 8.7 15.1 @@ -417,6 +427,7 @@ LayingPawn
  • + -10 9 9 -14.1 @@ -518,6 +529,7 @@ 3 3 0 + -10
  • @@ -527,6 +539,7 @@ LayingPawn
  • + 43 9 8.7 15.1 @@ -622,6 +635,7 @@ 0
  • + 43 1 8.7 15.1 diff --git a/Defs/AnimationDefs/Animations_Vanilla2.xml b/1.2/Defs/AnimationDefs/Animations_Vanilla2.xml similarity index 100% rename from Defs/AnimationDefs/Animations_Vanilla2.xml rename to 1.2/Defs/AnimationDefs/Animations_Vanilla2.xml diff --git a/Defs/AnimationDefs/Animations_vanilla.xml b/1.2/Defs/AnimationDefs/Animations_vanilla.xml similarity index 93% rename from Defs/AnimationDefs/Animations_vanilla.xml rename to 1.2/Defs/AnimationDefs/Animations_vanilla.xml index f8e5e1c..079753a 100644 --- a/Defs/AnimationDefs/Animations_vanilla.xml +++ b/1.2/Defs/AnimationDefs/Animations_vanilla.xml @@ -9,6 +9,16 @@
  • Vaginal
  • Anal
  • + + +
  • AnalSex
  • +
  • AnalSexF
  • +
  • AnalRape
  • +
  • VaginalSex
  • +
  • VaginalSexF
  • +
  • VaginalRape
  • +
    +
  • @@ -21,6 +31,7 @@
  • Human
  • + true true true @@ -247,6 +258,7 @@ LayingPawn
  • + 27 0 10 16.6 @@ -276,6 +288,7 @@ 1 1 0 + 27
  • @@ -324,6 +337,7 @@ LayingPawn
  • + 27 8 11 -0.217 @@ -353,6 +367,7 @@ 1 1 0 + 27
  • @@ -412,6 +427,7 @@ LayingPawn
  • + 27 8 11 -0.217 @@ -448,6 +464,7 @@ 1 1 0 + 27
  • @@ -461,7 +478,31 @@ true
  • Oral
  • +
  • Fellatio
  • + +
  • Handjob
  • +
  • HandjobF
  • +
  • HandjobRape
  • +
  • HandjobRapeF
  • + +
  • Breastjob
  • +
  • BreastjobF
  • +
  • BreastjobRape
  • +
  • BreastjobRapeF
  • + +
  • Fellatio
  • +
  • FellatioF
  • +
  • FellatioRape
  • +
  • FellatioRapeF
  • + +
  • Beakjob
  • +
  • BeakjobF
  • +
  • BeakjobRape
  • +
  • BeakjobRapeF
  • + + +
  • @@ -881,6 +922,14 @@
  • Anal
  • Vaginal
  • + +
  • AnalSex
  • +
  • AnalSexF
  • +
  • AnalRape
  • +
  • VaginalSex
  • +
  • VaginalSexF
  • +
  • VaginalRape
  • +
  • @@ -898,6 +947,7 @@ true true + true (0, 0.2) @@ -949,6 +999,7 @@ LayingPawn
  • + 6 30 -3.18 -0.41 @@ -959,6 +1010,7 @@ 0
  • + 40 Fuck 29 17.11 @@ -978,6 +1030,7 @@ 3 3 0 + 6
  • @@ -1615,6 +1668,7 @@ LayingPawn
  • + 6 13 -3.18 -0.41 @@ -1625,6 +1679,7 @@ 0
  • + 40 Fuck 12 17.11 @@ -1644,6 +1699,7 @@ 3 3 0 + 6
  • @@ -1838,6 +1894,7 @@ LayingPawn
  • + 6 7 -3.18 -0.41 @@ -1848,6 +1905,7 @@ 0
  • + 40 Fuck 7 17.11 @@ -1859,6 +1917,7 @@ 0
  • + 6 1 -3.18 -0.41 @@ -1870,6 +1929,7 @@
  • + 6 7 -3.18 -0.41 @@ -1880,6 +1940,7 @@ 0
  • + 40 Fuck 7 17.11 @@ -1891,6 +1952,7 @@ 0
  • + 6 1 -3.18 -0.41 @@ -1902,6 +1964,7 @@
  • + 6 7 -3.18 -0.41 @@ -1912,6 +1975,7 @@ 0
  • + 40 Fuck 7 17.11 @@ -1923,6 +1987,7 @@ 0
  • + 6 1 -3.18 -0.41 @@ -1934,16 +1999,18 @@
  • - 7 - -3.18 - -0.41 - 0.122 - 0.356 - 3 - 3 - 0 -
  • -
  • + 6 + 7 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 Cum 75 17.11 @@ -1955,6 +2022,7 @@ 0
  • + 40 27 17.11 -2.87 @@ -1965,6 +2033,7 @@ 0
  • + 6 1 -3.18 -0.41 @@ -1989,6 +2058,15 @@
  • Anal
  • Vaginal
  • + + +
  • AnalSex
  • +
  • AnalSexF
  • +
  • AnalRapeF
  • +
  • VaginalSex
  • +
  • VaginalSexF
  • +
  • VaginalRapeF
  • +
    @@ -2201,7 +2279,7 @@ LayingPawn
  • - 33 + 16 180 180 0 @@ -2211,17 +2289,39 @@ 0 0
  • +
  • + 17 + 180 + 180 + 0 + -0.347 + 2 + 2 + 0.015 + -15 +
  • - 33 + 16 180 180 0 - -0.313 + -0.331 2 2 - 0.045 + 0.03 0
  • +
  • + 17 + 180 + 180 + 0 + -0.315 + 2 + 2 + 0.045 + 15 +
  • 1 180 @@ -2233,6 +2333,127 @@ 0 0
  • +
  • + 16 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 17 + 180 + 180 + 0 + -0.347 + 2 + 2 + 0.015 + -15 +
  • +
  • + 16 + 180 + 180 + 0 + -0.331 + 2 + 2 + 0.03 + 0 +
  • +
  • + 17 + 180 + 180 + 0 + -0.315 + 2 + 2 + 0.045 + 15 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 33 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 33 + 180 + 180 + 0 + -0.315 + 2 + 2 + 0.045 + 0 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 33 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 33 + 180 + 180 + 0 + -0.315 + 2 + 2 + 0.045 + 0 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • diff --git a/Defs/AnimationDefs/TemplateAnimation.xml b/1.2/Defs/AnimationDefs/TemplateAnimation.xml similarity index 100% rename from Defs/AnimationDefs/TemplateAnimation.xml rename to 1.2/Defs/AnimationDefs/TemplateAnimation.xml diff --git a/Defs/JobDefs/Jobs_SexForAnim.xml b/1.2/Defs/JobDefs/Jobs_SexForAnim.xml similarity index 100% rename from Defs/JobDefs/Jobs_SexForAnim.xml rename to 1.2/Defs/JobDefs/Jobs_SexForAnim.xml diff --git a/Defs/MainTabDefs/MainButtonDef.xml b/1.2/Defs/MainTabDefs/MainButtonDef.xml similarity index 100% rename from Defs/MainTabDefs/MainButtonDef.xml rename to 1.2/Defs/MainTabDefs/MainButtonDef.xml diff --git a/Defs/SoundDefs/Sounds_Sex.xml b/1.2/Defs/SoundDefs/Sounds_Sex.xml similarity index 97% rename from Defs/SoundDefs/Sounds_Sex.xml rename to 1.2/Defs/SoundDefs/Sounds_Sex.xml index 7d3500c..4cce5d0 100644 --- a/Defs/SoundDefs/Sounds_Sex.xml +++ b/1.2/Defs/SoundDefs/Sounds_Sex.xml @@ -6,6 +6,7 @@ MapOnly 1 + 1
  • @@ -34,6 +35,7 @@ MapOnly 1 + 1
  • @@ -62,6 +64,7 @@ MapOnly 1 + 1
  • @@ -118,6 +121,7 @@ MapOnly 1 + 1
  • @@ -168,6 +172,7 @@ MapOnly 1 + 1
  • diff --git a/1.2/Patch_HatsDisplaySelection/Patch_HatsDisplaySelection.csproj b/1.2/Patch_HatsDisplaySelection/Patch_HatsDisplaySelection.csproj new file mode 100644 index 0000000..8da21a6 --- /dev/null +++ b/1.2/Patch_HatsDisplaySelection/Patch_HatsDisplaySelection.csproj @@ -0,0 +1,75 @@ + + + + + Debug + AnyCPU + {BA766964-1716-422D-A09E-29426F8EB9D5} + Library + Properties + Patch_HatsDisplaySelection + Patch_HatsDisplaySelection + v4.7.2 + 512 + true + + + false + none + false + 1.2\Assemblies\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\..\workshop\content\294100\2009463077\Current\Assemblies\0Harmony.dll + False + + + ..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll + False + + + ..\..\..\..\..\workshop\content\294100\1542291825\1.2\Assemblies\HatDisplaySelection.dll + False + + + ..\1.2\Assemblies\Rimworld-Animations.dll + False + + + + + + + + + + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll + False + + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll + False + + + + + + + + + + + \ No newline at end of file diff --git a/1.2/Patch_HatsDisplaySelection/Properties/AssemblyInfo.cs b/1.2/Patch_HatsDisplaySelection/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6905d78 --- /dev/null +++ b/1.2/Patch_HatsDisplaySelection/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Patch_HatsDisplaySelection")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Patch_HatsDisplaySelection")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("ba766964-1716-422d-a09e-29426f8eb9d5")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/1.2/Patch_HatsDisplaySelection/Source/Patches/Patch_HatsDisplaySelection.cs b/1.2/Patch_HatsDisplaySelection/Source/Patches/Patch_HatsDisplaySelection.cs new file mode 100644 index 0000000..6f00a5a --- /dev/null +++ b/1.2/Patch_HatsDisplaySelection/Source/Patches/Patch_HatsDisplaySelection.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using HatDisplaySelection; +using Rimworld_Animations; +using UnityEngine; +using Verse; + +namespace Patch_HatsDisplaySelection +{ + [HarmonyBefore(new string[] { "velc.HatsDisplaySelection" })] + [HarmonyPatch(typeof(HatDisplaySelection.Patch), "Patch_PawnRenderer_RenderPawnInternal_Initialize")] + public class Patch_HatsDisplaySelectionInitialize + + { + + public static void Prefix(PawnRenderer __instance, ref Pawn ___pawn, ref Vector3 rootLoc, ref float angle, ref Rot4 bodyFacing, ref Rot4 headFacing) + { + + CompBodyAnimator bodyAnim = ___pawn.TryGetComp(); + bodyAnim.animatePawn(ref rootLoc, ref angle, ref bodyFacing, ref headFacing); + } + + public static void Postfix(PawnRenderer __instance) + { + PawnGraphicSet graphics = __instance.graphics; + Pawn pawn = graphics.pawn; + CompBodyAnimator bodyAnim = pawn.TryGetComp(); + + if (!graphics.AllResolved) + { + graphics.ResolveAllGraphics(); + } + + + if (bodyAnim != null && bodyAnim.isAnimating && pawn.Map == Find.CurrentMap) + { + bodyAnim.tickGraphics(graphics); + + + } + } + } +} diff --git a/Patches/AnimationPatch_CompBodyAnimator.xml b/1.2/Patches/AnimationPatch_CompBodyAnimator.xml similarity index 100% rename from Patches/AnimationPatch_CompBodyAnimator.xml rename to 1.2/Patches/AnimationPatch_CompBodyAnimator.xml diff --git a/1.2/Patches/CompatibilityPatch_FacialAnimation.xml b/1.2/Patches/CompatibilityPatch_FacialAnimation.xml new file mode 100644 index 0000000..125d79f --- /dev/null +++ b/1.2/Patches/CompatibilityPatch_FacialAnimation.xml @@ -0,0 +1,130 @@ + + + + +
  • [NL] Facial Animation - WIP
  • + + + Always + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/targetJobs + Always + +
  • RJW_Masturbate
  • +
  • GettinBred
  • +
  • Bestiality
  • +
  • BestialityForFemale
  • +
  • ViolateCorpse
  • +
  • Quickie
  • +
  • GettingQuickie
  • +
  • GettinRaped
  • +
  • JoinInBed
  • +
  • GettinLoved
  • +
  • GettinLicked
  • +
  • GettinSucked
  • +
  • WhoreIsServingVisitors
  • +
  • JoinInBedAnimation
  • +
  • GettinLovedAnimation
  • + + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="WaitCombat" or defName="Wait_Combat_Rare"]/targetJobs + Always + +
  • RapeComfortPawn
  • +
  • RandomRape
  • +
  • RapeEnemy
  • + + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="StandAndBeSociallyActive"]/targetJobs + Always + +
  • WhoreInvitingVisitors
  • + + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Wear" or defName="Wear2" or defName="Wear3"]/targetJobs + Always + +
  • CleanSelf
  • +
  • StruggleInBondageGear
  • + + +
  • + +
  • Rimworld-Animations
  • + + + Always + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/animationFrames/li[1]/headOffset + Always +
  • +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin"]/animationFrames/li[2]/headOffset + Always +
  • +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin"]/animationFrames/li[3]/headOffset + Always +
  • +
    +
    + +
    +
    + + + + \ No newline at end of file diff --git a/Patches/CompatibilityPatch_HCSK.xml b/1.2/Patches/CompatibilityPatch_HCSK.xml similarity index 100% rename from Patches/CompatibilityPatch_HCSK.xml rename to 1.2/Patches/CompatibilityPatch_HCSK.xml diff --git a/Sounds/Sex/Clap_1.wav b/1.2/Sounds/Sex/Clap_1.wav similarity index 100% rename from Sounds/Sex/Clap_1.wav rename to 1.2/Sounds/Sex/Clap_1.wav diff --git a/Sounds/Sex/Clap_2.wav b/1.2/Sounds/Sex/Clap_2.wav similarity index 100% rename from Sounds/Sex/Clap_2.wav rename to 1.2/Sounds/Sex/Clap_2.wav diff --git a/Sounds/Sex/Clap_3.wav b/1.2/Sounds/Sex/Clap_3.wav similarity index 100% rename from Sounds/Sex/Clap_3.wav rename to 1.2/Sounds/Sex/Clap_3.wav diff --git a/Sounds/Sex/Clap_4.wav b/1.2/Sounds/Sex/Clap_4.wav similarity index 100% rename from Sounds/Sex/Clap_4.wav rename to 1.2/Sounds/Sex/Clap_4.wav diff --git a/Sounds/Sex/Clap_5.wav b/1.2/Sounds/Sex/Clap_5.wav similarity index 100% rename from Sounds/Sex/Clap_5.wav rename to 1.2/Sounds/Sex/Clap_5.wav diff --git a/Sounds/Sex/Clap_6.wav b/1.2/Sounds/Sex/Clap_6.wav similarity index 100% rename from Sounds/Sex/Clap_6.wav rename to 1.2/Sounds/Sex/Clap_6.wav diff --git a/Sounds/Sex/Clap_7.wav b/1.2/Sounds/Sex/Clap_7.wav similarity index 100% rename from Sounds/Sex/Clap_7.wav rename to 1.2/Sounds/Sex/Clap_7.wav diff --git a/Sounds/Sex/Clap_8.wav b/1.2/Sounds/Sex/Clap_8.wav similarity index 100% rename from Sounds/Sex/Clap_8.wav rename to 1.2/Sounds/Sex/Clap_8.wav diff --git a/1.2/Sounds/Sex/Slime/Slimy1.wav b/1.2/Sounds/Sex/Slime/Slimy1.wav new file mode 100644 index 0000000..3cfbd74 Binary files /dev/null and b/1.2/Sounds/Sex/Slime/Slimy1.wav differ diff --git a/1.2/Sounds/Sex/Slime/Slimy2.wav b/1.2/Sounds/Sex/Slime/Slimy2.wav new file mode 100644 index 0000000..36a9197 Binary files /dev/null and b/1.2/Sounds/Sex/Slime/Slimy2.wav differ diff --git a/1.2/Sounds/Sex/Slime/Slimy3.wav b/1.2/Sounds/Sex/Slime/Slimy3.wav new file mode 100644 index 0000000..40aff1e Binary files /dev/null and b/1.2/Sounds/Sex/Slime/Slimy3.wav differ diff --git a/1.2/Sounds/Sex/Slime/Slimy4.wav b/1.2/Sounds/Sex/Slime/Slimy4.wav new file mode 100644 index 0000000..0b6404e Binary files /dev/null and b/1.2/Sounds/Sex/Slime/Slimy4.wav differ diff --git a/1.2/Sounds/Sex/Slime/Slimy5.wav b/1.2/Sounds/Sex/Slime/Slimy5.wav new file mode 100644 index 0000000..ea310db Binary files /dev/null and b/1.2/Sounds/Sex/Slime/Slimy5.wav differ diff --git a/1.2/Sounds/Sex/Suck/Suck_1.wav b/1.2/Sounds/Sex/Suck/Suck_1.wav new file mode 100644 index 0000000..4f1eafd Binary files /dev/null and b/1.2/Sounds/Sex/Suck/Suck_1.wav differ diff --git a/1.2/Sounds/Sex/Suck/Suck_10.wav b/1.2/Sounds/Sex/Suck/Suck_10.wav new file mode 100644 index 0000000..284cda3 Binary files /dev/null and b/1.2/Sounds/Sex/Suck/Suck_10.wav differ diff --git a/1.2/Sounds/Sex/Suck/Suck_3.wav b/1.2/Sounds/Sex/Suck/Suck_3.wav new file mode 100644 index 0000000..95e7348 Binary files /dev/null and b/1.2/Sounds/Sex/Suck/Suck_3.wav differ diff --git a/1.2/Sounds/Sex/Suck/Suck_4.wav b/1.2/Sounds/Sex/Suck/Suck_4.wav new file mode 100644 index 0000000..753a023 Binary files /dev/null and b/1.2/Sounds/Sex/Suck/Suck_4.wav differ diff --git a/1.2/Sounds/Sex/Suck/Suck_5.wav b/1.2/Sounds/Sex/Suck/Suck_5.wav new file mode 100644 index 0000000..8ecda9c Binary files /dev/null and b/1.2/Sounds/Sex/Suck/Suck_5.wav differ diff --git a/1.2/Sounds/Sex/Suck/Suck_6.wav b/1.2/Sounds/Sex/Suck/Suck_6.wav new file mode 100644 index 0000000..08567d6 Binary files /dev/null and b/1.2/Sounds/Sex/Suck/Suck_6.wav differ diff --git a/1.2/Sounds/Sex/Suck/Suck_7.wav b/1.2/Sounds/Sex/Suck/Suck_7.wav new file mode 100644 index 0000000..a63b0e4 Binary files /dev/null and b/1.2/Sounds/Sex/Suck/Suck_7.wav differ diff --git a/1.2/Sounds/Sex/Suck/Suck_8.wav b/1.2/Sounds/Sex/Suck/Suck_8.wav new file mode 100644 index 0000000..320da09 Binary files /dev/null and b/1.2/Sounds/Sex/Suck/Suck_8.wav differ diff --git a/1.2/Sounds/Sex/Suck/Suck_9.wav b/1.2/Sounds/Sex/Suck/Suck_9.wav new file mode 100644 index 0000000..7ab538a Binary files /dev/null and b/1.2/Sounds/Sex/Suck/Suck_9.wav differ diff --git a/1.2/Sounds/Sex/Suck/Swallow_1.wav b/1.2/Sounds/Sex/Suck/Swallow_1.wav new file mode 100644 index 0000000..f3276cc Binary files /dev/null and b/1.2/Sounds/Sex/Suck/Swallow_1.wav differ diff --git a/1.2/Sounds/Sex/Suck/Swallow_2.wav b/1.2/Sounds/Sex/Suck/Swallow_2.wav new file mode 100644 index 0000000..09a7a00 Binary files /dev/null and b/1.2/Sounds/Sex/Suck/Swallow_2.wav differ diff --git a/1.2/Sounds/Sex/Suck/Swallow_3.wav b/1.2/Sounds/Sex/Suck/Swallow_3.wav new file mode 100644 index 0000000..2817b29 Binary files /dev/null and b/1.2/Sounds/Sex/Suck/Swallow_3.wav differ diff --git a/1.2/Sounds/Sex/Suck/suck_2.wav b/1.2/Sounds/Sex/Suck/suck_2.wav new file mode 100644 index 0000000..a8305c1 Binary files /dev/null and b/1.2/Sounds/Sex/Suck/suck_2.wav differ diff --git a/Sounds/Sex/cum.wav b/1.2/Sounds/Sex/cum.wav similarity index 100% rename from Sounds/Sex/cum.wav rename to 1.2/Sounds/Sex/cum.wav diff --git a/Sounds/Sex/kucyu04.wav b/1.2/Sounds/Sex/kucyu04.wav similarity index 100% rename from Sounds/Sex/kucyu04.wav rename to 1.2/Sounds/Sex/kucyu04.wav diff --git a/Textures/UI/MainTab.png b/1.2/Textures/UI/MainTab.png similarity index 100% rename from Textures/UI/MainTab.png rename to 1.2/Textures/UI/MainTab.png diff --git a/1.3/Assemblies/Rimworld-Animations.dll b/1.3/Assemblies/Rimworld-Animations.dll new file mode 100644 index 0000000..7f376ba Binary files /dev/null and b/1.3/Assemblies/Rimworld-Animations.dll differ diff --git a/1.3/Defs/AnimationDefs/AnimationDefs.rar b/1.3/Defs/AnimationDefs/AnimationDefs.rar new file mode 100644 index 0000000..e7bf2a1 Binary files /dev/null and b/1.3/Defs/AnimationDefs/AnimationDefs.rar differ diff --git a/1.3/Defs/AnimationDefs/Animations_Beast.xml b/1.3/Defs/AnimationDefs/Animations_Beast.xml new file mode 100644 index 0000000..30d14fc --- /dev/null +++ b/1.3/Defs/AnimationDefs/Animations_Beast.xml @@ -0,0 +1,2180 @@ + + + + Dog_Doggystyle + + true + +
  • Anal
  • +
  • Vaginal
  • +
    + + +
  • VaginalBreeding
  • +
  • AnalBreeding
  • +
    + + +
  • + +
  • Human
  • + + true + +
  • + +
  • Wolf_Timber
  • +
  • Wolf_Arctic
  • +
  • Whitefox
  • +
  • Warg
  • +
  • Husky
  • +
  • LabradorRetriever
  • + +
  • AEXP_WelshTerrier
  • +
  • AEXP_Rottweiler
  • +
  • AEXP_Poodle
  • +
  • AEXP_GreatDane
  • +
  • AEXP_GermanShepherd
  • +
  • AEXP_FrenchBulldog
  • +
  • AEXP_Corgi
  • +
  • AEXP_CatAbyssinian
  • +
  • AEXP_CatBengal
  • +
  • AEXP_CatMaineCoon
  • +
  • AEXP_CatSphynx
  • + + +
  • QuadrupedAnimalWithHooves
  • +
  • QuadrupedAnimalWithPawsAndTail
  • +
    + true + true + +
    + + + + +
  • + Fuck + true + 765 + 0 + +
  • + LayingPawn + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 + 0 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 + 0 +
  • + +
    + +
  • + +
  • + + 8 + -33.7 + 0 + -0.492 + 0.266 + 1 + 0 + 0 +
  • +
  • + 8 + Fuck + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 +
  • +
  • + 1 + -33.7 + 0 + -0.492 + 0.266 + 1 + 0 + 0 +
  • + + + + +
  • + Knot + False + 71 + 0 + +
  • + LayingPawn + +
  • + true + 60 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 1 + 0 +
  • +
  • + 6 + Cum + 53.7 + 28.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 4 + 51.7 + 33.4 + 0.098 + -0.038 + 1 + 1 +
  • +
  • + 1 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 1 + 0 +
  • + + + +
  • + +
  • + + 60 + -33.7 + 0 + -0.492 + 0.266 + 1 + 0 + 0 +
  • +
  • + 6 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 +
  • +
  • + 4 + Fuck + -41.6 + 0 + -0.383 + 0.256 + 1 + 0 +
  • +
  • + 1 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 + 0 +
  • + + + + + + +
  • + Cum + true + 600 + 0 + +
  • + LayingPawn + +
  • + 40 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 1 + 0 +
  • +
  • + 40 + Cum + 57.7 + 28.4 + 0.073 + -0.038 + 1 + 1 +
  • +
  • + 1 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 1 + 0 +
  • + + + +
  • + + +
  • + 10 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 + 0 +
  • +
  • + 10 + -40.6 + 0 + -0.358 + 0.256 + 1 + 0 +
  • +
  • + 10 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 +
  • +
  • + 10 + -40.6 + 0 + -0.358 + 0.256 + 1 + 0 +
  • +
  • + 10 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 +
  • +
  • + 10 + -40.6 + 0 + -0.358 + 0.256 + 1 + 0 +
  • +
  • + 10 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 +
  • +
  • + 10 + -40.6 + 0 + -0.358 + 0.256 + 1 + 0 +
  • +
  • + 1 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 + 0 +
  • + + + + + + + + + + + + Horse_Cowgirl + + true + +
  • Anal
  • +
  • Vaginal
  • +
    + + +
  • RequestVaginalBreeding
  • +
  • RequestAnalBreeding
  • +
    + + +
  • + +
  • Human
  • + + true + true + + (0, 0.2) + + +
  • + +
  • Horse
  • + + +
  • QuadrupedAnimalWithHooves
  • +
    + true + +
    + + + + +
  • + Insertion + false + 0 + +
  • + +
  • + 180 + -24.337 + -37.1218948 + 0 + 0.698042035 + -0.20718734 + 0 + 3 + 3 +
  • +
  • + 70 + -2.54239845 + 7.31265259 + 0 + 0.606091142 + -0.045959726 + 0 + 3 + 3 + Slimy +
  • +
  • + 60 + -4.84361649 + -23.6405125 + 0 + 0.650456548 + -0.0570534021 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -35.01766 + -26.3706665 + 0 + 0.455286169 + -0.3646413 + 0 + 3 + 3 + Slimy +
  • + + +
  • + LayingPawn + +
  • + 250 + 177.083145 + 0 + 0 + -0.256229281 + -0.362511069 + 0 + 1 + 0 + +
  • +
  • + 60 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • +
  • + 1 + 179.6811 + 0 + 0 + -0.267210543 + -0.3991253 + 0 + 1 + 0 +
  • + + + + + +
  • + SlowFuck + true + 1300 + 0 + +
  • + +
  • + 80 + -35.01766 + -26.3706665 + 0 + 0.455286169 + -0.3646413 + 0 + 3 + 3 +
  • +
  • + 49 + -49.8178673 + -35.7418823 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -35.01766 + -26.3706665 + 0 + 0.455286169 + -0.3646413 + 0 + 3 + 3 + Fuck +
  • + + +
  • + LayingPawn + +
  • + 80 + 179.6811 + 0 + 0 + -0.267210543 + -0.3991253 + 0 + 1 + 0 +
  • +
  • + 49 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • +
  • + 1 + 179.6811 + 0 + 0 + -0.267210543 + -0.3991253 + 0 + 1 + 0 +
  • + + + + + +
  • + Transition + false + 0 + +
  • + +
  • + 50 + -35.01766 + -26.3706665 + 0 + 0.455286169 + -0.3646413 + 0 + 3 + 3 + Fuck +
  • + +
  • + 15 + -49.8178673 + -35.7418823 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + +
  • + 80 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • + +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.48456946 + -0.489136577 + 0 + 3 + 3 +
  • + + +
  • + LayingPawn + +
  • + 50 + 179.6811 + 0 + 0 + -0.267210543 + -0.3991253 + 0 + 1 + 0 +
  • + +
  • + 15 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • + +
  • + 80 + 175.467651 + 0 + 0 + -0.2123042 + -0.5309518 + 0 + 1 + 0 + Fuck +
  • + +
  • + 1 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • + + + + + +
  • + FastFuck + true + 1260 + 0 + +
  • + + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 2 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 2 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 2 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 2 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 2 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 2 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + + +
  • + LayingPawn + + +
  • + 10 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • +
  • + 24 + 175.467651 + 0 + 0 + -0.2123042 + -0.5309518 + 0 + 1 + 0 + Fuck +
  • +
  • + 1 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • + + + + + +
  • + FasterFuck + true + 418 + 0 + +
  • + + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 +
  • +
  • + 8 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + + +
  • + LayingPawn + +
  • + 10 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • +
  • + 8 + 175.467651 + 0 + 0 + -0.2123042 + -0.5309518 + 0 + 1 + 0 + Fuck +
  • +
  • + 1 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • + + + + + +
  • + Cum + True + 318 + 0 + +
  • + + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + +
  • +
  • + true + 80 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 + Cum +
  • +
  • + 25 + -49.8178673 + 2.654541 + 0 + 0.5175133 + -0.547725141 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 +
  • + + + +
  • + LayingPawn + + +
  • + 10 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • +
  • + 80 + 175.467651 + 0 + 0 + -0.2123042 + -0.5309518 + 0 + 1 + 0 +
  • +
  • + 25 + 173.81427 + 0 + 0 + -0.197662517 + -0.545600235 + 0 + 1 + 0 +
  • +
  • + 1 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • + + + + + + +
    + +
    + diff --git a/1.3/Defs/AnimationDefs/Animations_Lesbian.xml b/1.3/Defs/AnimationDefs/Animations_Lesbian.xml new file mode 100644 index 0000000..56d805a --- /dev/null +++ b/1.3/Defs/AnimationDefs/Animations_Lesbian.xml @@ -0,0 +1,1782 @@ + + + + Tribadism + + true + +
  • Scissoring
  • +
    + + +
  • + +
  • Human
  • + + true + +
  • Vagina
  • +
    + +
  • + +
  • Human
  • + + true + true + +
  • Vagina
  • +
    + + +
    + + +
  • + Tribbing + true + 992 + 0 + +
  • + LayingPawn + +
  • + + 20 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 20 + -79.56 + -79.56 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 20 + -81.53 + -81.53 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + + +
  • + +
  • + + 20 + 9.97 + -7.61 + 0.444 + 0.368 + 3 + 3 + 0 +
  • +
  • + 20 + 23.82 + -6.90 + 0.432 + 0.403 + 3 + 3 + 0 +
  • +
  • + 20 + 5.19 + -6.19 + 0.442 + 0.388 + 3 + 3 + 0 +
  • +
  • + 1 + 9.97 + -7.61 + 0.444 + 0.368 + 3 + 3 + 0 +
  • + + + + + +
  • + TribadismFast + true + 682 + 0 + +
  • + LayingPawn + +
  • + + 10 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + 10 + -79.56 + -79.56 + -0.218 + 0.082 + 2 + 1 + 0 +
  • +
  • + 10 + -81.53 + -81.53 + -0.219 + 0.07 + 2 + 1 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + + 10 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + 10 + -79.56 + -79.56 + -0.218 + 0.082 + 2 + 1 + 0 +
  • +
  • + 10 + -81.53 + -81.53 + -0.219 + 0.07 + 2 + 1 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • + +
  • + + 10 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + 10 + -79.56 + -79.56 + -0.218 + 0.082 + 2 + 1 + 0 +
  • +
  • + 10 + -81.53 + -81.53 + -0.219 + 0.07 + 2 + 1 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + + 10 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + 10 + -79.56 + -79.56 + -0.218 + 0.082 + 2 + 1 + 0 +
  • +
  • + 10 + -81.53 + -81.53 + -0.219 + 0.07 + 2 + 1 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • + + +
  • + + 10 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 10 + -79.56 + -77.66 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 10 + -81.53 + -77.74 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + + +
  • + + 10 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 10 + -79.56 + -77.66 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 10 + -81.53 + -77.74 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + + +
  • + + 10 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 10 + -79.56 + -77.66 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 10 + -81.53 + -77.74 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + + +
  • + + 10 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 10 + -79.56 + -77.66 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 10 + -81.53 + -77.74 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + + +
  • + + 10 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 10 + -79.56 + -77.66 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 10 + -81.53 + -77.74 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + + +
  • + + 10 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 10 + -79.56 + -77.66 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 10 + -81.53 + -77.74 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + +
  • + + 10 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + 10 + -79.56 + -79.56 + -0.218 + 0.082 + 2 + 1 + 0 +
  • +
  • + 10 + -81.53 + -81.53 + -0.219 + 0.07 + 2 + 1 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • + + +
  • + +
  • + + 10 + 9.97 + -7.61 + 0.444 + 0.368 + 3 + 3 + 0 +
  • +
  • + 10 + 23.82 + -6.90 + 0.432 + 0.403 + 3 + 3 + 0 +
  • +
  • + 10 + 5.19 + -6.19 + 0.442 + 0.388 + 3 + 3 + 0 +
  • +
  • + 1 + 9.97 + -7.61 + 0.444 + 0.368 + 3 + 3 + 0 +
  • + + + + + +
    + +
    + + Cunnilingus + + true + +
  • Oral
  • +
  • Fingering
  • +
  • Cunnilingus
  • +
    + + +
  • Cunnilingus
  • +
  • CunnilingusF
  • +
  • CunnilingusRape
  • +
  • CunnilingusRapeF
  • + +
  • Fingering
  • +
  • FingeringF
  • +
  • FingeringRape
  • +
  • FingeringRapeF
  • + +
  • Fisting
  • +
  • FistingF
  • +
  • FistingRape
  • +
  • FistingRapeF
  • + +
    + +
  • + +
  • Human
  • + + true + +
  • Vagina
  • +
    + + (-0.2, 0.1) + + +
  • + +
  • Human
  • + + true + + (-0.1, 0.15) + + +
    + + + + +
  • + Initial + False + 0 + +
  • + +
  • + 60 + -81.06536 + -56.4483032 + 0 + -0.0624052179 + -0.437134951 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + +
  • + 60 + -27.578373 + 0.2816162 + 0 + 0.102704488 + 0.50675 + 0 + 3 + 3 +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 + Slimy +
  • + + + + + + +
  • + Slow + True + 1497 + 0 + +
  • + +
  • + 98 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 40 + -87.26528 + -65.901825 + 0 + -0.0737426062 + -0.432820916 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • + +
  • + 98 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 40 + -87.26528 + -65.901825 + 0 + -0.0737426062 + -0.432820916 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • + +
  • + 60 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 120 + -86.52611 + -68.86432 + 0 + -0.05432228 + -0.439906 + 0 + 1 + 1 +
  • +
  • + 40 + -88.36286 + -84.3309 + 0 + -0.06637782 + -0.440140843 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + +
  • + 80 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 +
  • +
  • + 18 + -41.1054764 + -10.1737061 + 0 + 0.04582855 + 0.462155169 + 0 + 3 + 3 +
  • +
  • + 40 + -38.1903877 + -31.6517334 + 0 + 0.0384018831 + 0.4874894 + 0 + 3 + 3 +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 + Slimy +
  • + +
  • + 80 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 +
  • +
  • + 18 + -41.1054764 + -10.1737061 + 0 + 0.04582855 + 0.462155169 + 0 + 3 + 3 +
  • +
  • + 40 + -38.1903877 + -31.6517334 + 0 + 0.0384018831 + 0.4874894 + 0 + 3 + 3 +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 + Slimy +
  • + +
  • + 60 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 + Slimy +
  • +
  • + 40 + -45.2595444 + -13.57782 + 0 + 0.009577712 + 0.4726282 + 0 + 3 + 3 + Slimy +
  • +
  • + 20 + -45.2595444 + -24.2278748 + 0 + 0.0315402448 + 0.415024319 + 0 + 3 + 3 + +
  • +
  • + 40 + -45.2595444 + -13.57782 + 0 + 0.009577712 + 0.4726282 + 0 + 3 + 3 + Slimy +
  • +
  • + 20 + -45.2595444 + -24.2278748 + 0 + 0.0315402448 + 0.415024319 + 0 + 3 + 3 + +
  • +
  • + 40 + -45.2595444 + -13.57782 + 0 + 0.009577712 + 0.4726282 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 + Slimy +
  • + + + + + + +
  • + Transition + False + 0 + +
  • + +
  • + 40 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 30 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + +
  • + 40 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 + Slimy +
  • +
  • + 30 + -35.8792953 + -9.312592 + 0 + 0.03684573 + 0.4285702 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • + + + + + +
  • + Fast + True + 710 + 0 + +
  • + +
  • + 40 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 30 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + +
  • + 40 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 30 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + +
  • + 40 + -87.3645554 + -79.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 2 +
  • +
  • + 30 + -97.90959 + -79.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 2 +
  • +
  • + 1 + -87.3645554 + -79.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 2 +
  • + +
  • + 40 + -87.3645554 + -79.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 2 +
  • +
  • + 30 + -97.90959 + -79.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 2 +
  • +
  • + 1 + -87.3645554 + -79.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 2 +
  • + +
  • + 40 + -87.3645554 + -79.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 2 +
  • +
  • + 30 + -97.90959 + -79.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 2 +
  • +
  • + 1 + -87.3645554 + -79.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 2 +
  • + +
  • + 40 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 30 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + +
  • + 40 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • +
  • + 30 + -35.8792953 + -3.312592 + 0 + 0.03684573 + 0.4285702 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • + + + + +
  • + Faster + True + 360 + 0 + +
  • + +
  • + 20 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 15 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + +
  • + 20 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • +
  • + 15 + -35.8792953 + -9.312592 + 0 + 0.03684573 + 0.4285702 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • + + + + +
  • + Cum + True + 639 + 0 + +
  • + +
  • + 20 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 15 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + +
  • + 20 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 15 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + +
  • + 20 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + True + 80 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 + Cum +
  • +
  • + 40 + -99.80413 + -94.4023743 + 0 + -0.01950606 + -0.447728932 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + + +
  • + 20 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • +
  • + 15 + -35.8792953 + -9.312592 + 0 + 0.03684573 + 0.4285702 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • + +
  • + 20 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • +
  • + 15 + -35.8792953 + -9.312592 + 0 + 0.03684573 + 0.4285702 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • + +
  • + 20 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • +
  • + 80 + -35.8792953 + -9.312592 + 0 + 0.03684573 + 0.4285702 + 0 + 3 + 3 +
  • +
  • + 40 + -38.5277061 + -1.13140869 + 0 + 0.0376501828 + 0.42935127 + 0 + 3 + 3 +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • + + + + + +
    + +
    +
    diff --git a/1.3/Defs/AnimationDefs/Animations_Masturbate.xml b/1.3/Defs/AnimationDefs/Animations_Masturbate.xml new file mode 100644 index 0000000..2968fa1 --- /dev/null +++ b/1.3/Defs/AnimationDefs/Animations_Masturbate.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/1.3/Defs/AnimationDefs/Animations_Multi.xml b/1.3/Defs/AnimationDefs/Animations_Multi.xml new file mode 100644 index 0000000..af7ea7a --- /dev/null +++ b/1.3/Defs/AnimationDefs/Animations_Multi.xml @@ -0,0 +1,660 @@ + + + + Double_Penetration + + true + +
  • DoublePenetration
  • +
  • Anal
  • +
  • Oral
  • +
  • Vaginal
  • +
    + +
  • + +
  • Human
  • + + true + +
  • + +
  • Human
  • + + true + true + true + +
  • + +
  • Human
  • + + true + true + true + +
    + + +
  • + Slow + true + 976 + 0 + +
  • + + +
  • + 25 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • +
  • + 35 + 48.1 + 16.3 + 0 + 0.188 + 1 + 1 + 0 +
  • +
  • + Suck + 1 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • + + +
  • + + LayingPawn + +
  • + -10 + 30 + 12 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 30 + 12 + -15.1 + 0.729 + 0.378 + 3 + 3 + 0 +
  • +
  • + -10 + 1 + 12 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • + + +
  • + + LayingPawn + +
  • + 43 + 27 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • +
  • + Fuck + 33 + -6.7 + 14.1 + -0.53 + 0.378 + 1 + 1 + 0 +
  • +
  • + 43 + 1 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • + + + + +
  • + Face_Fuck + true + 650 + 0 + +
  • + + +
  • + 13 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • +
  • + 6 + 60.7 + 5.6 + 0.025 + 0.118 + 1 + 1 + 0 +
  • +
  • + 6 + 62.7 + 0.2 + 0.08 + 0.118 + 1 + 1 + 0 +
  • +
  • + Suck + 1 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • + + +
  • + + LayingPawn + +
  • + -10 + 13 + 12 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 12 + 2 + -15.1 + 0.729 + 0.378 + 3 + 3 + 0 +
  • +
  • + -10 + 1 + 12 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • + + +
  • + + LayingPawn + +
  • + 43 + 13 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • +
  • + Fuck + 12 + -6.7 + 14.1 + -0.53 + 0.378 + 1 + 1 + 0 +
  • +
  • + 43 + 1 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • + + + + +
  • + Cum + true + 392 + 0 + +
  • + + +
  • + 9 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • +
  • + 4 + 60.7 + 5.6 + 0.025 + 0.118 + 1 + 1 + 0 +
  • +
  • + 4 + 62.7 + 0.2 + 0.056 + 0.118 + 1 + 1 + 0 +
  • +
  • + Suck + 1 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • + +
  • + 9 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • +
  • + 4 + 60.7 + 5.6 + 0.025 + 0.118 + 1 + 1 + 0 +
  • +
  • + 4 + 62.7 + 0.2 + 0.056 + 0.118 + 1 + 1 + 0 +
  • +
  • + Suck + 1 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • + +
  • + 9 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • +
  • + true + 120 + 60.7 + 5.6 + 0.025 + 0.118 + 1 + 1 + 0 +
  • +
  • + 30 + 62.7 + 0.2 + 0.056 + 0.118 + 1 + 1 + 0 +
  • +
  • + Suck + 1 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • + + +
  • + + LayingPawn + +
  • + -10 + 9 + 9 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 8 + 0 + -15.1 + 0.729 + 0.378 + 3 + 3 + 0 +
  • +
  • + 1 + 9 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • + +
  • + 9 + 9 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 8 + 0 + -15.1 + 0.729 + 0.378 + 3 + 3 + 0 +
  • +
  • + 1 + 9 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • + + +
  • + 9 + 9 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 120 + 9 + -15.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 30 + 9 + 7 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 1 + 9 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 + -10 +
  • + + + +
  • + + LayingPawn + +
  • + 43 + 9 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • +
  • + Fuck + 8 + -6.7 + 14.1 + -0.53 + 0.378 + 1 + 1 + 0 +
  • +
  • + 1 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • + +
  • + 9 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • +
  • + Fuck + 8 + -6.7 + 14.1 + -0.53 + 0.378 + 1 + 1 + 0 +
  • +
  • + 1 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • + +
  • + 9 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • +
  • + Cum + 120 + -6.7 + 14.1 + -0.53 + 0.378 + 1 + 1 + 0 +
  • +
  • + 30 + -6.7 + -7 + -0.53 + 0.378 + 1 + 1 + 0 +
  • +
  • + 43 + 1 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • + + + + + +
    + +
    + +
    diff --git a/1.3/Defs/AnimationDefs/Animations_SexToys.xml b/1.3/Defs/AnimationDefs/Animations_SexToys.xml new file mode 100644 index 0000000..320d3aa --- /dev/null +++ b/1.3/Defs/AnimationDefs/Animations_SexToys.xml @@ -0,0 +1,59 @@ + + + + diff --git a/1.3/Defs/AnimationDefs/Animations_Vanilla2.xml b/1.3/Defs/AnimationDefs/Animations_Vanilla2.xml new file mode 100644 index 0000000..71b02a9 --- /dev/null +++ b/1.3/Defs/AnimationDefs/Animations_Vanilla2.xml @@ -0,0 +1,378 @@ + + + + + + + \ No newline at end of file diff --git a/1.3/Defs/AnimationDefs/Animations_vanilla.xml b/1.3/Defs/AnimationDefs/Animations_vanilla.xml new file mode 100644 index 0000000..0fd61d5 --- /dev/null +++ b/1.3/Defs/AnimationDefs/Animations_vanilla.xml @@ -0,0 +1,2799 @@ + + + + + Doggystyle + + true + +
  • Vaginal
  • +
  • Anal
  • +
  • DoublePenetration
  • +
    + + +
  • AnalSex
  • +
  • AnalSexF
  • +
  • AnalRape
  • +
  • VaginalSex
  • +
  • VaginalSexF
  • +
  • VaginalRape
  • +
    + + +
  • + + +
  • Human
  • + + true + +
  • + +
  • Human
  • + + true + true + true + + (0, 0.2) + + +
    + + +
  • + Slow_Fuck + true + 612 + 0 + +
  • + +
  • + 0 + 10 + 27 + 0.298 + 0.166 + 0 + 1 + 2 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 2 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 2 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 2 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 2 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 2 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 2 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 2 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 2 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 1 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 1 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 1 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 1 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 1 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 1 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 1 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 1 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 1 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 1 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 1 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 1 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 1 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 1 +
  • +
  • + 0 + 1 + 27 + 0.298 + 0.166 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + +
  • + 27 + 0 + 10 + 16.6 + -0.217 + 0.175 + 3 + 1 + 1 +
  • + +
  • + 40 + Fuck + -17 + -0.217 + 0.272 + 5.4 + 1 + 1 +
  • +
  • + 1 + 16.6 + -0.217 + 0.175 + 3 + 1 + 1 + 0 + 27 +
  • + + + + +
  • + Fast_Fuck + true + 609 + 0 + +
  • + +
  • + 8 + 27 + 0.298 + 0.166 + 1 + 1 + 1 + 0 +
  • +
  • + 12 + 32 + 0.326 + 0.190 + 4 + 1 + 1 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 1 + 1 + 0 +
  • + + +
  • + LayingPawn + +
  • + 27 + 8 + 11 + -0.217 + 0.175 + 8 + 1 + 1 + 0 +
  • + +
  • + 12 + Fuck + -12 + -0.217 + 0.272 + 9 + 1 + 1 +
  • +
  • + 1 + 11 + -0.217 + 0.175 + 8 + 1 + 1 + 0 + 27 +
  • + + + + +
  • + Cum + true + 300 + 0 + +
  • + +
  • + 8 + 27 + 0.298 + 0.166 + 0 + 1 + 1 + 0 +
  • +
  • + Cum + 100 + 32 + 0.326 + 0.190 + -1 + 1 + 1 + true +
  • +
  • + 12 + 35 + 0.326 + 0.190 + -14 + 1 + 1 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 0 + 1 + 1 + 0 +
  • + + +
  • + LayingPawn + +
  • + 27 + 8 + 11 + -0.217 + 0.175 + -8 + 1 + 1 + 0 +
  • +
  • + 100 + -12 + -0.217 + 0.272 + -9 + 1 + 1 +
  • +
  • + 12 + -15 + -0.227 + 0.272 + -4 + 1 + 1 +
  • +
  • + 1 + 11 + -0.217 + 0.175 + -8 + 1 + 1 + 0 + 27 +
  • + + + + +
    +
    + + Blowjob + + true + +
  • Oral
  • +
  • Fellatio
  • +
    + +
  • Handjob
  • +
  • HandjobF
  • +
  • HandjobRape
  • +
  • HandjobRapeF
  • + +
  • Breastjob
  • +
  • BreastjobF
  • +
  • BreastjobRape
  • +
  • BreastjobRapeF
  • + +
  • Fellatio
  • +
  • FellatioF
  • +
  • FellatioRape
  • +
  • FellatioRapeF
  • + +
  • Beakjob
  • +
  • BeakjobF
  • +
  • BeakjobRape
  • +
  • BeakjobRapeF
  • + + +
    + +
  • + + +
  • Human
  • + + + (0, -0.2) + + +
  • + +
  • Human
  • + + true + true + true + + (0, 0.2) + + +
    + +
  • + Slow_Suck + true + 1140 + 0 + +
  • + +
  • + 35 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • +
  • + Suck + 59 + 0 + 0 + -0.33 + 0 + 0 + -0.16 +
  • +
  • + 1 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • + +
  • + 35 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • +
  • + Suck + 59 + 0 + 0 + -0.33 + 0 + 0 + -0.15 +
  • +
  • + 1 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • + +
  • + 35 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • +
  • + Suck + 59 + + 6 + 0 + -0.33 + 0 + 0 + -0.13 +
  • +
  • + 1 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • + +
  • + 35 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • +
  • + Suck + 59 + 0 + -4 + 0 + -0.33 + 0 + 0 + -0.12 +
  • +
  • + 1 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • + + +
  • + LayingPawn + +
  • + 35 + 0 + 0 + 0 + 0.473 + 2 + 2 + 0 + 180 +
  • +
  • + 59 + 0 + 0 + 0.490 + 2 + 2 + -0.003 +
  • +
  • + 1 + 0 + 0 + 0 + 0.473 + 2 + 2 + 0 + 180 +
  • + + + + +
  • + Face_Fuck + true + 300 + 0 + +
  • + +
  • + 15 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • +
  • + Suck + 14 + 0 + 0 + -0.270 + 0 + 0 + -0.06 +
  • +
  • + 1 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • + + +
  • + LayingPawn + +
  • + 15 + 0 + 0 + 0 + 0.473 + 2 + 2 + 0 + 180 +
  • +
  • + 14 + 0 + 0 + 0.575 + 2 + 2 + -0.051 +
  • +
  • + 1 + 0 + 0 + 0 + 0.473 + 2 + 2 + 0 + 180 +
  • + + + + +
  • + Cum + true + 600 + 0 + +
  • + +
  • + 12 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • +
  • + 7 + 0 + 0 + -0.290 + 0 + 0 + -0.06 +
  • +
  • + 7 + Suck + 0 + 0 + -0.290 + 0 + 0 + -0.008 +
  • +
  • + 60 + 0 + 0 + -0.290 + 0 + 0 + -0.06 +
  • +
  • + 14 + 0 + 0 + -0.290 + 0 + 0 + -0.06 +
  • +
  • + 1 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • + + +
  • + LayingPawn + +
  • + 12 + 0 + 0 + 0 + 0.473 + 2 + 2 + 0 + 180 +
  • +
  • + 7 + Cum + 0 + 0 + 0.575 + 2 + 2 + -0.051 +
  • +
  • + 7 + 0 + 0 + 0.50 + 2 + 2 + -0.04 +
  • +
  • + true + 60 + 0 + 0 + 0.575 + 2 + 2 + -0.051 +
  • +
  • + 14 + 0 + 0 + 0.575 + 2 + 2 + -0.051 +
  • +
  • + 1 + 0 + 0 + 0 + 0.473 + 2 + 2 + 0 + 180 +
  • + + + + +
    + +
    + + ReverseStandAndCarry + + true + +
  • Anal
  • +
  • Vaginal
  • +
  • DoublePenetration
  • +
    + +
  • AnalSex
  • +
  • AnalSexF
  • +
  • AnalRape
  • +
  • VaginalSex
  • +
  • VaginalSexF
  • +
  • VaginalRape
  • +
    + +
  • + + +
  • Human
  • + + true + + (0, 0.2) + + +
  • + +
  • Human
  • + + true + true + true + + (0, 0.2) + + +
    + + +
  • + Slow_Fuck + true + 1080 + 0 + +
  • + +
  • + 30 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 29 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + + +
  • + LayingPawn + +
  • + 6 + 30 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 + Fuck + 29 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 1 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 + 6 +
  • + + + + + +
  • + Fast_Fuck + true + 780 + 0 + +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + + + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + + +
  • + LayingPawn + +
  • + 6 + 13 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 + Fuck + 12 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 1 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 + 6 +
  • + + + + + +
  • + Cum + true + 415 + 0 + +
  • + +
  • + 3 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 4 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 3 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 4 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 3 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 4 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 3 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 4 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + true + 75 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 27 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + + +
  • + LayingPawn + +
  • + 6 + 7 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 + Fuck + 7 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 6 + 1 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • + +
  • + 6 + 7 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 + Fuck + 7 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 6 + 1 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • + +
  • + 6 + 7 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 + Fuck + 7 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 6 + 1 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • + +
  • + 6 + 7 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 + Cum + 75 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 40 + 27 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 6 + 1 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • + + + + +
    + +
    + + Cowgirl + + true + +
  • Anal
  • +
  • Vaginal
  • +
  • DoublePenetration
  • +
    + + +
  • AnalSex
  • +
  • AnalSexF
  • +
  • AnalRapeF
  • +
  • VaginalSex
  • +
  • VaginalSexF
  • +
  • VaginalRapeF
  • +
    + + + +
  • + + +
  • Human
  • + + true + true + + (0, 0.2) + + + +
  • + +
  • Human
  • + + true + true + + (0, -0.2) + + + +
    + + +
  • + Slow_Fuck + true + 1340 + 0 + +
  • + + +
  • + 16 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 17 + 3.5 + 0 + -0.03 + 0.624 + 2 + 2 + -0.02 +
  • +
  • + 16 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 17 + -3.5 + 0 + 0.03 + 0.624 + 2 + 2 + -0.02 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + +
  • + 16 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 17 + 3.5 + 0 + -0.03 + 0.624 + 2 + 2 + -0.02 +
  • +
  • + 16 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 17 + -3.5 + 0 + 0.03 + 0.624 + 2 + 2 + -0.02 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + + +
  • + 33 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 33 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + +
  • + 33 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 33 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + + +
  • + LayingPawn + +
  • + 16 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 17 + 180 + 180 + 0 + -0.347 + 2 + 2 + 0.015 + -15 +
  • +
  • + 16 + 180 + 180 + 0 + -0.331 + 2 + 2 + 0.03 + 0 +
  • +
  • + 17 + 180 + 180 + 0 + -0.315 + 2 + 2 + 0.045 + 15 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 16 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 17 + 180 + 180 + 0 + -0.347 + 2 + 2 + 0.015 + -15 +
  • +
  • + 16 + 180 + 180 + 0 + -0.331 + 2 + 2 + 0.03 + 0 +
  • +
  • + 17 + 180 + 180 + 0 + -0.315 + 2 + 2 + 0.045 + 15 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 33 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 33 + 180 + 180 + 0 + -0.315 + 2 + 2 + 0.045 + 0 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 33 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 33 + 180 + 180 + 0 + -0.315 + 2 + 2 + 0.045 + 0 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • + + + + +
  • + Fast_Fuck + true + 780 + 0 + +
  • + +
  • + 13 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 13 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + + +
  • + LayingPawn + +
  • + 13 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 13 + 180 + 180 + 0 + -0.313 + 2 + 2 + 0.045 + 0 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • + + + + +
  • + Cum + true + 594 + 0 + +
  • + +
  • + 10 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 10 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + +
  • + 10 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 10 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + +
  • + 10 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 10 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + true + 45 + Cum + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + true + 40 + 0 + 0 + 0 + 0.534 + 2 + 2 + 0 +
  • +
  • + 1 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + + +
  • + LayingPawn + +
  • + 10 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 10 + 180 + 180 + 0 + -0.313 + 2 + 2 + 0.045 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 +
  • + +
  • + 10 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 +
  • +
  • + 10 + 180 + 180 + 0 + -0.313 + 2 + 2 + 0.045 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 +
  • + +
  • + 10 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 +
  • +
  • + 10 + 180 + 180 + 0 + -0.313 + 2 + 2 + 0.045 +
  • +
  • + 45 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 +
  • +
  • + 40 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • + + + + +
    + +
    +
    + + + diff --git a/1.3/Defs/AnimationDefs/TemplateAnimation.xml b/1.3/Defs/AnimationDefs/TemplateAnimation.xml new file mode 100644 index 0000000..0305903 --- /dev/null +++ b/1.3/Defs/AnimationDefs/TemplateAnimation.xml @@ -0,0 +1,54 @@ + + + + diff --git a/1.3/Defs/MainTabDefs/MainButtonDef.xml b/1.3/Defs/MainTabDefs/MainButtonDef.xml new file mode 100644 index 0000000..0674d24 --- /dev/null +++ b/1.3/Defs/MainTabDefs/MainButtonDef.xml @@ -0,0 +1,15 @@ + + + + + OffsetManager + + Control pawn offsets + Rimworld_Animations.MainTabWindow_OffsetConfigure + 54 + false + UI/MainTab + true + + + \ No newline at end of file diff --git a/1.3/Defs/SoundDefs/Sounds_Sex.xml b/1.3/Defs/SoundDefs/Sounds_Sex.xml new file mode 100644 index 0000000..4cce5d0 --- /dev/null +++ b/1.3/Defs/SoundDefs/Sounds_Sex.xml @@ -0,0 +1,212 @@ + + + + + Cum + MapOnly + + 1 + 1 + +
  • + +
  • + Sex/cum +
  • + + + 30 + 40 + + + 0.8 + 1.2 + + + 0 + 51.86047 + + False + +
    +
    + + Sex + MapOnly + + 1 + 1 + +
  • + +
  • + Sex/kucyu04 +
  • + + + 16 + 16 + + + 0.8 + 1.2 + + + 0 + 51.86047 + + False + +
    +
    + + Suck + MapOnly + + 1 + 1 + +
  • + +
  • + Sex/Suck/Suck_1 +
  • +
  • + Sex/Suck/Suck_2 +
  • +
  • + Sex/Suck/Suck_3 +
  • +
  • + Sex/Suck/Suck_4 +
  • +
  • + Sex/Suck/Suck_5 +
  • +
  • + Sex/Suck/Suck_6 +
  • +
  • + Sex/Suck/Suck_7 +
  • +
  • + Sex/Suck/Suck_8 +
  • +
  • + Sex/Suck/Suck_9 +
  • +
  • + Sex/Suck/Suck_10 +
  • + + + 20 + 35 + + + 1.0 + 1.0 + + + 0 + 51.86047 + + NeverTwice + false + +
    +
    + + Fuck + MapOnly + + 1 + 1 + +
  • + +
  • + Sex/Clap_1 +
  • +
  • + Sex/Clap_2 +
  • +
  • + Sex/Clap_3 +
  • +
  • + Sex/Clap_4 +
  • +
  • + Sex/Clap_5 +
  • +
  • + Sex/Clap_6 +
  • +
  • + Sex/Clap_7 +
  • +
  • + Sex/Clap_8 +
  • + + + 45 + 70 + + + 1.0 + 1.0 + + + 0 + 51.86047 + + NeverTwice + false + +
    +
    + + Slimy + MapOnly + + 1 + 1 + +
  • + +
  • + Sex/Slime/Slimy1 +
  • +
  • + Sex/Slime/Slimy2 +
  • +
  • + Sex/Slime/Slimy3 +
  • +
  • + Sex/Slime/Slimy4 +
  • +
  • + Sex/Slime/Slimy5 +
  • + + + 45 + 75 + + + 1.4 + 1.8 + + + 0 + 100 + + NeverTwice + false + +
    +
    +
    \ No newline at end of file diff --git a/1.3/Patch_HatsDisplaySelection/Patch_HatsDisplaySelection.csproj b/1.3/Patch_HatsDisplaySelection/Patch_HatsDisplaySelection.csproj new file mode 100644 index 0000000..8da21a6 --- /dev/null +++ b/1.3/Patch_HatsDisplaySelection/Patch_HatsDisplaySelection.csproj @@ -0,0 +1,75 @@ + + + + + Debug + AnyCPU + {BA766964-1716-422D-A09E-29426F8EB9D5} + Library + Properties + Patch_HatsDisplaySelection + Patch_HatsDisplaySelection + v4.7.2 + 512 + true + + + false + none + false + 1.2\Assemblies\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\..\workshop\content\294100\2009463077\Current\Assemblies\0Harmony.dll + False + + + ..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll + False + + + ..\..\..\..\..\workshop\content\294100\1542291825\1.2\Assemblies\HatDisplaySelection.dll + False + + + ..\1.2\Assemblies\Rimworld-Animations.dll + False + + + + + + + + + + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll + False + + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll + False + + + + + + + + + + + \ No newline at end of file diff --git a/1.3/Patches/AnimationPatchHSK.xml b/1.3/Patches/AnimationPatchHSK.xml new file mode 100644 index 0000000..74038ea --- /dev/null +++ b/1.3/Patches/AnimationPatchHSK.xml @@ -0,0 +1,31 @@ + + + + +
  • Core SK
  • +
    + + + +
  • + Defs/ThingDef/comps + Always + + Defs/ThingDef + + + + +
  • + +
  • + Defs/ThingDef[@Name="BaseAnimalPawn" or @Name="SK_BasePawn" or @Name="BasePawnSkynet"]/comps + +
  • + +
  • + +
    +
    +
    +
    diff --git a/1.3/Patches/AnimationPatch_CompBodyAnimator.xml b/1.3/Patches/AnimationPatch_CompBodyAnimator.xml new file mode 100644 index 0000000..e645747 --- /dev/null +++ b/1.3/Patches/AnimationPatch_CompBodyAnimator.xml @@ -0,0 +1,35 @@ + + + + Always + +
  • + Always + Defs/ThingDef[race][not(comps)] + + + +
  • +
  • + Always + Defs/AlienRace.ThingDef_AlienRace[not(comps)] + + + +
  • + +
  • + Defs/ThingDef[@Name="BasePawn"]/comps + +
  • + +
  • +
  • + Defs/AlienRace.ThingDef_AlienRace/comps + +
  • + +
  • +
    +
    +
    diff --git a/1.3/Patches/CompPatches/AutoCleaner.xml b/1.3/Patches/CompPatches/AutoCleaner.xml new file mode 100644 index 0000000..c2ad860 --- /dev/null +++ b/1.3/Patches/CompPatches/AutoCleaner.xml @@ -0,0 +1,19 @@ + + + + Always + +
  • + /Defs/ThingDef[@Name="BaseBaseAutocleaner"]/comps + Always + + /Defs/ThingDef[@Name="BaseBaseAutocleaner"]/comps + +
  • + + +
  • +
    +
    +
    + diff --git a/1.3/Patches/CompPatches/CombatExtended.xml b/1.3/Patches/CompPatches/CombatExtended.xml new file mode 100644 index 0000000..7d35127 --- /dev/null +++ b/1.3/Patches/CompPatches/CombatExtended.xml @@ -0,0 +1,18 @@ + + + + Always + +
  • + /Defs/ThingDef[@Name="BasePawnSimple"]/comps + Always + + /Defs/ThingDef[@Name="BasePawnSimple"]/comps + +
  • + + +
  • +
    +
    +
    diff --git a/1.3/Patches/CompPatches/ZombieLand.xml b/1.3/Patches/CompPatches/ZombieLand.xml new file mode 100644 index 0000000..e950e0e --- /dev/null +++ b/1.3/Patches/CompPatches/ZombieLand.xml @@ -0,0 +1,18 @@ + + + + Always + +
  • + /Defs/ThingDef[@Name="BaseZombie"]/comps + Always + + /Defs/ThingDef[@Name="BaseZombie"]/comps + +
  • + + +
  • +
    +
    +
    diff --git a/1.3/Patches/CompatibilityPatch_FacialAnimation.xml b/1.3/Patches/CompatibilityPatch_FacialAnimation.xml new file mode 100644 index 0000000..125d79f --- /dev/null +++ b/1.3/Patches/CompatibilityPatch_FacialAnimation.xml @@ -0,0 +1,130 @@ + + + + +
  • [NL] Facial Animation - WIP
  • +
    + + Always + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/targetJobs + Always + +
  • RJW_Masturbate
  • +
  • GettinBred
  • +
  • Bestiality
  • +
  • BestialityForFemale
  • +
  • ViolateCorpse
  • +
  • Quickie
  • +
  • GettingQuickie
  • +
  • GettinRaped
  • +
  • JoinInBed
  • +
  • GettinLoved
  • +
  • GettinLicked
  • +
  • GettinSucked
  • +
  • WhoreIsServingVisitors
  • +
  • JoinInBedAnimation
  • +
  • GettinLovedAnimation
  • + + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="WaitCombat" or defName="Wait_Combat_Rare"]/targetJobs + Always + +
  • RapeComfortPawn
  • +
  • RandomRape
  • +
  • RapeEnemy
  • + + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="StandAndBeSociallyActive"]/targetJobs + Always + +
  • WhoreInvitingVisitors
  • + + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Wear" or defName="Wear2" or defName="Wear3"]/targetJobs + Always + +
  • CleanSelf
  • +
  • StruggleInBondageGear
  • + + +
  • + +
  • Rimworld-Animations
  • + + + Always + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/animationFrames/li[1]/headOffset + Always +
  • +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin"]/animationFrames/li[2]/headOffset + Always +
  • +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin"]/animationFrames/li[3]/headOffset + Always +
  • +
    +
    + +
    +
    +
    +
    + + \ No newline at end of file diff --git a/1.3/Patches/CompatibilityPatch_HCSK.xml b/1.3/Patches/CompatibilityPatch_HCSK.xml new file mode 100644 index 0000000..ead8783 --- /dev/null +++ b/1.3/Patches/CompatibilityPatch_HCSK.xml @@ -0,0 +1,39 @@ + + + + + +
  • Core SK
  • +
    + + Always + +
  • + /Defs/ThingDef/comps + Always + + /Defs/ThingDef + + + + +
  • + +
  • + /Defs/ThingDef[@Name="SK_BasePawn"]/comps + +
  • + +
  • + +
  • + /Defs/ThingDef[@Name="BaseAnimalPawn"]/comps + +
  • + +
  • +
    +
    +
    + +
    \ No newline at end of file diff --git a/1.3/Patches/RacePatches/Epona race Renaissance.xml b/1.3/Patches/RacePatches/Epona race Renaissance.xml new file mode 100644 index 0000000..f39b509 --- /dev/null +++ b/1.3/Patches/RacePatches/Epona race Renaissance.xml @@ -0,0 +1,19 @@ + + + + +
  • Epona race Renaissance
  • +
    + + +
  • + /Defs/AlienRace.ThingDef_AlienRace[defName = "Alien_Epona"]/alienRace/generalSettings/alienPartGenerator/bodyAddons/li[hediffGraphics/Epona_OHPG_female="Things/Pawn/Addons/Breasts/Breasts"]/drawnInBed + + false + +
  • +
    +
    +
    + +
    diff --git a/1.3/Patches/RacePatches/Nyaron.xml b/1.3/Patches/RacePatches/Nyaron.xml new file mode 100644 index 0000000..0a7a08e --- /dev/null +++ b/1.3/Patches/RacePatches/Nyaron.xml @@ -0,0 +1,19 @@ + + + + +
  • Nyaron race
  • +
    + + +
  • + /Defs/AlienRace.ThingDef_AlienRace[defName = "Alien_Nyaron"]/alienRace/generalSettings/alienPartGenerator/bodyAddons/li[bodyPart="tail"] + + false + +
  • +
    +
    +
    + +
    diff --git a/1.3/Sounds/Sex/Clap_1.wav b/1.3/Sounds/Sex/Clap_1.wav new file mode 100644 index 0000000..bccd0f2 Binary files /dev/null and b/1.3/Sounds/Sex/Clap_1.wav differ diff --git a/1.3/Sounds/Sex/Clap_2.wav b/1.3/Sounds/Sex/Clap_2.wav new file mode 100644 index 0000000..a382f59 Binary files /dev/null and b/1.3/Sounds/Sex/Clap_2.wav differ diff --git a/1.3/Sounds/Sex/Clap_3.wav b/1.3/Sounds/Sex/Clap_3.wav new file mode 100644 index 0000000..65cf39b Binary files /dev/null and b/1.3/Sounds/Sex/Clap_3.wav differ diff --git a/1.3/Sounds/Sex/Clap_4.wav b/1.3/Sounds/Sex/Clap_4.wav new file mode 100644 index 0000000..3ae1b3e Binary files /dev/null and b/1.3/Sounds/Sex/Clap_4.wav differ diff --git a/1.3/Sounds/Sex/Clap_5.wav b/1.3/Sounds/Sex/Clap_5.wav new file mode 100644 index 0000000..65144e7 Binary files /dev/null and b/1.3/Sounds/Sex/Clap_5.wav differ diff --git a/1.3/Sounds/Sex/Clap_6.wav b/1.3/Sounds/Sex/Clap_6.wav new file mode 100644 index 0000000..0026325 Binary files /dev/null and b/1.3/Sounds/Sex/Clap_6.wav differ diff --git a/1.3/Sounds/Sex/Clap_7.wav b/1.3/Sounds/Sex/Clap_7.wav new file mode 100644 index 0000000..6d7de2a Binary files /dev/null and b/1.3/Sounds/Sex/Clap_7.wav differ diff --git a/1.3/Sounds/Sex/Clap_8.wav b/1.3/Sounds/Sex/Clap_8.wav new file mode 100644 index 0000000..1af5710 Binary files /dev/null and b/1.3/Sounds/Sex/Clap_8.wav differ diff --git a/1.3/Sounds/Sex/Slime/Slimy1.wav b/1.3/Sounds/Sex/Slime/Slimy1.wav new file mode 100644 index 0000000..3cfbd74 Binary files /dev/null and b/1.3/Sounds/Sex/Slime/Slimy1.wav differ diff --git a/1.3/Sounds/Sex/Slime/Slimy2.wav b/1.3/Sounds/Sex/Slime/Slimy2.wav new file mode 100644 index 0000000..36a9197 Binary files /dev/null and b/1.3/Sounds/Sex/Slime/Slimy2.wav differ diff --git a/1.3/Sounds/Sex/Slime/Slimy3.wav b/1.3/Sounds/Sex/Slime/Slimy3.wav new file mode 100644 index 0000000..40aff1e Binary files /dev/null and b/1.3/Sounds/Sex/Slime/Slimy3.wav differ diff --git a/1.3/Sounds/Sex/Slime/Slimy4.wav b/1.3/Sounds/Sex/Slime/Slimy4.wav new file mode 100644 index 0000000..0b6404e Binary files /dev/null and b/1.3/Sounds/Sex/Slime/Slimy4.wav differ diff --git a/1.3/Sounds/Sex/Slime/Slimy5.wav b/1.3/Sounds/Sex/Slime/Slimy5.wav new file mode 100644 index 0000000..ea310db Binary files /dev/null and b/1.3/Sounds/Sex/Slime/Slimy5.wav differ diff --git a/1.3/Sounds/Sex/Suck/Suck_1.wav b/1.3/Sounds/Sex/Suck/Suck_1.wav new file mode 100644 index 0000000..4f1eafd Binary files /dev/null and b/1.3/Sounds/Sex/Suck/Suck_1.wav differ diff --git a/1.3/Sounds/Sex/Suck/Suck_10.wav b/1.3/Sounds/Sex/Suck/Suck_10.wav new file mode 100644 index 0000000..284cda3 Binary files /dev/null and b/1.3/Sounds/Sex/Suck/Suck_10.wav differ diff --git a/1.3/Sounds/Sex/Suck/Suck_3.wav b/1.3/Sounds/Sex/Suck/Suck_3.wav new file mode 100644 index 0000000..95e7348 Binary files /dev/null and b/1.3/Sounds/Sex/Suck/Suck_3.wav differ diff --git a/1.3/Sounds/Sex/Suck/Suck_4.wav b/1.3/Sounds/Sex/Suck/Suck_4.wav new file mode 100644 index 0000000..753a023 Binary files /dev/null and b/1.3/Sounds/Sex/Suck/Suck_4.wav differ diff --git a/1.3/Sounds/Sex/Suck/Suck_5.wav b/1.3/Sounds/Sex/Suck/Suck_5.wav new file mode 100644 index 0000000..8ecda9c Binary files /dev/null and b/1.3/Sounds/Sex/Suck/Suck_5.wav differ diff --git a/1.3/Sounds/Sex/Suck/Suck_6.wav b/1.3/Sounds/Sex/Suck/Suck_6.wav new file mode 100644 index 0000000..08567d6 Binary files /dev/null and b/1.3/Sounds/Sex/Suck/Suck_6.wav differ diff --git a/1.3/Sounds/Sex/Suck/Suck_7.wav b/1.3/Sounds/Sex/Suck/Suck_7.wav new file mode 100644 index 0000000..a63b0e4 Binary files /dev/null and b/1.3/Sounds/Sex/Suck/Suck_7.wav differ diff --git a/1.3/Sounds/Sex/Suck/Suck_8.wav b/1.3/Sounds/Sex/Suck/Suck_8.wav new file mode 100644 index 0000000..320da09 Binary files /dev/null and b/1.3/Sounds/Sex/Suck/Suck_8.wav differ diff --git a/1.3/Sounds/Sex/Suck/Suck_9.wav b/1.3/Sounds/Sex/Suck/Suck_9.wav new file mode 100644 index 0000000..7ab538a Binary files /dev/null and b/1.3/Sounds/Sex/Suck/Suck_9.wav differ diff --git a/1.3/Sounds/Sex/Suck/Swallow_1.wav b/1.3/Sounds/Sex/Suck/Swallow_1.wav new file mode 100644 index 0000000..f3276cc Binary files /dev/null and b/1.3/Sounds/Sex/Suck/Swallow_1.wav differ diff --git a/1.3/Sounds/Sex/Suck/Swallow_2.wav b/1.3/Sounds/Sex/Suck/Swallow_2.wav new file mode 100644 index 0000000..09a7a00 Binary files /dev/null and b/1.3/Sounds/Sex/Suck/Swallow_2.wav differ diff --git a/1.3/Sounds/Sex/Suck/Swallow_3.wav b/1.3/Sounds/Sex/Suck/Swallow_3.wav new file mode 100644 index 0000000..2817b29 Binary files /dev/null and b/1.3/Sounds/Sex/Suck/Swallow_3.wav differ diff --git a/1.3/Sounds/Sex/Suck/suck_2.wav b/1.3/Sounds/Sex/Suck/suck_2.wav new file mode 100644 index 0000000..a8305c1 Binary files /dev/null and b/1.3/Sounds/Sex/Suck/suck_2.wav differ diff --git a/1.3/Sounds/Sex/cum.wav b/1.3/Sounds/Sex/cum.wav new file mode 100644 index 0000000..ef98437 Binary files /dev/null and b/1.3/Sounds/Sex/cum.wav differ diff --git a/1.3/Sounds/Sex/kucyu04.wav b/1.3/Sounds/Sex/kucyu04.wav new file mode 100644 index 0000000..3ae1ce8 Binary files /dev/null and b/1.3/Sounds/Sex/kucyu04.wav differ diff --git a/Source/Actors/Actor.cs b/1.3/Source/Actors/Actor.cs similarity index 89% rename from Source/Actors/Actor.cs rename to 1.3/Source/Actors/Actor.cs index 55e4f79..3b382dd 100644 --- a/Source/Actors/Actor.cs +++ b/1.3/Source/Actors/Actor.cs @@ -20,6 +20,7 @@ namespace Rimworld_Animations { public List bodyDefTypes = new List(); public BodyTypeOffset bodyTypeOffset = new BodyTypeOffset(); public Vector3 offset = new Vector2(0, 0); - + public List requiredGender; + public List tags = new List(); } } diff --git a/Source/Actors/AlienRaceOffset.cs b/1.3/Source/Actors/AlienRaceOffset.cs similarity index 100% rename from Source/Actors/AlienRaceOffset.cs rename to 1.3/Source/Actors/AlienRaceOffset.cs diff --git a/Source/Actors/BodyTypeOffset.cs b/1.3/Source/Actors/BodyTypeOffset.cs similarity index 100% rename from Source/Actors/BodyTypeOffset.cs rename to 1.3/Source/Actors/BodyTypeOffset.cs diff --git a/Source/Animations/AnimationStage.cs b/1.3/Source/Animations/AnimationStage.cs similarity index 88% rename from Source/Animations/AnimationStage.cs rename to 1.3/Source/Animations/AnimationStage.cs index 475c079..7a1304e 100644 --- a/Source/Animations/AnimationStage.cs +++ b/1.3/Source/Animations/AnimationStage.cs @@ -10,9 +10,10 @@ namespace Rimworld_Animations { public string stageName; public int stageIndex; public int playTimeTicks = 0; + public int playTimeTicksQuick = -1; public bool isLooping; public List animationClips; - + public List tags = new List(); public void initialize() { foreach (BaseAnimationClip clip in animationClips) { diff --git a/Source/Animations/Clips/BaseAnimationClip.cs b/1.3/Source/Animations/Clips/BaseAnimationClip.cs similarity index 76% rename from Source/Animations/Clips/BaseAnimationClip.cs rename to 1.3/Source/Animations/Clips/BaseAnimationClip.cs index 1aaf03f..aa35b31 100644 --- a/Source/Animations/Clips/BaseAnimationClip.cs +++ b/1.3/Source/Animations/Clips/BaseAnimationClip.cs @@ -9,11 +9,12 @@ using Verse; namespace Rimworld_Animations { public abstract class BaseAnimationClip { + public Dictionary SoundEffects = new Dictionary(); public List types; //types of participants public int duration; public abstract void buildSimpleCurves(); public string soundDef = null; //for playing sounds public int actor; - + public List tags = new List(); } } diff --git a/Source/Animations/Clips/PawnAnimationClip.cs b/1.3/Source/Animations/Clips/PawnAnimationClip.cs similarity index 98% rename from Source/Animations/Clips/PawnAnimationClip.cs rename to 1.3/Source/Animations/Clips/PawnAnimationClip.cs index 746c3f4..e9d2489 100644 --- a/Source/Animations/Clips/PawnAnimationClip.cs +++ b/1.3/Source/Animations/Clips/PawnAnimationClip.cs @@ -12,7 +12,6 @@ namespace Rimworld_Animations { public List keyframes; public AltitudeLayer layer = AltitudeLayer.Pawn; - public Dictionary SoundEffects = new Dictionary(); public Dictionary quiver = new Dictionary(); public SimpleCurve GenitalAngle = new SimpleCurve(); public SimpleCurve BodyAngle = new SimpleCurve(); diff --git a/1.3/Source/Animations/Clips/ThingAnimationClip.cs b/1.3/Source/Animations/Clips/ThingAnimationClip.cs new file mode 100644 index 0000000..26f4d4c --- /dev/null +++ b/1.3/Source/Animations/Clips/ThingAnimationClip.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using RimWorld; + +namespace Rimworld_Animations { + public class ThingAnimationClip : BaseAnimationClip + { + public List keyframes; + + public SimpleCurve PositionX = new SimpleCurve(); + public SimpleCurve PositionZ = new SimpleCurve(); + public SimpleCurve Rotation = new SimpleCurve(); + + + public override void buildSimpleCurves() { + int duration = 0; + //getting the length of the whole clip + foreach (ThingKeyframe frame in keyframes) + { + duration += frame.tickDuration; + } + + //guarantees loops don't get cut off mid-anim + this.duration = duration; + + int keyframePosition = 0; + foreach (ThingKeyframe frame in keyframes) + { + + if (frame.atTick.HasValue) + { + if (frame.positionX.HasValue) + PositionX.Add((float)frame.atTick / (float)duration, frame.positionX.Value, true); + + if (frame.positionZ.HasValue) + PositionZ.Add((float)frame.atTick / (float)duration, frame.positionZ.Value, true); + + if (frame.rotation.HasValue) + Rotation.Add((float)frame.atTick / (float)duration, frame.rotation.Value, true); + + if (frame.soundEffect != null) + { + SoundEffects.Add((int)frame.atTick, frame.soundEffect); + } + + + } + else + { + if (frame.positionX.HasValue) + PositionX.Add((float)keyframePosition / (float)duration, frame.positionX.Value, true); + + if (frame.positionZ.HasValue) + PositionZ.Add((float)keyframePosition / (float)duration, frame.positionZ.Value, true); + + if (frame.rotation.HasValue) + Rotation.Add((float)keyframePosition / (float)duration, frame.rotation.Value, true); + + if (frame.soundEffect != null) + { + SoundEffects.Add(keyframePosition, frame.soundEffect); + } + keyframePosition += frame.tickDuration; + + } + + } + } + } +} diff --git a/Source/Animations/Keyframes/Keyframe.cs b/1.3/Source/Animations/Keyframes/Keyframe.cs similarity index 66% rename from Source/Animations/Keyframes/Keyframe.cs rename to 1.3/Source/Animations/Keyframes/Keyframe.cs index 8b49841..8cd859d 100644 --- a/Source/Animations/Keyframes/Keyframe.cs +++ b/1.3/Source/Animations/Keyframes/Keyframe.cs @@ -8,7 +8,8 @@ namespace Rimworld_Animations { public abstract class Keyframe { public int tickDuration = 1; - - + public float? atTick; + public string soundEffect; + public List tags = new List(); } } diff --git a/Source/Animations/Keyframes/PawnKeyframe.cs b/1.3/Source/Animations/Keyframes/PawnKeyframe.cs similarity index 89% rename from Source/Animations/Keyframes/PawnKeyframe.cs rename to 1.3/Source/Animations/Keyframes/PawnKeyframe.cs index 685009e..e710981 100644 --- a/Source/Animations/Keyframes/PawnKeyframe.cs +++ b/1.3/Source/Animations/Keyframes/PawnKeyframe.cs @@ -22,9 +22,7 @@ namespace Rimworld_Animations { public int? bodyFacing; public int? headFacing; - public string soundEffect; public bool? quiver; - public float? atTick; } } diff --git a/Source/Animations/Keyframes/ThingKeyframe.cs b/1.3/Source/Animations/Keyframes/ThingKeyframe.cs similarity index 67% rename from Source/Animations/Keyframes/ThingKeyframe.cs rename to 1.3/Source/Animations/Keyframes/ThingKeyframe.cs index 9d35a96..6604f5e 100644 --- a/Source/Animations/Keyframes/ThingKeyframe.cs +++ b/1.3/Source/Animations/Keyframes/ThingKeyframe.cs @@ -7,5 +7,12 @@ using System.Threading.Tasks; namespace Rimworld_Animations { public class ThingKeyframe : Keyframe { + + public float? positionX; + public float? positionZ; + public float? rotation; + + + } } diff --git a/Source/Comps/CompBodyAnimator.cs b/1.3/Source/Comps/CompBodyAnimator.cs similarity index 56% rename from Source/Comps/CompBodyAnimator.cs rename to 1.3/Source/Comps/CompBodyAnimator.cs index 33bd110..7910f7d 100644 --- a/Source/Comps/CompBodyAnimator.cs +++ b/1.3/Source/Comps/CompBodyAnimator.cs @@ -11,12 +11,12 @@ using Verse; using Verse.Sound; namespace Rimworld_Animations { - class CompBodyAnimator : ThingComp + public class CompBodyAnimator : ThingComp { public Pawn pawn => base.parent as Pawn; public PawnGraphicSet Graphics; - - public CompProperties_BodyAnimator Props => (CompProperties_BodyAnimator)(object)base.props; + + //public CompProperties_BodyAnimator Props => (CompProperties_BodyAnimator)(object)base.props; public bool isAnimating { get { @@ -25,10 +25,11 @@ namespace Rimworld_Animations { set { Animating = value; - if(value == true) { + if (value == true) { SexUtility.DrawNude(pawn); } else { pawn.Drawer.renderer.graphics.ResolveAllGraphics(); + actorsInCurrentAnimation = null; } PortraitsCache.SetDirty(pawn); @@ -48,10 +49,19 @@ namespace Rimworld_Animations { public float bodyAngle = 0, headAngle = 0, genitalAngle = 0; public Rot4 headFacing = Rot4.North, bodyFacing = Rot4.North; + public List actorsInCurrentAnimation; + public bool controlGenitalAngle = false; + public bool fastAnimForQuickie = false; private AnimationDef anim; - private AnimationStage stage => anim.animationStages[curStage]; + private AnimationStage stage { + get + { + return anim.animationStages[curStage]; + } + + } private PawnAnimationClip clip => (PawnAnimationClip)stage.animationClips[actor]; public bool Mirror { @@ -102,8 +112,14 @@ namespace Rimworld_Animations { anchor = thing.Position.ToVector3Shifted(); } } - public void StartAnimation(AnimationDef anim, int actor, bool mirror = false, bool shiver = false, bool fastAnimForQuickie = false) { + public void StartAnimation(AnimationDef anim, List actors, int actor, bool mirror = false, bool shiver = false, bool fastAnimForQuickie = false) { + actorsInCurrentAnimation = actors; + + if (anim.actors.Count <= actor) + { + return; + } AlienRaceOffset raceOffset = anim?.actors[actor]?.raceOffsets?.Find(x => x.defName == pawn.def.defName); if (raceOffset != null) { @@ -140,9 +156,18 @@ namespace Rimworld_Animations { this.actor = actor; this.anim = anim; this.mirror = mirror; + this.fastAnimForQuickie = fastAnimForQuickie; - curStage = fastAnimForQuickie ? 1 : 0; - animTicks = 0; + if (fastAnimForQuickie && anim.animationStages.Any(x => x.playTimeTicksQuick >= 0) == false) + { + curStage = 1; + animTicks = anim.animationStages[0].playTimeTicks; + } else + { + curStage = 0; + animTicks = 0; + } + stageTicks = 0; clipTicks = 0; @@ -155,14 +180,16 @@ namespace Rimworld_Animations { //tick once for initialization tickAnim(); - - } + public override void CompTick() { base.CompTick(); if(isAnimating) { + + GlobalTextureAtlasManager.TryMarkPawnFrameSetDirty(pawn); + if (pawn.Dead || pawn?.jobs?.curDriver == null || (pawn?.jobs?.curDriver != null && !(pawn?.jobs?.curDriver is rjw.JobDriver_Sex))) { isAnimating = false; } @@ -171,7 +198,7 @@ namespace Rimworld_Animations { } } } - public void animatePawn(ref Vector3 rootLoc, ref float angle, ref Rot4 bodyFacing, ref Rot4 headFacing) { + public void animatePawnBody(ref Vector3 rootLoc, ref float angle, ref Rot4 bodyFacing) { if(!isAnimating) { return; @@ -179,35 +206,63 @@ namespace Rimworld_Animations { rootLoc = anchor + deltaPos; angle = bodyAngle; bodyFacing = this.bodyFacing; - headFacing = this.headFacing; - - - } + public Rot4 AnimateHeadFacing() + { + return this.headFacing; + } + + public void tickGraphics(PawnGraphicSet graphics) { this.Graphics = graphics; } public void tickAnim() { + + if (!isAnimating) return; + if (anim == null) { + isAnimating = false; + return; + } + animTicks++; + if (animTicks < anim.animationTimeTicks) { tickStage(); } else { - isAnimating = false; + if(LoopNeverending()) + { + ResetOnLoop(); + } else + { + isAnimating = false; + } + + } + + + } public void tickStage() { + + if(stage == null) + { + isAnimating = false; + return; + } + stageTicks++; - if(stageTicks >= stage.playTimeTicks) { + if(stageTicks >= stage.playTimeTicks || (fastAnimForQuickie && stage.playTimeTicksQuick >= 0 && stageTicks >= stage.playTimeTicksQuick)) { curStage++; @@ -217,9 +272,16 @@ namespace Rimworld_Animations { } if(curStage >= anim.animationStages.Count) { - isAnimating = false; - pawn.jobs.curDriver.ReadyForNextToil(); - + if (LoopNeverending()) + { + ResetOnLoop(); + } + else + { + isAnimating = false; + pawn.jobs.curDriver.ReadyForNextToil(); + } + } else { tickClip(); } @@ -234,18 +296,34 @@ namespace Rimworld_Animations { //play sound effect if(rjw.RJWSettings.sounds_enabled && clip.SoundEffects.ContainsKey(clipTicks) && AnimationSettings.soundOverride) { - SoundDef.Named(clip.SoundEffects[clipTicks]).PlayOneShot(new TargetInfo(pawn.Position, pawn.Map)); + - if (AnimationSettings.applySemenOnAnimationOrgasm && (pawn?.jobs?.curDriver is JobDriver_Sex) && clip.SoundEffects[clipTicks] == "Cum") { + SoundInfo sound = new TargetInfo(pawn.Position, pawn.Map); + string soundEffectName = clip.SoundEffects[clipTicks]; - Pawn partner = (pawn.jobs.curDriver as JobDriver_Sex)?.Partner; - if(anim.sexTypes.Contains((pawn.jobs.curDriver as JobDriver_Sex).sexType)) { - SemenHelper.calculateAndApplySemen(pawn, partner, (pawn.jobs.curDriver as JobDriver_Sex).sexType); - } - + if ((pawn.jobs.curDriver as JobDriver_Sex).isAnimalOnAnimal) + { + sound.volumeFactor *= RJWSettings.sounds_animal_on_animal_volume; } + if(soundEffectName.StartsWith("Voiceline_")) + { + sound.volumeFactor *= RJWSettings.sounds_voice_volume; + } + + if (clip.SoundEffects[clipTicks] == "Cum") { + + sound.volumeFactor *= RJWSettings.sounds_cum_volume; + //considerApplyingSemen(); + + } else + { + sound.volumeFactor *= RJWSettings.sounds_sex_volume; + } + + SoundDef.Named(soundEffectName).PlayOneShot(sound); + } if(AnimationSettings.orgasmQuiver && clip.quiver.ContainsKey(clipTicks)) { quiver = clip.quiver[clipTicks]; @@ -260,6 +338,18 @@ namespace Rimworld_Animations { calculateDrawValues(); } + public void considerApplyingSemen() + { + if(AnimationSettings.applySemenOnAnimationOrgasm && (pawn?.jobs?.curDriver is JobDriver_Sex)) + { + + if (anim.sexTypes.Contains((pawn.jobs.curDriver as JobDriver_Sex).Sexprops.sexType)) + { + //SemenHelper.calculateAndApplySemen((pawn.jobs.curDriver as JobDriver_Sex).Sexprops); + } + } + } + public void calculateDrawValues() { /*if(Find.TickManager.TickRateMultiplier > 1 && (lastDrawFrame + 1 >= RealTime.frameCount || RealTime.deltaTime < 0.05f)) { @@ -268,9 +358,11 @@ namespace Rimworld_Animations { deltaPos = new Vector3(clip.BodyOffsetX.Evaluate(clipPercent) * (mirror ? -1 : 1), clip.layer.AltitudeFor(), clip.BodyOffsetZ.Evaluate(clipPercent)); - if (AnimationSettings.offsets != null && AnimationSettings.offsets.ContainsKey(CurrentAnimation.defName + pawn.def.defName + ActorIndex)) { - deltaPos.x += AnimationSettings.offsets[CurrentAnimation.defName + pawn.def.defName + ActorIndex].x * (mirror ? -1 : 1); - deltaPos.z += AnimationSettings.offsets[CurrentAnimation.defName + pawn.def.defName + ActorIndex].y; + string bodyTypeDef = (pawn.story?.bodyType != null) ? pawn.story.bodyType.ToString() : ""; + + if (AnimationSettings.offsets != null && AnimationSettings.offsets.ContainsKey(CurrentAnimation.defName + pawn.def.defName + bodyTypeDef + ActorIndex)) { + deltaPos.x += AnimationSettings.offsets[CurrentAnimation.defName + pawn.def.defName + bodyTypeDef + ActorIndex].x * (mirror ? -1 : 1); + deltaPos.z += AnimationSettings.offsets[CurrentAnimation.defName + pawn.def.defName + bodyTypeDef + ActorIndex].y; } @@ -281,8 +373,8 @@ namespace Rimworld_Animations { genitalAngle = clip.GenitalAngle.Evaluate(clipPercent) * (mirror ? -1 : 1); } - if (AnimationSettings.rotation != null && AnimationSettings.rotation.ContainsKey(CurrentAnimation.defName + pawn.def.defName + ActorIndex)) { - float offsetRotation = AnimationSettings.rotation[CurrentAnimation.defName + pawn.def.defName + ActorIndex] * (Mirror ? -1 : 1); + if (AnimationSettings.rotation != null && AnimationSettings.rotation.ContainsKey(CurrentAnimation.defName + pawn.def.defName + bodyTypeDef + ActorIndex)) { + float offsetRotation = AnimationSettings.rotation[CurrentAnimation.defName + pawn.def.defName + bodyTypeDef + ActorIndex] * (Mirror ? -1 : 1); genitalAngle += offsetRotation; bodyAngle += offsetRotation; headAngle += offsetRotation; @@ -290,6 +382,7 @@ namespace Rimworld_Animations { //don't go past 360 or less than 0 + if (bodyAngle < 0) bodyAngle = 360 - ((-1f*bodyAngle) % 360); if (bodyAngle > 360) bodyAngle %= 360; @@ -298,7 +391,7 @@ namespace Rimworld_Animations { if (headAngle > 360) headAngle %= 360; if (genitalAngle < 0) genitalAngle = 360 - ((-1f * genitalAngle) % 360); - if (genitalAngle > 360) genitalAngle %= 360; + if (genitalAngle > 360) genitalAngle %= 360; bodyFacing = mirror ? new Rot4((int)clip.BodyFacing.Evaluate(clipPercent)).Opposite : new Rot4((int)clip.BodyFacing.Evaluate(clipPercent)); @@ -326,6 +419,11 @@ namespace Rimworld_Animations { } + public Vector3 getPawnHeadOffset() + { + return Quaternion.AngleAxis(bodyAngle, Vector3.up) * (pawn.Drawer.renderer.BaseHeadOffsetAt(headFacing) + headBob); + + } public AnimationDef CurrentAnimation { get { @@ -342,33 +440,88 @@ namespace Rimworld_Animations { public override void PostExposeData() { base.PostExposeData(); - Scribe_Defs.Look(ref anim, "anim"); + Scribe_Defs.Look(ref anim, "RJWAnimations-Anim"); - Scribe_Values.Look(ref animTicks, "animTicks", 1); - Scribe_Values.Look(ref stageTicks, "stageTicks", 1); - Scribe_Values.Look(ref clipTicks, "clipTicks", 1); - Scribe_Values.Look(ref clipPercent, "clipPercent", 1); + Scribe_Values.Look(ref animTicks, "RJWAnimations-animTicks", 1); + Scribe_Values.Look(ref stageTicks, "RJWAnimations-stageTicks", 1); + Scribe_Values.Look(ref clipTicks, "RJWAnimations-clipTicks", 1); + Scribe_Values.Look(ref clipPercent, "RJWAnimations-clipPercent", 1); + Scribe_Values.Look(ref mirror, "RJWAnimations-mirror"); - Scribe_Values.Look(ref mirror, "mirror"); + Scribe_Values.Look(ref curStage, "RJWAnimations-curStage", 0); + Scribe_Values.Look(ref actor, "RJWAnimations-actor"); - Scribe_Values.Look(ref curStage, "curStage", 0); - Scribe_Values.Look(ref actor, "actor"); + Scribe_Values.Look(ref anchor, "RJWAnimations-anchor"); + Scribe_Values.Look(ref deltaPos, "RJWAnimations-deltaPos"); + Scribe_Values.Look(ref headBob, "RJWAnimations-headBob"); + Scribe_Values.Look(ref bodyAngle, "RJWAnimations-bodyAngle"); + Scribe_Values.Look(ref headAngle, "RJWAnimations-headAngle"); - Scribe_Values.Look(ref Animating, "Animating"); - Scribe_Values.Look(ref anchor, "anchor"); - Scribe_Values.Look(ref deltaPos, "deltaPos"); - Scribe_Values.Look(ref headBob, "headBob"); - Scribe_Values.Look(ref bodyAngle, "bodyAngle"); - Scribe_Values.Look(ref headAngle, "headAngle"); + Scribe_Values.Look(ref genitalAngle, "RJWAnimations-GenitalAngle"); + Scribe_Values.Look(ref controlGenitalAngle, "RJWAnimations-controlGenitalAngle"); - Scribe_Values.Look(ref genitalAngle, "GenitalAngle"); - Scribe_Values.Look(ref controlGenitalAngle, "controlGenitalAngle"); + Scribe_Values.Look(ref headFacing, "RJWAnimations-headFacing"); + Scribe_Values.Look(ref headFacing, "RJWAnimations-bodyFacing"); - Scribe_Values.Look(ref headFacing, "headFacing"); - Scribe_Values.Look(ref headFacing, "bodyFacing"); - - Scribe_Values.Look(ref quiver, "orgasmQuiver"); + Scribe_Values.Look(ref quiver, "RJWAnimations-orgasmQuiver"); } + public void shiftActorPositionAndRestartAnimation() { + actor = (actor == anim.actors.Count - 1 ? 0 : actor + 1); + + if (pawn?.story?.bodyType != null) { + if (pawn.story.bodyType == BodyTypeDefOf.Fat && anim?.actors[actor]?.bodyTypeOffset?.Fat != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Fat.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Fat.Value.y; + } + else if (pawn.story.bodyType == BodyTypeDefOf.Female && anim?.actors[actor]?.bodyTypeOffset?.Female != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Female.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Female.Value.y; + } + else if (pawn.story.bodyType == BodyTypeDefOf.Male && anim?.actors[actor]?.bodyTypeOffset?.Male != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Male.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Male.Value.y; + } + else if (pawn.story.bodyType == BodyTypeDefOf.Thin && anim?.actors[actor]?.bodyTypeOffset?.Thin != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Thin.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Thin.Value.y; + } + else if (pawn.story.bodyType == BodyTypeDefOf.Hulk && anim?.actors[actor]?.bodyTypeOffset?.Hulk != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Hulk.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Hulk.Value.y; + } + } + + curStage = 0; + animTicks = 0; + stageTicks = 0; + clipTicks = 0; + + controlGenitalAngle = anim.actors[actor].controlGenitalAngle; + + tickAnim(); + } + + 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) + { + return true; + } + + return false; + } + + public void ResetOnLoop() + { + curStage = 1; + animTicks = 0; + stageTicks = 0; + clipTicks = 0; + + tickAnim(); + } } } diff --git a/Source/Comps/CompProperties_BodyAnimator.cs b/1.3/Source/Comps/CompProperties_BodyAnimator.cs similarity index 68% rename from Source/Comps/CompProperties_BodyAnimator.cs rename to 1.3/Source/Comps/CompProperties_BodyAnimator.cs index cc40925..09df7ce 100644 --- a/Source/Comps/CompProperties_BodyAnimator.cs +++ b/1.3/Source/Comps/CompProperties_BodyAnimator.cs @@ -7,10 +7,10 @@ using Verse; using RimWorld; namespace Rimworld_Animations { - class CompProperties_BodyAnimator : CompProperties + public class CompProperties_BodyAnimator : CompProperties { - public CompProperties_BodyAnimator() { - + public CompProperties_BodyAnimator() + { base.compClass = typeof(CompBodyAnimator); } } diff --git a/1.3/Source/Comps/CompProperties_ThingAnimator.cs b/1.3/Source/Comps/CompProperties_ThingAnimator.cs new file mode 100644 index 0000000..34c67b1 --- /dev/null +++ b/1.3/Source/Comps/CompProperties_ThingAnimator.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace Rimworld_Animations { + public class CompProperties_ThingAnimator : CompProperties + { + + public CompProperties_ThingAnimator() + { + base.compClass = typeof(CompThingAnimator); + } + } +} diff --git a/1.3/Source/Comps/CompThingAnimator.cs b/1.3/Source/Comps/CompThingAnimator.cs new file mode 100644 index 0000000..f5315e4 --- /dev/null +++ b/1.3/Source/Comps/CompThingAnimator.cs @@ -0,0 +1,245 @@ +using RimWorld; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace Rimworld_Animations { + public class CompThingAnimator : ThingComp + { + Vector3 anchor; + + Pawn pawn; + + public bool isAnimating = false, mirror; + + int animTicks = 0, stageTicks = 0, clipTicks = 0, curStage = 0; + float rotation = 0; + float clipPercent = 0; + + public Vector3 deltaPos; + + AnimationDef anim; + private ThingAnimationClip clip => (ThingAnimationClip)stage.animationClips[1]; + private AnimationStage stage + { + get + { + return anim.animationStages[curStage]; + } + + } + + public void StartAnimation(AnimationDef anim, Pawn pawn, bool mirror = false) + { + isAnimating = true; + + this.anim = anim; + this.pawn = pawn; + this.mirror = mirror; + + animTicks = 0; + stageTicks = 0; + clipTicks = 0; + + curStage = 0; + clipPercent = 0; + + tickAnim(); + + } + + public void setAnchor(IntVec3 position) + { + anchor = position.ToVector3(); + } + + public override void CompTick() + { + base.CompTick(); + + if(isAnimating) + { + if (pawn.Dead || pawn?.jobs?.curDriver == null || (pawn?.jobs?.curDriver != null && !(pawn?.jobs?.curDriver is rjw.JobDriver_Sex))) + { + isAnimating = false; + } + else + { + tickAnim(); + } + } + + + } + + public void tickAnim() + { + if (!isAnimating) return; + animTicks++; + + if (animTicks < anim.animationTimeTicks) + { + tickStage(); + } + else + { + if (LoopNeverending()) + { + ResetOnLoop(); + } + else + { + isAnimating = false; + } + + + } + + } + + public void tickStage() + { + if (stage == null) + { + isAnimating = false; + return; + } + + stageTicks++; + + if (stageTicks >= stage.playTimeTicks) + { + + curStage++; + + stageTicks = 0; + clipTicks = 0; + clipPercent = 0; + } + + if (curStage >= anim.animationStages.Count) + { + if (LoopNeverending()) + { + ResetOnLoop(); + } + else + { + isAnimating = false; + } + + } + else + { + tickClip(); + } + } + + public void tickClip() + { + clipTicks++; + + if (clipPercent >= 1 && stage.isLooping) + { + clipTicks = 1;//warning: don't set to zero or else calculations go wrong + } + clipPercent = (float)clipTicks / (float)clip.duration; + + calculateDrawValues(); + } + + public void setAnchor(Thing thing) + { + + //center on bed + if (thing is Building_Bed) + { + anchor = thing.Position.ToVector3(); + if (((Building_Bed)thing).SleepingSlotsCount == 2) + { + if (thing.Rotation.AsInt == 0) + { + anchor.x += 1; + anchor.z += 1; + } + else if (thing.Rotation.AsInt == 1) + { + anchor.x += 1; + } + else if (thing.Rotation.AsInt == 3) + { + anchor.z += 1; + } + + } + else + { + if (thing.Rotation.AsInt == 0) + { + anchor.x += 0.5f; + anchor.z += 1f; + } + else if (thing.Rotation.AsInt == 1) + { + anchor.x += 1f; + anchor.z += 0.5f; + } + else if (thing.Rotation.AsInt == 2) + { + anchor.x += 0.5f; + } + else + { + anchor.z += 0.5f; + } + } + } + else + { + anchor = thing.Position.ToVector3Shifted(); + } + + anchor -= new Vector3(0.5f, 0, 0.5f); + } + private void calculateDrawValues() + { + + //shift up and right 0.5f to align center + deltaPos = new Vector3((clip.PositionX.Evaluate(clipPercent)) * (mirror ? -1 : 1) + 0.5f, AltitudeLayer.Item.AltitudeFor(), clip.PositionZ.Evaluate(clipPercent) + 0.5f); + //Log.Message("Clip percent: " + clipPercent + " deltaPos: " + deltaPos); + rotation = clip.Rotation.Evaluate(clipPercent) * (mirror ? -1 : 1); + } + + public void AnimateThing(Thing thing) + { + thing.Graphic.Draw(deltaPos + anchor, mirror ? Rot4.West : Rot4.East, thing, rotation); + } + + public bool LoopNeverending() + { + if (pawn?.jobs?.curDriver != null && + (pawn.jobs.curDriver is JobDriver_Sex) && (pawn.jobs.curDriver as JobDriver_Sex).neverendingsex) + { + return true; + } + + return false; + } + + public void ResetOnLoop() + { + curStage = 1; + animTicks = 0; + stageTicks = 0; + clipTicks = 0; + + tickAnim(); + } + + } +} diff --git a/Source/Defs/AnimationDef.cs b/1.3/Source/Defs/AnimationDef.cs similarity index 80% rename from Source/Defs/AnimationDef.cs rename to 1.3/Source/Defs/AnimationDef.cs index 064f10b..395ff83 100644 --- a/Source/Defs/AnimationDef.cs +++ b/1.3/Source/Defs/AnimationDef.cs @@ -13,7 +13,9 @@ namespace Rimworld_Animations { public List actors; public int animationTimeTicks = 0; //do not set manually public bool sounds = false; - public List sexTypes; + public List sexTypes = null; + public List interactionDefTypes = null; + public List tags = new List(); public override void PostLoad() { base.PostLoad(); diff --git a/1.3/Source/Extensions/PawnWoundDrawerExtension.cs b/1.3/Source/Extensions/PawnWoundDrawerExtension.cs new file mode 100644 index 0000000..4901de2 --- /dev/null +++ b/1.3/Source/Extensions/PawnWoundDrawerExtension.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using RimWorld; +using UnityEngine; +using Verse; +using Rimworld_Animations; + +namespace Rimworld_Animations +{ + [StaticConstructorOnStartup] + public static class PawnWoundDrawerExtension + { + public static void RenderOverBody(this PawnWoundDrawer pawnWoundDrawer, Vector3 drawLoc, Mesh bodyMesh, Quaternion quat, bool drawNow, BodyTypeDef.WoundLayer layer, Rot4 pawnRot, bool? overApparel = null, Pawn pawn = null, PawnRenderFlags flags = new PawnRenderFlags()) + { + if (pawn == null) + { return; } + + if (!flags.FlagSet(PawnRenderFlags.Portrait) && layer == BodyTypeDef.WoundLayer.Head) + { + CompBodyAnimator pawnAnimator = pawn.TryGetComp(); + if (pawnAnimator != null && pawnAnimator.isAnimating && pawn.Drawer.renderer.graphics.headGraphic != null) + { + pawnRot = pawnAnimator.headFacing; + quat = Quaternion.AngleAxis(angle: pawnAnimator.headAngle, axis: Vector3.up); + float y = drawLoc.y; + drawLoc = pawnAnimator.getPawnHeadPosition() - Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up) * pawn.Drawer.renderer.BaseHeadOffsetAt(pawnAnimator.headFacing); + drawLoc.y = y; + } + } + + pawnWoundDrawer.RenderOverBody(drawLoc, bodyMesh, quat, drawNow, layer, pawnRot, overApparel); + } + } +} diff --git a/1.3/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs b/1.3/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs new file mode 100644 index 0000000..b7fef1d --- /dev/null +++ b/1.3/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using RimWorld; +using UnityEngine; + +namespace Rimworld_Animations { + class MainTabWindow_OffsetConfigure : MainTabWindow + { + + public override Vector2 RequestedTabSize => new Vector2(505, 380); + public override void DoWindowContents(Rect inRect) { + + Rect position = new Rect(inRect.x, inRect.y, inRect.width, inRect.height); + + + Listing_Standard listingStandard = new Listing_Standard(); + listingStandard.Begin(position); + + listingStandard.Label("Animation Manager"); + + listingStandard.GapLine(); + + + if (Find.Selector.SingleSelectedThing is Pawn) { + + Pawn curPawn = Find.Selector.SingleSelectedThing as Pawn; + + if (curPawn.TryGetComp().isAnimating) { + + AnimationDef def = curPawn.TryGetComp().CurrentAnimation; + int ActorIndex = curPawn.TryGetComp().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().ActorIndex + " Body Type (if any): " + bodyTypeDef + " Animation: " + def.label + (curPawn.TryGetComp().Mirror ? " mirrored" : "")); + + if(curPawn.def.defName == "Human") { + listingStandard.Label("Warning--You generally don't want to change human offsets, only alien offsets"); + } + + bool mirrored = curPawn.TryGetComp().Mirror; + + float.TryParse(listingStandard.TextEntryLabeled("X Offset: ", offsetX.ToString()), out offsetX); + offsetX = listingStandard.Slider(offsetX, -2 * (mirrored ? -1 : 1), 2 * (mirrored ? -1 : 1)); + + 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().actorsInCurrentAnimation.Count; i++) { + + Pawn actor = curPawn.TryGetComp().actorsInCurrentAnimation[i]; + + actor.TryGetComp()?.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; + } + + } + + } + 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(); + } + + if(AnimationSettings.rotation == null) { + if (AnimationSettings.debugMode) + Log.Message("New rotation"); + AnimationSettings.rotation = new Dictionary(); + } + } + + public override void PostClose() { + base.PostClose(); + + LoadedModManager.GetMod().WriteSettings(); + } + } +} diff --git a/Source/MainTabWindows/OffsetMainButtonDefOf.cs b/1.3/Source/MainTabWindows/OffsetMainButtonDefOf.cs similarity index 100% rename from Source/MainTabWindows/OffsetMainButtonDefOf.cs rename to 1.3/Source/MainTabWindows/OffsetMainButtonDefOf.cs diff --git a/Source/MainTabWindows/WorldComponent_UpdateMainTab.cs b/1.3/Source/MainTabWindows/WorldComponent_UpdateMainTab.cs similarity index 100% rename from Source/MainTabWindows/WorldComponent_UpdateMainTab.cs rename to 1.3/Source/MainTabWindows/WorldComponent_UpdateMainTab.cs diff --git a/Source/Patches/Harmony_PatchAll.cs b/1.3/Source/Patches/Harmony_PatchAll.cs similarity index 87% rename from Source/Patches/Harmony_PatchAll.cs rename to 1.3/Source/Patches/Harmony_PatchAll.cs index 3a0a7bb..1c1d63f 100644 --- a/Source/Patches/Harmony_PatchAll.cs +++ b/1.3/Source/Patches/Harmony_PatchAll.cs @@ -14,7 +14,7 @@ namespace Rimworld_Animations { static Harmony_PatchAll() { - Harmony val = new Harmony("rimworldanim"); + Harmony val = new Harmony("rjwanim"); val.PatchAll(Assembly.GetExecutingAssembly()); } diff --git a/1.3/Source/Patches/OtherModPatches/HarmonyPatch_AlienRace.cs b/1.3/Source/Patches/OtherModPatches/HarmonyPatch_AlienRace.cs new file mode 100644 index 0000000..b7198da --- /dev/null +++ b/1.3/Source/Patches/OtherModPatches/HarmonyPatch_AlienRace.cs @@ -0,0 +1,397 @@ +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; +using AlienRace; + +namespace Rimworld_Animations { + + + [StaticConstructorOnStartup] + public static class HarmonyPatch_AlienRace + { + static HarmonyPatch_AlienRace() + { + (new Harmony("rjwanim")).Patch(AccessTools.Method(AccessTools.TypeByName("AlienRace.HarmonyPatches"), "DrawAddons"), + prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_AlienRace), "Prefix_AnimateHeadAddons"))); + } + + + public static bool Prefix_AnimateHeadAddons(PawnRenderFlags renderFlags, Vector3 vector /*rootloc*/, Vector3 headOffset, Pawn pawn, Quaternion quat, Rot4 rotation) + { + + if (renderFlags.FlagSet(PawnRenderFlags.Portrait) || pawn.TryGetComp() == null || !pawn.TryGetComp().isAnimating) return true; + if (!(pawn.def is ThingDef_AlienRace alienProps) || renderFlags.FlagSet(PawnRenderFlags.Invisible)) return false; + + List addons = alienProps.alienRace.generalSettings.alienPartGenerator.bodyAddons; + AlienPartGenerator.AlienComp comp = pawn.GetComp(); + CompBodyAnimator pawnAnimator = pawn.TryGetComp(); + + for (int i = 0; i < addons.Count; i++) + { + AlienPartGenerator.BodyAddon ba = addons[index: i]; + + if (!ba.CanDrawAddon(pawn: pawn)) continue; + + 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, comp.crownType) : Vector3.zero; + AlienPartGenerator.RotationOffset offset2 = ba.offsets.GetOffset((ba.drawnInBed && !forceDrawForBody) || ba.alignWithHead ? pawnAnimator.headFacing : pawnAnimator.bodyFacing); + Vector3 vector2 = a + ((offset2 != null) ? offset2.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, comp.crownType) : Vector3.zero); + vector2.y = (ba.inFrontOfBody ? (0.3f + vector2.y) : (-0.3f - vector2.y)); + float num = ba.angle; + if (rotation == Rot4.North) + { + if (ba.layerInvert) + { + vector2.y = 0f - vector2.y; + } + num = 0f; + } + if (rotation == Rot4.East) + { + num = 0f - num; + vector2.x = 0f - vector2.x; + } + Graphic addonGraphic = comp.addonGraphics[i]; + + addonGraphic.drawSize = ((renderFlags.FlagSet(PawnRenderFlags.Portrait) && ba.drawSizePortrait != Vector2.zero) ? ba.drawSizePortrait : ba.drawSize) * (ba.scaleWithPawnDrawsize ? (ba.alignWithHead ? (renderFlags.FlagSet(PawnRenderFlags.Portrait) ? comp.customPortraitHeadDrawSize : comp.customHeadDrawSize) : (renderFlags.FlagSet(PawnRenderFlags.Portrait) ? comp.customPortraitDrawSize : comp.customDrawSize)) : Vector2.one) * 1.5f; + + Vector3 orassanv = Vector3.zero; + bool orassan = false; + if ((pawn.def as ThingDef_AlienRace).defName == "Alien_Orassan") + { + orassan = true; + + if (ba.path.Contains("closed")) + { + continue; + } + + if (ba.bodyPart.Contains("ear")) + + { + orassan = true; + + orassanv = new Vector3(0, 0, 0.23f); + if (pawnAnimator.headFacing == Rot4.North) + { + orassanv.z -= 0.1f; + orassanv.y += 1f; + + if (ba.bodyPart.Contains("left")) + { + orassanv.x += 0.03f; + } + else + { + orassanv.x -= 0.03f; + } + + } + else if (pawnAnimator.headFacing == Rot4.East) + { + orassanv.x -= 0.1f; + } + else if (pawnAnimator.headFacing == Rot4.West) + { + orassanv.x = 0.1f; + } + else + { + orassanv.z -= 0.1f; + orassanv.y += 1f; + + if (ba.bodyPart.Contains("right")) + { + //orassanv.x += 0.3f; + } + else + { + //orassanv.x -= 0.3f; + } + } + orassanv = orassanv.RotatedBy(pawnAnimator.headAngle); + } + } + + + if ((ba.drawnInBed && !forceDrawForBody) || ba.alignWithHead) + { + + Quaternion addonRotation = Quaternion.AngleAxis(pawnAnimator.headAngle < 0 ? 360 - (360 % pawnAnimator.headAngle) : pawnAnimator.headAngle, Vector3.up); + /* + * + * genital rotation is borked + 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"))) + { + addonRotation = Quaternion.AngleAxis(angle: pawnAnimator.genitalAngle < 0 ? 360 - (360 % pawnAnimator.genitalAngle) : pawnAnimator.genitalAngle, axis: Vector3.up); + } + + */ + + GenDraw.DrawMeshNowOrLater(mesh: addonGraphic.MeshAt(rot: pawnAnimator.headFacing), loc: vector /*rootloc*/ + orassanv + (ba.alignWithHead && !orassan ? headOffset : headOffset - addonRotation * pawn.Drawer.renderer.BaseHeadOffsetAt(pawnAnimator.headFacing)) + 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: pawnAnimator.headFacing), renderFlags.FlagSet(PawnRenderFlags.DrawNow)); + + + } + + else + { + Quaternion 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)); + } + + 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)); + } + + } + + + } + + return false; + } + } + + [HarmonyPatch(typeof(PawnGraphicSet), "ResolveApparelGraphics")] + public static class HarmonyPatch_ResolveApparelGraphics + { + public static bool Prefix(ref Pawn ___pawn) + { + + if (___pawn.TryGetComp() != null && ___pawn.TryGetComp().isAnimating) + { + return false; + } + return true; + } + } + + /* + + [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(); + AlienPartGenerator.AlienComp comp = pawn.GetComp(); + + 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; + AlienPartGenerator.RotationOffset offset2 = bodyAddon.offsets.GetOffset(rotation); + Vector3 vector2 = a + ((offset2 != null) ? offset2.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, comp.crownType) : Vector3.zero); + vector2.y = (bodyAddon.inFrontOfBody ? (0.3f + vector2.y) : (-0.3f - vector2.y)); + float num = bodyAddon.angle; + if (rotation == Rot4.North) + { + if (bodyAddon.layerInvert) + { + vector2.y = -vector2.y; + } + num = 0f; + } + if (rotation == Rot4.East) + { + num = -num; + vector2.x = -vector2.x; + } + + vector = vector + Quaternion.AngleAxis(pawnAnimator.bodyAngle, Vector3.up) * pawn.Drawer.renderer.BaseHeadOffsetAt(pawnAnimator.bodyFacing) - pawnAnimator.getPawnHeadOffset(); //convert vector into pseudo body pos for head + quat = Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up); + loc = vector + (bodyAddon.alignWithHead ? headOffset : Vector3.zero) + vector2.RotatedBy(Mathf.Acos(Quaternion.Dot(Quaternion.identity, quat)) * 2f * 57.29578f); + 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; + AlienPartGenerator.RotationOffset offset2 = bodyAddon.offsets.GetOffset(rotation); + Vector3 vector2 = a + ((offset2 != null) ? offset2.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, comp.crownType) : Vector3.zero); + vector2.y = (bodyAddon.inFrontOfBody ? (0.3f + vector2.y) : (-0.3f - vector2.y)); + float num = bodyAddon.angle; + if (rotation == Rot4.North) + { + if (bodyAddon.layerInvert) + { + vector2.y = -vector2.y; + } + num = 0f; + } + if (rotation == Rot4.East) + { + num = -num; + vector2.x = -vector2.x; + } + quat = Quaternion.AngleAxis(pawnAnimator.bodyAngle, Vector3.up); + loc = vector + (bodyAddon.alignWithHead ? headOffset : Vector3.zero) + vector2.RotatedBy(Mathf.Acos(Quaternion.Dot(Quaternion.identity, quat)) * 2f * 57.29578f); + + } + + } + GenDraw.DrawMeshNowOrLater(mesh, loc, quat, mat, drawNow); + + /* + 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")) + + { + orassan = true; + + orassanv = new Vector3(0, 0, 0.23f); + if (pawnAnimator.headFacing == Rot4.North) + { + orassanv.z -= 0.1f; + orassanv.y += 1f; + + if(bodyAddon.bodyPart.Contains("left")) + { + orassanv.x += 0.03f; + } else + { + orassanv.x -= 0.03f; + } + + } + else if (pawnAnimator.headFacing == Rot4.East) + { + orassanv.x -= 0.1f; + } + else if (pawnAnimator.headFacing == Rot4.West) + { + orassanv.x = 0.1f; + } + else + { + orassanv.z -= 0.1f; + orassanv.y += 1f; + + if (bodyAddon.bodyPart.Contains("right")) + { + orassanv.x += 0.05f; + } + else + { + orassanv.x -= 0.05f; + } + } + orassanv = orassanv.RotatedBy(pawnAnimator.headAngle); + } + } + + + + + + GenDraw.DrawMeshNowOrLater(mesh: graphic.MeshAt(rot: headRotInAnimation), loc: loc + orassanv + (bodyAddon.alignWithHead ? headOffset : Vector3.zero),// + v.RotatedBy(Mathf.Acos(Quaternion.Dot(Quaternion.identity, quat)) * 2f * 57.29578f), + quat: Quaternion.AngleAxis(angle: num, axis: Vector3.up) * headQuatInAnimation, mat: graphic.MatAt(rot: pawnAnimator.headFacing), drawNow: drawNow);; + } + + else + { + + } + + + } + + + public static IEnumerable Transpiler(IEnumerable instructions) + { + List 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 + yield return new CodeInstruction(OpCodes.Ldloc, (object)5); //offsetVector/AddonOffset (v) + yield return new CodeInstruction(OpCodes.Ldarg, (object)2); //headOffset + yield return new CodeInstruction(OpCodes.Ldarg, (object)3); //pawn + yield return new CodeInstruction(OpCodes.Ldarg, (object)0); //renderflags + yield return new CodeInstruction(OpCodes.Ldarg, (object)1); //vector + yield return new CodeInstruction(OpCodes.Ldarg, (object)5); //rotation + + 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(); + + if(anim == null) + { + return true; + } + + if (anim != null && !renderFlags.FlagSet(PawnRenderFlags.Portrait) && anim.isAnimating) + { + //quat = Quaternion.AngleAxis(anim.bodyAngle, Vector3.up); + } + + return true; + + } + } + + + */ + +} + + diff --git a/Source/Patches/HarmonyPatch_CSL.cs b/1.3/Source/Patches/OtherModPatches/HarmonyPatch_CSL.cs similarity index 100% rename from Source/Patches/HarmonyPatch_CSL.cs rename to 1.3/Source/Patches/OtherModPatches/HarmonyPatch_CSL.cs diff --git a/Source/Patches/HarmonyPatch_DontShaveYourHead.cs b/1.3/Source/Patches/OtherModPatches/HarmonyPatch_DontShaveYourHead.cs similarity index 71% rename from Source/Patches/HarmonyPatch_DontShaveYourHead.cs rename to 1.3/Source/Patches/OtherModPatches/HarmonyPatch_DontShaveYourHead.cs index fa5a5cc..3cb2a63 100644 --- a/Source/Patches/HarmonyPatch_DontShaveYourHead.cs +++ b/1.3/Source/Patches/OtherModPatches/HarmonyPatch_DontShaveYourHead.cs @@ -17,7 +17,7 @@ namespace Rimworld_Animations { ((Action)(() => { if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "Don't Shave Your Head 1.0")) { - (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("DontShaveYourHead.Harmony_PawnRenderer"), "DrawHairReroute"), //typeof(ShowHair.Patch_PawnRenderer_RenderPawnInternal), nameof(ShowHair.Patch_PawnRenderer_RenderPawnInternal.Postfix)), + (new Harmony("rjwanim")).Patch(AccessTools.Method(AccessTools.TypeByName("DontShaveYourHead.Harmony_PawnRenderer"), "DrawHairReroute"), //typeof(ShowHair.Patch_PawnRenderer_RenderPawnInternal), nameof(ShowHair.Patch_PawnRenderer_RenderPawnInternal.Postfix)), transpiler: new HarmonyMethod(AccessTools.Method(typeof(Patch_ShowHairWithHats), "Transpiler"))); } }))(); diff --git a/Source/Patches/HarmonyPatch_FacialAnimation.cs b/1.3/Source/Patches/OtherModPatches/HarmonyPatch_FacialAnimation.cs similarity index 77% rename from Source/Patches/HarmonyPatch_FacialAnimation.cs rename to 1.3/Source/Patches/OtherModPatches/HarmonyPatch_FacialAnimation.cs index 6d561de..83ffd5b 100644 --- a/Source/Patches/HarmonyPatch_FacialAnimation.cs +++ b/1.3/Source/Patches/OtherModPatches/HarmonyPatch_FacialAnimation.cs @@ -18,15 +18,8 @@ namespace Rimworld_Animations { try { ((Action)(() => { if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "[NL] Facial Animation - WIP")) { - (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("FacialAnimation.DrawFaceGraphicsComp"), "DrawGraphics"), + (new Harmony("rjwanim")).Patch(AccessTools.Method(AccessTools.TypeByName("FacialAnimation.DrawFaceGraphicsComp"), "DrawGraphics"), prefix: new HarmonyMethod(AccessTools.Method(typeof(Patch_FacialAnimation), "Prefix"))); - - - (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("FacialAnimation.FaceAnimationDef"), "IsSame", new Type[] { typeof(JobDef) }), - prefix: new HarmonyMethod(AccessTools.Method(typeof(Patch_FacialAnimation), "Prefix_IsSameA"))); - - (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("FacialAnimation.FaceAnimationDef"), "IsSame", new Type[] { typeof(string) }), - prefix: new HarmonyMethod(AccessTools.Method(typeof(Patch_FacialAnimation), "Prefix_IsSameB"))); } }))(); } @@ -48,7 +41,7 @@ namespace Rimworld_Animations { return true; } - + /* public static List rjwLovinDefNames = new List{ "Lovin", "Quickie", @@ -72,6 +65,11 @@ namespace Rimworld_Animations { "UseFM" }; + public static List rjwRapeDefNames = new List { + "RapeComfortPawn", + "RandomRape", + "RapeEnemy" + }; public static bool Prefix_IsSameA(JobDef job, string ___jobDef, ref bool __result) { @@ -79,6 +77,11 @@ namespace Rimworld_Animations { __result = true; return false; } + else if (___jobDef != null && ___jobDef == "Wait_Combat" && job?.defName != null && rjwRapeDefNames.Contains(job?.defName)) { + __result = true; + return false; + } + return true; } @@ -89,8 +92,13 @@ namespace Rimworld_Animations { __result = true; return false; } + if (___jobDef != null && ___jobDef == "Wait_Combat" && jobName != null && rjwRapeDefNames.Contains(jobName)) { + __result = true; + return false; + } return true; } + */ } -} +} \ No newline at end of file diff --git a/1.3/Source/Patches/OtherModPatches/HarmonyPatch_HatsDisplaySelection.cs b/1.3/Source/Patches/OtherModPatches/HarmonyPatch_HatsDisplaySelection.cs new file mode 100644 index 0000000..1cd5707 --- /dev/null +++ b/1.3/Source/Patches/OtherModPatches/HarmonyPatch_HatsDisplaySelection.cs @@ -0,0 +1,77 @@ +/*using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using RimWorld; +using Verse; +using UnityEngine; +using System.Reflection; +using System.Reflection.Emit; + +namespace Rimworld_Animations { + public static class HarmonyPatch_HatsDisplaySelection { + + public static void PatchHatsDisplaySelectionArgs() { + (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("HatDisplaySelection.Patch"), "DrawHatCEWithHair"), + transpiler: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_HatsDisplaySelection), "ReplaceDrawMeshOrLaterWithAnimate"))); + + (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("HatDisplaySelection.Patch"), "DrawHatWithHair"), + transpiler: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_HatsDisplaySelection), "ReplaceDrawMeshOrLaterWithAnimate"))); + + (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("HatDisplaySelection.Patch"), "DrawHeadApparelWithHair"), + prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_HatsDisplaySelection), "PrefixPatchForDrawHeadApparelWithHair"))); + + + } + + public static void PrefixPatchForDrawHeadApparelWithHair(PawnRenderer renderer, ref Vector3 rootLoc, ref float angle, bool renderBody, ref Rot4 bodyFacing, ref Rot4 headFacing, RotDrawMode bodyDrawType, bool portrait, bool headStump, bool invisible) + { + PawnGraphicSet graphics = renderer.graphics; + Pawn pawn = graphics.pawn; + CompBodyAnimator bodyAnim = pawn.TryGetComp(); + + if (!graphics.AllResolved) + { + graphics.ResolveAllGraphics(); + } + + + if (bodyAnim != null && bodyAnim.isAnimating && !portrait && pawn.Map == Find.CurrentMap) + { + bodyAnim.tickGraphics(graphics); + bodyAnim.animatePawn(ref rootLoc, ref angle, ref bodyFacing, ref headFacing); + + } + } + + + public static IEnumerable ReplaceDrawMeshOrLaterWithAnimate(IEnumerable instructions) { + + MethodInfo drawMeshNowOrLater = AccessTools.Method(typeof(GenDraw), "DrawMeshNowOrLater"); + List codes = instructions.ToList(); + for (int i = 0; i < instructions.Count(); i++) { + + + if (codes[i]. + + +(drawMeshNowOrLater)) { + + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(AccessTools.TypeByName("HatDisplaySelection.Patch"), "pawn")); + yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(AnimationUtility), nameof(AnimationUtility.RenderPawnHeadMeshInAnimation), new Type[] { typeof(Mesh), typeof(Vector3), typeof(Quaternion), typeof(Material), typeof(bool), typeof(Pawn) })); + + } + else { + yield return codes[i]; + } + + } + + } + + } +} +*/ \ No newline at end of file diff --git a/Source/Patches/HarmonyPatch_ShowHairWithHats.cs b/1.3/Source/Patches/OtherModPatches/HarmonyPatch_ShowHairWithHats.cs similarity index 86% rename from Source/Patches/HarmonyPatch_ShowHairWithHats.cs rename to 1.3/Source/Patches/OtherModPatches/HarmonyPatch_ShowHairWithHats.cs index 3714503..a42ab7d 100644 --- a/Source/Patches/HarmonyPatch_ShowHairWithHats.cs +++ b/1.3/Source/Patches/OtherModPatches/HarmonyPatch_ShowHairWithHats.cs @@ -18,7 +18,7 @@ namespace Rimworld_Animations { ((Action)(() => { if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "[KV] Show Hair With Hats or Hide All Hats - 1.1")) { - (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("ShowHair.Patch_PawnRenderer_RenderPawnInternal"), "Postfix"), //typeof(ShowHair.Patch_PawnRenderer_RenderPawnInternal), nameof(ShowHair.Patch_PawnRenderer_RenderPawnInternal.Postfix)), + (new Harmony("rjwanim")).Patch(AccessTools.Method(AccessTools.TypeByName("ShowHair.Patch_PawnRenderer_RenderPawnInternal"), "Postfix"), //typeof(ShowHair.Patch_PawnRenderer_RenderPawnInternal), nameof(ShowHair.Patch_PawnRenderer_RenderPawnInternal.Postfix)), transpiler: new HarmonyMethod(AccessTools.Method(typeof(Patch_ShowHairWithHats), "Transpiler"))); } }))(); diff --git a/1.3/Source/Patches/RJWPatches/HarmonyPatch_PlaySexSounds.cs b/1.3/Source/Patches/RJWPatches/HarmonyPatch_PlaySexSounds.cs new file mode 100644 index 0000000..6544f13 --- /dev/null +++ b/1.3/Source/Patches/RJWPatches/HarmonyPatch_PlaySexSounds.cs @@ -0,0 +1,25 @@ +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 +{ + [HarmonyPatch(typeof(JobDriver_Sex), "PlaySexSound")] + class HarmonyPatch_PlaySexSounds + { + public static bool Prefix(JobDriver_Sex __instance) + { + if (__instance.pawn.TryGetComp().isAnimating) + { + return false; + } + + return true; + } + } +} diff --git a/1.3/Source/Patches/RJWPatches/HarmonyPatch_SexTick.cs b/1.3/Source/Patches/RJWPatches/HarmonyPatch_SexTick.cs new file mode 100644 index 0000000..9ba03b2 --- /dev/null +++ b/1.3/Source/Patches/RJWPatches/HarmonyPatch_SexTick.cs @@ -0,0 +1,61 @@ +using HarmonyLib; +using RimWorld; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using Verse.AI; + +namespace Rimworld_Animations +{ + [HarmonyPatch(typeof(JobDriver_Sex), "SexTick")] + public class HarmonyPatch_SexTick + { + public static bool Prefix(JobDriver_Sex __instance, Pawn pawn, Thing target) + { + + if ((target is Pawn) && + !( + (target as Pawn)?.jobs?.curDriver is JobDriver_SexBaseReciever + && + ((target as Pawn).jobs.curDriver as JobDriver_SexBaseReciever).parteners.Any() + && + ((target as Pawn).jobs.curDriver as JobDriver_SexBaseReciever).parteners[0] == pawn)) + { + + __instance.ticks_left--; + __instance.sex_ticks--; + __instance.Orgasm(); + + + if (pawn.IsHashIntervalTick(__instance.ticks_between_thrusts)) + { + __instance.ChangePsyfocus(pawn, target); + __instance.Animate(pawn, target); + __instance.PlaySexSound(); + if (!__instance.Sexprops.isRape) + { + pawn.GainComfortFromCellIfPossible(false); + if (target is Pawn) + { + (target as Pawn).GainComfortFromCellIfPossible(false); + } + } + if(!__instance.isEndytophile) + { + SexUtility.DrawNude(pawn, false); + } + } + + return false; + } + + return true; + } + + } + +} diff --git a/Source/Patches/rjwPatches/HarmonyPatch_WorkGiverSex.cs b/1.3/Source/Patches/RJWPatches/HarmonyPatch_WorkGiverSex.cs similarity index 98% rename from Source/Patches/rjwPatches/HarmonyPatch_WorkGiverSex.cs rename to 1.3/Source/Patches/RJWPatches/HarmonyPatch_WorkGiverSex.cs index 5b7479f..af4a755 100644 --- a/Source/Patches/rjwPatches/HarmonyPatch_WorkGiverSex.cs +++ b/1.3/Source/Patches/RJWPatches/HarmonyPatch_WorkGiverSex.cs @@ -10,7 +10,7 @@ using RimWorld; using Verse.AI; namespace Rimworld_Animations { - + /* [HarmonyPatch(typeof(WorkGiver_Sex), "JobOnThing")] public static class HarmonyPatch_WorkGiverSex { @@ -26,4 +26,6 @@ namespace Rimworld_Animations { } } + + */ } diff --git a/1.3/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_JoinInBed.cs b/1.3/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_JoinInBed.cs new file mode 100644 index 0000000..18c955e --- /dev/null +++ b/1.3/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_JoinInBed.cs @@ -0,0 +1,84 @@ +using System; +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 +{ + + [HarmonyPatch(typeof(Bed_Utility), "in_same_bed")] + public static class HarmonyPatch_JobDriver_InSameBedPatch + { + + public static bool Prefix(Pawn partner, ref bool __result) + { + + if(partner != null && partner.CurJobDef == xxx.casual_sex) + { + __result = true; + return false; + } + + return true; + + } + + + + } + + [HarmonyPatch(typeof(JobDriver_JoinInBed), "MakeNewToils")] + public static class HarmonyPatch_JobDriver_JoinInBed + { + + public static void Postfix(JobDriver_JoinInBed __instance, ref IEnumerable __result) + { + + var toils = __result.ToList(); + + Toil goToPawnInBed = Toils_Goto.GotoThing(__instance.iTarget, PathEndMode.OnCell); + goToPawnInBed.FailOn(() => !RestUtility.InBed(__instance.Partner) && __instance.Partner.CurJobDef != xxx.gettin_loved && !Bed_Utility.in_same_bed(__instance.Partner, __instance.pawn)); + + toils[1] = goToPawnInBed; + + + Toil startPartnerSex = new Toil(); + startPartnerSex.initAction = delegate { + + + if (!(__instance.Partner.jobs.curDriver is JobDriver_SexBaseReciever)) // allows threesomes + { + Job gettinLovedJob = JobMaker.MakeJob(xxx.gettin_loved, __instance.pawn, __instance.Bed); // new gettin loved toil that wakes up the pawn goes here + __instance.Partner.jobs.jobQueue.EnqueueFirst(gettinLovedJob); + __instance.Partner.jobs.EndCurrentJob(JobCondition.InterruptForced); + } + + }; + + toils[2] = startPartnerSex; + + toils[3].AddPreTickAction(() => + { + if (!__instance.Partner.TryGetComp().isAnimating) + { + __instance.pawn.TryGetComp().isAnimating = false; + } + }); + + + __result = toils.AsEnumerable(); + + + } + + + + } +} diff --git a/Source/Patches/rjwPatches/HarmonyPatch_JobDriver_SexBaseInitiator.cs b/1.3/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseInitiator.cs similarity index 63% rename from Source/Patches/rjwPatches/HarmonyPatch_JobDriver_SexBaseInitiator.cs rename to 1.3/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseInitiator.cs index 04cdef2..260d924 100644 --- a/Source/Patches/rjwPatches/HarmonyPatch_JobDriver_SexBaseInitiator.cs +++ b/1.3/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseInitiator.cs @@ -13,7 +13,6 @@ namespace Rimworld_Animations { [HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "Start")] static class HarmonyPatch_JobDriver_SexBaseInitiator_Start { public static void Postfix(ref JobDriver_SexBaseInitiator __instance) { - /* These particular jobs need special code don't play anim for now @@ -22,49 +21,49 @@ namespace Rimworld_Animations { return; } + if(!AnimationSettings.PlayAnimForNonsexualActs && NonSexualAct(__instance)) + { + return; + } + Pawn pawn = __instance.pawn; Building_Bed bed = __instance.Bed; - /* - if (__instance is JobDriver_BestialityForFemale) - bed = (__instance as JobDriver_BestialityForFemale).Bed; - else if (__instance is JobDriver_WhoreIsServingVisitors) { - bed = (__instance as JobDriver_WhoreIsServingVisitors).Bed; - } - else if (__instance is JobDriver_SexCasualForAnimation) { - bed = (__instance as JobDriver_SexCasualForAnimation).Bed; - } - else if (__instance is JobDriver_Masturbate) - bed = (__instance as JobDriver_Masturbate).Bed; - else if (__instance is JobDriver_Rape) - bed = (__instance?.Partner?.jobs?.curDriver as JobDriver_Sex)?.Bed; - - */ - if ((__instance.Target as Pawn)?.jobs?.curDriver is JobDriver_SexBaseReciever) { Pawn Target = __instance.Target as Pawn; - if (!(Target.jobs.curDriver as JobDriver_SexBaseReciever).parteners.Contains(pawn)) { - (Target.jobs.curDriver as JobDriver_SexBaseReciever).parteners.Add(pawn); - } - bool quickie = (__instance is JobDriver_SexQuick) && AnimationSettings.fastAnimForQuickie; + int preAnimDuration = __instance.duration; + int AnimationTimeTicks = 0; + + if (bed != null) { - RerollAnimations(Target, __instance.duration, bed as Thing, __instance.sexType, quickie, sexProps: __instance.Sexprops); - } + RerollAnimations(Target, out AnimationTimeTicks, bed as Thing, __instance.Sexprops.sexType, quickie, sexProps: __instance.Sexprops); + } else { - RerollAnimations(Target, __instance.duration, sexType: __instance.sexType, fastAnimForQuickie: quickie, sexProps: __instance.Sexprops); + RerollAnimations(Target, out AnimationTimeTicks, sexType: __instance.Sexprops.sexType, fastAnimForQuickie: quickie, sexProps: __instance.Sexprops); } + + + //Modify Orgasm ticks to only orgasm as many times as RJW stock orgasm allows + if(AnimationTimeTicks != 0) + { + __instance.orgasmstick = preAnimDuration * __instance.orgasmstick / AnimationTimeTicks; + } + + } } - public static void RerollAnimations(Pawn pawn, int duration, Thing bed = null, xxx.rjwSextype sexType = xxx.rjwSextype.None, bool fastAnimForQuickie = false, rjw.SexProps sexProps = null) { + public static void RerollAnimations(Pawn pawn, out int AnimationTimeTicks, Thing bed = null, xxx.rjwSextype sexType = xxx.rjwSextype.None, bool fastAnimForQuickie = false, rjw.SexProps sexProps = null) { + + AnimationTimeTicks = 0; if(pawn == null || !(pawn.jobs?.curDriver is JobDriver_SexBaseReciever)) { - Log.Message("Error: Tried to reroll animations when pawn isn't sexing"); + Log.Error("Error: Tried to reroll animations when pawn isn't sexing"); return; } @@ -74,15 +73,26 @@ namespace Rimworld_Animations { pawnsToAnimate = pawnsToAnimate.Append(pawn).ToList(); } + for(int i = 0; i < pawnsToAnimate.Count; i++) { + + if(pawnsToAnimate[i].TryGetComp() == null) { + Log.Error("Error: " + pawnsToAnimate[i].Name + " of race " + pawnsToAnimate[i].def.defName + " does not have CompBodyAnimator attached!"); + break; + } + } + AnimationDef anim = AnimationUtility.tryFindAnimation(ref pawnsToAnimate, sexType, sexProps); if (anim != null) { bool mirror = GenTicks.TicksGame % 2 == 0; - Log.Message("Now playing " + anim.defName + (mirror ? " mirrored" : "")); - IntVec3 pos = pawn.Position; + + for (int i = 0; i < anim.actors.Count; i++) + { + pawnsToAnimate[i].TryGetComp().isAnimating = false; + } for (int i = 0; i < pawnsToAnimate.Count; i++) { @@ -94,11 +104,16 @@ namespace Rimworld_Animations { } bool shiver = pawnsToAnimate[i].jobs.curDriver is JobDriver_SexBaseRecieverRaped; - pawnsToAnimate[i].TryGetComp().StartAnimation(anim, i, mirror, shiver, fastAnimForQuickie); - (pawnsToAnimate[i].jobs.curDriver as JobDriver_Sex).ticks_left = anim.animationTimeTicks; - (pawnsToAnimate[i].jobs.curDriver as JobDriver_Sex).ticksLeftThisToil = anim.animationTimeTicks; - (pawnsToAnimate[i].jobs.curDriver as JobDriver_Sex).duration = anim.animationTimeTicks; - (pawnsToAnimate[i].jobs.curDriver as JobDriver_Sex).ticks_remaining = anim.animationTimeTicks; + pawnsToAnimate[i].TryGetComp().StartAnimation(anim, pawnsToAnimate, i, mirror, shiver, fastAnimForQuickie); + + int animTicks = anim.animationTimeTicks - (fastAnimForQuickie ? anim.animationStages[0].playTimeTicks : 0); + (pawnsToAnimate[i].jobs.curDriver as JobDriver_Sex).ticks_left = animTicks; + (pawnsToAnimate[i].jobs.curDriver as JobDriver_Sex).sex_ticks = animTicks; + (pawnsToAnimate[i].jobs.curDriver as JobDriver_Sex).duration = animTicks; + + + AnimationTimeTicks = animTicks; + if(!AnimationSettings.hearts) { (pawnsToAnimate[i].jobs.curDriver as JobDriver_Sex).ticks_between_hearts = Int32.MaxValue; } @@ -106,16 +121,35 @@ namespace Rimworld_Animations { } } else { - Log.Message("Anim not found"); + Log.Message("No animation found"); + + /* + //if pawn isn't already animating, if (!pawn.TryGetComp().isAnimating) { (pawn.jobs.curDriver as JobDriver_SexBaseReciever).increase_time(duration); //they'll just do the thrusting anim } + + */ } - - } + + + static IEnumerable NonSexActRulePackDefNames = new String[] + { + "MutualHandholdingRP", + "MutualMakeoutRP", + }; + + public static bool NonSexualAct(JobDriver_SexBaseInitiator sexBaseInitiator) + { + if(NonSexActRulePackDefNames.Contains(sexBaseInitiator.Sexprops.rulePack)) + { + return true; + } + return false; + } } [HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "End")] diff --git a/1.3/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseReceiverLoved.cs b/1.3/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseReceiverLoved.cs new file mode 100644 index 0000000..d328d2b --- /dev/null +++ b/1.3/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseReceiverLoved.cs @@ -0,0 +1,40 @@ +using System; +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; + +namespace Rimworld_Animations +{ + + [HarmonyPatch(typeof(JobDriver_SexBaseRecieverLoved), "MakeSexToil")] + public static class HarmonyPatch_JobDriver_SexBaseReceiverLoved + { + + public static IEnumerable Transpiler(IEnumerable codeInstructions) + { + + var ins = codeInstructions.ToList(); + for(int i = 0; i < ins.Count; i++) + { + if(i + 13 < ins.Count && ins[i + 13].opcode == OpCodes.Call && ins[i + 13].OperandIs(AccessTools.DeclaredMethod(typeof(Toils_LayDown), "LayDown"))) { + + ins.RemoveRange(i, 14); + + } + + else + { + yield return ins[i]; + } + } + + } + + } +} diff --git a/1.3/Source/Patches/RimworldPatches/HarmonyPatch_HeadHair.cs b/1.3/Source/Patches/RimworldPatches/HarmonyPatch_HeadHair.cs new file mode 100644 index 0000000..37ba6ce --- /dev/null +++ b/1.3/Source/Patches/RimworldPatches/HarmonyPatch_HeadHair.cs @@ -0,0 +1,22 @@ +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using RimWorld; +using UnityEngine; + +namespace Rimworld_Animations +{ + [HarmonyPatch(typeof(PawnRenderer), "DrawHeadHair")] + public static class HarmonyPatch_HeadHair + { + public static void Prefix(ref Vector3 headOffset, ref float angle) + { + + } + + } +} diff --git a/1.3/Source/Patches/RimworldPatches/HarmonyPatch_PawnRenderer.cs b/1.3/Source/Patches/RimworldPatches/HarmonyPatch_PawnRenderer.cs new file mode 100644 index 0000000..218e45b --- /dev/null +++ b/1.3/Source/Patches/RimworldPatches/HarmonyPatch_PawnRenderer.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using HarmonyLib; +using RimWorld; +using Verse; +using UnityEngine; +using System.Reflection; +using System.Reflection.Emit; + +namespace Rimworld_Animations { + + [HarmonyPatch(typeof(PawnRenderer), "RenderPawnInternal", new Type[] + { + typeof(Vector3), + typeof(float), + typeof(bool), + typeof(Rot4), + typeof(RotDrawMode), + typeof(PawnRenderFlags) + } + )] + public static class HarmonyPatch_PawnRenderer + { + + [HarmonyBefore(new string[] { "showhair.kv.rw", "erdelf.HumanoidAlienRaces", "Nals.FacialAnimation" })] + public static void Prefix(PawnRenderer __instance, ref Vector3 rootLoc, ref float angle, bool renderBody, ref Rot4 bodyFacing, RotDrawMode bodyDrawType, PawnRenderFlags flags) + { + + if (flags.FlagSet(PawnRenderFlags.Portrait)) return; + + PawnGraphicSet graphics = __instance.graphics; + Pawn pawn = graphics.pawn; + CompBodyAnimator bodyAnim = pawn.TryGetComp(); + + + if (bodyAnim != null && bodyAnim.isAnimating && pawn.Map == Find.CurrentMap) + { + bodyAnim.animatePawnBody(ref rootLoc, ref angle, ref bodyFacing); + + } + + } + + public static IEnumerable Transpiler(IEnumerable instructions) + { + List ins = instructions.ToList(); + + for(int i = 0; i < instructions.Count(); i++) + { + + if (i - 3 >= 0 && ins[i - 3].opcode == OpCodes.Call && ins[i - 3].operand != null && ins[i - 3].OperandIs(AccessTools.DeclaredMethod(typeof(PawnRenderer), "BaseHeadOffsetAt"))) + { + + yield return new CodeInstruction(OpCodes.Ldloca, (object)0); + yield return new CodeInstruction(OpCodes.Ldloca, (object)7); + yield return new CodeInstruction(OpCodes.Ldloca, (object)6); + yield return new CodeInstruction(OpCodes.Ldarga, (object)2); + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(typeof(PawnRenderer), "pawn")); + yield return new CodeInstruction(OpCodes.Ldarg, (object)6); + yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(AnimationUtility), "AdjustHead")); + yield return ins[i]; + //headFacing equals true + } + + // Fixes the offsets for eye implants and wounds on the head during animations + else if (ins[i].opcode == OpCodes.Callvirt && ins[i].operand != null && ins[i].OperandIs(AccessTools.DeclaredMethod(typeof(PawnWoundDrawer), "RenderOverBody"))) + { + // Pass some additional info to a new overload of RenderOverBody + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(typeof(PawnRenderer), "pawn")); + yield return new CodeInstruction(OpCodes.Ldarg_S, (object)6); // renderer flags + yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(PawnWoundDrawerExtension), "RenderOverBody")); + } + + else + { + yield return ins[i]; + } + } + } + } +} diff --git a/Source/Patches/HarmonyPatch_PawnRotation.cs b/1.3/Source/Patches/RimworldPatches/HarmonyPatch_PawnRotation.cs similarity index 99% rename from Source/Patches/HarmonyPatch_PawnRotation.cs rename to 1.3/Source/Patches/RimworldPatches/HarmonyPatch_PawnRotation.cs index 9fb95ef..7ec75a1 100644 --- a/Source/Patches/HarmonyPatch_PawnRotation.cs +++ b/1.3/Source/Patches/RimworldPatches/HarmonyPatch_PawnRotation.cs @@ -25,4 +25,5 @@ namespace Rimworld_Animations { } } + } diff --git a/Source/Patches/HarmonyPatch_Pawn_DrawTracker.cs b/1.3/Source/Patches/RimworldPatches/HarmonyPatch_Pawn_DrawTracker.cs similarity index 100% rename from Source/Patches/HarmonyPatch_Pawn_DrawTracker.cs rename to 1.3/Source/Patches/RimworldPatches/HarmonyPatch_Pawn_DrawTracker.cs diff --git a/1.3/Source/Patches/RimworldPatches/HarmonyPatch_SetPawnAnimatable.cs b/1.3/Source/Patches/RimworldPatches/HarmonyPatch_SetPawnAnimatable.cs new file mode 100644 index 0000000..b8c66b8 --- /dev/null +++ b/1.3/Source/Patches/RimworldPatches/HarmonyPatch_SetPawnAnimatable.cs @@ -0,0 +1,40 @@ +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 +{ + [HarmonyPatch(typeof(PawnRenderer), "RenderPawnAt")] + public static class PawnRenderer_RenderPawnAt_Patch + { + static bool ClearCache(Pawn pawn) + { + return pawn.IsInvisible() || (pawn.TryGetComp() != null && pawn.TryGetComp().isAnimating); + } + + public static IEnumerable Transpiler(IEnumerable instructions) + { + var list = instructions.ToList(); + + foreach (CodeInstruction i in instructions) + { + if (i.OperandIs(AccessTools.Method(typeof(PawnUtility), "IsInvisible"))) + { + yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PawnRenderer_RenderPawnAt_Patch), "ClearCache")); + } + else + { + yield return i; + } + } + } + } + +} diff --git a/1.3/Source/Patches/RimworldPatches/HarmonyPatch_Thing.cs b/1.3/Source/Patches/RimworldPatches/HarmonyPatch_Thing.cs new file mode 100644 index 0000000..9477abf --- /dev/null +++ b/1.3/Source/Patches/RimworldPatches/HarmonyPatch_Thing.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using RimWorld; +using Verse; + +namespace Rimworld_Animations +{ + [HarmonyPatch(typeof(Thing), "DrawAt")] + public static class HarmonyPatch_Thing + { + + public static bool Prefix(Thing __instance) + { + CompThingAnimator thingAnimator = __instance.TryGetComp(); + if (thingAnimator != null && thingAnimator.isAnimating) + { + thingAnimator.AnimateThing(__instance); + return false; + + } + + return true; + + } + + } +} diff --git a/Source/Settings/AnimationSettings.cs b/1.3/Source/Settings/AnimationSettings.cs similarity index 64% rename from Source/Settings/AnimationSettings.cs rename to 1.3/Source/Settings/AnimationSettings.cs index 75308b8..0a96621 100644 --- a/Source/Settings/AnimationSettings.cs +++ b/1.3/Source/Settings/AnimationSettings.cs @@ -11,8 +11,9 @@ namespace Rimworld_Animations { public class AnimationSettings : ModSettings { - public static bool orgasmQuiver, rapeShiver, soundOverride = true, hearts = true, controlGenitalRotation = false, applySemenOnAnimationOrgasm = false, fastAnimForQuickie = false; - public static bool offsetTab = false; + 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 offsets = new Dictionary(); @@ -22,19 +23,21 @@ namespace Rimworld_Animations { base.ExposeData(); - Scribe_Values.Look(ref offsetTab, "EnableOffsetTab", false); - Scribe_Values.Look(ref controlGenitalRotation, "controlGenitalRotation", false); - Scribe_Values.Look(ref orgasmQuiver, "orgasmQuiver"); - Scribe_Values.Look(ref fastAnimForQuickie, "fastAnimForQuickie"); - Scribe_Values.Look(ref rapeShiver, "rapeShiver"); - Scribe_Values.Look(ref hearts, "heartsOnLovin"); - Scribe_Values.Look(ref applySemenOnAnimationOrgasm, "applySemenOnOrgasm", false); - Scribe_Values.Look(ref soundOverride, "rjwAnimSoundOverride", true); - Scribe_Values.Look(ref shiverIntensity, "shiverIntensity", 2f); + 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-sheartsOnLovin"); + 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, "animationOffsets"); - Scribe_Collections.Look(ref rotation, "rotationOffsets"); + Scribe_Collections.Look(ref offsets, "RJWAnimations-animationOffsets"); + Scribe_Collections.Look(ref rotation, "RJWAnimations-rotationOffsets"); @@ -69,12 +72,14 @@ namespace Rimworld_Animations { 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("Enable Offset Tab", ref AnimationSettings.offsetTab); + 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); diff --git a/1.3/Source/Utilities/AnimationUtility.cs b/1.3/Source/Utilities/AnimationUtility.cs new file mode 100644 index 0000000..a75fc32 --- /dev/null +++ b/1.3/Source/Utilities/AnimationUtility.cs @@ -0,0 +1,319 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RimWorld; +using rjw.Modules.Interactions.Helpers; +using rjw.Modules.Interactions.Objects; +using UnityEngine; +using Verse; +using Verse.AI; +using rjw.Modules.Interactions.Enums; + +namespace Rimworld_Animations { + public static class AnimationUtility { + /* + Note: always make the list in this order: + Female pawns, animal female pawns, male pawns, animal male pawns + */ + public static AnimationDef tryFindAnimation(ref List participants, rjw.xxx.rjwSextype sexType = 0, rjw.SexProps sexProps = null) { + + + InteractionWithExtension interaction = InteractionHelper.GetWithExtension(sexProps.dictionaryKey); + + + if(interaction.HasInteractionTag(InteractionTag.Reverse)) + { + Pawn buffer = participants[1]; + participants[1] = participants[0]; + participants[0] = buffer; + } + + participants = + participants.OrderBy(p => p.jobs.curDriver is rjw.JobDriver_SexBaseInitiator) + .OrderBy(p => rjw.xxx.can_fuck(p)) + .ToList(); + + + List localParticipants = new List(participants); + + IEnumerable options = DefDatabase.AllDefs.Where((AnimationDef x) => { + + + if (x.actors.Count != localParticipants.Count) { + return false; + } + for (int i = 0; i < x.actors.Count; i++) { + + if (rjw.RJWPreferenceSettings.Malesex == rjw.RJWPreferenceSettings.AllowedSex.Nohomo) { + if (rjw.xxx.is_male(localParticipants[i]) && x.actors[i].isFucked) { + return false; + } + } + if (x.actors[i].requiredGender != null && !x.actors[i].requiredGender.Contains(localParticipants[i].gender.ToStringSafe())) + { + if (AnimationSettings.debugMode) + { + Log.Message(string.Concat(new string[] + { + x.defName.ToStringSafe(), + " not selected -- ", + localParticipants[i].def.defName.ToStringSafe(), + " ", + localParticipants[i].Name.ToStringSafe(), + " does not match required gender" + })); + } + return false; + } + if ((x.actors[i].blacklistedRaces != null) && x.actors[i].blacklistedRaces.Contains(localParticipants[i].def.defName)) { + if(AnimationSettings.debugMode) + Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " is blacklisted"); + return false; + } + + if(x.actors[i].defNames.Contains("Human")) { + if (!rjw.xxx.is_human(localParticipants[i])) { + if (AnimationSettings.debugMode) + Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " is not human"); + + return false; + } + + } + else if (!x.actors[i].bodyDefTypes.Contains(localParticipants[i].RaceProps.body)) { + + if (!x.actors[i].defNames.Contains(localParticipants[i].def.defName)) { + + if (rjw.RJWSettings.DevMode) { + string animInfo = x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " is not "; + foreach(String defname in x.actors[i].defNames) { + animInfo += defname + ", "; + } + if (AnimationSettings.debugMode) + Log.Message(animInfo); + } + + return false; + } + } + //genitals checking + + if(!GenitalCheckForPawn(x.actors[i].requiredGenitals, localParticipants[i], out string failReason)) { + Debug.Log("Didn't select " + x.defName + ", " + localParticipants[i].Name + " " + failReason); + return false; + } + + //TESTING ANIMATIONS ONLY REMEMBER TO COMMENT OUT BEFORE PUSH + /* + if (x.defName != "Cunnilingus") + return false; + */ + + + if (x.actors[i].isFucking && !rjw.xxx.can_fuck(localParticipants[i])) { + if (AnimationSettings.debugMode) + Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " can't fuck"); + return false; + } + + if (x.actors[i].isFucked && !rjw.xxx.can_be_fucked(localParticipants[i])) { + if (AnimationSettings.debugMode) + Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " can't be fucked"); + return false; + } + } + return true; + }); + List optionsWithInteractionType = options.ToList().FindAll(x => x.interactionDefTypes != null && x.interactionDefTypes.Contains(sexProps.sexType.ToStringSafe())); + if (optionsWithInteractionType.Any()) { + if (AnimationSettings.debugMode) + Log.Message("Selecting animation for interaction type " + sexProps.sexType.ToStringSafe() + "..."); + return optionsWithInteractionType.RandomElement(); + } + List optionsWithSexType = options.ToList().FindAll(x => x.sexTypes != null && x.sexTypes.Contains(sexType)); + if (optionsWithSexType.Any()) { + if (AnimationSettings.debugMode) + Log.Message("Selecting animation for rjwSexType " + sexType.ToStringSafe() + "..."); + return optionsWithSexType.RandomElement(); + } + + /* + if(optionsWithInitiator.Any()) { + if (AnimationSettings.debugMode) + Log.Message("Selecting animation for initiators..."); + } + */ + + if (options != null && options.Any()) { + if (AnimationSettings.debugMode) + Log.Message("Randomly selecting animation..."); + return options.RandomElement(); + } + else + return null; + } + + public static void RenderPawnHeadMeshInAnimation1(Mesh mesh, Vector3 loc, Quaternion quaternion, Material material, bool drawNow, Pawn pawn) { + + if (pawn == null || pawn.Map != Find.CurrentMap) { + GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, drawNow); + return; + } + + CompBodyAnimator pawnAnimator = pawn.TryGetComp(); + + if (pawnAnimator == null || !pawnAnimator.isAnimating) { + GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, drawNow); + } else { + Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition(); + pawnHeadPosition.y = loc.y; + GenDraw.DrawMeshNowOrLater(MeshPool.humanlikeHeadSet.MeshAt(pawnAnimator.headFacing), pawnHeadPosition, Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up), material, true); + } + } + + public static void AdjustHead(ref Quaternion quat, ref Rot4 bodyFacing, ref Vector3 pos, ref float angle, Pawn pawn, PawnRenderFlags flags) + { + if (flags.FlagSet(PawnRenderFlags.Portrait)) return; + + CompBodyAnimator anim = pawn.TryGetComp(); + if (anim.isAnimating) + { + bodyFacing = anim.headFacing; + angle = anim.headAngle; + quat = Quaternion.AngleAxis(anim.headAngle, Vector3.up); + pos = anim.getPawnHeadOffset(); + + } + } + + public static void RenderPawnHeadMeshInAnimation(Mesh mesh, Vector3 loc, Quaternion quaternion, Material material, bool portrait, Pawn pawn, float bodySizeFactor = 1) { + + if (pawn == null) { + GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, portrait); + return; + } + + CompBodyAnimator pawnAnimator = pawn.TryGetComp(); + + if (pawnAnimator == null || !pawnAnimator.isAnimating || portrait) { + GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, portrait); + } + else { + Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition(); + pawnHeadPosition.x *= bodySizeFactor; + pawnHeadPosition.x *= bodySizeFactor; + pawnHeadPosition.y = loc.y; + GenDraw.DrawMeshNowOrLater(mesh, pawnHeadPosition, Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up), material, portrait); + } + } + + public static bool GenitalCheckForPawn(List requiredGenitals, Pawn pawn, out string failReason) { + + failReason = null; + if (requiredGenitals != null) { + if (requiredGenitals.Contains("Vagina")) { + + if (!rjw.Genital_Helper.has_vagina(pawn)) { + failReason = "missing vagina"; + return false; + } + + } + + if (requiredGenitals.Contains("Penis")) { + + if (!(rjw.Genital_Helper.has_multipenis(pawn) || rjw.Genital_Helper.has_penis_infertile(pawn) || rjw.Genital_Helper.has_penis_fertile(pawn) || rjw.Genital_Helper.has_ovipositorM(pawn) || rjw.Genital_Helper.has_ovipositorF(pawn))) { + failReason = "missing penis"; + return false; + } + + } + + if (requiredGenitals.Contains("Mouth")) { + + if (!rjw.Genital_Helper.has_mouth(pawn)) { + failReason = "missing mouth"; + return false; + } + + } + + if (requiredGenitals.Contains("Anus")) { + + if (!rjw.Genital_Helper.has_anus(pawn)) { + failReason = "missing anus"; + return false; + } + + } + + if (requiredGenitals.Contains("Breasts")) { + if (!rjw.Genital_Helper.can_do_breastjob(pawn)) { + failReason = "missing breasts"; + return false; + } + } + + if (requiredGenitals.Contains("NoVagina")) { + + if (rjw.Genital_Helper.has_vagina(pawn)) { + failReason = "has vagina"; + return false; + } + + } + + if (requiredGenitals.Contains("NoPenis")) { + + if ((rjw.Genital_Helper.has_multipenis(pawn) || rjw.Genital_Helper.has_penis_infertile(pawn) || rjw.Genital_Helper.has_penis_fertile(pawn))) { + failReason = "has penis"; + return false; + } + + } + + if (requiredGenitals.Contains("NoMouth")) { + + if (rjw.Genital_Helper.has_mouth(pawn)) { + failReason = "has mouth"; + return false; + } + + } + + if (requiredGenitals.Contains("NoAnus")) { + + if (rjw.Genital_Helper.has_anus(pawn)) { + failReason = "has anus"; + return false; + } + + } + + if (requiredGenitals.Contains("NoBreasts")) { + if (rjw.Genital_Helper.can_do_breastjob(pawn)) { + failReason = "has breasts"; + return false; + } + } + } + + return true; + + } + + public static Rot4 PawnHeadRotInAnimation(Pawn pawn, Rot4 regularPos) + { + Debug.Log("Test"); + + if(pawn?.TryGetComp() != null && pawn.TryGetComp().isAnimating) + { + return pawn.TryGetComp().headFacing; + } + + return regularPos; + } + } +} diff --git a/1.3/Source/Utilities/PatchOperationAddOrReplace.cs b/1.3/Source/Utilities/PatchOperationAddOrReplace.cs new file mode 100644 index 0000000..4e1bd85 --- /dev/null +++ b/1.3/Source/Utilities/PatchOperationAddOrReplace.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using Verse; + +namespace Rimworld_Animations +{ + public class PatchOperationAddOrReplace : PatchOperationPathed + { + + protected string key; + private XmlContainer value; + + protected override bool ApplyWorker(XmlDocument xml) + { + XmlNode valNode = value.node; + bool result = false; + IEnumerator enumerator = xml.SelectNodes(xpath).GetEnumerator(); + try + { + while (enumerator.MoveNext()) + { + object obj = enumerator.Current; + result = true; + XmlNode parentNode = obj as XmlNode; + XmlNode xmlNode = parentNode.SelectSingleNode(key); + if (xmlNode == null) + { + // Add - Add node if not existing + xmlNode = parentNode.OwnerDocument.CreateElement(key); + parentNode.AppendChild(xmlNode); + } + else + { + // Replace - Clear existing children + xmlNode.RemoveAll(); + } + // (Re)add value + xmlNode.AppendChild(parentNode.OwnerDocument.ImportNode(valNode.FirstChild, true)); + } + } + finally + { + IDisposable disposable = enumerator as IDisposable; + if (disposable != null) + { + disposable.Dispose(); + } + } + return result; + } + + } + +} diff --git a/1.3/Textures/UI/MainTab.png b/1.3/Textures/UI/MainTab.png new file mode 100644 index 0000000..92f855f Binary files /dev/null and b/1.3/Textures/UI/MainTab.png differ diff --git a/1.4/Assemblies/Rimworld-Animations.dll b/1.4/Assemblies/Rimworld-Animations.dll new file mode 100644 index 0000000..0b959d9 Binary files /dev/null and b/1.4/Assemblies/Rimworld-Animations.dll differ diff --git a/1.4/Defs/AnimationDefs/AnimationDefs.rar b/1.4/Defs/AnimationDefs/AnimationDefs.rar new file mode 100644 index 0000000..e7bf2a1 Binary files /dev/null and b/1.4/Defs/AnimationDefs/AnimationDefs.rar differ diff --git a/1.4/Defs/AnimationDefs/Animations_Beast.xml b/1.4/Defs/AnimationDefs/Animations_Beast.xml new file mode 100644 index 0000000..30d14fc --- /dev/null +++ b/1.4/Defs/AnimationDefs/Animations_Beast.xml @@ -0,0 +1,2180 @@ + + + + Dog_Doggystyle + + true + +
  • Anal
  • +
  • Vaginal
  • +
    + + +
  • VaginalBreeding
  • +
  • AnalBreeding
  • +
    + + +
  • + +
  • Human
  • + + true + +
  • + +
  • Wolf_Timber
  • +
  • Wolf_Arctic
  • +
  • Whitefox
  • +
  • Warg
  • +
  • Husky
  • +
  • LabradorRetriever
  • + +
  • AEXP_WelshTerrier
  • +
  • AEXP_Rottweiler
  • +
  • AEXP_Poodle
  • +
  • AEXP_GreatDane
  • +
  • AEXP_GermanShepherd
  • +
  • AEXP_FrenchBulldog
  • +
  • AEXP_Corgi
  • +
  • AEXP_CatAbyssinian
  • +
  • AEXP_CatBengal
  • +
  • AEXP_CatMaineCoon
  • +
  • AEXP_CatSphynx
  • + + +
  • QuadrupedAnimalWithHooves
  • +
  • QuadrupedAnimalWithPawsAndTail
  • +
    + true + true + +
    + + + + +
  • + Fuck + true + 765 + 0 + +
  • + LayingPawn + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 + 0 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • +
  • + 6 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 2 +
  • +
  • + 1 + 56.7 + 27.5 + 0.057 + -0.038 + 1 + 2 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • + +
  • + + 10 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 +
  • +
  • + 6 + 53.7 + 5.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 1 + 56.7 + 7.5 + 0.057 + -0.038 + 1 + 1 + 0 +
  • + + + +
  • + +
  • + + 8 + -33.7 + 0 + -0.492 + 0.266 + 1 + 0 + 0 +
  • +
  • + 8 + Fuck + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 +
  • +
  • + 1 + -33.7 + 0 + -0.492 + 0.266 + 1 + 0 + 0 +
  • + + + + +
  • + Knot + False + 71 + 0 + +
  • + LayingPawn + +
  • + true + 60 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 1 + 0 +
  • +
  • + 6 + Cum + 53.7 + 28.4 + 0.068 + -0.038 + 1 + 1 +
  • +
  • + 4 + 51.7 + 33.4 + 0.098 + -0.038 + 1 + 1 +
  • +
  • + 1 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 1 + 0 +
  • + + + +
  • + +
  • + + 60 + -33.7 + 0 + -0.492 + 0.266 + 1 + 0 + 0 +
  • +
  • + 6 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 +
  • +
  • + 4 + Fuck + -41.6 + 0 + -0.383 + 0.256 + 1 + 0 +
  • +
  • + 1 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 + 0 +
  • + + + + + + +
  • + Cum + true + 600 + 0 + +
  • + LayingPawn + +
  • + 40 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 1 + 0 +
  • +
  • + 40 + Cum + 57.7 + 28.4 + 0.073 + -0.038 + 1 + 1 +
  • +
  • + 1 + 53.7 + 25.4 + 0.068 + -0.038 + 1 + 1 + 0 +
  • + + + +
  • + + +
  • + 10 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 + 0 +
  • +
  • + 10 + -40.6 + 0 + -0.358 + 0.256 + 1 + 0 +
  • +
  • + 10 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 +
  • +
  • + 10 + -40.6 + 0 + -0.358 + 0.256 + 1 + 0 +
  • +
  • + 10 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 +
  • +
  • + 10 + -40.6 + 0 + -0.358 + 0.256 + 1 + 0 +
  • +
  • + 10 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 +
  • +
  • + 10 + -40.6 + 0 + -0.358 + 0.256 + 1 + 0 +
  • +
  • + 1 + -39.6 + 0 + -0.353 + 0.256 + 1 + 0 + 0 +
  • + + + + + + + +
    + +
    + + Horse_Cowgirl + + true + +
  • Anal
  • +
  • Vaginal
  • +
    + + +
  • RequestVaginalBreeding
  • +
  • RequestAnalBreeding
  • +
    + + +
  • + +
  • Human
  • + + true + true + + (0, 0.2) + + +
  • + +
  • Horse
  • + + +
  • QuadrupedAnimalWithHooves
  • +
    + true + +
    + + + + +
  • + Insertion + false + 0 + +
  • + +
  • + 180 + -24.337 + -37.1218948 + 0 + 0.698042035 + -0.20718734 + 0 + 3 + 3 +
  • +
  • + 70 + -2.54239845 + 7.31265259 + 0 + 0.606091142 + -0.045959726 + 0 + 3 + 3 + Slimy +
  • +
  • + 60 + -4.84361649 + -23.6405125 + 0 + 0.650456548 + -0.0570534021 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -35.01766 + -26.3706665 + 0 + 0.455286169 + -0.3646413 + 0 + 3 + 3 + Slimy +
  • + + +
  • + LayingPawn + +
  • + 250 + 177.083145 + 0 + 0 + -0.256229281 + -0.362511069 + 0 + 1 + 0 + +
  • +
  • + 60 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • +
  • + 1 + 179.6811 + 0 + 0 + -0.267210543 + -0.3991253 + 0 + 1 + 0 +
  • + + + + + +
  • + SlowFuck + true + 1300 + 0 + +
  • + +
  • + 80 + -35.01766 + -26.3706665 + 0 + 0.455286169 + -0.3646413 + 0 + 3 + 3 +
  • +
  • + 49 + -49.8178673 + -35.7418823 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -35.01766 + -26.3706665 + 0 + 0.455286169 + -0.3646413 + 0 + 3 + 3 + Fuck +
  • + + +
  • + LayingPawn + +
  • + 80 + 179.6811 + 0 + 0 + -0.267210543 + -0.3991253 + 0 + 1 + 0 +
  • +
  • + 49 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • +
  • + 1 + 179.6811 + 0 + 0 + -0.267210543 + -0.3991253 + 0 + 1 + 0 +
  • + + + + + +
  • + Transition + false + 0 + +
  • + +
  • + 50 + -35.01766 + -26.3706665 + 0 + 0.455286169 + -0.3646413 + 0 + 3 + 3 + Fuck +
  • + +
  • + 15 + -49.8178673 + -35.7418823 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + +
  • + 80 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • + +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.48456946 + -0.489136577 + 0 + 3 + 3 +
  • + + +
  • + LayingPawn + +
  • + 50 + 179.6811 + 0 + 0 + -0.267210543 + -0.3991253 + 0 + 1 + 0 +
  • + +
  • + 15 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • + +
  • + 80 + 175.467651 + 0 + 0 + -0.2123042 + -0.5309518 + 0 + 1 + 0 + Fuck +
  • + +
  • + 1 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • + + + + + +
  • + FastFuck + true + 1260 + 0 + +
  • + + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 2 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 2 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 2 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 2 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 2 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 2 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 2 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • +
  • + 24 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + + +
  • + LayingPawn + + +
  • + 10 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • +
  • + 24 + 175.467651 + 0 + 0 + -0.2123042 + -0.5309518 + 0 + 1 + 0 + Fuck +
  • +
  • + 1 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • + + + + + +
  • + FasterFuck + true + 418 + 0 + +
  • + + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 +
  • +
  • + 8 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + Slimy +
  • + + +
  • + LayingPawn + +
  • + 10 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • +
  • + 8 + 175.467651 + 0 + 0 + -0.2123042 + -0.5309518 + 0 + 1 + 0 + Fuck +
  • +
  • + 1 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • + + + + + +
  • + Cum + True + 318 + 0 + +
  • + + +
  • + 10 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 + +
  • +
  • + true + 80 + -49.8178673 + -8.273987 + 0 + 0.506531835 + -0.55575326 + 0 + 3 + 3 + Cum +
  • +
  • + 25 + -49.8178673 + 2.654541 + 0 + 0.5175133 + -0.547725141 + 0 + 3 + 3 +
  • +
  • + 1 + -49.8178673 + -14.1647339 + 0 + 0.484569454 + -0.489136577 + 0 + 3 + 3 +
  • + + + +
  • + LayingPawn + + +
  • + 10 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • +
  • + 80 + 175.467651 + 0 + 0 + -0.2123042 + -0.5309518 + 0 + 1 + 0 +
  • +
  • + 25 + 173.81427 + 0 + 0 + -0.197662517 + -0.545600235 + 0 + 1 + 0 +
  • +
  • + 1 + 177.981537 + 0 + 0 + -0.24524799 + -0.358849227 + 0 + 1 + 0 +
  • + + + + + + +
    + +
    +
    diff --git a/1.4/Defs/AnimationDefs/Animations_Lesbian.xml b/1.4/Defs/AnimationDefs/Animations_Lesbian.xml new file mode 100644 index 0000000..56d805a --- /dev/null +++ b/1.4/Defs/AnimationDefs/Animations_Lesbian.xml @@ -0,0 +1,1782 @@ + + + + Tribadism + + true + +
  • Scissoring
  • +
    + + +
  • + +
  • Human
  • + + true + +
  • Vagina
  • +
    + +
  • + +
  • Human
  • + + true + true + +
  • Vagina
  • +
    + + +
    + + +
  • + Tribbing + true + 992 + 0 + +
  • + LayingPawn + +
  • + + 20 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 20 + -79.56 + -79.56 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 20 + -81.53 + -81.53 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + + +
  • + +
  • + + 20 + 9.97 + -7.61 + 0.444 + 0.368 + 3 + 3 + 0 +
  • +
  • + 20 + 23.82 + -6.90 + 0.432 + 0.403 + 3 + 3 + 0 +
  • +
  • + 20 + 5.19 + -6.19 + 0.442 + 0.388 + 3 + 3 + 0 +
  • +
  • + 1 + 9.97 + -7.61 + 0.444 + 0.368 + 3 + 3 + 0 +
  • + + + + + +
  • + TribadismFast + true + 682 + 0 + +
  • + LayingPawn + +
  • + + 10 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + 10 + -79.56 + -79.56 + -0.218 + 0.082 + 2 + 1 + 0 +
  • +
  • + 10 + -81.53 + -81.53 + -0.219 + 0.07 + 2 + 1 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + + 10 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + 10 + -79.56 + -79.56 + -0.218 + 0.082 + 2 + 1 + 0 +
  • +
  • + 10 + -81.53 + -81.53 + -0.219 + 0.07 + 2 + 1 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • + +
  • + + 10 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + 10 + -79.56 + -79.56 + -0.218 + 0.082 + 2 + 1 + 0 +
  • +
  • + 10 + -81.53 + -81.53 + -0.219 + 0.07 + 2 + 1 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + + 10 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + 10 + -79.56 + -79.56 + -0.218 + 0.082 + 2 + 1 + 0 +
  • +
  • + 10 + -81.53 + -81.53 + -0.219 + 0.07 + 2 + 1 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • + + +
  • + + 10 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 10 + -79.56 + -77.66 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 10 + -81.53 + -77.74 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + + +
  • + + 10 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 10 + -79.56 + -77.66 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 10 + -81.53 + -77.74 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + + +
  • + + 10 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 10 + -79.56 + -77.66 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 10 + -81.53 + -77.74 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + + +
  • + + 10 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 10 + -79.56 + -77.66 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 10 + -81.53 + -77.74 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + + +
  • + + 10 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 10 + -79.56 + -77.66 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 10 + -81.53 + -77.74 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + + +
  • + + 10 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • +
  • + 10 + -79.56 + -77.66 + -0.218 + 0.082 + 2 + 2 + 0 +
  • +
  • + 10 + -81.53 + -77.74 + -0.219 + 0.07 + 2 + 2 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -73.04 + -0.218 + 0.073 + 2 + 2 + 0 +
  • + +
  • + + 10 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • +
  • + 10 + -79.56 + -79.56 + -0.218 + 0.082 + 2 + 1 + 0 +
  • +
  • + 10 + -81.53 + -81.53 + -0.219 + 0.07 + 2 + 1 + 0 +
  • +
  • + Slimy + 1 + -81.3 + -81.3 + -0.218 + 0.073 + 2 + 1 + 0 +
  • + + +
  • + +
  • + + 10 + 9.97 + -7.61 + 0.444 + 0.368 + 3 + 3 + 0 +
  • +
  • + 10 + 23.82 + -6.90 + 0.432 + 0.403 + 3 + 3 + 0 +
  • +
  • + 10 + 5.19 + -6.19 + 0.442 + 0.388 + 3 + 3 + 0 +
  • +
  • + 1 + 9.97 + -7.61 + 0.444 + 0.368 + 3 + 3 + 0 +
  • + + + + + +
    + +
    + + Cunnilingus + + true + +
  • Oral
  • +
  • Fingering
  • +
  • Cunnilingus
  • +
    + + +
  • Cunnilingus
  • +
  • CunnilingusF
  • +
  • CunnilingusRape
  • +
  • CunnilingusRapeF
  • + +
  • Fingering
  • +
  • FingeringF
  • +
  • FingeringRape
  • +
  • FingeringRapeF
  • + +
  • Fisting
  • +
  • FistingF
  • +
  • FistingRape
  • +
  • FistingRapeF
  • + +
    + +
  • + +
  • Human
  • + + true + +
  • Vagina
  • +
    + + (-0.2, 0.1) + + +
  • + +
  • Human
  • + + true + + (-0.1, 0.15) + + +
    + + + + +
  • + Initial + False + 0 + +
  • + +
  • + 60 + -81.06536 + -56.4483032 + 0 + -0.0624052179 + -0.437134951 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + +
  • + 60 + -27.578373 + 0.2816162 + 0 + 0.102704488 + 0.50675 + 0 + 3 + 3 +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 + Slimy +
  • + + + + + + +
  • + Slow + True + 1497 + 0 + +
  • + +
  • + 98 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 40 + -87.26528 + -65.901825 + 0 + -0.0737426062 + -0.432820916 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • + +
  • + 98 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 40 + -87.26528 + -65.901825 + 0 + -0.0737426062 + -0.432820916 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • + +
  • + 60 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 120 + -86.52611 + -68.86432 + 0 + -0.05432228 + -0.439906 + 0 + 1 + 1 +
  • +
  • + 40 + -88.36286 + -84.3309 + 0 + -0.06637782 + -0.440140843 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.0692383763 + -0.440020353 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + +
  • + 80 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 +
  • +
  • + 18 + -41.1054764 + -10.1737061 + 0 + 0.04582855 + 0.462155169 + 0 + 3 + 3 +
  • +
  • + 40 + -38.1903877 + -31.6517334 + 0 + 0.0384018831 + 0.4874894 + 0 + 3 + 3 +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 + Slimy +
  • + +
  • + 80 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 +
  • +
  • + 18 + -41.1054764 + -10.1737061 + 0 + 0.04582855 + 0.462155169 + 0 + 3 + 3 +
  • +
  • + 40 + -38.1903877 + -31.6517334 + 0 + 0.0384018831 + 0.4874894 + 0 + 3 + 3 +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 + Slimy +
  • + +
  • + 60 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 + Slimy +
  • +
  • + 40 + -45.2595444 + -13.57782 + 0 + 0.009577712 + 0.4726282 + 0 + 3 + 3 + Slimy +
  • +
  • + 20 + -45.2595444 + -24.2278748 + 0 + 0.0315402448 + 0.415024319 + 0 + 3 + 3 + +
  • +
  • + 40 + -45.2595444 + -13.57782 + 0 + 0.009577712 + 0.4726282 + 0 + 3 + 3 + Slimy +
  • +
  • + 20 + -45.2595444 + -24.2278748 + 0 + 0.0315402448 + 0.415024319 + 0 + 3 + 3 + +
  • +
  • + 40 + -45.2595444 + -13.57782 + 0 + 0.009577712 + 0.4726282 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 + Slimy +
  • + + + + + + +
  • + Transition + False + 0 + +
  • + +
  • + 40 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 30 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + +
  • + 40 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + -0.1 + 3 + 3 + Slimy +
  • +
  • + 30 + -35.8792953 + -9.312592 + 0 + 0.03684573 + 0.4285702 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • + + + + + +
  • + Fast + True + 710 + 0 + +
  • + +
  • + 40 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 30 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + +
  • + 40 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 30 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + +
  • + 40 + -87.3645554 + -79.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 2 +
  • +
  • + 30 + -97.90959 + -79.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 2 +
  • +
  • + 1 + -87.3645554 + -79.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 2 +
  • + +
  • + 40 + -87.3645554 + -79.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 2 +
  • +
  • + 30 + -97.90959 + -79.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 2 +
  • +
  • + 1 + -87.3645554 + -79.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 2 +
  • + +
  • + 40 + -87.3645554 + -79.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 2 +
  • +
  • + 30 + -97.90959 + -79.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 2 +
  • +
  • + 1 + -87.3645554 + -79.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 2 +
  • + +
  • + 40 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 30 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + +
  • + 40 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • +
  • + 30 + -35.8792953 + -3.312592 + 0 + 0.03684573 + 0.4285702 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • + + + + +
  • + Faster + True + 360 + 0 + +
  • + +
  • + 20 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 15 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + +
  • + 20 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • +
  • + 15 + -35.8792953 + -9.312592 + 0 + 0.03684573 + 0.4285702 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • + + + + +
  • + Cum + True + 639 + 0 + +
  • + +
  • + 20 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 15 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + +
  • + 20 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + 15 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + +
  • + 20 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • +
  • + True + 80 + -97.90959 + -69.72717 + 0 + -0.0259781852 + -0.445601642 + 0 + 1 + 1 + Cum +
  • +
  • + 40 + -99.80413 + -94.4023743 + 0 + -0.01950606 + -0.447728932 + 0 + 1 + 1 +
  • +
  • + 1 + -87.3645554 + -69.70276 + 0 + -0.06923838 + -0.440020353 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + + +
  • + 20 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • +
  • + 15 + -35.8792953 + -9.312592 + 0 + 0.03684573 + 0.4285702 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • + +
  • + 20 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • +
  • + 15 + -35.8792953 + -9.312592 + 0 + 0.03684573 + 0.4285702 + 0 + 3 + 3 + Slimy +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • + +
  • + 20 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • +
  • + 80 + -35.8792953 + -9.312592 + 0 + 0.03684573 + 0.4285702 + 0 + 3 + 3 +
  • +
  • + 40 + -38.5277061 + -1.13140869 + 0 + 0.0376501828 + 0.42935127 + 0 + 3 + 3 +
  • +
  • + 1 + -47.9400826 + -21.93164 + 0 + -0.04209958 + 0.467844343 + 0 + 3 + 3 + Slimy +
  • + + + + + +
    + +
    +
    diff --git a/1.4/Defs/AnimationDefs/Animations_Masturbate.xml b/1.4/Defs/AnimationDefs/Animations_Masturbate.xml new file mode 100644 index 0000000..2968fa1 --- /dev/null +++ b/1.4/Defs/AnimationDefs/Animations_Masturbate.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/1.4/Defs/AnimationDefs/Animations_Multi.xml b/1.4/Defs/AnimationDefs/Animations_Multi.xml new file mode 100644 index 0000000..af7ea7a --- /dev/null +++ b/1.4/Defs/AnimationDefs/Animations_Multi.xml @@ -0,0 +1,660 @@ + + + + Double_Penetration + + true + +
  • DoublePenetration
  • +
  • Anal
  • +
  • Oral
  • +
  • Vaginal
  • +
    + +
  • + +
  • Human
  • + + true + +
  • + +
  • Human
  • + + true + true + true + +
  • + +
  • Human
  • + + true + true + true + +
    + + +
  • + Slow + true + 976 + 0 + +
  • + + +
  • + 25 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • +
  • + 35 + 48.1 + 16.3 + 0 + 0.188 + 1 + 1 + 0 +
  • +
  • + Suck + 1 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • + + +
  • + + LayingPawn + +
  • + -10 + 30 + 12 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 30 + 12 + -15.1 + 0.729 + 0.378 + 3 + 3 + 0 +
  • +
  • + -10 + 1 + 12 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • + + +
  • + + LayingPawn + +
  • + 43 + 27 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • +
  • + Fuck + 33 + -6.7 + 14.1 + -0.53 + 0.378 + 1 + 1 + 0 +
  • +
  • + 43 + 1 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • + + + + +
  • + Face_Fuck + true + 650 + 0 + +
  • + + +
  • + 13 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • +
  • + 6 + 60.7 + 5.6 + 0.025 + 0.118 + 1 + 1 + 0 +
  • +
  • + 6 + 62.7 + 0.2 + 0.08 + 0.118 + 1 + 1 + 0 +
  • +
  • + Suck + 1 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • + + +
  • + + LayingPawn + +
  • + -10 + 13 + 12 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 12 + 2 + -15.1 + 0.729 + 0.378 + 3 + 3 + 0 +
  • +
  • + -10 + 1 + 12 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • + + +
  • + + LayingPawn + +
  • + 43 + 13 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • +
  • + Fuck + 12 + -6.7 + 14.1 + -0.53 + 0.378 + 1 + 1 + 0 +
  • +
  • + 43 + 1 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • + + + + +
  • + Cum + true + 392 + 0 + +
  • + + +
  • + 9 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • +
  • + 4 + 60.7 + 5.6 + 0.025 + 0.118 + 1 + 1 + 0 +
  • +
  • + 4 + 62.7 + 0.2 + 0.056 + 0.118 + 1 + 1 + 0 +
  • +
  • + Suck + 1 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • + +
  • + 9 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • +
  • + 4 + 60.7 + 5.6 + 0.025 + 0.118 + 1 + 1 + 0 +
  • +
  • + 4 + 62.7 + 0.2 + 0.056 + 0.118 + 1 + 1 + 0 +
  • +
  • + Suck + 1 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • + +
  • + 9 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • +
  • + true + 120 + 60.7 + 5.6 + 0.025 + 0.118 + 1 + 1 + 0 +
  • +
  • + 30 + 62.7 + 0.2 + 0.056 + 0.118 + 1 + 1 + 0 +
  • +
  • + Suck + 1 + 62.7 + 0.2 + 0.01 + 0.118 + 1 + 1 + 0 +
  • + + +
  • + + LayingPawn + +
  • + -10 + 9 + 9 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 8 + 0 + -15.1 + 0.729 + 0.378 + 3 + 3 + 0 +
  • +
  • + 1 + 9 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • + +
  • + 9 + 9 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 8 + 0 + -15.1 + 0.729 + 0.378 + 3 + 3 + 0 +
  • +
  • + 1 + 9 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • + + +
  • + 9 + 9 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 120 + 9 + -15.1 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 30 + 9 + 7 + 0.674 + 0.378 + 3 + 3 + 0 +
  • +
  • + 1 + 9 + -14.1 + 0.674 + 0.378 + 3 + 3 + 0 + -10 +
  • + + + +
  • + + LayingPawn + +
  • + 43 + 9 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • +
  • + Fuck + 8 + -6.7 + 14.1 + -0.53 + 0.378 + 1 + 1 + 0 +
  • +
  • + 1 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • + +
  • + 9 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • +
  • + Fuck + 8 + -6.7 + 14.1 + -0.53 + 0.378 + 1 + 1 + 0 +
  • +
  • + 1 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • + +
  • + 9 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • +
  • + Cum + 120 + -6.7 + 14.1 + -0.53 + 0.378 + 1 + 1 + 0 +
  • +
  • + 30 + -6.7 + -7 + -0.53 + 0.378 + 1 + 1 + 0 +
  • +
  • + 43 + 1 + 8.7 + 15.1 + -0.70 + 0.378 + 1 + 1 + 0 +
  • + + + + + +
    + +
    + +
    diff --git a/1.4/Defs/AnimationDefs/Animations_SexToys.xml b/1.4/Defs/AnimationDefs/Animations_SexToys.xml new file mode 100644 index 0000000..320d3aa --- /dev/null +++ b/1.4/Defs/AnimationDefs/Animations_SexToys.xml @@ -0,0 +1,59 @@ + + + + diff --git a/1.4/Defs/AnimationDefs/Animations_Vanilla2.xml b/1.4/Defs/AnimationDefs/Animations_Vanilla2.xml new file mode 100644 index 0000000..71b02a9 --- /dev/null +++ b/1.4/Defs/AnimationDefs/Animations_Vanilla2.xml @@ -0,0 +1,378 @@ + + + + + + + \ No newline at end of file diff --git a/1.4/Defs/AnimationDefs/Animations_vanilla.xml b/1.4/Defs/AnimationDefs/Animations_vanilla.xml new file mode 100644 index 0000000..0fd61d5 --- /dev/null +++ b/1.4/Defs/AnimationDefs/Animations_vanilla.xml @@ -0,0 +1,2799 @@ + + + + + Doggystyle + + true + +
  • Vaginal
  • +
  • Anal
  • +
  • DoublePenetration
  • +
    + + +
  • AnalSex
  • +
  • AnalSexF
  • +
  • AnalRape
  • +
  • VaginalSex
  • +
  • VaginalSexF
  • +
  • VaginalRape
  • +
    + + +
  • + + +
  • Human
  • + + true + +
  • + +
  • Human
  • + + true + true + true + + (0, 0.2) + + +
    + + +
  • + Slow_Fuck + true + 612 + 0 + +
  • + +
  • + 0 + 10 + 27 + 0.298 + 0.166 + 0 + 1 + 2 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 2 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 2 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 2 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 2 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 2 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 2 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 2 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 2 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 1 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 1 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 1 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 1 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 1 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 1 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 1 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 1 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 1 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 1 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 1 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 1 +
  • + +
  • + 10 + 27 + 0.298 + 0.166 + 1 + 1 +
  • +
  • + 40 + 32 + 0.326 + 0.190 + 1 + 1 +
  • +
  • + 0 + 1 + 27 + 0.298 + 0.166 + 0 + 1 + 1 +
  • + + +
  • + LayingPawn + +
  • + 27 + 0 + 10 + 16.6 + -0.217 + 0.175 + 3 + 1 + 1 +
  • + +
  • + 40 + Fuck + -17 + -0.217 + 0.272 + 5.4 + 1 + 1 +
  • +
  • + 1 + 16.6 + -0.217 + 0.175 + 3 + 1 + 1 + 0 + 27 +
  • + + + + +
  • + Fast_Fuck + true + 609 + 0 + +
  • + +
  • + 8 + 27 + 0.298 + 0.166 + 1 + 1 + 1 + 0 +
  • +
  • + 12 + 32 + 0.326 + 0.190 + 4 + 1 + 1 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 1 + 1 + 1 + 0 +
  • + + +
  • + LayingPawn + +
  • + 27 + 8 + 11 + -0.217 + 0.175 + 8 + 1 + 1 + 0 +
  • + +
  • + 12 + Fuck + -12 + -0.217 + 0.272 + 9 + 1 + 1 +
  • +
  • + 1 + 11 + -0.217 + 0.175 + 8 + 1 + 1 + 0 + 27 +
  • + + + + +
  • + Cum + true + 300 + 0 + +
  • + +
  • + 8 + 27 + 0.298 + 0.166 + 0 + 1 + 1 + 0 +
  • +
  • + Cum + 100 + 32 + 0.326 + 0.190 + -1 + 1 + 1 + true +
  • +
  • + 12 + 35 + 0.326 + 0.190 + -14 + 1 + 1 +
  • +
  • + 1 + 27 + 0.298 + 0.166 + 0 + 1 + 1 + 0 +
  • + + +
  • + LayingPawn + +
  • + 27 + 8 + 11 + -0.217 + 0.175 + -8 + 1 + 1 + 0 +
  • +
  • + 100 + -12 + -0.217 + 0.272 + -9 + 1 + 1 +
  • +
  • + 12 + -15 + -0.227 + 0.272 + -4 + 1 + 1 +
  • +
  • + 1 + 11 + -0.217 + 0.175 + -8 + 1 + 1 + 0 + 27 +
  • + + + + +
    +
    + + Blowjob + + true + +
  • Oral
  • +
  • Fellatio
  • +
    + +
  • Handjob
  • +
  • HandjobF
  • +
  • HandjobRape
  • +
  • HandjobRapeF
  • + +
  • Breastjob
  • +
  • BreastjobF
  • +
  • BreastjobRape
  • +
  • BreastjobRapeF
  • + +
  • Fellatio
  • +
  • FellatioF
  • +
  • FellatioRape
  • +
  • FellatioRapeF
  • + +
  • Beakjob
  • +
  • BeakjobF
  • +
  • BeakjobRape
  • +
  • BeakjobRapeF
  • + + +
    + +
  • + + +
  • Human
  • + + + (0, -0.2) + + +
  • + +
  • Human
  • + + true + true + true + + (0, 0.2) + + +
    + +
  • + Slow_Suck + true + 1140 + 0 + +
  • + +
  • + 35 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • +
  • + Suck + 59 + 0 + 0 + -0.33 + 0 + 0 + -0.16 +
  • +
  • + 1 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • + +
  • + 35 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • +
  • + Suck + 59 + 0 + 0 + -0.33 + 0 + 0 + -0.15 +
  • +
  • + 1 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • + +
  • + 35 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • +
  • + Suck + 59 + + 6 + 0 + -0.33 + 0 + 0 + -0.13 +
  • +
  • + 1 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • + +
  • + 35 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • +
  • + Suck + 59 + 0 + -4 + 0 + -0.33 + 0 + 0 + -0.12 +
  • +
  • + 1 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • + + +
  • + LayingPawn + +
  • + 35 + 0 + 0 + 0 + 0.473 + 2 + 2 + 0 + 180 +
  • +
  • + 59 + 0 + 0 + 0.490 + 2 + 2 + -0.003 +
  • +
  • + 1 + 0 + 0 + 0 + 0.473 + 2 + 2 + 0 + 180 +
  • + + + + +
  • + Face_Fuck + true + 300 + 0 + +
  • + +
  • + 15 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • +
  • + Suck + 14 + 0 + 0 + -0.270 + 0 + 0 + -0.06 +
  • +
  • + 1 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • + + +
  • + LayingPawn + +
  • + 15 + 0 + 0 + 0 + 0.473 + 2 + 2 + 0 + 180 +
  • +
  • + 14 + 0 + 0 + 0.575 + 2 + 2 + -0.051 +
  • +
  • + 1 + 0 + 0 + 0 + 0.473 + 2 + 2 + 0 + 180 +
  • + + + + +
  • + Cum + true + 600 + 0 + +
  • + +
  • + 12 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • +
  • + 7 + 0 + 0 + -0.290 + 0 + 0 + -0.06 +
  • +
  • + 7 + Suck + 0 + 0 + -0.290 + 0 + 0 + -0.008 +
  • +
  • + 60 + 0 + 0 + -0.290 + 0 + 0 + -0.06 +
  • +
  • + 14 + 0 + 0 + -0.290 + 0 + 0 + -0.06 +
  • +
  • + 1 + 0 + 0 + 0 + -0.255 + 0 + 0 + 0 +
  • + + +
  • + LayingPawn + +
  • + 12 + 0 + 0 + 0 + 0.473 + 2 + 2 + 0 + 180 +
  • +
  • + 7 + Cum + 0 + 0 + 0.575 + 2 + 2 + -0.051 +
  • +
  • + 7 + 0 + 0 + 0.50 + 2 + 2 + -0.04 +
  • +
  • + true + 60 + 0 + 0 + 0.575 + 2 + 2 + -0.051 +
  • +
  • + 14 + 0 + 0 + 0.575 + 2 + 2 + -0.051 +
  • +
  • + 1 + 0 + 0 + 0 + 0.473 + 2 + 2 + 0 + 180 +
  • + + + + +
    + +
    + + ReverseStandAndCarry + + true + +
  • Anal
  • +
  • Vaginal
  • +
  • DoublePenetration
  • +
    + +
  • AnalSex
  • +
  • AnalSexF
  • +
  • AnalRape
  • +
  • VaginalSex
  • +
  • VaginalSexF
  • +
  • VaginalRape
  • +
    + +
  • + + +
  • Human
  • + + true + + (0, 0.2) + + +
  • + +
  • Human
  • + + true + true + true + + (0, 0.2) + + +
    + + +
  • + Slow_Fuck + true + 1080 + 0 + +
  • + +
  • + 30 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 29 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + + +
  • + LayingPawn + +
  • + 6 + 30 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 + Fuck + 29 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 1 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 + 6 +
  • + + + + + +
  • + Fast_Fuck + true + 780 + 0 + +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 2 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 2 + 0 +
  • + + + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 6 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 12 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + + +
  • + LayingPawn + +
  • + 6 + 13 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 + Fuck + 12 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 1 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 + 6 +
  • + + + + + +
  • + Cum + true + 415 + 0 + +
  • + +
  • + 3 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 4 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 3 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 4 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 3 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 4 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 7 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + +
  • + 3 + 10.6 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + 4 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • +
  • + true + 75 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 27 + 6.04 + 15 + -0.175 + 0.437 + 3 + 3 + 0 +
  • +
  • + 1 + 11.23 + 11.23 + -0.183 + 0.468 + 3 + 3 + 0 +
  • + + +
  • + LayingPawn + +
  • + 6 + 7 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 + Fuck + 7 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 6 + 1 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • + +
  • + 6 + 7 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 + Fuck + 7 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 6 + 1 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • + +
  • + 6 + 7 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 + Fuck + 7 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 6 + 1 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • + +
  • + 6 + 7 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • +
  • + 40 + Cum + 75 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 40 + 27 + 17.11 + -2.87 + 0.114 + 0.359 + 3 + 3 + 0 +
  • +
  • + 6 + 1 + -3.18 + -0.41 + 0.122 + 0.356 + 3 + 3 + 0 +
  • + + + + +
    + +
    + + Cowgirl + + true + +
  • Anal
  • +
  • Vaginal
  • +
  • DoublePenetration
  • +
    + + +
  • AnalSex
  • +
  • AnalSexF
  • +
  • AnalRapeF
  • +
  • VaginalSex
  • +
  • VaginalSexF
  • +
  • VaginalRapeF
  • +
    + + + +
  • + + +
  • Human
  • + + true + true + + (0, 0.2) + + + +
  • + +
  • Human
  • + + true + true + + (0, -0.2) + + + +
    + + +
  • + Slow_Fuck + true + 1340 + 0 + +
  • + + +
  • + 16 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 17 + 3.5 + 0 + -0.03 + 0.624 + 2 + 2 + -0.02 +
  • +
  • + 16 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 17 + -3.5 + 0 + 0.03 + 0.624 + 2 + 2 + -0.02 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + +
  • + 16 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 17 + 3.5 + 0 + -0.03 + 0.624 + 2 + 2 + -0.02 +
  • +
  • + 16 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 17 + -3.5 + 0 + 0.03 + 0.624 + 2 + 2 + -0.02 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + + +
  • + 33 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 33 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + +
  • + 33 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 33 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + + +
  • + LayingPawn + +
  • + 16 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 17 + 180 + 180 + 0 + -0.347 + 2 + 2 + 0.015 + -15 +
  • +
  • + 16 + 180 + 180 + 0 + -0.331 + 2 + 2 + 0.03 + 0 +
  • +
  • + 17 + 180 + 180 + 0 + -0.315 + 2 + 2 + 0.045 + 15 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 16 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 17 + 180 + 180 + 0 + -0.347 + 2 + 2 + 0.015 + -15 +
  • +
  • + 16 + 180 + 180 + 0 + -0.331 + 2 + 2 + 0.03 + 0 +
  • +
  • + 17 + 180 + 180 + 0 + -0.315 + 2 + 2 + 0.045 + 15 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 33 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 33 + 180 + 180 + 0 + -0.315 + 2 + 2 + 0.045 + 0 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 33 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 33 + 180 + 180 + 0 + -0.315 + 2 + 2 + 0.045 + 0 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • + + + + +
  • + Fast_Fuck + true + 780 + 0 + +
  • + +
  • + 13 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 13 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + + +
  • + LayingPawn + +
  • + 13 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 13 + 180 + 180 + 0 + -0.313 + 2 + 2 + 0.045 + 0 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • + + + + +
  • + Cum + true + 594 + 0 + +
  • + +
  • + 10 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 10 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + +
  • + 10 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 10 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + 1 + Fuck + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + +
  • + 10 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + 10 + 0 + 0 + 0 + 0.694 + 2 + 2 + -0.03 +
  • +
  • + true + 45 + Cum + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • +
  • + true + 40 + 0 + 0 + 0 + 0.534 + 2 + 2 + 0 +
  • +
  • + 1 + 0 + 0 + 0 + 0.554 + 2 + 2 + 0 +
  • + + +
  • + LayingPawn + +
  • + 10 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • +
  • + 10 + 180 + 180 + 0 + -0.313 + 2 + 2 + 0.045 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 +
  • + +
  • + 10 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 +
  • +
  • + 10 + 180 + 180 + 0 + -0.313 + 2 + 2 + 0.045 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 +
  • + +
  • + 10 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 +
  • +
  • + 10 + 180 + 180 + 0 + -0.313 + 2 + 2 + 0.045 +
  • +
  • + 45 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 +
  • +
  • + 40 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 +
  • +
  • + 1 + 180 + 180 + 0 + -0.363 + 2 + 2 + 0 + 0 +
  • + + + + +
    + +
    +
    + + + diff --git a/1.4/Defs/AnimationDefs/TemplateAnimation.xml b/1.4/Defs/AnimationDefs/TemplateAnimation.xml new file mode 100644 index 0000000..0305903 --- /dev/null +++ b/1.4/Defs/AnimationDefs/TemplateAnimation.xml @@ -0,0 +1,54 @@ + + + + diff --git a/1.4/Defs/MainTabDefs/MainButtonDef.xml b/1.4/Defs/MainTabDefs/MainButtonDef.xml new file mode 100644 index 0000000..0674d24 --- /dev/null +++ b/1.4/Defs/MainTabDefs/MainButtonDef.xml @@ -0,0 +1,15 @@ + + + + + OffsetManager + + Control pawn offsets + Rimworld_Animations.MainTabWindow_OffsetConfigure + 54 + false + UI/MainTab + true + + + \ No newline at end of file diff --git a/1.4/Defs/SoundDefs/Sounds_Sex.xml b/1.4/Defs/SoundDefs/Sounds_Sex.xml new file mode 100644 index 0000000..f05a1a8 --- /dev/null +++ b/1.4/Defs/SoundDefs/Sounds_Sex.xml @@ -0,0 +1,212 @@ + + + + + Cum + MapOnly + + 1 + 1 + +
  • + +
  • + Sex/cum +
  • + + + 30 + 40 + + + 0.8 + 1.2 + + + 0 + 51.86047 + + False + +
    +
    + + Sex + MapOnly + + 1 + 1 + +
  • + +
  • + Sex/kucyu04 +
  • + + + 16 + 16 + + + 0.8 + 1.2 + + + 0 + 51.86047 + + False + +
    +
    + + Suck + MapOnly + + 1 + 1 + +
  • + +
  • + Sex/Suck/Suck_1 +
  • +
  • + Sex/Suck/Suck_2 +
  • +
  • + Sex/Suck/Suck_3 +
  • +
  • + Sex/Suck/Suck_4 +
  • +
  • + Sex/Suck/Suck_5 +
  • +
  • + Sex/Suck/Suck_6 +
  • +
  • + Sex/Suck/Suck_7 +
  • +
  • + Sex/Suck/Suck_8 +
  • +
  • + Sex/Suck/Suck_9 +
  • +
  • + Sex/Suck/Suck_10 +
  • + + + 20 + 35 + + + 1.0 + 1.0 + + + 0 + 51.86047 + + NeverTwice + false + +
    +
    + + Fuck + MapOnly + + 1 + 1 + +
  • + +
  • + Sex/Clap_1 +
  • +
  • + Sex/Clap_2 +
  • +
  • + Sex/Clap_3 +
  • +
  • + Sex/Clap_4 +
  • +
  • + Sex/Clap_5 +
  • +
  • + Sex/Clap_6 +
  • +
  • + Sex/Clap_7 +
  • +
  • + Sex/Clap_8 +
  • + + + 45 + 70 + + + 1.0 + 1.0 + + + 0 + 51.86047 + + NeverTwice + false + +
    +
    + + Slimy + MapOnly + + 1 + 1 + +
  • + +
  • + Sex/Slime/Slimy1 +
  • +
  • + Sex/Slime/Slimy2 +
  • +
  • + Sex/Slime/Slimy3 +
  • +
  • + Sex/Slime/Slimy4 +
  • +
  • + Sex/Slime/Slimy5 +
  • + + + 45 + 75 + + + 1.4 + 1.8 + + + 0 + 100 + + NeverTwice + false + +
    +
    +
    \ No newline at end of file diff --git a/1.4/Patch_HatsDisplaySelection/Patch_HatsDisplaySelection.csproj b/1.4/Patch_HatsDisplaySelection/Patch_HatsDisplaySelection.csproj new file mode 100644 index 0000000..8da21a6 --- /dev/null +++ b/1.4/Patch_HatsDisplaySelection/Patch_HatsDisplaySelection.csproj @@ -0,0 +1,75 @@ + + + + + Debug + AnyCPU + {BA766964-1716-422D-A09E-29426F8EB9D5} + Library + Properties + Patch_HatsDisplaySelection + Patch_HatsDisplaySelection + v4.7.2 + 512 + true + + + false + none + false + 1.2\Assemblies\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\..\workshop\content\294100\2009463077\Current\Assemblies\0Harmony.dll + False + + + ..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll + False + + + ..\..\..\..\..\workshop\content\294100\1542291825\1.2\Assemblies\HatDisplaySelection.dll + False + + + ..\1.2\Assemblies\Rimworld-Animations.dll + False + + + + + + + + + + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll + False + + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll + False + + + + + + + + + + + \ No newline at end of file diff --git a/1.4/Patches/AnimationPatchHSK.xml b/1.4/Patches/AnimationPatchHSK.xml new file mode 100644 index 0000000..74038ea --- /dev/null +++ b/1.4/Patches/AnimationPatchHSK.xml @@ -0,0 +1,31 @@ + + + + +
  • Core SK
  • +
    + + + +
  • + Defs/ThingDef/comps + Always + + Defs/ThingDef + + + + +
  • + +
  • + Defs/ThingDef[@Name="BaseAnimalPawn" or @Name="SK_BasePawn" or @Name="BasePawnSkynet"]/comps + +
  • + +
  • + +
    +
    +
    +
    diff --git a/1.4/Patches/AnimationPatch_CompBodyAnimator.xml b/1.4/Patches/AnimationPatch_CompBodyAnimator.xml new file mode 100644 index 0000000..e645747 --- /dev/null +++ b/1.4/Patches/AnimationPatch_CompBodyAnimator.xml @@ -0,0 +1,35 @@ + + + + Always + +
  • + Always + Defs/ThingDef[race][not(comps)] + + + +
  • +
  • + Always + Defs/AlienRace.ThingDef_AlienRace[not(comps)] + + + +
  • + +
  • + Defs/ThingDef[@Name="BasePawn"]/comps + +
  • + +
  • +
  • + Defs/AlienRace.ThingDef_AlienRace/comps + +
  • + +
  • +
    +
    +
    diff --git a/1.4/Patches/CompPatches/AutoCleaner.xml b/1.4/Patches/CompPatches/AutoCleaner.xml new file mode 100644 index 0000000..c2ad860 --- /dev/null +++ b/1.4/Patches/CompPatches/AutoCleaner.xml @@ -0,0 +1,19 @@ + + + + Always + +
  • + /Defs/ThingDef[@Name="BaseBaseAutocleaner"]/comps + Always + + /Defs/ThingDef[@Name="BaseBaseAutocleaner"]/comps + +
  • + + +
  • +
    +
    +
    + diff --git a/1.4/Patches/CompPatches/CombatExtended.xml b/1.4/Patches/CompPatches/CombatExtended.xml new file mode 100644 index 0000000..7d35127 --- /dev/null +++ b/1.4/Patches/CompPatches/CombatExtended.xml @@ -0,0 +1,18 @@ + + + + Always + +
  • + /Defs/ThingDef[@Name="BasePawnSimple"]/comps + Always + + /Defs/ThingDef[@Name="BasePawnSimple"]/comps + +
  • + + +
  • +
    +
    +
    diff --git a/1.4/Patches/CompPatches/ZombieLand.xml b/1.4/Patches/CompPatches/ZombieLand.xml new file mode 100644 index 0000000..e950e0e --- /dev/null +++ b/1.4/Patches/CompPatches/ZombieLand.xml @@ -0,0 +1,18 @@ + + + + Always + +
  • + /Defs/ThingDef[@Name="BaseZombie"]/comps + Always + + /Defs/ThingDef[@Name="BaseZombie"]/comps + +
  • + + +
  • +
    +
    +
    diff --git a/1.4/Patches/CompatibilityPatch_FacialAnimation.xml b/1.4/Patches/CompatibilityPatch_FacialAnimation.xml new file mode 100644 index 0000000..125d79f --- /dev/null +++ b/1.4/Patches/CompatibilityPatch_FacialAnimation.xml @@ -0,0 +1,130 @@ + + + + +
  • [NL] Facial Animation - WIP
  • +
    + + Always + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/targetJobs + Always + +
  • RJW_Masturbate
  • +
  • GettinBred
  • +
  • Bestiality
  • +
  • BestialityForFemale
  • +
  • ViolateCorpse
  • +
  • Quickie
  • +
  • GettingQuickie
  • +
  • GettinRaped
  • +
  • JoinInBed
  • +
  • GettinLoved
  • +
  • GettinLicked
  • +
  • GettinSucked
  • +
  • WhoreIsServingVisitors
  • +
  • JoinInBedAnimation
  • +
  • GettinLovedAnimation
  • + + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="WaitCombat" or defName="Wait_Combat_Rare"]/targetJobs + Always + +
  • RapeComfortPawn
  • +
  • RandomRape
  • +
  • RapeEnemy
  • + + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="StandAndBeSociallyActive"]/targetJobs + Always + +
  • WhoreInvitingVisitors
  • + + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Wear" or defName="Wear2" or defName="Wear3"]/targetJobs + Always + +
  • CleanSelf
  • +
  • StruggleInBondageGear
  • + + +
  • + +
  • Rimworld-Animations
  • + + + Always + +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/animationFrames/li[1]/headOffset + Always +
  • +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin"]/animationFrames/li[2]/headOffset + Always +
  • +
  • + /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin"]/animationFrames/li[3]/headOffset + Always +
  • +
    +
    + +
    +
    +
    +
    + + \ No newline at end of file diff --git a/1.4/Patches/CompatibilityPatch_HCSK.xml b/1.4/Patches/CompatibilityPatch_HCSK.xml new file mode 100644 index 0000000..ead8783 --- /dev/null +++ b/1.4/Patches/CompatibilityPatch_HCSK.xml @@ -0,0 +1,39 @@ + + + + + +
  • Core SK
  • +
    + + Always + +
  • + /Defs/ThingDef/comps + Always + + /Defs/ThingDef + + + + +
  • + +
  • + /Defs/ThingDef[@Name="SK_BasePawn"]/comps + +
  • + +
  • + +
  • + /Defs/ThingDef[@Name="BaseAnimalPawn"]/comps + +
  • + +
  • +
    +
    +
    + +
    \ No newline at end of file diff --git a/1.4/Patches/RacePatches/Epona race Renaissance.xml b/1.4/Patches/RacePatches/Epona race Renaissance.xml new file mode 100644 index 0000000..f39b509 --- /dev/null +++ b/1.4/Patches/RacePatches/Epona race Renaissance.xml @@ -0,0 +1,19 @@ + + + + +
  • Epona race Renaissance
  • +
    + + +
  • + /Defs/AlienRace.ThingDef_AlienRace[defName = "Alien_Epona"]/alienRace/generalSettings/alienPartGenerator/bodyAddons/li[hediffGraphics/Epona_OHPG_female="Things/Pawn/Addons/Breasts/Breasts"]/drawnInBed + + false + +
  • +
    +
    +
    + +
    diff --git a/1.4/Patches/RacePatches/Nyaron.xml b/1.4/Patches/RacePatches/Nyaron.xml new file mode 100644 index 0000000..0a7a08e --- /dev/null +++ b/1.4/Patches/RacePatches/Nyaron.xml @@ -0,0 +1,19 @@ + + + + +
  • Nyaron race
  • +
    + + +
  • + /Defs/AlienRace.ThingDef_AlienRace[defName = "Alien_Nyaron"]/alienRace/generalSettings/alienPartGenerator/bodyAddons/li[bodyPart="tail"] + + false + +
  • +
    +
    +
    + +
    diff --git a/1.4/Sounds/Sex/Clap_1.wav b/1.4/Sounds/Sex/Clap_1.wav new file mode 100644 index 0000000..bccd0f2 Binary files /dev/null and b/1.4/Sounds/Sex/Clap_1.wav differ diff --git a/1.4/Sounds/Sex/Clap_2.wav b/1.4/Sounds/Sex/Clap_2.wav new file mode 100644 index 0000000..a382f59 Binary files /dev/null and b/1.4/Sounds/Sex/Clap_2.wav differ diff --git a/1.4/Sounds/Sex/Clap_3.wav b/1.4/Sounds/Sex/Clap_3.wav new file mode 100644 index 0000000..65cf39b Binary files /dev/null and b/1.4/Sounds/Sex/Clap_3.wav differ diff --git a/1.4/Sounds/Sex/Clap_4.wav b/1.4/Sounds/Sex/Clap_4.wav new file mode 100644 index 0000000..3ae1b3e Binary files /dev/null and b/1.4/Sounds/Sex/Clap_4.wav differ diff --git a/1.4/Sounds/Sex/Clap_5.wav b/1.4/Sounds/Sex/Clap_5.wav new file mode 100644 index 0000000..65144e7 Binary files /dev/null and b/1.4/Sounds/Sex/Clap_5.wav differ diff --git a/1.4/Sounds/Sex/Clap_6.wav b/1.4/Sounds/Sex/Clap_6.wav new file mode 100644 index 0000000..0026325 Binary files /dev/null and b/1.4/Sounds/Sex/Clap_6.wav differ diff --git a/1.4/Sounds/Sex/Clap_7.wav b/1.4/Sounds/Sex/Clap_7.wav new file mode 100644 index 0000000..6d7de2a Binary files /dev/null and b/1.4/Sounds/Sex/Clap_7.wav differ diff --git a/1.4/Sounds/Sex/Clap_8.wav b/1.4/Sounds/Sex/Clap_8.wav new file mode 100644 index 0000000..1af5710 Binary files /dev/null and b/1.4/Sounds/Sex/Clap_8.wav differ diff --git a/1.4/Sounds/Sex/Slime/Slimy1.wav b/1.4/Sounds/Sex/Slime/Slimy1.wav new file mode 100644 index 0000000..3cfbd74 Binary files /dev/null and b/1.4/Sounds/Sex/Slime/Slimy1.wav differ diff --git a/1.4/Sounds/Sex/Slime/Slimy2.wav b/1.4/Sounds/Sex/Slime/Slimy2.wav new file mode 100644 index 0000000..36a9197 Binary files /dev/null and b/1.4/Sounds/Sex/Slime/Slimy2.wav differ diff --git a/1.4/Sounds/Sex/Slime/Slimy3.wav b/1.4/Sounds/Sex/Slime/Slimy3.wav new file mode 100644 index 0000000..40aff1e Binary files /dev/null and b/1.4/Sounds/Sex/Slime/Slimy3.wav differ diff --git a/1.4/Sounds/Sex/Slime/Slimy4.wav b/1.4/Sounds/Sex/Slime/Slimy4.wav new file mode 100644 index 0000000..0b6404e Binary files /dev/null and b/1.4/Sounds/Sex/Slime/Slimy4.wav differ diff --git a/1.4/Sounds/Sex/Slime/Slimy5.wav b/1.4/Sounds/Sex/Slime/Slimy5.wav new file mode 100644 index 0000000..ea310db Binary files /dev/null and b/1.4/Sounds/Sex/Slime/Slimy5.wav differ diff --git a/1.4/Sounds/Sex/Suck/Suck_1.wav b/1.4/Sounds/Sex/Suck/Suck_1.wav new file mode 100644 index 0000000..4f1eafd Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Suck_1.wav differ diff --git a/1.4/Sounds/Sex/Suck/Suck_10.wav b/1.4/Sounds/Sex/Suck/Suck_10.wav new file mode 100644 index 0000000..284cda3 Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Suck_10.wav differ diff --git a/1.4/Sounds/Sex/Suck/Suck_2.wav b/1.4/Sounds/Sex/Suck/Suck_2.wav new file mode 100644 index 0000000..a8305c1 Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Suck_2.wav differ diff --git a/1.4/Sounds/Sex/Suck/Suck_3.wav b/1.4/Sounds/Sex/Suck/Suck_3.wav new file mode 100644 index 0000000..95e7348 Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Suck_3.wav differ diff --git a/1.4/Sounds/Sex/Suck/Suck_4.wav b/1.4/Sounds/Sex/Suck/Suck_4.wav new file mode 100644 index 0000000..753a023 Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Suck_4.wav differ diff --git a/1.4/Sounds/Sex/Suck/Suck_5.wav b/1.4/Sounds/Sex/Suck/Suck_5.wav new file mode 100644 index 0000000..8ecda9c Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Suck_5.wav differ diff --git a/1.4/Sounds/Sex/Suck/Suck_6.wav b/1.4/Sounds/Sex/Suck/Suck_6.wav new file mode 100644 index 0000000..08567d6 Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Suck_6.wav differ diff --git a/1.4/Sounds/Sex/Suck/Suck_7.wav b/1.4/Sounds/Sex/Suck/Suck_7.wav new file mode 100644 index 0000000..a63b0e4 Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Suck_7.wav differ diff --git a/1.4/Sounds/Sex/Suck/Suck_8.wav b/1.4/Sounds/Sex/Suck/Suck_8.wav new file mode 100644 index 0000000..320da09 Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Suck_8.wav differ diff --git a/1.4/Sounds/Sex/Suck/Suck_9.wav b/1.4/Sounds/Sex/Suck/Suck_9.wav new file mode 100644 index 0000000..7ab538a Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Suck_9.wav differ diff --git a/1.4/Sounds/Sex/Suck/Swallow_1.wav b/1.4/Sounds/Sex/Suck/Swallow_1.wav new file mode 100644 index 0000000..f3276cc Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Swallow_1.wav differ diff --git a/1.4/Sounds/Sex/Suck/Swallow_2.wav b/1.4/Sounds/Sex/Suck/Swallow_2.wav new file mode 100644 index 0000000..09a7a00 Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Swallow_2.wav differ diff --git a/1.4/Sounds/Sex/Suck/Swallow_3.wav b/1.4/Sounds/Sex/Suck/Swallow_3.wav new file mode 100644 index 0000000..2817b29 Binary files /dev/null and b/1.4/Sounds/Sex/Suck/Swallow_3.wav differ diff --git a/1.4/Sounds/Sex/cum.wav b/1.4/Sounds/Sex/cum.wav new file mode 100644 index 0000000..ef98437 Binary files /dev/null and b/1.4/Sounds/Sex/cum.wav differ diff --git a/1.4/Sounds/Sex/kucyu04.wav b/1.4/Sounds/Sex/kucyu04.wav new file mode 100644 index 0000000..3ae1ce8 Binary files /dev/null and b/1.4/Sounds/Sex/kucyu04.wav differ diff --git a/1.4/Source/Actors/Actor.cs b/1.4/Source/Actors/Actor.cs new file mode 100644 index 0000000..3b382dd --- /dev/null +++ b/1.4/Source/Actors/Actor.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace Rimworld_Animations { + public class Actor { + public List defNames; + public List requiredGenitals; + public List raceOffsets; + public List blacklistedRaces; + public bool initiator = false; + public string gender; + public bool isFucking = false; + public bool isFucked = false; + public bool controlGenitalAngle = false; + public List bodyDefTypes = new List(); + public BodyTypeOffset bodyTypeOffset = new BodyTypeOffset(); + public Vector3 offset = new Vector2(0, 0); + public List requiredGender; + public List tags = new List(); + } +} diff --git a/Source/Comps/CompProperties_ThingAnimator.cs b/1.4/Source/Actors/AlienRaceOffset.cs similarity index 57% rename from Source/Comps/CompProperties_ThingAnimator.cs rename to 1.4/Source/Actors/AlienRaceOffset.cs index f9b76bd..a5bbe20 100644 --- a/Source/Comps/CompProperties_ThingAnimator.cs +++ b/1.4/Source/Actors/AlienRaceOffset.cs @@ -3,9 +3,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using UnityEngine; namespace Rimworld_Animations { - class CompProperties_ThingAnimator - { + public class AlienRaceOffset { + + public string defName; + public Vector2 offset; + } } diff --git a/1.4/Source/Actors/BodyTypeOffset.cs b/1.4/Source/Actors/BodyTypeOffset.cs new file mode 100644 index 0000000..82a23a3 --- /dev/null +++ b/1.4/Source/Actors/BodyTypeOffset.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace Rimworld_Animations { + public class BodyTypeOffset { + + public Vector2? Male; + public Vector2? Female; + public Vector2? Thin; + public Vector2? Hulk; + public Vector2? Fat; + + } +} diff --git a/1.4/Source/Animations/AnimationStage.cs b/1.4/Source/Animations/AnimationStage.cs new file mode 100644 index 0000000..7a1304e --- /dev/null +++ b/1.4/Source/Animations/AnimationStage.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rimworld_Animations { + public class AnimationStage + { + public string stageName; + public int stageIndex; + public int playTimeTicks = 0; + public int playTimeTicksQuick = -1; + public bool isLooping; + public List animationClips; + public List tags = new List(); + + public void initialize() { + foreach (BaseAnimationClip clip in animationClips) { + clip.buildSimpleCurves(); + //select playTimeTicks as longest playtime of all the animations + if(clip.duration > playTimeTicks) { + playTimeTicks = clip.duration; + } + } + } + } +} diff --git a/1.4/Source/Animations/Clips/BaseAnimationClip.cs b/1.4/Source/Animations/Clips/BaseAnimationClip.cs new file mode 100644 index 0000000..aa35b31 --- /dev/null +++ b/1.4/Source/Animations/Clips/BaseAnimationClip.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RimWorld; +using Verse; + +namespace Rimworld_Animations { + public abstract class BaseAnimationClip + { + public Dictionary SoundEffects = new Dictionary(); + public List types; //types of participants + public int duration; + public abstract void buildSimpleCurves(); + public string soundDef = null; //for playing sounds + public int actor; + public List tags = new List(); + } +} diff --git a/1.4/Source/Animations/Clips/PawnAnimationClip.cs b/1.4/Source/Animations/Clips/PawnAnimationClip.cs new file mode 100644 index 0000000..e9d2489 --- /dev/null +++ b/1.4/Source/Animations/Clips/PawnAnimationClip.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RimWorld; +using Verse; + +namespace Rimworld_Animations { + public class PawnAnimationClip : BaseAnimationClip { + + public List keyframes; + public AltitudeLayer layer = AltitudeLayer.Pawn; + + public Dictionary quiver = new Dictionary(); + public SimpleCurve GenitalAngle = new SimpleCurve(); + public SimpleCurve BodyAngle = new SimpleCurve(); + public SimpleCurve HeadAngle = new SimpleCurve(); + public SimpleCurve HeadBob = new SimpleCurve(); + public SimpleCurve BodyOffsetX = new SimpleCurve(); + public SimpleCurve BodyOffsetZ = new SimpleCurve(); + public SimpleCurve HeadFacing = new SimpleCurve(); + public SimpleCurve BodyFacing = new SimpleCurve(); + + + public override void buildSimpleCurves() { + + + int duration = 0; + //getting the length of the whole clip + foreach(PawnKeyframe frame in keyframes) { + duration += frame.tickDuration; + } + + //guarantees loops don't get cut off mid-anim + this.duration = duration; + + int keyframePosition = 0; + foreach (PawnKeyframe frame in keyframes) { + + if (frame.atTick.HasValue) { + if (frame.bodyAngle.HasValue) + BodyAngle.Add((float)frame.atTick / (float)duration, frame.bodyAngle.Value, true); + + if (frame.headAngle.HasValue) + HeadAngle.Add((float)frame.atTick / (float)duration, frame.headAngle.Value, true); + + if (frame.bodyOffsetX.HasValue) + BodyOffsetX.Add((float)frame.atTick / (float)duration, frame.bodyOffsetX.Value, true); + + if (frame.bodyOffsetZ.HasValue) + BodyOffsetZ.Add((float)frame.atTick / (float)duration, frame.bodyOffsetZ.Value, true); + + if (frame.headFacing.HasValue) + HeadFacing.Add((float)frame.atTick / (float)duration, frame.headFacing.Value, true); + + if (frame.bodyFacing.HasValue) + BodyFacing.Add((float)frame.atTick / (float)duration, frame.bodyFacing.Value, true); + + if (frame.headBob.HasValue) + HeadBob.Add((float)frame.atTick / (float)duration, frame.headBob.Value, true); + + if (frame.genitalAngle.HasValue) + GenitalAngle.Add((float)frame.atTick / (float)duration, frame.genitalAngle.Value, true); + + if (frame.soundEffect != null) { + SoundEffects.Add((int)frame.atTick, frame.soundEffect); + } + + + } + else { + if (frame.bodyAngle.HasValue) + BodyAngle.Add((float)keyframePosition / (float)duration, frame.bodyAngle.Value, true); + + if (frame.headAngle.HasValue) + HeadAngle.Add((float)keyframePosition / (float)duration, frame.headAngle.Value, true); + + if (frame.bodyOffsetX.HasValue) + BodyOffsetX.Add((float)keyframePosition / (float)duration, frame.bodyOffsetX.Value, true); + + if (frame.bodyOffsetZ.HasValue) + BodyOffsetZ.Add((float)keyframePosition / (float)duration, frame.bodyOffsetZ.Value, true); + + if (frame.headFacing.HasValue) + HeadFacing.Add((float)keyframePosition / (float)duration, frame.headFacing.Value, true); + + if (frame.bodyFacing.HasValue) + BodyFacing.Add((float)keyframePosition / (float)duration, frame.bodyFacing.Value, true); + + if (frame.headBob.HasValue) + HeadBob.Add((float)keyframePosition / (float)duration, frame.headBob.Value, true); + + if (frame.genitalAngle.HasValue) + GenitalAngle.Add((float)keyframePosition / (float)duration, frame.genitalAngle.Value, true); + + if (frame.soundEffect != null) { + SoundEffects.Add(keyframePosition, frame.soundEffect); + } + + if(frame.tickDuration != 1 && frame.quiver.HasValue) { + + quiver.Add(keyframePosition, true); + quiver.Add(keyframePosition + frame.tickDuration - 1, false); + } + keyframePosition += frame.tickDuration; + + } + + } + + } + + } +} diff --git a/1.4/Source/Animations/Clips/ThingAnimationClip.cs b/1.4/Source/Animations/Clips/ThingAnimationClip.cs new file mode 100644 index 0000000..26f4d4c --- /dev/null +++ b/1.4/Source/Animations/Clips/ThingAnimationClip.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using RimWorld; + +namespace Rimworld_Animations { + public class ThingAnimationClip : BaseAnimationClip + { + public List keyframes; + + public SimpleCurve PositionX = new SimpleCurve(); + public SimpleCurve PositionZ = new SimpleCurve(); + public SimpleCurve Rotation = new SimpleCurve(); + + + public override void buildSimpleCurves() { + int duration = 0; + //getting the length of the whole clip + foreach (ThingKeyframe frame in keyframes) + { + duration += frame.tickDuration; + } + + //guarantees loops don't get cut off mid-anim + this.duration = duration; + + int keyframePosition = 0; + foreach (ThingKeyframe frame in keyframes) + { + + if (frame.atTick.HasValue) + { + if (frame.positionX.HasValue) + PositionX.Add((float)frame.atTick / (float)duration, frame.positionX.Value, true); + + if (frame.positionZ.HasValue) + PositionZ.Add((float)frame.atTick / (float)duration, frame.positionZ.Value, true); + + if (frame.rotation.HasValue) + Rotation.Add((float)frame.atTick / (float)duration, frame.rotation.Value, true); + + if (frame.soundEffect != null) + { + SoundEffects.Add((int)frame.atTick, frame.soundEffect); + } + + + } + else + { + if (frame.positionX.HasValue) + PositionX.Add((float)keyframePosition / (float)duration, frame.positionX.Value, true); + + if (frame.positionZ.HasValue) + PositionZ.Add((float)keyframePosition / (float)duration, frame.positionZ.Value, true); + + if (frame.rotation.HasValue) + Rotation.Add((float)keyframePosition / (float)duration, frame.rotation.Value, true); + + if (frame.soundEffect != null) + { + SoundEffects.Add(keyframePosition, frame.soundEffect); + } + keyframePosition += frame.tickDuration; + + } + + } + } + } +} diff --git a/1.4/Source/Animations/Keyframes/Keyframe.cs b/1.4/Source/Animations/Keyframes/Keyframe.cs new file mode 100644 index 0000000..8cd859d --- /dev/null +++ b/1.4/Source/Animations/Keyframes/Keyframe.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rimworld_Animations { + public abstract class Keyframe + { + public int tickDuration = 1; + public float? atTick; + public string soundEffect; + public List tags = new List(); + } +} diff --git a/1.4/Source/Animations/Keyframes/PawnKeyframe.cs b/1.4/Source/Animations/Keyframes/PawnKeyframe.cs new file mode 100644 index 0000000..e710981 --- /dev/null +++ b/1.4/Source/Animations/Keyframes/PawnKeyframe.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace Rimworld_Animations { + public class PawnKeyframe : Keyframe + { + public float? bodyAngle; + public float? headAngle; + + public float? genitalAngle; + + public float? bodyOffsetZ; + public float? bodyOffsetX; + + public float? headBob; + //todo: add headOffsets l/r? + + public int? bodyFacing; + public int? headFacing; + + public bool? quiver; + + } +} diff --git a/Source/Comps/CompThingAnimator.cs b/1.4/Source/Animations/Keyframes/ThingKeyframe.cs similarity index 53% rename from Source/Comps/CompThingAnimator.cs rename to 1.4/Source/Animations/Keyframes/ThingKeyframe.cs index bb3c944..6604f5e 100644 --- a/Source/Comps/CompThingAnimator.cs +++ b/1.4/Source/Animations/Keyframes/ThingKeyframe.cs @@ -5,7 +5,14 @@ using System.Text; using System.Threading.Tasks; namespace Rimworld_Animations { - class CompThingAnimator + public class ThingKeyframe : Keyframe { + + public float? positionX; + public float? positionZ; + public float? rotation; + + + } } diff --git a/1.4/Source/Comps/CompBodyAnimator.cs b/1.4/Source/Comps/CompBodyAnimator.cs new file mode 100644 index 0000000..5d355a6 --- /dev/null +++ b/1.4/Source/Comps/CompBodyAnimator.cs @@ -0,0 +1,529 @@ +using System; +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.Sound; + +namespace Rimworld_Animations { + public class CompBodyAnimator : ThingComp + { + public Pawn pawn => base.parent as Pawn; + public PawnGraphicSet Graphics; + + //public CompProperties_BodyAnimator Props => (CompProperties_BodyAnimator)(object)base.props; + + public bool isAnimating { + get { + return Animating; + } + set { + Animating = value; + + if (value == true) { + SexUtility.DrawNude(pawn); + } else { + pawn.Drawer.renderer.graphics.ResolveAllGraphics(); + actorsInCurrentAnimation = null; + } + + PortraitsCache.SetDirty(pawn); + } + } + private bool Animating = false; + private bool mirror = false, quiver = false, shiver = false; + private int actor; + + private int lastDrawFrame = -1; + + private int animTicks = 0, stageTicks = 0, clipTicks = 0; + private int curStage = 0; + private float clipPercent = 0; + + public Vector3 anchor = Vector3.zero, deltaPos = Vector3.zero, headBob = Vector3.zero; + public float bodyAngle = 0, headAngle = 0, genitalAngle = 0; + public Rot4 headFacing = Rot4.North, bodyFacing = Rot4.North; + + public List actorsInCurrentAnimation; + + public bool controlGenitalAngle = false; + public bool fastAnimForQuickie = false; + + private AnimationDef anim; + private AnimationStage stage { + get + { + return anim.animationStages[curStage]; + } + + } + private PawnAnimationClip clip => (PawnAnimationClip)stage.animationClips[actor]; + + public bool Mirror { + get { + return mirror; + } + } + + public void setAnchor(IntVec3 pos) + { + anchor = pos.ToVector3Shifted(); + } + public void setAnchor(Thing thing) { + + //center on bed + if(thing is Building_Bed) { + anchor = thing.Position.ToVector3(); + if (((Building_Bed)thing).SleepingSlotsCount == 2) { + if (thing.Rotation.AsInt == 0) { + anchor.x += 1; + anchor.z += 1; + } + else if (thing.Rotation.AsInt == 1) { + anchor.x += 1; + } + else if(thing.Rotation.AsInt == 3) { + anchor.z += 1; + } + + } + else { + if(thing.Rotation.AsInt == 0) { + anchor.x += 0.5f; + anchor.z += 1f; + } + else if(thing.Rotation.AsInt == 1) { + anchor.x += 1f; + anchor.z += 0.5f; + } + else if(thing.Rotation.AsInt == 2) { + anchor.x += 0.5f; + } else { + anchor.z += 0.5f; + } + } + } + else { + anchor = thing.Position.ToVector3Shifted(); + } + } + public void StartAnimation(AnimationDef anim, List actors, int actor, bool mirror = false, bool shiver = false, bool fastAnimForQuickie = false) { + + actorsInCurrentAnimation = actors; + + if (anim.actors.Count <= actor) + { + return; + } + AlienRaceOffset raceOffset = anim?.actors[actor]?.raceOffsets?.Find(x => x.defName == pawn.def.defName); + + if (raceOffset != null) { + anchor.x += mirror ? raceOffset.offset.x * -1f : raceOffset.offset.x; + anchor.z += raceOffset.offset.y; + } + + //change the offset based on pawn body type + if(pawn?.story?.bodyType != null) { + if (pawn.story.bodyType == BodyTypeDefOf.Fat && anim?.actors[actor]?.bodyTypeOffset?.Fat != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Fat.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Fat.Value.y; + } + else if (pawn.story.bodyType == BodyTypeDefOf.Female && anim?.actors[actor]?.bodyTypeOffset?.Female != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Female.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Female.Value.y; + } + else if (pawn.story.bodyType == BodyTypeDefOf.Male && anim?.actors[actor]?.bodyTypeOffset?.Male != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Male.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Male.Value.y; + } + else if (pawn.story.bodyType == BodyTypeDefOf.Thin && anim?.actors[actor]?.bodyTypeOffset?.Thin != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Thin.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Thin.Value.y; + } + else if (pawn.story.bodyType == BodyTypeDefOf.Hulk && anim?.actors[actor]?.bodyTypeOffset?.Hulk != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Hulk.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Hulk.Value.y; + } + } + + pawn.jobs.posture = PawnPosture.Standing; + + this.actor = actor; + this.anim = anim; + this.mirror = mirror; + this.fastAnimForQuickie = fastAnimForQuickie; + + if (fastAnimForQuickie && anim.animationStages.Any(x => x.playTimeTicksQuick >= 0) == false) + { + curStage = 1; + animTicks = anim.animationStages[0].playTimeTicks; + } else + { + curStage = 0; + animTicks = 0; + } + + stageTicks = 0; + clipTicks = 0; + + quiver = false; + this.shiver = shiver && AnimationSettings.rapeShiver; + + controlGenitalAngle = anim.actors[actor].controlGenitalAngle; + + isAnimating = true; + //tick once for initialization + tickAnim(); + + } + + public override void CompTick() { + + base.CompTick(); + + if(isAnimating) { + + GlobalTextureAtlasManager.TryMarkPawnFrameSetDirty(pawn); + + if (pawn.Dead || pawn?.jobs?.curDriver == null || (pawn?.jobs?.curDriver != null && !(pawn?.jobs?.curDriver is rjw.JobDriver_Sex))) { + isAnimating = false; + } + else { + tickAnim(); + } + } + } + public void animatePawnBody(ref Vector3 rootLoc, ref float angle, ref Rot4 bodyFacing) { + + if(!isAnimating) { + return; + } + rootLoc = anchor + deltaPos; + angle = bodyAngle; + bodyFacing = this.bodyFacing; + + } + + public Rot4 AnimateHeadFacing() + { + return this.headFacing; + } + + + public void tickGraphics(PawnGraphicSet graphics) { + this.Graphics = graphics; + } + + public void tickAnim() { + + + + if (!isAnimating) return; + + if (anim == null) { + isAnimating = false; + return; + } + + animTicks++; + + if (animTicks < anim.animationTimeTicks) { + tickStage(); + } else { + + if(LoopNeverending()) + { + ResetOnLoop(); + } else + { + isAnimating = false; + } + + + } + + + + } + + public void tickStage() + { + + if(stage == null) + { + isAnimating = false; + return; + } + + stageTicks++; + + if(stageTicks >= stage.playTimeTicks || (fastAnimForQuickie && stage.playTimeTicksQuick >= 0 && stageTicks >= stage.playTimeTicksQuick)) { + + curStage++; + + stageTicks = 0; + clipTicks = 0; + clipPercent = 0; + } + + if(curStage >= anim.animationStages.Count) { + if (LoopNeverending()) + { + ResetOnLoop(); + } + else + { + isAnimating = false; + pawn.jobs.curDriver.ReadyForNextToil(); + } + + } else { + tickClip(); + } + + + + } + + public void tickClip() { + + clipTicks++; + + //play sound effect + if(rjw.RJWSettings.sounds_enabled && clip.SoundEffects.ContainsKey(clipTicks) && AnimationSettings.soundOverride) { + + + SoundInfo sound = new TargetInfo(pawn.Position, pawn.Map); + string soundEffectName = clip.SoundEffects[clipTicks]; + + + if ((pawn.jobs.curDriver as JobDriver_Sex).isAnimalOnAnimal) + { + sound.volumeFactor *= RJWSettings.sounds_animal_on_animal_volume; + } + + if(soundEffectName.StartsWith("Voiceline_")) + { + sound.volumeFactor *= RJWSettings.sounds_voice_volume; + } + + if (clip.SoundEffects[clipTicks] == "Cum") { + + sound.volumeFactor *= RJWSettings.sounds_cum_volume; + //considerApplyingSemen(); + + } else + { + sound.volumeFactor *= RJWSettings.sounds_sex_volume; + } + + SoundDef.Named(soundEffectName).PlayOneShot(sound); + + } + if(AnimationSettings.orgasmQuiver && clip.quiver.ContainsKey(clipTicks)) { + quiver = clip.quiver[clipTicks]; + } + + //loop animation if possible + if (clipPercent >= 1 && stage.isLooping) { + clipTicks = 1;//warning: don't set to zero or else calculations go wrong + } + clipPercent = (float)clipTicks / (float)clip.duration; + + calculateDrawValues(); + } + + public void considerApplyingSemen() + { + if(AnimationSettings.applySemenOnAnimationOrgasm && (pawn?.jobs?.curDriver is JobDriver_Sex)) + { + + if (anim.sexTypes.Contains((pawn.jobs.curDriver as JobDriver_Sex).Sexprops.sexType)) + { + //SemenHelper.calculateAndApplySemen((pawn.jobs.curDriver as JobDriver_Sex).Sexprops); + } + } + } + + public void calculateDrawValues() { + + /*if(Find.TickManager.TickRateMultiplier > 1 && (lastDrawFrame + 1 >= RealTime.frameCount || RealTime.deltaTime < 0.05f)) { + return; + }*/ + + deltaPos = new Vector3(clip.BodyOffsetX.Evaluate(clipPercent) * (mirror ? -1 : 1), clip.layer.AltitudeFor(), clip.BodyOffsetZ.Evaluate(clipPercent)); + + string bodyTypeDef = (pawn.story?.bodyType != null) ? pawn.story.bodyType.ToString() : ""; + + if (AnimationSettings.offsets != null && AnimationSettings.offsets.ContainsKey(CurrentAnimation.defName + pawn.def.defName + bodyTypeDef + ActorIndex)) { + deltaPos.x += AnimationSettings.offsets[CurrentAnimation.defName + pawn.def.defName + bodyTypeDef + ActorIndex].x * (mirror ? -1 : 1); + deltaPos.z += AnimationSettings.offsets[CurrentAnimation.defName + pawn.def.defName + bodyTypeDef + ActorIndex].y; + } + + + bodyAngle = (clip.BodyAngle.Evaluate(clipPercent) + (quiver || shiver ? ((Rand.Value * AnimationSettings.shiverIntensity) - (AnimationSettings.shiverIntensity / 2f)) : 0f)) * (mirror ? -1 : 1); + headAngle = clip.HeadAngle.Evaluate(clipPercent) * (mirror ? -1 : 1); + + if (controlGenitalAngle) { + genitalAngle = clip.GenitalAngle.Evaluate(clipPercent) * (mirror ? -1 : 1); + } + + if (AnimationSettings.rotation != null && AnimationSettings.rotation.ContainsKey(CurrentAnimation.defName + pawn.def.defName + bodyTypeDef + ActorIndex)) { + float offsetRotation = AnimationSettings.rotation[CurrentAnimation.defName + pawn.def.defName + bodyTypeDef + ActorIndex] * (Mirror ? -1 : 1); + genitalAngle += offsetRotation; + bodyAngle += offsetRotation; + headAngle += offsetRotation; + } + + + //don't go past 360 or less than 0 + + if (bodyAngle < 0) bodyAngle = 360 - ((-1f*bodyAngle) % 360); + if (bodyAngle > 360) bodyAngle %= 360; + + + if (headAngle < 0) headAngle = 360 - ((-1f * headAngle) % 360); + if (headAngle > 360) headAngle %= 360; + + if (genitalAngle < 0) genitalAngle = 360 - ((-1f * genitalAngle) % 360); + if (genitalAngle > 360) genitalAngle %= 360; + + + bodyFacing = mirror ? new Rot4((int)clip.BodyFacing.Evaluate(clipPercent)).Opposite : new Rot4((int)clip.BodyFacing.Evaluate(clipPercent)); + + bodyFacing = new Rot4((int)clip.BodyFacing.Evaluate(clipPercent)); + if(bodyFacing.IsHorizontal && mirror) { + bodyFacing = bodyFacing.Opposite; + } + + headFacing = new Rot4((int)clip.HeadFacing.Evaluate(clipPercent)); + if(headFacing.IsHorizontal && mirror) { + headFacing = headFacing.Opposite; + } + headBob = new Vector3(0, 0, clip.HeadBob.Evaluate(clipPercent)); + Vector2 bodyScale = (pawn.story?.bodyType?.bodyGraphicScale != null ? pawn.story.bodyType.bodyGraphicScale : Vector2.one); + headBob.z *= bodyScale.x; + + lastDrawFrame = RealTime.frameCount; + + } + + public Vector3 getPawnHeadPosition() { + + Vector3 headPos = anchor + deltaPos + Quaternion.AngleAxis(bodyAngle, Vector3.up) * (pawn.Drawer.renderer.BaseHeadOffsetAt(headFacing) + headBob); + + return headPos; + + } + + public Vector3 getPawnHeadOffset() + { + return Quaternion.AngleAxis(bodyAngle, Vector3.up) * (pawn.Drawer.renderer.BaseHeadOffsetAt(headFacing) + headBob); + + } + + public AnimationDef CurrentAnimation { + get { + return anim; + } + } + + public int ActorIndex { + get { + return actor; + } + } + + public override void PostExposeData() { + base.PostExposeData(); + + Scribe_Defs.Look(ref anim, "RJWAnimations-Anim"); + + Scribe_Values.Look(ref animTicks, "RJWAnimations-animTicks", 1); + Scribe_Values.Look(ref stageTicks, "RJWAnimations-stageTicks", 1); + Scribe_Values.Look(ref clipTicks, "RJWAnimations-clipTicks", 1); + Scribe_Values.Look(ref clipPercent, "RJWAnimations-clipPercent", 1); + Scribe_Values.Look(ref mirror, "RJWAnimations-mirror"); + + Scribe_Values.Look(ref curStage, "RJWAnimations-curStage", 0); + Scribe_Values.Look(ref actor, "RJWAnimations-actor"); + + Scribe_Values.Look(ref anchor, "RJWAnimations-anchor"); + Scribe_Values.Look(ref deltaPos, "RJWAnimations-deltaPos"); + Scribe_Values.Look(ref headBob, "RJWAnimations-headBob"); + Scribe_Values.Look(ref bodyAngle, "RJWAnimations-bodyAngle"); + Scribe_Values.Look(ref headAngle, "RJWAnimations-headAngle"); + + Scribe_Values.Look(ref genitalAngle, "RJWAnimations-GenitalAngle"); + Scribe_Values.Look(ref controlGenitalAngle, "RJWAnimations-controlGenitalAngle"); + + Scribe_Values.Look(ref headFacing, "RJWAnimations-headFacing"); + Scribe_Values.Look(ref headFacing, "RJWAnimations-bodyFacing"); + + Scribe_Values.Look(ref quiver, "RJWAnimations-orgasmQuiver"); + } + + public void shiftActorPositionAndRestartAnimation() { + actor = (actor == anim.actors.Count - 1 ? 0 : actor + 1); + + if (pawn?.story?.bodyType != null) { + if (pawn.story.bodyType == BodyTypeDefOf.Fat && anim?.actors[actor]?.bodyTypeOffset?.Fat != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Fat.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Fat.Value.y; + } + else if (pawn.story.bodyType == BodyTypeDefOf.Female && anim?.actors[actor]?.bodyTypeOffset?.Female != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Female.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Female.Value.y; + } + else if (pawn.story.bodyType == BodyTypeDefOf.Male && anim?.actors[actor]?.bodyTypeOffset?.Male != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Male.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Male.Value.y; + } + else if (pawn.story.bodyType == BodyTypeDefOf.Thin && anim?.actors[actor]?.bodyTypeOffset?.Thin != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Thin.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Thin.Value.y; + } + else if (pawn.story.bodyType == BodyTypeDefOf.Hulk && anim?.actors[actor]?.bodyTypeOffset?.Hulk != null) { + anchor.x += anim.actors[actor].bodyTypeOffset.Hulk.Value.x * (mirror ? -1f : 1f); + anchor.z += anim.actors[actor].bodyTypeOffset.Hulk.Value.y; + } + } + + curStage = 0; + animTicks = 0; + stageTicks = 0; + clipTicks = 0; + + controlGenitalAngle = anim.actors[actor].controlGenitalAngle; + + tickAnim(); + } + + 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) + { + return true; + } + + return false; + } + + public void ResetOnLoop() + { + curStage = 1; + animTicks = 0; + stageTicks = 0; + clipTicks = 0; + + tickAnim(); + } + } +} diff --git a/1.4/Source/Comps/CompProperties_BodyAnimator.cs b/1.4/Source/Comps/CompProperties_BodyAnimator.cs new file mode 100644 index 0000000..09df7ce --- /dev/null +++ b/1.4/Source/Comps/CompProperties_BodyAnimator.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using RimWorld; + +namespace Rimworld_Animations { + public class CompProperties_BodyAnimator : CompProperties + { + public CompProperties_BodyAnimator() + { + base.compClass = typeof(CompBodyAnimator); + } + } +} diff --git a/1.4/Source/Comps/CompProperties_ThingAnimator.cs b/1.4/Source/Comps/CompProperties_ThingAnimator.cs new file mode 100644 index 0000000..34c67b1 --- /dev/null +++ b/1.4/Source/Comps/CompProperties_ThingAnimator.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace Rimworld_Animations { + public class CompProperties_ThingAnimator : CompProperties + { + + public CompProperties_ThingAnimator() + { + base.compClass = typeof(CompThingAnimator); + } + } +} diff --git a/1.4/Source/Comps/CompThingAnimator.cs b/1.4/Source/Comps/CompThingAnimator.cs new file mode 100644 index 0000000..f5315e4 --- /dev/null +++ b/1.4/Source/Comps/CompThingAnimator.cs @@ -0,0 +1,245 @@ +using RimWorld; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace Rimworld_Animations { + public class CompThingAnimator : ThingComp + { + Vector3 anchor; + + Pawn pawn; + + public bool isAnimating = false, mirror; + + int animTicks = 0, stageTicks = 0, clipTicks = 0, curStage = 0; + float rotation = 0; + float clipPercent = 0; + + public Vector3 deltaPos; + + AnimationDef anim; + private ThingAnimationClip clip => (ThingAnimationClip)stage.animationClips[1]; + private AnimationStage stage + { + get + { + return anim.animationStages[curStage]; + } + + } + + public void StartAnimation(AnimationDef anim, Pawn pawn, bool mirror = false) + { + isAnimating = true; + + this.anim = anim; + this.pawn = pawn; + this.mirror = mirror; + + animTicks = 0; + stageTicks = 0; + clipTicks = 0; + + curStage = 0; + clipPercent = 0; + + tickAnim(); + + } + + public void setAnchor(IntVec3 position) + { + anchor = position.ToVector3(); + } + + public override void CompTick() + { + base.CompTick(); + + if(isAnimating) + { + if (pawn.Dead || pawn?.jobs?.curDriver == null || (pawn?.jobs?.curDriver != null && !(pawn?.jobs?.curDriver is rjw.JobDriver_Sex))) + { + isAnimating = false; + } + else + { + tickAnim(); + } + } + + + } + + public void tickAnim() + { + if (!isAnimating) return; + animTicks++; + + if (animTicks < anim.animationTimeTicks) + { + tickStage(); + } + else + { + if (LoopNeverending()) + { + ResetOnLoop(); + } + else + { + isAnimating = false; + } + + + } + + } + + public void tickStage() + { + if (stage == null) + { + isAnimating = false; + return; + } + + stageTicks++; + + if (stageTicks >= stage.playTimeTicks) + { + + curStage++; + + stageTicks = 0; + clipTicks = 0; + clipPercent = 0; + } + + if (curStage >= anim.animationStages.Count) + { + if (LoopNeverending()) + { + ResetOnLoop(); + } + else + { + isAnimating = false; + } + + } + else + { + tickClip(); + } + } + + public void tickClip() + { + clipTicks++; + + if (clipPercent >= 1 && stage.isLooping) + { + clipTicks = 1;//warning: don't set to zero or else calculations go wrong + } + clipPercent = (float)clipTicks / (float)clip.duration; + + calculateDrawValues(); + } + + public void setAnchor(Thing thing) + { + + //center on bed + if (thing is Building_Bed) + { + anchor = thing.Position.ToVector3(); + if (((Building_Bed)thing).SleepingSlotsCount == 2) + { + if (thing.Rotation.AsInt == 0) + { + anchor.x += 1; + anchor.z += 1; + } + else if (thing.Rotation.AsInt == 1) + { + anchor.x += 1; + } + else if (thing.Rotation.AsInt == 3) + { + anchor.z += 1; + } + + } + else + { + if (thing.Rotation.AsInt == 0) + { + anchor.x += 0.5f; + anchor.z += 1f; + } + else if (thing.Rotation.AsInt == 1) + { + anchor.x += 1f; + anchor.z += 0.5f; + } + else if (thing.Rotation.AsInt == 2) + { + anchor.x += 0.5f; + } + else + { + anchor.z += 0.5f; + } + } + } + else + { + anchor = thing.Position.ToVector3Shifted(); + } + + anchor -= new Vector3(0.5f, 0, 0.5f); + } + private void calculateDrawValues() + { + + //shift up and right 0.5f to align center + deltaPos = new Vector3((clip.PositionX.Evaluate(clipPercent)) * (mirror ? -1 : 1) + 0.5f, AltitudeLayer.Item.AltitudeFor(), clip.PositionZ.Evaluate(clipPercent) + 0.5f); + //Log.Message("Clip percent: " + clipPercent + " deltaPos: " + deltaPos); + rotation = clip.Rotation.Evaluate(clipPercent) * (mirror ? -1 : 1); + } + + public void AnimateThing(Thing thing) + { + thing.Graphic.Draw(deltaPos + anchor, mirror ? Rot4.West : Rot4.East, thing, rotation); + } + + public bool LoopNeverending() + { + if (pawn?.jobs?.curDriver != null && + (pawn.jobs.curDriver is JobDriver_Sex) && (pawn.jobs.curDriver as JobDriver_Sex).neverendingsex) + { + return true; + } + + return false; + } + + public void ResetOnLoop() + { + curStage = 1; + animTicks = 0; + stageTicks = 0; + clipTicks = 0; + + tickAnim(); + } + + } +} diff --git a/1.4/Source/Defs/AnimationDef.cs b/1.4/Source/Defs/AnimationDef.cs new file mode 100644 index 0000000..395ff83 --- /dev/null +++ b/1.4/Source/Defs/AnimationDef.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RimWorld; +using Verse; + +namespace Rimworld_Animations { + public class AnimationDef : Def + { + public List animationStages; + public List actors; + public int animationTimeTicks = 0; //do not set manually + public bool sounds = false; + public List sexTypes = null; + public List interactionDefTypes = null; + public List tags = new List(); + + public override void PostLoad() { + base.PostLoad(); + foreach(AnimationStage stage in animationStages) { + stage.initialize(); + animationTimeTicks += stage.playTimeTicks; + } + } + } +} diff --git a/1.4/Source/Extensions/PawnWoundDrawerExtension.cs b/1.4/Source/Extensions/PawnWoundDrawerExtension.cs new file mode 100644 index 0000000..417f8ed --- /dev/null +++ b/1.4/Source/Extensions/PawnWoundDrawerExtension.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using RimWorld; +using UnityEngine; +using Verse; +using Rimworld_Animations; + +namespace Rimworld_Animations { + + [StaticConstructorOnStartup] + public static class PawnWoundDrawerExtension + { + public static void RenderPawnOverlay(this PawnWoundDrawer pawnWoundDrawer, Vector3 drawLoc, Mesh bodyMesh, Quaternion quat, bool drawNow, PawnOverlayDrawer.OverlayLayer layer, Rot4 pawnRot, bool? overApparel = null, Pawn pawn = null, PawnRenderFlags flags = new PawnRenderFlags()) + { + if (pawn == null) + { return; } + + if (!flags.FlagSet(PawnRenderFlags.Portrait) && layer == PawnOverlayDrawer.OverlayLayer.Head) + { + CompBodyAnimator pawnAnimator = pawn.TryGetComp(); + if (pawnAnimator != null && pawnAnimator.isAnimating && pawn.Drawer.renderer.graphics.headGraphic != null) + { + pawnRot = pawnAnimator.headFacing; + quat = Quaternion.AngleAxis(angle: pawnAnimator.headAngle, axis: Vector3.up); + float y = drawLoc.y; + drawLoc = pawnAnimator.getPawnHeadPosition() - Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up) * pawn.Drawer.renderer.BaseHeadOffsetAt(pawnAnimator.headFacing); + drawLoc.y = y; + } + } + + pawnWoundDrawer.RenderPawnOverlay(drawLoc, bodyMesh, quat, drawNow, layer, pawnRot, overApparel); + } + } + +} diff --git a/1.4/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs b/1.4/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs new file mode 100644 index 0000000..b7fef1d --- /dev/null +++ b/1.4/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using RimWorld; +using UnityEngine; + +namespace Rimworld_Animations { + class MainTabWindow_OffsetConfigure : MainTabWindow + { + + public override Vector2 RequestedTabSize => new Vector2(505, 380); + public override void DoWindowContents(Rect inRect) { + + Rect position = new Rect(inRect.x, inRect.y, inRect.width, inRect.height); + + + Listing_Standard listingStandard = new Listing_Standard(); + listingStandard.Begin(position); + + listingStandard.Label("Animation Manager"); + + listingStandard.GapLine(); + + + if (Find.Selector.SingleSelectedThing is Pawn) { + + Pawn curPawn = Find.Selector.SingleSelectedThing as Pawn; + + if (curPawn.TryGetComp().isAnimating) { + + AnimationDef def = curPawn.TryGetComp().CurrentAnimation; + int ActorIndex = curPawn.TryGetComp().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().ActorIndex + " Body Type (if any): " + bodyTypeDef + " Animation: " + def.label + (curPawn.TryGetComp().Mirror ? " mirrored" : "")); + + if(curPawn.def.defName == "Human") { + listingStandard.Label("Warning--You generally don't want to change human offsets, only alien offsets"); + } + + bool mirrored = curPawn.TryGetComp().Mirror; + + float.TryParse(listingStandard.TextEntryLabeled("X Offset: ", offsetX.ToString()), out offsetX); + offsetX = listingStandard.Slider(offsetX, -2 * (mirrored ? -1 : 1), 2 * (mirrored ? -1 : 1)); + + 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().actorsInCurrentAnimation.Count; i++) { + + Pawn actor = curPawn.TryGetComp().actorsInCurrentAnimation[i]; + + actor.TryGetComp()?.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; + } + + } + + } + 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(); + } + + if(AnimationSettings.rotation == null) { + if (AnimationSettings.debugMode) + Log.Message("New rotation"); + AnimationSettings.rotation = new Dictionary(); + } + } + + public override void PostClose() { + base.PostClose(); + + LoadedModManager.GetMod().WriteSettings(); + } + } +} diff --git a/1.4/Source/MainTabWindows/OffsetMainButtonDefOf.cs b/1.4/Source/MainTabWindows/OffsetMainButtonDefOf.cs new file mode 100644 index 0000000..e7ad9eb --- /dev/null +++ b/1.4/Source/MainTabWindows/OffsetMainButtonDefOf.cs @@ -0,0 +1,22 @@ +using RimWorld; +using Verse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rimworld_Animations { + + [DefOf] + public static class OffsetMainButtonDefOf { + + public static MainButtonDef OffsetManager; + + + static OffsetMainButtonDefOf() { + DefOfHelper.EnsureInitializedInCtor(typeof(OffsetMainButtonDefOf)); + } + + } +} diff --git a/1.4/Source/MainTabWindows/WorldComponent_UpdateMainTab.cs b/1.4/Source/MainTabWindows/WorldComponent_UpdateMainTab.cs new file mode 100644 index 0000000..2694419 --- /dev/null +++ b/1.4/Source/MainTabWindows/WorldComponent_UpdateMainTab.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RimWorld; +using RimWorld.Planet; +using Verse; + +namespace Rimworld_Animations { + public class WorldComponent_UpdateMainTab : WorldComponent { + + public WorldComponent_UpdateMainTab(World world) : base(world) { + + } + + public override void FinalizeInit() { + base.FinalizeInit(); + OffsetMainButtonDefOf.OffsetManager.buttonVisible = AnimationSettings.offsetTab; + } + + + } +} diff --git a/1.4/Source/Patches/Harmony_PatchAll.cs b/1.4/Source/Patches/Harmony_PatchAll.cs new file mode 100644 index 0000000..1c1d63f --- /dev/null +++ b/1.4/Source/Patches/Harmony_PatchAll.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using HarmonyLib; +using System.Reflection; + +namespace Rimworld_Animations { + + [StaticConstructorOnStartup] + public static class Harmony_PatchAll { + + static Harmony_PatchAll() { + + Harmony val = new Harmony("rjwanim"); + val.PatchAll(Assembly.GetExecutingAssembly()); + + } + } +} diff --git a/1.4/Source/Patches/OtherModPatches/HarmonyPatch_AlienRace.cs b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_AlienRace.cs new file mode 100644 index 0000000..c53edb4 --- /dev/null +++ b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_AlienRace.cs @@ -0,0 +1,358 @@ +/*using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; +using AlienRace; + +namespace Rimworld_Animations { + + + [StaticConstructorOnStartup] + public static class HarmonyPatch_AlienRace + { + static HarmonyPatch_AlienRace() + { + (new Harmony("rjwanim")).Patch(AccessTools.Method(AccessTools.TypeByName("AlienRace.HarmonyPatches"), "DrawAddons"), + prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_AlienRace), "Prefix_AnimateHeadAddons"))); + } + + /* 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(); + + if (animator == null || !animator.isAnimating) + { + return; + } + + if(addon.alignWithHead || addon.drawnInBed) + { + rot = animator.headFacing; + angle = animator.headAngle; + offsetVector += animator.deltaPos + animator.bodyAngle * animator.headBob; + + } + else + { + rot = animator.bodyFacing; + angle = animator.bodyAngle; + offsetVector += animator.deltaPos; + } + + } + + public static bool Prefix_AnimateHeadAddons(PawnRenderFlags renderFlags, Vector3 vector, Vector3 headOffset, Pawn pawn, Quaternion quat, Rot4 rotation) + { + + if (renderFlags.FlagSet(PawnRenderFlags.Portrait) || pawn.TryGetComp() == null || !pawn.TryGetComp().isAnimating) return true; + if (!(pawn.def is ThingDef_AlienRace alienProps) || renderFlags.FlagSet(PawnRenderFlags.Invisible)) return false; + + List addons = alienProps.alienRace.generalSettings.alienPartGenerator.bodyAddons; + AlienPartGenerator.AlienComp comp = pawn.GetComp(); + CompBodyAnimator pawnAnimator = pawn.TryGetComp(); + + bool flag = renderFlags.FlagSet(PawnRenderFlags.Portrait); + bool flag2 = renderFlags.FlagSet(PawnRenderFlags.Invisible); + + for (int i = 0; i < addons.Count; i++) + { + AlienPartGenerator.BodyAddon ba = addons[index: i]; + + if (!ba.CanDrawAddon(pawn: pawn)) continue; + + 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); + Vector3 vector2 = a + ((offset2 != null) ? offset2.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, pawn.story.headType) : Vector3.zero); + vector2.y = (ba.inFrontOfBody ? (0.3f + vector2.y) : (-0.3f - vector2.y)); + float num = ba.angle; + if (((ba.drawnInBed && !forceDrawForBody) || ba.alignWithHead ? pawnAnimator.headFacing : pawnAnimator.bodyFacing) == Rot4.North) + { + if (ba.layerInvert) + { + vector2.y = 0f - vector2.y; + } + num = 0f; + } + if (((ba.drawnInBed && !forceDrawForBody) || ba.alignWithHead ? pawnAnimator.headFacing : pawnAnimator.bodyFacing) == Rot4.East) + { + num = 0f - num; + vector2.x = 0f - vector2.x; + } + Graphic addonGraphic = comp.addonGraphics[i]; + + addonGraphic.drawSize = ((flag && ba.drawSizePortrait != Vector2.zero) ? ba.drawSizePortrait : ba.drawSize) * (ba.scaleWithPawnDrawsize ? (ba.alignWithHead ? ((flag ? comp.customPortraitHeadDrawSize : comp.customHeadDrawSize) * (ModsConfig.BiotechActive ? (pawn.ageTracker.CurLifeStage.headSizeFactor ?? 1.5f) : 1.5f)) : ((flag ? comp.customPortraitDrawSize : comp.customDrawSize) * (ModsConfig.BiotechActive ? pawn.ageTracker.CurLifeStage.bodySizeFactor : 1f) * 1.5f)) : (Vector2.one * 1.5f)); + + if ((ba.drawnInBed && !forceDrawForBody) || ba.alignWithHead) + { + + Quaternion addonRotation = Quaternion.AngleAxis(pawnAnimator.headAngle < 0 ? 360 - (360 % pawnAnimator.headAngle) : pawnAnimator.headAngle, Vector3.up); + + GenDraw.DrawMeshNowOrLater(mesh: addonGraphic.MeshAt(rot: pawnAnimator.headFacing), loc: vector + (ba.alignWithHead ? headOffset : headOffset - addonRotation * pawn.Drawer.renderer.BaseHeadOffsetAt(pawnAnimator.headFacing)) + 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: pawnAnimator.headFacing), renderFlags.FlagSet(PawnRenderFlags.DrawNow)); + + + } + + else + { + Quaternion 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)); + } + + 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)); + } + + } + + + } + + return false; + } + } + + [HarmonyPatch(typeof(PawnGraphicSet), "ResolveApparelGraphics")] + public static class HarmonyPatch_ResolveApparelGraphics + { + public static bool Prefix(ref Pawn ___pawn) + { + + if (___pawn.TryGetComp() != null && ___pawn.TryGetComp().isAnimating) + { + return false; + } + return true; + } + } +*/ +/* + +[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(); + AlienPartGenerator.AlienComp comp = pawn.GetComp(); + + 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; + AlienPartGenerator.RotationOffset offset2 = bodyAddon.offsets.GetOffset(rotation); + Vector3 vector2 = a + ((offset2 != null) ? offset2.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, comp.crownType) : Vector3.zero); + vector2.y = (bodyAddon.inFrontOfBody ? (0.3f + vector2.y) : (-0.3f - vector2.y)); + float num = bodyAddon.angle; + if (rotation == Rot4.North) + { + if (bodyAddon.layerInvert) + { + vector2.y = -vector2.y; + } + num = 0f; + } + if (rotation == Rot4.East) + { + num = -num; + vector2.x = -vector2.x; + } + + vector = vector + Quaternion.AngleAxis(pawnAnimator.bodyAngle, Vector3.up) * pawn.Drawer.renderer.BaseHeadOffsetAt(pawnAnimator.bodyFacing) - pawnAnimator.getPawnHeadOffset(); //convert vector into pseudo body pos for head + quat = Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up); + loc = vector + (bodyAddon.alignWithHead ? headOffset : Vector3.zero) + vector2.RotatedBy(Mathf.Acos(Quaternion.Dot(Quaternion.identity, quat)) * 2f * 57.29578f); + 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; + AlienPartGenerator.RotationOffset offset2 = bodyAddon.offsets.GetOffset(rotation); + Vector3 vector2 = a + ((offset2 != null) ? offset2.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, comp.crownType) : Vector3.zero); + vector2.y = (bodyAddon.inFrontOfBody ? (0.3f + vector2.y) : (-0.3f - vector2.y)); + float num = bodyAddon.angle; + if (rotation == Rot4.North) + { + if (bodyAddon.layerInvert) + { + vector2.y = -vector2.y; + } + num = 0f; + } + if (rotation == Rot4.East) + { + num = -num; + vector2.x = -vector2.x; + } + quat = Quaternion.AngleAxis(pawnAnimator.bodyAngle, Vector3.up); + loc = vector + (bodyAddon.alignWithHead ? headOffset : Vector3.zero) + vector2.RotatedBy(Mathf.Acos(Quaternion.Dot(Quaternion.identity, quat)) * 2f * 57.29578f); + + } + + } + GenDraw.DrawMeshNowOrLater(mesh, loc, quat, mat, drawNow); + + /* + 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")) + + { + orassan = true; + + orassanv = new Vector3(0, 0, 0.23f); + if (pawnAnimator.headFacing == Rot4.North) + { + orassanv.z -= 0.1f; + orassanv.y += 1f; + + if(bodyAddon.bodyPart.Contains("left")) + { + orassanv.x += 0.03f; + } else + { + orassanv.x -= 0.03f; + } + + } + else if (pawnAnimator.headFacing == Rot4.East) + { + orassanv.x -= 0.1f; + } + else if (pawnAnimator.headFacing == Rot4.West) + { + orassanv.x = 0.1f; + } + else + { + orassanv.z -= 0.1f; + orassanv.y += 1f; + + if (bodyAddon.bodyPart.Contains("right")) + { + orassanv.x += 0.05f; + } + else + { + orassanv.x -= 0.05f; + } + } + orassanv = orassanv.RotatedBy(pawnAnimator.headAngle); + } + } + + + + + + GenDraw.DrawMeshNowOrLater(mesh: graphic.MeshAt(rot: headRotInAnimation), loc: loc + orassanv + (bodyAddon.alignWithHead ? headOffset : Vector3.zero),// + v.RotatedBy(Mathf.Acos(Quaternion.Dot(Quaternion.identity, quat)) * 2f * 57.29578f), + quat: Quaternion.AngleAxis(angle: num, axis: Vector3.up) * headQuatInAnimation, mat: graphic.MatAt(rot: pawnAnimator.headFacing), drawNow: drawNow);; + } + + else + { + + } + + + } + + + public static IEnumerable Transpiler(IEnumerable instructions) + { + List 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 + yield return new CodeInstruction(OpCodes.Ldloc, (object)5); //offsetVector/AddonOffset (v) + yield return new CodeInstruction(OpCodes.Ldarg, (object)2); //headOffset + yield return new CodeInstruction(OpCodes.Ldarg, (object)3); //pawn + yield return new CodeInstruction(OpCodes.Ldarg, (object)0); //renderflags + yield return new CodeInstruction(OpCodes.Ldarg, (object)1); //vector + yield return new CodeInstruction(OpCodes.Ldarg, (object)5); //rotation + + 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(); + + if(anim == null) + { + return true; + } + + if (anim != null && !renderFlags.FlagSet(PawnRenderFlags.Portrait) && anim.isAnimating) + { + //quat = Quaternion.AngleAxis(anim.bodyAngle, Vector3.up); + } + + return true; + + } +} + + + + +} + + +*/ \ No newline at end of file diff --git a/Source/Patches/HarmonyPatch_PawnRenderer.cs b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_CSL.cs similarity index 55% rename from Source/Patches/HarmonyPatch_PawnRenderer.cs rename to 1.4/Source/Patches/OtherModPatches/HarmonyPatch_CSL.cs index 8bad2f2..8345ede 100644 --- a/Source/Patches/HarmonyPatch_PawnRenderer.cs +++ b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_CSL.cs @@ -1,55 +1,54 @@ -using System; +/* +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using HarmonyLib; -using RimWorld; +using rjw; using Verse; -using UnityEngine; -using System.Reflection; +using RimWorld; using System.Reflection.Emit; +using System.Reflection; +using UnityEngine; namespace Rimworld_Animations { + [StaticConstructorOnStartup] + public static class HarmonyPatch_CSL { + static HarmonyPatch_CSL() { + try { + ((Action)(() => { + if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "Children, school and learning")) { - [HarmonyPatch(typeof(PawnRenderer), "RenderPawnInternal", new Type[] - { - typeof(Vector3), - typeof(float), - typeof(bool), - typeof(Rot4), - typeof(Rot4), - typeof(RotDrawMode), - typeof(bool), - typeof(bool), - typeof(bool) - })] - - public static class HarmonyPatch_PawnRenderer - { + (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("Children.PawnRenderer_RenderPawnInternal_Patch"), "RenderPawnInternalScaled"), + prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_CSL), "Prefix_CSL")), + transpiler: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_CSL), "Transpiler_CSL"))); + } + }))(); + } + catch (TypeLoadException ex) { + + } + } + + public static void Prefix_CSL(PawnRenderer __instance, Pawn pawn, ref Vector3 rootLoc, ref float angle, bool renderBody, ref Rot4 bodyFacing, ref Rot4 headFacing, RotDrawMode bodyDrawType, bool portrait, bool headStump, bool invisible) { - [HarmonyBefore(new string[] { "showhair.kv.rw", "erdelf.HumanoidAlienRaces", "Nals.FacialAnimation" })] - public static void Prefix(PawnRenderer __instance, ref Vector3 rootLoc, ref float angle, bool renderBody, ref Rot4 bodyFacing, ref Rot4 headFacing, RotDrawMode bodyDrawType, bool portrait, bool headStump, bool invisible) - { PawnGraphicSet graphics = __instance.graphics; - Pawn pawn = graphics.pawn; CompBodyAnimator bodyAnim = pawn.TryGetComp(); if (!graphics.AllResolved) { graphics.ResolveAllGraphics(); } - - if (bodyAnim != null && bodyAnim.isAnimating && !portrait && pawn.Map == Find.CurrentMap) { + + if (bodyAnim != null && bodyAnim.isAnimating && !portrait) { bodyAnim.tickGraphics(graphics); - bodyAnim.animatePawn(ref rootLoc, ref angle, ref bodyFacing, ref headFacing); + pawn.TryGetComp().animatePawn(ref rootLoc, ref angle, ref bodyFacing, ref headFacing); } } - [HarmonyAfter(new string[] { "showhair.kv.rw", "erdelf.HumanoidAlienRaces", "Nals.FacialAnimation" })] - [HarmonyReversePatch(HarmonyReversePatchType.Snapshot)] - public static IEnumerable Transpiler(IEnumerable instructions) { + public static IEnumerable Transpiler_CSL(IEnumerable instructions) { MethodInfo drawMeshNowOrLater = AccessTools.Method(typeof(GenDraw), "DrawMeshNowOrLater"); FieldInfo headGraphic = AccessTools.Field(typeof(PawnGraphicSet), "headGraphic"); @@ -57,23 +56,24 @@ namespace Rimworld_Animations { List codes = instructions.ToList(); bool forHead = true; - for(int i = 0; i < codes.Count(); i++) { + for (int i = 0; i < codes.Count(); i++) { //Instead of calling drawmeshnoworlater, add pawn to the stack and call my special static method if (codes[i].OperandIs(drawMeshNowOrLater) && forHead) { yield return new CodeInstruction(OpCodes.Ldarg_0); yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(typeof(PawnRenderer), "pawn")); - yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(AnimationUtility), nameof(AnimationUtility.RenderPawnHeadMeshInAnimation), new Type[] { typeof(Mesh), typeof(Vector3), typeof(Quaternion), typeof(Material), typeof(bool), typeof(Pawn) })); + yield return new CodeInstruction(OpCodes.Ldarg_2); + yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(AnimationUtility), nameof(AnimationUtility.RenderPawnHeadMeshInAnimation), new Type[] { typeof(Mesh), typeof(Vector3), typeof(Quaternion), typeof(Material), typeof(bool), typeof(Pawn), typeof(float) })); } //checking for if(graphics.headGraphic != null) else if (codes[i].opcode == OpCodes.Ldfld && codes[i].OperandIs(headGraphic)) { forHead = true; yield return codes[i]; - } + } //checking for if(renderbody) - else if(codes[i].opcode == OpCodes.Ldarg_3) { + else if (codes[i].opcode == OpCodes.Ldarg_3) { forHead = false; yield return codes[i]; } @@ -82,5 +82,6 @@ namespace Rimworld_Animations { } } } - } -} + + } +}*/ diff --git a/1.4/Source/Patches/OtherModPatches/HarmonyPatch_DontShaveYourHead.cs b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_DontShaveYourHead.cs new file mode 100644 index 0000000..3cb2a63 --- /dev/null +++ b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_DontShaveYourHead.cs @@ -0,0 +1,29 @@ +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace Rimworld_Animations { + class HarmonyPatch_DontShaveYourHead { + + [StaticConstructorOnStartup] + public static class Patch_DontShaveYourHead { + + static Patch_DontShaveYourHead() { + try { + ((Action)(() => + { + if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "Don't Shave Your Head 1.0")) { + (new Harmony("rjwanim")).Patch(AccessTools.Method(AccessTools.TypeByName("DontShaveYourHead.Harmony_PawnRenderer"), "DrawHairReroute"), //typeof(ShowHair.Patch_PawnRenderer_RenderPawnInternal), nameof(ShowHair.Patch_PawnRenderer_RenderPawnInternal.Postfix)), + transpiler: new HarmonyMethod(AccessTools.Method(typeof(Patch_ShowHairWithHats), "Transpiler"))); + } + }))(); + } + catch (TypeLoadException ex) { } + } + } + } +} diff --git a/1.4/Source/Patches/OtherModPatches/HarmonyPatch_FacialAnimation.cs b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_FacialAnimation.cs new file mode 100644 index 0000000..83ffd5b --- /dev/null +++ b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_FacialAnimation.cs @@ -0,0 +1,104 @@ +using HarmonyLib; +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace Rimworld_Animations { + [StaticConstructorOnStartup] + public static class Patch_FacialAnimation { + + static Patch_FacialAnimation() { + try { + ((Action)(() => { + if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "[NL] Facial Animation - WIP")) { + (new Harmony("rjwanim")).Patch(AccessTools.Method(AccessTools.TypeByName("FacialAnimation.DrawFaceGraphicsComp"), "DrawGraphics"), + prefix: new HarmonyMethod(AccessTools.Method(typeof(Patch_FacialAnimation), "Prefix"))); + } + }))(); + } + catch (TypeLoadException ex) { + + } + } + + public static bool Prefix(ref Pawn ___pawn, ref Rot4 headFacing, ref Vector3 headOrigin, ref Quaternion quaternion, ref bool portrait) { + + CompBodyAnimator bodyAnim = ___pawn.TryGetComp(); + + if (bodyAnim != null && bodyAnim.isAnimating && !portrait) { + + headFacing = bodyAnim.headFacing; + headOrigin = new Vector3(bodyAnim.getPawnHeadPosition().x, headOrigin.y, bodyAnim.getPawnHeadPosition().z); + quaternion = Quaternion.AngleAxis(bodyAnim.headAngle, Vector3.up); + } + + return true; + } + /* + public static List rjwLovinDefNames = new List{ + "Lovin", + "Quickie", + "GettingQuickie", + "JoinInBed", + "JoinInBedAnimation", + "GettinLovedAnimation", + "GettinLoved", + "GettinLicked", + "GettinSucked", + "GettinRaped", + "ViolateCorpse", + "RJW_Masturbate", + "GettinBred", + "Breed", + "RJW_Mate", + "Bestiality", + "BestialityForFemale", + "StruggleInBondageGear", + "WhoreIsServingVisitors", + "UseFM" + }; + + public static List rjwRapeDefNames = new List { + "RapeComfortPawn", + "RandomRape", + "RapeEnemy" + }; + + public static bool Prefix_IsSameA(JobDef job, string ___jobDef, ref bool __result) { + + if(___jobDef != null && ___jobDef == "Lovin" && job?.defName != null && rjwLovinDefNames.Contains(job?.defName)) { + __result = true; + return false; + } + else if (___jobDef != null && ___jobDef == "Wait_Combat" && job?.defName != null && rjwRapeDefNames.Contains(job?.defName)) { + __result = true; + return false; + } + + + return true; + } + + public static bool Prefix_IsSameB(string jobName, string ___jobDef, ref bool __result) { + + if (___jobDef != null && ___jobDef == "Lovin" && jobName != null && rjwLovinDefNames.Contains(jobName)) { + __result = true; + return false; + } + if (___jobDef != null && ___jobDef == "Wait_Combat" && jobName != null && rjwRapeDefNames.Contains(jobName)) { + __result = true; + return false; + } + + return true; + } + */ + } +} \ No newline at end of file diff --git a/1.4/Source/Patches/OtherModPatches/HarmonyPatch_HatsDisplaySelection.cs b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_HatsDisplaySelection.cs new file mode 100644 index 0000000..1cd5707 --- /dev/null +++ b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_HatsDisplaySelection.cs @@ -0,0 +1,77 @@ +/*using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using RimWorld; +using Verse; +using UnityEngine; +using System.Reflection; +using System.Reflection.Emit; + +namespace Rimworld_Animations { + public static class HarmonyPatch_HatsDisplaySelection { + + public static void PatchHatsDisplaySelectionArgs() { + (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("HatDisplaySelection.Patch"), "DrawHatCEWithHair"), + transpiler: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_HatsDisplaySelection), "ReplaceDrawMeshOrLaterWithAnimate"))); + + (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("HatDisplaySelection.Patch"), "DrawHatWithHair"), + transpiler: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_HatsDisplaySelection), "ReplaceDrawMeshOrLaterWithAnimate"))); + + (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("HatDisplaySelection.Patch"), "DrawHeadApparelWithHair"), + prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_HatsDisplaySelection), "PrefixPatchForDrawHeadApparelWithHair"))); + + + } + + public static void PrefixPatchForDrawHeadApparelWithHair(PawnRenderer renderer, ref Vector3 rootLoc, ref float angle, bool renderBody, ref Rot4 bodyFacing, ref Rot4 headFacing, RotDrawMode bodyDrawType, bool portrait, bool headStump, bool invisible) + { + PawnGraphicSet graphics = renderer.graphics; + Pawn pawn = graphics.pawn; + CompBodyAnimator bodyAnim = pawn.TryGetComp(); + + if (!graphics.AllResolved) + { + graphics.ResolveAllGraphics(); + } + + + if (bodyAnim != null && bodyAnim.isAnimating && !portrait && pawn.Map == Find.CurrentMap) + { + bodyAnim.tickGraphics(graphics); + bodyAnim.animatePawn(ref rootLoc, ref angle, ref bodyFacing, ref headFacing); + + } + } + + + public static IEnumerable ReplaceDrawMeshOrLaterWithAnimate(IEnumerable instructions) { + + MethodInfo drawMeshNowOrLater = AccessTools.Method(typeof(GenDraw), "DrawMeshNowOrLater"); + List codes = instructions.ToList(); + for (int i = 0; i < instructions.Count(); i++) { + + + if (codes[i]. + + +(drawMeshNowOrLater)) { + + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(AccessTools.TypeByName("HatDisplaySelection.Patch"), "pawn")); + yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(AnimationUtility), nameof(AnimationUtility.RenderPawnHeadMeshInAnimation), new Type[] { typeof(Mesh), typeof(Vector3), typeof(Quaternion), typeof(Material), typeof(bool), typeof(Pawn) })); + + } + else { + yield return codes[i]; + } + + } + + } + + } +} +*/ \ No newline at end of file diff --git a/1.4/Source/Patches/OtherModPatches/HarmonyPatch_ShowHairWithHats.cs b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_ShowHairWithHats.cs new file mode 100644 index 0000000..a42ab7d --- /dev/null +++ b/1.4/Source/Patches/OtherModPatches/HarmonyPatch_ShowHairWithHats.cs @@ -0,0 +1,51 @@ +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace Rimworld_Animations { + [StaticConstructorOnStartup] + public static class Patch_ShowHairWithHats { + + static Patch_ShowHairWithHats() { + try { + ((Action)(() => + { + if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "[KV] Show Hair With Hats or Hide All Hats - 1.1")) { + (new Harmony("rjwanim")).Patch(AccessTools.Method(AccessTools.TypeByName("ShowHair.Patch_PawnRenderer_RenderPawnInternal"), "Postfix"), //typeof(ShowHair.Patch_PawnRenderer_RenderPawnInternal), nameof(ShowHair.Patch_PawnRenderer_RenderPawnInternal.Postfix)), + transpiler: new HarmonyMethod(AccessTools.Method(typeof(Patch_ShowHairWithHats), "Transpiler"))); + } + }))(); + } + catch (TypeLoadException ex) { } + } + + + public static IEnumerable Transpiler(IEnumerable instructions) { + + MethodInfo drawMeshNowOrLater = AccessTools.Method(typeof(GenDraw), "DrawMeshNowOrLater"); + + List codes = instructions.ToList(); + for (int i = 0; i < codes.Count(); i++) { + + //Instead of calling drawmeshnoworlater, add pawn to the stack and call my special static method + if (codes[i].OperandIs(drawMeshNowOrLater)) { + + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(typeof(PawnRenderer), "pawn")); + yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(AnimationUtility), nameof(AnimationUtility.RenderPawnHeadMeshInAnimation), new Type[] { typeof(Mesh), typeof(Vector3), typeof(Quaternion), typeof(Material), typeof(bool), typeof(Pawn) })); + + } + else { + yield return codes[i]; + } + } + } + } +} diff --git a/1.4/Source/Patches/RJWPatches/HarmonyPatch_PlaySexSounds.cs b/1.4/Source/Patches/RJWPatches/HarmonyPatch_PlaySexSounds.cs new file mode 100644 index 0000000..6544f13 --- /dev/null +++ b/1.4/Source/Patches/RJWPatches/HarmonyPatch_PlaySexSounds.cs @@ -0,0 +1,25 @@ +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 +{ + [HarmonyPatch(typeof(JobDriver_Sex), "PlaySexSound")] + class HarmonyPatch_PlaySexSounds + { + public static bool Prefix(JobDriver_Sex __instance) + { + if (__instance.pawn.TryGetComp().isAnimating) + { + return false; + } + + return true; + } + } +} diff --git a/1.4/Source/Patches/RJWPatches/HarmonyPatch_SexTick.cs b/1.4/Source/Patches/RJWPatches/HarmonyPatch_SexTick.cs new file mode 100644 index 0000000..9ba03b2 --- /dev/null +++ b/1.4/Source/Patches/RJWPatches/HarmonyPatch_SexTick.cs @@ -0,0 +1,61 @@ +using HarmonyLib; +using RimWorld; +using rjw; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using Verse.AI; + +namespace Rimworld_Animations +{ + [HarmonyPatch(typeof(JobDriver_Sex), "SexTick")] + public class HarmonyPatch_SexTick + { + public static bool Prefix(JobDriver_Sex __instance, Pawn pawn, Thing target) + { + + if ((target is Pawn) && + !( + (target as Pawn)?.jobs?.curDriver is JobDriver_SexBaseReciever + && + ((target as Pawn).jobs.curDriver as JobDriver_SexBaseReciever).parteners.Any() + && + ((target as Pawn).jobs.curDriver as JobDriver_SexBaseReciever).parteners[0] == pawn)) + { + + __instance.ticks_left--; + __instance.sex_ticks--; + __instance.Orgasm(); + + + if (pawn.IsHashIntervalTick(__instance.ticks_between_thrusts)) + { + __instance.ChangePsyfocus(pawn, target); + __instance.Animate(pawn, target); + __instance.PlaySexSound(); + if (!__instance.Sexprops.isRape) + { + pawn.GainComfortFromCellIfPossible(false); + if (target is Pawn) + { + (target as Pawn).GainComfortFromCellIfPossible(false); + } + } + if(!__instance.isEndytophile) + { + SexUtility.DrawNude(pawn, false); + } + } + + return false; + } + + return true; + } + + } + +} diff --git a/1.4/Source/Patches/RJWPatches/HarmonyPatch_WorkGiverSex.cs b/1.4/Source/Patches/RJWPatches/HarmonyPatch_WorkGiverSex.cs new file mode 100644 index 0000000..af4a755 --- /dev/null +++ b/1.4/Source/Patches/RJWPatches/HarmonyPatch_WorkGiverSex.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using rjw; +using HarmonyLib; +using Verse; +using RimWorld; +using Verse.AI; + +namespace Rimworld_Animations { + /* + [HarmonyPatch(typeof(WorkGiver_Sex), "JobOnThing")] + public static class HarmonyPatch_WorkGiverSex { + + public static bool Prefix(ref Job __result, ref Thing t) { + + Building_Bed bed = RestUtility.CurrentBed(t as Pawn); + if (bed == null) { + return false; + } + __result = JobMaker.MakeJob(DefDatabase.GetNamed("JoinInBedAnimation", true), t as Pawn, bed); + return false; + + } + + } + + */ +} diff --git a/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_JoinInBed.cs b/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_JoinInBed.cs new file mode 100644 index 0000000..18c955e --- /dev/null +++ b/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_JoinInBed.cs @@ -0,0 +1,84 @@ +using System; +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 +{ + + [HarmonyPatch(typeof(Bed_Utility), "in_same_bed")] + public static class HarmonyPatch_JobDriver_InSameBedPatch + { + + public static bool Prefix(Pawn partner, ref bool __result) + { + + if(partner != null && partner.CurJobDef == xxx.casual_sex) + { + __result = true; + return false; + } + + return true; + + } + + + + } + + [HarmonyPatch(typeof(JobDriver_JoinInBed), "MakeNewToils")] + public static class HarmonyPatch_JobDriver_JoinInBed + { + + public static void Postfix(JobDriver_JoinInBed __instance, ref IEnumerable __result) + { + + var toils = __result.ToList(); + + Toil goToPawnInBed = Toils_Goto.GotoThing(__instance.iTarget, PathEndMode.OnCell); + goToPawnInBed.FailOn(() => !RestUtility.InBed(__instance.Partner) && __instance.Partner.CurJobDef != xxx.gettin_loved && !Bed_Utility.in_same_bed(__instance.Partner, __instance.pawn)); + + toils[1] = goToPawnInBed; + + + Toil startPartnerSex = new Toil(); + startPartnerSex.initAction = delegate { + + + if (!(__instance.Partner.jobs.curDriver is JobDriver_SexBaseReciever)) // allows threesomes + { + Job gettinLovedJob = JobMaker.MakeJob(xxx.gettin_loved, __instance.pawn, __instance.Bed); // new gettin loved toil that wakes up the pawn goes here + __instance.Partner.jobs.jobQueue.EnqueueFirst(gettinLovedJob); + __instance.Partner.jobs.EndCurrentJob(JobCondition.InterruptForced); + } + + }; + + toils[2] = startPartnerSex; + + toils[3].AddPreTickAction(() => + { + if (!__instance.Partner.TryGetComp().isAnimating) + { + __instance.pawn.TryGetComp().isAnimating = false; + } + }); + + + __result = toils.AsEnumerable(); + + + } + + + + } +} diff --git a/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseInitiator.cs b/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseInitiator.cs new file mode 100644 index 0000000..260d924 --- /dev/null +++ b/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseInitiator.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using RimWorld; +using Verse; +using rjw; + +namespace Rimworld_Animations { + + [HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "Start")] + static class HarmonyPatch_JobDriver_SexBaseInitiator_Start { + public static void Postfix(ref JobDriver_SexBaseInitiator __instance) { + /* + These particular jobs need special code + don't play anim for now + */ + if(__instance is JobDriver_Masturbate || __instance is JobDriver_ViolateCorpse) { + return; + } + + if(!AnimationSettings.PlayAnimForNonsexualActs && NonSexualAct(__instance)) + { + return; + } + + Pawn pawn = __instance.pawn; + + Building_Bed bed = __instance.Bed; + + if ((__instance.Target as Pawn)?.jobs?.curDriver is JobDriver_SexBaseReciever) { + + Pawn Target = __instance.Target as Pawn; + + bool quickie = (__instance is JobDriver_SexQuick) && AnimationSettings.fastAnimForQuickie; + + int preAnimDuration = __instance.duration; + int AnimationTimeTicks = 0; + + + if (bed != null) { + RerollAnimations(Target, out AnimationTimeTicks, bed as Thing, __instance.Sexprops.sexType, quickie, sexProps: __instance.Sexprops); + } + else { + RerollAnimations(Target, out AnimationTimeTicks, sexType: __instance.Sexprops.sexType, fastAnimForQuickie: quickie, sexProps: __instance.Sexprops); + } + + + //Modify Orgasm ticks to only orgasm as many times as RJW stock orgasm allows + if(AnimationTimeTicks != 0) + { + __instance.orgasmstick = preAnimDuration * __instance.orgasmstick / AnimationTimeTicks; + } + + + } + } + + public static void RerollAnimations(Pawn pawn, out int AnimationTimeTicks, Thing bed = null, xxx.rjwSextype sexType = xxx.rjwSextype.None, bool fastAnimForQuickie = false, rjw.SexProps sexProps = null) { + + AnimationTimeTicks = 0; + + if(pawn == null || !(pawn.jobs?.curDriver is JobDriver_SexBaseReciever)) { + Log.Error("Error: Tried to reroll animations when pawn isn't sexing"); + return; + } + + List pawnsToAnimate = (pawn.jobs.curDriver as JobDriver_SexBaseReciever).parteners.ToList(); + + if (!pawnsToAnimate.Contains(pawn)) { + pawnsToAnimate = pawnsToAnimate.Append(pawn).ToList(); + } + + for(int i = 0; i < pawnsToAnimate.Count; i++) { + + if(pawnsToAnimate[i].TryGetComp() == null) { + Log.Error("Error: " + pawnsToAnimate[i].Name + " of race " + pawnsToAnimate[i].def.defName + " does not have CompBodyAnimator attached!"); + break; + } + } + + AnimationDef anim = AnimationUtility.tryFindAnimation(ref pawnsToAnimate, sexType, sexProps); + + if (anim != null) { + + bool mirror = GenTicks.TicksGame % 2 == 0; + + IntVec3 pos = pawn.Position; + + for (int i = 0; i < anim.actors.Count; i++) + { + pawnsToAnimate[i].TryGetComp().isAnimating = false; + } + + for (int i = 0; i < pawnsToAnimate.Count; i++) { + + if (bed != null) + pawnsToAnimate[i].TryGetComp().setAnchor(bed); + else { + + pawnsToAnimate[i].TryGetComp().setAnchor(pos); + } + + bool shiver = pawnsToAnimate[i].jobs.curDriver is JobDriver_SexBaseRecieverRaped; + pawnsToAnimate[i].TryGetComp().StartAnimation(anim, pawnsToAnimate, i, mirror, shiver, fastAnimForQuickie); + + int animTicks = anim.animationTimeTicks - (fastAnimForQuickie ? anim.animationStages[0].playTimeTicks : 0); + (pawnsToAnimate[i].jobs.curDriver as JobDriver_Sex).ticks_left = animTicks; + (pawnsToAnimate[i].jobs.curDriver as JobDriver_Sex).sex_ticks = animTicks; + (pawnsToAnimate[i].jobs.curDriver as JobDriver_Sex).duration = animTicks; + + + AnimationTimeTicks = animTicks; + + if(!AnimationSettings.hearts) { + (pawnsToAnimate[i].jobs.curDriver as JobDriver_Sex).ticks_between_hearts = Int32.MaxValue; + } + + } + } + else { + Log.Message("No animation found"); + + /* + + //if pawn isn't already animating, + if (!pawn.TryGetComp().isAnimating) { + (pawn.jobs.curDriver as JobDriver_SexBaseReciever).increase_time(duration); + //they'll just do the thrusting anim + } + + */ + } + } + + + static IEnumerable NonSexActRulePackDefNames = new String[] + { + "MutualHandholdingRP", + "MutualMakeoutRP", + }; + + public static bool NonSexualAct(JobDriver_SexBaseInitiator sexBaseInitiator) + { + if(NonSexActRulePackDefNames.Contains(sexBaseInitiator.Sexprops.rulePack)) + { + return true; + } + return false; + } + } + + [HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "End")] + static class HarmonyPatch_JobDriver_SexBaseInitiator_End { + + public static void Postfix(ref JobDriver_SexBaseInitiator __instance) { + + if ((__instance.Target as Pawn)?.jobs?.curDriver is JobDriver_SexBaseReciever) { + if (__instance.pawn.TryGetComp().isAnimating) { + + List parteners = ((__instance.Target as Pawn)?.jobs.curDriver as JobDriver_SexBaseReciever).parteners; + + for (int i = 0; i < parteners.Count; i++) { + + //prevents pawns who started a new anim from stopping their new anim + if (!((parteners[i].jobs.curDriver as JobDriver_SexBaseInitiator) != null && (parteners[i].jobs.curDriver as JobDriver_SexBaseInitiator).Target != __instance.pawn)) + parteners[i].TryGetComp().isAnimating = false; + + } + + __instance.Target.TryGetComp().isAnimating = false; + + if (xxx.is_human((__instance.Target as Pawn))) { + (__instance.Target as Pawn)?.Drawer.renderer.graphics.ResolveApparelGraphics(); + PortraitsCache.SetDirty((__instance.Target as Pawn)); + } + } + + ((__instance.Target as Pawn)?.jobs.curDriver as JobDriver_SexBaseReciever).parteners.Remove(__instance.pawn); + + } + + if (xxx.is_human(__instance.pawn)) { + __instance.pawn.Drawer.renderer.graphics.ResolveApparelGraphics(); + PortraitsCache.SetDirty(__instance.pawn); + } + } + } +} diff --git a/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseReceiverLoved.cs b/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseReceiverLoved.cs new file mode 100644 index 0000000..dfa116e --- /dev/null +++ b/1.4/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseReceiverLoved.cs @@ -0,0 +1,46 @@ +using System; +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 +{ + + [HarmonyPatch(typeof(JobDriver_SexBaseRecieverLoved), "MakeSexToil")] + public static class HarmonyPatch_JobDriver_SexBaseReceiverLoved + { + public static IEnumerable Transpiler(IEnumerable codeInstructions) + { + + var ins = codeInstructions.ToList(); + for(int i = 0; i < ins.Count; i++) + { + if(i < ins.Count && ins[i].opcode == OpCodes.Call && ins[i].OperandIs(AccessTools.DeclaredMethod(typeof(Toils_LayDown), "LayDown"))) { + + ins[i].operand = AccessTools.DeclaredMethod(typeof(HarmonyPatch_JobDriver_SexBaseReceiverLoved), "DoNotLayDown"); + yield return ins[i]; + + } + + else + { + yield return ins[i]; + } + } + + } + + public static Toil DoNotLayDown(TargetIndex bedOrRestSpotIndex, bool hasBed, bool lookForOtherJobs, bool canSleep = true, bool gainRestAndHealth = true, PawnPosture noBedLayingPosture = PawnPosture.LayingMask, bool deathrest = false) + { + return new Toil(); + } + + } +} diff --git a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_HeadHair.cs b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_HeadHair.cs new file mode 100644 index 0000000..37ba6ce --- /dev/null +++ b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_HeadHair.cs @@ -0,0 +1,22 @@ +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using RimWorld; +using UnityEngine; + +namespace Rimworld_Animations +{ + [HarmonyPatch(typeof(PawnRenderer), "DrawHeadHair")] + public static class HarmonyPatch_HeadHair + { + public static void Prefix(ref Vector3 headOffset, ref float angle) + { + + } + + } +} diff --git a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRenderer.cs b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRenderer.cs new file mode 100644 index 0000000..b7ff70d --- /dev/null +++ b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRenderer.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using HarmonyLib; +using RimWorld; +using Verse; +using UnityEngine; +using System.Reflection; +using System.Reflection.Emit; + +namespace Rimworld_Animations { + + [HarmonyPatch(typeof(PawnRenderer), "RenderPawnInternal", new Type[] + { + typeof(Vector3), + typeof(float), + typeof(bool), + typeof(Rot4), + typeof(RotDrawMode), + typeof(PawnRenderFlags) + } + )] + public static class HarmonyPatch_PawnRenderer + { + + [HarmonyBefore(new string[] { "showhair.kv.rw", "erdelf.HumanoidAlienRaces", "Nals.FacialAnimation" })] + public static void Prefix(PawnRenderer __instance, ref Vector3 rootLoc, ref float angle, bool renderBody, ref Rot4 bodyFacing, RotDrawMode bodyDrawType, PawnRenderFlags flags) + { + + if (flags.FlagSet(PawnRenderFlags.Portrait)) return; + + PawnGraphicSet graphics = __instance.graphics; + Pawn pawn = graphics.pawn; + CompBodyAnimator bodyAnim = pawn.TryGetComp(); + + + if (bodyAnim != null && bodyAnim.isAnimating && pawn.Map == Find.CurrentMap) + { + bodyAnim.animatePawnBody(ref rootLoc, ref angle, ref bodyFacing); + + } + + } + + public static IEnumerable Transpiler(IEnumerable instructions) + { + List ins = instructions.ToList(); + + for(int i = 0; i < instructions.Count(); i++) + { + + if (i - 3 >= 0 && ins[i - 3].opcode == OpCodes.Call && ins[i - 3].operand != null && ins[i - 3].OperandIs(AccessTools.DeclaredMethod(typeof(PawnRenderer), "BaseHeadOffsetAt"))) + { + + yield return new CodeInstruction(OpCodes.Ldloca, (object)0); + yield return new CodeInstruction(OpCodes.Ldloca, (object)9); + yield return new CodeInstruction(OpCodes.Ldloca, (object)8); + yield return new CodeInstruction(OpCodes.Ldarga, (object)2); + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(typeof(PawnRenderer), "pawn")); + yield return new CodeInstruction(OpCodes.Ldarg, (object)6); + yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(AnimationUtility), "AdjustHead")); + yield return ins[i]; + //headFacing equals true + } + // Fixes the offsets for eye implants and wounds on the head during animations + else if (ins[i].opcode == OpCodes.Callvirt && ins[i].operand != null && ins[i].OperandIs(AccessTools.DeclaredMethod(typeof(PawnOverlayDrawer), "RenderPawnOverlay"))) + { + // Pass some additional info to a new overload of RenderOverBody + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(typeof(PawnRenderer), "pawn")); + yield return new CodeInstruction(OpCodes.Ldarg_S, (object)6); // renderer flags + yield return new CodeInstruction(OpCodes.Call, AccessTools.DeclaredMethod(typeof(PawnWoundDrawerExtension), "RenderPawnOverlay")); + } + else + { + yield return ins[i]; + } + } + } + } +} diff --git a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRotation.cs b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRotation.cs new file mode 100644 index 0000000..7ec75a1 --- /dev/null +++ b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_PawnRotation.cs @@ -0,0 +1,29 @@ +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)] + public static class HarmonyPatch_PawnRotation { + + public static bool Prefix(Thing __instance, ref Rot4 __result) { + + if(!(__instance is Pawn) || (__instance as Pawn)?.TryGetComp() == null || !(__instance as Pawn).TryGetComp().isAnimating) { + return true; + } + + Pawn pawn = (__instance as Pawn); + __result = pawn.TryGetComp().bodyFacing; + + return false; + + + } + + } + +} diff --git a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_Pawn_DrawTracker.cs b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_Pawn_DrawTracker.cs new file mode 100644 index 0000000..5cdcfce --- /dev/null +++ b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_Pawn_DrawTracker.cs @@ -0,0 +1,26 @@ +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +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) { + + CompBodyAnimator bodyAnim = ___pawn.TryGetComp(); + + if (bodyAnim != null && bodyAnim.isAnimating) { + __result = ___pawn.TryGetComp().anchor + ___pawn.TryGetComp().deltaPos; + + return false; + } + return true; + } + } +} diff --git a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_SetPawnAnimatable.cs b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_SetPawnAnimatable.cs new file mode 100644 index 0000000..b8c66b8 --- /dev/null +++ b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_SetPawnAnimatable.cs @@ -0,0 +1,40 @@ +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 +{ + [HarmonyPatch(typeof(PawnRenderer), "RenderPawnAt")] + public static class PawnRenderer_RenderPawnAt_Patch + { + static bool ClearCache(Pawn pawn) + { + return pawn.IsInvisible() || (pawn.TryGetComp() != null && pawn.TryGetComp().isAnimating); + } + + public static IEnumerable Transpiler(IEnumerable instructions) + { + var list = instructions.ToList(); + + foreach (CodeInstruction i in instructions) + { + if (i.OperandIs(AccessTools.Method(typeof(PawnUtility), "IsInvisible"))) + { + yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PawnRenderer_RenderPawnAt_Patch), "ClearCache")); + } + else + { + yield return i; + } + } + } + } + +} diff --git a/1.4/Source/Patches/RimworldPatches/HarmonyPatch_Thing.cs b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_Thing.cs new file mode 100644 index 0000000..9477abf --- /dev/null +++ b/1.4/Source/Patches/RimworldPatches/HarmonyPatch_Thing.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HarmonyLib; +using RimWorld; +using Verse; + +namespace Rimworld_Animations +{ + [HarmonyPatch(typeof(Thing), "DrawAt")] + public static class HarmonyPatch_Thing + { + + public static bool Prefix(Thing __instance) + { + CompThingAnimator thingAnimator = __instance.TryGetComp(); + if (thingAnimator != null && thingAnimator.isAnimating) + { + thingAnimator.AnimateThing(__instance); + return false; + + } + + return true; + + } + + } +} diff --git a/1.4/Source/Settings/AnimationSettings.cs b/1.4/Source/Settings/AnimationSettings.cs new file mode 100644 index 0000000..0a96621 --- /dev/null +++ b/1.4/Source/Settings/AnimationSettings.cs @@ -0,0 +1,98 @@ +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 offsets = new Dictionary(); + public static Dictionary rotation = new Dictionary(); + + 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-sheartsOnLovin"); + 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(); + + } + + 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"; + } + } +} diff --git a/1.4/Source/Utilities/AnimationUtility.cs b/1.4/Source/Utilities/AnimationUtility.cs new file mode 100644 index 0000000..a75fc32 --- /dev/null +++ b/1.4/Source/Utilities/AnimationUtility.cs @@ -0,0 +1,319 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RimWorld; +using rjw.Modules.Interactions.Helpers; +using rjw.Modules.Interactions.Objects; +using UnityEngine; +using Verse; +using Verse.AI; +using rjw.Modules.Interactions.Enums; + +namespace Rimworld_Animations { + public static class AnimationUtility { + /* + Note: always make the list in this order: + Female pawns, animal female pawns, male pawns, animal male pawns + */ + public static AnimationDef tryFindAnimation(ref List participants, rjw.xxx.rjwSextype sexType = 0, rjw.SexProps sexProps = null) { + + + InteractionWithExtension interaction = InteractionHelper.GetWithExtension(sexProps.dictionaryKey); + + + if(interaction.HasInteractionTag(InteractionTag.Reverse)) + { + Pawn buffer = participants[1]; + participants[1] = participants[0]; + participants[0] = buffer; + } + + participants = + participants.OrderBy(p => p.jobs.curDriver is rjw.JobDriver_SexBaseInitiator) + .OrderBy(p => rjw.xxx.can_fuck(p)) + .ToList(); + + + List localParticipants = new List(participants); + + IEnumerable options = DefDatabase.AllDefs.Where((AnimationDef x) => { + + + if (x.actors.Count != localParticipants.Count) { + return false; + } + for (int i = 0; i < x.actors.Count; i++) { + + if (rjw.RJWPreferenceSettings.Malesex == rjw.RJWPreferenceSettings.AllowedSex.Nohomo) { + if (rjw.xxx.is_male(localParticipants[i]) && x.actors[i].isFucked) { + return false; + } + } + if (x.actors[i].requiredGender != null && !x.actors[i].requiredGender.Contains(localParticipants[i].gender.ToStringSafe())) + { + if (AnimationSettings.debugMode) + { + Log.Message(string.Concat(new string[] + { + x.defName.ToStringSafe(), + " not selected -- ", + localParticipants[i].def.defName.ToStringSafe(), + " ", + localParticipants[i].Name.ToStringSafe(), + " does not match required gender" + })); + } + return false; + } + if ((x.actors[i].blacklistedRaces != null) && x.actors[i].blacklistedRaces.Contains(localParticipants[i].def.defName)) { + if(AnimationSettings.debugMode) + Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " is blacklisted"); + return false; + } + + if(x.actors[i].defNames.Contains("Human")) { + if (!rjw.xxx.is_human(localParticipants[i])) { + if (AnimationSettings.debugMode) + Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " is not human"); + + return false; + } + + } + else if (!x.actors[i].bodyDefTypes.Contains(localParticipants[i].RaceProps.body)) { + + if (!x.actors[i].defNames.Contains(localParticipants[i].def.defName)) { + + if (rjw.RJWSettings.DevMode) { + string animInfo = x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " is not "; + foreach(String defname in x.actors[i].defNames) { + animInfo += defname + ", "; + } + if (AnimationSettings.debugMode) + Log.Message(animInfo); + } + + return false; + } + } + //genitals checking + + if(!GenitalCheckForPawn(x.actors[i].requiredGenitals, localParticipants[i], out string failReason)) { + Debug.Log("Didn't select " + x.defName + ", " + localParticipants[i].Name + " " + failReason); + return false; + } + + //TESTING ANIMATIONS ONLY REMEMBER TO COMMENT OUT BEFORE PUSH + /* + if (x.defName != "Cunnilingus") + return false; + */ + + + if (x.actors[i].isFucking && !rjw.xxx.can_fuck(localParticipants[i])) { + if (AnimationSettings.debugMode) + Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " can't fuck"); + return false; + } + + if (x.actors[i].isFucked && !rjw.xxx.can_be_fucked(localParticipants[i])) { + if (AnimationSettings.debugMode) + Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " can't be fucked"); + return false; + } + } + return true; + }); + List optionsWithInteractionType = options.ToList().FindAll(x => x.interactionDefTypes != null && x.interactionDefTypes.Contains(sexProps.sexType.ToStringSafe())); + if (optionsWithInteractionType.Any()) { + if (AnimationSettings.debugMode) + Log.Message("Selecting animation for interaction type " + sexProps.sexType.ToStringSafe() + "..."); + return optionsWithInteractionType.RandomElement(); + } + List optionsWithSexType = options.ToList().FindAll(x => x.sexTypes != null && x.sexTypes.Contains(sexType)); + if (optionsWithSexType.Any()) { + if (AnimationSettings.debugMode) + Log.Message("Selecting animation for rjwSexType " + sexType.ToStringSafe() + "..."); + return optionsWithSexType.RandomElement(); + } + + /* + if(optionsWithInitiator.Any()) { + if (AnimationSettings.debugMode) + Log.Message("Selecting animation for initiators..."); + } + */ + + if (options != null && options.Any()) { + if (AnimationSettings.debugMode) + Log.Message("Randomly selecting animation..."); + return options.RandomElement(); + } + else + return null; + } + + public static void RenderPawnHeadMeshInAnimation1(Mesh mesh, Vector3 loc, Quaternion quaternion, Material material, bool drawNow, Pawn pawn) { + + if (pawn == null || pawn.Map != Find.CurrentMap) { + GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, drawNow); + return; + } + + CompBodyAnimator pawnAnimator = pawn.TryGetComp(); + + if (pawnAnimator == null || !pawnAnimator.isAnimating) { + GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, drawNow); + } else { + Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition(); + pawnHeadPosition.y = loc.y; + GenDraw.DrawMeshNowOrLater(MeshPool.humanlikeHeadSet.MeshAt(pawnAnimator.headFacing), pawnHeadPosition, Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up), material, true); + } + } + + public static void AdjustHead(ref Quaternion quat, ref Rot4 bodyFacing, ref Vector3 pos, ref float angle, Pawn pawn, PawnRenderFlags flags) + { + if (flags.FlagSet(PawnRenderFlags.Portrait)) return; + + CompBodyAnimator anim = pawn.TryGetComp(); + if (anim.isAnimating) + { + bodyFacing = anim.headFacing; + angle = anim.headAngle; + quat = Quaternion.AngleAxis(anim.headAngle, Vector3.up); + pos = anim.getPawnHeadOffset(); + + } + } + + public static void RenderPawnHeadMeshInAnimation(Mesh mesh, Vector3 loc, Quaternion quaternion, Material material, bool portrait, Pawn pawn, float bodySizeFactor = 1) { + + if (pawn == null) { + GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, portrait); + return; + } + + CompBodyAnimator pawnAnimator = pawn.TryGetComp(); + + if (pawnAnimator == null || !pawnAnimator.isAnimating || portrait) { + GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, portrait); + } + else { + Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition(); + pawnHeadPosition.x *= bodySizeFactor; + pawnHeadPosition.x *= bodySizeFactor; + pawnHeadPosition.y = loc.y; + GenDraw.DrawMeshNowOrLater(mesh, pawnHeadPosition, Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up), material, portrait); + } + } + + public static bool GenitalCheckForPawn(List requiredGenitals, Pawn pawn, out string failReason) { + + failReason = null; + if (requiredGenitals != null) { + if (requiredGenitals.Contains("Vagina")) { + + if (!rjw.Genital_Helper.has_vagina(pawn)) { + failReason = "missing vagina"; + return false; + } + + } + + if (requiredGenitals.Contains("Penis")) { + + if (!(rjw.Genital_Helper.has_multipenis(pawn) || rjw.Genital_Helper.has_penis_infertile(pawn) || rjw.Genital_Helper.has_penis_fertile(pawn) || rjw.Genital_Helper.has_ovipositorM(pawn) || rjw.Genital_Helper.has_ovipositorF(pawn))) { + failReason = "missing penis"; + return false; + } + + } + + if (requiredGenitals.Contains("Mouth")) { + + if (!rjw.Genital_Helper.has_mouth(pawn)) { + failReason = "missing mouth"; + return false; + } + + } + + if (requiredGenitals.Contains("Anus")) { + + if (!rjw.Genital_Helper.has_anus(pawn)) { + failReason = "missing anus"; + return false; + } + + } + + if (requiredGenitals.Contains("Breasts")) { + if (!rjw.Genital_Helper.can_do_breastjob(pawn)) { + failReason = "missing breasts"; + return false; + } + } + + if (requiredGenitals.Contains("NoVagina")) { + + if (rjw.Genital_Helper.has_vagina(pawn)) { + failReason = "has vagina"; + return false; + } + + } + + if (requiredGenitals.Contains("NoPenis")) { + + if ((rjw.Genital_Helper.has_multipenis(pawn) || rjw.Genital_Helper.has_penis_infertile(pawn) || rjw.Genital_Helper.has_penis_fertile(pawn))) { + failReason = "has penis"; + return false; + } + + } + + if (requiredGenitals.Contains("NoMouth")) { + + if (rjw.Genital_Helper.has_mouth(pawn)) { + failReason = "has mouth"; + return false; + } + + } + + if (requiredGenitals.Contains("NoAnus")) { + + if (rjw.Genital_Helper.has_anus(pawn)) { + failReason = "has anus"; + return false; + } + + } + + if (requiredGenitals.Contains("NoBreasts")) { + if (rjw.Genital_Helper.can_do_breastjob(pawn)) { + failReason = "has breasts"; + return false; + } + } + } + + return true; + + } + + public static Rot4 PawnHeadRotInAnimation(Pawn pawn, Rot4 regularPos) + { + Debug.Log("Test"); + + if(pawn?.TryGetComp() != null && pawn.TryGetComp().isAnimating) + { + return pawn.TryGetComp().headFacing; + } + + return regularPos; + } + } +} diff --git a/1.4/Source/Utilities/PatchOperationAddOrReplace.cs b/1.4/Source/Utilities/PatchOperationAddOrReplace.cs new file mode 100644 index 0000000..4e1bd85 --- /dev/null +++ b/1.4/Source/Utilities/PatchOperationAddOrReplace.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using Verse; + +namespace Rimworld_Animations +{ + public class PatchOperationAddOrReplace : PatchOperationPathed + { + + protected string key; + private XmlContainer value; + + protected override bool ApplyWorker(XmlDocument xml) + { + XmlNode valNode = value.node; + bool result = false; + IEnumerator enumerator = xml.SelectNodes(xpath).GetEnumerator(); + try + { + while (enumerator.MoveNext()) + { + object obj = enumerator.Current; + result = true; + XmlNode parentNode = obj as XmlNode; + XmlNode xmlNode = parentNode.SelectSingleNode(key); + if (xmlNode == null) + { + // Add - Add node if not existing + xmlNode = parentNode.OwnerDocument.CreateElement(key); + parentNode.AppendChild(xmlNode); + } + else + { + // Replace - Clear existing children + xmlNode.RemoveAll(); + } + // (Re)add value + xmlNode.AppendChild(parentNode.OwnerDocument.ImportNode(valNode.FirstChild, true)); + } + } + finally + { + IDisposable disposable = enumerator as IDisposable; + if (disposable != null) + { + disposable.Dispose(); + } + } + return result; + } + + } + +} diff --git a/1.4/Textures/UI/MainTab.png b/1.4/Textures/UI/MainTab.png new file mode 100644 index 0000000..92f855f Binary files /dev/null and b/1.4/Textures/UI/MainTab.png differ diff --git a/About/About.xml b/About/About.xml index 1c8f765..fbfc206 100644 --- a/About/About.xml +++ b/About/About.xml @@ -3,11 +3,14 @@ Rimworld-Animations C0ffee - https://gitgud.io/Platinumspoons/rimworld-animations/ + https://gitgud.io/c0ffeeeeeeee/rimworld-animations
  • 1.1
  • +
  • 1.2
  • +
  • 1.3
  • +
  • 1.4
  • - platinumspoons.rimworld.animations + c0ffee.rimworld.animations
  • brrainz.harmony @@ -21,17 +24,28 @@ https://github.com/UnlimitedHugs/RimworldHugsLib/releases/latest steam://url/CommunityFilePage/818773962
  • -
  • - rim.job.world - RimJobWorld - https://www.loverslab.com/topic/110270-mod-rimjobworld/ -
  • +
  • + rim.job.world + RimJobWorld + https://www.loverslab.com/topic/110270-mod-rimjobworld/ +
  • +
  • + erdelf.HumanoidAlienRaces + Humanoid Alien Races 2.0 + https://steamcommunity.com/sharedfiles/filedetails/?id=839005762 +
  • UnlimitedHugs.HugsLib
  • brrainz.harmony
  • -
  • rim.job.world
  • +
  • erdelf.humanoidalienraces
  • +
  • nals.facialanimation
  • +
  • com.yayo.yayoAni
  • + + + + Rimworld Animations! Hurray! diff --git a/About/Manifest.xml b/About/Manifest.xml new file mode 100644 index 0000000..2391026 --- /dev/null +++ b/About/Manifest.xml @@ -0,0 +1,5 @@ + + + Rimworld-Animations + 1.3.0 + diff --git a/Languages/PortugueseBrazilian/DefInjected/MainButtonDef/MainButtonDef.xml b/Languages/PortugueseBrazilian/DefInjected/MainButtonDef/MainButtonDef.xml new file mode 100644 index 0000000..03525fa --- /dev/null +++ b/Languages/PortugueseBrazilian/DefInjected/MainButtonDef/MainButtonDef.xml @@ -0,0 +1,7 @@ + + + + gerenciador de posições + Controla as posições sexuais dos colonos. + + \ No newline at end of file diff --git a/Languages/PortugueseBrazilian/DefInjected/Rimworld_Animations.AnimationDef/Animations_Beast.xml b/Languages/PortugueseBrazilian/DefInjected/Rimworld_Animations.AnimationDef/Animations_Beast.xml new file mode 100644 index 0000000..796b225 --- /dev/null +++ b/Languages/PortugueseBrazilian/DefInjected/Rimworld_Animations.AnimationDef/Animations_Beast.xml @@ -0,0 +1,7 @@ + + + + estilo cachorrinho + vaqueira + + \ No newline at end of file diff --git a/Languages/PortugueseBrazilian/DefInjected/Rimworld_Animations.AnimationDef/Animations_Lesbian.xml b/Languages/PortugueseBrazilian/DefInjected/Rimworld_Animations.AnimationDef/Animations_Lesbian.xml new file mode 100644 index 0000000..ff95a7c --- /dev/null +++ b/Languages/PortugueseBrazilian/DefInjected/Rimworld_Animations.AnimationDef/Animations_Lesbian.xml @@ -0,0 +1,7 @@ + + + + tribadismo + cunilíngua + + \ No newline at end of file diff --git a/Languages/PortugueseBrazilian/DefInjected/Rimworld_Animations.AnimationDef/Animations_Multi.xml b/Languages/PortugueseBrazilian/DefInjected/Rimworld_Animations.AnimationDef/Animations_Multi.xml new file mode 100644 index 0000000..bc698f0 --- /dev/null +++ b/Languages/PortugueseBrazilian/DefInjected/Rimworld_Animations.AnimationDef/Animations_Multi.xml @@ -0,0 +1,6 @@ + + + + dupla penetração + + \ No newline at end of file diff --git a/Languages/PortugueseBrazilian/DefInjected/Rimworld_Animations.AnimationDef/Animations_vanilla.xml b/Languages/PortugueseBrazilian/DefInjected/Rimworld_Animations.AnimationDef/Animations_vanilla.xml new file mode 100644 index 0000000..8d86e17 --- /dev/null +++ b/Languages/PortugueseBrazilian/DefInjected/Rimworld_Animations.AnimationDef/Animations_vanilla.xml @@ -0,0 +1,9 @@ + + + + estilo cachorrinho + boquete + 69 + vaqueira + + \ No newline at end of file diff --git a/LoadFolders.xml b/LoadFolders.xml new file mode 100644 index 0000000..4fad350 --- /dev/null +++ b/LoadFolders.xml @@ -0,0 +1,28 @@ + + + +
  • /
  • +
  • 1.1
  • +
    + +
  • /
  • +
  • 1.2
  • +
  • Patch_HatsDisplaySelection/1.2
  • +
    + +
  • /
  • +
  • 1.3
  • +
  • Patch_HatsDisplaySelection/1.2
  • +
  • Patch_SexToysMasturbation
  • +
  • Patch_SexToysMasturbation/1.3
  • +
    + +
  • /
  • +
  • 1.4
  • +
  • Patch_HatsDisplaySelection/1.2
  • +
  • Patch_SexToysMasturbation
  • +
  • Patch_SexToysMasturbation/1.4
  • +
    + + +
    diff --git a/Patch_SexToysMasturbation/1.3/Assemblies/Patch_SexToysMasturbation.dll b/Patch_SexToysMasturbation/1.3/Assemblies/Patch_SexToysMasturbation.dll new file mode 100644 index 0000000..723e4ee Binary files /dev/null and b/Patch_SexToysMasturbation/1.3/Assemblies/Patch_SexToysMasturbation.dll differ diff --git a/Patch_SexToysMasturbation/1.3/Defs/AnimationDefs/Animations_Dildo.xml b/Patch_SexToysMasturbation/1.3/Defs/AnimationDefs/Animations_Dildo.xml new file mode 100644 index 0000000..dd483ea --- /dev/null +++ b/Patch_SexToysMasturbation/1.3/Defs/AnimationDefs/Animations_Dildo.xml @@ -0,0 +1,465 @@ + + + + Masturbation_DildoVaginal + + vagina + true + +
  • Masturbation
  • +
    + +
  • + +
  • Human
  • + + true + +
    + + +
  • + Masturbating + true + 917 + 0 + +
  • + LayingPawn + +
  • + + 40 + 73.01611 + 40.0739746 + 0 + 0.054543376 + 0.112624526 + 0 + 3 + 3 +
  • +
  • + + Slimy + 30 + 76.4867554 + 45.3887634 + 0 + 0.0506898165 + 0.08564949 + 0 + 3 + 3 +
  • +
  • + + 30 + 78.22131 + 48.0072327 + 0 + 0.039129138 + 0.07794231 + 0 + 3 + 3 +
  • +
  • + + 30 + 76.4867554 + 45.3887634 + 0 + 0.0506898165 + 0.08564949 + 0 + 3 + 3 +
  • +
  • + + 1 + 73.01611 + 40.0739746 + 0 + 0.054543376 + 0.112624526 + 0 + 3 + 3 +
  • + + +
  • + +
  • + + 40 + -0.359264076 + -0.00901746 + 114.011215 +
  • +
  • + + 30 + -0.2783391 + -0.0514066666 + 81.16443 +
  • +
  • + + 30 + -0.1704393 + -0.0668209046 + 72.8611145 +
  • +
  • + + 30 + -0.2783391 + -0.0514066666 + 81.16443 +
  • +
  • + + 1 + -0.359264076 + -0.00901746 + 114.011215 +
  • + + + + +
  • + GettingIntoPosition + false + 0 + +
  • + LayingPawn + +
  • + + 50 + 73.01611 + 40.0739746 + 0 + 0.054543376 + 0.112624526 + 0 + 3 + 3 +
  • +
  • + Slimy + 1 + 81.65927 + 58.8843079 + 0 + 0.03912908 + 0.08950315 + 0 + 3 + 3 +
  • + + +
  • + +
  • + + 50 + -0.359264076 + -0.00901746 + 114.011215 +
  • +
  • + + 1 + -0.2899 + -0.0282852575 + 98.13748 +
  • + + + + +
  • + FastMasturbation + true + 0 + 1610 + +
  • + LayingPawn + +
  • + 20 + 81.65927 + 58.8843079 + 0 + 0.03912908 + 0.08950315 + 0 + 3 + 3 +
  • +
  • + Slimy + 25 + 85.17255 + 58.0615845 + 0 + 0.03527552 + 0.0471138731 + 0 + 3 + 3 +
  • +
  • + 1 + 81.65927 + 58.8843079 + 0 + 0.03912908 + 0.08950315 + 0 + 3 + 3 +
  • + + +
  • + +
  • + + 25 + -0.2899 + -0.0282852575 + 98.13748 +
  • +
  • + + 20 + -0.178146541 + -0.01672452 + 96.95889 +
  • +
  • + + 1 + -0.2899 + -0.0282852575 + 98.13748 +
  • + + + + +
  • + VeryFastMasturbation + true + 0 + 225 + +
  • + LayingPawn + +
  • + 6 + 81.65927 + 58.8843079 + 0 + 0.03912908 + 0.08950315 + 0 + 3 + 3 +
  • +
  • + Slimy + 8 + 85.17255 + 58.0615845 + 0 + 0.03527552 + 0.0471138731 + 0 + 3 + 3 +
  • +
  • + 1 + 81.65927 + 58.8843079 + 0 + 0.03912908 + 0.08950315 + 0 + 3 + 3 +
  • + + +
  • + +
  • + + 6 + -0.2899 + -0.0282852575 + 98.13748 +
  • +
  • + + 8 + -0.178146541 + -0.01672452 + 96.95889 +
  • +
  • + + 1 + -0.2899 + -0.0282852575 + 98.13748 +
  • + + + + +
  • + Orgasm + false + 0 + +
  • + LayingPawn + +
  • + Slimy + 6 + 81.65927 + 58.8843079 + 0 + 0.03912908 + 0.08950315 + 0 + 3 + 3 +
  • +
  • + True + Cum + 80 + 85.17255 + 58.0615845 + 0 + 0.03527552 + 0.0471138731 + 0 + 3 + 3 +
  • +
  • + True + Cum + 90 + 92.15109 + 96.34238 + 0 + 0.0237147212 + 0.0432603136 + 0 + 3 + 3 +
  • +
  • + True + Cum + 70 + 92.15109 + 96.34238 + 0 + 0.0237147212 + 0.0432603136 + 0 + 3 + 3 +
  • +
  • + 70 + 92.15109 + 96.34238 + 0 + 0.0237147212 + 0.0432603136 + 0 + 3 + 3 +
  • +
  • + 1 + 81.65927 + 58.8843079 + 0 + 0.03912908 + 0.08950315 + 0 + 3 + 3 +
  • + + +
  • + +
  • + + 6 + -0.2899 + -0.0282852575 + 98.13748 +
  • +
  • + + 80 + -0.178146541 + -0.01672452 + 96.95889 +
  • +
  • + + 90 + -0.178146541 + -0.01672452 + 96.95889 +
  • +
  • + + 70 + -0.178146541 + -0.01672452 + 96.95889 +
  • +
  • + + 70 + -0.178146541 + -0.01672452 + 96.95889 +
  • +
  • + + 1 + -0.2899 + -0.0282852575 + 98.13748 +
  • + + + + +
    +
    +
    \ No newline at end of file diff --git a/Patch_SexToysMasturbation/1.4/Assemblies/Patch_SexToysMasturbation.dll b/Patch_SexToysMasturbation/1.4/Assemblies/Patch_SexToysMasturbation.dll new file mode 100644 index 0000000..1680010 Binary files /dev/null and b/Patch_SexToysMasturbation/1.4/Assemblies/Patch_SexToysMasturbation.dll differ diff --git a/Patch_SexToysMasturbation/Patch_SexToysMasturbation.csproj b/Patch_SexToysMasturbation/Patch_SexToysMasturbation.csproj new file mode 100644 index 0000000..9509bd9 --- /dev/null +++ b/Patch_SexToysMasturbation/Patch_SexToysMasturbation.csproj @@ -0,0 +1,87 @@ + + + + + Debug + AnyCPU + {87763712-0536-4D5F-9EAA-520F15D4F84E} + Library + Properties + Patch_SexToysMasturbation + Patch_SexToysMasturbation + v4.7.2 + 512 + true + + + false + none + false + 1.4\Assemblies\ + DEBUG;TRACE + prompt + 4 + Auto + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\..\workshop\content\294100\1127530465\1.3\Assemblies\0Harmony.dll + False + + + ..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll + False + + + False + ..\1.3\Assemblies\Rimworld-Animations.dll + False + + + ..\..\rjw\1.4\Assemblies\RJW.dll + False + + + ..\..\rjw-toys-and-masturbation\Assemblies\RJW-ToysAndMasturbation.dll + False + + + + + + + + + + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll + False + + + ..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll + False + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Patch_SexToysMasturbation/Properties/AssemblyInfo.cs b/Patch_SexToysMasturbation/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..55c921a --- /dev/null +++ b/Patch_SexToysMasturbation/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Patch_SexToysMasturbation")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Patch_SexToysMasturbation")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("87763712-0536-4d5f-9eaa-520f15d4f84e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Patch_SexToysMasturbation/Source/Defs/SexToyAnimationDef.cs b/Patch_SexToysMasturbation/Source/Defs/SexToyAnimationDef.cs new file mode 100644 index 0000000..a572d5e --- /dev/null +++ b/Patch_SexToysMasturbation/Source/Defs/SexToyAnimationDef.cs @@ -0,0 +1,16 @@ +using Rimworld_Animations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Patch_SexToysMasturbation +{ + public class SexToyAnimationDef : AnimationDef + { + + public String requiredBodyPart = null; + + } +} diff --git a/Patch_SexToysMasturbation/Source/Harmony/Harmony_PatchAll.cs b/Patch_SexToysMasturbation/Source/Harmony/Harmony_PatchAll.cs new file mode 100644 index 0000000..b48ece7 --- /dev/null +++ b/Patch_SexToysMasturbation/Source/Harmony/Harmony_PatchAll.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using HarmonyLib; +using System.Reflection; + +namespace Patch_SexToysMasturbation +{ + + [StaticConstructorOnStartup] + public static class Harmony_PatchAll { + + static Harmony_PatchAll() { + + Harmony val = new Harmony("animtoyspatch"); + val.PatchAll(Assembly.GetExecutingAssembly()); + + } + } +} diff --git a/Patch_SexToysMasturbation/Source/Patches/HarmonyPatch_JobDriver_SexBaseInitiator.cs b/Patch_SexToysMasturbation/Source/Patches/HarmonyPatch_JobDriver_SexBaseInitiator.cs new file mode 100644 index 0000000..ef3f4fb --- /dev/null +++ b/Patch_SexToysMasturbation/Source/Patches/HarmonyPatch_JobDriver_SexBaseInitiator.cs @@ -0,0 +1,75 @@ +using HarmonyLib; +using Rimworld_Animations; +using rjw; +using RJW_ToysAndMasturbation; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace Patch_SexToysMasturbation +{ + [HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "Start")] + public class HarmonyPatch_JobDriver_SexBaseInitiator + { + + public static void Postfix(ref JobDriver_SexBaseInitiator __instance) + { + + if(__instance is JobDriver_MasturbateWithToy masturbateJobDriver) + { + + Log.Message("Rerolling animations..."); + Pawn pawn = masturbateJobDriver.pawn; + Thing sexToy = masturbateJobDriver.dildo; + + RerollAnimationsForSexToy(pawn, sexToy, masturbateJobDriver.Bed); + } + + + } + + public static void RerollAnimationsForSexToy(Pawn pawn, Thing thing, Thing bed) + { + CompSexToy sextoy = thing.TryGetComp(); + + SexToyAnimationDef anim = AnimSexToyUtility.tryFindAnimation(sextoy, pawn); + + if (anim != null) + { + Log.Message("Playing anim " + anim.defName); + + if(bed != null) + { + pawn.TryGetComp().setAnchor(bed); + thing.TryGetComp().setAnchor(bed); + } + else + { + pawn.TryGetComp().setAnchor(pawn.Position); + thing.TryGetComp().setAnchor(pawn.Position); + } + + bool mirror = GenTicks.TicksGame % 2 == 0; + + pawn.TryGetComp().StartAnimation(anim, new List { pawn }, 0, mirror); + thing.TryGetComp().StartAnimation(anim, pawn, mirror); + + (pawn.jobs.curDriver as JobDriver_Sex).ticks_left = anim.animationTimeTicks; + (pawn.jobs.curDriver as JobDriver_Sex).sex_ticks = anim.animationTimeTicks; + (pawn.jobs.curDriver as JobDriver_Sex).duration = anim.animationTimeTicks; + } + else + { + Log.Message("No animation found"); + } + + + } + + } + + +} diff --git a/Patch_SexToysMasturbation/Source/Utilities/AnimSexToyUtility.cs b/Patch_SexToysMasturbation/Source/Utilities/AnimSexToyUtility.cs new file mode 100644 index 0000000..5ab05b1 --- /dev/null +++ b/Patch_SexToysMasturbation/Source/Utilities/AnimSexToyUtility.cs @@ -0,0 +1,47 @@ +using rjw; +using RJW_ToysAndMasturbation; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace Patch_SexToysMasturbation +{ + public class AnimSexToyUtility + { + + public static SexToyAnimationDef tryFindAnimation(CompSexToy sexToy, Pawn pawn) + { + + IEnumerable options = DefDatabase.AllDefs.Where((SexToyAnimationDef x) => + { + + if(!sexToy.Props.requiredBodyParts.Contains(x.requiredBodyPart)) + { + return false; + } + + if(x.requiredBodyPart == "vagina" && !Genital_Helper.has_vagina(pawn)) + { + return false; + } + + return true; + + }); + + if(options != null && options.Any()) + { + return options.RandomElement(); + } + else + { + return null; + } + + } + + } +} diff --git a/Patches/CompatibilityPatch_FacialAnimation.xml b/Patches/CompatibilityPatch_FacialAnimation.xml deleted file mode 100644 index edc59b2..0000000 --- a/Patches/CompatibilityPatch_FacialAnimation.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - -
  • [NL] Facial Animation - WIP
  • -
    - - Always - -
  • - /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/animationFrames/li[1]/headOffset - Always -
  • -
  • - /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/animationFrames/li[2]/headOffset - Always -
  • -
  • - /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/animationFrames/li[3]/headOffset - Always -
  • -
  • - /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/animationFrames/li[4]/headOffset - Always -
  • -
  • - /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/animationFrames/li[5]/headOffset - Always -
  • -
  • - /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/animationFrames/li[6]/headOffset - Always -
  • -
  • - /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/animationFrames/li[7]/headOffset - Always -
  • -
  • - /Defs/FacialAnimation.FaceAnimationDef[defName="Lovin" or defName="Lovin2"]/animationFrames/li[8]/headOffset - Always -
  • -
    -
    -
    -
    \ No newline at end of file diff --git a/Rimworld-Animations.csproj b/Rimworld-Animations.csproj index c9053f8..dc4896e 100644 --- a/Rimworld-Animations.csproj +++ b/Rimworld-Animations.csproj @@ -9,15 +9,16 @@ Properties Rimworld_Animations Rimworld-Animations - v4.7.2 + v4.8 512 true + false none false - 1.1\Assemblies\ + 1.4\Assemblies\ DEBUG;TRACE prompt 4 @@ -32,19 +33,19 @@ - ..\..\..\..\workshop\content\294100\2009463077\Current\Assemblies\0Harmony.dll - - - ..\..\..\..\workshop\content\294100\839005762\1.1\Assemblies\AlienRace.dll + ..\..\..\..\workshop\content\294100\839005762\1.4\Assemblies\0Harmony.dll False - - False + ..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll False - ..\RJW\1.1\Assemblies\RJW.dll + ..\rjw\1.4\Assemblies\RJW.dll + False + + + ..\rjw-toys-and-masturbation\Assemblies\RJW-ToysAndMasturbation.dll False @@ -55,68 +56,125 @@ - - False + ..\..\RimWorldWin64_Data\Managed\UnityEngine.dll False - - False + ..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Rimworld-Animations.sln b/Rimworld-Animations.sln index f552a93..ca55d6f 100644 --- a/Rimworld-Animations.sln +++ b/Rimworld-Animations.sln @@ -5,6 +5,10 @@ VisualStudioVersion = 16.0.29905.134 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rimworld-Animations", "Rimworld-Animations.csproj", "{71B05D71-67B2-4014-82CD-18C20AC0882F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Patch_HatsDisplaySelection", "Patch_HatsDisplaySelection\Patch_HatsDisplaySelection.csproj", "{BA766964-1716-422D-A09E-29426F8EB9D5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Patch_SexToysMasturbation", "Patch_SexToysMasturbation\Patch_SexToysMasturbation.csproj", "{87763712-0536-4D5F-9EAA-520F15D4F84E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +19,13 @@ Global {71B05D71-67B2-4014-82CD-18C20AC0882F}.Debug|Any CPU.Build.0 = Debug|Any CPU {71B05D71-67B2-4014-82CD-18C20AC0882F}.Release|Any CPU.ActiveCfg = Release|Any CPU {71B05D71-67B2-4014-82CD-18C20AC0882F}.Release|Any CPU.Build.0 = Release|Any CPU + {BA766964-1716-422D-A09E-29426F8EB9D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA766964-1716-422D-A09E-29426F8EB9D5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA766964-1716-422D-A09E-29426F8EB9D5}.Release|Any CPU.Build.0 = Release|Any CPU + {87763712-0536-4D5F-9EAA-520F15D4F84E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {87763712-0536-4D5F-9EAA-520F15D4F84E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {87763712-0536-4D5F-9EAA-520F15D4F84E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {87763712-0536-4D5F-9EAA-520F15D4F84E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Sounds/Sex/Slime/Slimy1.mp3 b/Sounds/Sex/Slime/Slimy1.mp3 deleted file mode 100644 index 7277d15..0000000 Binary files a/Sounds/Sex/Slime/Slimy1.mp3 and /dev/null differ diff --git a/Sounds/Sex/Slime/Slimy2.mp3 b/Sounds/Sex/Slime/Slimy2.mp3 deleted file mode 100644 index 8311746..0000000 Binary files a/Sounds/Sex/Slime/Slimy2.mp3 and /dev/null differ diff --git a/Sounds/Sex/Slime/Slimy3.mp3 b/Sounds/Sex/Slime/Slimy3.mp3 deleted file mode 100644 index 797adc0..0000000 Binary files a/Sounds/Sex/Slime/Slimy3.mp3 and /dev/null differ diff --git a/Sounds/Sex/Slime/Slimy4.mp3 b/Sounds/Sex/Slime/Slimy4.mp3 deleted file mode 100644 index 8e568f7..0000000 Binary files a/Sounds/Sex/Slime/Slimy4.mp3 and /dev/null differ diff --git a/Sounds/Sex/Slime/Slimy5.mp3 b/Sounds/Sex/Slime/Slimy5.mp3 deleted file mode 100644 index ba1d554..0000000 Binary files a/Sounds/Sex/Slime/Slimy5.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/Suck_1.mp3 b/Sounds/Sex/Suck/Suck_1.mp3 deleted file mode 100644 index fc82452..0000000 Binary files a/Sounds/Sex/Suck/Suck_1.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/Suck_10.mp3 b/Sounds/Sex/Suck/Suck_10.mp3 deleted file mode 100644 index 70ac207..0000000 Binary files a/Sounds/Sex/Suck/Suck_10.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/Suck_3.mp3 b/Sounds/Sex/Suck/Suck_3.mp3 deleted file mode 100644 index 838322f..0000000 Binary files a/Sounds/Sex/Suck/Suck_3.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/Suck_4.mp3 b/Sounds/Sex/Suck/Suck_4.mp3 deleted file mode 100644 index 54f701d..0000000 Binary files a/Sounds/Sex/Suck/Suck_4.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/Suck_5.mp3 b/Sounds/Sex/Suck/Suck_5.mp3 deleted file mode 100644 index f3f399e..0000000 Binary files a/Sounds/Sex/Suck/Suck_5.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/Suck_6.mp3 b/Sounds/Sex/Suck/Suck_6.mp3 deleted file mode 100644 index 94c8de1..0000000 Binary files a/Sounds/Sex/Suck/Suck_6.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/Suck_7.mp3 b/Sounds/Sex/Suck/Suck_7.mp3 deleted file mode 100644 index f429c8e..0000000 Binary files a/Sounds/Sex/Suck/Suck_7.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/Suck_8.mp3 b/Sounds/Sex/Suck/Suck_8.mp3 deleted file mode 100644 index 2a29cd8..0000000 Binary files a/Sounds/Sex/Suck/Suck_8.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/Suck_9.mp3 b/Sounds/Sex/Suck/Suck_9.mp3 deleted file mode 100644 index 2655ec9..0000000 Binary files a/Sounds/Sex/Suck/Suck_9.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/Swallow_1.mp3 b/Sounds/Sex/Suck/Swallow_1.mp3 deleted file mode 100644 index c4a489b..0000000 Binary files a/Sounds/Sex/Suck/Swallow_1.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/Swallow_2.mp3 b/Sounds/Sex/Suck/Swallow_2.mp3 deleted file mode 100644 index d0c8adf..0000000 Binary files a/Sounds/Sex/Suck/Swallow_2.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/Swallow_3.mp3 b/Sounds/Sex/Suck/Swallow_3.mp3 deleted file mode 100644 index 1d9b59b..0000000 Binary files a/Sounds/Sex/Suck/Swallow_3.mp3 and /dev/null differ diff --git a/Sounds/Sex/Suck/suck_2.mp3 b/Sounds/Sex/Suck/suck_2.mp3 deleted file mode 100644 index a44f0e5..0000000 Binary files a/Sounds/Sex/Suck/suck_2.mp3 and /dev/null differ diff --git a/Source/AnimationUtility.cs b/Source/AnimationUtility.cs deleted file mode 100644 index 52a86d6..0000000 --- a/Source/AnimationUtility.cs +++ /dev/null @@ -1,292 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using RimWorld; -using UnityEngine; -using Verse; -using Verse.AI; - -namespace Rimworld_Animations { - public static class AnimationUtility { - /* - Note: always make the list in this order: - Female pawns, animal female pawns, male pawns, animal male pawns - */ - public static AnimationDef tryFindAnimation(ref List participants, rjw.xxx.rjwSextype sexType = 0, rjw.SexProps sexProps = null) { - - //aggressors last - participants = participants.OrderBy(p => p.jobs.curDriver is rjw.JobDriver_SexBaseInitiator).ToList(); - - participants = participants.OrderBy(p => p == sexProps.Giver).ToList(); - - participants = participants.OrderByDescending(p => rjw.GenderHelper.GetSex(p) == rjw.GenderHelper.Sex.futa).ToList(); - - //pawns that can fuck last - participants = participants.OrderBy(p => rjw.xxx.can_fuck(p)).ToList(); - - - List localParticipants = new List(participants); - - IEnumerable options = DefDatabase.AllDefs.Where((AnimationDef x) => { - - - if (x.actors.Count != localParticipants.Count) { - return false; - } - for (int i = 0; i < x.actors.Count; i++) { - - if (rjw.RJWPreferenceSettings.Malesex == rjw.RJWPreferenceSettings.AllowedSex.Nohomo) { - if (rjw.xxx.is_male(localParticipants[i]) && x.actors[i].isFucked) { - return false; - } - } - - if ((x.actors[i].blacklistedRaces != null) && x.actors[i].blacklistedRaces.Contains(localParticipants[i].def.defName)) { - if (rjw.RJWSettings.DevMode) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " is blacklisted"); - } - return false; - } - - if(x.actors[i].defNames.Contains("Human")) { - if (!rjw.xxx.is_human(localParticipants[i])) { - if(rjw.RJWSettings.DevMode) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " is not human"); - } - - return false; - } - - } - else if (!x.actors[i].bodyDefTypes.Contains(localParticipants[i].RaceProps.body)) { - - if (!x.actors[i].defNames.Contains(localParticipants[i].def.defName)) { - - if (rjw.RJWSettings.DevMode) { - string animInfo = x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " is not "; - foreach(String defname in x.actors[i].defNames) { - animInfo += defname + ", "; - } - Log.Message(animInfo); - } - - return false; - } - } - //genitals checking - if(x.actors[i].requiredGenitals != null) { - if (x.actors[i].requiredGenitals.Contains("Vagina")) { - - if (!rjw.Genital_Helper.has_vagina(localParticipants[i])) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " doesn't have vagina"); - return false; - } - - } - - if (x.actors[i].requiredGenitals.Contains("Penis")) { - - if (!(rjw.Genital_Helper.has_multipenis(localParticipants[i]) || rjw.Genital_Helper.has_penis_infertile(localParticipants[i]) || rjw.Genital_Helper.has_penis_fertile(localParticipants[i]))) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " doesn't have penis"); - return false; - } - - } - - if (x.actors[i].requiredGenitals.Contains("Mouth")) { - - if (!rjw.Genital_Helper.has_mouth(localParticipants[i])) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " doesn't have mouth"); - return false; - } - - } - - if (x.actors[i].requiredGenitals.Contains("Anus")) { - - if (!rjw.Genital_Helper.has_anus(localParticipants[i])) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " doesn't have anus"); - return false; - } - - } - - if(x.actors[i].requiredGenitals.Contains("Breasts")) { - if (!rjw.Genital_Helper.can_do_breastjob(localParticipants[i])) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " doesn't have breasts"); - return false; - } - } - - if (x.actors[i].requiredGenitals.Contains("NoVagina")) { - - if (rjw.Genital_Helper.has_vagina(localParticipants[i])) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " has vagina"); - return false; - } - - } - - if (x.actors[i].requiredGenitals.Contains("NoPenis")) { - - if ((rjw.Genital_Helper.has_multipenis(localParticipants[i]) || rjw.Genital_Helper.has_penis_infertile(localParticipants[i]) || rjw.Genital_Helper.has_penis_fertile(localParticipants[i]))) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " has penis"); - return false; - } - - } - - if (x.actors[i].requiredGenitals.Contains("NoMouth")) { - - if (rjw.Genital_Helper.has_mouth(localParticipants[i])) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " has mouth"); - return false; - } - - } - - if (x.actors[i].requiredGenitals.Contains("NoAnus")) { - - if (rjw.Genital_Helper.has_anus(localParticipants[i])) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " has anus"); - return false; - } - - } - - if (x.actors[i].requiredGenitals.Contains("NoBreasts")) { - if (rjw.Genital_Helper.can_do_breastjob(localParticipants[i])) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " has breasts"); - return false; - } - } - } - - - - //TESTING ANIMATIONS ONLY REMEMBER TO COMMENT OUT BEFORE PUSH - /* - if (x.defName != "Cunnilingus") - return false; - */ - - - if (x.actors[i].isFucking && !rjw.xxx.can_fuck(localParticipants[i])) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " can't fuck"); - return false; - } - - if (x.actors[i].isFucked && !rjw.xxx.can_be_fucked(localParticipants[i])) { - Log.Message(x.defName.ToStringSafe() + " not selected -- " + localParticipants[i].def.defName.ToStringSafe() + " " + localParticipants[i].Name.ToStringSafe() + " can't be fucked"); - return false; - } - } - return true; - }); - List optionsWithSexType = options.ToList().FindAll(x => x.sexTypes.Contains(sexType)); - List optionsWithSexTypeAndInitiator = optionsWithSexType.FindAll(x => { - bool initiatorsAlignWithSexType = true; - for (int i = 0; i < x.actors.Count; i++) { - - //if the animation not for initiators, but an initiator is playing it - - if(sexProps != null) { - - if(x.actors[i].initiator && localParticipants[i] == sexProps.Reciever) { - initiatorsAlignWithSexType = false; - } - - } - - else if (x.actors[i].initiator && !(localParticipants[i].jobs.curDriver is rjw.JobDriver_SexBaseInitiator)) { - initiatorsAlignWithSexType = false; - } - } - return initiatorsAlignWithSexType; - }); - List optionsWithInitiator = options.ToList().FindAll(x => { - bool initiatorsAlignWithSexType = true; - for (int i = 0; i < x.actors.Count; i++) { - - //if the animation not for initiators, but an initiator is playing it - - if (sexProps != null) { - - if (x.actors[i].initiator && localParticipants[i] == sexProps.Giver) { - initiatorsAlignWithSexType = false; - } - - } - - else if (x.actors[i].initiator && !(localParticipants[i].jobs.curDriver is rjw.JobDriver_SexBaseInitiator)) { - initiatorsAlignWithSexType = false; - } - } - return initiatorsAlignWithSexType; - }); - - - if (optionsWithSexTypeAndInitiator.Any()) { - Log.Message("Selecting animation for rjwSexType " + sexType.ToStringSafe() + " and initiators..."); - return optionsWithSexType.RandomElement(); - } - - if (optionsWithSexType.Any()) { - Log.Message("Selecting animation for rjwSexType " + sexType.ToStringSafe() + "..."); - return optionsWithSexType.RandomElement(); - } - - if(optionsWithInitiator.Any()) { - Log.Message("Selecting animation for initiators..."); - } - - if (options != null && options.Any()) { - Log.Message("Randomly selecting animation..."); - return options.RandomElement(); - } - else - return null; - } - - public static void RenderPawnHeadMeshInAnimation(Mesh mesh, Vector3 loc, Quaternion quaternion, Material material, bool portrait, Pawn pawn) { - - if(pawn == null || pawn.Map != Find.CurrentMap) { - GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, portrait); - return; - } - - CompBodyAnimator pawnAnimator = pawn.TryGetComp(); - - if (pawnAnimator == null || !pawnAnimator.isAnimating || portrait) { - GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, portrait); - } else { - Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition(); - pawnHeadPosition.y = loc.y; - GenDraw.DrawMeshNowOrLater(mesh, pawnHeadPosition, Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up), material, portrait); - } - } - - public static void RenderPawnHeadMeshInAnimation(Mesh mesh, Vector3 loc, Quaternion quaternion, Material material, bool portrait, Pawn pawn, float bodySizeFactor = 1) { - - if (pawn == null) { - GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, portrait); - return; - } - - CompBodyAnimator pawnAnimator = pawn.TryGetComp(); - - if (pawnAnimator == null || !pawnAnimator.isAnimating || portrait) { - GenDraw.DrawMeshNowOrLater(mesh, loc, quaternion, material, portrait); - } - else { - Vector3 pawnHeadPosition = pawnAnimator.getPawnHeadPosition(); - pawnHeadPosition.x *= bodySizeFactor; - pawnHeadPosition.x *= bodySizeFactor; - pawnHeadPosition.y = loc.y; - GenDraw.DrawMeshNowOrLater(mesh, pawnHeadPosition, Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up), material, portrait); - } - } - } -} diff --git a/Source/Animations/Clips/ThingAnimationClip.cs b/Source/Animations/Clips/ThingAnimationClip.cs deleted file mode 100644 index 80ff19e..0000000 --- a/Source/Animations/Clips/ThingAnimationClip.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Rimworld_Animations { - public class ThingAnimationClip : BaseAnimationClip - { - public List keyframes; - - public override void buildSimpleCurves() { - - } - } -} diff --git a/Source/JobDrivers/JobDriver_SexBaseRecieverLovedForAnimation.cs b/Source/JobDrivers/JobDriver_SexBaseRecieverLovedForAnimation.cs deleted file mode 100644 index 4b5d844..0000000 --- a/Source/JobDrivers/JobDriver_SexBaseRecieverLovedForAnimation.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.Collections.Generic; -using RimWorld; -using Verse; -using Verse.AI; -using System; -using rjw; - -namespace Rimworld_Animations { - public class JobDriver_SexBaseRecieverLovedForAnimation : JobDriver_SexBaseReciever { - - public readonly TargetIndex ipartner = TargetIndex.A; - public readonly TargetIndex ibed = TargetIndex.B; - - public override bool TryMakePreToilReservations(bool errorOnFailed) { - - return base.TryMakePreToilReservations(errorOnFailed); - } - - protected override IEnumerable MakeNewToils() { - - - setup_ticks(); - - float partner_ability = xxx.get_sex_ability(Partner); - - // More/less hearts based on partner ability. - if (partner_ability < 0.8f) - ticks_between_thrusts += 100; - else if (partner_ability > 2.0f) - ticks_between_thrusts -= 25; - - // More/less hearts based on opinion. - if (pawn.relations.OpinionOf(Partner) < 0) - ticks_between_hearts += 50; - else if (pawn.relations.OpinionOf(Partner) > 60) - ticks_between_hearts -= 25; - - - parteners.Add(Partner);// add job starter, so this wont fail, before Initiator starts his job - //--Log.Message("[RJW]JobDriver_GettinLoved::MakeNewToils is called"); - - this.FailOnDespawnedOrNull(ipartner); - this.FailOn(() => !Partner.health.capacities.CanBeAwake); - this.FailOn(() => pawn.Drafted); - this.KeepLyingDown(ibed); - yield return Toils_Reserve.Reserve(ipartner, 1, 0); - yield return Toils_Reserve.Reserve(ibed, Bed.SleepingSlotsCount, 0); - - Toil get_loved = new Toil(); - get_loved.FailOn(() => Partner.CurJobDef != DefDatabase.GetNamed("JoinInBedAnimation", true)); - get_loved.defaultCompleteMode = ToilCompleteMode.Never; - get_loved.socialMode = RandomSocialMode.Off; - get_loved.handlingFacing = true; - get_loved.AddPreTickAction(delegate { - if (pawn.IsHashIntervalTick(ticks_between_hearts)) - MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart); - }); - get_loved.AddFinishAction(delegate { - if (xxx.is_human(pawn)) - pawn.Drawer.renderer.graphics.ResolveApparelGraphics(); - }); - yield return get_loved; - - - } - } -} \ No newline at end of file diff --git a/Source/JobDrivers/JobDriver_SexCasualForAnimation.cs b/Source/JobDrivers/JobDriver_SexCasualForAnimation.cs deleted file mode 100644 index 25e46f3..0000000 --- a/Source/JobDrivers/JobDriver_SexCasualForAnimation.cs +++ /dev/null @@ -1,85 +0,0 @@ -using RimWorld; -using rjw; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Verse; -using Verse.AI; - -namespace Rimworld_Animations { - class JobDriver_SexCasualForAnimation : JobDriver_SexBaseInitiator { - - public readonly TargetIndex ipartner = TargetIndex.A; - public readonly TargetIndex ibed = TargetIndex.B; - - public override bool TryMakePreToilReservations(bool errorOnFailed) { - return pawn.Reserve(Target, job, xxx.max_rapists_per_prisoner, 0, null, errorOnFailed); - } - - protected override IEnumerable MakeNewToils() { - setup_ticks(); - this.FailOnDespawnedOrNull(ipartner); - this.FailOnDespawnedOrNull(ibed); - this.FailOn(() => !Partner.health.capacities.CanBeAwake); - - yield return Toils_Reserve.Reserve(ipartner, xxx.max_rapists_per_prisoner, 0, null); - - Toil goToPawnInBed = Toils_Goto.GotoThing(ipartner, PathEndMode.OnCell); - goToPawnInBed.FailOn(() => !RestUtility.InBed(Partner) && !xxx.in_same_bed(Partner, pawn)); - - yield return goToPawnInBed; - - - Toil startPartnerSex = new Toil(); - startPartnerSex.initAction = delegate { - - Job gettinLovedJob = JobMaker.MakeJob(DefDatabase.GetNamed("GettinLovedAnimation"), pawn, Bed); // new gettin loved toil that wakes up the pawn goes here - - Partner.jobs.jobQueue.EnqueueFirst(gettinLovedJob); - Partner.jobs.EndCurrentJob(JobCondition.InterruptForced); - }; - yield return startPartnerSex; - - Toil sexToil = new Toil(); - sexToil.FailOn(() => (Partner.CurJobDef == null) || Partner.CurJobDef != DefDatabase.GetNamed("GettinLovedAnimation", true)); //partner jobdriver is not sexbaserecieverlovedforanim - sexToil.socialMode = RandomSocialMode.Off; - sexToil.defaultCompleteMode = ToilCompleteMode.Never; - sexToil.handlingFacing = true; - sexToil.initAction = delegate { - - usedCondom = (CondomUtility.TryUseCondom(base.pawn) || CondomUtility.TryUseCondom(Partner)); - Start(); - }; - - sexToil.AddPreTickAction(delegate { - - ticks_left--; - if(Gen.IsHashIntervalTick(pawn, ticks_between_hearts)) { - MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart); - } - SexTick(pawn, Partner); - SexUtility.reduce_rest(Partner); - SexUtility.reduce_rest(pawn, 2); - if (ticks_left <= 0) - ReadyForNextToil(); - - }); - sexToil.AddFinishAction(delegate { - - End(); - - }); - yield return sexToil; - - Toil finish = new Toil(); - finish.initAction = delegate { - SexUtility.ProcessSex(pawn, Partner, usedCondom, isRape, isCoreLovin: false, isWhoring, sexType); - }; - finish.defaultCompleteMode = ToilCompleteMode.Instant; - yield return finish; - - } - } -} diff --git a/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs b/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs deleted file mode 100644 index ab2a354..0000000 --- a/Source/MainTabWindows/MainTabWindow_OffsetConfigure.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Verse; -using RimWorld; -using UnityEngine; - -namespace Rimworld_Animations { - class MainTabWindow_OffsetConfigure : MainTabWindow - { - - public override Vector2 RequestedTabSize => new Vector2(505, 340); - public override void DoWindowContents(Rect inRect) { - - Rect position = new Rect(inRect.x, inRect.y, inRect.width, inRect.height); - - - Listing_Standard listingStandard = new Listing_Standard(); - listingStandard.Begin(position); - - listingStandard.Label("Offset Manager"); - - listingStandard.GapLine(); - - - if (Find.Selector.SingleSelectedThing is Pawn) { - - Pawn curPawn = Find.Selector.SingleSelectedThing as Pawn; - - if (curPawn.TryGetComp().isAnimating) { - - AnimationDef def = curPawn.TryGetComp().CurrentAnimation; - int ActorIndex = curPawn.TryGetComp().ActorIndex; - float offsetX = 0, offsetZ = 0, rotation = 0; - - if (AnimationSettings.offsets.ContainsKey(def.defName + curPawn.def.defName + ActorIndex)) { - offsetX = AnimationSettings.offsets[def.defName + curPawn.def.defName + ActorIndex].x; - offsetZ = AnimationSettings.offsets[def.defName + curPawn.def.defName + ActorIndex].y; - } else { - AnimationSettings.offsets.Add(def.defName + curPawn.def.defName + ActorIndex, new Vector2(0, 0)); - } - - if (AnimationSettings.rotation.ContainsKey(def.defName + curPawn.def.defName + ActorIndex)) { - rotation = AnimationSettings.rotation[def.defName + curPawn.def.defName + ActorIndex]; - } - else { - AnimationSettings.rotation.Add(def.defName + curPawn.def.defName + ActorIndex, 0); - } - - - listingStandard.Label("Offset for race " + curPawn.def.defName + " in actor position " + curPawn.TryGetComp().ActorIndex + (curPawn.TryGetComp().Mirror ? " mirrored" : "")); - - if(curPawn.def.defName == "Human") { - listingStandard.Label("Warning--You generally don't want to change human offsets, only alien offsets"); - } - - - listingStandard.Label("X Offset: " + offsetX); - offsetX = listingStandard.Slider(offsetX, -10, 10); - - listingStandard.Label("Z Offset: " + offsetZ); - offsetZ = listingStandard.Slider(offsetZ, -10, 10); - - listingStandard.Label("Rotation: " + rotation); - rotation = listingStandard.Slider(rotation, -180, 180); - - if(listingStandard.ButtonText("Reset All")) { - offsetX = 0; - offsetZ = 0; - rotation = 0; - } - - if (offsetX != AnimationSettings.offsets[def.defName + curPawn.def.defName + ActorIndex].x || offsetZ != AnimationSettings.offsets[def.defName + curPawn.def.defName + ActorIndex].y) { - AnimationSettings.offsets[def.defName + curPawn.def.defName + ActorIndex] = new Vector2(offsetX, offsetZ); - - } - - if(rotation != AnimationSettings.rotation[def.defName + curPawn.def.defName + ActorIndex]) { - AnimationSettings.rotation[def.defName + curPawn.def.defName + ActorIndex] = rotation; - } - - } - - - } - else { - listingStandard.Label("Select a pawn currently in an animation to change their offsets"); - } - - listingStandard.End(); - - base.DoWindowContents(inRect); - - } - - public override void PreOpen() { - base.PreOpen(); - if(AnimationSettings.offsets == null) { - Log.Message("New offsets"); - AnimationSettings.offsets = new Dictionary(); - } - - if(AnimationSettings.rotation == null) { - Log.Message("New rotation"); - AnimationSettings.rotation = new Dictionary(); - } - } - - public override void PostClose() { - base.PostClose(); - - LoadedModManager.GetMod().WriteSettings(); - } - } -} diff --git a/Source/Patches/HarmonyPatch_AlienRace.cs b/Source/Patches/HarmonyPatch_AlienRace.cs deleted file mode 100644 index 9ebfed0..0000000 --- a/Source/Patches/HarmonyPatch_AlienRace.cs +++ /dev/null @@ -1,147 +0,0 @@ -using HarmonyLib; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using Verse; -using AlienRace; - -namespace Rimworld_Animations { - [StaticConstructorOnStartup] - public static class HarmonyPatch_AlienRace { - static HarmonyPatch_AlienRace () { - try { - ((Action)(() => { - if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "Humanoid Alien Races 2.0")) { - - (new Harmony("rjw")).Patch(AccessTools.Method(typeof(PawnGraphicSet), "ResolveApparelGraphics"), - prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_AlienRace), "Prefix_StopResolveAllGraphicsWhileSex"))); - - (new Harmony("rjw")).Patch(AccessTools.Method(AccessTools.TypeByName("AlienRace.HarmonyPatches"), "DrawAddons"), - prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_AlienRace), "Prefix_AnimateHeadAddons"))); - } - }))(); - } - catch (TypeLoadException ex) { - - } - } - - public static bool Prefix_StopResolveAllGraphicsWhileSex(ref Pawn ___pawn) { - - if(___pawn.TryGetComp() != null && ___pawn.TryGetComp().isAnimating) { - return false; - } - return true; - } - - public static bool Prefix_AnimateHeadAddons(bool portrait, Vector3 vector, Pawn pawn, Quaternion quat, Rot4 rotation, bool invisible) { - - if (portrait || pawn.TryGetComp() == null || !pawn.TryGetComp().isAnimating) return true; - if (!(pawn.def is ThingDef_AlienRace alienProps) || invisible) return false; - - List addons = alienProps.alienRace.generalSettings.alienPartGenerator.bodyAddons; - AlienPartGenerator.AlienComp alienComp = pawn.GetComp(); - CompBodyAnimator pawnAnimator = pawn.TryGetComp(); - - for (int i = 0; i < addons.Count; i++) { - AlienPartGenerator.BodyAddon ba = addons[index: i]; - if (!ba.CanDrawAddon(pawn: pawn)) continue; - - AlienPartGenerator.RotationOffset offset; - if (ba.drawnInBed) { - - offset = pawnAnimator.headFacing == Rot4.South ? - ba.offsets.south : - pawnAnimator.headFacing == Rot4.North ? - ba.offsets.north : - pawnAnimator.headFacing == Rot4.East ? - ba.offsets.east : - ba.offsets.west; - - } else { - - offset = rotation == Rot4.South ? - ba.offsets.south : - rotation == Rot4.North ? - ba.offsets.north : - rotation == Rot4.East ? - ba.offsets.east : - ba.offsets.west; - - } - - - - Vector2 bodyOffset = (portrait ? offset?.portraitBodyTypes ?? offset?.bodyTypes : offset?.bodyTypes)?.FirstOrDefault(predicate: to => to.bodyType == pawn.story.bodyType) - ?.offset ?? Vector2.zero; - Vector2 crownOffset = (portrait ? offset?.portraitCrownTypes ?? offset?.crownTypes : offset?.crownTypes)?.FirstOrDefault(predicate: to => to.crownType == alienComp.crownType) - ?.offset ?? Vector2.zero; - - //Defaults for tails - //south 0.42f, -0.3f, -0.22f - //north 0f, 0.3f, -0.55f - //east -0.42f, -0.3f, -0.22f - - float moffsetX = 0.42f; - float moffsetZ = -0.22f; - float moffsetY = ba.inFrontOfBody ? 0.3f + ba.layerOffset : -0.3f - ba.layerOffset; - float num = ba.angle; - - if ((ba.drawnInBed ? pawnAnimator.headFacing : rotation) == Rot4.North) { - moffsetX = 0f; - if (ba.layerInvert) - moffsetY = -moffsetY; - - moffsetZ = -0.55f; - num = 0; - } - - moffsetX += bodyOffset.x + crownOffset.x; - moffsetZ += bodyOffset.y + crownOffset.y; - - if ((ba.drawnInBed ? pawnAnimator.headFacing : rotation) == Rot4.East) { - moffsetX = -moffsetX; - num = -num; //Angle - } - - Vector3 offsetVector = new Vector3(x: moffsetX, y: moffsetY, z: moffsetZ); - - //Angle calculation to not pick the shortest, taken from Quaternion.Angle and modified - - //assume drawnInBed means headAddon - if (ba.drawnInBed && pawn.TryGetComp() != null && pawn.TryGetComp().isAnimating) { - - Quaternion headQuatInAnimation = Quaternion.AngleAxis(pawnAnimator.headAngle, Vector3.up); - Rot4 headRotInAnimation = pawnAnimator.headFacing; - Vector3 headPositionInAnimation = pawnAnimator.getPawnHeadPosition() - pawn.Drawer.renderer.BaseHeadOffsetAt(pawnAnimator.headFacing).RotatedBy(angle: Mathf.Acos(f: Quaternion.Dot(a: Quaternion.identity, b: headQuatInAnimation)) * 2f * 57.29578f); - - - GenDraw.DrawMeshNowOrLater(mesh: alienComp.addonGraphics[index: i].MeshAt(rot: headRotInAnimation), loc: headPositionInAnimation + offsetVector.RotatedBy(angle: Mathf.Acos(f: Quaternion.Dot(a: Quaternion.identity, b: headQuatInAnimation)) * 2f * 57.29578f), - quat: Quaternion.AngleAxis(angle: num, axis: Vector3.up) * headQuatInAnimation, mat: alienComp.addonGraphics[index: i].MatAt(rot: pawnAnimator.headFacing), drawNow: portrait); - - } - - else { - - Quaternion addonRotation = quat; - 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"))) { - addonRotation = Quaternion.AngleAxis(angle: pawnAnimator.genitalAngle, axis: Vector3.up); - } - - GenDraw.DrawMeshNowOrLater(mesh: alienComp.addonGraphics[index: i].MeshAt(rot: rotation), loc: vector + offsetVector.RotatedBy(angle: Mathf.Acos(f: Quaternion.Dot(a: Quaternion.identity, b: quat)) * 2f * 57.29578f), - quat: Quaternion.AngleAxis(angle: num, axis: Vector3.up) * addonRotation, mat: alienComp.addonGraphics[index: i].MatAt(rot: rotation), drawNow: portrait); - - } - - - } - - return false; - } - } -} \ No newline at end of file diff --git a/Source/Patches/rjwPatches/HarmonyPatch_DoLovinAnimationPatch.cs b/Source/Patches/rjwPatches/HarmonyPatch_DoLovinAnimationPatch.cs deleted file mode 100644 index c508266..0000000 --- a/Source/Patches/rjwPatches/HarmonyPatch_DoLovinAnimationPatch.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; -using RimWorld; -using Verse; -using rjw; -using Verse.AI; - -namespace Rimworld_Animations { - - [HarmonyPatch(typeof(JobGiver_DoLovin), "TryGiveJob")] - public static class HarmonyPatch_DoLovinAnimationPatch { - - public static void Postfix(ref Pawn pawn, ref Job __result) { - - if(__result != null) { - Pawn partnerInMyBed = LovePartnerRelationUtility.GetPartnerInMyBed(pawn); - RestUtility.WakeUp(pawn); - __result = JobMaker.MakeJob(DefDatabase.GetNamed("JoinInBedAnimation", true), partnerInMyBed, partnerInMyBed.CurrentBed()); - } - } - } -} diff --git a/Source/Patches/rjwPatches/HarmonyPatch_DrawSemen.cs b/Source/Patches/rjwPatches/HarmonyPatch_DrawSemen.cs deleted file mode 100644 index 2d291d3..0000000 --- a/Source/Patches/rjwPatches/HarmonyPatch_DrawSemen.cs +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Todo: Ask to make SemenSplatch and DrawSemen public - * - * - * using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using rjw; -using HarmonyLib; - -namespace Rimworld_Animations { - [HarmonyPatch("DrawSemen")] - public static class HarmonyPatch_DrawSemen { - - public static void Prefix(ref Dictionary) { - - } - - } -}*/ diff --git a/Source/Patches/rjwPatches/HarmonyPatch_JoinInBedGiveJob.cs b/Source/Patches/rjwPatches/HarmonyPatch_JoinInBedGiveJob.cs deleted file mode 100644 index 7a8b573..0000000 --- a/Source/Patches/rjwPatches/HarmonyPatch_JoinInBedGiveJob.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using rjw; -using Verse; -using Verse.AI; -using RimWorld; -using HarmonyLib; - -namespace Rimworld_Animations { - [HarmonyPatch(typeof(JobGiver_JoinInBed), "TryGiveJob")] - public static class HarmonyPatch_JoinInBedGiveJob { - - public static bool Prefix(ref Job __result, ref Pawn pawn) { - - __result = null; - - if (!RJWHookupSettings.HookupsEnabled) - return false; - - if (pawn.Drafted) - return false; - - if (!SexUtility.ReadyForHookup(pawn)) - return false; - - // We increase the time right away to prevent the fairly expensive check from happening too frequently - SexUtility.IncreaseTicksToNextHookup(pawn); - - // If the pawn is a whore, or recently had sex, skip the job unless they're really horny - if (!xxx.is_frustrated(pawn) && (xxx.is_whore(pawn) || !SexUtility.ReadyForLovin(pawn))) - return false; - - // This check attempts to keep groups leaving the map, like guests or traders, from turning around to hook up - if (pawn.mindState?.duty?.def == DutyDefOf.TravelOrLeave) { - // TODO: Some guest pawns keep the TravelOrLeave duty the whole time, I think the ones assigned to guard the pack animals. - // That's probably ok, though it wasn't the intention. - if (RJWSettings.DebugLogJoinInBed) Log.Message($"[RJW] JoinInBed.TryGiveJob:({xxx.get_pawnname(pawn)}): has TravelOrLeave, no time for lovin!"); - return false; - } - - if (pawn.CurJob == null || pawn.CurJob.def == JobDefOf.LayDown) { - //--Log.Message(" checking pawn and abilities"); - if (xxx.can_fuck(pawn) || xxx.can_be_fucked(pawn)) { - //--Log.Message(" finding partner"); - Pawn partner = JobGiver_JoinInBed.find_pawn_to_fuck(pawn, pawn.Map); - - //--Log.Message(" checking partner"); - if (partner == null) - return false; - - // Can never be null, since find checks for bed. - Building_Bed bed = partner.CurrentBed(); - - // Interrupt current job. - if (pawn.CurJob != null && pawn.jobs.curDriver != null) - pawn.jobs.curDriver.EndJobWith(JobCondition.InterruptForced); - - __result = JobMaker.MakeJob(DefDatabase.GetNamed("JoinInBedAnimation", true), partner, bed); - return false; - } - } - - return false; - - } - - } -} diff --git a/Source/Patches/rjwPatches/HarmonyPatch_PlayAnimJoinInBedRMB.cs b/Source/Patches/rjwPatches/HarmonyPatch_PlayAnimJoinInBedRMB.cs deleted file mode 100644 index aab9e41..0000000 --- a/Source/Patches/rjwPatches/HarmonyPatch_PlayAnimJoinInBedRMB.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using RimWorld; -using Verse.AI; -using rjw; -using HarmonyLib; -using Verse; - -namespace Rimworld_Animations { - - [HarmonyPatch(typeof(Pawn_JobTracker), "TryTakeOrderedJob")] - class HarmonyPatch_PlayAnimJoinInBedRMB { - public static void Prefix(ref Job job) { - if(job.def == xxx.casual_sex) { - Log.Message("Replacing vanilla RJW JoinInBed JobDriver for animation JobDriver"); - job = new Job(DefDatabase.GetNamed("JoinInBedAnimation", true), job.targetA, job.targetB, job.targetC); - } - - } - - } -} diff --git a/Source/Patches/rjwPatches/HarmonyPatch_SexTick.cs b/Source/Patches/rjwPatches/HarmonyPatch_SexTick.cs deleted file mode 100644 index c645d18..0000000 --- a/Source/Patches/rjwPatches/HarmonyPatch_SexTick.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using HarmonyLib; -using RimWorld; -using Verse; -using rjw; -using Verse.Sound; - -namespace Rimworld_Animations { - - [HarmonyPatch(typeof(JobDriver_Sex), "SexTick")] - public static class HarmonyPatch_SexTick { - - public static bool Prefix(ref JobDriver_Sex __instance, ref Pawn pawn, ref Thing target, ref bool pawnnude, ref bool partnernude) { - - Pawn pawn2 = target as Pawn; - - if (pawn == null || pawn2 == null) { - return true; - } - - - if (pawn.IsHashIntervalTick(__instance.ticks_between_thrusts)) { - - __instance.ChangePsyfocus(pawn, pawn2); - - __instance.Animate(pawn, pawn2); - - if (!AnimationSettings.soundOverride || pawn.TryGetComp() == null || !pawn.TryGetComp().isAnimating) { - __instance.PlaySexSound(); - } - - if (!__instance.isRape) { - pawn.GainComfortFromCellIfPossible(); - pawn2?.GainComfortFromCellIfPossible(); - } - } - if (!xxx.has_quirk(pawn, "Endytophile")) { - if (pawnnude) { - SexUtility.DrawNude(pawn); - } - if (pawn2 != null && partnernude) { - SexUtility.DrawNude(pawn2); - } - } - - return false; - } - } -}