This commit is contained in:
AbstractConcept 2022-09-11 01:05:16 -05:00
parent 8e6918ae70
commit 0fcdce6dc1
24 changed files with 122 additions and 226 deletions

View File

@ -1,3 +1,7 @@
Chnage log v 1.2.1
- Change: Optimisation of the body part rendering code - there should be much better frame rates now. Just avoid hosting orgies involving 50 or more people...
- Addition: Added option to the basic settings menu to toggle hair redrawing for portraits (helps make sure that body parts are properly covered by long hair)
Change log v 1.2.0 Change log v 1.2.0
- Fix: Fixed bug where married pawns could be accused of cheating when having sex with another spouse - Fix: Fixed bug where married pawns could be accused of cheating when having sex with another spouse
- Fix: Fixed bug where some animations would not result in an orgasm occuring when they should be occuring - Fix: Fixed bug where some animations would not result in an orgasm occuring when they should be occuring

View File

@ -36,6 +36,8 @@
<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> <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>
<show_hands> Add animated hands to animations</show_hands> <show_hands> Add animated hands to animations</show_hands>
<show_hands_desc>Requires RimNudeWorld.</show_hands_desc> <show_hands_desc>Requires RimNudeWorld.</show_hands_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>
<rimworld_animation_patch_clothing>Clothing options</rimworld_animation_patch_clothing> <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> Crop the bottoms of worn shirts, tank tops, etc. when not wearing pants or a skirt</crop_apparel>

View File

@ -14,6 +14,10 @@
<inFrontOfBody>false</inFrontOfBody> <inFrontOfBody>false</inFrontOfBody>
</value> </value>
</li> </li>
<li Class="PatchOperationRemove">
<xpath>Defs/ThingDef/alienRace/generalSettings/alienPartGenerator/bodyAddons/li[bodyPart="Anus"]/hiddenUnderApparelFor</xpath>
</li>
</operations> </operations>
</match> </match>

View File

@ -8,32 +8,16 @@
<success>Normal</success> <success>Normal</success>
<operations> <operations>
<li Class="PatchOperationAdd"> <!-- Hiding these bodyparts is now handled by code -->
<xpath>Defs/ThingDef/alienRace/generalSettings/alienPartGenerator/bodyAddons/li/hiddenUnderApparelFor[li="Torso"]</xpath> <li Class="PatchOperationRemove">
<value> <xpath>Defs/ThingDef/alienRace/generalSettings/alienPartGenerator/bodyAddons/li[bodyPart="Genitals"]/hiddenUnderApparelFor</xpath>
<li>ChestBPG</li>
</value>
</li> </li>
<li Class="PatchOperationAdd"> <li Class="PatchOperationRemove">
<xpath>Defs/ThingDef/alienRace/generalSettings/alienPartGenerator/bodyAddons/li/hiddenUnderApparelFor[li="Legs"]</xpath> <xpath>Defs/ThingDef/alienRace/generalSettings/alienPartGenerator/bodyAddons/li[bodyPart="Chest"]/hiddenUnderApparelFor</xpath>
<value>
<li>GenitalsBPG</li>
</value>
</li> </li>
<li Class="PatchOperationConditional"> <!-- Changes the layering of belly graphics so they are rendered first -->
<xpath>Defs/ThingDef/alienRace/generalSettings/alienPartGenerator/bodyAddons/li[hediffGraphics/RJW_pregnancy]/hiddenUnderApparelFor</xpath>
<nomatch Class="PatchOperationAdd">
<xpath>Defs/ThingDef/alienRace/generalSettings/alienPartGenerator/bodyAddons/li[hediffGraphics/RJW_pregnancy]</xpath>
<value>
<hiddenUnderApparelFor>
<li>Torso</li>
</hiddenUnderApparelFor>
</value>
</nomatch>
</li>
<li Class="PatchOperationReplace"> <li Class="PatchOperationReplace">
<xpath>Defs/ThingDef/alienRace/generalSettings/alienPartGenerator/bodyAddons/li[hediffGraphics/RJW_pregnancy]/offsets/south/layerOffset</xpath> <xpath>Defs/ThingDef/alienRace/generalSettings/alienPartGenerator/bodyAddons/li[hediffGraphics/RJW_pregnancy]/offsets/south/layerOffset</xpath>
<value> <value>

View File

@ -67,6 +67,7 @@
<Reference Include="Rimworld-Animations, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Rimworld-Animations, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\rimworld-animations-master\1.3\Assemblies\Rimworld-Animations.dll</HintPath> <HintPath>..\..\rimworld-animations-master\1.3\Assemblies\Rimworld-Animations.dll</HintPath>
<Private>False</Private>
</Reference> </Reference>
<Reference Include="RJW, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="RJW, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>

View File

@ -14,14 +14,21 @@ namespace Rimworld_Animations_Patch
public Apparel apparel => base.parent as Apparel; public Apparel apparel => base.parent as Apparel;
public Vector3 position; public Vector3 position;
public float rotation = 0f; public float rotation = 0f;
public bool isBeingWorn = true; public bool isBeingWorn = true;
public bool coversChest = false;
public bool coversGroin = false;
public bool coversBelly = false;
public RimNudeDataStatus rimNudeDataStatus = RimNudeDataStatus.NotLoaded;
private IntVec3 cellPosition; private IntVec3 cellPosition;
public override void PostExposeData() public override void PostExposeData()
{ {
base.PostExposeData(); base.PostExposeData();
Scribe_Values.Look(ref position, "position", default); Scribe_Values.Look(ref position, "position", default);
Scribe_Values.Look(ref rotation, "rotation", 0);
Scribe_Values.Look(ref cellPosition, "cellPosition", default); Scribe_Values.Look(ref cellPosition, "cellPosition", default);
} }
@ -44,32 +51,5 @@ namespace Rimworld_Animations_Patch
position = cellPosition.ToVector3() + offset + new Vector3(0.5f, AltitudeLayer.ItemImportant.AltitudeFor() - Mathf.Clamp(apparel.def.apparel.LastLayer.drawOrder/100000f, 0f, 1f), 0.5f); position = cellPosition.ToVector3() + offset + new Vector3(0.5f, AltitudeLayer.ItemImportant.AltitudeFor() - Mathf.Clamp(apparel.def.apparel.LastLayer.drawOrder/100000f, 0f, 1f), 0.5f);
rotation = 120 * (-1f + 2f * Rand.Value); rotation = 120 * (-1f + 2f * Rand.Value);
} }
/*public bool IsBeingWorn()
{
Pawn pawn = apparel.Wearer;
if (apparel.def.apparel.wornGraphicPath.NullOrEmpty())
{ return true; }
foreach (ApparelGraphicRecord record in pawn.Drawer.renderer.graphics.apparelGraphics)
{
if (record.sourceApparel == apparel)
{ return true; }
}
return false;
}*/
} }
} }
//var methodInfo = AccessTools.Method(typeof(GenPlace), "TryFindPlaceSpotNear", null, null);
//object[] parameters = new object[] { apparel.Wearer.Position, default(Rot4), apparel.Wearer.Map, apparel.Wearer, false, null, null };
//object result = methodInfo.Invoke(null, parameters);
/*bool _result = (bool)result;
if (_result)
{
bestSpot = (IntVec3)parameters[5];
DebugMode.Message("Best position: " + bestSpot.ToString());
}*/

