diff --git a/RJWSexperience/IdeologyAddon/Ideology/HistoryEventDefExtension_PartnerDependentOverrides.cs b/RJWSexperience/IdeologyAddon/Ideology/HistoryEventDefExtension_PartnerDependentOverrides.cs new file mode 100644 index 0000000..3879d27 --- /dev/null +++ b/RJWSexperience/IdeologyAddon/Ideology/HistoryEventDefExtension_PartnerDependentOverrides.cs @@ -0,0 +1,29 @@ +using RimWorld; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using Verse; + +namespace RJWSexperience.Ideology +{ + public class HistoryEventDefExtension_PartnerDependentOverrides : DefModExtension + { + [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")] + public List overrideRules = new List(); + + public class PartnerDependentOverride + { + [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")] + public HistoryEventDef historyEventDef; + [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")] + public PartnerFilter filter; + + public bool Applies(Pawn pawn, Pawn partner) + { + if (filter == null) + return false; + + return filter.Applies(pawn, partner); + } + } + } +} diff --git a/RJWSexperience/IdeologyAddon/Ideology/IdeoUtility.cs b/RJWSexperience/IdeologyAddon/Ideology/IdeoUtility.cs index 9e8fad4..fe92ed1 100644 --- a/RJWSexperience/IdeologyAddon/Ideology/IdeoUtility.cs +++ b/RJWSexperience/IdeologyAddon/Ideology/IdeoUtility.cs @@ -37,7 +37,7 @@ namespace RJWSexperience.Ideology return true; } - public static bool IsIncest(Pawn pawn, Pawn partner, bool close) + public static bool IsIncest(Pawn pawn, Pawn partner) { IEnumerable relations = pawn.GetRelations(partner); if (relations.EnumerableNullOrEmpty()) @@ -45,15 +45,8 @@ namespace RJWSexperience.Ideology foreach (PawnRelationDef relation in relations) { - if (close) - { - if (relation.incestOpinionOffset < 0) - return true; - } - else if (relation.familyByBloodRelation) - { + if (relation.familyByBloodRelation) return true; - } } return false; } diff --git a/RJWSexperience/IdeologyAddon/Ideology/PartnerFilter.cs b/RJWSexperience/IdeologyAddon/Ideology/PartnerFilter.cs index c02b7af..c0f4439 100644 --- a/RJWSexperience/IdeologyAddon/Ideology/PartnerFilter.cs +++ b/RJWSexperience/IdeologyAddon/Ideology/PartnerFilter.cs @@ -21,6 +21,10 @@ namespace RJWSexperience.Ideology [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")] public List hasNoneOfRelations; + private bool initialized = false; + private HashSet hasOneOfRelationsHashed; + private HashSet hasNoneOfRelationsHashed; + public bool Applies(Pawn pawn, Pawn partner) { if (isAnimal != null && isAnimal != partner.IsAnimal()) @@ -35,34 +39,48 @@ namespace RJWSexperience.Ideology //if (isAlien != null && isAlien != partner) // return false; - if (!hasOneOfRelations.NullOrEmpty()) + if (!CheckRelations(pawn, partner)) + return false; + + return true; + } + + private bool CheckRelations(Pawn pawn, Pawn partner) + { + if (!initialized) + Initialize(); + + if (hasNoneOfRelationsHashed == null && hasOneOfRelationsHashed == null) + return true; + + IEnumerable relations = pawn.GetRelations(partner); + + if (hasOneOfRelationsHashed != null) { - if (pawn.relations == null) + if (relations.EnumerableNullOrEmpty()) return false; - bool found = false; - foreach (PawnRelationDef relationDef in hasOneOfRelations) - { - if (pawn.relations?.DirectRelationExists(relationDef, partner) == true) - { - found = true; - break; - } - } - if (!found) + if (!hasOneOfRelationsHashed.Overlaps(relations)) return false; } - if (!hasNoneOfRelations.NullOrEmpty() && pawn.relations != null) + if (hasNoneOfRelationsHashed != null && !relations.EnumerableNullOrEmpty() && hasNoneOfRelationsHashed.Overlaps(relations)) { - foreach (PawnRelationDef relationDef in hasNoneOfRelations) - { - if (pawn.relations.DirectRelationExists(relationDef, partner)) - return false; - } + return false; } return true; } + + private void Initialize() + { + if (!hasNoneOfRelations.NullOrEmpty()) + hasNoneOfRelationsHashed = new HashSet(hasNoneOfRelations); + + if (!hasOneOfRelations.NullOrEmpty()) + hasOneOfRelationsHashed = new HashSet(hasOneOfRelations); + + initialized = true; + } } } diff --git a/RJWSexperience/IdeologyAddon/Ideology/Patches/RJW_Patch_Ideo.cs b/RJWSexperience/IdeologyAddon/Ideology/Patches/RJW_Patch_Ideo.cs index 57f41ff..606b461 100644 --- a/RJWSexperience/IdeologyAddon/Ideology/Patches/RJW_Patch_Ideo.cs +++ b/RJWSexperience/IdeologyAddon/Ideology/Patches/RJW_Patch_Ideo.cs @@ -16,11 +16,28 @@ namespace RJWSexperience.Ideology.Patches { return new HistoryEvent(def, pawn.Named(HistoryEventArgsNames.Doer), tag.Named(HistoryEventArgsNamesCustom.Tag), partner.Named(HistoryEventArgsNamesCustom.Partner)); } + public static HistoryEvent CreateEvent(this HistoryEventDef def, Pawn pawn) { return new HistoryEvent(def, pawn.Named(HistoryEventArgsNames.Doer)); } + public static HistoryEvent CreateEventWithPartner(this HistoryEventDef def, Pawn pawn, Pawn partner) + { + HistoryEventDefExtension_PartnerDependentOverrides overrides = def.GetModExtension(); + + if (overrides == null) + return new HistoryEvent(def, pawn.Named(HistoryEventArgsNames.Doer), partner.Named(HistoryEventArgsNamesCustom.Partner)); + + foreach (var rule in overrides.overrideRules) + { + if (rule.Applies(pawn, partner)) + return rule.historyEventDef.CreateEventWithPartner(pawn, partner); + } + + return new HistoryEvent(def, pawn.Named(HistoryEventArgsNames.Doer), partner.Named(HistoryEventArgsNamesCustom.Partner)); + } + public static Faction GetFactionUsingPrecept(this Pawn baby, out Ideo ideo) { Faction playerfaction = Find.FactionManager.OfPlayer; @@ -90,56 +107,60 @@ namespace RJWSexperience.Ideology.Patches { public static void Postfix(SexProps props) { - Pawn pawn = props.pawn; - Pawn partner = props.partner; + InteractionDefExtension_HistoryEvents interactionEvents = props.dictionaryKey.GetModExtension(); if (props.hasPartner()) { - if (xxx.is_human(pawn)) - AfterSexHuman(pawn, partner, props.isRape); - else if (xxx.is_human(partner)) - AfterSexHuman(partner, pawn, false, true); + if (xxx.is_human(props.pawn)) + AfterSexHuman(props.pawn, props.partner, props.isRape); + else if (xxx.is_human(props.partner)) + AfterSexHuman(props.partner, props.pawn, false); + + if (xxx.is_human(props.partner) && props.isRape) + { + if (props.partner.IsPrisoner) + props.partner.guest.will = Math.Max(0, props.partner.guest.will - 0.2f); + if (props.partner.IsSlave) + RapeEffectSlave(props.partner); + } + + if (interactionEvents != null) + { + foreach (HistoryEventDef eventDef in interactionEvents.pawnEvents) + Find.HistoryEventsManager.RecordEvent(eventDef.CreateEventWithPartner(props.pawn, props.partner)); + + foreach (HistoryEventDef eventDef in interactionEvents.partnerEvents) + Find.HistoryEventsManager.RecordEvent(eventDef.CreateEventWithPartner(props.partner, props.pawn)); + } } - - InteractionDefExtension_HistoryEvents interactionEvents = props.dictionaryKey.GetModExtension(); - if (interactionEvents != null) + else { - foreach (HistoryEventDef eventDef in interactionEvents.pawnEvents) - Find.HistoryEventsManager.RecordEvent(eventDef.CreateEvent(pawn)); - - foreach (HistoryEventDef eventDef in interactionEvents.partnerEvents) - Find.HistoryEventsManager.RecordEvent(eventDef.CreateEvent(partner)); + if (interactionEvents != null) + { + foreach (HistoryEventDef eventDef in interactionEvents.pawnEvents) + Find.HistoryEventsManager.RecordEvent(eventDef.CreateEvent(props.pawn)); + } } } - public static void AfterSexHuman(Pawn human, Pawn partner, bool rape, bool isHumanReceiving = false) + public static void AfterSexHuman(Pawn human, Pawn partner, bool rape) { - HistoryEventDef incestEvent = GetIncestTypeEvent(human, partner); - Find.HistoryEventsManager.RecordEvent(incestEvent.CreateEvent(human)); - Find.HistoryEventsManager.RecordEvent(incestEvent.CreateEvent(partner)); + Find.HistoryEventsManager.RecordEvent(VariousDefOf.RSI_NonIncestuosSex.CreateEventWithPartner(human, partner)); + Find.HistoryEventsManager.RecordEvent(VariousDefOf.RSI_NonIncestuosSex.CreateEventWithPartner(partner, human)); if (partner.IsAnimal()) { - string tag = HETag.Gender(human); - if (isHumanReceiving && rape) - { - tag += HETag.BeenRaped; - - if (human.IsSlave) - RapeEffectSlave(human); - } - if (human.Ideo?.IsVeneratedAnimal(partner) ?? false) - Find.HistoryEventsManager.RecordEvent(VariousDefOf.SexWithVeneratedAnimal.CreateTaggedEvent(human, tag, partner)); + Find.HistoryEventsManager.RecordEvent(VariousDefOf.SexWithVeneratedAnimal.CreateEventWithPartner(human, partner)); else - Find.HistoryEventsManager.RecordEvent(VariousDefOf.SexWithNonVeneratedAnimal.CreateTaggedEvent(human, tag, partner)); + Find.HistoryEventsManager.RecordEvent(VariousDefOf.SexWithNonVeneratedAnimal.CreateEventWithPartner(human, partner)); if (human.Ideo != null && human.relations?.DirectRelationExists(PawnRelationDefOf.Bond, partner) == true) - Find.HistoryEventsManager.RecordEvent(VariousDefOf.SexWithBondedAnimal.CreateTaggedEvent(human, tag, partner)); + Find.HistoryEventsManager.RecordEvent(VariousDefOf.SexWithBondedAnimal.CreateEventWithPartner(human, partner)); else - Find.HistoryEventsManager.RecordEvent(VariousDefOf.SexWithNonBondAnimal.CreateTaggedEvent(human, tag, partner)); + Find.HistoryEventsManager.RecordEvent(VariousDefOf.SexWithNonBondAnimal.CreateEventWithPartner(human, partner)); - Find.HistoryEventsManager.RecordEvent(VariousDefOf.SexWithAnimal.CreateTaggedEvent(human, tag, partner)); + Find.HistoryEventsManager.RecordEvent(VariousDefOf.SexWithAnimal.CreateEventWithPartner(human, partner)); } else if (xxx.is_human(partner)) { @@ -149,13 +170,11 @@ namespace RJWSexperience.Ideology.Patches { Find.HistoryEventsManager.RecordEvent(VariousDefOf.RapedSlave.CreateTaggedEvent(human, HETag.Rape + HETag.Gender(human), partner)); Find.HistoryEventsManager.RecordEvent(VariousDefOf.WasRapedSlave.CreateTaggedEvent(partner, HETag.BeenRaped + HETag.Gender(partner), human)); - RapeEffectSlave(partner); } else if (partner.IsPrisoner) { Find.HistoryEventsManager.RecordEvent(VariousDefOf.RapedPrisoner.CreateTaggedEvent(human, HETag.Rape + HETag.Gender(human), partner)); Find.HistoryEventsManager.RecordEvent(VariousDefOf.WasRapedPrisoner.CreateTaggedEvent(partner, HETag.BeenRaped + HETag.Gender(partner), human)); - partner.guest.will = Math.Max(0, partner.guest.will - 0.2f); } else { @@ -166,17 +185,6 @@ namespace RJWSexperience.Ideology.Patches } } - private static HistoryEventDef GetIncestTypeEvent(Pawn pawn, Pawn partner) - { - if (IdeoUtility.IsIncest(pawn, partner, true)) - return VariousDefOf.RSI_CloseRelativeSex; - - if (IdeoUtility.IsIncest(pawn, partner, false)) - return VariousDefOf.RSI_IncestuosSex; - - return VariousDefOf.RSI_NonIncestuosSex; - } - public static void RapeEffectSlave(Pawn victim) { Need_Suppression suppression = victim.needs.TryGetNeed(); diff --git a/RJWSexperience/IdeologyAddon/Ideology/Patches/Rimworld_Patch.cs b/RJWSexperience/IdeologyAddon/Ideology/Patches/Rimworld_Patch.cs index 6b612d6..c6799db 100644 --- a/RJWSexperience/IdeologyAddon/Ideology/Patches/Rimworld_Patch.cs +++ b/RJWSexperience/IdeologyAddon/Ideology/Patches/Rimworld_Patch.cs @@ -12,21 +12,8 @@ namespace RJWSexperience.Ideology.Patches { public static void Postfix(Pawn firstPawn, Pawn secondPawn) { - if (IdeoUtility.IsIncest(firstPawn, secondPawn, false)) - { - if (IdeoUtility.IsIncest(firstPawn, secondPawn, true)) - { - Find.HistoryEventsManager.RecordEvent(VariousDefOf.RSI_CloseRelativeMarriage.CreateEvent(firstPawn)); - Find.HistoryEventsManager.RecordEvent(VariousDefOf.RSI_CloseRelativeMarriage.CreateEvent(secondPawn)); - } - Find.HistoryEventsManager.RecordEvent(VariousDefOf.RSI_IncestuosMarriage.CreateEvent(firstPawn)); - Find.HistoryEventsManager.RecordEvent(VariousDefOf.RSI_IncestuosMarriage.CreateEvent(secondPawn)); - } - else - { - Find.HistoryEventsManager.RecordEvent(VariousDefOf.RSI_NonIncestuosMarriage.CreateEvent(firstPawn)); - Find.HistoryEventsManager.RecordEvent(VariousDefOf.RSI_NonIncestuosMarriage.CreateEvent(secondPawn)); - } + Find.HistoryEventsManager.RecordEvent(VariousDefOf.RSI_NonIncestuosMarriage.CreateEventWithPartner(firstPawn, secondPawn)); + Find.HistoryEventsManager.RecordEvent(VariousDefOf.RSI_NonIncestuosMarriage.CreateEventWithPartner(secondPawn, firstPawn)); } } @@ -36,7 +23,7 @@ namespace RJWSexperience.Ideology.Patches public static void Postfix(Pawn otherPawn, Pawn ___pawn, ref float __result) { Ideo ideo = ___pawn.Ideo; - if (ideo?.HasPrecept(VariousDefOf.Incestuos_IncestOnly) == true && IdeoUtility.IsIncest(___pawn, otherPawn, false)) + if (ideo?.HasPrecept(VariousDefOf.Incestuos_IncestOnly) == true && IdeoUtility.IsIncest(___pawn, otherPawn)) { __result *= 8f; } diff --git a/RJWSexperience/IdeologyAddon/IdeologyAddon.csproj b/RJWSexperience/IdeologyAddon/IdeologyAddon.csproj index 4e5b461..e374324 100644 --- a/RJWSexperience/IdeologyAddon/IdeologyAddon.csproj +++ b/RJWSexperience/IdeologyAddon/IdeologyAddon.csproj @@ -43,6 +43,7 @@ + @@ -58,6 +59,7 @@ + diff --git a/RJWSexperience/IdeologyAddon/VariousDefOf.cs b/RJWSexperience/IdeologyAddon/VariousDefOf.cs index bbfa4f9..35cd518 100644 --- a/RJWSexperience/IdeologyAddon/VariousDefOf.cs +++ b/RJWSexperience/IdeologyAddon/VariousDefOf.cs @@ -26,18 +26,8 @@ namespace RJWSexperience.Ideology [MayRequireIdeology] public static readonly HistoryEventDef WasRaped = DefDatabase.GetNamed("WasRaped"); [MayRequireIdeology] public static readonly HistoryEventDef WasRapedSlave = DefDatabase.GetNamed("WasRapedSlave"); [MayRequireIdeology] public static readonly HistoryEventDef WasRapedPrisoner = DefDatabase.GetNamed("WasRapedPrisoner"); - [MayRequireIdeology] public static readonly HistoryEventDef VaginalSex = DefDatabase.GetNamed("VaginalSex"); - [MayRequireIdeology] public static readonly HistoryEventDef AnalSex = DefDatabase.GetNamed("AnalSex"); - [MayRequireIdeology] public static readonly HistoryEventDef OralSex = DefDatabase.GetNamed("OralSex"); - [MayRequireIdeology] public static readonly HistoryEventDef MiscSex = DefDatabase.GetNamed("MiscSex"); - [MayRequireIdeology] public static readonly HistoryEventDef PromiscuousSex = DefDatabase.GetNamed("PromiscuousSex"); - [MayRequireIdeology] public static readonly HistoryEventDef RSI_CloseRelativeMarriage = DefDatabase.GetNamed("RSI_CloseRelativeMarriage"); - [MayRequireIdeology] public static readonly HistoryEventDef RSI_IncestuosMarriage = DefDatabase.GetNamed("RSI_IncestuosMarriage"); [MayRequireIdeology] public static readonly HistoryEventDef RSI_NonIncestuosMarriage = DefDatabase.GetNamed("RSI_NonIncestuosMarriage"); - [MayRequireIdeology] public static readonly HistoryEventDef RSI_CloseRelativeSex = DefDatabase.GetNamed("RSI_CloseRelativeSex"); - [MayRequireIdeology] public static readonly HistoryEventDef RSI_IncestuosSex = DefDatabase.GetNamed("RSI_IncestuosSex"); [MayRequireIdeology] public static readonly HistoryEventDef RSI_NonIncestuosSex = DefDatabase.GetNamed("RSI_NonIncestuosSex"); - [MayRequireIdeology] public static readonly HistoryEventDef SexWithCorpse = DefDatabase.GetNamed("SexWithCorpse"); [MayRequireIdeology] public static readonly HistoryEventDef Virgin_TakenF = DefDatabase.GetNamed("Virgin_TakenF"); [MayRequireIdeology] public static readonly HistoryEventDef Virgin_TakenM = DefDatabase.GetNamed("Virgin_TakenM"); [MayRequireIdeology] public static readonly HistoryEventDef Virgin_TookF = DefDatabase.GetNamed("Virgin_TookF"); diff --git a/RJWSexperience_Ideology/Defs/PreceptDefs/Precepts_Incest.xml b/RJWSexperience_Ideology/Defs/PreceptDefs/Precepts_Incest.xml index 485a77c..e97d4aa 100644 --- a/RJWSexperience_Ideology/Defs/PreceptDefs/Precepts_Incest.xml +++ b/RJWSexperience_Ideology/Defs/PreceptDefs/Precepts_Incest.xml @@ -21,6 +21,50 @@ RSI_NonIncestuosMarriage + +
  • + +
  • + + +
  • Parent
  • +
  • Child
  • +
  • Sibling
  • +
  • HalfSibling
  • +
  • Grandparent
  • +
  • Grandchild
  • +
  • NephewOrNiece
  • +
  • UncleOrAunt
  • + + + RSI_CloseRelativeMarriage + +
  • + + +
  • Parent
  • +
  • Child
  • +
  • Sibling
  • +
  • HalfSibling
  • +
  • Grandparent
  • +
  • Grandchild
  • +
  • NephewOrNiece
  • +
  • UncleOrAunt
  • +
  • GreatGrandparent
  • +
  • GreatGrandchild
  • +
  • GranduncleOrGrandaunt
  • +
  • GrandnephewOrGrandniece
  • +
  • CousinOnceRemoved
  • +
  • SecondCousin
  • +
  • Cousin
  • +
  • Kin
  • + + + RSI_IncestuosMarriage + + + +
    @@ -36,6 +80,50 @@ RSI_NonIncestuosSex + +
  • + +
  • + + +
  • Parent
  • +
  • Child
  • +
  • Sibling
  • +
  • HalfSibling
  • +
  • Grandparent
  • +
  • Grandchild
  • +
  • NephewOrNiece
  • +
  • UncleOrAunt
  • + + + RSI_CloseRelativeSex + +
  • + + +
  • Parent
  • +
  • Child
  • +
  • Sibling
  • +
  • HalfSibling
  • +
  • Grandparent
  • +
  • Grandchild
  • +
  • NephewOrNiece
  • +
  • UncleOrAunt
  • +
  • GreatGrandparent
  • +
  • GreatGrandchild
  • +
  • GranduncleOrGrandaunt
  • +
  • GrandnephewOrGrandniece
  • +
  • CousinOnceRemoved
  • +
  • SecondCousin
  • +
  • Cousin
  • +
  • Kin
  • + + + RSI_IncestuosSex + + + +