Implement HistoryEvent overrides

This commit is contained in:
amevarashi 2022-07-03 20:04:28 +05:00
parent 724bcbe86b
commit bfddab0cf1
8 changed files with 213 additions and 98 deletions

View file

@ -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<PartnerDependentOverride> overrideRules = new List<PartnerDependentOverride>();
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);
}
}
}
}

View file

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

View file

@ -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<PawnRelationDef> hasNoneOfRelations;
private bool initialized = false;
private HashSet<PawnRelationDef> hasOneOfRelationsHashed;
private HashSet<PawnRelationDef> 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<PawnRelationDef> 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<PawnRelationDef>(hasNoneOfRelations);
if (!hasOneOfRelations.NullOrEmpty())
hasOneOfRelationsHashed = new HashSet<PawnRelationDef>(hasOneOfRelations);
initialized = true;
}
}
}

View file

@ -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<HistoryEventDefExtension_PartnerDependentOverrides>();
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<InteractionDefExtension_HistoryEvents>();
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<InteractionDefExtension_HistoryEvents>();
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<Need_Suppression>();

View file

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

View file

@ -43,6 +43,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="Ideology\HistoryEventDefExtension_PartnerDependentOverrides.cs" />
<Compile Include="Ideology\InteractionDefExtension_HistoryEvents.cs" />
<Compile Include="Ideology\GoodwillSituationWorker_MemeCompatibility.cs" />
<Compile Include="Harmony.cs" />
@ -58,6 +59,7 @@
<Compile Include="Ideology\Precepts\DefExtension_ModifyBestialityMtb.cs" />
<Compile Include="Ideology\Precepts\DefExtension_ModifyPreference.cs" />
<Compile Include="Ideology\Precepts\DefExtension_MultipleMemesRequired.cs" />
<Compile Include="Ideology\PartnerFilter.cs" />
<Compile Include="Ideology\Precepts\PreceptComp_KnowsMemoryThoughtTagged.cs" />
<Compile Include="Ideology\Rituals\JobGiver_GangbangConsensual.cs" />
<Compile Include="Ideology\Rituals\LordJob_Rituals.cs" />

View file

@ -26,18 +26,8 @@ namespace RJWSexperience.Ideology
[MayRequireIdeology] public static readonly HistoryEventDef WasRaped = DefDatabase<HistoryEventDef>.GetNamed("WasRaped");
[MayRequireIdeology] public static readonly HistoryEventDef WasRapedSlave = DefDatabase<HistoryEventDef>.GetNamed("WasRapedSlave");
[MayRequireIdeology] public static readonly HistoryEventDef WasRapedPrisoner = DefDatabase<HistoryEventDef>.GetNamed("WasRapedPrisoner");
[MayRequireIdeology] public static readonly HistoryEventDef VaginalSex = DefDatabase<HistoryEventDef>.GetNamed("VaginalSex");
[MayRequireIdeology] public static readonly HistoryEventDef AnalSex = DefDatabase<HistoryEventDef>.GetNamed("AnalSex");
[MayRequireIdeology] public static readonly HistoryEventDef OralSex = DefDatabase<HistoryEventDef>.GetNamed("OralSex");
[MayRequireIdeology] public static readonly HistoryEventDef MiscSex = DefDatabase<HistoryEventDef>.GetNamed("MiscSex");
[MayRequireIdeology] public static readonly HistoryEventDef PromiscuousSex = DefDatabase<HistoryEventDef>.GetNamed("PromiscuousSex");
[MayRequireIdeology] public static readonly HistoryEventDef RSI_CloseRelativeMarriage = DefDatabase<HistoryEventDef>.GetNamed("RSI_CloseRelativeMarriage");
[MayRequireIdeology] public static readonly HistoryEventDef RSI_IncestuosMarriage = DefDatabase<HistoryEventDef>.GetNamed("RSI_IncestuosMarriage");
[MayRequireIdeology] public static readonly HistoryEventDef RSI_NonIncestuosMarriage = DefDatabase<HistoryEventDef>.GetNamed("RSI_NonIncestuosMarriage");
[MayRequireIdeology] public static readonly HistoryEventDef RSI_CloseRelativeSex = DefDatabase<HistoryEventDef>.GetNamed("RSI_CloseRelativeSex");
[MayRequireIdeology] public static readonly HistoryEventDef RSI_IncestuosSex = DefDatabase<HistoryEventDef>.GetNamed("RSI_IncestuosSex");
[MayRequireIdeology] public static readonly HistoryEventDef RSI_NonIncestuosSex = DefDatabase<HistoryEventDef>.GetNamed("RSI_NonIncestuosSex");
[MayRequireIdeology] public static readonly HistoryEventDef SexWithCorpse = DefDatabase<HistoryEventDef>.GetNamed("SexWithCorpse");
[MayRequireIdeology] public static readonly HistoryEventDef Virgin_TakenF = DefDatabase<HistoryEventDef>.GetNamed("Virgin_TakenF");
[MayRequireIdeology] public static readonly HistoryEventDef Virgin_TakenM = DefDatabase<HistoryEventDef>.GetNamed("Virgin_TakenM");
[MayRequireIdeology] public static readonly HistoryEventDef Virgin_TookF = DefDatabase<HistoryEventDef>.GetNamed("Virgin_TookF");