View File

@ -12,4 +12,11 @@ namespace Rimworld_Animations_Patch
MinorTaboo = 1, MinorTaboo = 1,
MajorTaboo = 2, MajorTaboo = 2,
} }
public enum RimNudeDataStatus
{
Unavailable = -1,
NotLoaded = 0,
Loaded = 1,
}
} }

View File

@ -29,7 +29,8 @@ namespace Rimworld_Animations_Patch
{ {
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 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); graphic = GraphicMaskingUtility.ApplyGraphicWithMasks(graphic, graphicWithApparelMask, true);
DebugMode.Message("Applying apparel mask: Masks/apparel_shirt_mask_" + bodyType.defName + " to " + apparel.def.defName + " (" + graphic.path + ")");
//DebugMode.Message("Applying apparel mask: Masks/apparel_shirt_mask_" + bodyType.defName + " to " + apparel.def.defName + " (" + graphic.path + ")");
} }
} }

View File

@ -83,12 +83,15 @@ namespace Rimworld_Animations_Patch
if (__instance.pawn.apparel.WornApparel.NullOrEmpty() == false) if (__instance.pawn.apparel.WornApparel.NullOrEmpty() == false)
{ {
foreach(Apparel apparel in __instance.pawn.apparel.WornApparel) foreach (Apparel apparel in __instance.pawn.apparel.WornApparel)
{ {
CompApparelVisibility comp = apparel.TryGetComp<CompApparelVisibility>(); CompApparelVisibility comp = apparel.TryGetComp<CompApparelVisibility>();
if (comp != null) if (comp != null)
{ comp.isBeingWorn = true; } {
comp.isBeingWorn = true;
comp.rimNudeDataStatus = RimNudeDataStatus.NotLoaded;
}
} }
} }
} }

View File

