Updated to refactored quirk removal

Updated to parity with quirk removal updates that added helper functions
This commit is contained in:
Matthew 2023-02-20 15:50:53 -05:00
parent 7585da099c
commit be5f2bdf9a
17 changed files with 151 additions and 395 deletions

Binary file not shown.

View File

@ -1,64 +0,0 @@
using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace rjwquirks.Data
{
public class RaceTags
{
private readonly static Dictionary<string, RaceTags> tagDatabase = new Dictionary<string, RaceTags>();
// I only created tags for RaceGroupDef properties that seemed like keywords (like slime) rather than behavior (like oviPregnancy).
public readonly static RaceTags Chitin = new RaceTags("Chitin");
public readonly static RaceTags Demon = new RaceTags("Demon");
public readonly static RaceTags Feathers = new RaceTags("Feathers");
public readonly static RaceTags Fur = new RaceTags("Fur");
public readonly static RaceTags Plant = new RaceTags("Plant");
public readonly static RaceTags Robot = new RaceTags("Robot");
public readonly static RaceTags Scales = new RaceTags("Scales");
public readonly static RaceTags Skin = new RaceTags("Skin");
public readonly static RaceTags Slime = new RaceTags("Slime");
public string Key { get; }
private RaceTags(string key)
{
Key = key;
tagDatabase.Add(key, this);
}
public static bool TryParse(string key, out RaceTags raceTag)
{
return tagDatabase.TryGetValue(key, out raceTag);
}
/// <summary>
/// For backwards compatability only. Shouldn't add more special cases here.
/// </summary>
public bool DefaultWhenNoRaceGroupDef(Pawn pawn)
{
if (this == Demon)
{
return xxx.is_demon(pawn);
}
else if (this == Slime)
{
return xxx.is_slime(pawn);
}
else if (this == Skin)
{
return true;
}
else
{
return false;
}
}
}
}

View File

@ -49,10 +49,10 @@ namespace rjwquirks.HarmonyPatches
// Readd the 30 score removed in regular RJW
__result += 30;
// Readd the 100 score taken from being in a doorway in regular RJW
__result += 100;
if (room.IsDoorway) __result += 100;
if (might_be_seen)
__result += 5;
__result += 35;
else
__result -= 10;

View File

@ -18,8 +18,7 @@ namespace rjwquirks.HarmonyPatches
[HarmonyPatch(nameof(CondomUtility.TryUseCondom))]
public static bool UseCondomPrefix(Pawn pawn)
{
if (xxx.is_human(pawn) && pawn.HasQuirk(QuirkDefOf.ImpregnationFetish))
return false;
if (xxx.is_human(pawn) && pawn.HasQuirk(QuirkDefOf.ImpregnationFetish)) return false;
return true;
}
@ -28,8 +27,7 @@ namespace rjwquirks.HarmonyPatches
[HarmonyPatch(nameof(CondomUtility.GetCondomFromRoom))]
public static bool GetCondomPrefix(Pawn pawn)
{
if (xxx.is_human(pawn) && pawn.HasQuirk(QuirkDefOf.ImpregnationFetish))
return false;
if (xxx.is_human(pawn) && pawn.HasQuirk(QuirkDefOf.ImpregnationFetish)) return false;
return true;
}

View File

@ -1,24 +0,0 @@
using HarmonyLib;
using rjw;
using rjwquirks.Modules.Quirks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace rjwquirks.HarmonyPatches
{
[HarmonyPatch(typeof(SexUtility), nameof(SexUtility.DrawNude))]
public class Patch_DrawNude
{
public static bool Prefix(Pawn pawn)
{
if (pawn.HasQuirk(QuirkDefOf.Endytophile))
return false;
return true;
}
}
}

View File

@ -1,35 +0,0 @@
using HarmonyLib;
using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace rjwquirks.HarmonyPatches
{
/*[HarmonyPatch(typeof(Hediff_BasePregnancy))]
public class Patch_Hediff_BasePregnancy
{
[HarmonyTranspiler]
[HarmonyPatch("GenerateBabies")]
public static IEnumerable<CodeInstruction> AdjustMaxLitterSize(IEnumerable<CodeInstruction> instructions)
{
bool found = false;
foreach (CodeInstruction i in instructions)
{
if (i.opcode == OpCodes.Ldc_R4 && i.operand as string == "0.33333334")
found = true;
if (found && i.opcode == OpCodes.Stloc_S)
Log.Warning(i.operand as string);
yield return i;
}
}
}*/
}

