diff --git a/1.4/Assemblies/RJWSexperience.Ideology.dll b/1.4/Assemblies/RJWSexperience.Ideology.dll
index ab82b7a..88b1f5a 100644
Binary files a/1.4/Assemblies/RJWSexperience.Ideology.dll and b/1.4/Assemblies/RJWSexperience.Ideology.dll differ
diff --git a/1.4/Defs/PreceptDefs/Precepts_Incest.xml b/1.4/Defs/PreceptDefs/Precepts_Incest.xml
index df0e490..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,24 +37,9 @@
-
- Parent
- Child
- Sibling
- HalfSibling
- Grandparent
- Grandchild
- NephewOrNiece
- UncleOrAunt
- GreatGrandparent
- GreatGrandchild
- GranduncleOrGrandaunt
- GrandnephewOrGrandniece
- CousinOnceRemoved
- SecondCousin
- Cousin
- Kin
-
+
+ FarRelative
+
RSI_IncestuosMarriage
@@ -90,16 +68,9 @@
-
- Parent
- Child
- Sibling
- HalfSibling
- Grandparent
- Grandchild
- NephewOrNiece
- UncleOrAunt
-
+
+ CloseRelative
+
RSI_CloseRelativeSex
@@ -107,24 +78,9 @@
-
- Parent
- Child
- Sibling
- HalfSibling
- Grandparent
- Grandchild
- NephewOrNiece
- UncleOrAunt
- GreatGrandparent
- GreatGrandchild
- GranduncleOrGrandaunt
- GrandnephewOrGrandniece
- CousinOnceRemoved
- SecondCousin
- Cousin
- Kin
-
+
+ FarRelative
+
RSI_IncestuosSex
@@ -145,6 +101,29 @@
60
1000
100
+
+
+
+ CloseRelative
+ FarRelative
+ NotRelated
+
+
+
+ CloseRelative
+ 1
+
+
+ FarRelative
+ 1
+
+
+ NotRelated
+ 1
+
+
+
+
@@ -172,16 +151,9 @@
-
- Parent
- Child
- Sibling
- HalfSibling
- Grandparent
- Grandchild
- NephewOrNiece
- UncleOrAunt
-
+
+ CloseRelative
+
Spouse
@@ -191,6 +163,22 @@
+
+
+ FarRelative
+ NotRelated
+
+
+
+ FarRelative
+ 1
+
+
+ NotRelated
+ 1
+
+
+
@@ -223,24 +211,10 @@
-
- Parent
- Child
- Sibling
- HalfSibling
- Grandparent
- Grandchild
- NephewOrNiece
- UncleOrAunt
- GreatGrandparent
- GreatGrandchild
- GranduncleOrGrandaunt
- GrandnephewOrGrandniece
- CousinOnceRemoved
- SecondCousin
- Cousin
- Kin
-
+
+ CloseRelative
+ FarRelative
+
Spouse
@@ -282,24 +256,10 @@
-
- Parent
- Child
- Sibling
- HalfSibling
- Grandparent
- Grandchild
- NephewOrNiece
- UncleOrAunt
- GreatGrandparent
- GreatGrandchild
- GranduncleOrGrandaunt
- GrandnephewOrGrandniece
- CousinOnceRemoved
- SecondCousin
- Cousin
- Kin
-
+
+ CloseRelative
+ FarRelative
+
Spouse
@@ -309,6 +269,18 @@
+
+
+
+ CloseRelative
+ 0.03
+
+
+ FarRelative
+ 0.03
+
+
+
@@ -320,9 +292,6 @@
High
0
1000
-
- Zoophile
-
RSI_NonIncestuosMarriage
@@ -339,30 +308,35 @@
-
- Parent
- Child
- Sibling
- HalfSibling
- Grandparent
- Grandchild
- NephewOrNiece
- UncleOrAunt
- GreatGrandparent
- GreatGrandchild
- GranduncleOrGrandaunt
- GrandnephewOrGrandniece
- CousinOnceRemoved
- SecondCousin
- Cousin
- Kin
-
+
+ NotRelated
+
- 2.0
+ 0.1
+
+
+ CloseRelative
+ FarRelative
+
+
+
+ CloseRelative
+ 1
+
+
+ FarRelative
+ 1
+
+
+ NotRelated
+ 0.03
+
+
+
diff --git a/1.4/Defs/PreceptDefs/Precepts_Pregnancy.xml b/1.4/Defs/PreceptDefs/Precepts_Pregnancy.xml
index 7e5b69f..bdd6015 100644
--- a/1.4/Defs/PreceptDefs/Precepts_Pregnancy.xml
+++ b/1.4/Defs/PreceptDefs/Precepts_Pregnancy.xml
@@ -100,14 +100,14 @@
- Pregnancy_Respected_Pregnant
+ Pregnancy_Respected_Pregnant
RJWSexperience.Ideology.PreceptWorkers.ThoughtWorker_Precept_Pregnant
Thought_Situational
I am pregnant. This makes me a pillar of society.
- 5
+ 10
@@ -120,19 +120,19 @@
I am soon making our colony stronger.
- 10
+ 5
- Pregnancy_Respected_Pregnant_Social
+ Pregnancy_Respected_Pregnant_Social
RJWSexperience.Ideology.PreceptWorkers.ThoughtWorker_Precept_Pregnant_Social
Thought_SituationalSocial
- 10
+ 20
@@ -144,7 +144,7 @@
- 20
+ 10
diff --git a/1.4/Defs/PreceptDefs/Precepts_Submissive.xml b/1.4/Defs/PreceptDefs/Precepts_Submissive.xml
index e69c135..aa7ae4d 100644
--- a/1.4/Defs/PreceptDefs/Precepts_Submissive.xml
+++ b/1.4/Defs/PreceptDefs/Precepts_Submissive.xml
@@ -76,11 +76,11 @@
BeenRaped_NotSubmissive
Female
-
+
@@ -140,11 +140,11 @@
BeenRaped_NotSubmissive
Male
-
+
diff --git a/1.4/Patches/RJW_ThoughtDefs.xml b/1.4/Patches/RJW_ThoughtDefs.xml
index e2e3f6e..30a1b66 100644
--- a/1.4/Patches/RJW_ThoughtDefs.xml
+++ b/1.4/Patches/RJW_ThoughtDefs.xml
@@ -8,6 +8,7 @@
Bestiality_OnlyVenerated
Bestiality_BondOnly
Bestiality_Honorable
+ Bestiality_Acceptable
@@ -19,6 +20,7 @@
Bestiality_OnlyVenerated
Bestiality_BondOnly
Bestiality_Honorable
+ Bestiality_Acceptable
@@ -30,6 +32,7 @@
Bestiality_OnlyVenerated
Bestiality_BondOnly
Bestiality_Honorable
+ Bestiality_Acceptable
@@ -41,6 +44,7 @@
Bestiality_OnlyVenerated
Bestiality_BondOnly
Bestiality_Honorable
+ Bestiality_Acceptable
@@ -52,6 +56,7 @@
Bestiality_OnlyVenerated
Bestiality_BondOnly
Bestiality_Honorable
+ Bestiality_Acceptable
@@ -63,6 +68,7 @@
Bestiality_OnlyVenerated
Bestiality_BondOnly
Bestiality_Honorable
+ Bestiality_Acceptable
diff --git a/About/Manifest.xml b/About/Manifest.xml
index bac3aa3..c6907d3 100644
--- a/About/Manifest.xml
+++ b/About/Manifest.xml
@@ -1,7 +1,7 @@
RJWSexperienceIdeology
- 1.0.1.2
+ 1.0.2.1
RimJobWorld >= 5.3.0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f9784d2..97418aa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,15 @@
+## Version 1.0.2.1
+* Fixed SecondaryRomanceChanceFactor patch
+## Version 1.0.2.0
+* Removed Incestuos_IncestOnly conflict with Zoophile
+* Patched manual romance to respect incestuous precepts
+* Patched SecondaryRomanceChanceFactor for incest precept
+* Added settings to disable ether of patches if needed
+* Changed Incestuos_IncestOnly would_fuck multiplier for blood related pawns: 2.0 -> 1.0
+* Changed Incestuos_IncestOnly would_fuck multiplier for non-blood related pawns: 1.0 -> 0.1
+* Removed "not obedient" social thought for raping a slave
+* Bestiality_Acceptable now nullifies RJW bestiality thoughts
+* Fixed swapped baseMoodEffect of holy and elevated pregnancy precepts
## Version 1.0.1.2
* Removed 100% certainty spam for sex proselyzing
* Maybe removed sex proselyzing error with bestiality
diff --git a/Languages/English/Keyed/RJW_Sexperience.xml b/Languages/English/Keyed/RJW_Sexperience.xml
index 9550b00..83d2026 100644
--- a/Languages/English/Keyed/RJW_Sexperience.xml
+++ b/Languages/English/Keyed/RJW_Sexperience.xml
@@ -9,4 +9,16 @@
not animal
capable of sex is required
+ Enable romance patch for incest precepts*
+ Patch for incest precepts to affect RomanceChanceFactor. May conflict with romance mods./n/n* Requires a game restart to apply changes
+ Enable manual romance patch for incest precepts*
+ Patch for incest precepts to affect manual romance options./n/n* Requires a game restart to apply changes
+
+ Time between bestiality attempts x{0}
+ Time between masturbation attempts x{0}
+ Time between necrophilia attempts x{0}
+ Time between rape attempts x{0}
+
+
+
\ 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..55838d7 100644
--- a/Source/IdeologyAddon/DebugAction.cs
+++ b/Source/IdeologyAddon/DebugAction.cs
@@ -1,20 +1,37 @@
using rjw;
using RJWSexperience.Ideology.HistoryEvents;
+using RJWSexperience.Ideology.Patches;
+using System.Collections.Generic;
using System.Linq;
using Verse;
namespace RJWSexperience.Ideology
{
- internal class DebugAction
+ internal static class DebugAction
{
[DebugAction("RJW Sexperience Ideology", "Test marriage event", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.PlayingOnMap)]
- private static void GenerateMarriageEvent(Pawn p)
+ public static void GenerateMarriageEvent(Pawn p)
{
Pawn hero = p.Map.PlayerPawnsForStoryteller.First(x => x.IsDesignatedHero());
if (hero == null)
return;
- RsiHistoryEventDefOf.RSI_NonIncestuosMarriage.RecordEventWithPartner(hero, p);
- RsiHistoryEventDefOf.RSI_NonIncestuosMarriage.RecordEventWithPartner(p, hero);
+ RsiDefOf.HistoryEvent.RSI_NonIncestuosMarriage.RecordEventWithPartner(hero, p);
+ RsiDefOf.HistoryEvent.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/RelationFilter.cs b/Source/IdeologyAddon/Filters/RelationFilter.cs
similarity index 64%
rename from Source/IdeologyAddon/RelationFilter.cs
rename to Source/IdeologyAddon/Filters/RelationFilter.cs
index cff5738..732ed7e 100644
--- a/Source/IdeologyAddon/RelationFilter.cs
+++ b/Source/IdeologyAddon/Filters/RelationFilter.cs
@@ -3,31 +3,33 @@ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Verse;
-namespace RJWSexperience.Ideology
+namespace RJWSexperience.Ideology.Filters
{
+ ///
+ /// Filter to describe how one pawn sees another
+ ///
+ [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Def loader")]
public class RelationFilter
{
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
public bool? isVeneratedAnimal;
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
- public bool? isAlien;
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
public List hasOneOfRelations;
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
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
+ ///
public bool Applies(Pawn pawn, Pawn partner)
{
+ // Fail if any single condition fails
if (isVeneratedAnimal != null && isVeneratedAnimal != pawn.Ideo.IsVeneratedAnimal(partner))
return false;
- //if (isAlien != null && isAlien != partner)
- // return false;
-
if (!CheckRelations(pawn, partner))
return false;
@@ -39,9 +41,14 @@ namespace RJWSexperience.Ideology
if (!initialized)
Initialize();
- if (hasNoneOfRelationsHashed == null && hasOneOfRelationsHashed == null)
+ if (hasNoneOfRelationsHashed == null && hasOneOfRelationsHashed == null && hasOneOfRelationDegreesHashed == null)
return true;
+ if (hasOneOfRelationDegreesHashed != null && !hasOneOfRelationDegreesHashed.Contains(RelationHelpers.GetBloodRelationDegree(pawn, partner)))
+ {
+ return false;
+ }
+
IEnumerable relations = pawn.GetRelations(partner);
if (hasOneOfRelationsHashed != null)
@@ -69,6 +76,9 @@ namespace RJWSexperience.Ideology
if (!hasOneOfRelations.NullOrEmpty())
hasOneOfRelationsHashed = new HashSet(hasOneOfRelations);
+ if (!hasOneOfRelationDegrees.NullOrEmpty())
+ hasOneOfRelationDegreesHashed = new HashSet(hasOneOfRelationDegrees);
+
initialized = true;
}
}
diff --git a/Source/IdeologyAddon/SinglePawnFilter.cs b/Source/IdeologyAddon/Filters/SinglePawnFilter.cs
similarity index 50%
rename from Source/IdeologyAddon/SinglePawnFilter.cs
rename to Source/IdeologyAddon/Filters/SinglePawnFilter.cs
index daa240f..40e7a0a 100644
--- a/Source/IdeologyAddon/SinglePawnFilter.cs
+++ b/Source/IdeologyAddon/Filters/SinglePawnFilter.cs
@@ -2,19 +2,24 @@
using System.Diagnostics.CodeAnalysis;
using Verse;
-namespace RJWSexperience.Ideology
+namespace RJWSexperience.Ideology.Filters
{
+ ///
+ /// Filter to describe one pawn
+ ///
+ [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Def loader")]
public class SinglePawnFilter
{
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
public bool? isAnimal;
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
public bool? isSlave;
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
public bool? isPrisoner;
+ ///
+ /// Check if pawn fits filter conditions
+ ///
public bool Applies(Pawn pawn)
{
+ // Fail if any single condition fails
if (isAnimal != null && isAnimal != pawn.IsAnimal())
return false;
diff --git a/Source/IdeologyAddon/Filters/TwoPawnFilter.cs b/Source/IdeologyAddon/Filters/TwoPawnFilter.cs
new file mode 100644
index 0000000..c0580b0
--- /dev/null
+++ b/Source/IdeologyAddon/Filters/TwoPawnFilter.cs
@@ -0,0 +1,34 @@
+using System.Diagnostics.CodeAnalysis;
+using Verse;
+
+namespace RJWSexperience.Ideology.Filters
+{
+ ///
+ /// Filter to describe two pawns and relations between them
+ ///
+ [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Def loader")]
+ public class TwoPawnFilter
+ {
+ public SinglePawnFilter doer;
+ public SinglePawnFilter partner;
+ public RelationFilter relations;
+
+ ///
+ /// Check if the pair of pawns fits filter conditions
+ ///
+ public bool Applies(Pawn pawn, Pawn partner)
+ {
+ // Fail if any single condition fails
+ if (doer?.Applies(pawn) == false)
+ return false;
+
+ if (this.partner?.Applies(partner) == false)
+ return false;
+
+ if (relations?.Applies(pawn, partner) == false)
+ return false;
+
+ return 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/HistoryEvents/TwoPawnEventRule.cs b/Source/IdeologyAddon/HistoryEvents/TwoPawnEventRule.cs
index dc61b89..9c9e3f1 100644
--- a/Source/IdeologyAddon/HistoryEvents/TwoPawnEventRule.cs
+++ b/Source/IdeologyAddon/HistoryEvents/TwoPawnEventRule.cs
@@ -1,16 +1,22 @@
using RimWorld;
+using RJWSexperience.Ideology.Filters;
using System.Diagnostics.CodeAnalysis;
using Verse;
namespace RJWSexperience.Ideology.HistoryEvents
{
+ ///
+ /// Type to associate single HistoryEventDef with a TwoPawnFilter
+ ///
+ [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Def loader")]
public class TwoPawnEventRule
{
- [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 TwoPawnFilter filter;
+ ///
+ /// Check if the pair of pawns fits filter conditions
+ ///
public bool Applies(Pawn pawn, Pawn partner) => filter?.Applies(pawn, partner) == true;
}
}
diff --git a/Source/IdeologyAddon/IdeoUtility.cs b/Source/IdeologyAddon/IdeoUtility.cs
index 4b44cce..05ffd75 100644
--- a/Source/IdeologyAddon/IdeoUtility.cs
+++ b/Source/IdeologyAddon/IdeoUtility.cs
@@ -12,9 +12,9 @@ namespace RJWSexperience.Ideology
if (ideo == null)
return false;
- if (ideo.HasPrecept(VariousDefOf.Submissive_Female) && pawn.gender == Gender.Female)
+ if (ideo.HasPrecept(RsiDefOf.Precept.Submissive_Female) && pawn.gender == Gender.Female)
return true;
- else if (ideo.HasPrecept(VariousDefOf.Submissive_Male) && pawn.gender == Gender.Male)
+ else if (ideo.HasPrecept(RsiDefOf.Precept.Submissive_Male) && pawn.gender == Gender.Male)
return true;
return false;
@@ -89,7 +89,7 @@ namespace RJWSexperience.Ideology
Hediff pregnancy = PregnancyHelper.GetPregnancy(pawn);
// Currently RJW does not check Biotech pregnancy
- if (pregnancy == null && VariousDefOf.PregnantHuman != null)
+ if (pregnancy == null && RsiDefOf.Hediff.PregnantHuman != null)
{
pregnancy = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.PregnantHuman);
}
diff --git a/Source/IdeologyAddon/IdeologyAddon.csproj b/Source/IdeologyAddon/IdeologyAddon.csproj
index 651dd5b..f791556 100644
--- a/Source/IdeologyAddon/IdeologyAddon.csproj
+++ b/Source/IdeologyAddon/IdeologyAddon.csproj
@@ -42,6 +42,7 @@
+
@@ -52,16 +53,19 @@
+
+
-
-
-
-
+
+
+
+
+
@@ -84,17 +88,19 @@
+
+
-
+
- 1.4.3537
+ 1.4.3704
2.2.2
diff --git a/Source/IdeologyAddon/Keyed.cs b/Source/IdeologyAddon/Keyed.cs
index 8a98c01..4083479 100644
--- a/Source/IdeologyAddon/Keyed.cs
+++ b/Source/IdeologyAddon/Keyed.cs
@@ -4,11 +4,17 @@ namespace RJWSexperience.Ideology
{
public static class Keyed
{
+ public static readonly string ModTitle = "RSI_Mod_Title".Translate();
public static readonly string MemeStatFactor = "MemeStatFactor".Translate();
public static readonly string RSVictimCondition = "RSVictimCondition".Translate();
public static readonly string RSBreederCondition = "RSBreederCondition".Translate();
public static readonly string RSNotHuman = "RSNotHuman".Translate();
public static readonly string RSNotAnimal = "RSNotAnimal".Translate();
public static readonly string RSShouldCanFuck = "RSShouldCanFuck".Translate();
+
+ public static readonly string PatchRomanceChanceFactor = "RSI_PatchRomanceChanceFactor".Translate();
+ public static readonly string PatchRomanceChanceFactorTip = "RSI_PatchRomanceChanceFactorTip".Translate();
+ public static readonly string PatchIncestuousManualRomance = "RSI_PatchIncestuousManualRomance".Translate();
+ public static readonly string PatchIncestuousManualRomanceTip = "RSI_PatchIncestuousManualRomanceTip".Translate();
}
}
diff --git a/Source/IdeologyAddon/Patches/RJW_Patch_ChancePerHour.cs b/Source/IdeologyAddon/Patches/RJW_Patch_ChancePerHour.cs
index 2a22c2c..18d8550 100644
--- a/Source/IdeologyAddon/Patches/RJW_Patch_ChancePerHour.cs
+++ b/Source/IdeologyAddon/Patches/RJW_Patch_ChancePerHour.cs
@@ -15,7 +15,7 @@ namespace RJWSexperience.Ideology.Patches
if (__result < 0f || pawn.Ideo == null) // ideo is null if don't have dlc
return;
- if (!RsiHistoryEventDefOf.RSI_SexWithAnimal.CreateEvent(pawn).DoerWillingToDo())
+ if (!RsiDefOf.HistoryEvent.RSI_SexWithAnimal.CreateEvent(pawn).DoerWillingToDo())
{
__result = -2f;
return;
@@ -32,7 +32,7 @@ namespace RJWSexperience.Ideology.Patches
if (__result < 0f || pawn.Ideo == null) // ideo is null if don't have dlc
return;
- if (!RsiHistoryEventDefOf.RSI_Raped.CreateEvent(pawn).DoerWillingToDo())
+ if (!RsiDefOf.HistoryEvent.RSI_Raped.CreateEvent(pawn).DoerWillingToDo())
{
__result = -2f;
return;
@@ -48,7 +48,7 @@ namespace RJWSexperience.Ideology.Patches
if (__result < 0f || pawn.Ideo == null) // ideo is null if don't have dlc
return;
- if (!RsiHistoryEventDefOf.RSI_SexWithCorpse.CreateEvent(pawn).DoerWillingToDo())
+ if (!RsiDefOf.HistoryEvent.RSI_SexWithCorpse.CreateEvent(pawn).DoerWillingToDo())
{
__result = -2f;
return;
@@ -65,7 +65,7 @@ namespace RJWSexperience.Ideology.Patches
if (__result < 0f || p.Ideo == null) // ideo is null if don't have dlc
return;
- if (!RsiHistoryEventDefOf.RSI_Masturbated.CreateEvent(p).DoerWillingToDo())
+ if (!RsiDefOf.HistoryEvent.RSI_Masturbated.CreateEvent(p).DoerWillingToDo())
{
__result = -2f;
return;
diff --git a/Source/IdeologyAddon/Patches/RJW_Patch_Ideo.cs b/Source/IdeologyAddon/Patches/RJW_Patch_Ideo.cs
index f387f14..4a06922 100644
--- a/Source/IdeologyAddon/Patches/RJW_Patch_Ideo.cs
+++ b/Source/IdeologyAddon/Patches/RJW_Patch_Ideo.cs
@@ -19,7 +19,7 @@ namespace RJWSexperience.Ideology.Patches
Ideo ideo = pawn.Ideo;
if (ideo != null && !pawn.IsSubmissive())
{
- __result = __result || ideo.HasMeme(VariousDefOf.Rapist);
+ __result = __result || ideo.HasMeme(RsiDefOf.Meme.Rapist);
}
}
}
@@ -32,7 +32,7 @@ namespace RJWSexperience.Ideology.Patches
Ideo ideo = pawn.Ideo;
if (ideo != null)
{
- __result = __result || ideo.HasMeme(VariousDefOf.Zoophile);
+ __result = __result || ideo.HasMeme(RsiDefOf.Meme.Zoophile);
}
}
}
@@ -45,7 +45,7 @@ namespace RJWSexperience.Ideology.Patches
Ideo ideo = pawn.Ideo;
if (ideo != null)
{
- __result = __result || ideo.HasMeme(VariousDefOf.Necrophile);
+ __result = __result || ideo.HasMeme(RsiDefOf.Meme.Necrophile);
}
}
}
@@ -85,10 +85,10 @@ namespace RJWSexperience.Ideology.Patches
private static void AfterSexHuman(Pawn human, Pawn partner)
{
- RsiHistoryEventDefOf.RSI_NonIncestuosSex.RecordEventWithPartner(human, partner);
+ RsiDefOf.HistoryEvent.RSI_NonIncestuosSex.RecordEventWithPartner(human, partner);
if (partner.IsAnimal())
- RsiHistoryEventDefOf.RSI_SexWithAnimal.RecordEventWithPartner(human, partner);
+ RsiDefOf.HistoryEvent.RSI_SexWithAnimal.RecordEventWithPartner(human, partner);
}
}
@@ -113,11 +113,13 @@ namespace RJWSexperience.Ideology.Patches
public static float PreceptSextype(Pawn pawn, Pawn partner, float score, List historyEventDefs)
{
- foreach(HistoryEventDef eventDef in historyEventDefs)
+ for (int i = 0; i < historyEventDefs.Count; i++)
{
+ HistoryEventDef eventDef = historyEventDefs[i];
+
if (eventDef.CreateEventWithPartner(pawn, partner).DoerWillingToDo())
{
- float mult = 8.0f * Math.Max(0.3f, 1 / Math.Max(0.01f, pawn.GetStatValue(xxx.sex_drive_stat)));
+ float mult = 8.0f * Math.Max(0.3f, 1 / Math.Max(0.01f, pawn.GetStatValue(xxx.sex_drive_stat, cacheStaleAfterTicks: 60)));
return score * mult;
}
}
@@ -148,7 +150,7 @@ namespace RJWSexperience.Ideology.Patches
public static void Postfix(Pawn pawn, ref bool __result)
{
Ideo ideo = pawn.Ideo;
- if (ideo?.HasMeme(VariousDefOf.Zoophile) == true)
+ if (ideo?.HasMeme(RsiDefOf.Meme.Zoophile) == true)
{
SaveStorage.DataStore.GetPawnData(pawn).CanDesignateBreeding = true;
__result = true;
@@ -213,14 +215,14 @@ namespace RJWSexperience.Ideology.Patches
Ideo mainideo = playerfaction.ideos.PrimaryIdeo;
if (mainideo != null)
{
- if (mainideo.HasPrecept(VariousDefOf.BabyFaction_AlwaysFather))
+ if (mainideo.HasPrecept(RsiDefOf.Precept.BabyFaction_AlwaysFather))
{
Pawn parent = baby.GetFather() ?? baby.GetMother();
ideo = parent.Ideo;
return parent.Faction;
}
- else if (mainideo.HasPrecept(VariousDefOf.BabyFaction_AlwaysColony))
+ else if (mainideo.HasPrecept(RsiDefOf.Precept.BabyFaction_AlwaysColony))
{
ideo = mainideo;
return playerfaction;
@@ -241,7 +243,7 @@ namespace RJWSexperience.Ideology.Patches
if (props.pawn?.Ideo == null || !props.hasPartner())
return;
- if (props.partner.Ideo?.HasPrecept(VariousDefOf.ProselyzingByOrgasm) == true)
+ if (props.partner.Ideo?.HasPrecept(RsiDefOf.Precept.ProselyzingByOrgasm) == true)
{
// Pawn is the one having the orgasm
// Partner is "giving" the orgasm, hence the pawn will be converted towards the partners ideology
diff --git a/Source/IdeologyAddon/Patches/Rimworld_Patch.cs b/Source/IdeologyAddon/Patches/Rimworld_Patch.cs
index e50098e..1cbf453 100644
--- a/Source/IdeologyAddon/Patches/Rimworld_Patch.cs
+++ b/Source/IdeologyAddon/Patches/Rimworld_Patch.cs
@@ -1,9 +1,14 @@
using HarmonyLib;
+using Mono.Cecil.Cil;
using RimWorld;
using rjw;
using RJWSexperience.Ideology.HistoryEvents;
using RJWSexperience.Ideology.Precepts;
using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Text;
using Verse;
namespace RJWSexperience.Ideology.Patches
@@ -13,8 +18,8 @@ namespace RJWSexperience.Ideology.Patches
{
public static void Postfix(Pawn firstPawn, Pawn secondPawn)
{
- RsiHistoryEventDefOf.RSI_NonIncestuosMarriage.RecordEventWithPartner(firstPawn, secondPawn);
- RsiHistoryEventDefOf.RSI_NonIncestuosMarriage.RecordEventWithPartner(secondPawn, firstPawn);
+ RsiDefOf.HistoryEvent.RSI_NonIncestuosMarriage.RecordEventWithPartner(firstPawn, secondPawn);
+ RsiDefOf.HistoryEvent.RSI_NonIncestuosMarriage.RecordEventWithPartner(secondPawn, firstPawn);
}
}
@@ -53,4 +58,193 @@ namespace RJWSexperience.Ideology.Patches
}
}
}
+
+ [HarmonyPatch(typeof(RelationsUtility), "Incestuous")]
+ public static class Rimworld_Patch_IncestuousManualRomance
+ {
+ public static bool Prepare() => RsiMod.Prefs.patchIncestuousManualRomance;
+
+ ///
+ /// Override incestuous check in the manual romance
+ ///
+ /// Pawn to try do romance
+ /// Target for romance
+ /// Result of the original method
+ /// Run original method implementation
+ 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 == RsiDefOf.Issue.Incestuos);
+ var allowManualRomanceOnlyFor = incestuousPrecept?.GetModExtension()?.allowManualRomanceOnlyFor;
+ BloodRelationDegree relationDegree = RelationHelpers.GetBloodRelationDegree(one, two);
+
+ if (allowManualRomanceOnlyFor == null)
+ {
+ return relationDegree < BloodRelationDegree.NotRelated;
+ }
+
+ return !allowManualRomanceOnlyFor.Contains(relationDegree);
+ }
+ }
+
+ [HarmonyPatch(typeof(Pawn_RelationsTracker), nameof(Pawn_RelationsTracker.SecondaryRomanceChanceFactor))]
+ public static class Rimworld_Patch_SecondaryRomanceChanceFactor
+ {
+ public static bool Prepare() => RsiMod.Prefs.patchRomanceChanceFactor;
+
+ ///
+ ///
+ /// Replace
+ /// float num = 1f;
+ /// foreach (PawnRelationDef pawnRelationDef in this.pawn.GetRelations(otherPawn))
+ /// {
+ /// num *= pawnRelationDef.romanceChanceFactor;
+ /// }
+ ///
+ /// with
+ ///
+ /// float num = 1f;
+ /// num = RomanceChanceFactorHelpers.GetRomanceChanceFactor(this.pawn, otherPawn)
+ ///
+ ///
+ /// Original method body
+ /// Modified method body
+ public static IEnumerable Transpiler(IEnumerable instructions)
+ {
+ MethodInfo getRelationsInfo = AccessTools.Method(
+ typeof(PawnRelationUtility),
+ nameof(PawnRelationUtility.GetRelations),
+ new[] { typeof(Pawn), typeof(Pawn) });
+ MethodInfo helperInfo = AccessTools.Method(
+ typeof(RomanceChanceFactorHelpers),
+ nameof(RomanceChanceFactorHelpers.GetRomanceChanceFactor),
+ new[] { typeof(Pawn), typeof(Pawn) });
+
+ // Original IL looks something like this:
+ // Load this.pawn
+ // Load otherPawn
+ // Call GetRelations
+ // Start loop
+ // ...
+ // Mul num and romanceChanceFactor
+ // Store result
+ // ...
+ // Endfinaly
+
+ // Idea is to substitute GetRelations call with a method with the same signature,
+ // store results in the same place original loop does and remove everything else until Endfinaly
+
+ IEnumerator enumerator = instructions.GetEnumerator();
+ bool endOfInstructions = !enumerator.MoveNext();
+
+ // Find and replace GetRelations
+ while (!endOfInstructions)
+ {
+ var instruction = enumerator.Current;
+
+ if (instruction.Calls(getRelationsInfo))
+ {
+ yield return new CodeInstruction(OpCodes.Call, helperInfo);
+ enumerator.MoveNext(); // skip original method call
+ break;
+ }
+
+ yield return instruction;
+ endOfInstructions = !enumerator.MoveNext();
+ }
+
+ if (endOfInstructions)
+ {
+ Log.Error("[RSI] Failed to transpile Pawn_RelationsTracker.SecondaryRomanceChanceFactor: PawnRelationUtility.GetRelations call not found");
+ yield break;
+ }
+
+ // Skip everything until Mul
+ while (!endOfInstructions)
+ {
+ if (enumerator.Current.opcode == OpCodes.Mul)
+ {
+ enumerator.MoveNext(); // skip Mul
+ yield return enumerator.Current; // return next op, it should be "store result"
+ break;
+ }
+
+ endOfInstructions = !enumerator.MoveNext();
+ }
+
+ if (endOfInstructions)
+ {
+ Log.Error("[RSI] Failed to transpile Pawn_RelationsTracker.SecondaryRomanceChanceFactor: Mul not found. This error means half of SecondaryRomanceChanceFactor was erased. Very not good");
+ yield break;
+ }
+
+ // Skip the rest of the loop
+ while (!endOfInstructions)
+ {
+ if (enumerator.Current.opcode == OpCodes.Endfinally)
+ {
+ // Endfinally will be skipped by the next MoveNext()
+ break;
+ }
+
+ endOfInstructions = !enumerator.MoveNext();
+ }
+
+ if (endOfInstructions)
+ {
+ Log.Error("[RSI] Failed to transpile Pawn_RelationsTracker.SecondaryRomanceChanceFactor: Endfinally not found. This error means half of SecondaryRomanceChanceFactor was erased. Very not good");
+ yield break;
+ }
+
+ // Return the rest of the method
+ while (enumerator.MoveNext())
+ {
+ yield return enumerator.Current;
+ }
+
+ if (Prefs.DevMode) Log.Message("[RSI] Successfully transpiled Pawn_RelationsTracker.SecondaryRomanceChanceFactor");
+ }
+
+ [HarmonyPatch(typeof(Precept), nameof(Precept.GetTip))]
+ public static class Rimworld_Patch_PreceptTip
+ {
+ public static void Postfix(ref string __result, Precept __instance)
+ {
+ if (__instance.def.modExtensions.NullOrEmpty())
+ {
+ return;
+ }
+
+ bool tipChanged = false;
+ StringBuilder tipBuilder = new StringBuilder(__result);
+ tipBuilder.AppendLine();
+ tipBuilder.AppendInNewLine((Keyed.ModTitle + ":").Colorize(ColoredText.TipSectionTitleColor));
+
+ for (int i = 0; i < __instance.def.modExtensions.Count; i++)
+ {
+ if (__instance.def.modExtensions[i] is IPreceptTipPostfix tipPostfix)
+ {
+ tipBuilder.AppendInNewLine(" - " + tipPostfix.GetTip());
+ tipChanged = true;
+ }
+ }
+
+ if (tipChanged)
+ {
+ __result = tipBuilder.ToString();
+ }
+ }
+ }
+ }
}
diff --git a/Source/IdeologyAddon/Patches/Sexperience_Patch.cs b/Source/IdeologyAddon/Patches/Sexperience_Patch.cs
index 6951eea..4f7471e 100644
--- a/Source/IdeologyAddon/Patches/Sexperience_Patch.cs
+++ b/Source/IdeologyAddon/Patches/Sexperience_Patch.cs
@@ -1,21 +1,25 @@
-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;
if (props.isRape && exVirgin == props.partner)
- RsiHistoryEventDefOf.RSI_VirginStolen.RecordEventWithPartner(exVirgin, partner);
+ RsiDefOf.HistoryEvent.RSI_VirginStolen.RecordEventWithPartner(exVirgin, partner);
else if (degree != femaleAfterSurgery)
- RsiHistoryEventDefOf.RSI_VirginTaken.RecordEventWithPartner(exVirgin, partner);
+ RsiDefOf.HistoryEvent.RSI_VirginTaken.RecordEventWithPartner(exVirgin, partner);
- RsiHistoryEventDefOf.RSI_TookVirgin.RecordEventWithPartner(partner, exVirgin);
+ RsiDefOf.HistoryEvent.RSI_TookVirgin.RecordEventWithPartner(partner, exVirgin);
}
}
}
diff --git a/Source/IdeologyAddon/Precepts/DefExtension_Incest.cs b/Source/IdeologyAddon/Precepts/DefExtension_Incest.cs
new file mode 100644
index 0000000..caf0ed0
--- /dev/null
+++ b/Source/IdeologyAddon/Precepts/DefExtension_Incest.cs
@@ -0,0 +1,73 @@
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using Verse;
+
+namespace RJWSexperience.Ideology.Precepts
+{
+ ///
+ /// Special Def extension for the Incestuous issue precepts
+ ///
+ [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Def loader")]
+ 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/Precepts/DefExtension_ModifyBestialityMtb.cs b/Source/IdeologyAddon/Precepts/DefExtension_ModifyBestialityMtb.cs
index 1d97595..111ee69 100644
--- a/Source/IdeologyAddon/Precepts/DefExtension_ModifyBestialityMtb.cs
+++ b/Source/IdeologyAddon/Precepts/DefExtension_ModifyBestialityMtb.cs
@@ -2,5 +2,6 @@
{
public class DefExtension_ModifyBestialityMtb : DefExtension_ModifyMtb
{
+ protected override string TipTemplateKey => "RSI_PreceptTipModifyBestialityMtb";
}
}
diff --git a/Source/IdeologyAddon/Precepts/DefExtension_ModifyFappinMtb.cs b/Source/IdeologyAddon/Precepts/DefExtension_ModifyFappinMtb.cs
index 8596b28..f01c4ed 100644
--- a/Source/IdeologyAddon/Precepts/DefExtension_ModifyFappinMtb.cs
+++ b/Source/IdeologyAddon/Precepts/DefExtension_ModifyFappinMtb.cs
@@ -2,5 +2,6 @@
{
public class DefExtension_ModifyFappinMtb : DefExtension_ModifyMtb
{
+ protected override string TipTemplateKey => "RSI_PreceptTipModifyFappinMtb";
}
}
diff --git a/Source/IdeologyAddon/Precepts/DefExtension_ModifyMtb.cs b/Source/IdeologyAddon/Precepts/DefExtension_ModifyMtb.cs
index e1553f3..361ceb1 100644
--- a/Source/IdeologyAddon/Precepts/DefExtension_ModifyMtb.cs
+++ b/Source/IdeologyAddon/Precepts/DefExtension_ModifyMtb.cs
@@ -1,11 +1,28 @@
-using System.Diagnostics.CodeAnalysis;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using Verse;
namespace RJWSexperience.Ideology.Precepts
{
- public abstract class DefExtension_ModifyMtb : DefModExtension
+ [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field values are loaded from XML")]
+ public abstract class DefExtension_ModifyMtb : DefModExtension, IPreceptTipPostfix
{
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
+ protected abstract string TipTemplateKey { get; }
+
public float multiplier = 1f;
+
+ public string GetTip() => TipTemplateKey.Translate(multiplier.ToString());
+
+ public override IEnumerable ConfigErrors()
+ {
+ if (multiplier == 1f)
+ {
+ yield return "There is no point if is 1";
+ }
+ else if (multiplier <= 0f)
+ {
+ yield return " must be > 0";
+ }
+ }
}
}
diff --git a/Source/IdeologyAddon/Precepts/DefExtension_ModifyNecroMtb.cs b/Source/IdeologyAddon/Precepts/DefExtension_ModifyNecroMtb.cs
index 3e544f7..ce35b27 100644
--- a/Source/IdeologyAddon/Precepts/DefExtension_ModifyNecroMtb.cs
+++ b/Source/IdeologyAddon/Precepts/DefExtension_ModifyNecroMtb.cs
@@ -2,5 +2,6 @@
{
public class DefExtension_ModifyNecroMtb : DefExtension_ModifyMtb
{
+ protected override string TipTemplateKey => "RSI_PreceptTipModifyNecroMtb";
}
}
diff --git a/Source/IdeologyAddon/Precepts/DefExtension_ModifyPreference.cs b/Source/IdeologyAddon/Precepts/DefExtension_ModifyPreference.cs
index 698bda1..19689bb 100644
--- a/Source/IdeologyAddon/Precepts/DefExtension_ModifyPreference.cs
+++ b/Source/IdeologyAddon/Precepts/DefExtension_ModifyPreference.cs
@@ -1,30 +1,41 @@
-using System.Collections.Generic;
+using RJWSexperience.Ideology.Filters;
+using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+using System.Linq;
using Verse;
namespace RJWSexperience.Ideology.Precepts
{
+ ///
+ /// Def extension to enable changing SexAppraiser results based on filters
+ ///
+ [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Def loader")]
public class DefExtension_ModifyPreference : DefModExtension
{
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
public List rules;
+ ///
+ /// Apply SexAppraiser modifiers from rules with a satisfied filter
+ ///
public void Apply(Pawn pawn, Pawn partner, ref float preference)
{
- foreach (Rule rule in rules)
+ foreach (Rule rule in rules.Where(rule => rule.Applies(pawn, partner)))
{
- if (rule.Applies(pawn, partner))
- preference *= rule.multiplier;
+ preference *= rule.multiplier;
}
}
+ ///
+ /// Type to associate SexAppraiser result modifier with a TwoPawnFilter
+ ///
public class Rule
{
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
public float multiplier = 1f;
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
public TwoPawnFilter filter;
+ ///
+ /// Check if the pair of pawns fits filter conditions
+ ///
public bool Applies(Pawn pawn, Pawn partner)
{
if (filter == null)
diff --git a/Source/IdeologyAddon/Precepts/DefExtension_ModifyRapeCPMtb.cs b/Source/IdeologyAddon/Precepts/DefExtension_ModifyRapeCPMtb.cs
index e83be70..ff09728 100644
--- a/Source/IdeologyAddon/Precepts/DefExtension_ModifyRapeCPMtb.cs
+++ b/Source/IdeologyAddon/Precepts/DefExtension_ModifyRapeCPMtb.cs
@@ -2,5 +2,6 @@
{
public class DefExtension_ModifyRapeCPMtb : DefExtension_ModifyMtb
{
+ protected override string TipTemplateKey => "RSI_PreceptTipModifyRapeCPMtb";
}
}
diff --git a/Source/IdeologyAddon/Precepts/IPreceptTipPostfix.cs b/Source/IdeologyAddon/Precepts/IPreceptTipPostfix.cs
new file mode 100644
index 0000000..85411fb
--- /dev/null
+++ b/Source/IdeologyAddon/Precepts/IPreceptTipPostfix.cs
@@ -0,0 +1,7 @@
+namespace RJWSexperience.Ideology.Precepts
+{
+ public interface IPreceptTipPostfix
+ {
+ string GetTip();
+ }
+}
diff --git a/Source/IdeologyAddon/RelationHelpers.cs b/Source/IdeologyAddon/RelationHelpers.cs
new file mode 100644
index 0000000..1033307
--- /dev/null
+++ b/Source/IdeologyAddon/RelationHelpers.cs
@@ -0,0 +1,52 @@
+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)
+ {
+ if (!pawn.relations.FamilyByBlood.Contains(partner))
+ {
+ return BloodRelationDegree.NotRelated;
+ }
+
+ 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/Rituals/JobGiver_DrugOrgy.cs b/Source/IdeologyAddon/Rituals/JobGiver_DrugOrgy.cs
index a7eacb0..82a541e 100644
--- a/Source/IdeologyAddon/Rituals/JobGiver_DrugOrgy.cs
+++ b/Source/IdeologyAddon/Rituals/JobGiver_DrugOrgy.cs
@@ -1,56 +1,47 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using RimWorld;
using rjw;
+using System;
+using System.Collections.Generic;
using Verse;
using Verse.AI;
-using RimWorld;
-
namespace RJWSexperience.Ideology
{
- public class JobGiver_DrugOrgy : ThinkNode_JobGiver
- {
- protected override Job TryGiveJob(Pawn pawn)
- {
- if (pawn.Drafted) return null;
- DutyDef dutyDef = null;
- PawnDuty duty = null;
- if (pawn.mindState != null)
- {
- duty = pawn.mindState.duty;
- dutyDef = duty.def;
- }
- else return null;
+ public class JobGiver_DrugOrgy : ThinkNode_JobGiver
+ {
+ protected override Job TryGiveJob(Pawn pawn)
+ {
+ if (pawn.Drafted || pawn.mindState == null)
+ {
+ return null;
+ }
- if (dutyDef == DutyDefOf.TravelOrLeave || !xxx.can_do_loving(pawn))
- {
- return null;
- }
-
- Pawn target = FindPartner(pawn, duty);
+ PawnDuty duty = pawn.mindState.duty;
- if (target == null || !pawn.CanReserveAndReach(target, PathEndMode.ClosestTouch, Danger.None,1)) return JobMaker.MakeJob(VariousDefOf.DrugMasturbate);
+ if (duty.def == DutyDefOf.TravelOrLeave || !xxx.can_do_loving(pawn))
+ {
+ return null;
+ }
- return JobMaker.MakeJob(VariousDefOf.DrugSex, target);
- }
+ Pawn target = FindPartner(pawn, duty);
- protected Pawn FindPartner(Pawn pawn, PawnDuty duty)
- {
- if (duty != null)
- {
- List pawns = pawn.Map.mapPawns.AllPawnsSpawned.FindAll(x => x.mindState?.duty?.def == duty.def);
- return pawns.RandomElementByWeightWithDefault(x => SexAppraiser.would_fuck(pawn,x), 0.1f);
- }
-
-
+ if (target == null || !pawn.CanReserveAndReach(target, PathEndMode.ClosestTouch, Danger.None, 1))
+ return JobMaker.MakeJob(RsiDefOf.Job.DrugMasturbate);
- return null;
- }
+ return JobMaker.MakeJob(RsiDefOf.Job.DrugSex, target);
+ }
- }
+ protected Pawn FindPartner(Pawn pawn, PawnDuty duty)
+ {
+ if (duty != null)
+ {
+ List pawns = pawn.Map.mapPawns.AllPawnsSpawned.FindAll(x => x.mindState?.duty?.def == duty.def);
+ return pawns.RandomElementByWeightWithDefault(x => SexAppraiser.would_fuck(pawn, x), 0.1f);
+ }
+
+ return null;
+ }
+ }
///
/// copied from rjw
@@ -65,7 +56,7 @@ namespace RJWSexperience.Ideology
protected override IEnumerable MakeNewToils()
{
setup_ticks();
- var PartnerJob = VariousDefOf.GettinDrugSex;
+ var PartnerJob = RsiDefOf.Job.GettinDrugSex;
this.FailOnDespawnedNullOrForbidden(iTarget);
this.FailOn(() => !Partner.health.capacities.CanBeAwake);
@@ -73,47 +64,52 @@ namespace RJWSexperience.Ideology
this.FailOn(() => Partner == null);
yield return Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell);
- Toil WaitForPartner = new Toil();
- WaitForPartner.defaultCompleteMode = ToilCompleteMode.Delay;
- WaitForPartner.initAction = delegate
+ Toil WaitForPartner = new Toil
{
- ticksLeftThisToil = 5000;
- };
- WaitForPartner.tickAction = delegate
- {
- pawn.GainComfortFromCellIfPossible();
- if (pawn.Position.DistanceTo(Partner.Position) <= 1f)
+ defaultCompleteMode = ToilCompleteMode.Delay,
+ initAction = delegate
{
- ReadyForNextToil();
+ ticksLeftThisToil = 5000;
+ },
+ tickAction = delegate
+ {
+ pawn.GainComfortFromCellIfPossible();
+ if (pawn.Position.DistanceTo(Partner.Position) <= 1f)
+ {
+ ReadyForNextToil();
+ }
}
};
yield return WaitForPartner;
- Toil StartPartnerJob = new Toil();
- StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
- StartPartnerJob.socialMode = RandomSocialMode.Off;
- StartPartnerJob.initAction = delegate
+ Toil StartPartnerJob = new Toil
{
- var dri = Partner.jobs.curDriver as JobDriver_DrugSexReceiver;
- if (dri == null)
- {
- Job gettingQuickie = JobMaker.MakeJob(PartnerJob, pawn, Partner);
- Partner.jobs.StartJob(gettingQuickie, JobCondition.InterruptForced);
+ defaultCompleteMode = ToilCompleteMode.Instant,
+ socialMode = RandomSocialMode.Off,
+ initAction = delegate
+ {
+ if (!(Partner.jobs.curDriver is JobDriver_DrugSexReceiver))
+ {
+ Job gettingQuickie = JobMaker.MakeJob(PartnerJob, pawn, Partner);
+ Partner.jobs.StartJob(gettingQuickie, JobCondition.InterruptForced);
+ }
}
};
yield return StartPartnerJob;
- Toil SexToil = new Toil();
- SexToil.defaultCompleteMode = ToilCompleteMode.Never;
- SexToil.socialMode = RandomSocialMode.Off;
- SexToil.defaultDuration = duration;
- SexToil.handlingFacing = true;
+ Toil SexToil = new Toil
+ {
+ defaultCompleteMode = ToilCompleteMode.Never,
+ socialMode = RandomSocialMode.Off,
+ defaultDuration = duration,
+ handlingFacing = true
+ };
SexToil.FailOn(() => Partner.CurJob.def != PartnerJob);
SexToil.initAction = delegate
{
Partner.pather.StopDead();
Partner.jobs.curDriver.asleep = false;
-
+
Start();
Sexprops.usedCondom = CondomUtility.TryUseCondom(pawn) || CondomUtility.TryUseCondom(Partner);
};
@@ -147,8 +143,7 @@ namespace RJWSexperience.Ideology
/// copied from rjw
///
public class JobDriver_DrugSexReceiver : JobDriver_SexBaseRecieverLoved
- {
-
+ {
protected override IEnumerable MakeNewToils()
{
setup_ticks();
@@ -168,23 +163,25 @@ namespace RJWSexperience.Ideology
yield return Toils_Reserve.Reserve(iTarget, 1, 0);
- var get_loved = MakeSexToil();
- get_loved.handlingFacing = false;
- yield return get_loved;
+ var get_loved = MakeSexToil();
+ get_loved.handlingFacing = false;
+ yield return get_loved;
}
protected Toil MakeSexToil()
{
- Toil get_loved = new Toil();
- get_loved.defaultCompleteMode = ToilCompleteMode.Never;
- get_loved.socialMode = RandomSocialMode.Off;
- get_loved.handlingFacing = true;
- get_loved.tickAction = delegate
+ Toil get_loved = new Toil
{
+ defaultCompleteMode = ToilCompleteMode.Never,
+ socialMode = RandomSocialMode.Off,
+ handlingFacing = true,
+ tickAction = delegate
+ {
+ }
};
get_loved.AddEndCondition(new Func(() =>
{
- if (parteners.Count <= 0)
+ if (parteners.Count == 0)
{
return JobCondition.Succeeded;
}
@@ -204,8 +201,7 @@ namespace RJWSexperience.Ideology
/// copied from rjw
///
public class JobDriver_DrugMasturabate : JobDriver_Masturbate
- {
-
+ {
protected override IEnumerable MakeNewToils()
{
setup_ticks();
@@ -252,6 +248,4 @@ namespace RJWSexperience.Ideology
};
}
}
-
-
}
diff --git a/Source/IdeologyAddon/Rituals/JobGiver_GangbangConsensual.cs b/Source/IdeologyAddon/Rituals/JobGiver_GangbangConsensual.cs
index dc6dc15..eae27e5 100644
--- a/Source/IdeologyAddon/Rituals/JobGiver_GangbangConsensual.cs
+++ b/Source/IdeologyAddon/Rituals/JobGiver_GangbangConsensual.cs
@@ -1,43 +1,36 @@
-using System;
+using RimWorld;
+using rjw;
+using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Verse;
using Verse.AI;
-using Verse.AI.Group;
-using RimWorld;
-using rjw;
namespace RJWSexperience.Ideology
{
- public class JobGiver_GangbangConsensual : ThinkNode_JobGiver
- {
- protected override Job TryGiveJob(Pawn pawn)
- {
- if (pawn.Drafted) return null;
- DutyDef dutyDef = null;
- PawnDuty duty = null;
- if (pawn.mindState != null)
- {
- duty = pawn.mindState.duty;
- dutyDef = duty.def;
- }
- else return null;
+ public class JobGiver_GangbangConsensual : ThinkNode_JobGiver
+ {
+ protected override Job TryGiveJob(Pawn pawn)
+ {
+ if (pawn.Drafted || pawn.mindState == null)
+ {
+ return null;
+ }
- if (dutyDef == DutyDefOf.TravelOrLeave || !xxx.can_do_loving(pawn))
- {
- return null;
- }
+ PawnDuty duty = pawn.mindState.duty;
- Pawn target = duty.focusSecond.Pawn;
+ if (duty.def == DutyDefOf.TravelOrLeave || !xxx.can_do_loving(pawn))
+ {
+ return null;
+ }
- if (!pawn.CanReach(target, PathEndMode.ClosestTouch, Danger.None)) return null;
+ Pawn target = duty.focusSecond.Pawn;
- return JobMaker.MakeJob(VariousDefOf.Gangbang, target);
- }
- }
+ if (!pawn.CanReach(target, PathEndMode.ClosestTouch, Danger.None))
+ return null;
+ return JobMaker.MakeJob(RsiDefOf.Job.Gangbang, target);
+ }
+ }
public class JobDriver_Gangbang : JobDriver_SexBaseInitiator
{
@@ -56,26 +49,28 @@ namespace RJWSexperience.Ideology
this.FailOn(() => Partner.Drafted);
yield return Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell);
- Toil StartPartnerJob = new Toil();
- StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
- StartPartnerJob.socialMode = RandomSocialMode.Off;
- StartPartnerJob.initAction = delegate
+ Toil StartPartnerJob = new Toil
{
-
- var dri = Partner.jobs.curDriver as JobDriver_SexBaseRecieverRaped;
- if (dri == null)
- {
- Job gettin_loved = JobMaker.MakeJob(VariousDefOf.GettinGangbang, pawn, Bed);
- Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced);
+ defaultCompleteMode = ToilCompleteMode.Instant,
+ socialMode = RandomSocialMode.Off,
+ initAction = delegate
+ {
+ if (!(Partner.jobs.curDriver is JobDriver_SexBaseRecieverRaped))
+ {
+ Job gettin_loved = JobMaker.MakeJob(RsiDefOf.Job.GettinGangbang, pawn, Bed);
+ Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced);
+ }
}
};
yield return StartPartnerJob;
- Toil SexToil = new Toil();
- SexToil.defaultCompleteMode = ToilCompleteMode.Never;
- SexToil.defaultDuration = duration;
- SexToil.handlingFacing = true;
- SexToil.FailOn(() => Partner.CurJob.def != VariousDefOf.GettinGangbang);
+ Toil SexToil = new Toil
+ {
+ defaultCompleteMode = ToilCompleteMode.Never,
+ defaultDuration = duration,
+ handlingFacing = true
+ };
+ SexToil.FailOn(() => Partner.CurJob.def != RsiDefOf.Job.GettinGangbang);
SexToil.initAction = delegate
{
Start();
@@ -108,28 +103,30 @@ namespace RJWSexperience.Ideology
}
public class JobDriver_GangbangReceiver : JobDriver_SexBaseRecieverLoved
- {
+ {
protected override IEnumerable MakeNewToils()
{
setup_ticks();
parteners.Add(Partner);// add job starter, so this wont fail, before Initiator starts his job
- Toil get_banged = new Toil();
- get_banged.defaultCompleteMode = ToilCompleteMode.Never;
- get_banged.handlingFacing = true;
- get_banged.initAction = delegate
+ Toil get_banged = new Toil
{
- pawn.pather.StopDead();
- pawn.jobs.curDriver.asleep = false;
- };
- get_banged.tickAction = delegate
- {
- if ((parteners.Count > 0) && pawn.IsHashIntervalTick(ticks_between_hearts / parteners.Count) && pawn.IsHashIntervalTick(ticks_between_hearts))
- ThrowMetaIconF(pawn.Position, pawn.Map, FleckDefOf.Heart);
+ defaultCompleteMode = ToilCompleteMode.Never,
+ handlingFacing = true,
+ initAction = delegate
+ {
+ pawn.pather.StopDead();
+ pawn.jobs.curDriver.asleep = false;
+ },
+ tickAction = delegate
+ {
+ if ((parteners.Count > 0) && pawn.IsHashIntervalTick(ticks_between_hearts / parteners.Count) && pawn.IsHashIntervalTick(ticks_between_hearts))
+ ThrowMetaIconF(pawn.Position, pawn.Map, FleckDefOf.Heart);
+ }
};
get_banged.AddEndCondition(new Func(() =>
{
- if (parteners.Count <= 0)
+ if (parteners.Count == 0)
{
return JobCondition.Succeeded;
}
@@ -148,12 +145,12 @@ namespace RJWSexperience.Ideology
Partner.jobs.jobQueue.EnqueueFirst(tobed);
}
else if (pawn.HostileTo(Partner))
+ {
pawn.health.AddHediff(xxx.submitting);
+ }
});
get_banged.socialMode = RandomSocialMode.Off;
yield return get_banged;
-
}
}
-
}
diff --git a/Source/IdeologyAddon/Rituals/JobGiver_GangbangVictim.cs b/Source/IdeologyAddon/Rituals/JobGiver_GangbangVictim.cs
index ce2ec72..092b00b 100644
--- a/Source/IdeologyAddon/Rituals/JobGiver_GangbangVictim.cs
+++ b/Source/IdeologyAddon/Rituals/JobGiver_GangbangVictim.cs
@@ -1,56 +1,46 @@
-using System;
+using RimWorld;
+using rjw;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Verse;
using Verse.AI;
-using Verse.AI.Group;
-using RimWorld;
-using rjw;
-
namespace RJWSexperience.Ideology
{
- public class JobGiver_GangbangVictim : ThinkNode_JobGiver
- {
- protected override Job TryGiveJob(Pawn pawn)
- {
- if (pawn.Drafted) return null;
- DutyDef dutyDef = null;
- PawnDuty duty = null;
- if (pawn.mindState != null)
- {
- duty = pawn.mindState.duty;
- dutyDef = duty.def;
- }
- else return null;
+ public class JobGiver_GangbangVictim : ThinkNode_JobGiver
+ {
+ protected override Job TryGiveJob(Pawn pawn)
+ {
+ if (pawn.Drafted || pawn.mindState == null)
+ {
+ return null;
+ }
- if (dutyDef == DutyDefOf.TravelOrLeave || !xxx.can_do_loving(pawn))
- {
- return null;
+ PawnDuty duty = pawn.mindState.duty;
+
+ if (duty.def == DutyDefOf.TravelOrLeave || !xxx.can_do_loving(pawn))
+ {
+ return null;
}
Pawn target = duty.focusSecond.Pawn;
- if (!pawn.CanReach(target, PathEndMode.ClosestTouch, Danger.None)) return null;
-
- return JobMaker.MakeJob(VariousDefOf.RapeVictim, target);
- }
- }
+ if (!pawn.CanReach(target, PathEndMode.ClosestTouch, Danger.None)) return null;
+ return JobMaker.MakeJob(RsiDefOf.Job.RapeVictim, target);
+ }
+ }
///
/// copied from rjw
///
public class JobDriver_RapeVictim : JobDriver_Rape
{
- public override bool TryMakePreToilReservations(bool errorOnFailed)
- {
+ public override bool TryMakePreToilReservations(bool errorOnFailed)
+ {
return true;
- }
+ }
- protected override IEnumerable MakeNewToils()
+ protected override IEnumerable MakeNewToils()
{
if (RJWSettings.DebugRape) ModLog.Message("" + this.GetType().ToString() + "::MakeNewToils() called");
setup_ticks();
@@ -64,25 +54,28 @@ namespace RJWSexperience.Ideology
SexUtility.RapeTargetAlert(pawn, Partner);
- Toil StartPartnerJob = new Toil();
- StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
- StartPartnerJob.socialMode = RandomSocialMode.Off;
- StartPartnerJob.initAction = delegate
+ Toil StartPartnerJob = new Toil
{
- var dri = Partner.jobs.curDriver as JobDriver_SexBaseRecieverRaped;
- if (dri == null)
+ defaultCompleteMode = ToilCompleteMode.Instant,
+ socialMode = RandomSocialMode.Off,
+ initAction = delegate
{
- Job gettin_raped = JobMaker.MakeJob(PartnerJob, pawn);
+ if (!(Partner.jobs.curDriver is JobDriver_SexBaseRecieverRaped))
+ {
+ Job gettin_raped = JobMaker.MakeJob(PartnerJob, pawn);
- Partner.jobs.StartJob(gettin_raped, JobCondition.InterruptForced, null, false, true, null);
+ Partner.jobs.StartJob(gettin_raped, JobCondition.InterruptForced, null, false, true, null);
+ }
}
};
yield return StartPartnerJob;
- Toil SexToil = new Toil();
- SexToil.defaultCompleteMode = ToilCompleteMode.Never;
- SexToil.defaultDuration = duration;
- SexToil.handlingFacing = true;
+ Toil SexToil = new Toil
+ {
+ defaultCompleteMode = ToilCompleteMode.Never,
+ defaultDuration = duration,
+ handlingFacing = true
+ };
SexToil.FailOn(() => Partner.CurJob.def != PartnerJob);
SexToil.initAction = delegate
{
diff --git a/Source/IdeologyAddon/Rituals/LordJob_Rituals.cs b/Source/IdeologyAddon/Rituals/LordJob_Rituals.cs
index e976d61..b496689 100644
--- a/Source/IdeologyAddon/Rituals/LordJob_Rituals.cs
+++ b/Source/IdeologyAddon/Rituals/LordJob_Rituals.cs
@@ -1,21 +1,15 @@
-using System;
+using RimWorld;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Verse;
-using Verse.AI;
-using RimWorld;
-
namespace RJWSexperience.Ideology
{
- public class LordJob_Ritual_Gangbang : LordJob_Ritual
- {
+ public class LordJob_Ritual_Gangbang : LordJob_Ritual
+ {
public LordJob_Ritual_Gangbang() { }
- public LordJob_Ritual_Gangbang(string targetID ,TargetInfo selectedTarget, Precept_Ritual ritual, RitualObligation obligation, List allStages, RitualRoleAssignments assignments, Pawn organizer = null) : base(selectedTarget, ritual, obligation, allStages, assignments, organizer)
- {
+ public LordJob_Ritual_Gangbang(string targetID, TargetInfo selectedTarget, Precept_Ritual ritual, RitualObligation obligation, List allStages, RitualRoleAssignments assignments, Pawn organizer = null) : base(selectedTarget, ritual, obligation, allStages, assignments, organizer)
+ {
foreach (RitualRole ritualRole in assignments.AllRolesForReading)
{
if (ritualRole != null && ritualRole.id.Contains(targetID))
@@ -25,6 +19,5 @@ namespace RJWSexperience.Ideology
}
}
}
-
}
}
diff --git a/Source/IdeologyAddon/Rituals/RitualRoles.cs b/Source/IdeologyAddon/Rituals/RitualRoles.cs
index 0d26048..e7fb7fc 100644
--- a/Source/IdeologyAddon/Rituals/RitualRoles.cs
+++ b/Source/IdeologyAddon/Rituals/RitualRoles.cs
@@ -1,106 +1,101 @@
using RimWorld;
-using Verse;
using rjw;
+using Verse;
namespace RJWSexperience.Ideology
{
- public class RitualRole_RapeVictim : RitualRole
- {
- public override bool AppliesToRole(Precept_Role role, out string reason, Precept_Ritual ritual = null, Pawn pawn = null, bool skipReason = false)
- {
- reason = null;
- return false;
- }
-
- public override bool AppliesToPawn(Pawn p, out string reason, TargetInfo selectedTarget, LordJob_Ritual ritual = null, RitualRoleAssignments assignments = null, Precept_Ritual precept = null, bool skipReason = false)
- {
- reason = null;
- if (CanBeVictim(p)) return true;
- if (!skipReason)
- {
- reason = Keyed.RSVictimCondition;
- }
- return false;
- }
+ public class RitualRole_RapeVictim : RitualRole
+ {
+ public override bool AppliesToRole(Precept_Role role, out string reason, Precept_Ritual ritual = null, Pawn pawn = null, bool skipReason = false)
+ {
+ reason = null;
+ return false;
+ }
- public static bool CanBeVictim(Pawn pawn)
- {
- if (pawn.IsPrisonerOfColony || pawn.IsSlaveOfColony) return true;
- if (pawn.IsSubmissive()) return true;
- if (pawn.IsDesignatedComfort() || (pawn.guilt != null && pawn.guilt.IsGuilty) || (pawn.apparel != null && pawn.apparel.PsychologicallyNude)) return true;
- return false;
- }
- }
+ public override bool AppliesToPawn(Pawn p, out string reason, TargetInfo selectedTarget, LordJob_Ritual ritual = null, RitualRoleAssignments assignments = null, Precept_Ritual precept = null, bool skipReason = false)
+ {
+ reason = null;
+ if (CanBeVictim(p)) return true;
+ if (!skipReason)
+ {
+ reason = Keyed.RSVictimCondition;
+ }
+ return false;
+ }
- public class RitualRole_HumanBreedee : RitualRole
- {
- public override bool AppliesToRole(Precept_Role role, out string reason, Precept_Ritual ritual = null, Pawn pawn = null, bool skipReason = false)
- {
- reason = null;
- return false;
- }
+ public static bool CanBeVictim(Pawn pawn)
+ {
+ if (pawn.IsPrisonerOfColony || pawn.IsSlaveOfColony) return true;
+ if (pawn.IsSubmissive()) return true;
+ if (pawn.IsDesignatedComfort() || (pawn.guilt != null && pawn.guilt.IsGuilty) || (pawn.apparel != null && pawn.apparel.PsychologicallyNude)) return true;
+ return false;
+ }
+ }
- public override bool AppliesToPawn(Pawn p, out string reason, TargetInfo selectedTarget, LordJob_Ritual ritual = null, RitualRoleAssignments assignments = null, Precept_Ritual precept = null, bool skipReason = false)
- {
-
- reason = null;
- if (!xxx.is_human(p))
- {
- reason = Keyed.RSNotHuman;
- return false;
- }
- if (CanBeBreedee(p)) return true;
- if (!skipReason)
- {
- reason = Keyed.RSShouldCanFuck;
- }
- return false;
- }
+ public class RitualRole_HumanBreedee : RitualRole
+ {
+ public override bool AppliesToRole(Precept_Role role, out string reason, Precept_Ritual ritual = null, Pawn pawn = null, bool skipReason = false)
+ {
+ reason = null;
+ return false;
+ }
- public static bool CanBeBreedee(Pawn pawn)
- {
- if (xxx.can_be_fucked(pawn)) return true;
- return false;
- }
- }
+ public override bool AppliesToPawn(Pawn p, out string reason, TargetInfo selectedTarget, LordJob_Ritual ritual = null, RitualRoleAssignments assignments = null, Precept_Ritual precept = null, bool skipReason = false)
+ {
+ reason = null;
+ if (!xxx.is_human(p))
+ {
+ reason = Keyed.RSNotHuman;
+ return false;
+ }
+ if (CanBeBreedee(p)) return true;
+ if (!skipReason)
+ {
+ reason = Keyed.RSShouldCanFuck;
+ }
+ return false;
+ }
- public class RitualRole_AnimalBreeder : RitualRole
- {
- public override bool Animal => true;
+ public static bool CanBeBreedee(Pawn pawn) => xxx.can_be_fucked(pawn);
+ }
- public override bool AppliesToRole(Precept_Role role, out string reason, Precept_Ritual ritual = null, Pawn pawn = null, bool skipReason = false)
- {
- reason = null;
- return false;
- }
+ public class RitualRole_AnimalBreeder : RitualRole
+ {
+ public override bool Animal => true;
- public override bool AppliesToPawn(Pawn p, out string reason, TargetInfo selectedTarget, LordJob_Ritual ritual = null, RitualRoleAssignments assignments = null, Precept_Ritual precept = null, bool skipReason = false)
- {
- reason = null;
- if (!p.IsAnimal())
- {
- reason = Keyed.RSNotAnimal;
- return false;
- }
- if (CanBeBreeder(p, assignments?.Ritual)) return true;
- if (!skipReason)
- {
- reason = Keyed.RSBreederCondition;
- }
- return false;
- }
+ public override bool AppliesToRole(Precept_Role role, out string reason, Precept_Ritual ritual = null, Pawn pawn = null, bool skipReason = false)
+ {
+ reason = null;
+ return false;
+ }
- public static bool CanBeBreeder(Pawn animal, Precept_Ritual precept)
- {
- if (precept != null && precept.ideo.HasPrecept(VariousDefOf.Bestiality_OnlyVenerated) && !precept.ideo.IsVeneratedAnimal(animal))
+ public override bool AppliesToPawn(Pawn p, out string reason, TargetInfo selectedTarget, LordJob_Ritual ritual = null, RitualRoleAssignments assignments = null, Precept_Ritual precept = null, bool skipReason = false)
+ {
+ reason = null;
+ if (!p.IsAnimal())
+ {
+ reason = Keyed.RSNotAnimal;
+ return false;
+ }
+ if (CanBeBreeder(p, assignments?.Ritual)) return true;
+ if (!skipReason)
+ {
+ reason = Keyed.RSBreederCondition;
+ }
+ return false;
+ }
+
+ public static bool CanBeBreeder(Pawn animal, Precept_Ritual precept)
+ {
+ if (precept != null && precept.ideo.HasPrecept(RsiDefOf.Precept.Bestiality_OnlyVenerated) && !precept.ideo.IsVeneratedAnimal(animal))
{
return false;
}
- if (!xxx.can_rape(animal)) return false;
- return true;
- }
-
- }
-
-
+ if (!xxx.can_rape(animal))
+ {
+ return false;
+ }
+ return true;
+ }
+ }
}
diff --git a/Source/IdeologyAddon/RomanceChanceFactorHelpers.cs b/Source/IdeologyAddon/RomanceChanceFactorHelpers.cs
new file mode 100644
index 0000000..6d970f3
--- /dev/null
+++ b/Source/IdeologyAddon/RomanceChanceFactorHelpers.cs
@@ -0,0 +1,89 @@
+using RimWorld;
+using RJWSexperience.Ideology.Precepts;
+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)
+ {
+ float romanceChanceFactor = 1f;
+
+ if (!pawn.relations.FamilyByBlood.Contains(partner))
+ {
+ if (pawn.Ideo?.HasPrecept(RsiDefOf.Precept.Incestuos_IncestOnly) == true)
+ {
+ return parentRomanceChanceFactor;
+ }
+ else
+ {
+ return romanceChanceFactor;
+ }
+ }
+
+ PreceptDef incestuousPrecept = pawn.Ideo?.PreceptsListForReading.Select(precept => precept.def).FirstOrFallback(def => def.issue == RsiDefOf.Issue.Incestuos);
+ IEnumerable relations = pawn.GetRelations(partner).Where(def => def.familyByBloodRelation);
+ 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)
+ {
+ return relationDef.romanceChanceFactor;
+ }
+
+ var incestDefExt = incestuousPrecept.GetModExtension();
+
+ if (incestDefExt == null)
+ {
+ return relationDef.romanceChanceFactor;
+ }
+
+ BloodRelationDegree relationDegree = RelationHelpers.GetBloodRelationDegree(relationDef);
+
+ if (incestDefExt.TryGetRomanceChanceFactor(relationDegree, out var romanceChanceOverride))
+ {
+ return romanceChanceOverride;
+ }
+
+ 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 == RsiDefOf.Issue.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/RsiDefOf.cs b/Source/IdeologyAddon/RsiDefOf.cs
new file mode 100644
index 0000000..d5b0cfa
--- /dev/null
+++ b/Source/IdeologyAddon/RsiDefOf.cs
@@ -0,0 +1,65 @@
+using RimWorld;
+using Verse;
+
+namespace RJWSexperience.Ideology
+{
+ public static class RsiDefOf
+ {
+ [DefOf]
+ public static class Job
+ {
+ public static readonly JobDef RapeVictim;
+ public static readonly JobDef Gangbang;
+ public static readonly JobDef GettinGangbang;
+ public static readonly JobDef DrugSex;
+ public static readonly JobDef GettinDrugSex;
+ public static readonly JobDef DrugMasturbate;
+ }
+
+ [DefOf]
+ public static class Meme
+ {
+ public static readonly MemeDef Zoophile;
+ public static readonly MemeDef Rapist;
+ public static readonly MemeDef Necrophile;
+ }
+
+ [DefOf]
+ public static class Issue
+ {
+ public static readonly IssueDef Incestuos;
+ }
+
+ [DefOf]
+ public static class Precept
+ {
+ 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;
+ }
+
+ [DefOf]
+ public static class HistoryEvent
+ {
+ public static readonly HistoryEventDef RSI_SexWithAnimal;
+ public static readonly HistoryEventDef RSI_Raped;
+ public static readonly HistoryEventDef RSI_NonIncestuosMarriage;
+ public static readonly HistoryEventDef RSI_NonIncestuosSex;
+ public static readonly HistoryEventDef RSI_SexWithCorpse;
+ public static readonly HistoryEventDef RSI_VirginTaken;
+ public static readonly HistoryEventDef RSI_VirginStolen;
+ public static readonly HistoryEventDef RSI_TookVirgin;
+ public static readonly HistoryEventDef RSI_Masturbated;
+ }
+
+ [DefOf]
+ public static class Hediff
+ {
+ [MayRequireBiotech] public static readonly HediffDef PregnantHuman;
+ }
+ }
+}
diff --git a/Source/IdeologyAddon/RsiHistoryEventDefOf.cs b/Source/IdeologyAddon/RsiHistoryEventDefOf.cs
deleted file mode 100644
index 0155d66..0000000
--- a/Source/IdeologyAddon/RsiHistoryEventDefOf.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using RimWorld;
-
-namespace RJWSexperience.Ideology
-{
- [DefOf]
- public static class RsiHistoryEventDefOf
- {
- [MayRequireIdeology] public static readonly HistoryEventDef RSI_SexWithAnimal;
- [MayRequireIdeology] public static readonly HistoryEventDef RSI_Raped;
- [MayRequireIdeology] public static readonly HistoryEventDef RSI_NonIncestuosMarriage;
- [MayRequireIdeology] public static readonly HistoryEventDef RSI_NonIncestuosSex;
- [MayRequireIdeology] public static readonly HistoryEventDef RSI_SexWithCorpse;
- [MayRequireIdeology] public static readonly HistoryEventDef RSI_VirginTaken;
- [MayRequireIdeology] public static readonly HistoryEventDef RSI_VirginStolen;
- [MayRequireIdeology] public static readonly HistoryEventDef RSI_TookVirgin;
- [MayRequireIdeology] public static readonly HistoryEventDef RSI_Masturbated;
- }
-}
diff --git a/Source/IdeologyAddon/RsiMod.cs b/Source/IdeologyAddon/RsiMod.cs
new file mode 100644
index 0000000..66dab60
--- /dev/null
+++ b/Source/IdeologyAddon/RsiMod.cs
@@ -0,0 +1,26 @@
+using UnityEngine;
+using Verse;
+
+namespace RJWSexperience.Ideology
+{
+ public class RsiMod : Mod
+ {
+ public static RsiSettings Prefs { get; private set; }
+
+ public RsiMod(ModContentPack content) : base(content)
+ {
+ Prefs = GetSettings();
+ }
+
+ public override string SettingsCategory() => Keyed.ModTitle;
+
+ public override void DoSettingsWindowContents(Rect inRect)
+ {
+ Listing_Standard listmain = new Listing_Standard();
+ listmain.Begin(inRect);
+ listmain.CheckboxLabeled(Keyed.PatchRomanceChanceFactor, ref Prefs.patchRomanceChanceFactor, Keyed.PatchRomanceChanceFactorTip);
+ listmain.CheckboxLabeled(Keyed.PatchIncestuousManualRomance, ref Prefs.patchIncestuousManualRomance, Keyed.PatchIncestuousManualRomanceTip);
+ listmain.End();
+ }
+ }
+}
diff --git a/Source/IdeologyAddon/RsiSettings.cs b/Source/IdeologyAddon/RsiSettings.cs
new file mode 100644
index 0000000..215b625
--- /dev/null
+++ b/Source/IdeologyAddon/RsiSettings.cs
@@ -0,0 +1,17 @@
+using Verse;
+
+namespace RJWSexperience.Ideology
+{
+ public class RsiSettings : ModSettings
+ {
+ public bool patchRomanceChanceFactor;
+ public bool patchIncestuousManualRomance;
+
+ public override void ExposeData()
+ {
+ base.ExposeData();
+ Scribe_Values.Look(ref patchRomanceChanceFactor, "patchSecondaryRomanceChanceFactor", true);
+ Scribe_Values.Look(ref patchIncestuousManualRomance, "patchIncestuousManualRomance", true);
+ }
+ }
+}
diff --git a/Source/IdeologyAddon/TwoPawnFilter.cs b/Source/IdeologyAddon/TwoPawnFilter.cs
deleted file mode 100644
index 7c49f92..0000000
--- a/Source/IdeologyAddon/TwoPawnFilter.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using rjw;
-using System.Diagnostics.CodeAnalysis;
-using Verse;
-
-namespace RJWSexperience.Ideology
-{
- public class TwoPawnFilter
- {
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
- public SinglePawnFilter doer;
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
- public SinglePawnFilter partner;
- [SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
- public RelationFilter relations;
-
- public bool Applies(Pawn pawn, Pawn partner)
- {
- if (doer?.Applies(pawn) == false)
- return false;
-
- if (this.partner?.Applies(partner) == false)
- return false;
-
- if (relations?.Applies(pawn, partner) == false)
- return false;
-
- return true;
- }
- }
-}
diff --git a/Source/IdeologyAddon/VariousDefOf.cs b/Source/IdeologyAddon/VariousDefOf.cs
deleted file mode 100644
index fb926ce..0000000
--- a/Source/IdeologyAddon/VariousDefOf.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using RimWorld;
-using Verse;
-
-namespace RJWSexperience.Ideology
-{
- [DefOf]
- public static class VariousDefOf
- {
- public static readonly JobDef RapeVictim;
- public static readonly JobDef Gangbang;
- public static readonly JobDef GettinGangbang;
- public static readonly JobDef DrugSex;
- 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;
- [MayRequireBiotech] public static readonly HediffDef PregnantHuman;
- }
-}