@ -24,6 +24,8 @@ namespace Rimworld_Animations_Patch
postfix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_Rimworld_Animations), "Postfix_RerollAnimations"))); postfix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_Rimworld_Animations), "Postfix_RerollAnimations")));
(new Harmony("Rimworld_Animations_Patch")).Patch(AccessTools.Method(AccessTools.TypeByName("Rimworld_Animations.HarmonyPatch_AlienRace"), "Prefix_AnimateHeadAddons"), (new Harmony("Rimworld_Animations_Patch")).Patch(AccessTools.Method(AccessTools.TypeByName("Rimworld_Animations.HarmonyPatch_AlienRace"), "Prefix_AnimateHeadAddons"),
prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_Rimworld_Animations), "Prefix_DrawAddons"))); prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_Rimworld_Animations), "Prefix_DrawAddons")));
(new Harmony("Rimworld_Animations_Patch")).Patch(AccessTools.Method(AccessTools.TypeByName("BodyAddon"), "CanDrawAddon"),
postfix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_Rimworld_Animations), "Postfix_CanDrawAddon")));
} }
// Extend the animation selector's body part check to include hands and whether the pawn is in bed or not // Extend the animation selector's body part check to include hands and whether the pawn is in bed or not
@ -81,101 +83,31 @@ namespace Rimworld_Animations_Patch
} }
// Determine if a body addon is covered by apparel // Determine if a body addon is covered by apparel
/*public static bool BodyAddonCoveredByApparel(Pawn pawn, AlienPartGenerator.BodyAddon bodyAddon)
{
foreach (ApparelGraphicRecord apparelGraphicRecord in pawn.Drawer.renderer.graphics.apparelGraphics)
{
Apparel apparel = apparelGraphicRecord.sourceApparel;
if (apparel.def.apparel.bodyPartGroups.Any(x => bodyAddon.hiddenUnderApparelFor.Contains(x)))
{ return true; }
}
return false;
}*/
public static bool BodyAddonCoveredByWornApparel(Pawn pawn, AlienPartGenerator.BodyAddon bodyAddon) public static bool BodyAddonCoveredByWornApparel(Pawn pawn, AlienPartGenerator.BodyAddon bodyAddon)
{ {
if (bodyAddon?.hiddenUnderApparelFor == null || bodyAddon?.hiddenUnderApparelTag == null) if (pawn?.apparel?.WornApparel == null || bodyAddon == null)
{ return false; } { return false; }
foreach (Apparel apparel in pawn.apparel.WornApparel) foreach (Apparel apparel in pawn.apparel.WornApparel)
{ {
if (ApparelAnimationUtility.BodyAddonCoveredByApparel(apparel, bodyAddon)) if (ApparelAnimationUtility.PrivatePartCoveredByApparel(apparel, bodyAddon.bodyPart))
{ return true; } { return true; }
} }
return false; return false;
} }
// Determine if a body addon should be drawn public static void Postfix_CanDrawAddon(AlienPartGenerator.BodyAddon __instance, ref bool __result, Pawn pawn)
public static bool CanDrawAddon(Pawn pawn, AlienPartGenerator.BodyAddon bodyAddon)
{ {
if (bodyAddon == null) if (__result == false) return;
{ return false; }
if (pawn.RaceProps.Animal) __result = BodyAddonCoveredByWornApparel(pawn, __instance) == false;
{ return true; }
Building_Bed building_Bed = pawn.CurrentBed();
if ((building_Bed == null ||
building_Bed.def.building.bed_showSleeperBody ||
bodyAddon.drawnInBed) && (bodyAddon.backstoryRequirement.NullOrEmpty() || pawn.story.AllBackstories.Any((Backstory x) => x.identifier == bodyAddon.backstoryRequirement)))
{
if (!bodyAddon.drawnDesiccated)
{
Corpse corpse = pawn.Corpse;
if (corpse != null && corpse.GetRotStage() == RotStage.Dessicated)
{ return false; }
}
if (!bodyAddon.bodyPart.NullOrEmpty() &&
!pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined, null, null).Any((BodyPartRecord bpr) => bpr.untranslatedCustomLabel == bodyAddon.bodyPart || bpr.def.defName == bodyAddon.bodyPart))
{
List<AlienPartGenerator.BodyAddonHediffGraphic> list = bodyAddon.hediffGraphics;
bool flag;
if (list == null)
{ flag = false; }
else
{ flag = list.Any((AlienPartGenerator.BodyAddonHediffGraphic bahg) => bahg.hediff == HediffDefOf.MissingBodyPart); }
if (!flag)
{ return false; }
}
if ((pawn.gender == Gender.Female) ? bodyAddon.drawForFemale : bodyAddon.drawForMale)
{
if (bodyAddon.bodyTypeRequirement.NullOrEmpty() || pawn.story.bodyType.ToString() == bodyAddon.bodyTypeRequirement)
{
bool renderClothes = true;
if (Find.WindowStack.currentlyDrawnWindow is Page_ConfigureStartingPawns)
{ renderClothes = (bool)AccessTools.Field(typeof(Page_ConfigureStartingPawns), "renderClothes").GetValue(Find.WindowStack.currentlyDrawnWindow); }
else
{ renderClothes = pawn.Drawer.renderer.graphics.apparelGraphics.Count > 0; }
bool conditionA = !BodyAddonCoveredByWornApparel(pawn, bodyAddon);
bool conditionB = !renderClothes;
bool conditionC = pawn.GetPosture() == PawnPosture.Standing;
bool conditionD = (pawn.GetPosture() == PawnPosture.LayingOnGroundNormal || pawn.GetPosture() == PawnPosture.LayingOnGroundFaceUp) && bodyAddon.drawnOnGround;
bool conditionE = pawn.GetPosture() == PawnPosture.LayingInBed && bodyAddon.drawnInBed;
return (conditionA || conditionB) && (conditionC || conditionD || conditionE);
}
}
}
return false;
} }
// Replacement patch for AlienRace to draw the body addons // Replacement patch for AlienRace to draw the body addons
public static bool Prefix_DrawAddons(PawnRenderFlags renderFlags, Vector3 vector, Vector3 headOffset, Pawn pawn, Quaternion quat, Rot4 rotation) public static bool Prefix_DrawAddons(PawnRenderFlags renderFlags, Vector3 vector, Vector3 headOffset, Pawn pawn, Quaternion quat, Rot4 rotation)
{ {
if (!(pawn.def is ThingDef_AlienRace alienProps) || renderFlags.FlagSet(PawnRenderFlags.Invisible)) if (!(pawn.def is ThingDef_AlienRace alienProps) || renderFlags.FlagSet(PawnRenderFlags.Invisible)) return false;
{ return false; }
// Try to draw apparel thrown on ground // Try to draw apparel thrown on ground
if (ApparelSettings.clothesThrownOnGround) if (ApparelSettings.clothesThrownOnGround)
@ -198,14 +130,19 @@ namespace Rimworld_Animations_Patch
for (int idx = 0; idx < idxBodyAddons.Count; idx++) for (int idx = 0; idx < idxBodyAddons.Count; idx++)
{ {
int i = idxBodyAddons[idx]; int i = idxBodyAddons[idx];
AlienPartGenerator.BodyAddon bodyAddon = bodyAddons[i];
BodyPartRecord bodyPartRecord = AnimationPatchUtility.GetBodyPartRecord(pawn, bodyAddon.bodyPart);
AlienPartGenerator.BodyAddon bodyAddon = bodyAddons[i];
Graphic addonGraphic = alienComp.addonGraphics[i];
bool canDraw = addonGraphic.path.ToLower().Contains("featureless") == false && bodyAddon.CanDrawAddon(pawn);
bool drawHand = !renderFlags.FlagSet(PawnRenderFlags.Portrait) && BasicSettings.showHands && handsAvailableCount > 0 && HandAnimationUtility.BodyPartIsBeingTouched(pawn, addonGraphic.path, out var handData);
if (canDraw == false && drawHand == false)
{ continue; }
BodyPartRecord bodyPartRecord = AnimationPatchUtility.GetBodyPartRecord(pawn, bodyAddon.bodyPart);
bool alignWithHead = bodyAddon.alignWithHead || (bodyPartRecord != null && bodyPartRecord.IsInGroup(BodyPartGroupDefOf.FullHead)); bool alignWithHead = bodyAddon.alignWithHead || (bodyPartRecord != null && bodyPartRecord.IsInGroup(BodyPartGroupDefOf.FullHead));
Graphic addonGraphic = alienComp.addonGraphics[i];
//DebugMode.Message(" Trying to draw " + addonGraphic.path);
Rot4 apparentRotation = rotation; Rot4 apparentRotation = rotation;
if (!renderFlags.FlagSet(PawnRenderFlags.Portrait) && pawnAnimator != null && pawnAnimator.isAnimating) if (!renderFlags.FlagSet(PawnRenderFlags.Portrait) && pawnAnimator != null && pawnAnimator.isAnimating)
{ apparentRotation = alignWithHead ? pawnAnimator.headFacing : pawnAnimator.bodyFacing; } { apparentRotation = alignWithHead ? pawnAnimator.headFacing : pawnAnimator.bodyFacing; }
@ -216,8 +153,7 @@ namespace Rimworld_Animations_Patch
Vector3 vector2 = bodyTypeOffset + ((offsets != null) ? offsets.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, alienComp.crownType) : Vector3.zero); Vector3 vector2 = bodyTypeOffset + ((offsets != null) ? offsets.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, alienComp.crownType) : Vector3.zero);
// Offset private parts so that they render over tattoos but under apparel (rendering under tatoos looks weird) // Offset private parts so that they render over tattoos but under apparel (rendering under tatoos looks weird)
if ((bodyPartRecord != null && (bodyPartRecord.IsInGroup(PatchBodyPartGroupDefOf.GenitalsBPG) || bodyPartRecord.IsInGroup(PatchBodyPartGroupDefOf.ChestBPG) || bodyPartRecord.IsInGroup(PatchBodyPartGroupDefOf.AnusBPG))) || if ((bodyPartRecord != null && (bodyPartRecord.IsInGroup(PatchBodyPartGroupDefOf.GenitalsBPG) || bodyPartRecord.IsInGroup(PatchBodyPartGroupDefOf.ChestBPG) || bodyPartRecord.IsInGroup(PatchBodyPartGroupDefOf.AnusBPG))) || addonGraphic.path.ToLower().Contains("belly"))
addonGraphic.path.ToLower().Contains("belly"))
{ {
vector2.y = (vector2.y + 0.40f) / 1000f + 0.012f; vector2.y = (vector2.y + 0.40f) / 1000f + 0.012f;
@ -225,7 +161,6 @@ namespace Rimworld_Animations_Patch
if (pawn.RaceProps.Humanlike && if (pawn.RaceProps.Humanlike &&
addonGraphic.path.ToLower().Contains("penis") && addonGraphic.path.ToLower().Contains("penis") &&
addonGraphic.path.ToLower().Contains("flaccid") == false && addonGraphic.path.ToLower().Contains("flaccid") == false &&
BodyAddonCoveredByWornApparel(pawn, bodyAddon) == false &&
apparentRotation == Rot4.South) apparentRotation == Rot4.South)
{ vector2.y += 0.010f; } { vector2.y += 0.010f; }
} }
@ -289,7 +224,7 @@ namespace Rimworld_Animations_Patch
finalAngle = bodyAngle; finalAngle = bodyAngle;
} }
} }
// Fixes 'leaning left' issue with Yayo's animations // Fixes 'leaning left' issue with Yayo's animations
else if (!renderFlags.FlagSet(PawnRenderFlags.Portrait) && (pawnAnimator == null || pawnAnimator.isAnimating == false)) else if (!renderFlags.FlagSet(PawnRenderFlags.Portrait) && (pawnAnimator == null || pawnAnimator.isAnimating == false))
{ {
@ -302,26 +237,29 @@ namespace Rimworld_Animations_Patch
{ vector2 -= pawn.Drawer.renderer.BaseHeadOffsetAt(apparentRotation); } { vector2 -= pawn.Drawer.renderer.BaseHeadOffsetAt(apparentRotation); }
Vector3 finalPosition = vector + (alignWithHead ? headOffset : Vector3.zero) + vector2.RotatedBy(angle: Mathf.Acos(f: Quaternion.Dot(a: Quaternion.identity, b: addonRotation)) * 2f * 57.29578f); Vector3 finalPosition = vector + (alignWithHead ? headOffset : Vector3.zero) + vector2.RotatedBy(angle: Mathf.Acos(f: Quaternion.Dot(a: Quaternion.identity, b: addonRotation)) * 2f * 57.29578f);
// Draw the addon if visible // Draw the addon if visible
if (CanDrawAddon(pawn, bodyAddon)) if (canDraw)
{ {
//DebugMode.Message("Drawing " + addonGraphic.path);
GenDraw.DrawMeshNowOrLater(mesh: addonGraphic.MeshAt(rot: apparentRotation), GenDraw.DrawMeshNowOrLater(mesh: addonGraphic.MeshAt(rot: apparentRotation),
loc: finalPosition, loc: finalPosition,
quat: Quaternion.AngleAxis(angle: bodyAddonAngle, axis: Vector3.up) * quatAdditional * addonRotation, quat: Quaternion.AngleAxis(angle: bodyAddonAngle, axis: Vector3.up) * quatAdditional * addonRotation,
mat: addonGraphic.MatAt(rot: apparentRotation), renderFlags.FlagSet(PawnRenderFlags.DrawNow)); mat: addonGraphic.MatAt(rot: apparentRotation),
drawNow: renderFlags.FlagSet(PawnRenderFlags.DrawNow));
} }
// Draw hand over the body part if required // Draw hand over the body part if required
if (BasicSettings.showHands && !renderFlags.FlagSet(PawnRenderFlags.Portrait) && handsAvailableCount > 0) if (drawHand)
{ {
if (HandAnimationUtility.TryToDrawHand(pawn, addonGraphic.path, finalPosition, finalAngle, rotation, renderFlags)) if (HandAnimationUtility.TryToDrawHand(pawn, addonGraphic.path, finalPosition, finalAngle, rotation, renderFlags))
{ handsAvailableCount--; } { handsAvailableCount--; }
} }
} }
// Body addons are sometimes are not appropriately concealed by long hair, so re-draw the pawn's hair here // 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) if (pawn.Drawer.renderer.graphics.headGraphic != null && renderFlags.FlagSet(PawnRenderFlags.Portrait) && BasicSettings.redrawHair)
{ {
var methodInfo = AccessTools.Method(typeof(PawnRenderer), "DrawHeadHair", null, null); var methodInfo = AccessTools.Method(typeof(PawnRenderer), "DrawHeadHair", null, null);

View File

@ -82,8 +82,9 @@ namespace Rimworld_Animations_Patch
{ {
foreach (Pawn pawn in Current.Game.CurrentMap.mapPawns.AllPawns) foreach (Pawn pawn in Current.Game.CurrentMap.mapPawns.AllPawns)
{ {
if (pawn.RaceProps.Humanlike && pawn.apparel.WornApparel.NullOrEmpty() == false) pawn.Drawer.renderer.graphics.ResolveAllGraphics();
{ pawn.Drawer.renderer.graphics.ResolveAllGraphics(); } PortraitsCache.SetDirty(pawn);
GlobalTextureAtlasManager.TryMarkPawnFrameSetDirty(pawn);
} }
} }
} }
@ -150,7 +151,6 @@ namespace Rimworld_Animations_Patch
int num = 0; int num = 0;
bool isEnabled = false; bool isEnabled = false;
bool linkChangesChanged = false;
// Get a list of apparel of interest // Get a list of apparel of interest
if (thingDefs.NullOrEmpty()) if (thingDefs.NullOrEmpty())
@ -281,7 +281,6 @@ namespace Rimworld_Animations_Patch
foreach (ThingDef thingDef in thingDefs) foreach (ThingDef thingDef in thingDefs)
{ {
isEnabled = false; isEnabled = false;
bool changeHappened = false;
innerX = 0; innerX = 0;
innerY = (float)num * (rowHeight); innerY = (float)num * (rowHeight);
@ -303,7 +302,6 @@ namespace Rimworld_Animations_Patch
{ {
isEnabled = rimNudeApparel.coversGroin; isEnabled = rimNudeApparel.coversGroin;
Widgets.Checkbox(innerX + SettingsUtility.Align(checkboxSize, singleColumnWidth), innerY + SettingsUtility.Align(checkboxSize, rowHeight), ref isEnabled, checkboxSize, false, true, null, null); Widgets.Checkbox(innerX + SettingsUtility.Align(checkboxSize, singleColumnWidth), innerY + SettingsUtility.Align(checkboxSize, rowHeight), ref isEnabled, checkboxSize, false, true, null, null);
if (isEnabled != rimNudeApparel.coversGroin) { changeHappened = true; }
rimNudeApparel.coversGroin = isEnabled; rimNudeApparel.coversGroin = isEnabled;
}; innerX += singleColumnWidth; }; innerX += singleColumnWidth;
@ -312,7 +310,6 @@ namespace Rimworld_Animations_Patch
{ {
isEnabled = rimNudeApparel.coversBelly; isEnabled = rimNudeApparel.coversBelly;
Widgets.Checkbox(innerX + SettingsUtility.Align(checkboxSize, singleColumnWidth), innerY + SettingsUtility.Align(checkboxSize, rowHeight), ref isEnabled, checkboxSize, false, true, null, null); Widgets.Checkbox(innerX + SettingsUtility.Align(checkboxSize, singleColumnWidth), innerY + SettingsUtility.Align(checkboxSize, rowHeight), ref isEnabled, checkboxSize, false, true, null, null);
if (isEnabled != rimNudeApparel.coversBelly) { changeHappened = true; }
rimNudeApparel.coversBelly = isEnabled; rimNudeApparel.coversBelly = isEnabled;
}; innerX += singleColumnWidth; }; innerX += singleColumnWidth;
@ -321,29 +318,14 @@ namespace Rimworld_Animations_Patch
{ {
isEnabled = rimNudeApparel.coversChest; isEnabled = rimNudeApparel.coversChest;
Widgets.Checkbox(innerX + SettingsUtility.Align(checkboxSize, singleColumnWidth), innerY + SettingsUtility.Align(checkboxSize, rowHeight), ref isEnabled, checkboxSize, false, true, null, null); Widgets.Checkbox(innerX + SettingsUtility.Align(checkboxSize, singleColumnWidth), innerY + SettingsUtility.Align(checkboxSize, rowHeight), ref isEnabled, checkboxSize, false, true, null, null);
if (isEnabled != rimNudeApparel.coversChest) { changeHappened = true; }
rimNudeApparel.coversChest = isEnabled; rimNudeApparel.coversChest = isEnabled;
}; innerX += singleColumnWidth; }; innerX += singleColumnWidth;
// Is sex-wear checkbox // Is sex-wear checkbox
isEnabled = rimNudeApparel.sexWear; isEnabled = rimNudeApparel.sexWear;
Widgets.Checkbox(innerX + SettingsUtility.Align(checkboxSize, singleColumnWidth), innerY + SettingsUtility.Align(checkboxSize, rowHeight), ref isEnabled, checkboxSize, false, true, null, null); Widgets.Checkbox(innerX + SettingsUtility.Align(checkboxSize, singleColumnWidth), innerY + SettingsUtility.Align(checkboxSize, rowHeight), ref isEnabled, checkboxSize, false, true, null, null);
if (isEnabled != rimNudeApparel.sexWear) { changeHappened = true; }
rimNudeApparel.sexWear = isEnabled; rimNudeApparel.sexWear = isEnabled;
innerX += singleColumnWidth; innerX += singleColumnWidth;
// Update other body types if linked changed are enabled
if (BasicSettings.linkChanges && (changeHappened || linkChangesChanged))
{
for (int i = 0; i < 5; i++)
{
RimNudeData _rimNudeApparel = ApparelSettings.rimNudeData.First(x => x.EquivalentTo(new RimNudeData(thingDef)));
_rimNudeApparel.coversGroin = rimNudeApparel.coversGroin;
_rimNudeApparel.coversBelly = rimNudeApparel.coversBelly;
_rimNudeApparel.coversChest = rimNudeApparel.coversChest;
_rimNudeApparel.sexWear = rimNudeApparel.sexWear;
}
}
} }
Widgets.EndScrollView(); Widgets.EndScrollView();

