mirror of
https://gitgud.io/amevarashi/rjw-sexperience-ideology.git
synced 2024-08-15 00:43:19 +00:00
Added settings for romance patches
Added in-game explanation for DefExtension_ModifyMtb effect
This commit is contained in:
parent
77dd1a23d6
commit
e622b7a391
12 changed files with 189 additions and 35 deletions
|
@ -9,6 +9,16 @@
|
||||||
<RSNotAnimal>not animal</RSNotAnimal>
|
<RSNotAnimal>not animal</RSNotAnimal>
|
||||||
<RSShouldCanFuck>capable of sex is required</RSShouldCanFuck>
|
<RSShouldCanFuck>capable of sex is required</RSShouldCanFuck>
|
||||||
|
|
||||||
|
<RSI_PatchRomanceChanceFactor>Enable romance patch for incest precepts*</RSI_PatchRomanceChanceFactor>
|
||||||
|
<RSI_PatchRomanceChanceFactorTip>Patch for incest precepts to affect RomanceChanceFactor. May conflict with romance mods./n/n* Requires a game restart to apply changes</RSI_PatchRomanceChanceFactorTip>
|
||||||
|
<RSI_PatchIncestuousManualRomance>Enable manual romance patch for incest precepts*</RSI_PatchIncestuousManualRomance>
|
||||||
|
<RSI_PatchIncestuousManualRomanceTip>Patch for incest precepts to affect manual romance options./n/n* Requires a game restart to apply changes</RSI_PatchIncestuousManualRomanceTip>
|
||||||
|
|
||||||
|
<RSI_PreceptTipModifyBestialityMtb>Time between bestiality attempts x{0}</RSI_PreceptTipModifyBestialityMtb>
|
||||||
|
<RSI_PreceptTipModifyFappinMtb>Time between masturbation attempts x{0}</RSI_PreceptTipModifyFappinMtb>
|
||||||
|
<RSI_PreceptTipModifyNecroMtb>Time between necrophilia attempts x{0}</RSI_PreceptTipModifyNecroMtb>
|
||||||
|
<RSI_PreceptTipModifyRapeCPMtb>Time between rape attempts x{0}</RSI_PreceptTipModifyRapeCPMtb>
|
||||||
|
|
||||||
<!-- Rewrite vanilla key -->
|
<!-- Rewrite vanilla key -->
|
||||||
<CantRomanceTargetIncest>forbidden by ideology</CantRomanceTargetIncest>
|
<!-- <CantRomanceTargetIncest>forbidden by ideology</CantRomanceTargetIncest> -->
|
||||||
</LanguageData>
|
</LanguageData>
|
|
@ -54,6 +54,7 @@
|
||||||
<Compile Include="HistoryEvents\ArgsNamesCustom.cs" />
|
<Compile Include="HistoryEvents\ArgsNamesCustom.cs" />
|
||||||
<Compile Include="Keyed.cs" />
|
<Compile Include="Keyed.cs" />
|
||||||
<Compile Include="Precepts\DefExtension_Incest.cs" />
|
<Compile Include="Precepts\DefExtension_Incest.cs" />
|
||||||
|
<Compile Include="Precepts\IPreceptTipPostfix.cs" />
|
||||||
<Compile Include="PreceptWorkers\ThoughtWorker_Precept_GenitalSize.cs" />
|
<Compile Include="PreceptWorkers\ThoughtWorker_Precept_GenitalSize.cs" />
|
||||||
<Compile Include="PreceptWorkers\ThoughtWorker_Precept_GenitalSize_Social.cs" />
|
<Compile Include="PreceptWorkers\ThoughtWorker_Precept_GenitalSize_Social.cs" />
|
||||||
<Compile Include="PreceptWorkers\ThoughtWorker_Precept_NonPregnant.cs" />
|
<Compile Include="PreceptWorkers\ThoughtWorker_Precept_NonPregnant.cs" />
|
||||||
|
@ -87,6 +88,8 @@
|
||||||
<Compile Include="Rituals\RitualBehaviorWorkers.cs" />
|
<Compile Include="Rituals\RitualBehaviorWorkers.cs" />
|
||||||
<Compile Include="Rituals\RitualOutcomeComps.cs" />
|
<Compile Include="Rituals\RitualOutcomeComps.cs" />
|
||||||
<Compile Include="Rituals\RitualRoles.cs" />
|
<Compile Include="Rituals\RitualRoles.cs" />
|
||||||
|
<Compile Include="RsiMod.cs" />
|
||||||
|
<Compile Include="RsiSettings.cs" />
|
||||||
<Compile Include="StatParts.cs" />
|
<Compile Include="StatParts.cs" />
|
||||||
<Compile Include="IdeoUtility.cs" />
|
<Compile Include="IdeoUtility.cs" />
|
||||||
<Compile Include="Thoughts\ThoughtDefExtension_IncreaseRecord.cs" />
|
<Compile Include="Thoughts\ThoughtDefExtension_IncreaseRecord.cs" />
|
||||||
|
@ -97,7 +100,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Krafs.Rimworld.Ref">
|
<PackageReference Include="Krafs.Rimworld.Ref">
|
||||||
<Version>1.4.3555</Version>
|
<Version>1.4.3704</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Lib.Harmony">
|
<PackageReference Include="Lib.Harmony">
|
||||||
<Version>2.2.2</Version>
|
<Version>2.2.2</Version>
|
||||||
|
|
|
@ -4,11 +4,17 @@ namespace RJWSexperience.Ideology
|
||||||
{
|
{
|
||||||
public static class Keyed
|
public static class Keyed
|
||||||
{
|
{
|
||||||
|
public static readonly string ModTitle = "RSI_Mod_Title".Translate();
|
||||||
public static readonly string MemeStatFactor = "MemeStatFactor".Translate();
|
public static readonly string MemeStatFactor = "MemeStatFactor".Translate();
|
||||||
public static readonly string RSVictimCondition = "RSVictimCondition".Translate();
|
public static readonly string RSVictimCondition = "RSVictimCondition".Translate();
|
||||||
public static readonly string RSBreederCondition = "RSBreederCondition".Translate();
|
public static readonly string RSBreederCondition = "RSBreederCondition".Translate();
|
||||||
public static readonly string RSNotHuman = "RSNotHuman".Translate();
|
public static readonly string RSNotHuman = "RSNotHuman".Translate();
|
||||||
public static readonly string RSNotAnimal = "RSNotAnimal".Translate();
|
public static readonly string RSNotAnimal = "RSNotAnimal".Translate();
|
||||||
public static readonly string RSShouldCanFuck = "RSShouldCanFuck".Translate();
|
public static readonly string RSShouldCanFuck = "RSShouldCanFuck".Translate();
|
||||||
|
|
||||||
|
public static readonly string PatchRomanceChanceFactor = "RSI_PatchRomanceChanceFactor".Translate();
|
||||||
|
public static readonly string PatchRomanceChanceFactorTip = "RSI_PatchRomanceChanceFactorTip".Translate();
|
||||||
|
public static readonly string PatchIncestuousManualRomance = "RSI_PatchIncestuousManualRomance".Translate();
|
||||||
|
public static readonly string PatchIncestuousManualRomanceTip = "RSI_PatchIncestuousManualRomanceTip".Translate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.Emit;
|
using System.Reflection.Emit;
|
||||||
|
using System.Text;
|
||||||
using Verse;
|
using Verse;
|
||||||
|
|
||||||
namespace RJWSexperience.Ideology.Patches
|
namespace RJWSexperience.Ideology.Patches
|
||||||
|
@ -60,6 +61,8 @@ namespace RJWSexperience.Ideology.Patches
|
||||||
[HarmonyPatch(typeof(RelationsUtility), "Incestuous")]
|
[HarmonyPatch(typeof(RelationsUtility), "Incestuous")]
|
||||||
public static class Rimworld_Patch_IncestuousManualRomance
|
public static class Rimworld_Patch_IncestuousManualRomance
|
||||||
{
|
{
|
||||||
|
public static bool Prepare() => RsiMod.Prefs.patchIncestuousManualRomance;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Override incestuous check in the manual romance
|
/// Override incestuous check in the manual romance
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -97,6 +100,8 @@ namespace RJWSexperience.Ideology.Patches
|
||||||
[HarmonyPatch(typeof(Pawn_RelationsTracker), nameof(Pawn_RelationsTracker.SecondaryRomanceChanceFactor))]
|
[HarmonyPatch(typeof(Pawn_RelationsTracker), nameof(Pawn_RelationsTracker.SecondaryRomanceChanceFactor))]
|
||||||
public static class Rimworld_Patch_SecondaryRomanceChanceFactor
|
public static class Rimworld_Patch_SecondaryRomanceChanceFactor
|
||||||
{
|
{
|
||||||
|
public static bool Prepare() => RsiMod.Prefs.patchRomanceChanceFactor;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>
|
/// <para>
|
||||||
/// Replace
|
/// Replace
|
||||||
|
@ -124,9 +129,6 @@ namespace RJWSexperience.Ideology.Patches
|
||||||
typeof(RomanceChanceFactorHelpers),
|
typeof(RomanceChanceFactorHelpers),
|
||||||
nameof(RomanceChanceFactorHelpers.GetRomanceChanceFactor),
|
nameof(RomanceChanceFactorHelpers.GetRomanceChanceFactor),
|
||||||
new[] { typeof(Pawn), typeof(Pawn) });
|
new[] { typeof(Pawn), typeof(Pawn) });
|
||||||
bool skipping = false;
|
|
||||||
bool yieldNext = false;
|
|
||||||
bool finished = false;
|
|
||||||
|
|
||||||
// Original IL looks something like this:
|
// Original IL looks something like this:
|
||||||
// Load this.pawn
|
// Load this.pawn
|
||||||
|
@ -142,41 +144,103 @@ namespace RJWSexperience.Ideology.Patches
|
||||||
// Idea is to substitute GetRelations call with a method with the same signature,
|
// Idea is to substitute GetRelations call with a method with the same signature,
|
||||||
// store results in the same place original loop does and remove everything else until Endfinaly
|
// store results in the same place original loop does and remove everything else until Endfinaly
|
||||||
|
|
||||||
foreach (CodeInstruction instruction in instructions)
|
IEnumerator<CodeInstruction> enumerator = instructions.GetEnumerator();
|
||||||
|
bool endOfInstructions = enumerator.MoveNext();
|
||||||
|
|
||||||
|
// Find and replace GetRelations
|
||||||
|
while (!endOfInstructions)
|
||||||
{
|
{
|
||||||
if (finished)
|
var instruction = enumerator.Current;
|
||||||
{
|
|
||||||
yield return instruction;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skipping)
|
|
||||||
{
|
|
||||||
if (yieldNext)
|
|
||||||
{
|
|
||||||
yield return instruction;
|
|
||||||
yieldNext = false;
|
|
||||||
}
|
|
||||||
else if (instruction.opcode == OpCodes.Mul)
|
|
||||||
{
|
|
||||||
yieldNext = true;
|
|
||||||
}
|
|
||||||
else if (instruction.opcode == OpCodes.Endfinally)
|
|
||||||
{
|
|
||||||
finished = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instruction.Calls(getRelationsInfo))
|
if (instruction.Calls(getRelationsInfo))
|
||||||
{
|
{
|
||||||
yield return new CodeInstruction(OpCodes.Call, helperInfo);
|
yield return new CodeInstruction(OpCodes.Call, helperInfo);
|
||||||
skipping = true;
|
enumerator.MoveNext(); // skip original method call
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield return instruction;
|
yield return instruction;
|
||||||
|
endOfInstructions = enumerator.MoveNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endOfInstructions)
|
||||||
|
{
|
||||||
|
Log.Error("[RSI] Failed to transpile Pawn_RelationsTracker.SecondaryRomanceChanceFactor: PawnRelationUtility.GetRelations call not found");
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip everything until Mul
|
||||||
|
while (!endOfInstructions)
|
||||||
|
{
|
||||||
|
if (enumerator.Current.opcode == OpCodes.Mul)
|
||||||
|
{
|
||||||
|
enumerator.MoveNext(); // skip Mul
|
||||||
|
yield return enumerator.Current; // return next op, it should be "store result"
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
endOfInstructions = enumerator.MoveNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endOfInstructions)
|
||||||
|
{
|
||||||
|
Log.Error("[RSI] Failed to transpile Pawn_RelationsTracker.SecondaryRomanceChanceFactor: Mul not found. This error means half of SecondaryRomanceChanceFactor was erased. Very not good");
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the rest of the loop
|
||||||
|
while (!endOfInstructions)
|
||||||
|
{
|
||||||
|
if (enumerator.Current.opcode == OpCodes.Endfinally)
|
||||||
|
{
|
||||||
|
// Endfinally will be skipped by the next MoveNext()
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
endOfInstructions = enumerator.MoveNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endOfInstructions)
|
||||||
|
{
|
||||||
|
Log.Error("[RSI] Failed to transpile Pawn_RelationsTracker.SecondaryRomanceChanceFactor: Endfinally not found. This error means half of SecondaryRomanceChanceFactor was erased. Very not good");
|
||||||
|
yield break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the rest of the method
|
||||||
|
while (enumerator.MoveNext())
|
||||||
|
{
|
||||||
|
yield return enumerator.Current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(Precept), nameof(Precept.GetTip))]
|
||||||
|
public static class Rimworld_Patch_PreceptTip
|
||||||
|
{
|
||||||
|
public static void Postfix(ref string __result, Precept __instance)
|
||||||
|
{
|
||||||
|
if (__instance.def.modExtensions.NullOrEmpty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tipChanged = false;
|
||||||
|
StringBuilder tipBuilder = new StringBuilder(__result);
|
||||||
|
tipBuilder.AppendLine();
|
||||||
|
tipBuilder.AppendInNewLine((Keyed.ModTitle + ":").Colorize(ColoredText.TipSectionTitleColor));
|
||||||
|
|
||||||
|
for (int i = 0; i < __instance.def.modExtensions.Count; i++)
|
||||||
|
{
|
||||||
|
if (__instance.def.modExtensions[i] is IPreceptTipPostfix tipPostfix)
|
||||||
|
{
|
||||||
|
tipBuilder.AppendInNewLine(" - " + tipPostfix.GetTip());
|
||||||
|
tipChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tipChanged)
|
||||||
|
{
|
||||||
|
__result = tipBuilder.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,5 +2,6 @@
|
||||||
{
|
{
|
||||||
public class DefExtension_ModifyBestialityMtb : DefExtension_ModifyMtb
|
public class DefExtension_ModifyBestialityMtb : DefExtension_ModifyMtb
|
||||||
{
|
{
|
||||||
|
protected override string TipTemplateKey => "RSI_PreceptTipModifyBestialityMtb";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,5 +2,6 @@
|
||||||
{
|
{
|
||||||
public class DefExtension_ModifyFappinMtb : DefExtension_ModifyMtb
|
public class DefExtension_ModifyFappinMtb : DefExtension_ModifyMtb
|
||||||
{
|
{
|
||||||
|
protected override string TipTemplateKey => "RSI_PreceptTipModifyFappinMtb";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,28 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Verse;
|
using Verse;
|
||||||
|
|
||||||
namespace RJWSexperience.Ideology.Precepts
|
namespace RJWSexperience.Ideology.Precepts
|
||||||
{
|
{
|
||||||
public abstract class DefExtension_ModifyMtb : DefModExtension
|
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field values are loaded from XML")]
|
||||||
|
public abstract class DefExtension_ModifyMtb : DefModExtension, IPreceptTipPostfix
|
||||||
{
|
{
|
||||||
[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
|
protected abstract string TipTemplateKey { get; }
|
||||||
|
|
||||||
public float multiplier = 1f;
|
public float multiplier = 1f;
|
||||||
|
|
||||||
|
public string GetTip() => TipTemplateKey.Translate(multiplier.ToString());
|
||||||
|
|
||||||
|
public override IEnumerable<string> ConfigErrors()
|
||||||
|
{
|
||||||
|
if (multiplier == 1f)
|
||||||
|
{
|
||||||
|
yield return "There is no point if <multiplier> is 1";
|
||||||
|
}
|
||||||
|
else if (multiplier <= 0f)
|
||||||
|
{
|
||||||
|
yield return "<multiplier> must be > 0";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,5 +2,6 @@
|
||||||
{
|
{
|
||||||
public class DefExtension_ModifyNecroMtb : DefExtension_ModifyMtb
|
public class DefExtension_ModifyNecroMtb : DefExtension_ModifyMtb
|
||||||
{
|
{
|
||||||
|
protected override string TipTemplateKey => "RSI_PreceptTipModifyNecroMtb";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,5 +2,6 @@
|
||||||
{
|
{
|
||||||
public class DefExtension_ModifyRapeCPMtb : DefExtension_ModifyMtb
|
public class DefExtension_ModifyRapeCPMtb : DefExtension_ModifyMtb
|
||||||
{
|
{
|
||||||
|
protected override string TipTemplateKey => "RSI_PreceptTipModifyRapeCPMtb";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
7
Source/IdeologyAddon/Precepts/IPreceptTipPostfix.cs
Normal file
7
Source/IdeologyAddon/Precepts/IPreceptTipPostfix.cs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
namespace RJWSexperience.Ideology.Precepts
|
||||||
|
{
|
||||||
|
public interface IPreceptTipPostfix
|
||||||
|
{
|
||||||
|
string GetTip();
|
||||||
|
}
|
||||||
|
}
|
26
Source/IdeologyAddon/RsiMod.cs
Normal file
26
Source/IdeologyAddon/RsiMod.cs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
using UnityEngine;
|
||||||
|
using Verse;
|
||||||
|
|
||||||
|
namespace RJWSexperience.Ideology
|
||||||
|
{
|
||||||
|
public class RsiMod : Mod
|
||||||
|
{
|
||||||
|
public static RsiSettings Prefs { get; private set; }
|
||||||
|
|
||||||
|
public RsiMod(ModContentPack content) : base(content)
|
||||||
|
{
|
||||||
|
Prefs = GetSettings<RsiSettings>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string SettingsCategory() => Keyed.ModTitle;
|
||||||
|
|
||||||
|
public override void DoSettingsWindowContents(Rect inRect)
|
||||||
|
{
|
||||||
|
Listing_Standard listmain = new Listing_Standard();
|
||||||
|
listmain.Begin(inRect);
|
||||||
|
listmain.CheckboxLabeled(Keyed.PatchRomanceChanceFactor, ref Prefs.patchRomanceChanceFactor, Keyed.PatchRomanceChanceFactorTip);
|
||||||
|
listmain.CheckboxLabeled(Keyed.PatchIncestuousManualRomance, ref Prefs.patchIncestuousManualRomance, Keyed.PatchIncestuousManualRomanceTip);
|
||||||
|
listmain.End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
Source/IdeologyAddon/RsiSettings.cs
Normal file
17
Source/IdeologyAddon/RsiSettings.cs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
using Verse;
|
||||||
|
|
||||||
|
namespace RJWSexperience.Ideology
|
||||||
|
{
|
||||||
|
public class RsiSettings : ModSettings
|
||||||
|
{
|
||||||
|
public bool patchRomanceChanceFactor;
|
||||||
|
public bool patchIncestuousManualRomance;
|
||||||
|
|
||||||
|
public override void ExposeData()
|
||||||
|
{
|
||||||
|
base.ExposeData();
|
||||||
|
Scribe_Values.Look(ref patchRomanceChanceFactor, "patchSecondaryRomanceChanceFactor", true);
|
||||||
|
Scribe_Values.Look(ref patchIncestuousManualRomance, "patchIncestuousManualRomance", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue