This commit is contained in:
AbstractConcept 2023-02-05 18:41:57 -06:00
parent 38ec4f86c1
commit ae95e34137
35 changed files with 242 additions and 612 deletions

View File

@ -56,13 +56,11 @@ Here's a brief overview of what's included in this mod
A full list of changes can be found in the main discussion thread on the forum
Known issues
- This mod requires that you run RimWorld Animations v 1.2.8 or later, otherwise animations will result in errors
- If you plan to use this mod's apparel cropping feature and the Sized Apparel mod, you must turn off texture caching or graphical glitches will occur (this can be done by adding Vanilla Expanded Framework to your mod list and enabling its 'Disable Texture Caching' setting)
- Using Dubs Apparel Tweaks or the Show Hair mod may result in hair rendering over hats during animations
- To avoid certain graphical issues, Dubs Apparel Tweaks should be loaded before this mod while Babies and Children should be loaded after (if you choose to use them). This will mean that you will not be able to run this mod with Dubs Apparel Tweaks and Babies and Children running at the same time
- Using Speak Up and Dirty Talk results in warning messages being posted in the log, however, this does not seem to be causing any problems. This issue will be monitored
- This mod isn't compatible with Tory's VoicePatch mod
- This mod will result in graphical errors when using Pawnmorpher's 'Pawn scaling' setting
- For best results, turn off texture caching (this can be done by adding the Vanilla Expanded Framework to your mod list and enabling its 'Disable Texture Caching' setting)
- The animations in this mod do not play any voices from Tory's VoicePatch mod
- Apparel masking cannot be used with the Sized Apparel mod
- This mod will result in floating body parts when using Pawnmorpher's 'Pawn scaling' setting
- If you're having some issues with frame rates on large colonies, try disabling hand rendering
</description>
</ModMetaData>

View File

@ -2,7 +2,10 @@
<Defs>
<Rimworld_Animations.AnimationDef>
<defName>threesome_sandwich</defName>
<label>participating in a threesome.</label>
<label>A threesome sandwich.</label>
<tags>
<li>participating in a threesome.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Vaginal</li>

View File

@ -4,7 +4,10 @@
<Rimworld_Animations.AnimationDef>
<defName>SixtyNine</defName>
<label>entangled in a sixty nine with TargetA.</label>
<label>Sixty-nine</label>
<tags>
<li>entangled in a sixty nine with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Sixtynine</li>
@ -408,7 +411,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>Butterfly</defName>
<label>having sex with TargetA.</label>
<label></label>
<tags>
<li>having sex with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Vaginal</li>
@ -901,7 +907,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>BreastJob</defName>
<label>engaged in breast play with TargetA.</label>
<label>Breast job</label>
<tags>
<li>engaged in breast play with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Boobjob</li>
@ -1315,7 +1324,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>Handjob</defName>
<label>engaged in a handjob with TargetA.</label>
<label>Hand job</label>
<tags>
<li>engaged in a handjob with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Handjob</li>
@ -1639,7 +1651,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>Fisting</defName>
<label>engaged in fisting with TargetA.</label>
<label>Fisting</label>
<tags>
<li>engaged in fisting with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Fisting</li>
@ -2171,7 +2186,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>Fingering</defName>
<label>fingering with TargetA.</label>
<label>Fingering</label>
<tags>
<li>engaged in fisting with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Fingering</li>
@ -2498,7 +2516,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>CunnilingusStanding</defName>
<label>engaged in cunnilingus with TargetA.</label>
<label>Cunnilingus</label>
<tags>
<li>engaged in cunnilingus with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Cunnilingus</li>
@ -2914,7 +2935,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>Rimming</defName>
<label>engaged in rimming with TargetA.</label>
<label>Rimming</label>
<tags>
<li>engaged in rimming with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Rimming</li>
@ -3502,8 +3526,11 @@
</animationStages>
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>ReverseCowgirl</defName>
<label>having sex with TargetA.</label>
<defName>ReverseCowgirl</defName>
<label>Reverse cowgirl</label>
<tags>
<li>having sex with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Vaginal</li>
@ -4087,7 +4114,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>FaceSitting</defName>
<label>engaged in cunnilingus with TargetA.</label>
<label>Face sitting</label>
<tags>
<li>engaged in cunnilingus with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Cunnilingus</li>
@ -4664,7 +4694,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>Footjob</defName>
<label>engaged in foot play with TargetA.</label>
<label>Foot job</label>
<tags>
<li>engaged in foot play with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Footjob</li>

View File

@ -3,7 +3,10 @@
<Rimworld_Animations.AnimationDef>
<defName>KissMakeout</defName>
<label>making out with TargetA.</label>
<label>Making out</label>
<tags>
<li>making out with TargetA.</li>
</tags>
<sexTypes>
<li>Oral</li>
</sexTypes>
@ -433,7 +436,10 @@
<Rimworld_Animations.AnimationDef>
<defName>MutualMasturbation</defName>
<label>masturbating with TargetA.</label>
<label>Mutual masturbation</label>
<tags>
<li>masturbating with TargetA.</li>
</tags>
<sexTypes>
<li>MutualMasturbation</li>
</sexTypes>

View File

@ -4,7 +4,10 @@
<Rimworld_Animations.AnimationDef>
<defName>Threesome1Male2Female</defName>
<label>taking part in a threesome.</label>
<label>Threesome</label>
<tags>
<li>taking part in a threesome.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Vaginal</li>

View File

@ -3,7 +3,10 @@
<Defs>
<Rimworld_Animations.AnimationDef>
<defName>Doggystyle</defName>
<label>having sex with TargetA.</label>
<label>Doggy style</label>
<tags>
<li>having sex with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Vaginal</li>
@ -468,7 +471,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>Blowjob</defName>
<label>engaged in a blowjob with TargetA</label>
<label>Blow job</label>
<tags>
<li>engaged in a blowjob with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Fellatio</li>
@ -883,7 +889,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>ReverseStandAndCarry</defName>
<label>having sex with TargetA.</label>
<label>Reverse stand-n-carry</label>
<tags>
<li>having sex with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Anal</li>
@ -2001,7 +2010,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>Cowgirl</defName>
<label>having sex with TargetA.</label>
<label>Cow girl</label>
<tags>
<li>having sex with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Anal</li>
@ -2587,7 +2599,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>Tribadism</defName>
<label>scissoring with TargetA.</label>
<label>Scissoring</label>
<tags>
<li>scissoring with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Scissoring</li>
@ -3520,7 +3535,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>Cunnilingus</defName>
<label>engaged in cunnilingus with TargetA</label>
<label>Cunnilingus</label>
<tags>
<li>engaged in cunnilingus with TargetA.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Oral</li>
@ -4461,7 +4479,10 @@
</Rimworld_Animations.AnimationDef>
<Rimworld_Animations.AnimationDef>
<defName>Double_Penetration</defName>
<label>taking part in a threesome.</label>
<label>Double penetration</label>
<tags>
<li>taking part in a threesome.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>DoublePenetration</li>