View File

@ -3,6 +3,7 @@ using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using Verse; using Verse;
using RimWorld;
namespace Rimworld_Animations_Patch namespace Rimworld_Animations_Patch
{ {
@ -16,6 +17,7 @@ namespace Rimworld_Animations_Patch
public static bool hideNamesForSex = false; public static bool hideNamesForSex = false;
public static bool debugMode = false; public static bool debugMode = false;
public static bool showHands = true; public static bool showHands = true;
public static bool redrawHair = true;
public static bool worryAboutInfidelity = true; public static bool worryAboutInfidelity = true;
public static bool worryAboutBeastiality = true; public static bool worryAboutBeastiality = true;
@ -42,6 +44,7 @@ namespace Rimworld_Animations_Patch
Scribe_Values.Look(ref hideNamesForSex, "hideNamesForSex", false); Scribe_Values.Look(ref hideNamesForSex, "hideNamesForSex", false);
Scribe_Values.Look(ref debugMode, "debugMode", false); Scribe_Values.Look(ref debugMode, "debugMode", false);
Scribe_Values.Look(ref showHands, "showHands", true); Scribe_Values.Look(ref showHands, "showHands", true);
Scribe_Values.Look(ref redrawHair, "redrawHair", true);
Scribe_Values.Look(ref worryAboutInfidelity, "worryAboutInfidelity", true); Scribe_Values.Look(ref worryAboutInfidelity, "worryAboutInfidelity", true);
Scribe_Values.Look(ref worryAboutBeastiality, "worryAboutBeastiality", true); Scribe_Values.Look(ref worryAboutBeastiality, "worryAboutBeastiality", true);
Scribe_Values.Look(ref worryAboutRape, "worryAboutRape", true); Scribe_Values.Look(ref worryAboutRape, "worryAboutRape", true);
@ -73,8 +76,9 @@ namespace Rimworld_Animations_Patch
{ {
foreach (Pawn pawn in Current.Game.CurrentMap.mapPawns.AllPawns) foreach (Pawn pawn in Current.Game.CurrentMap.mapPawns.AllPawns)
{ {
if (pawn.RaceProps.Humanlike && pawn.apparel.WornApparel.NullOrEmpty() == false) pawn.Drawer.renderer.graphics.ResolveAllGraphics();
{ pawn.Drawer.renderer.graphics.ResolveAllGraphics(); } PortraitsCache.SetDirty(pawn);
GlobalTextureAtlasManager.TryMarkPawnFrameSetDirty(pawn);
} }
} }
} }
@ -105,6 +109,7 @@ namespace Rimworld_Animations_Patch
listingStandard.Label("chance_for_other_to_join_in_sex".Translate() + ": " + BasicSettings.chanceForOtherToJoinInSex.ToString("F"), -1f, "chance_for_other_to_join_in_sex_desc".Translate()); listingStandard.Label("chance_for_other_to_join_in_sex".Translate() + ": " + BasicSettings.chanceForOtherToJoinInSex.ToString("F"), -1f, "chance_for_other_to_join_in_sex_desc".Translate());
BasicSettings.chanceForOtherToJoinInSex = listingStandard.Slider(BasicSettings.chanceForOtherToJoinInSex, 0f, 1f); BasicSettings.chanceForOtherToJoinInSex = listingStandard.Slider(BasicSettings.chanceForOtherToJoinInSex, 0f, 1f);
listingStandard.CheckboxLabeled("hide_names_for_sex".Translate(), ref BasicSettings.hideNamesForSex, "hide_names_for_sex_desc".Translate()); listingStandard.CheckboxLabeled("hide_names_for_sex".Translate(), ref BasicSettings.hideNamesForSex, "hide_names_for_sex_desc".Translate());
listingStandard.CheckboxLabeled("debug_mode".Translate(), ref BasicSettings.debugMode, "debug_mode_desc".Translate()); listingStandard.CheckboxLabeled("debug_mode".Translate(), ref BasicSettings.debugMode, "debug_mode_desc".Translate());
@ -114,6 +119,7 @@ namespace Rimworld_Animations_Patch
listingStandard.CheckboxLabeled("autoscale_delta_pos".Translate(), ref BasicSettings.autoscaleDeltaPos, "autoscale_delta_pos_desc".Translate()); listingStandard.CheckboxLabeled("autoscale_delta_pos".Translate(), ref BasicSettings.autoscaleDeltaPos, "autoscale_delta_pos_desc".Translate());
listingStandard.CheckboxLabeled("show_hands".Translate(), ref BasicSettings.showHands, "show_hands_desc".Translate()); listingStandard.CheckboxLabeled("show_hands".Translate(), ref BasicSettings.showHands, "show_hands_desc".Translate());
listingStandard.CheckboxLabeled("redraw_hair".Translate(), ref BasicSettings.redrawHair, "redraw_hair_desc".Translate());
listingStandard.End(); listingStandard.End();
base.DoSettingsWindowContents(inRect); base.DoSettingsWindowContents(inRect);