View File

@ -1,43 +0,0 @@
using HarmonyLib;
using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace rjwquirks.HarmonyPatches
{
[HarmonyPatch(typeof(Hediff_PartBaseArtifical))]
public class Patch_Hediff_PartBaseArtifical
{
[HarmonyTranspiler]
[HarmonyPatch(nameof(Hediff_PartBaseArtifical.Tick))]
public static IEnumerable<CodeInstruction> ChangeMaxEggsSize(IEnumerable<CodeInstruction> instructions)
{
FieldInfo Pawn = AccessTools.Field(typeof(Hediff_PartBaseArtifical), nameof(Hediff_PartBaseArtifical.pawn));
MethodInfo EggSize = AccessTools.Method(typeof(Patch_Hediff_PartBaseArtifical), nameof(EditMaxEggsSize));
foreach (CodeInstruction i in instructions)
{
if (i.opcode == OpCodes.Ldc_R4 && i.operand as string == "0.0")
{
yield return new CodeInstruction(OpCodes.Ldfld, Pawn);
yield return new CodeInstruction(OpCodes.Ldloc_3);
yield return new CodeInstruction(OpCodes.Call, EggSize);
}
yield return i;
}
}
public static void EditMaxEggsSize(Pawn pawn, float eggsSize)
{
if (pawn.GetQuirks() != null)
pawn.GetQuirks().ApplyValueModifiers("maxEggsSize", ref eggsSize);
}
}
}

View File

@ -1,47 +0,0 @@
using HarmonyLib;
using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace rjwquirks.HarmonyPatches
{
[HarmonyPatch(typeof(Hediff_PartBaseNatural))]
public class Patch_Hediff_PartBaseNatural
{
[HarmonyTranspiler]
[HarmonyPatch(nameof(Hediff_PartBaseNatural.Tick))]
public static IEnumerable<CodeInstruction> ChangeMaxEggsSize(IEnumerable<CodeInstruction> instructions)
{
FieldInfo Pawn = AccessTools.Field(typeof(Hediff_PartBaseNatural), nameof(Hediff_PartBaseNatural.pawn));
MethodInfo EggSize = AccessTools.Method(typeof(Patch_Hediff_PartBaseNatural), nameof(EditMaxEggsSize));
bool found = false;
foreach (CodeInstruction i in instructions)
{
if (i.opcode == OpCodes.Ldc_R4 && i.operand as string == "0.0" && found)
{
yield return new CodeInstruction(OpCodes.Ldfld, Pawn);
yield return new CodeInstruction(OpCodes.Ldloc_3);
yield return new CodeInstruction(OpCodes.Call, EggSize);
}
if (i.opcode == OpCodes.Ldc_R4 && i.operand as string == "0.0")
found = true;
yield return i;
}
}
public static void EditMaxEggsSize(Pawn pawn, float eggsSize)
{
if (pawn.GetQuirks() != null)
pawn.GetQuirks().ApplyValueModifiers("maxEggsSize", ref eggsSize);
}
}
}

View File

@ -12,48 +12,16 @@ using rjwquirks.Modules.Quirks;
namespace rjwquirks.HarmonyPatches
{
/*[HarmonyPatch(typeof(JobGiver_Masturbate))]
[HarmonyPatch(typeof(JobGiver_Masturbate), nameof(JobGiver_Masturbate.WantsToMasturbate))]
public class Patch_JobGiver_Masturbate
{
[HarmonyTranspiler]
[HarmonyPatch("TryGiveJob")]
public static IEnumerable<CodeInstruction> ApplyQuirkToMasturbate(IEnumerable<CodeInstruction> instructions)
[HarmonyPostfix]
public static void ApplyQuirkToMasturbate(Pawn pawn, ref bool __result)
{
MethodInfo Frustrated = AccessTools.Method(typeof(xxx), nameof(xxx.is_frustrated));
MethodInfo Apply = AccessTools.Method(typeof(Patch_JobGiver_Masturbate), nameof(ApplyQuirk));
var labels = instructions.ElementAt(0).labels.ListFullCopy<Label>();
Log.Warning(labels.Count.ToString());
bool found = false;
foreach (CodeInstruction i in instructions)
if (!__result && pawn.HasQuirk(QuirkDefOf.Exhibitionist))
{
if (i.opcode == OpCodes.Call && i.operand as MethodInfo == Frustrated)
{
yield return new CodeInstruction(OpCodes.Ldarg_1);
yield return new CodeInstruction(OpCodes.Call, Apply);
yield return new CodeInstruction(OpCodes.Brtrue_S, labels[4]);
found = true;
}
if (found && i.opcode == OpCodes.Call && i.operand as MethodInfo == Frustrated)
{
yield return new CodeInstruction(OpCodes.Ldarg_1);
yield return new CodeInstruction(OpCodes.Call, Apply);
yield return new CodeInstruction(OpCodes.Brtrue_S, labels[5]);
found = false;
}
yield return i;
__result = true;
}
}
public static bool ApplyQuirk(Pawn pawn)
{
if (pawn.GetQuirks() != null)
return pawn.HasQuirk(QuirkDefOf.Exhibitionist);
return false;
}
}*/
}
}

View File

@ -13,16 +13,14 @@ using Verse;
namespace rjwquirks.HarmonyPatches
{
[HarmonyPatch(typeof(PartPreferenceDetectorService), nameof(PartPreferenceDetectorService.DetectPartPreferences))]
public class Patch_QuirkPartPreference
public class Patch_PartPreferenceDetectorService
{
public static void Prefix(InteractionContext context, IList<IPartPreferenceRule> ____partKindUsageRules)
{
if (____partKindUsageRules.Any(x => x.GetType() == typeof(QuirksPartKindUsageRule)) || (context.Internals.Submissive.Pawn.GetQuirks() == null || context.Internals.Dominant.Pawn.GetQuirks() == null))
return;
Log.Warning(____partKindUsageRules.Count().ToString());
____partKindUsageRules.Add(new QuirksPartKindUsageRule());
Log.Warning(____partKindUsageRules.Count().ToString());
}
}
}

View File

@ -0,0 +1,27 @@
using HarmonyLib;
using rjw;
using rjwquirks.Modules.Quirks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace rjwquirks.HarmonyPatches
{
[HarmonyPatch(typeof(rjw.PawnExtensions), nameof(rjw.PawnExtensions.MaxEggSize))]
public class Patch_PawnExtensions
{
[HarmonyPostfix]
public static void AdjustMaxEggsSize(Pawn pawn, ref float __result)
{
if (pawn.HasQuirk(QuirkDefOf.Incubator))
{
__result *= 2f;
}
}
}
}

View File

@ -0,0 +1,26 @@
using HarmonyLib;
using rjw;
using rjwquirks.Modules.Quirks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using Verse;
namespace rjwquirks.HarmonyPatches
{
[HarmonyPatch(typeof(PregnancyHelper), nameof(PregnancyHelper.MaxLitterSize))]
public class Patch_PregnancyHelper
{
[HarmonyPostfix]
public static void AdjustMaxLitterSize(Pawn mother, ref float __result)
{
if (mother.HasQuirk(QuirkDefOf.Breeder) || mother.HasQuirk(QuirkDefOf.Incubator))
{
__result *= 2f;
}
}
}
}

View File