View File

@ -4,7 +4,10 @@
<Rimworld_Animations.AnimationDef>
<defName>MasturbationWithPenis_Standing</defName>
<label>masturbatin'.</label>
<label>Masturbating</label>
<tags>
<li>masturbatin'.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Masturbation</li>
@ -224,7 +227,10 @@
<Rimworld_Animations.AnimationDef>
<defName>MasturbationWithPenis_InBed</defName>
<label>masturbatin'.</label>
<label>Masturbating</label>
<tags>
<li>masturbatin'.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Masturbation</li>
@ -433,7 +439,10 @@
<Rimworld_Animations.AnimationDef>
<defName>MasturbationWithVagina_Standing</defName>
<label>masturbatin'.</label>
<label>Masturbating</label>
<tags>
<li>masturbatin'.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Masturbation</li>
@ -640,7 +649,10 @@
<Rimworld_Animations.AnimationDef>
<defName>MasturbationWithVagina_InBed</defName>
<label>masturbatin'.</label>
<label>Masturbating</label>
<tags>
<li>masturbatin'.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Masturbation</li>
@ -847,7 +859,10 @@
<Rimworld_Animations.AnimationDef>
<defName>MasturbationWithBreasts_Standing</defName>
<label>masturbatin'.</label>
<label>Masturbating</label>
<tags>
<li>masturbatin'.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Masturbation</li>
@ -1055,7 +1070,10 @@
<Rimworld_Animations.AnimationDef>
<defName>MasturbationWithBreasts_InBed</defName>
<label>masturbatin'.</label>
<label>Masturbating</label>
<tags>
<li>masturbatin'.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Masturbation</li>
@ -1263,7 +1281,10 @@
<Rimworld_Animations.AnimationDef>
<defName>MasturbationWithBreastsPlusPenis_Standing</defName>
<label>masturbatin'.</label>
<label>Masturbating</label>
<tags>
<li>masturbatin'.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Masturbation</li>
@ -1471,7 +1492,10 @@
<Rimworld_Animations.AnimationDef>
<defName>MasturbationWithBreastsPlusPenis_InBed</defName>
<label>masturbatin'.</label>
<label>Masturbating</label>
<tags>
<li>masturbatin'.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Masturbation</li>
@ -1679,7 +1703,10 @@
<Rimworld_Animations.AnimationDef>
<defName>MasturbationWithAnus_Standing</defName>
<label>masturbatin'.</label>
<label>Masturbating</label>
<tags>
<li>masturbatin'.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Masturbation</li>
@ -1886,7 +1913,10 @@
<Rimworld_Animations.AnimationDef>
<defName>MasturbationWithAnus_InBed</defName>
<label>masturbatin'.</label>
<label>Masturbating</label>
<tags>
<li>masturbatin'.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Masturbation</li>
@ -2093,7 +2123,10 @@
<Rimworld_Animations.AnimationDef>
<defName>MasturbationHumping_InBed</defName>
<label>masturbatin'.</label>
<label>Masturbating</label>
<tags>
<li>masturbatin'.</li>
</tags>
<sounds>true</sounds>
<sexTypes>
<li>Masturbation</li>

View File