View File

@ -15,14 +15,14 @@ namespace Rimworld_Animations_Patch
public static void TryToDrawApparelOnFloor(Pawn pawn) public static void TryToDrawApparelOnFloor(Pawn pawn)
{ {
if (pawn?.apparel?.WornApparel != null) if (pawn?.apparel?.WornApparel != null)
{ {
CompBodyAnimator compBodyAnimator = pawn.TryGetComp<CompBodyAnimator>(); CompBodyAnimator compBodyAnimator = pawn.TryGetComp<CompBodyAnimator>();
if (ApparelSettings.clothesThrownOnGround == false || Find.CurrentMap != pawn.Map || compBodyAnimator == null || compBodyAnimator.isAnimating == false) if (ApparelSettings.clothesThrownOnGround == false || Find.CurrentMap != pawn.Map || compBodyAnimator == null || compBodyAnimator.isAnimating == false)
{ return; } { return; }
foreach (Apparel apparel in pawn.apparel.WornApparel) foreach (Apparel apparel in pawn.apparel.WornApparel)
{ {
CompApparelVisibility compApparelVisibility = apparel.TryGetComp<CompApparelVisibility>(); CompApparelVisibility compApparelVisibility = apparel.TryGetComp<CompApparelVisibility>();
@ -40,64 +40,48 @@ namespace Rimworld_Animations_Patch
apparelGraphic.drawSize.x *= 1f / apparelScale; apparelGraphic.drawSize.x *= 1f / apparelScale;
apparelGraphic.drawSize.y *= 1f / apparelScale; apparelGraphic.drawSize.y *= 1f / apparelScale;
DebugMode.Message(compApparelVisibility.rotation.ToString());
//DebugMode.Message("Drawing " + apparel.def.defName + " on ground"); //DebugMode.Message("Drawing " + apparel.def.defName + " on ground");
} }
} }
} }
} }
public static bool BodyAddonCoveredByApparel(Apparel apparel, AlienPartGenerator.BodyAddon bodyAddon) public static bool PrivatePartCoveredByApparel(Apparel apparel, string bodyPart)
{ {
CompApparelVisibility comp = apparel.TryGetComp<CompApparelVisibility>(); CompApparelVisibility comp = apparel.TryGetComp<CompApparelVisibility>();
if (comp != null && comp.isBeingWorn == false) if (comp == null || comp.rimNudeDataStatus == RimNudeDataStatus.Unavailable)
{ return false; } { return false; }
RimNudeData rimNudeData = ApparelSettings.GetRimNudeData(apparel); if (comp.rimNudeDataStatus == RimNudeDataStatus.NotLoaded)
if (rimNudeData != null && bodyAddon?.bodyPart != null)
{ {
if (bodyAddon.bodyPart == "Genitals" && rimNudeData.coversGroin == false) RimNudeData rimNudeData = ApparelSettings.GetRimNudeData(apparel);
{ return false; }
if (bodyAddon.bodyPart == "Chest" && rimNudeData.coversChest == false) if (rimNudeData == null)
{ return false; } {
comp.rimNudeDataStatus = RimNudeDataStatus.Unavailable;
return false;
}
if (bodyAddon.bodyPart == "Torso" && rimNudeData.coversBelly == false) comp.coversBelly = rimNudeData.coversBelly;
{ return false; } comp.coversChest = rimNudeData.coversChest;
comp.coversGroin = rimNudeData.coversGroin;
comp.rimNudeDataStatus = RimNudeDataStatus.Loaded;
} }
if (apparel.def.apparel.bodyPartGroups.Any(x => bodyAddon.hiddenUnderApparelFor.Contains(x)) || if (comp.isBeingWorn == false)
apparel.def.apparel.tags.Any(x => bodyAddon.hiddenUnderApparelTag.Contains(x)))
{ return true; }
return false;
}
public static bool BodyPartCoveredByApparel(Apparel apparel, BodyPartRecord bodyPart)
{
CompApparelVisibility comp = apparel.TryGetComp<CompApparelVisibility>();
if (comp != null && comp.isBeingWorn == false)
{ return false; } { return false; }
RimNudeData rimNudeData = ApparelSettings.GetRimNudeData(apparel); if (bodyPart == "Genitals")
{ return comp.coversGroin; }
if (rimNudeData != null) if (bodyPart == "Chest")
{ { return comp.coversChest; }
if (bodyPart.def.defName == "Genitals" && rimNudeData.coversGroin == false)
{ return false; }
if (bodyPart.def.defName == "Chest" && rimNudeData.coversChest == false) if (bodyPart == "Torso")
{ return false; } { return comp.coversBelly; }
if (bodyPart.def.defName == "Torso" && rimNudeData.coversBelly == false)
{ return false; }
}
if (apparel.def.apparel.CoversBodyPart(bodyPart))
{ return true; }
return false; return false;
} }
@ -109,9 +93,10 @@ namespace Rimworld_Animations_Patch
if (pawn.RaceProps.Humanlike == false || pawn?.apparel?.WornApparel == null || jobdriver == null) if (pawn.RaceProps.Humanlike == false || pawn?.apparel?.WornApparel == null || jobdriver == null)
{ return; } { return; }
foreach (Apparel apparel in pawn.apparel?.WornApparel) foreach (Apparel apparel in pawn.apparel.WornApparel)
{ {
CompApparelVisibility comp = apparel.TryGetComp<CompApparelVisibility>(); CompApparelVisibility comp = apparel.TryGetComp<CompApparelVisibility>();
if (comp != null) if (comp != null)
{ comp.isBeingWorn = true; } { comp.isBeingWorn = true; }
} }
@ -177,19 +162,19 @@ namespace Rimworld_Animations_Patch
{ requiredGenitals = new List<string>(); } { requiredGenitals = new List<string>(); }
if (anim.actors[actorID].isFucking || requiredGenitals.Contains("Penis")) if (anim.actors[actorID].isFucking || requiredGenitals.Contains("Penis"))
{ bodyPartCovered = bodyPartCovered || BodyPartCoveredByApparel(apparel, bodyParts.FirstOrDefault(x => x.def == xxx.genitalsDef)); } { bodyPartCovered = bodyPartCovered || PrivatePartCoveredByApparel(apparel, "Genitals"); }
if (anim.actors[actorID].isFucked || requiredGenitals.Contains("Vagina")) if (anim.actors[actorID].isFucked || requiredGenitals.Contains("Vagina"))
{ bodyPartCovered = bodyPartCovered || BodyPartCoveredByApparel(apparel, bodyParts.FirstOrDefault(x => x.def == xxx.genitalsDef)); } { bodyPartCovered = bodyPartCovered || PrivatePartCoveredByApparel(apparel, "Genitals"); }
if (anim.actors[actorID].isFucked || requiredGenitals.Contains("Anus")) if (anim.actors[actorID].isFucked || requiredGenitals.Contains("Anus"))
{ bodyPartCovered = bodyPartCovered || BodyPartCoveredByApparel(apparel, bodyParts.FirstOrDefault(x => x.def == xxx.anusDef)); } { bodyPartCovered = bodyPartCovered || PrivatePartCoveredByApparel(apparel, "Genitals"); }
if (requiredGenitals.Contains("Breasts")) if (requiredGenitals.Contains("Breasts"))
{ bodyPartCovered = bodyPartCovered || BodyPartCoveredByApparel(apparel, bodyParts.FirstOrDefault(x => x.def == xxx.breastsDef)); } { bodyPartCovered = bodyPartCovered || PrivatePartCoveredByApparel(apparel, "Chest"); }
if (requiredGenitals.Contains("Mouth")) if (requiredGenitals.Contains("Mouth"))
{ bodyPartCovered = bodyPartCovered || BodyPartCoveredByApparel(apparel, bodyParts.FirstOrDefault(x => x.def.defName.ToLower().ContainsAny("mouth", "teeth", "jaw", "beak"))); } { bodyPartCovered = bodyPartCovered || apparel.def.apparel.CoversBodyPart(bodyParts.FirstOrDefault(x => x.def.defName.ToLower().ContainsAny("mouth", "teeth", "jaw", "beak"))); }
return bodyPartCovered; return bodyPartCovered;
} }