@ -17,6 +17,16 @@ namespace rjwquirks.HarmonyPatches
[HarmonyPatch(typeof(SexUtility))]
public class Patch_SexUtility
{
[HarmonyPrefix]
[HarmonyPatch(nameof(SexUtility.DrawNude))]
public static bool Prefix(Pawn pawn)
{
if (pawn.HasQuirk(QuirkDefOf.Endytophile))
return false;
return true;
}
// Increases cum filth generated by pawn
[HarmonyPostfix]
[HarmonyPatch(nameof(SexUtility.CumOutputModifier))]
@ -27,42 +37,16 @@ namespace rjwquirks.HarmonyPatches
}
// Change how much the pawn wants to clean post sex
[HarmonyTranspiler]
[HarmonyPatch(nameof(SexUtility.ConsiderCleaning))]
static IEnumerable<CodeInstruction> ConsiderCleanup(IEnumerable<CodeInstruction> instructions)
[HarmonyPostfix]
[HarmonyPatch(nameof(SexUtility.CleaningChance))]
public static void AdjustConsiderScore(Pawn fapper, ref float __result)
{
FieldInfo PawnNeeds = AccessTools.Field(typeof(Pawn), nameof(Pawn.needs));
MethodInfo Cleanup = AccessTools.Method(typeof(Patch_SexUtility), nameof(CleanupChanceAdjuster));
bool found = false;
foreach (CodeInstruction i in instructions)
{
if (found)
{
yield return i;
yield return new CodeInstruction(OpCodes.Ldloc_0);
yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Call, Cleanup);
found = false;
continue;
}
if (i.opcode == OpCodes.Ldfld && i.operand as FieldInfo == PawnNeeds)
found = true;
yield return i;
}
}
public static void CleanupChanceAdjuster(float chance, Pawn pawn)
{
pawn.GetQuirks().ApplyValueModifiers("cleanAfterFapChance", ref chance);
fapper.GetQuirks().ApplyValueModifiers("cleanAfterFapChance", ref __result);
}
// Change satisfaction from sex
[HarmonyPostfix]
[HarmonyPatch(nameof(SexUtility.GetExtraSatisfaction))]
[HarmonyPatch(nameof(SexUtility.ExtraSatisfaction))]
public static void Satisfaction(SexProps props, ref float __result)
{
var quirkCount = props.pawn.GetQuirks().GetSatisfiedBySex(props).Count();
@ -75,71 +59,22 @@ namespace rjwquirks.HarmonyPatches
}
// Change ticks to next lovin
[HarmonyTranspiler]
[HarmonyPatch(nameof(SexUtility.GenerateMinTicksToNextLovin))]
public static IEnumerable<CodeInstruction> ChangeTicksToNextLovin(IEnumerable<CodeInstruction> instructions)
[HarmonyPostfix]
[HarmonyPatch(nameof(SexUtility.MinLovinTicks))]
public static void ChangeTicksToNextLovin(Pawn pawn, ref float __result)
{
MethodInfo SexDrive = AccessTools.Method(typeof(xxx), nameof(xxx.get_sex_drive));
MethodInfo AdjustTicks = AccessTools.Method(typeof(Patch_SexUtility), nameof(AdjustTicksToNextLovin));
bool found = false;
foreach (var i in instructions)
if(pawn.GetQuirks() != null)
{
if (found)
{
yield return i;
yield return new CodeInstruction(OpCodes.Ldloc_0);
yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Call, AdjustTicks);
found = false;
continue;
}
if (i.opcode == OpCodes.Call && i.operand as MethodInfo == SexDrive)
found = true;
yield return i;
}
}
public static void AdjustTicksToNextLovin(float ticks, Pawn pawn)
{
if (pawn.GetQuirks() != null)
{
pawn.GetQuirks().ApplyValueModifiers("ticksToNextLovin", ref ticks);
pawn.GetQuirks().ApplyValueModifiers("ticksToNextLovin", ref __result);
}
}
// Rest adjustments
[HarmonyTranspiler]
[HarmonyPrefix]
[HarmonyPatch(nameof(SexUtility.reduce_rest))]
public static IEnumerable<CodeInstruction> AdjustRest(IEnumerable<CodeInstruction> instructions)
public static void AdjustRest(Pawn pawn, ref float x)
{
MethodInfo Adjustment = AccessTools.Method(typeof(Patch_SexUtility), nameof(AdjustRestFromQuirk));
bool found = false;
bool completed = false;
foreach (CodeInstruction i in instructions)
{
if (found && !completed)
{
yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Ldarg_1);
yield return new CodeInstruction(OpCodes.Call, Adjustment);
completed = true;
found = false;
}
if (i.opcode == OpCodes.Dup)
found = true;
yield return i;
}
}
public static void AdjustRestFromQuirk(Pawn pawn, float x)
{
if(pawn.GetQuirks() != null)
if (pawn.GetQuirks() != null)
pawn.GetQuirks().ApplyValueModifiers("reduceRest", ref x);
}
}

View File

@ -0,0 +1,28 @@
using HarmonyLib;
using rjw;
using rjwquirks.Modules.Quirks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using Verse.AI;
namespace rjwquirks.HarmonyPatches
{
[HarmonyPatch(typeof(ThinkNode_ChancePerHour_Fappin), nameof(ThinkNode_ChancePerHour_Fappin.AloneFactor))]
public static class Patch_ThinkNode_ChancePerHour_Fappin
{
[HarmonyPostfix]
public static void Postfix(Pawn pawn, ref float __result)
{
bool isAlone = !pawn.Map.mapPawns.AllPawnsSpawned.Any(x => pawn.CanSee(x) && xxx.is_human(x));
if (pawn.HasQuirk(QuirkDefOf.Exhibitionist))
{
__result = isAlone ? 1.0f : 0.6f;
}
}
}
}