@ -6,31 +6,7 @@
<rimworld_animation_patch_apparelsettings>Rimworld Animations Patch - Clothing settings</rimworld_animation_patch_apparelsettings>
<rimworld_animation_patch_general>General Options</rimworld_animation_patch_general>
<need_privacy> People have opinions about having sex in front of others</need_privacy>
<need_privacy_desc>Their reaction will depend on their Exhibitionist precept and whether the Exhibitionist or Voyeur quirk. Embarrassed colonist will stop any lovin' related activities they are doing.\n\nUnconventional sex acts and those that break taboo may provoke a stronger reaction. People will turn a blind eye to these transgressions, however, if they take place during a ritual or party.</need_privacy_desc>
<worry_about_infidelity> People will react if they encounter their partner cheating</worry_about_infidelity>
<worry_about_infidelity_desc>Their reaction will depend on their Lovin' precept, whether they have the Polygamous trait, and whether the copulating couple are married. Cheating is considered a major taboo by default.</worry_about_infidelity_desc>
<worry_about_beastiality> People will react to beastiality</worry_about_beastiality>
<worry_about_beastiality_desc>Their reaction will depend on their Bestiality precept (Sexperience - Ideology) and whether they are a Zoophile. Beastiality is considered a major taboo by default.</worry_about_beastiality_desc>
<worry_about_rape> People will react to rape</worry_about_rape>
<worry_about_rape_desc>Their reaction will depend on their Rape precept (Sexperience - Ideology) and whether they have the Rapist trait. Rape is considered a major taboo by default.</worry_about_rape_desc>
<ignore_slave_rape> People will ignore a rape if the victim is a prisoner or slave</ignore_slave_rape>
<worry_about_necro> People will react to necrophilia</worry_about_necro>
<worry_about_necro_desc>Their reaction will depend on their Necrophilia precept (Sexperience - Ideology) and whether they have the Necrophile trait. Necrophilia is considered a major taboo by default.</worry_about_necro_desc>
<worry_about_xeno> People will react to couplings between humanoids of different species</worry_about_xeno>
<worry_about_xeno_desc>Their reaction will depend on their Alien Dating precept (Humanoid Alien Races) and whether they are Xenophile or Xenophobe traits. Xenophilia is acceptable by default.</worry_about_xeno_desc>
<worry_about_masturbation> People will react to necrophilia</worry_about_masturbation>
<worry_about_masturbation_desc>Their reaction will depend on their Necrophilia precept (Sexperience - Ideology) and whether they have the Necrophile trait. Necrophilia is considered a major taboo by default.</worry_about_masturbation_desc>
<worry_about_incest> People will react to incest</worry_about_incest>
<worry_about_incest_desc>Their reaction will depend on their Incest precept (Sexperience - Ideology). Incest is disapproved of by default.</worry_about_incest_desc>
<major_taboo_can_start_fights> Witnessing a major taboo will result in an extreme reaction</major_taboo_can_start_fights>
<major_taboo_can_start_fights_desc>Individuals who witness something that seriously upsets them will cause them to flee, or even possibly attack the offender.</major_taboo_can_start_fights_desc>
<slaves_ignore_sex> Prisoners and slaves ignore sex</slaves_ignore_sex>
<slaves_ignore_sex_desc>Prisoners and slaves have learnt it is better to simply ignore any sexual acts occurring around them.</slaves_ignore_sex_desc>
<other_factions_ignore_sex> People belong to other factions will ignore sex</other_factions_ignore_sex>
<other_factions_ignore_sex_desc>The other factions will turn a blind eye to any sexual acts occurring around them.</other_factions_ignore_sex_desc>
<chance_for_other_to_join_in_sex> People who are lovin' have a chance to invite passersby to join them for some fun (default is 0.25)</chance_for_other_to_join_in_sex>
<chance_for_other_to_join_in_sex_desc>Note that setting this value to its maximum will not guarantee that this event will occur! It just maximises the chance of an invitation being made. All individuals involved must be attracted to / have a good opinion of each other, and the activity must not violate their traits or ideology. Set this value to zero to prevent these events from happening.</chance_for_other_to_join_in_sex_desc>
<hide_names_for_sex> Hide names when getting some lovin'</hide_names_for_sex>
@ -44,22 +20,17 @@
<autoscale_delta_pos_desc>Turning this setting on may help when using alien races which are much larger or smaller than regular humans.</autoscale_delta_pos_desc>
<redraw_hair> Redraw hair in pawn portraits</redraw_hair>
<redraw_hair_desc>Helps prevent bodyparts from rendering over long hair in portraits. Disable this feature if you find two sets of hair appearing on your pawns or hair is being rendered over headgear.</redraw_hair_desc>
<use_legacy_animation_system> Patch RimWorld Animation System</use_legacy_animation_system>
<use_legacy_animation_system_desc>Having this setting turned on patches C0ffee's RimWorld Animation framework with tweaks and visual improvements. This patching can cause conflict with other mods, however. If you are running into graphical issues with animation, try turning this setting off.</use_legacy_animation_system_desc>
<show_hands> Add animated hands to animations</show_hands>
<show_hands_desc>Requires RimNudeWorld. This feature can be performance intense. If you have large colonies (50+ colonist), you may wish to turn this off.</show_hands_desc>
<rimworld_animation_patch_clothing>Clothing options</rimworld_animation_patch_clothing>
<crop_apparel> Crop the bottoms of worn shirts, tank tops, etc. when not wearing pants or a skirt</crop_apparel>
<crop_apparel_desc>Only applies to torso covering apparel that lies directly on the skin and that does not cover the legs. Best used with mods that draw pants graphics, like the Visible Pants mod.\n\nRequires that the game to be reset when toggled off.</crop_apparel_desc>
<crop_apparel_desc>Only applies to torso covering apparel that lies directly on the skin and that does not cover the legs - best used alongside mods that draw pants on pawns, like the Visible Pants mod.\n\nThis setting will not be applied if you are using the Sized Apparel mod.\n\nRequires that the game to be reset if you wish to toggle it off.</crop_apparel_desc>
<clothes_thrown_on_ground> Show discarded clothing on the floor while getting some lovin'</clothes_thrown_on_ground>
<clothes_thrown_on_ground_desc>If a pawn undresses while lovin', these items of clothing will be piled on the floor nearby.\n\nThis is a purely visual effect.</clothes_thrown_on_ground_desc>
<wearing_clothes_in_bed> Preferred state of dress for people lovin' in a bed</wearing_clothes_in_bed>
<wearing_clothes_in_bed_desc>Changing this will update the clothing preference setting in RJW (and vice versa).</wearing_clothes_in_bed_desc>
<wearing_clothes_for_quickies> Preferred state of dress for people having a quickie</wearing_clothes_for_quickies>
<wearing_clothes_for_quickies_desc>Nothing more to say.</wearing_clothes_for_quickies_desc>
<underwear_sufficent_for_ideos> Underwear satisfies ideological needs for modesty</underwear_sufficent_for_ideos>
<underwear_sufficent_for_ideos_desc>If an ideology requires that certain body parts must be covered, wearing underwear can help fulfill this requirement.\n\nYou may want to turn this setting off if you want ideologies to be more strict about what they consider to be 'modestly clothed'.\n\nIdeologies which prefer to wear fewer clothes than normal are not affected by this setting.</underwear_sufficent_for_ideos_desc>
<exposed_underwear_mood> People feel embarassed if their underwear is showing</exposed_underwear_mood>
<exposed_underwear_mood_desc>It's not as bad as being naked, but your colonists would prefer to wear some additional clothes.\n\nExhibitionists, however, will get a small thrill if their underwear is exposed.</exposed_underwear_mood_desc>
<wearing_clothes_for_quickies_desc></wearing_clothes_for_quickies_desc>
</LanguageData>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>
<VoyeurQuirk><![CDATA[
{pawn} gets a thrill out of spying upon others while they are engaged in intimate acts.
]]></VoyeurQuirk>
</LanguageData>

View File

@ -66,7 +66,7 @@
<Private>False</Private>
</Reference>
<Reference Include="RimNudeWorld">
<HintPath>..\..\rimnude-unofficial-master\Assembly Folders\1.4 Assembly\Assemblies\RimNudeWorld.dll</HintPath>
<HintPath>..\..\rimnude-unofficial-abscon\Assembly Folders\1.4 Assembly\Assemblies\RimNudeWorld.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Rimworld-Animations">
@ -81,6 +81,10 @@
<HintPath>..\..\rjw-events-master\1.4\Assemblies\RJW-Events.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="SpeakUp">
<HintPath>..\..\..\..\..\workshop\content\294100\2502518544\1.4\Assemblies\SpeakUp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
@ -108,10 +112,7 @@
<Compile Include="Scripts\Comps\CompProperties_ApparelVisibility.cs" />
<Compile Include="Scripts\Comps\CompApparelVisibility.cs" />
<Compile Include="Scripts\Comps\CompPawnSexData.cs" />
<Compile Include="Scripts\Defs\ActorAddon.cs" />
<Compile Include="Scripts\Defs\ActorAddonDef.cs" />
<Compile Include="Scripts\Defs\ActorAnimationData.cs" />
<Compile Include="Scripts\Defs\AddonKeyframe.cs" />
<Compile Include="Scripts\Defs\BodyAddonData.cs" />
<Compile Include="Scripts\Defs\HandAnimationDef.cs" />
<Compile Include="Scripts\Extensions\StringExtension.cs" />
@ -123,22 +124,17 @@
<Compile Include="Scripts\HandMotions\RubBreasts_FacingNS.cs" />
<Compile Include="Scripts\HandMotions\StrokeGenitalsUpAndDown_FacingNS.cs" />
<Compile Include="Scripts\HandMotions\StrokeGenitalsUpAndDownShort_FacingNS.cs" />
<Compile Include="Scripts\Extensions\PawnAnimationClipExt.cs" />
<Compile Include="Scripts\Defs\RimNudeData.cs" />
<Compile Include="Scripts\Enums.cs" />
<Compile Include="Scripts\Extensions\PawnKeyframeExt.cs" />
<Compile Include="Scripts\Patches\HarmonyPatch_ApparelGraphicRecordGetter.cs" />
<Compile Include="Scripts\Patches\HarmonyPatch_BabiesAndChildren.cs" />
<Compile Include="Scripts\Patches\HarmonyPatch_Pawn_ApparelTracker.cs" />
<Compile Include="Scripts\Patches\HarmonyPatch_DrawGUIOverlay.cs" />
<Compile Include="Scripts\Patches\HarmonyPatch_JobDriver.cs" />
<Compile Include="Scripts\Patches\HarmonyPatch_RJWEvents.cs" />
<Compile Include="Scripts\Settings\ApparelSettings.cs" />
<Compile Include="Scripts\Utilities\ApparelAnimationUtility.cs" />
<Compile Include="Scripts\Utilities\ApparelSettingsUtility.cs" />
<Compile Include="Scripts\Utilities\DebugMode.cs" />
<Compile Include="Scripts\JobDrivers\JobDriver_JoinInSex.cs" />
<Compile Include="Scripts\Patches\HarmonyPatch_RimNudeWorld.cs" />
<Compile Include="Scripts\Utilities\HandAnimationUtility.cs" />
<Compile Include="Scripts\Utilities\PatchDefOf.cs" />
<Compile Include="Scripts\Utilities\SettingsUtility.cs" />