View File

@ -14,9 +14,6 @@ namespace Rimworld_Animations_Patch
foreach (ThingDef thingDef in DefDatabase<ThingDef>.AllDefs) foreach (ThingDef thingDef in DefDatabase<ThingDef>.AllDefs)
{ {
if (thingDef.IsApparel && thingDef.apparel.layers.Count == 1 && thingDef.apparel.layers[0] == ApparelLayerDefOf.Belt)
{ continue; }
if (thingDef.IsApparel && if (thingDef.IsApparel &&
(thingDef.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Torso) || (thingDef.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Torso) ||
thingDef.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Legs) || thingDef.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Legs) ||

View File

@ -16,8 +16,11 @@ namespace Rimworld_Animations_Patch
public static bool BodyPartIsBeingTouched(Pawn pawn, string bodypartFilePath, out List<HandAnimationData> handAnimationData) public static bool BodyPartIsBeingTouched(Pawn pawn, string bodypartFilePath, out List<HandAnimationData> handAnimationData)
{ {
handAnimationData = new List<HandAnimationData>(); handAnimationData = new List<HandAnimationData>();
ActorAnimationData actorAnimationData = pawn.GetAnimationData(); ActorAnimationData actorAnimationData = pawn.GetAnimationData();
if (actorAnimationData == null)
{ return false; }
HandAnimationDef handAnimationDef = DefDatabase<HandAnimationDef>.AllDefs.FirstOrDefault(x => x.animationDefName == actorAnimationData.animationDef.defName); HandAnimationDef handAnimationDef = DefDatabase<HandAnimationDef>.AllDefs.FirstOrDefault(x => x.animationDefName == actorAnimationData.animationDef.defName);
if (handAnimationDef == null) if (handAnimationDef == null)
@ -47,13 +50,13 @@ namespace Rimworld_Animations_Patch
if (methodInfo == null) if (methodInfo == null)
{ {
Debug.LogWarning("Hand anaimation motion '" + handAnimationData.motion + "' was not found"); Debug.LogWarning("Hand animation motion '" + handAnimationData.motion + "' was not found");
return default; return default;
} }
Vector3 handPosition = (Vector3)methodInfo.Invoke(null, new object[] { pawn, handAnimationData, baseAngle }); Vector3 handPosition = (Vector3)methodInfo.Invoke(null, new object[] { pawn, handAnimationData, baseAngle });
return handPosition * pawn.RaceProps.baseBodySize + basePosition; return handPosition * pawn.RaceProps.baseBodySize + basePosition + new Vector3(0f, 0.3f, 0f);
} }
public static float GetGenitalSize(Pawn pawn, string genitalName) public static float GetGenitalSize(Pawn pawn, string genitalName)
@ -195,7 +198,7 @@ namespace Rimworld_Animations_Patch
public static bool TryToDrawHand(Pawn pawn, string bodyAddonName, Vector3 bodyAddonPosition, float bodyAddonAngle, Rot4 bodyAddonRotation, PawnRenderFlags renderFlags) public static bool TryToDrawHand(Pawn pawn, string bodyAddonName, Vector3 bodyAddonPosition, float bodyAddonAngle, Rot4 bodyAddonRotation, PawnRenderFlags renderFlags)
{ {
if (pawn.TryGetComp<CompBodyAnimator>() != null && pawn.TryGetComp<CompBodyAnimator>().isAnimating && BodyPartIsBeingTouched(pawn, bodyAddonName, out List<HandAnimationData> handAnimationData)) if (BodyPartIsBeingTouched(pawn, bodyAddonName, out List<HandAnimationData> handAnimationData))
{ {
foreach (HandAnimationData datum in handAnimationData) foreach (HandAnimationData datum in handAnimationData)
{ {

View File

@ -3,5 +3,4 @@ C:\Program Files (x86)\Steam\SteamApps\common\RimWorld\Mods\rimworld-animations-
C:\Program Files (x86)\Steam\SteamApps\common\RimWorld\Mods\rimworld-animations-patch-abscon\1.3\Assemblies\Rimworld-Animations-Patch.pdb C:\Program Files (x86)\Steam\SteamApps\common\RimWorld\Mods\rimworld-animations-patch-abscon\1.3\Assemblies\Rimworld-Animations-Patch.pdb
C:\Program Files (x86)\Steam\SteamApps\common\RimWorld\Mods\rimworld-animations-patch-abscon\Source\obj\Debug\Rimworld-Animations-Patch.dll C:\Program Files (x86)\Steam\SteamApps\common\RimWorld\Mods\rimworld-animations-patch-abscon\Source\obj\Debug\Rimworld-Animations-Patch.dll
C:\Program Files (x86)\Steam\SteamApps\common\RimWorld\Mods\rimworld-animations-patch-abscon\Source\obj\Debug\Rimworld-Animations-Patch.pdb C:\Program Files (x86)\Steam\SteamApps\common\RimWorld\Mods\rimworld-animations-patch-abscon\Source\obj\Debug\Rimworld-Animations-Patch.pdb
C:\Program Files (x86)\Steam\SteamApps\common\RimWorld\Mods\rimworld-animations-patch-abscon\Source\obj\Debug\Rimworld-Animations-Patch.csproj.CopyComplete
C:\Program Files (x86)\Steam\SteamApps\common\RimWorld\Mods\rimworld-animations-patch-abscon\Source\obj\Debug\Rimworld-Animations-Patch.csprojAssemblyReference.cache C:\Program Files (x86)\Steam\SteamApps\common\RimWorld\Mods\rimworld-animations-patch-abscon\Source\obj\Debug\Rimworld-Animations-Patch.csprojAssemblyReference.cache