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;
}
}