View File

@ -22,13 +22,20 @@ namespace Rimworld_Animations_Patch
public Dictionary<AlienPartGenerator.BodyAddon, BodyAddonData> bodyAddonData = new Dictionary<AlienPartGenerator.BodyAddon, BodyAddonData>();
public Dictionary<AlienPartGenerator.BodyAddon, BodyAddonData> bodyAddonDataPortraits = new Dictionary<AlienPartGenerator.BodyAddon, BodyAddonData>();
private Pawn pawn;
private Pawn pawn { get { return parent as Pawn; } }
private bool initialized;
public override void CompTick()
{
if (initialized == false)
{
pawn?.Drawer?.renderer?.graphics?.ResolveAllGraphics();
initialized = true;
}
}
public BodyAddonData GetBodyAddonData(AlienPartGenerator.BodyAddon bodyAddon, bool isPortrait)
{
if (pawn == null)
{ pawn = parent as Pawn; }
if (pawn == null || (pawn.Map != Find.CurrentMap && pawn.holdingOwner == null) || bodyAddon == null) return null;
if (isPortrait)
@ -67,16 +74,16 @@ namespace Rimworld_Animations_Patch
{
hands = pawn?.health?.hediffSet?.GetNotMissingParts()?.Where(x => x.def.tags.Contains(BodyPartTagDefOf.ManipulationLimbCore))?.ToList();
Hediff hediffPenis = pawn?.health?.hediffSet?.hediffs?.FirstOrDefault(x => x.def.defName.Contains("penis") == true || x.def.defName.Contains("Penis"));
Hediff hediffPenis = pawn?.health?.hediffSet?.hediffs?.FirstOrDefault(x => x.def.defName.Contains("penis", StringComparison.OrdinalIgnoreCase) == true);
sizeOfPenis = hediffPenis != null ? hediffPenis.Severity : 0f;
Hediff hediffBreasts = pawn?.health?.hediffSet?.hediffs?.FirstOrDefault(x => x.def.defName.Contains("breasts") == true || x.def.defName.Contains("Breasts") == true);
Hediff hediffBreasts = pawn?.health?.hediffSet?.hediffs?.FirstOrDefault(x => x.def.defName.Contains("breasts", StringComparison.OrdinalIgnoreCase) == true);
sizeOfBreasts = hediffBreasts != null ? hediffBreasts.Severity : 0f;
}
public int GetNumberOfHands()
{
if (hands.Any() == false) return 0;
if (hands.NullOrEmpty()) return 0;
return hands.Count;
}

View File

@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace Rimworld_Animations_Patch
{
public class ActorAddon
{
// Data to/from animationDef
public string addonName;
public int? anchoringActor;
public string anchorName;
public string layer = "Pawn";
public GraphicData graphicData;
public bool? render;
// Data helper functions
public string AddonName
{
get { return addonName; }
set { addonName = value; }
}
public int AnchoringActor
{
get { return anchoringActor.HasValue ? anchoringActor.Value : 0; }
set { anchoringActor = value; }
}
public string AnchorName
{
get { return anchorName; }
set { anchorName = value; }
}
public string Layer
{
get { return layer; }
set { layer = value; }
}
public GraphicData GraphicData
{
get { return graphicData; }
set { graphicData = value; }
}
public bool Render
{
get { return render == true; }
set { render = value; }
}
// Simple curves
public SimpleCurve PosX = new SimpleCurve();
public SimpleCurve PosZ = new SimpleCurve();
public SimpleCurve Rotation = new SimpleCurve();
// Constructors
public ActorAddon() { }
public ActorAddon(ActorAddonDef actorAddonDef)
{
this.GraphicData = actorAddonDef.graphicData;
}
}
}

View File

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace Rimworld_Animations_Patch
{
public class ActorAddonDef : Def
{
public float scale = 1f;
public GraphicData graphicData;
}
}

View File

@ -1,56 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Rimworld_Animations_Patch
{
public class AddonKeyframe
{
// Data to/from animationDef
public string addonName;
public float? posX;
public float? posZ;
public float? rotation;
// Data serialization control
public bool ShouldSerializeposX() { return posX.HasValue; }
public bool ShouldSerializeposZ() { return posZ.HasValue; }
public bool ShouldSerializerotation() { return rotation.HasValue; }
// Data helper functions
public string AddonName
{
get { return addonName; }
set { addonName = value; }
}
public float PosX
{
get { return posX.HasValue ? posX.Value : 0f; }
set { posX = value; }
}
public float PosZ
{
get { return posZ.HasValue ? posZ.Value : 0f; }
set { posZ = value; }
}
public float Rotation
{
get { return rotation.HasValue ? rotation.Value : 0f; }
set { rotation = value; }
}
// Constructors
public AddonKeyframe() { }
public AddonKeyframe(string addonName)
{
this.AddonName = addonName;
}
}
}

View File

@ -22,12 +22,12 @@ namespace Rimworld_Animations_Patch
private PawnRenderFlags renderFlags;
private bool canDraw = false;
private bool bodyPartMissing = false;
public BodyAddonData(Pawn pawn, AlienPartGenerator.BodyAddon bodyAddon, bool isPortrait = false)
{
this.pawn = pawn;
this.bodyAddon = bodyAddon;
if (isPortrait)
{ renderFlags |= PawnRenderFlags.Portrait; }
@ -42,11 +42,11 @@ namespace Rimworld_Animations_Patch
{
bodyType = pawn.story.bodyType.defName;
bodyAddonOffsets.Clear();
int bodyAddonIndex = (pawn.def as ThingDef_AlienRace).alienRace.generalSettings.alienPartGenerator.bodyAddons.IndexOf(bodyAddon);
AlienPartGenerator.AlienComp alienComp = pawn.GetComp<AlienPartGenerator.AlienComp>();
Graphic addonGraphic = alienComp.addonGraphics[bodyAddonIndex];
for (int i = 0; i < 4; i++)
{
Rot4 apparentRotation = new Rot4(i);
@ -54,8 +54,8 @@ namespace Rimworld_Animations_Patch
// Get basic offset for body addon
AlienPartGenerator.RotationOffset defaultOffsets = bodyAddon.defaultOffsets.GetOffset(apparentRotation);
Vector3 bodyTypeOffset = (defaultOffsets != null) ? defaultOffsets.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, pawn.story.headType) : Vector3.zero;
AlienPartGenerator.RotationOffset rotationOffsets = bodyAddon.offsets.GetOffset(apparentRotation);
AlienPartGenerator.RotationOffset rotationOffsets = bodyAddon.offsets.GetOffset(apparentRotation);
Vector3 bodyAddonOffset = bodyTypeOffset + ((rotationOffsets != null) ? rotationOffsets.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, pawn.story.headType) : Vector3.zero);
// Offset private parts so that they render over tattoos but under apparel (rendering under tatoos looks weird)
@ -65,8 +65,8 @@ namespace Rimworld_Animations_Patch
// Erected penises should be drawn over apparel
if (pawn.RaceProps.Humanlike &&
(addonGraphic.path.Contains("penis") || addonGraphic.path.Contains("Penis")) &&
(addonGraphic.path.Contains("flaccid") == false && addonGraphic.path.Contains("Flaccid") == false) &&
addonGraphic.path.Contains("penis", StringComparison.OrdinalIgnoreCase) &&
(addonGraphic.path.Contains("flaccid", StringComparison.OrdinalIgnoreCase) == false) &&
apparentRotation == Rot4.South)
{ bodyAddonOffset.y += 0.010f; }
}
@ -74,21 +74,21 @@ namespace Rimworld_Animations_Patch
// Otherwise use the standard offsets
else
{ bodyAddonOffset.y = 0.3f + bodyAddonOffset.y; }
// Draw addons infront of body
if (!bodyAddon.inFrontOfBody)
{ bodyAddonOffset.y *= -1f; }
// Adjust for facing
if (apparentRotation == Rot4.North)
{
if (bodyAddon.layerInvert)
{ bodyAddonOffset.y = -bodyAddonOffset.y; }
}
if (apparentRotation == Rot4.East)
{ bodyAddonOffset.x = -bodyAddonOffset.x; }
// Adjustment for body addons attached to the head that are not marked as such
if (alignsWithHead && bodyAddon.alignWithHead == false)
{ bodyAddonOffset -= pawn.Drawer.renderer.BaseHeadOffsetAt(apparentRotation); }
@ -102,9 +102,9 @@ namespace Rimworld_Animations_Patch
{
if (pawn.story.bodyType.defName != bodyType)
{ GenerateOffsets(); }
return bodyAddonOffsets[facing.AsInt];
}
}
public bool CanDraw()
{
@ -146,7 +146,7 @@ namespace Rimworld_Animations_Patch
if (pawn?.apparel?.WornApparel == null || pawn.apparel.WornApparel.NullOrEmpty())
{ return; }
foreach (Apparel apparel in pawn.apparel.WornApparel)
{
CompApparelVisibility comp = apparel?.TryGetComp<CompApparelVisibility>();
@ -155,9 +155,9 @@ namespace Rimworld_Animations_Patch
if (comp.isBeingWorn == false) continue;
if (bodyAddon.bodyPart == PatchBodyPartDefOf.Genitals ||
bodyAddon.bodyPart == PatchBodyPartDefOf.Anus ||
bodyAddon.bodyPart == PatchBodyPartDefOf.Chest ||
if (bodyAddon.bodyPart == PatchBodyPartDefOf.Genitals ||
bodyAddon.bodyPart == PatchBodyPartDefOf.Anus ||
bodyAddon.bodyPart == PatchBodyPartDefOf.Chest ||
bodyAddon.hediffGraphics?.Any(x => x.path.NullOrEmpty() == false && (x.path.Contains("belly") || x.path.Contains("Belly"))) == true)
{
if ((bodyAddon.bodyPart == PatchBodyPartDefOf.Genitals || bodyAddon.bodyPart == PatchBodyPartDefOf.Anus) && comp.coversGroin)
@ -204,4 +204,4 @@ namespace Rimworld_Animations_Patch
}
}
}
}
}