View file

@ -21,6 +21,50 @@
<HistoryEventDef>
<defName>RSI_NonIncestuosMarriage</defName>
<label>Non-incestuos marriage</label>
<modExtensions>
<li Class="RJWSexperience.Ideology.HistoryEventDefExtension_PartnerDependentOverrides">
<overrideRules>
<li>
<filter>
<hasOneOfRelations>
<li>Parent</li>
<li>Child</li>
<li>Sibling</li>
<li>HalfSibling</li>
<li>Grandparent</li>
<li>Grandchild</li>
<li>NephewOrNiece</li>
<li>UncleOrAunt</li>
</hasOneOfRelations>
</filter>
<historyEventDef>RSI_CloseRelativeMarriage</historyEventDef>
</li>
<li>
<filter>
<hasOneOfRelations>
<li>Parent</li>
<li>Child</li>
<li>Sibling</li>
<li>HalfSibling</li>
<li>Grandparent</li>
<li>Grandchild</li>
<li>NephewOrNiece</li>
<li>UncleOrAunt</li>
<li>GreatGrandparent</li>
<li>GreatGrandchild</li>
<li>GranduncleOrGrandaunt</li>
<li>GrandnephewOrGrandniece</li>
<li>CousinOnceRemoved</li>
<li>SecondCousin</li>
<li>Cousin</li>
<li>Kin</li>
</hasOneOfRelations>
</filter>
<historyEventDef>RSI_IncestuosMarriage</historyEventDef>
</li>
</overrideRules>
</li>
</modExtensions>
</HistoryEventDef>
<HistoryEventDef>
@ -36,6 +80,50 @@
<HistoryEventDef>
<defName>RSI_NonIncestuosSex</defName>
<label>Non-incestuos sex</label>
<modExtensions>
<li Class="RJWSexperience.Ideology.HistoryEventDefExtension_PartnerDependentOverrides">
<overrideRules>
<li>
<filter>
<hasOneOfRelations>
<li>Parent</li>
<li>Child</li>
<li>Sibling</li>
<li>HalfSibling</li>
<li>Grandparent</li>
<li>Grandchild</li>
<li>NephewOrNiece</li>
<li>UncleOrAunt</li>
</hasOneOfRelations>
</filter>
<historyEventDef>RSI_CloseRelativeSex</historyEventDef>
</li>
<li>
<filter>
<hasOneOfRelations>
<li>Parent</li>
<li>Child</li>
<li>Sibling</li>
<li>HalfSibling</li>
<li>Grandparent</li>
<li>Grandchild</li>
<li>NephewOrNiece</li>
<li>UncleOrAunt</li>
<li>GreatGrandparent</li>
<li>GreatGrandchild</li>
<li>GranduncleOrGrandaunt</li>
<li>GrandnephewOrGrandniece</li>
<li>CousinOnceRemoved</li>
<li>SecondCousin</li>
<li>Cousin</li>
<li>Kin</li>
</hasOneOfRelations>
</filter>
<historyEventDef>RSI_IncestuosSex</historyEventDef>
</li>
</overrideRules>
</li>
</modExtensions>
</HistoryEventDef>
<!-- Precepts -->