diff --git a/1.4/Defs/PreceptDefs/Precepts_Incest.xml b/1.4/Defs/PreceptDefs/Precepts_Incest.xml index 23f82de..54c079a 100644 --- a/1.4/Defs/PreceptDefs/Precepts_Incest.xml +++ b/1.4/Defs/PreceptDefs/Precepts_Incest.xml @@ -27,16 +27,9 @@
  • - -
  • Parent
  • -
  • Child
  • -
  • Sibling
  • -
  • HalfSibling
  • -
  • Grandparent
  • -
  • Grandchild
  • -
  • NephewOrNiece
  • -
  • UncleOrAunt
  • - + +
  • CloseRelative
  • +
    RSI_CloseRelativeMarriage @@ -44,7 +37,9 @@
  • - true + +
  • FarRelative
  • + RSI_IncestuosMarriage @@ -73,16 +68,9 @@
  • - -
  • Parent
  • -
  • Child
  • -
  • Sibling
  • -
  • HalfSibling
  • -
  • Grandparent
  • -
  • Grandchild
  • -
  • NephewOrNiece
  • -
  • UncleOrAunt
  • - + +
  • CloseRelative
  • +
    RSI_CloseRelativeSex @@ -90,7 +78,9 @@
  • - true + +
  • FarRelative
  • + RSI_IncestuosSex @@ -118,6 +108,20 @@
  • FarRelative
  • NotRelated
  • + +
  • + CloseRelative + 1 +
  • +
  • + FarRelative + 1 +
  • +
  • + NotRelated + 1 +
  • +
    @@ -147,16 +151,9 @@
  • - -
  • Parent
  • -
  • Child
  • -
  • Sibling
  • -
  • HalfSibling
  • -
  • Grandparent
  • -
  • Grandchild
  • -
  • NephewOrNiece
  • -
  • UncleOrAunt
  • - + +
  • CloseRelative
  • +
  • Spouse
  • @@ -171,6 +168,16 @@
  • FarRelative
  • NotRelated
  • + +
  • + FarRelative + 1 +
  • +
  • + NotRelated + 1 +
  • +
    @@ -204,7 +211,10 @@
  • - true + +
  • CloseRelative
  • +
  • FarRelative
  • +
  • Spouse
  • @@ -246,7 +256,10 @@
  • - true + +
  • CloseRelative
  • +
  • FarRelative
  • +
  • Spouse
  • @@ -256,6 +269,18 @@ +
  • + +
  • + CloseRelative + 0.03 +
  • +
  • + FarRelative + 0.03 +
  • + + @@ -283,7 +308,9 @@
  • - false + +
  • NotRelated
  • + 0.1 @@ -295,6 +322,20 @@
  • CloseRelative
  • FarRelative
  • + +
  • + CloseRelative + 1 +
  • +
  • + FarRelative + 1 +
  • +
  • + NotRelated + 0.03 +
  • +
    diff --git a/Source/IdeologyAddon/Filters/RelationFilter.cs b/Source/IdeologyAddon/Filters/RelationFilter.cs index 32fa1ed..732ed7e 100644 --- a/Source/IdeologyAddon/Filters/RelationFilter.cs +++ b/Source/IdeologyAddon/Filters/RelationFilter.cs @@ -1,7 +1,6 @@ using RimWorld; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; using Verse; namespace RJWSexperience.Ideology.Filters @@ -13,14 +12,14 @@ namespace RJWSexperience.Ideology.Filters public class RelationFilter { public bool? isVeneratedAnimal; - public bool? isAlien; - public bool? isBloodRelated; public List hasOneOfRelations; public List hasNoneOfRelations; + public List hasOneOfRelationDegrees; private bool initialized = false; private HashSet hasOneOfRelationsHashed; private HashSet hasNoneOfRelationsHashed; + private HashSet hasOneOfRelationDegreesHashed; /// /// Check if the pair of pawns fits filter conditions @@ -31,9 +30,6 @@ namespace RJWSexperience.Ideology.Filters if (isVeneratedAnimal != null && isVeneratedAnimal != pawn.Ideo.IsVeneratedAnimal(partner)) return false; - //if (isAlien != null && isAlien != partner) - // return false; - if (!CheckRelations(pawn, partner)) return false; @@ -45,13 +41,15 @@ namespace RJWSexperience.Ideology.Filters if (!initialized) Initialize(); - if (hasNoneOfRelationsHashed == null && hasOneOfRelationsHashed == null && isBloodRelated == null) + if (hasNoneOfRelationsHashed == null && hasOneOfRelationsHashed == null && hasOneOfRelationDegreesHashed == null) return true; - IEnumerable relations = pawn.GetRelations(partner); - - if (isBloodRelated != null && isBloodRelated != relations.Any(def => def.familyByBloodRelation)) + if (hasOneOfRelationDegreesHashed != null && !hasOneOfRelationDegreesHashed.Contains(RelationHelpers.GetBloodRelationDegree(pawn, partner))) + { return false; + } + + IEnumerable relations = pawn.GetRelations(partner); if (hasOneOfRelationsHashed != null) { @@ -78,6 +76,9 @@ namespace RJWSexperience.Ideology.Filters if (!hasOneOfRelations.NullOrEmpty()) hasOneOfRelationsHashed = new HashSet(hasOneOfRelations); + if (!hasOneOfRelationDegrees.NullOrEmpty()) + hasOneOfRelationDegreesHashed = new HashSet(hasOneOfRelationDegrees); + initialized = true; } } diff --git a/Source/IdeologyAddon/Harmony.cs b/Source/IdeologyAddon/Harmony.cs index 08a78d0..d756855 100644 --- a/Source/IdeologyAddon/Harmony.cs +++ b/Source/IdeologyAddon/Harmony.cs @@ -1,25 +1,14 @@ -using HarmonyLib; -using RJWSexperience.Ideology.Patches; -using System.Reflection; +using System.Reflection; using Verse; namespace RJWSexperience.Ideology { [StaticConstructorOnStartup] - internal static class First + internal static class Harmony { - static First() + static Harmony() { - var harmony = new Harmony("RJW_Sexperience.Ideology"); - harmony.PatchAll(Assembly.GetExecutingAssembly()); - - if (ModLister.HasActiveModWithName("RJW Sexperience")) - { - harmony.Patch(AccessTools.Method("RJWSexperience.RJWUtility:ThrowVirginHistoryEvent"), - prefix: null, - postfix: new HarmonyMethod(typeof(Sexperience_Patch_ThrowVirginHistoryEvent), nameof(Sexperience_Patch_ThrowVirginHistoryEvent.Postfix)) - ); - } + new HarmonyLib.Harmony("RJW_Sexperience.Ideology").PatchAll(Assembly.GetExecutingAssembly()); } } } diff --git a/Source/IdeologyAddon/Patches/Sexperience_Patch.cs b/Source/IdeologyAddon/Patches/Sexperience_Patch.cs index 6951eea..1be61cd 100644 --- a/Source/IdeologyAddon/Patches/Sexperience_Patch.cs +++ b/Source/IdeologyAddon/Patches/Sexperience_Patch.cs @@ -1,11 +1,15 @@ -using rjw; +using HarmonyLib; +using rjw; using RJWSexperience.Ideology.HistoryEvents; using Verse; namespace RJWSexperience.Ideology.Patches { + [HarmonyPatch("RJWSexperience.RJWUtility", "ThrowVirginHistoryEvent")] public static class Sexperience_Patch_ThrowVirginHistoryEvent { + public static bool Prepare() => ModsConfig.IsActive("rjw.sexperience"); + public static void Postfix(Pawn exVirgin, Pawn partner, SexProps props, int degree) { const int femaleAfterSurgery = 1; diff --git a/Source/IdeologyAddon/Precepts/DefExtension_Incest.cs b/Source/IdeologyAddon/Precepts/DefExtension_Incest.cs index f4e474d..caf0ed0 100644 --- a/Source/IdeologyAddon/Precepts/DefExtension_Incest.cs +++ b/Source/IdeologyAddon/Precepts/DefExtension_Incest.cs @@ -1,5 +1,4 @@ -using RJWSexperience.Ideology.Filters; -using System.Collections.Generic; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Verse; @@ -12,5 +11,63 @@ namespace RJWSexperience.Ideology.Precepts public class DefExtension_Incest : DefModExtension { public List allowManualRomanceOnlyFor; + public List bloodRelationDegreeRomanceFactors; + + private Dictionary _relationDegreeFactorsDict; + + public bool TryGetRomanceChanceFactor(BloodRelationDegree relationDegree, out float romanceChanceFactor) + { + if (bloodRelationDegreeRomanceFactors.NullOrEmpty()) + { + romanceChanceFactor = 1f; + return false; + } + + if (_relationDegreeFactorsDict == null) + { + _relationDegreeFactorsDict = new Dictionary(); + foreach (BloodRelationDegreeFactor relationDegreeFactor in bloodRelationDegreeRomanceFactors) + { + _relationDegreeFactorsDict.Add((BloodRelationDegree)relationDegreeFactor.bloodRelationDegree, relationDegreeFactor.romanceChanceFactor); + } + } + + return _relationDegreeFactorsDict.TryGetValue(relationDegree, out romanceChanceFactor); + } + + public override IEnumerable ConfigErrors() + { + foreach (string error in base.ConfigErrors()) + { + yield return error; + } + + foreach (BloodRelationDegreeFactor factor in bloodRelationDegreeRomanceFactors) + { + foreach(string error in factor.ConfigErrors()) + { + yield return error; + } + } + } + + public class BloodRelationDegreeFactor + { + public BloodRelationDegree? bloodRelationDegree; + public float romanceChanceFactor; + + public IEnumerable ConfigErrors() + { + if (bloodRelationDegree == null) + { + yield return " is empty"; + } + + if (romanceChanceFactor == 0f) + { + yield return " should be > 0"; + } + } + } } } diff --git a/Source/IdeologyAddon/RelationHelpers.cs b/Source/IdeologyAddon/RelationHelpers.cs index 2a5fe77..1033307 100644 --- a/Source/IdeologyAddon/RelationHelpers.cs +++ b/Source/IdeologyAddon/RelationHelpers.cs @@ -11,6 +11,11 @@ namespace RJWSexperience.Ideology /// public static BloodRelationDegree GetBloodRelationDegree(Pawn pawn, Pawn partner) { + if (!pawn.relations.FamilyByBlood.Contains(partner)) + { + return BloodRelationDegree.NotRelated; + } + PawnRelationDef closestBloodRelation = pawn .GetRelations(partner) ?.Where(def => def.familyByBloodRelation) diff --git a/Source/IdeologyAddon/RomanceChanceFactorHelpers.cs b/Source/IdeologyAddon/RomanceChanceFactorHelpers.cs index 298916c..bae549e 100644 --- a/Source/IdeologyAddon/RomanceChanceFactorHelpers.cs +++ b/Source/IdeologyAddon/RomanceChanceFactorHelpers.cs @@ -1,4 +1,5 @@ using RimWorld; +using RJWSexperience.Ideology.Precepts; using System.Collections.Generic; using System.Linq; using Verse; @@ -17,13 +18,11 @@ namespace RJWSexperience.Ideology /// 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 (!pawn.relations.FamilyByBlood.Contains(partner)) { - if (incestuousPrecept == RsiPreceptDefOf.Incestuos_IncestOnly) + if (pawn.Ideo?.HasPrecept(RsiPreceptDefOf.Incestuos_IncestOnly) == true) { return parentRomanceChanceFactor; } @@ -33,6 +32,8 @@ namespace RJWSexperience.Ideology } } + PreceptDef incestuousPrecept = pawn.Ideo?.PreceptsListForReading.Select(precept => precept.def).FirstOrFallback(def => def.issue == VariousDefOf.Incestuos); + IEnumerable relations = pawn.GetRelations(partner).Where(def => def.familyByBloodRelation); foreach (PawnRelationDef relationDef in relations) { romanceChanceFactor *= GetRomanceChanceFactor(relationDef, incestuousPrecept); @@ -46,43 +47,23 @@ namespace RJWSexperience.Ideology /// public static float GetRomanceChanceFactor(PawnRelationDef relationDef, PreceptDef incestuousPrecept) { - if (incestuousPrecept == null || incestuousPrecept == RsiPreceptDefOf.Incestuos_Disapproved) // Default game setup + if (incestuousPrecept == null) { return relationDef.romanceChanceFactor; } - if (incestuousPrecept == RsiPreceptDefOf.Incestuos_Free) + var incestDefExt = incestuousPrecept.GetModExtension(); + + if (incestDefExt == null) { - return 1f; + return relationDef.romanceChanceFactor; } - else if (incestuousPrecept == RsiPreceptDefOf.Incestuos_Disapproved_CloseOnly) + + BloodRelationDegree relationDegree = RelationHelpers.GetBloodRelationDegree(relationDef); + + if (incestDefExt.TryGetRomanceChanceFactor(relationDegree, out var romanceChanceOverride)) { - if (relationDef.familyByBloodRelation && relationDef.importance > PawnRelationDefOf.Cousin.importance) - { - return relationDef.romanceChanceFactor; - } - else - { - return 1f; - } - } - else if (incestuousPrecept == RsiPreceptDefOf.Incestuos_Forbidden) - { - if (relationDef.familyByBloodRelation) - { - return parentRomanceChanceFactor; - } - } - else if (incestuousPrecept == RsiPreceptDefOf.Incestuos_IncestOnly) - { - if (!relationDef.familyByBloodRelation) - { - return parentRomanceChanceFactor; - } - else - { - return 1f; - } + return romanceChanceOverride; } return relationDef.romanceChanceFactor; diff --git a/Source/IdeologyAddon/RsiPreceptDefOf.cs b/Source/IdeologyAddon/RsiPreceptDefOf.cs index 977954a..1638e76 100644 --- a/Source/IdeologyAddon/RsiPreceptDefOf.cs +++ b/Source/IdeologyAddon/RsiPreceptDefOf.cs @@ -5,10 +5,6 @@ namespace RJWSexperience.Ideology [DefOf] public static class RsiPreceptDefOf { - 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;