View File

@ -1,54 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Rimworld_Animations;
namespace Rimworld_Animations_Patch
{
public class PawnAnimationClipExt : PawnAnimationClip
{
public List<ActorAddon> addons = new List<ActorAddon>();
public override void buildSimpleCurves()
{
base.buildSimpleCurves();
int keyframePosition = 0;
for (int i = 0; i < keyframes.Count; i++)
{
PawnKeyframeExt keyframe = keyframes[i] as PawnKeyframeExt;
if (keyframe.atTick.HasValue)
{
foreach (ActorAddon addon in addons)
{
if (keyframe.addonKeyframes.Any(x => x.AddonName == addon.AddonName) == false)
{ keyframe.addonKeyframes.Add(new AddonKeyframe(addon.AddonName)); }
addon.PosX.Add((float)keyframe.atTick / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).PosX, true);
addon.PosZ.Add((float)keyframe.atTick / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).PosZ, true);
addon.Rotation.Add((float)keyframe.atTick / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).Rotation, true);
}
}
else
{
foreach (ActorAddon addon in addons)
{
if (keyframe.addonKeyframes.Any(x => x.AddonName == addon.AddonName) == false)
{ keyframe.addonKeyframes.Add(new AddonKeyframe(addon.AddonName)); }
addon.PosX.Add((float)keyframePosition / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).PosX, true);
addon.PosZ.Add((float)keyframePosition / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).PosZ, true);
addon.Rotation.Add((float)keyframePosition / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).Rotation, true);
}
keyframePosition += keyframe.tickDuration;
}
}
}
}
}

View File

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Rimworld_Animations;
namespace Rimworld_Animations_Patch
{
public class PawnKeyframeExt : PawnKeyframe
{
public List<AddonKeyframe> addonKeyframes;
public AddonKeyframe GetAddonKeyframe(string addonName)
{
return addonKeyframes.FirstOrDefault(x => x.AddonName == addonName);
}
}
}

View File