View File

@ -1,44 +1,44 @@
using rjw;
using rjwquirks.Data;
using rjwquirks.Modules.Shared.PawnSelectors;
using System.Collections.Generic;
using Verse;
namespace rjwquirks.Modules.Shared.PawnSelectors
{
public class HasRaceTag : PawnSelector
{
/// <summary>
/// For def load only. Use RaceTag property
/// </summary>
public string raceTag;
public class HasRaceTag : PawnSelector
{
/// <summary>
/// For def load only. Use RaceTag property
/// </summary>
public string raceTag;
public RaceTags RaceTag
{
get
{
if (RaceTags.TryParse(raceTag, out RaceTags tag))
return tag;
return null;
}
}
public RaceTag RaceTag
{
get
{
if (RaceTag.TryParse(raceTag, out RaceTag tag))
return tag;
return null;
}
}
public override bool PawnSatisfies(Pawn pawn) => pawn.HasRaceTag(RaceTag);
public override bool PawnSatisfies(Pawn pawn) => pawn.Has(RaceTag);
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
public override IEnumerable<string> ConfigErrors()
{
foreach (string error in base.ConfigErrors())
{
yield return error;
}
if (raceTag.NullOrEmpty())
{
yield return "<raceTag> is empty";
}
else if (!RaceTags.TryParse(raceTag, out _))
if (raceTag.NullOrEmpty())
{
yield return "<raceTag> is empty";
}
else if (!RaceTag.TryParse(raceTag, out _))
{
yield return $"\"{raceTag}\" is not a valid RaceTag";
}
}
}
}
}

View File

@ -1,5 +1,4 @@
using rjw;
using rjwquirks.Data;
using rjwquirks.Modules.Quirks;
using System.Linq;
using Verse;
@ -17,16 +16,5 @@ namespace rjwquirks
{
return pawn.GetComp<QuirkSet>();
}
public static bool HasRaceTag(this Pawn pawn, RaceTags tag)
{
if (RaceGroupDef_Helper.TryGetRaceGroupDef(pawn, out var raceGroupDef))
{
return raceGroupDef.tags != null && raceGroupDef.tags.Contains(tag.Key);
} else
{
return tag.DefaultWhenNoRaceGroupDef(pawn);
}
}
}
}

View File

@ -71,19 +71,17 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Core.cs" />
<Compile Include="Data\RaceTags.cs" />
<Compile Include="HarmonyPatches\Patch_CasualSex_Helper.cs" />
<Compile Include="HarmonyPatches\Patch_CondomUtility.cs" />
<Compile Include="HarmonyPatches\Patch_Dialog_Sexcard.cs" />
<Compile Include="HarmonyPatches\Patch_DrawNude.cs" />
<Compile Include="HarmonyPatches\Patch_Hediff_BasePregnancy.cs" />
<Compile Include="HarmonyPatches\Patch_Hediff_PartBaseArtifical.cs" />
<Compile Include="HarmonyPatches\Patch_Hediff_PartBaseNatural.cs" />
<Compile Include="HarmonyPatches\Patch_PregnancyHelper.cs" />
<Compile Include="HarmonyPatches\Patch_PawnExtensions.cs" />
<Compile Include="HarmonyPatches\Patch_JobGiver_Masturbate.cs" />
<Compile Include="HarmonyPatches\Patch_QuirkPartPreference.cs" />
<Compile Include="HarmonyPatches\Patch_PartPreferenceDetectorService.cs" />
<Compile Include="HarmonyPatches\Patch_RecordsTracker_NotifyRecordChanged.cs" />
<Compile Include="HarmonyPatches\Patch_SexAppraiser.cs" />
<Compile Include="HarmonyPatches\Patch_SexUtility.cs" />
<Compile Include="HarmonyPatches\Patch_ThinkNode_ChancePerHour_Fappin.cs" />
<Compile Include="Modules\Interactions\QuirksPartKindUsageRule.cs" />
<Compile Include="Modules\Quirks\CompProperties_QuirkSet.cs" />
<Compile Include="Modules\Quirks\Comps\CompAdder.cs" />
@ -167,5 +165,8 @@
<Compile Include="PawnExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Data\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>