From 3bedfec30e811b51f591b63f892adab6a8dd03d2 Mon Sep 17 00:00:00 2001 From: amevarashi Date: Sun, 20 Nov 2022 18:47:55 +0500 Subject: [PATCH] Patched manual romance to respect incestuous precepts --- Languages/English/Keyed/RJW_Sexperience.xml | 2 + Source/IdeologyAddon/BloodRelationDegree.cs | 9 ++ Source/IdeologyAddon/DebugAction.cs | 17 +++ Source/IdeologyAddon/IdeologyAddon.csproj | 5 +- .../IdeologyAddon/Patches/Rimworld_Patch.cs | 52 +++++++++ Source/IdeologyAddon/RelationHelpers.cs | 47 ++++++++ .../RomanceChanceFactorHelpers.cs | 108 ++++++++++++++++++ Source/IdeologyAddon/VariousDefOf.cs | 24 ++-- 8 files changed, 254 insertions(+), 10 deletions(-) create mode 100644 Source/IdeologyAddon/BloodRelationDegree.cs create mode 100644 Source/IdeologyAddon/RelationHelpers.cs create mode 100644 Source/IdeologyAddon/RomanceChanceFactorHelpers.cs diff --git a/Languages/English/Keyed/RJW_Sexperience.xml b/Languages/English/Keyed/RJW_Sexperience.xml index 9550b00..92fe2bc 100644 --- a/Languages/English/Keyed/RJW_Sexperience.xml +++ b/Languages/English/Keyed/RJW_Sexperience.xml @@ -9,4 +9,6 @@ not animal capable of sex is required + + forbidden by ideology \ No newline at end of file diff --git a/Source/IdeologyAddon/BloodRelationDegree.cs b/Source/IdeologyAddon/BloodRelationDegree.cs new file mode 100644 index 0000000..e23f9ee --- /dev/null +++ b/Source/IdeologyAddon/BloodRelationDegree.cs @@ -0,0 +1,9 @@ +namespace RJWSexperience.Ideology +{ + public enum BloodRelationDegree + { + CloseRelative, + FarRelative, + NotRelated + } +} diff --git a/Source/IdeologyAddon/DebugAction.cs b/Source/IdeologyAddon/DebugAction.cs index 9655f50..91f5b20 100644 --- a/Source/IdeologyAddon/DebugAction.cs +++ b/Source/IdeologyAddon/DebugAction.cs @@ -1,5 +1,7 @@ using rjw; using RJWSexperience.Ideology.HistoryEvents; +using RJWSexperience.Ideology.Patches; +using System.Collections.Generic; using System.Linq; using Verse; @@ -16,5 +18,20 @@ namespace RJWSexperience.Ideology RsiHistoryEventDefOf.RSI_NonIncestuosMarriage.RecordEventWithPartner(hero, p); RsiHistoryEventDefOf.RSI_NonIncestuosMarriage.RecordEventWithPartner(p, hero); } + + [DebugAction("RJW Sexperience Ideology", "Manual romance check", false, true, actionType = DebugActionType.Action, allowedGameStates = AllowedGameStates.PlayingOnMap)] + public static void DisplayDebugTable() + { + IEnumerable pawns = Find.CurrentMap.mapPawns.AllPawnsSpawned.Where(pawn => pawn.IsColonist); + + IEnumerable> columns = pawns + .Select(pawn => new TableDataGetter(pawn.Name.ToStringShort, (Pawn p) => Rimworld_Patch_IncestuousManualRomance.RsiIncestuous(p, pawn))); + + var name = new TableDataGetter("Name", (Pawn pawn) => pawn.Name.ToStringShort); + + TableDataGetter[] getters = (new List>() { name }).Concat(columns).ToArray(); + + DebugTables.MakeTablesDialog(pawns, getters); + } } } diff --git a/Source/IdeologyAddon/IdeologyAddon.csproj b/Source/IdeologyAddon/IdeologyAddon.csproj index 651dd5b..e2571af 100644 --- a/Source/IdeologyAddon/IdeologyAddon.csproj +++ b/Source/IdeologyAddon/IdeologyAddon.csproj @@ -42,6 +42,7 @@ + @@ -59,6 +60,8 @@ + + @@ -94,7 +97,7 @@ - 1.4.3537 + 1.4.3542 2.2.2 diff --git a/Source/IdeologyAddon/Patches/Rimworld_Patch.cs b/Source/IdeologyAddon/Patches/Rimworld_Patch.cs index e50098e..9243d70 100644 --- a/Source/IdeologyAddon/Patches/Rimworld_Patch.cs +++ b/Source/IdeologyAddon/Patches/Rimworld_Patch.cs @@ -4,6 +4,7 @@ using rjw; using RJWSexperience.Ideology.HistoryEvents; using RJWSexperience.Ideology.Precepts; using System.Collections.Generic; +using System.Linq; using Verse; namespace RJWSexperience.Ideology.Patches @@ -53,4 +54,55 @@ namespace RJWSexperience.Ideology.Patches } } } + + public static class Rimworld_Patch_IncestuousManualRomance + { + /// + /// Override incestuous check in the manual romance + /// + /// Pawn to try do romance + /// Target for romance + /// Result of the original method + /// Run original method implementation + [HarmonyPatch(typeof(RelationsUtility), "Incestuous")] + public static bool Prefix(Pawn one, Pawn two, ref bool __result) + { + __result = RsiIncestuous(one, two); + return false; + } + + /// + /// Check if Ideology allows romance attempt + /// + /// Pawn to try do romance + /// Target for romance + /// Forbid romance option + public static bool RsiIncestuous(Pawn one, Pawn two) + { + PreceptDef incestuousPrecept = one.Ideo?.PreceptsListForReading.Select(precept => precept.def).FirstOrFallback(def => def.issue == VariousDefOf.Incestuos); + BloodRelationDegree relationDegree = RelationHelpers.GetBloodRelationDegree(one, two); + + if (incestuousPrecept == null || + incestuousPrecept == VariousDefOf.Incestuos_Disapproved || + incestuousPrecept == VariousDefOf.Incestuos_Forbidden) + { + return relationDegree < BloodRelationDegree.NotRelated; + } + else if (incestuousPrecept == VariousDefOf.Incestuos_Free) + { + return false; + } + else if (incestuousPrecept == VariousDefOf.Incestuos_Disapproved_CloseOnly) + { + return relationDegree == BloodRelationDegree.CloseRelative; + } + else if (incestuousPrecept == VariousDefOf.Incestuos_IncestOnly) + { + return relationDegree == BloodRelationDegree.NotRelated; + } + + // Modded incestuous precept? + return true; + } + } } diff --git a/Source/IdeologyAddon/RelationHelpers.cs b/Source/IdeologyAddon/RelationHelpers.cs new file mode 100644 index 0000000..2a5fe77 --- /dev/null +++ b/Source/IdeologyAddon/RelationHelpers.cs @@ -0,0 +1,47 @@ +using RimWorld; +using System.Linq; +using Verse; + +namespace RJWSexperience.Ideology +{ + public static class RelationHelpers + { + /// + /// Get degree of blood relation between two pawns + /// + public static BloodRelationDegree GetBloodRelationDegree(Pawn pawn, Pawn partner) + { + PawnRelationDef closestBloodRelation = pawn + .GetRelations(partner) + ?.Where(def => def.familyByBloodRelation) + ?.OrderByDescending(def => def.importance) + ?.FirstOrFallback(); + + if (closestBloodRelation == null) + { + return BloodRelationDegree.NotRelated; + } + + return GetBloodRelationDegree(closestBloodRelation); + } + + /// + /// Get degree of blood relation for a relationDef + /// + public static BloodRelationDegree GetBloodRelationDegree(PawnRelationDef relationDef) + { + if (!relationDef.familyByBloodRelation) + { + return BloodRelationDegree.NotRelated; + } + else if (relationDef.importance <= PawnRelationDefOf.Cousin.importance) + { + return BloodRelationDegree.FarRelative; + } + else + { + return BloodRelationDegree.CloseRelative; + } + } + } +} diff --git a/Source/IdeologyAddon/RomanceChanceFactorHelpers.cs b/Source/IdeologyAddon/RomanceChanceFactorHelpers.cs new file mode 100644 index 0000000..f2831ee --- /dev/null +++ b/Source/IdeologyAddon/RomanceChanceFactorHelpers.cs @@ -0,0 +1,108 @@ +using RimWorld; +using System.Collections.Generic; +using System.Linq; +using Verse; + +namespace RJWSexperience.Ideology +{ + public static class RomanceChanceFactorHelpers + { + /// + /// Default value for parent relation + /// + private const float parentRomanceChanceFactor = 0.03f; + + /// + /// Get ideology adjusted romanceChanceFactor + /// + public static float GetRomanceChanceFactor(Pawn pawn, Pawn partner) + { + IEnumerable relations = pawn.GetRelations(partner).Where(def => def.familyByBloodRelation); + PreceptDef incestuousPrecept = pawn.Ideo?.PreceptsListForReading.Select(precept => precept.def).FirstOrFallback(def => def.issue == VariousDefOf.Incestuos); + float romanceChanceFactor = 1f; + + if (!relations.Any()) + { + if (incestuousPrecept == VariousDefOf.Incestuos_IncestOnly) + { + return parentRomanceChanceFactor; + } + else + { + return romanceChanceFactor; + } + } + + foreach (PawnRelationDef relationDef in relations) + { + romanceChanceFactor *= GetRomanceChanceFactor(relationDef, incestuousPrecept); + } + + return romanceChanceFactor; + } + + /// + /// Get ideology adjusted romanceChanceFactor for the relation + /// + public static float GetRomanceChanceFactor(PawnRelationDef relationDef, PreceptDef incestuousPrecept) + { + if (incestuousPrecept == null || incestuousPrecept == VariousDefOf.Incestuos_Disapproved) // Default game setup + { + return relationDef.romanceChanceFactor; + } + + if (incestuousPrecept == VariousDefOf.Incestuos_Free) + { + return 1f; + } + else if (incestuousPrecept == VariousDefOf.Incestuos_Disapproved_CloseOnly) + { + if (relationDef.familyByBloodRelation && relationDef.importance > PawnRelationDefOf.Cousin.importance) + { + return relationDef.romanceChanceFactor; + } + else + { + return 1f; + } + } + else if (incestuousPrecept == VariousDefOf.Incestuos_Forbidden) + { + if (relationDef.familyByBloodRelation) + { + return parentRomanceChanceFactor; + } + } + else if (incestuousPrecept == VariousDefOf.Incestuos_IncestOnly) + { + if (!relationDef.familyByBloodRelation) + { + return parentRomanceChanceFactor; + } + else + { + return 1f; + } + } + + return relationDef.romanceChanceFactor; + } + + [DebugAction("RJW Sexperience Ideology", "Show romanceChanceFactors", false, true, actionType = DebugActionType.Action, allowedGameStates = AllowedGameStates.Entry)] + public static void DisplayDebugTable() + { + IEnumerable incestuousPrecepts = DefDatabase + .AllDefsListForReading + .Where(def => def.issue == VariousDefOf.Incestuos); + + IEnumerable> preceptGetters = incestuousPrecepts + .Select(precept => new TableDataGetter(precept.defName,(PawnRelationDef rel) => GetRomanceChanceFactor(rel, precept))); + + var relName = new TableDataGetter("Relation Def", (PawnRelationDef rel) => rel.defName); + + TableDataGetter[] getters = (new List>() { relName }).Concat(preceptGetters).ToArray(); + + DebugTables.MakeTablesDialog(DefDatabase.AllDefsListForReading, getters); + } + } +} \ No newline at end of file diff --git a/Source/IdeologyAddon/VariousDefOf.cs b/Source/IdeologyAddon/VariousDefOf.cs index fb926ce..996a479 100644 --- a/Source/IdeologyAddon/VariousDefOf.cs +++ b/Source/IdeologyAddon/VariousDefOf.cs @@ -13,15 +13,21 @@ namespace RJWSexperience.Ideology public static readonly JobDef GettinDrugSex; public static readonly JobDef DrugMasturbate; - [MayRequireIdeology] public static readonly MemeDef Zoophile; - [MayRequireIdeology] public static readonly MemeDef Rapist; - [MayRequireIdeology] public static readonly MemeDef Necrophile; - [MayRequireIdeology] public static readonly PreceptDef Bestiality_OnlyVenerated; - [MayRequireIdeology] public static readonly PreceptDef BabyFaction_AlwaysFather; - [MayRequireIdeology] public static readonly PreceptDef BabyFaction_AlwaysColony; - [MayRequireIdeology] public static readonly PreceptDef Submissive_Male; - [MayRequireIdeology] public static readonly PreceptDef Submissive_Female; - [MayRequireIdeology] public static readonly PreceptDef ProselyzingByOrgasm; + public static readonly MemeDef Zoophile; + public static readonly MemeDef Rapist; + public static readonly MemeDef Necrophile; + public static readonly IssueDef Incestuos; + public static readonly PreceptDef Incestuos_Free; + public static readonly PreceptDef Incestuos_Disapproved_CloseOnly; + public static readonly PreceptDef Incestuos_Disapproved; + public static readonly PreceptDef Incestuos_Forbidden; + public static readonly PreceptDef Incestuos_IncestOnly; + public static readonly PreceptDef Bestiality_OnlyVenerated; + public static readonly PreceptDef BabyFaction_AlwaysFather; + public static readonly PreceptDef BabyFaction_AlwaysColony; + public static readonly PreceptDef Submissive_Male; + public static readonly PreceptDef Submissive_Female; + public static readonly PreceptDef ProselyzingByOrgasm; [MayRequireBiotech] public static readonly HediffDef PregnantHuman; } }