@ -1,79 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using RimWorld;
using UnityEngine;
using Verse;
using Verse.AI;
using rjw;
using Rimworld_Animations;
namespace Rimworld_Animations_Patch
{
public class JobDriver_JoinInSex : JobDriver_SexBaseInitiator
{
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
return true; // pawn.Reserve(Target, job, 3, 0, null, errorOnFailed);
}
protected override IEnumerable<Toil> MakeNewToils()
{
setup_ticks();
this.FailOnDespawnedNullOrForbidden(iTarget);
this.FailOn(() => !Partner.health.capacities.CanBeAwake);
this.FailOn(() => pawn.Drafted);
this.FailOn(() => Partner.Drafted);
Toil FollowToil = new Toil();
FollowToil.defaultCompleteMode = ToilCompleteMode.Delay;
FollowToil.socialMode = RandomSocialMode.Off;
FollowToil.defaultDuration = 1200;
FollowToil.tickAction = delegate
{
pawn.pather.StartPath(Partner, PathEndMode.Touch);
if (pawn.pather.Moving == false && Partner.pather.Moving == false && Partner.jobs.curDriver is JobDriver_SexBaseReciever)
{ ReadyForNextToil(); }
};
yield return FollowToil;
Toil SexToil = new Toil();
SexToil.defaultCompleteMode = ToilCompleteMode.Never;
SexToil.socialMode = RandomSocialMode.Off;
SexToil.defaultDuration = duration;
SexToil.handlingFacing = true;
SexToil.FailOn(() => (Partner.jobs.curDriver is JobDriver_SexBaseReciever) == false);
SexToil.initAction = delegate
{
Start();
Sexprops.usedCondom = CondomUtility.TryUseCondom(pawn) || CondomUtility.TryUseCondom(Partner);
};
SexToil.AddPreTickAction(delegate
{
if (pawn.IsHashIntervalTick(ticks_between_hearts))
ThrowMetaIconF(pawn.Position, pawn.Map, FleckDefOf.Heart);
SexTick(pawn, Partner);
SexUtility.reduce_rest(pawn, 1);
if (ticks_left <= 0)
ReadyForNextToil();
});
SexToil.AddFinishAction(delegate
{
End();
});
yield return SexToil;
yield return new Toil
{
initAction = delegate
{
//// Trying to add some interactions and social logs
SexUtility.ProcessSex(Sexprops);
},
defaultCompleteMode = ToilCompleteMode.Instant
};
}
}
}

View File

@ -8,13 +8,31 @@ using Verse;
namespace Rimworld_Animations_Patch
{
[StaticConstructorOnStartup]
[HarmonyPatch(typeof(ApparelGraphicRecordGetter), "TryGetGraphicApparel")]
public static class HarmonyPatch_ApparelGraphicRecordGetter_TryGetGraphicApparel
{
static bool _checkedForSizedApparel;
static bool _isRunningSizedApparel;
// Not compatible with SizedApparel - running Graphic.Blit on the resized apparel will cause the pawn to turn invisible for one facing
public static bool IsRunningSizedApparel
{
get
{
if (_checkedForSizedApparel == false)
{
_isRunningSizedApparel = LoadedModManager.RunningModsListForReading.Any(x => x.PackageIdPlayerFacing == "OTYOTY.SizedApparel");
_checkedForSizedApparel = true;
}
return _isRunningSizedApparel;
}
}
public static void Postfix(ref bool __result, ref Apparel apparel, ref BodyTypeDef bodyType, ref ApparelGraphicRecord rec)
{
if (__result == false || apparel == null || bodyType == null || rec.graphic == null || ApparelSettings.cropApparel == false)
{ return; }
if (__result == false || apparel == null || bodyType == null || rec.graphic == null || ApparelSettings.cropApparel == false || IsRunningSizedApparel) return;
// Get graphic
Graphic graphic = rec.graphic;
@ -23,17 +41,14 @@ namespace Rimworld_Animations_Patch
if (apparel.def.apparel.LastLayer == ApparelLayerDefOf.OnSkin && apparel.def.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Torso) && !apparel.def.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Legs))
{
Dictionary<GraphicRequest, Graphic> allGraphics = Traverse.Create(typeof(GraphicDatabase)).Field("allGraphics").GetValue() as Dictionary<GraphicRequest, Graphic>;
GraphicRequest graphicRequest = new GraphicRequest(typeof(Graphic_Multi), graphic.path, ShaderDatabase.CutoutComplex, apparel.def.graphicData.drawSize, apparel.DrawColor, apparel.DrawColor, null, 0, null, "Masks/apparel_shirt_mask_" + bodyType.defName);
GraphicRequest graphicRequest = new GraphicRequest(typeof(Graphic_Multi), graphic.path, ShaderDatabase.CutoutComplex, graphic.drawSize, apparel.DrawColor, apparel.DrawColor, null, 0, null, "Masks/apparel_shirt_mask_" + bodyType.defName);
if (allGraphics.TryGetValue(graphicRequest) == null)
{
Graphic graphicWithApparelMask = GraphicDatabase.Get<Graphic_Multi>(graphic.path, ShaderDatabase.CutoutComplex, apparel.def.graphicData.drawSize, apparel.DrawColor, apparel.DrawColor, null, "Masks/apparel_shirt_mask_" + bodyType.defName);
graphic = GraphicMaskingUtility.ApplyGraphicWithMasks(graphic, graphicWithApparelMask, true);
//DebugMode.Message("Applying apparel mask: Masks/apparel_shirt_mask_" + bodyType.defName + " to " + apparel.def.defName + " (" + graphic.path + ")");
Graphic graphicWithApparelMasks = GraphicDatabase.Get<Graphic_Multi>(graphic.path, ShaderDatabase.CutoutComplex, graphic.drawSize, apparel.DrawColor, apparel.DrawColor, null, "Masks/apparel_shirt_mask_" + bodyType.defName);
graphic = GraphicMaskingUtility.ApplyGraphicMasks(graphic, graphicWithApparelMasks, true);
if (apparel.Wearer != null)
{ PortraitsCache.SetDirty(apparel.Wearer); }
//DebugMode.Message("Applying apparel mask: Masks/apparel_shirt_mask_" + bodyType.defName + " to " + apparel.def.defName + " (" + graphic.path + ")");
}
}

View File

@ -10,7 +10,8 @@ using BabiesAndChildren.api;
namespace Rimworld_Animations_Patch
{
[StaticConstructorOnStartup]
// To be revisited if BabiesAndChildren is updated
/*[StaticConstructorOnStartup]
public static class HarmonyPatch_BabiesAndChildren
{
static HarmonyPatch_BabiesAndChildren()
@ -45,5 +46,5 @@ namespace Rimworld_Animations_Patch
return false;
}
}
}*/
}

View File

@ -21,12 +21,14 @@ namespace Rimworld_Animations_Patch
if (__instance?.pawn == null)
{ return; }
// Scale delta by body size
if (BasicSettings.autoscaleDeltaPos)
{
__instance.deltaPos.x *= __instance.pawn.RaceProps.baseBodySize;
__instance.deltaPos.z *= __instance.pawn.RaceProps.baseBodySize;
}
// In-bed specific animations cause the actors to turn to match its facing
if (__instance.pawn.IsInBed(out Building bed) &&
__instance.pawn.GetAnimationData().animationDef.actors[__instance.pawn.GetAnimationData().actorID].requiredGenitals.NullOrEmpty() == false &&
__instance.pawn.GetAnimationData().animationDef.actors[__instance.pawn.GetAnimationData().actorID].requiredGenitals.Contains("Bed"))

View File

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
using RimWorld;
using Verse;
using Verse.AI;
using Rimworld_Animations;
using rjw;
namespace Rimworld_Animations_Patch
{
[HarmonyPatch(typeof(JobDriver), "GetReport")]
public static class HarmonyPatch_JobDriver
{
public static bool Prefix(JobDriver __instance, ref string __result)
{
JobDriver_Sex jobdriver = __instance as JobDriver_Sex;
if (jobdriver != null && jobdriver.pawn != null && jobdriver.pawn.GetAnimationData() != null && jobdriver.Sexprops.isRape == false && jobdriver.Sexprops.isWhoring == false)
{
LocalTargetInfo a = jobdriver.job.targetA.IsValid ? jobdriver.job.targetA : jobdriver.job.targetQueueA.FirstValid();
LocalTargetInfo b = jobdriver.job.targetB.IsValid ? jobdriver.job.targetB : jobdriver.job.targetQueueB.FirstValid();
LocalTargetInfo targetC = jobdriver.job.targetC;
//__result = JobUtility.GetResolvedJobReport(jobdriver.pawn.GetAnimationData().animationDef.label, a, b, targetC);
//return false;
}
return true;
}
}
}

View File

@ -1,37 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using HarmonyLib;
using RimNudeWorld;
namespace Rimworld_Animations_Patch
{
/*[StaticConstructorOnStartup]
public static class HarmonyPatch_RimNudeWorld
{
static HarmonyPatch_RimNudeWorld()
{
try
{
((Action)(() =>
{
if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageIdPlayerFacing == "shauaputa.rimnudeworld"))
{
(new Harmony("Rimworld_Animations_Patch")).Patch(AccessTools.Method(AccessTools.TypeByName("RevealingApparel.HarmonyPatch_DrawAddons"), "Postfix"),
prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_RimNudeWorld), "Prefix_HarmonyPatch_DrawAddons")));
}
}))();
}
catch (TypeLoadException) { }
}
// Patch RimNudeWorld to override the revealing apparel feature; this task is handled by the new apparel settings system
public static bool Prefix_HarmonyPatch_DrawAddons()
{
return false;
}
}*/
}

View File

@ -163,7 +163,7 @@ namespace Rimworld_Animations_Patch
if (bodyAddonDatum.alignsWithHead)
{ bodyAngle = MathUtility.ClampAngle(animatorComp.headAngle); }
if (animatorComp.controlGenitalAngle && (addonGraphic.path.Contains("penis") || addonGraphic.path.Contains("Penis")))
if (animatorComp.controlGenitalAngle && addonGraphic.path.Contains("penis", StringComparison.OrdinalIgnoreCase))
{ bodyAddonAngle = MathUtility.ClampAngle(bodyAddonAngle + (AnimationSettings.controlGenitalRotation ? MathUtility.ClampAngle(animatorComp.genitalAngle) : 0f)); }
}
@ -205,30 +205,6 @@ namespace Rimworld_Animations_Patch
}
}
// Add-ons
if (animatorComp?.isAnimating == true)
{
//ActorAnimationData actorData = pawn.GetAnimationData();
//PawnAnimationClipExt clip = actorData.animationDef.animationStages[actorData.currentStage].animationClips[actorData.actorID] as PawnAnimationClipExt;
/*foreach (ActorAddon addon in clip.Addons)
{
actorBodypart = actorBody.GetActorBodyPart(addon.AddonName);
if (actorBodypart == null) continue;
ActorBody anchoringActorBody = actorBodies.GetComponentsInChildren<ActorBody>()?.FirstOrDefault(x => x.actorID == addon.AnchoringActor);
Vector3 anchor = PawnUtility.GetBodyPartAnchor(anchoringActorBody, addon.anchorName);
actorBodypart.transform.position = anchor + new Vector3(addon.PosX.Evaluate(clipPercent), addon.PosZ.Evaluate(clipPercent), 0);
actorBodypart.transform.eulerAngles = new Vector3(0, 0, -addon.Rotation.Evaluate(clipPercent));
actorBodypart.bodyPartRenderer.sortingLayerName = addon.Layer;
//actorBodypart.bodyPartRenderer.sprite
actorBodypart.gameObject.SetActive(addon.Render);
}*/
}
// Body addons are sometimes are not appropriately concealed by long hair in portraits, so re-draw the pawn's hair here
if (pawn.Drawer.renderer.graphics.headGraphic != null && renderFlags.FlagSet(PawnRenderFlags.Portrait) && BasicSettings.redrawHair)
{

View File

@ -42,8 +42,8 @@ namespace Rimworld_Animations_Patch
public class ApparelSettingsDisplay : Mod
{
private const float windowY = 290f;
private const float windowHeight = 320f;
private const float windowY = 240f;
private const float windowHeight = 360f;
private Vector2 scrollPosition;
private const float scrollBarWidthMargin = 18f;
@ -62,10 +62,10 @@ namespace Rimworld_Animations_Patch
private const float singleColumnWidth = 100f;
private const float doubleColumnWidth = 180f;
private IEnumerable<ThingDef> shortListedApparelDefs = new List<ThingDef>();
private IEnumerable<ThingDef> allApparelDefs = new List<ThingDef>();
private List<ThingDef> shortListedApparelDefs = new List<ThingDef>();
private List<ThingDef> allApparelDefs = new List<ThingDef>();
private IEnumerable<ModContentPack> relevantModContentPacks = new List<ModContentPack>();
private List<ModContentPack> relevantModContentPacks = new List<ModContentPack>();
private ModContentPack currentModContentPack;
public ApparelSettingsDisplay(ModContentPack content) : base(content)
@ -161,18 +161,19 @@ namespace Rimworld_Animations_Patch
bool isEnabled = false;
// Get a list of apparel and mods of interest
if (allApparelDefs.Any() == false)
if (allApparelDefs.NullOrEmpty())
{
allApparelDefs = ApparelSettingsUtility.GetApparelOfInterest();
foreach (ThingDef thingDef in allApparelDefs)
{
if (relevantModContentPacks.Contains(thingDef.modContentPack) == false)
{ relevantModContentPacks.Append(thingDef.modContentPack); }
}
{ relevantModContentPacks.AddDistinct(thingDef.modContentPack); }
currentModContentPack = relevantModContentPacks.First();
shortListedApparelDefs = allApparelDefs.Where(x => x.modContentPack == currentModContentPack);
currentModContentPack = relevantModContentPacks.FirstOrDefault();
if (currentModContentPack == null)
{ DebugMode.Message("ERROR: No mod content has been loaded?"); return; }
shortListedApparelDefs = allApparelDefs.Where(x => x.modContentPack == currentModContentPack)?.ToList();
}
// Ensure that all apparel has associated RimNudeData
@ -182,44 +183,29 @@ namespace Rimworld_Animations_Patch
// Add buttons to the top of the main window
innerX = halfColumnWidth;
// Mod selection button
if (Widgets.ButtonText(new Rect(innerX + SettingsUtility.Align(labelWidth, doubleColumnWidth), windowY - 2 * headerHeight - 5, 2 * doubleColumnWidth + 10, headerHeight), currentModContentPack.Name))
{
if (shortListedApparelDefs.NullOrEmpty()) return;
// Apparel
tempRect = new Rect(innerX + SettingsUtility.Align(labelWidth, doubleColumnWidth), windowY - headerHeight - 5, labelWidth, headerHeight);
Widgets.DrawHighlightIfMouseover(tempRect);
TooltipHandler.TipRegion(tempRect, "List of apparel that covers the legs and/or torso. Use the provided drop down menu to load apparel settings for different mods.");
if (Widgets.ButtonText(tempRect, "Apparel - " + currentModContentPack.ModMetaData.Name)) {
List<FloatMenuOption> options = new List<FloatMenuOption> { };
foreach (ModContentPack modContentPack in relevantModContentPacks)
{
FloatMenuOption option = new FloatMenuOption(modContentPack.Name, delegate ()
{
currentModContentPack = modContentPack;
shortListedApparelDefs = allApparelDefs.Where(x => x.modContentPack == currentModContentPack);
},
FloatMenuOption option = new FloatMenuOption(modContentPack.ModMetaData.Name, delegate ()
{
currentModContentPack = modContentPack;
shortListedApparelDefs = allApparelDefs.Where(x => x.modContentPack == currentModContentPack)?.ToList();
},
MenuOptionPriority.Default, null, null, 0f, null, null, true, 0);
options.Add(option);
}
Find.WindowStack.Add(new FloatMenu(options));
}
if (shortListedApparelDefs.Any() == false) return;
// Apparel
tempRect = new Rect(innerX + SettingsUtility.Align(labelWidth, doubleColumnWidth), windowY - headerHeight - 5, labelWidth, headerHeight);
Widgets.DrawHighlightIfMouseover(tempRect);
TooltipHandler.TipRegion(tempRect, "List of apparel that covers the legs and/or torso. This list can be sorted alphabetically or by the mod that added them.");
if (Widgets.ButtonText(tempRect, "Apparel"))
{
List<FloatMenuOption> options = new List<FloatMenuOption>
{
new FloatMenuOption("Sort by name", delegate()
{ shortListedApparelDefs = shortListedApparelDefs.OrderBy(x => x.label);
}, MenuOptionPriority.Default, null, null, 0f, null, null, true, 0),
new FloatMenuOption("Sort by mod", delegate()
{ shortListedApparelDefs = ApparelSettingsUtility.GetApparelOfInterest();
}, MenuOptionPriority.Default, null, null, 0f, null, null, true, 0),
}; Find.WindowStack.Add(new FloatMenu(options));
}; innerX += doubleColumnWidth;
// Covers groin

View File

@ -19,7 +19,6 @@ namespace Rimworld_Animations_Patch
RenderTexture.active = rt;
if (mat != null)
{ Graphics.Blit(source, rt, mat); }
else
{ Graphics.Blit(source, rt); }
@ -49,7 +48,7 @@ namespace Rimworld_Animations_Patch
DebugMode.Message("mainTex or maskTex is missing!");
return mainTex;
}
Color[] mainArray = GetReadableTexture2D(mainTex).GetPixels();
Color[] maskArray = GetReadableTexture2D(maskTex, mainTex.width, mainTex.height).GetPixels();
@ -64,7 +63,7 @@ namespace Rimworld_Animations_Patch
else if (mainArray[j].a > 0 && maskArray[j].a > 0 && writeOverMainTex)
{ mainArray[j] = new Color(Mathf.Min(mainArray[j].r, maskArray[j].r), Mathf.Min(mainArray[j].g, maskArray[j].g), Mathf.Min(mainArray[j].b, maskArray[j].b), Mathf.Min(mainArray[j].a, maskArray[j].a)); }
}
Texture2D newTex = new Texture2D(mainTex.width, mainTex.height, TextureFormat.RGBA32, mipChain: true);
newTex.SetPixels(mainArray);
newTex.filterMode = FilterMode.Trilinear;
@ -74,71 +73,23 @@ namespace Rimworld_Animations_Patch
return newTex;
}
public static Graphic ApplyGraphicWithMasks(Graphic graphic, Graphic graphicWithMask, bool writeOverMainTex)
public static Graphic ApplyGraphicMasks(Graphic graphic, Graphic graphicWithMask, bool writeOverMainTex)
{
for (int i = 0; i < 4; i++)
{
Texture2D mainTex = (Texture2D)graphic.MatAt(new Rot4(i)).mainTexture;
Texture2D maskTex = graphicWithMask.MatAt(new Rot4(i)).GetMaskTexture();
graphic.MatAt(new Rot4(i)).mainTexture = ApplyMaskToTexture2D(mainTex, maskTex, writeOverMainTex);
}
return graphic;
}
public static Graphic ApplyGraphicWithMasks(Graphic graphic, string mask, bool writeOverMainTex)
{
for (int i = 0; i < 4; i++)
{
Texture2D mainTex = (Texture2D)graphic.MatAt(new Rot4(i)).mainTexture;
if (mainTex == null)
{ DebugMode.Message("Main Texture2D not found for " + graphic.path + ". Rotation: " + i.ToString()); continue; }
string suffix = string.Empty;
switch (i)
{
case 0: suffix = "_north"; break;
case 1: suffix = "_east"; break;
case 2: suffix = "_south"; break;
case 3: suffix = "_west"; break;
}
Texture2D maskTex = ContentFinder<Texture2D>.Get(mask + suffix, false);
if (maskTex == null)
{ DebugMode.Message("Mask Texture2D not found for " + mask + ". Rotation: " + i.ToString()); continue; }
{ DebugMode.Message("Mask Texture2D not found for " + graphic.path + ". Rotation: " + i.ToString()); continue; }
graphic.MatAt(new Rot4(i)).mainTexture = ApplyMaskToTexture2D(mainTex, maskTex, writeOverMainTex);
}
return graphic;
}
public static void ResetGraphic(Graphic graphic)
{
for (int i = 0; i < 4; i++)
{
string suffix = string.Empty;
switch (i)
{
case 0: suffix = "_north"; break;
case 1: suffix = "_east"; break;
case 2: suffix = "_south"; break;
case 3: suffix = "_west"; break;
}
Texture2D texture2D = ContentFinder<Texture2D>.Get(graphic.path + suffix, false);
if (texture2D == null && i == 3)
{ texture2D = ContentFinder<Texture2D>.Get(graphic.path + "_east", false); }
if (texture2D == null)
{ texture2D = ContentFinder<Texture2D>.Get(graphic.path + "_north", false); }
if (texture2D != null)
{ graphic.MatAt(new Rot4(i)).mainTexture = texture2D; }
}
}
}
}

View File

@ -35,7 +35,7 @@ namespace Rimworld_Animations_Patch
{
IEnumerable<IntVec3> cells = GenRadial.RadialCellsAround(pawn.Position, radius + 0.75f, false).Where(x => x.Standable(pawn.Map) && x.GetRoom(pawn.Map) == pawn.GetRoom());
if (cells.Any() == true && cells.Count() > 0)
if (cells?.Any() == true && cells.Count() > 0)
{ return cells.RandomElement(); }
}
}

View File

@ -1 +1 @@
0035486d66161d603d82d58abd89b02b042a2e0c
fff727b2ad4bd81d64cd84c1b3509271d8320a48