mirror of
				https://gitgud.io/amevarashi/rjw-sexperience-ideology.git
				synced 2024-08-15 00:43:19 +00:00 
			
		
		
		
	Initial commit
This commit is contained in:
		
						commit
						8c960f3d15
					
				
					 182 changed files with 10200 additions and 0 deletions
				
			
		
							
								
								
									
										8
									
								
								Source/IdeologyAddon/GlobalSuppressions.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								Source/IdeologyAddon/GlobalSuppressions.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
// This file is used by Code Analysis to maintain SuppressMessage
 | 
			
		||||
// attributes that are applied to this project.
 | 
			
		||||
// Project-level suppressions either have no target or are given
 | 
			
		||||
// a specific target and scoped to a namespace, type, member, etc.
 | 
			
		||||
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
 | 
			
		||||
[assembly: SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Rimworld naming conventions")]
 | 
			
		||||
							
								
								
									
										25
									
								
								Source/IdeologyAddon/Harmony.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								Source/IdeologyAddon/Harmony.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
using HarmonyLib;
 | 
			
		||||
using RJWSexperience.Ideology.Patches;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology
 | 
			
		||||
{
 | 
			
		||||
	[StaticConstructorOnStartup]
 | 
			
		||||
	internal static class First
 | 
			
		||||
	{
 | 
			
		||||
		static First()
 | 
			
		||||
		{
 | 
			
		||||
			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))
 | 
			
		||||
					);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology
 | 
			
		||||
{
 | 
			
		||||
	public class GoodwillSituationWorker_OneWayReceive : GoodwillSituationWorker_MemeCompatibility
 | 
			
		||||
	{
 | 
			
		||||
		public override int GetNaturalGoodwillOffset(Faction other)
 | 
			
		||||
		{
 | 
			
		||||
			if (!Applies(other))
 | 
			
		||||
				return 0;
 | 
			
		||||
			return def.naturalGoodwillOffset;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected bool Applies(Faction other)
 | 
			
		||||
		{
 | 
			
		||||
			Ideo primaryideo = Faction.OfPlayer.ideos?.PrimaryIdeo;
 | 
			
		||||
			Ideo primaryideo2 = other.ideos?.PrimaryIdeo;
 | 
			
		||||
			if (primaryideo == null || primaryideo2 == null)
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
			return primaryideo.memes.Contains(def.meme) && !primaryideo2.memes.Contains(def.meme);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
namespace RJWSexperience.Ideology.HistoryEvents
 | 
			
		||||
{
 | 
			
		||||
	public static class ArgsNamesCustom
 | 
			
		||||
	{
 | 
			
		||||
		public const string Partner = "PARTNER";
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology.HistoryEvents
 | 
			
		||||
{
 | 
			
		||||
	public class DefExtension_EventOverrides : DefModExtension
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public List<TwoPawnEventRule> overrideRules = new List<TwoPawnEventRule>();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology.HistoryEvents
 | 
			
		||||
{
 | 
			
		||||
	public class DefExtension_SecondaryEvents : DefModExtension
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public List<TwoPawnEventRule> generationRules = new List<TwoPawnEventRule>();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology.HistoryEvents
 | 
			
		||||
{
 | 
			
		||||
	public static class HistoryEventDefExtensionMethods
 | 
			
		||||
	{
 | 
			
		||||
		public static void RecordEventWithPartner(this HistoryEventDef def, Pawn pawn, Pawn partner)
 | 
			
		||||
		{
 | 
			
		||||
			DefExtension_SecondaryEvents secondaryEvents = def.GetModExtension<DefExtension_SecondaryEvents>();
 | 
			
		||||
 | 
			
		||||
			if (secondaryEvents != null)
 | 
			
		||||
			{
 | 
			
		||||
				foreach (TwoPawnEventRule rule in secondaryEvents.generationRules)
 | 
			
		||||
				{
 | 
			
		||||
					if (rule.Applies(pawn, partner))
 | 
			
		||||
						rule.historyEventDef.RecordEventWithPartner(pawn, partner);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Find.HistoryEventsManager.RecordEvent(def.CreateEventWithPartner(pawn, 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)
 | 
			
		||||
		{
 | 
			
		||||
			DefExtension_EventOverrides overrides = def.GetModExtension<DefExtension_EventOverrides>();
 | 
			
		||||
 | 
			
		||||
			if (overrides == null)
 | 
			
		||||
				return new HistoryEvent(def, pawn.Named(HistoryEventArgsNames.Doer), partner.Named(ArgsNamesCustom.Partner));
 | 
			
		||||
 | 
			
		||||
			foreach (TwoPawnEventRule 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(ArgsNamesCustom.Partner));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology.HistoryEvents
 | 
			
		||||
{
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
		public bool Applies(Pawn pawn, Pawn partner) => filter?.Applies(pawn, partner) == true;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								Source/IdeologyAddon/Ideology/IdeoUtility.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Source/IdeologyAddon/Ideology/IdeoUtility.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology
 | 
			
		||||
{
 | 
			
		||||
	public static class IdeoUtility
 | 
			
		||||
	{
 | 
			
		||||
		public static bool IsSubmissive(this Pawn pawn)
 | 
			
		||||
		{
 | 
			
		||||
			Ideo ideo = pawn.Ideo;
 | 
			
		||||
			if (ideo == null)
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
			if (ideo.HasPrecept(VariousDefOf.Submissive_Female) && pawn.gender == Gender.Female)
 | 
			
		||||
				return true;
 | 
			
		||||
			else if (ideo.HasPrecept(VariousDefOf.Submissive_Male) && pawn.gender == Gender.Male)
 | 
			
		||||
				return true;
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static float GetPreceptsMtbMultiplier<T>(Ideo ideo) where T : Precepts.DefExtension_ModifyMtb
 | 
			
		||||
		{
 | 
			
		||||
			float finalMultiplier = 1f;
 | 
			
		||||
			for (int i = 0; i < ideo.PreceptsListForReading.Count; i++)
 | 
			
		||||
			{
 | 
			
		||||
				T defExtension = ideo.PreceptsListForReading[i].def.GetModExtension<T>();
 | 
			
		||||
 | 
			
		||||
				if (defExtension == null)
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				finalMultiplier *= defExtension.multiplier;
 | 
			
		||||
			}
 | 
			
		||||
			return finalMultiplier;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology
 | 
			
		||||
{
 | 
			
		||||
	public class InteractionDefExtension_HistoryEvents : DefModExtension
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public List<HistoryEventDef> pawnEvents = new List<HistoryEventDef>();
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public List<HistoryEventDef> partnerEvents = new List<HistoryEventDef>();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								Source/IdeologyAddon/Ideology/Keyed.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Source/IdeologyAddon/Ideology/Keyed.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience
 | 
			
		||||
{
 | 
			
		||||
	public static class Keyed
 | 
			
		||||
	{
 | 
			
		||||
		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();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,76 @@
 | 
			
		|||
using HarmonyLib;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw;
 | 
			
		||||
using RJWSexperience.Ideology.HistoryEvents;
 | 
			
		||||
using RJWSexperience.Ideology.Precepts;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology.Patches
 | 
			
		||||
{
 | 
			
		||||
	[HarmonyPatch(typeof(ThinkNode_ChancePerHour_Bestiality), "MtbHours")]
 | 
			
		||||
	public static class RJW_Patch_ThinkNode_ChancePerHour_Bestiality
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(Pawn pawn, ref float __result)
 | 
			
		||||
		{
 | 
			
		||||
			if (__result < 0f || pawn.Ideo == null) // ideo is null if don't have dlc
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			if (!RsiHistoryEventDefOf.RSI_SexWithAnimal.CreateEvent(pawn).DoerWillingToDo())
 | 
			
		||||
			{
 | 
			
		||||
				__result = -2f;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			__result *= IdeoUtility.GetPreceptsMtbMultiplier<DefExtension_ModifyBestialityMtb>(pawn.Ideo);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(ThinkNode_ChancePerHour_RapeCP), "MtbHours")]
 | 
			
		||||
	public static class RJW_Patch_ThinkNode_ChancePerHour_RapeCP
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(Pawn pawn, ref float __result)
 | 
			
		||||
		{
 | 
			
		||||
			if (__result < 0f || pawn.Ideo == null) // ideo is null if don't have dlc
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			if (!RsiHistoryEventDefOf.RSI_Raped.CreateEvent(pawn).DoerWillingToDo())
 | 
			
		||||
			{
 | 
			
		||||
				__result = -2f;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			__result *= IdeoUtility.GetPreceptsMtbMultiplier<DefExtension_ModifyRapeCPMtb>(pawn.Ideo);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	[HarmonyPatch(typeof(ThinkNode_ChancePerHour_Necro), "MtbHours")]
 | 
			
		||||
	public static class RJW_Patch_ThinkNode_ChancePerHour_Necro
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(Pawn pawn, ref float __result)
 | 
			
		||||
		{
 | 
			
		||||
			if (__result < 0f || pawn.Ideo == null) // ideo is null if don't have dlc
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			if (!RsiHistoryEventDefOf.RSI_SexWithCorpse.CreateEvent(pawn).DoerWillingToDo())
 | 
			
		||||
			{
 | 
			
		||||
				__result = -2f;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			__result *= IdeoUtility.GetPreceptsMtbMultiplier<DefExtension_ModifyNecroMtb>(pawn.Ideo);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(ThinkNode_ChancePerHour_Fappin), "MtbHours")]
 | 
			
		||||
	public static class RJW_Patch_ThinkNode_ChancePerHour_Fappin
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(Pawn p, ref float __result)
 | 
			
		||||
		{
 | 
			
		||||
			if (__result < 0f || p.Ideo == null) // ideo is null if don't have dlc
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			if (!RsiHistoryEventDefOf.RSI_Masturbated.CreateEvent(p).DoerWillingToDo())
 | 
			
		||||
			{
 | 
			
		||||
				__result = -2f;
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			__result *= IdeoUtility.GetPreceptsMtbMultiplier<DefExtension_ModifyFappinMtb>(p.Ideo);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										214
									
								
								Source/IdeologyAddon/Ideology/Patches/RJW_Patch_Ideo.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								Source/IdeologyAddon/Ideology/Patches/RJW_Patch_Ideo.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,214 @@
 | 
			
		|||
using HarmonyLib;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw;
 | 
			
		||||
using rjw.Modules.Interactions.Internals.Implementation;
 | 
			
		||||
using rjw.Modules.Interactions.Objects;
 | 
			
		||||
using RJWSexperience.Ideology.HistoryEvents;
 | 
			
		||||
using RJWSexperience.Ideology.Precepts;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology.Patches
 | 
			
		||||
{
 | 
			
		||||
	[HarmonyPatch(typeof(xxx), nameof(xxx.is_rapist))]
 | 
			
		||||
	public static class RJW_Patch_is_rapist
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(Pawn pawn, ref bool __result)
 | 
			
		||||
		{
 | 
			
		||||
			Ideo ideo = pawn.Ideo;
 | 
			
		||||
			if (ideo != null && !pawn.IsSubmissive())
 | 
			
		||||
			{
 | 
			
		||||
				__result = __result || ideo.HasMeme(VariousDefOf.Rapist);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(xxx), nameof(xxx.is_zoophile))]
 | 
			
		||||
	public static class RJW_Patch_is_zoophile
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(Pawn pawn, ref bool __result)
 | 
			
		||||
		{
 | 
			
		||||
			Ideo ideo = pawn.Ideo;
 | 
			
		||||
			if (ideo != null)
 | 
			
		||||
			{
 | 
			
		||||
				__result = __result || ideo.HasMeme(VariousDefOf.Zoophile);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(xxx), nameof(xxx.is_necrophiliac))]
 | 
			
		||||
	public static class RJW_Patch_is_necrophiliac
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(Pawn pawn, ref bool __result)
 | 
			
		||||
		{
 | 
			
		||||
			Ideo ideo = pawn.Ideo;
 | 
			
		||||
			if (ideo != null)
 | 
			
		||||
			{
 | 
			
		||||
				__result = __result || ideo.HasMeme(VariousDefOf.Necrophile);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(SexUtility), nameof(SexUtility.Aftersex), new Type[] { typeof(SexProps) })]
 | 
			
		||||
	public static class RJW_Patch_SexUtility_Aftersex_RecordHistoryEvents
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(SexProps props)
 | 
			
		||||
		{
 | 
			
		||||
			InteractionDefExtension_HistoryEvents interactionEvents = props.dictionaryKey.GetModExtension<InteractionDefExtension_HistoryEvents>();
 | 
			
		||||
 | 
			
		||||
			if (props.hasPartner())
 | 
			
		||||
			{
 | 
			
		||||
				if (xxx.is_human(props.pawn))
 | 
			
		||||
					AfterSexHuman(props.pawn, props.partner);
 | 
			
		||||
				if (xxx.is_human(props.partner))
 | 
			
		||||
					AfterSexHuman(props.partner, props.pawn);
 | 
			
		||||
 | 
			
		||||
				if (interactionEvents != null)
 | 
			
		||||
				{
 | 
			
		||||
					foreach (HistoryEventDef eventDef in interactionEvents.pawnEvents)
 | 
			
		||||
						eventDef.RecordEventWithPartner(props.pawn, props.partner);
 | 
			
		||||
 | 
			
		||||
					foreach (HistoryEventDef eventDef in interactionEvents.partnerEvents)
 | 
			
		||||
						eventDef.RecordEventWithPartner(props.partner, props.pawn);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				if (interactionEvents != null)
 | 
			
		||||
				{
 | 
			
		||||
					foreach (HistoryEventDef eventDef in interactionEvents.pawnEvents)
 | 
			
		||||
						Find.HistoryEventsManager.RecordEvent(eventDef.CreateEvent(props.pawn));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void AfterSexHuman(Pawn human, Pawn partner)
 | 
			
		||||
		{
 | 
			
		||||
			RsiHistoryEventDefOf.RSI_NonIncestuosSex.RecordEventWithPartner(human, partner);
 | 
			
		||||
 | 
			
		||||
			if (partner.IsAnimal())
 | 
			
		||||
				RsiHistoryEventDefOf.RSI_SexWithAnimal.RecordEventWithPartner(human, partner);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Set prefer sextype using precepts
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	[HarmonyPatch(typeof(InteractionScoringService), nameof(InteractionScoringService.Score), new Type[] { typeof(InteractionWithExtension), typeof(InteractionPawn), typeof(InteractionPawn) })]
 | 
			
		||||
	public static class RJW_Patch_DetermineSexScores
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(InteractionWithExtension interaction, InteractionPawn dominant, InteractionPawn submissive, ref InteractionScore __result)
 | 
			
		||||
		{
 | 
			
		||||
			InteractionDefExtension_HistoryEvents interactionEvents = interaction.Interaction.GetModExtension<InteractionDefExtension_HistoryEvents>();
 | 
			
		||||
			if (interactionEvents == null)
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			if (dominant.Pawn.Ideo != null)
 | 
			
		||||
				__result.Dominant = PreceptSextype(dominant.Pawn, submissive.Pawn, __result.Dominant, interactionEvents.pawnEvents);
 | 
			
		||||
 | 
			
		||||
			if (submissive.Pawn.Ideo != null)
 | 
			
		||||
				__result.Submissive = PreceptSextype(submissive.Pawn, dominant.Pawn, __result.Submissive, interactionEvents.partnerEvents);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static float PreceptSextype(Pawn pawn, Pawn partner, float score, List<HistoryEventDef> historyEventDefs)
 | 
			
		||||
		{
 | 
			
		||||
			foreach(HistoryEventDef eventDef in historyEventDefs)
 | 
			
		||||
			{
 | 
			
		||||
				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)));
 | 
			
		||||
					return score * mult;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return score;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(SexAppraiser), nameof(SexAppraiser.would_fuck), new Type[] { typeof(Pawn), typeof(Pawn), typeof(bool), typeof(bool), typeof(bool) })]
 | 
			
		||||
	public static class RJW_Patch_would_fuck
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(Pawn fucker, Pawn fucked, ref float __result)
 | 
			
		||||
		{
 | 
			
		||||
			if (!xxx.is_human(fucker))
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			Ideo ideo = fucker.Ideo;
 | 
			
		||||
			if (ideo == null)
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < ideo.PreceptsListForReading.Count; i++)
 | 
			
		||||
				ideo.PreceptsListForReading[i].def.GetModExtension<DefExtension_ModifyPreference>()?.Apply(fucker, fucked, ref __result);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(PawnDesignations_Breedee), nameof(PawnDesignations_Breedee.UpdateCanDesignateBreeding))]
 | 
			
		||||
	public static class RJW_Patch_UpdateCanDesignateBreeding
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(Pawn pawn, ref bool __result)
 | 
			
		||||
		{
 | 
			
		||||
			Ideo ideo = pawn.Ideo;
 | 
			
		||||
			if (ideo?.HasMeme(VariousDefOf.Zoophile) == true)
 | 
			
		||||
			{
 | 
			
		||||
				SaveStorage.DataStore.GetPawnData(pawn).CanDesignateBreeding = true;
 | 
			
		||||
				__result = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(PawnDesignations_Comfort), nameof(PawnDesignations_Comfort.UpdateCanDesignateComfort))]
 | 
			
		||||
	public static class RJW_PatchUpdateCanDesignateComfort
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(Pawn pawn, ref bool __result)
 | 
			
		||||
		{
 | 
			
		||||
			if (pawn.IsSubmissive())
 | 
			
		||||
			{
 | 
			
		||||
				SaveStorage.DataStore.GetPawnData(pawn).CanDesignateComfort = true;
 | 
			
		||||
				__result = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(Hediff_BasePregnancy), nameof(Hediff_BasePregnancy.PostBirth))]
 | 
			
		||||
	public static class RJW_Patch_PostBirth
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(Pawn mother, Pawn baby)
 | 
			
		||||
		{
 | 
			
		||||
			if (!mother.IsAnimal())
 | 
			
		||||
			{
 | 
			
		||||
				Faction faction = baby.GetFactionUsingPrecept(out Ideo ideo);
 | 
			
		||||
				if (baby.Faction != faction)
 | 
			
		||||
					baby.SetFaction(faction);
 | 
			
		||||
 | 
			
		||||
				baby.ideo?.SetIdeo(ideo);
 | 
			
		||||
 | 
			
		||||
				if (baby.Faction == Find.FactionManager.OfPlayer && !baby.IsSlave)
 | 
			
		||||
					baby.guest?.SetGuestStatus(null, GuestStatus.Guest);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static Faction GetFactionUsingPrecept(this Pawn baby, out Ideo ideo)
 | 
			
		||||
		{
 | 
			
		||||
			Faction playerfaction = Find.FactionManager.OfPlayer;
 | 
			
		||||
			Ideo mainideo = playerfaction.ideos.PrimaryIdeo;
 | 
			
		||||
			if (mainideo != null)
 | 
			
		||||
			{
 | 
			
		||||
				if (mainideo.HasPrecept(VariousDefOf.BabyFaction_AlwaysFather))
 | 
			
		||||
				{
 | 
			
		||||
					Pawn parent = baby.GetFather() ?? baby.GetMother();
 | 
			
		||||
 | 
			
		||||
					ideo = parent.Ideo;
 | 
			
		||||
					return parent.Faction;
 | 
			
		||||
				}
 | 
			
		||||
				else if (mainideo.HasPrecept(VariousDefOf.BabyFaction_AlwaysColony))
 | 
			
		||||
				{
 | 
			
		||||
					ideo = mainideo;
 | 
			
		||||
					return playerfaction;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			Pawn mother = baby.GetMother();
 | 
			
		||||
			ideo = mother?.Ideo;
 | 
			
		||||
			return mother?.Faction ?? baby.Faction;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								Source/IdeologyAddon/Ideology/Patches/Rimworld_Patch.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								Source/IdeologyAddon/Ideology/Patches/Rimworld_Patch.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
using HarmonyLib;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw;
 | 
			
		||||
using RJWSexperience.Ideology.HistoryEvents;
 | 
			
		||||
using RJWSexperience.Ideology.Precepts;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology.Patches
 | 
			
		||||
{
 | 
			
		||||
	[HarmonyPatch(typeof(MarriageCeremonyUtility), nameof(MarriageCeremonyUtility.Married))]
 | 
			
		||||
	public static class Rimworld_Patch_Marriage
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(Pawn firstPawn, Pawn secondPawn)
 | 
			
		||||
		{
 | 
			
		||||
			RsiHistoryEventDefOf.RSI_NonIncestuosMarriage.RecordEventWithPartner(firstPawn, secondPawn);
 | 
			
		||||
			RsiHistoryEventDefOf.RSI_NonIncestuosMarriage.RecordEventWithPartner(secondPawn, firstPawn);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(RitualOutcomeEffectWorker_FromQuality), "GiveMemoryToPawn")]
 | 
			
		||||
	public static class Rimworld_Patch_RitualOutcome_DontGiveMemoryToAnimals
 | 
			
		||||
	{
 | 
			
		||||
		public static bool Prefix(Pawn pawn)
 | 
			
		||||
		{
 | 
			
		||||
			return !pawn.IsAnimal();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(IdeoFoundation), nameof(IdeoFoundation.CanAdd))]
 | 
			
		||||
	public static class Rimworld_Patch_IdeoFoundation
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(PreceptDef precept, ref IdeoFoundation __instance, ref AcceptanceReport __result)
 | 
			
		||||
		{
 | 
			
		||||
			DefExtension_MultipleMemesRequired extension = precept.GetModExtension<DefExtension_MultipleMemesRequired>();
 | 
			
		||||
 | 
			
		||||
			if (extension == null)
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			if (extension.requiredAllMemes.NullOrEmpty())
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			for (int i = 0; i < extension.requiredAllMemes.Count; i++)
 | 
			
		||||
			{
 | 
			
		||||
				if (!__instance.ideo.memes.Contains(extension.requiredAllMemes[i]))
 | 
			
		||||
				{
 | 
			
		||||
					List<string> report = new List<string>();
 | 
			
		||||
					foreach (MemeDef meme in extension.requiredAllMemes) report.Add(meme.LabelCap);
 | 
			
		||||
 | 
			
		||||
					__result = new AcceptanceReport("RequiresMeme".Translate() + ": " + report.ToCommaList());
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								Source/IdeologyAddon/Ideology/Patches/Sexperience_Patch.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Source/IdeologyAddon/Ideology/Patches/Sexperience_Patch.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
using rjw;
 | 
			
		||||
using RJWSexperience.Ideology.HistoryEvents;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology.Patches
 | 
			
		||||
{
 | 
			
		||||
	public static class Sexperience_Patch_ThrowVirginHistoryEvent
 | 
			
		||||
	{
 | 
			
		||||
		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);
 | 
			
		||||
			else if (degree != femaleAfterSurgery)
 | 
			
		||||
				RsiHistoryEventDefOf.RSI_VirginTaken.RecordEventWithPartner(exVirgin, partner);
 | 
			
		||||
 | 
			
		||||
			RsiHistoryEventDefOf.RSI_TookVirgin.RecordEventWithPartner(partner, exVirgin);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology.Precepts
 | 
			
		||||
{
 | 
			
		||||
	public class Comp_KnowsMemoryThought_Gendered : PreceptComp_KnowsMemoryThought
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public Gender doersGender;
 | 
			
		||||
 | 
			
		||||
		public override void Notify_MemberWitnessedAction(HistoryEvent ev, Precept precept, Pawn member)
 | 
			
		||||
		{
 | 
			
		||||
			Pawn doer = ev.args.GetArg<Pawn>(HistoryEventArgsNames.Doer);
 | 
			
		||||
			if (doer.gender == doersGender)
 | 
			
		||||
				base.Notify_MemberWitnessedAction(ev, precept, member);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology.Precepts
 | 
			
		||||
{
 | 
			
		||||
	public class Comp_SelfTookMemoryThought_Gendered : PreceptComp_SelfTookMemoryThought
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public Gender gender;
 | 
			
		||||
 | 
			
		||||
		public override void Notify_MemberTookAction(HistoryEvent ev, Precept precept, bool canApplySelfTookThoughts)
 | 
			
		||||
		{
 | 
			
		||||
			Pawn doer = ev.args.GetArg<Pawn>(HistoryEventArgsNames.Doer);
 | 
			
		||||
			if (doer.gender == gender)
 | 
			
		||||
				TakeThought(ev, precept, canApplySelfTookThoughts, doer);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// This is a copy of base.Notify_MemberTookAction, but with partner handling
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		protected void TakeThought(HistoryEvent ev, Precept precept, bool canApplySelfTookThoughts, Pawn doer)
 | 
			
		||||
		{
 | 
			
		||||
			if (ev.def != eventDef || !canApplySelfTookThoughts)
 | 
			
		||||
			{
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			Pawn partner = ev.args.GetArg<Pawn>(HistoryEvents.ArgsNamesCustom.Partner);
 | 
			
		||||
			if (doer.needs?.mood != null && (!onlyForNonSlaves || !doer.IsSlave))
 | 
			
		||||
			{
 | 
			
		||||
				if (thought.minExpectationForNegativeThought != null && ExpectationsUtility.CurrentExpectationFor(doer).order < thought.minExpectationForNegativeThought.order)
 | 
			
		||||
				{
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				Thought_Memory thought_Memory = ThoughtMaker.MakeThought(thought, precept);
 | 
			
		||||
				if (thought_Memory is Thought_KilledInnocentAnimal thought_KilledInnocentAnimal && ev.args.TryGetArg<Pawn>(HistoryEventArgsNames.Victim, out Pawn animal))
 | 
			
		||||
				{
 | 
			
		||||
					thought_KilledInnocentAnimal.SetAnimal(animal);
 | 
			
		||||
				}
 | 
			
		||||
				if (thought_Memory is Thought_MemoryObservation thought_MemoryObservation && ev.args.TryGetArg<Corpse>(HistoryEventArgsNames.Subject, out Corpse target))
 | 
			
		||||
				{
 | 
			
		||||
					thought_MemoryObservation.Target = target;
 | 
			
		||||
				}
 | 
			
		||||
				doer.needs.mood.thoughts.memories.TryGainMemory(thought_Memory, partner);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
namespace RJWSexperience.Ideology.Precepts
 | 
			
		||||
{
 | 
			
		||||
	public class DefExtension_ModifyBestialityMtb : DefExtension_ModifyMtb
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
namespace RJWSexperience.Ideology.Precepts
 | 
			
		||||
{
 | 
			
		||||
	public class DefExtension_ModifyFappinMtb : DefExtension_ModifyMtb
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
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 value loaded from XML")]
 | 
			
		||||
		public float multiplier = 1f;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
namespace RJWSexperience.Ideology.Precepts
 | 
			
		||||
{
 | 
			
		||||
	public class DefExtension_ModifyNecroMtb : DefExtension_ModifyMtb
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology.Precepts
 | 
			
		||||
{
 | 
			
		||||
	public class DefExtension_ModifyPreference : DefModExtension
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public List<Rule> rules;
 | 
			
		||||
 | 
			
		||||
		public void Apply(Pawn pawn, Pawn partner, ref float preference)
 | 
			
		||||
		{
 | 
			
		||||
			foreach (Rule rule in rules)
 | 
			
		||||
			{
 | 
			
		||||
				if (rule.Applies(pawn, partner))
 | 
			
		||||
					preference *= rule.multiplier;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		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;
 | 
			
		||||
 | 
			
		||||
			public bool Applies(Pawn pawn, Pawn partner)
 | 
			
		||||
			{
 | 
			
		||||
				if (filter == null)
 | 
			
		||||
					return true;
 | 
			
		||||
 | 
			
		||||
				return filter.Applies(pawn, partner);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
namespace RJWSexperience.Ideology.Precepts
 | 
			
		||||
{
 | 
			
		||||
	public class DefExtension_ModifyRapeCPMtb : DefExtension_ModifyMtb
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology.Precepts
 | 
			
		||||
{
 | 
			
		||||
	public class DefExtension_MultipleMemesRequired : DefModExtension
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public List<MemeDef> requiredAllMemes = new List<MemeDef>();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										75
									
								
								Source/IdeologyAddon/Ideology/RelationFilter.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								Source/IdeologyAddon/Ideology/RelationFilter.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology
 | 
			
		||||
{
 | 
			
		||||
	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<PawnRelationDef> hasOneOfRelations;
 | 
			
		||||
		[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 (isVeneratedAnimal != null && isVeneratedAnimal != pawn.Ideo.IsVeneratedAnimal(partner))
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
			//if (isAlien != null && isAlien != partner)
 | 
			
		||||
			//	return false;
 | 
			
		||||
 | 
			
		||||
			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 (relations.EnumerableNullOrEmpty())
 | 
			
		||||
					return false;
 | 
			
		||||
 | 
			
		||||
				if (!hasOneOfRelationsHashed.Overlaps(relations))
 | 
			
		||||
					return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (hasNoneOfRelationsHashed != null && !relations.EnumerableNullOrEmpty() && hasNoneOfRelationsHashed.Overlaps(relations))
 | 
			
		||||
			{
 | 
			
		||||
				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;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										257
									
								
								Source/IdeologyAddon/Ideology/Rituals/JobGiver_DrugOrgy.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										257
									
								
								Source/IdeologyAddon/Ideology/Rituals/JobGiver_DrugOrgy.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,257 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using rjw;
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
            if (dutyDef == DutyDefOf.TravelOrLeave || !xxx.can_do_loving(pawn))
 | 
			
		||||
            {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            Pawn target = FindPartner(pawn, duty);
 | 
			
		||||
 | 
			
		||||
            if (target == null || !pawn.CanReserveAndReach(target, PathEndMode.ClosestTouch, Danger.None,1)) return JobMaker.MakeJob(VariousDefOf.DrugMasturbate);
 | 
			
		||||
 | 
			
		||||
            return JobMaker.MakeJob(VariousDefOf.DrugSex, target);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected Pawn FindPartner(Pawn pawn, PawnDuty duty)
 | 
			
		||||
        {
 | 
			
		||||
            if (duty != null)
 | 
			
		||||
            {
 | 
			
		||||
                List<Pawn> 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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// copied from rjw
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public class JobDriver_SexDrugOrgy : JobDriver_SexBaseInitiator
 | 
			
		||||
	{
 | 
			
		||||
		public override bool TryMakePreToilReservations(bool errorOnFailed)
 | 
			
		||||
		{
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected override IEnumerable<Toil> MakeNewToils()
 | 
			
		||||
		{
 | 
			
		||||
			setup_ticks();
 | 
			
		||||
			var PartnerJob = VariousDefOf.GettinDrugSex;
 | 
			
		||||
 | 
			
		||||
			this.FailOnDespawnedNullOrForbidden(iTarget);
 | 
			
		||||
			this.FailOn(() => !Partner.health.capacities.CanBeAwake);
 | 
			
		||||
			this.FailOn(() => pawn.Drafted);
 | 
			
		||||
			this.FailOn(() => Partner == null);
 | 
			
		||||
			yield return Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell);
 | 
			
		||||
 | 
			
		||||
			Toil WaitForPartner = new Toil();
 | 
			
		||||
			WaitForPartner.defaultCompleteMode = ToilCompleteMode.Delay;
 | 
			
		||||
			WaitForPartner.initAction = delegate
 | 
			
		||||
			{
 | 
			
		||||
				ticksLeftThisToil = 5000;
 | 
			
		||||
			};
 | 
			
		||||
			WaitForPartner.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
 | 
			
		||||
			{
 | 
			
		||||
				var dri = Partner.jobs.curDriver as JobDriver_DrugSexReceiver;
 | 
			
		||||
				if (dri == null)
 | 
			
		||||
                {
 | 
			
		||||
					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;
 | 
			
		||||
			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);
 | 
			
		||||
			};
 | 
			
		||||
			SexToil.AddPreTickAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				SexTick(pawn, Partner);
 | 
			
		||||
				SexUtility.reduce_rest(Partner, 1);
 | 
			
		||||
				SexUtility.reduce_rest(pawn, 1);
 | 
			
		||||
				if (ticks_left <= 0)
 | 
			
		||||
					ReadyForNextToil();
 | 
			
		||||
			});
 | 
			
		||||
			SexToil.AddFinishAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				End();
 | 
			
		||||
			});
 | 
			
		||||
			yield return SexToil;
 | 
			
		||||
 | 
			
		||||
			yield return new Toil
 | 
			
		||||
			{
 | 
			
		||||
				initAction = delegate
 | 
			
		||||
				{
 | 
			
		||||
					//// Trying to add some interactions and social logs
 | 
			
		||||
					SexUtility.ProcessSex(Sexprops);
 | 
			
		||||
				},
 | 
			
		||||
				defaultCompleteMode = ToilCompleteMode.Instant
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// copied from rjw
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public class JobDriver_DrugSexReceiver : JobDriver_SexBaseRecieverLoved
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
		protected override IEnumerable<Toil> MakeNewToils()
 | 
			
		||||
		{
 | 
			
		||||
			setup_ticks();
 | 
			
		||||
			parteners.Add(Partner);// add job starter, so this wont fail, before Initiator starts his job
 | 
			
		||||
 | 
			
		||||
			// More/less hearts based on opinion.
 | 
			
		||||
			if (pawn.relations.OpinionOf(Partner) < 0)
 | 
			
		||||
				ticks_between_hearts += 50;
 | 
			
		||||
			else if (pawn.relations.OpinionOf(Partner) > 60)
 | 
			
		||||
				ticks_between_hearts -= 25;
 | 
			
		||||
 | 
			
		||||
			this.FailOnDespawnedOrNull(iTarget);
 | 
			
		||||
			this.FailOn(() => !Partner.health.capacities.CanBeAwake);
 | 
			
		||||
			this.FailOn(() => pawn.Drafted);
 | 
			
		||||
			this.FailOn(() => Partner.Drafted);
 | 
			
		||||
			this.FailOn(() => Partner == null);
 | 
			
		||||
 | 
			
		||||
			yield return Toils_Reserve.Reserve(iTarget, 1, 0);
 | 
			
		||||
 | 
			
		||||
				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
 | 
			
		||||
			{
 | 
			
		||||
			};
 | 
			
		||||
			get_loved.AddEndCondition(new Func<JobCondition>(() =>
 | 
			
		||||
			{
 | 
			
		||||
				if (parteners.Count <= 0)
 | 
			
		||||
				{
 | 
			
		||||
					return JobCondition.Succeeded;
 | 
			
		||||
				}
 | 
			
		||||
				return JobCondition.Ongoing;
 | 
			
		||||
			}));
 | 
			
		||||
			get_loved.AddFinishAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				if (xxx.is_human(pawn))
 | 
			
		||||
					pawn.Drawer.renderer.graphics.ResolveApparelGraphics();
 | 
			
		||||
			});
 | 
			
		||||
			get_loved.socialMode = RandomSocialMode.Off;
 | 
			
		||||
			return get_loved;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// copied from rjw
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public class JobDriver_DrugMasturabate : JobDriver_Masturbate
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
		protected override IEnumerable<Toil> MakeNewToils()
 | 
			
		||||
		{
 | 
			
		||||
			setup_ticks();
 | 
			
		||||
 | 
			
		||||
			this.FailOn(() => pawn.health.Downed);
 | 
			
		||||
			this.FailOn(() => pawn.IsBurning());
 | 
			
		||||
			this.FailOn(() => pawn.IsFighting());
 | 
			
		||||
			this.FailOn(() => pawn.Drafted);
 | 
			
		||||
 | 
			
		||||
			Toil SexToil = Toils_General.Wait(duration);
 | 
			
		||||
			SexToil.handlingFacing = true;
 | 
			
		||||
			SexToil.initAction = delegate
 | 
			
		||||
			{
 | 
			
		||||
				Start();
 | 
			
		||||
			};
 | 
			
		||||
			SexToil.tickAction = delegate
 | 
			
		||||
			{
 | 
			
		||||
				SexTick(pawn, null, true);
 | 
			
		||||
				SexUtility.reduce_rest(pawn, 1);
 | 
			
		||||
				if (ticks_left <= 0)
 | 
			
		||||
					ReadyForNextToil();
 | 
			
		||||
			};
 | 
			
		||||
			SexToil.AddFinishAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				End();
 | 
			
		||||
			});
 | 
			
		||||
			yield return SexToil;
 | 
			
		||||
 | 
			
		||||
			yield return new Toil
 | 
			
		||||
			{
 | 
			
		||||
				initAction = delegate
 | 
			
		||||
				{
 | 
			
		||||
					SexUtility.Aftersex(Sexprops);
 | 
			
		||||
					if (!SexUtility.ConsiderCleaning(pawn)) return;
 | 
			
		||||
 | 
			
		||||
					LocalTargetInfo own_cum = pawn.PositionHeld.GetFirstThing<Filth>(pawn.Map);
 | 
			
		||||
 | 
			
		||||
					Job clean = JobMaker.MakeJob(JobDefOf.Clean);
 | 
			
		||||
					clean.AddQueuedTarget(TargetIndex.A, own_cum);
 | 
			
		||||
 | 
			
		||||
					pawn.jobs.jobQueue.EnqueueFirst(clean);
 | 
			
		||||
				},
 | 
			
		||||
				defaultCompleteMode = ToilCompleteMode.Instant
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,159 @@
 | 
			
		|||
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;
 | 
			
		||||
 | 
			
		||||
            if (dutyDef == 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.Gangbang, target);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public class JobDriver_Gangbang : JobDriver_SexBaseInitiator
 | 
			
		||||
	{
 | 
			
		||||
		public override bool TryMakePreToilReservations(bool errorOnFailed)
 | 
			
		||||
		{
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected override IEnumerable<Toil> MakeNewToils()
 | 
			
		||||
		{
 | 
			
		||||
			setup_ticks();
 | 
			
		||||
 | 
			
		||||
			this.FailOnDespawnedNullOrForbidden(iTarget);
 | 
			
		||||
			this.FailOn(() => Partner == null);
 | 
			
		||||
			this.FailOn(() => pawn.Drafted);
 | 
			
		||||
			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
 | 
			
		||||
			{
 | 
			
		||||
 | 
			
		||||
				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);
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
			yield return StartPartnerJob;
 | 
			
		||||
 | 
			
		||||
			Toil SexToil = new Toil();
 | 
			
		||||
			SexToil.defaultCompleteMode = ToilCompleteMode.Never;
 | 
			
		||||
			SexToil.defaultDuration = duration;
 | 
			
		||||
			SexToil.handlingFacing = true;
 | 
			
		||||
			SexToil.FailOn(() => Partner.CurJob.def != VariousDefOf.GettinGangbang);
 | 
			
		||||
			SexToil.initAction = delegate
 | 
			
		||||
			{
 | 
			
		||||
				Start();
 | 
			
		||||
				Sexprops.usedCondom = CondomUtility.TryUseCondom(pawn) || CondomUtility.TryUseCondom(Partner);
 | 
			
		||||
			};
 | 
			
		||||
			SexToil.AddPreTickAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				SexTick(pawn, Partner);
 | 
			
		||||
				SexUtility.reduce_rest(Partner, 1);
 | 
			
		||||
				SexUtility.reduce_rest(pawn, 2);
 | 
			
		||||
				if (ticks_left <= 0)
 | 
			
		||||
					ReadyForNextToil();
 | 
			
		||||
			});
 | 
			
		||||
			SexToil.AddFinishAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				End();
 | 
			
		||||
			});
 | 
			
		||||
			yield return SexToil;
 | 
			
		||||
 | 
			
		||||
			yield return new Toil
 | 
			
		||||
			{
 | 
			
		||||
				initAction = delegate
 | 
			
		||||
				{
 | 
			
		||||
					// Trying to add some interactions and social logs
 | 
			
		||||
					SexUtility.ProcessSex(Sexprops);
 | 
			
		||||
				},
 | 
			
		||||
				defaultCompleteMode = ToilCompleteMode.Instant
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public class JobDriver_GangbangReceiver : JobDriver_SexBaseRecieverLoved
 | 
			
		||||
    {
 | 
			
		||||
		protected override IEnumerable<Toil> 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
 | 
			
		||||
			{
 | 
			
		||||
				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);
 | 
			
		||||
			};
 | 
			
		||||
			get_banged.AddEndCondition(new Func<JobCondition>(() =>
 | 
			
		||||
			{
 | 
			
		||||
				if (parteners.Count <= 0)
 | 
			
		||||
				{
 | 
			
		||||
					return JobCondition.Succeeded;
 | 
			
		||||
				}
 | 
			
		||||
				return JobCondition.Ongoing;
 | 
			
		||||
			}));
 | 
			
		||||
			get_banged.AddFinishAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				if (xxx.is_human(pawn))
 | 
			
		||||
					pawn.Drawer.renderer.graphics.ResolveApparelGraphics();
 | 
			
		||||
				GlobalTextureAtlasManager.TryMarkPawnFrameSetDirty(pawn);
 | 
			
		||||
 | 
			
		||||
				if (Bed != null && pawn.Downed)
 | 
			
		||||
				{
 | 
			
		||||
					Job tobed = JobMaker.MakeJob(JobDefOf.Rescue, pawn, Bed);
 | 
			
		||||
					tobed.count = 1;
 | 
			
		||||
					Partner.jobs.jobQueue.EnqueueFirst(tobed);
 | 
			
		||||
				}
 | 
			
		||||
				else if (pawn.HostileTo(Partner))
 | 
			
		||||
					pawn.health.AddHediff(xxx.submitting);
 | 
			
		||||
			});
 | 
			
		||||
			get_banged.socialMode = RandomSocialMode.Off;
 | 
			
		||||
			yield return get_banged;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										121
									
								
								Source/IdeologyAddon/Ideology/Rituals/JobGiver_GangbangVictim.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								Source/IdeologyAddon/Ideology/Rituals/JobGiver_GangbangVictim.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,121 @@
 | 
			
		|||
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_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;
 | 
			
		||||
 | 
			
		||||
			if (dutyDef == 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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// copied from rjw
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public class JobDriver_RapeVictim : JobDriver_Rape
 | 
			
		||||
	{
 | 
			
		||||
        public override bool TryMakePreToilReservations(bool errorOnFailed)
 | 
			
		||||
        {
 | 
			
		||||
			return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override IEnumerable<Toil> MakeNewToils()
 | 
			
		||||
		{
 | 
			
		||||
			if (RJWSettings.DebugRape) ModLog.Message("" + this.GetType().ToString() + "::MakeNewToils() called");
 | 
			
		||||
			setup_ticks();
 | 
			
		||||
			var PartnerJob = xxx.gettin_raped;
 | 
			
		||||
 | 
			
		||||
			this.FailOnDespawnedNullOrForbidden(iTarget);
 | 
			
		||||
			this.FailOn(() => Partner == null);
 | 
			
		||||
			this.FailOn(() => pawn.Drafted);
 | 
			
		||||
			this.FailOn(() => Partner.Drafted);
 | 
			
		||||
			yield return Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell);
 | 
			
		||||
 | 
			
		||||
			SexUtility.RapeTargetAlert(pawn, Partner);
 | 
			
		||||
 | 
			
		||||
			Toil StartPartnerJob = new Toil();
 | 
			
		||||
			StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant;
 | 
			
		||||
			StartPartnerJob.socialMode = RandomSocialMode.Off;
 | 
			
		||||
			StartPartnerJob.initAction = delegate
 | 
			
		||||
			{
 | 
			
		||||
				var dri = Partner.jobs.curDriver as JobDriver_SexBaseRecieverRaped;
 | 
			
		||||
				if (dri == null)
 | 
			
		||||
				{
 | 
			
		||||
					Job gettin_raped = JobMaker.MakeJob(PartnerJob, pawn);
 | 
			
		||||
 | 
			
		||||
					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;
 | 
			
		||||
			SexToil.FailOn(() => Partner.CurJob.def != PartnerJob);
 | 
			
		||||
			SexToil.initAction = delegate
 | 
			
		||||
			{
 | 
			
		||||
				Partner.pather.StopDead();
 | 
			
		||||
				Partner.jobs.curDriver.asleep = false;
 | 
			
		||||
 | 
			
		||||
				if (RJWSettings.DebugRape) ModLog.Message("JobDriver_RapeComfortPawn::MakeNewToils() - reserving prisoner");
 | 
			
		||||
				Start();
 | 
			
		||||
			};
 | 
			
		||||
			SexToil.tickAction = delegate
 | 
			
		||||
			{
 | 
			
		||||
				SexTick(pawn, Partner);
 | 
			
		||||
				SexUtility.reduce_rest(Partner, 1);
 | 
			
		||||
				SexUtility.reduce_rest(pawn, 2);
 | 
			
		||||
				if (ticks_left <= 0)
 | 
			
		||||
					ReadyForNextToil();
 | 
			
		||||
			};
 | 
			
		||||
			SexToil.AddFinishAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				End();
 | 
			
		||||
			});
 | 
			
		||||
			yield return SexToil;
 | 
			
		||||
 | 
			
		||||
			yield return new Toil
 | 
			
		||||
			{
 | 
			
		||||
				initAction = delegate
 | 
			
		||||
				{
 | 
			
		||||
					// Trying to add some interactions and social logs
 | 
			
		||||
					SexUtility.ProcessSex(Sexprops);
 | 
			
		||||
					Partner.records.Increment(xxx.GetRapedAsComfortPawn);
 | 
			
		||||
				},
 | 
			
		||||
				defaultCompleteMode = ToilCompleteMode.Instant
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								Source/IdeologyAddon/Ideology/Rituals/LordJob_Rituals.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Source/IdeologyAddon/Ideology/Rituals/LordJob_Rituals.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
using System;
 | 
			
		||||
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 LordJob_Ritual_Gangbang() { }
 | 
			
		||||
 | 
			
		||||
		public LordJob_Ritual_Gangbang(string targetID ,TargetInfo selectedTarget, Precept_Ritual ritual, RitualObligation obligation, List<RitualStage> 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))
 | 
			
		||||
				{
 | 
			
		||||
					Pawn item = assignments.FirstAssignedPawn(ritualRole);
 | 
			
		||||
					pawnsDeathIgnored.Add(item);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,69 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI.Group;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology
 | 
			
		||||
{
 | 
			
		||||
    public class RitualBehaviorWorker_Gangbang : RitualBehaviorWorker
 | 
			
		||||
    {
 | 
			
		||||
		public RitualBehaviorWorker_Gangbang() { }
 | 
			
		||||
 | 
			
		||||
		public RitualBehaviorWorker_Gangbang(RitualBehaviorDef def) : base(def) { }
 | 
			
		||||
		
 | 
			
		||||
		public override void PostCleanup(LordJob_Ritual ritual)
 | 
			
		||||
		{
 | 
			
		||||
			Pawn warden = ritual.PawnWithRole("initiator");
 | 
			
		||||
			Pawn pawn = ritual.PawnWithRole("victim");
 | 
			
		||||
			if (pawn.IsPrisonerOfColony)
 | 
			
		||||
			{
 | 
			
		||||
				WorkGiver_Warden_TakeToBed.TryTakePrisonerToBed(pawn, warden);
 | 
			
		||||
				pawn.guest.WaitInsteadOfEscapingFor(1250);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        protected override LordJob CreateLordJob(TargetInfo target, Pawn organizer, Precept_Ritual ritual, RitualObligation obligation, RitualRoleAssignments assignments)
 | 
			
		||||
        {
 | 
			
		||||
            return new LordJob_Ritual_Gangbang("victim", target, ritual, obligation, def.stages, assignments, organizer);
 | 
			
		||||
		}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	public class RitualBehaviorWorker_Gangbang_Consensual : RitualBehaviorWorker
 | 
			
		||||
	{
 | 
			
		||||
		public RitualBehaviorWorker_Gangbang_Consensual() { }
 | 
			
		||||
 | 
			
		||||
		public RitualBehaviorWorker_Gangbang_Consensual(RitualBehaviorDef def) : base(def) { }
 | 
			
		||||
 | 
			
		||||
		protected override LordJob CreateLordJob(TargetInfo target, Pawn organizer, Precept_Ritual ritual, RitualObligation obligation, RitualRoleAssignments assignments)
 | 
			
		||||
		{
 | 
			
		||||
			return new LordJob_Ritual_Gangbang("initiator", target, ritual, obligation, def.stages, assignments, organizer);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public class RitualStage_InteractWithVictim : RitualStage
 | 
			
		||||
    {
 | 
			
		||||
		public override TargetInfo GetSecondFocus(LordJob_Ritual ritual)
 | 
			
		||||
		{
 | 
			
		||||
			return ritual.assignments.AssignedPawns("victim").FirstOrDefault(p => RitualRole_RapeVictim.CanBeVictim(p));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public class RitualStage_InteractWithVictim_All : RitualStage
 | 
			
		||||
	{
 | 
			
		||||
		public override TargetInfo GetSecondFocus(LordJob_Ritual ritual)
 | 
			
		||||
		{
 | 
			
		||||
			return ritual.assignments.AssignedPawns("victim").FirstOrDefault();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	public class RitualStage_InteractWithInitiator : RitualStage
 | 
			
		||||
	{
 | 
			
		||||
		public override TargetInfo GetSecondFocus(LordJob_Ritual ritual)
 | 
			
		||||
		{
 | 
			
		||||
			return ritual.assignments.AssignedPawns("initiator").FirstOrDefault();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								Source/IdeologyAddon/Ideology/Rituals/RitualOutcomeComps.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								Source/IdeologyAddon/Ideology/Rituals/RitualOutcomeComps.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology
 | 
			
		||||
{
 | 
			
		||||
	public class RitualOutcomeComp_HediffBased : RitualOutcomeComp_QualitySingleOffset
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public HediffDef hediffDef = null;
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public float minSeverity = 0;
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public string roleId = "";
 | 
			
		||||
 | 
			
		||||
		protected override string LabelForDesc => label;
 | 
			
		||||
		public override bool DataRequired => false;
 | 
			
		||||
		public override bool Applies(LordJob_Ritual ritual)
 | 
			
		||||
		{
 | 
			
		||||
			Pawn victim = null;
 | 
			
		||||
			foreach (RitualRole ritualRole in ritual.assignments.AllRolesForReading)
 | 
			
		||||
			{
 | 
			
		||||
				if (ritualRole?.id.Contains(roleId) == true)
 | 
			
		||||
				{
 | 
			
		||||
					victim = ritual.assignments.FirstAssignedPawn(ritualRole);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (victim != null && hediffDef != null)
 | 
			
		||||
			{
 | 
			
		||||
				Hediff hediff = victim.health.hediffSet.GetFirstHediffOfDef(hediffDef);
 | 
			
		||||
				if (hediff?.Severity >= minSeverity)
 | 
			
		||||
				{
 | 
			
		||||
					return true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override ExpectedOutcomeDesc GetExpectedOutcomeDesc(Precept_Ritual ritual, TargetInfo ritualTarget, RitualObligation obligation, RitualRoleAssignments assignments, RitualOutcomeComp_Data data)
 | 
			
		||||
		{
 | 
			
		||||
			return new ExpectedOutcomeDesc
 | 
			
		||||
			{
 | 
			
		||||
				label = LabelForDesc.CapitalizeFirst(),
 | 
			
		||||
				present = false,
 | 
			
		||||
				uncertainOutcome = true,
 | 
			
		||||
				effect = ExpectedOffsetDesc(true, -1f),
 | 
			
		||||
				quality = qualityOffset,
 | 
			
		||||
				positive = true
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public class RitualOutcomeComp_NeedBased : RitualOutcomeComp_QualitySingleOffset
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public NeedDef needDef = null;
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public float minAvgNeed = 0;
 | 
			
		||||
 | 
			
		||||
		protected override string LabelForDesc => label;
 | 
			
		||||
		public override bool DataRequired => false;
 | 
			
		||||
		public override bool Applies(LordJob_Ritual ritual)
 | 
			
		||||
		{
 | 
			
		||||
			float avgNeed = 0;
 | 
			
		||||
			foreach (Pawn pawn in ritual.assignments.AllPawns)
 | 
			
		||||
			{
 | 
			
		||||
				avgNeed += pawn.needs?.TryGetNeed(needDef)?.CurLevel ?? 0f;
 | 
			
		||||
			}
 | 
			
		||||
			avgNeed /= ritual.assignments.AllPawns.Count;
 | 
			
		||||
			return avgNeed >= minAvgNeed;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override ExpectedOutcomeDesc GetExpectedOutcomeDesc(Precept_Ritual ritual, TargetInfo ritualTarget, RitualObligation obligation, RitualRoleAssignments assignments, RitualOutcomeComp_Data data)
 | 
			
		||||
		{
 | 
			
		||||
			return new ExpectedOutcomeDesc
 | 
			
		||||
			{
 | 
			
		||||
				label = LabelForDesc.CapitalizeFirst(),
 | 
			
		||||
				present = false,
 | 
			
		||||
				uncertainOutcome = true,
 | 
			
		||||
				effect = ExpectedOffsetDesc(true, -1f),
 | 
			
		||||
				quality = qualityOffset,
 | 
			
		||||
				positive = true
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										111
									
								
								Source/IdeologyAddon/Ideology/Rituals/RitualRoles.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								Source/IdeologyAddon/Ideology/Rituals/RitualRoles.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,111 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
using rjw;
 | 
			
		||||
 | 
			
		||||
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, 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 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 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 override bool AppliesToPawn(Pawn p, out string reason, 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 static bool CanBeBreedee(Pawn pawn)
 | 
			
		||||
        {
 | 
			
		||||
            if (xxx.can_be_fucked(pawn)) return true;
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class RitualRole_AnimalBreeder : RitualRole
 | 
			
		||||
    {
 | 
			
		||||
        public override bool Animal => true;
 | 
			
		||||
 | 
			
		||||
        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, 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(VariousDefOf.Bestiality_OnlyVenerated) && !precept.ideo.IsVeneratedAnimal(animal))
 | 
			
		||||
			{
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
			if (!xxx.can_rape(animal)) return false;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								Source/IdeologyAddon/Ideology/RsiHistoryEventDefOf.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								Source/IdeologyAddon/Ideology/RsiHistoryEventDefOf.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								Source/IdeologyAddon/Ideology/SinglePawnFilter.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Source/IdeologyAddon/Ideology/SinglePawnFilter.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
using rjw;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology
 | 
			
		||||
{
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
		public bool Applies(Pawn pawn)
 | 
			
		||||
		{
 | 
			
		||||
			if (isAnimal != null && isAnimal != pawn.IsAnimal())
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
			if (isSlave != null && isSlave != pawn.IsSlave)
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
			if (isPrisoner != null && isPrisoner != pawn.IsPrisoner)
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								Source/IdeologyAddon/Ideology/StatParts.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								Source/IdeologyAddon/Ideology/StatParts.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology
 | 
			
		||||
{
 | 
			
		||||
	public class StatPart_GenderPrimacy : StatPart
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public float modifier;
 | 
			
		||||
 | 
			
		||||
		public override string ExplanationPart(StatRequest req)
 | 
			
		||||
		{
 | 
			
		||||
			if (!req.HasThing || !(req.Thing is Pawn pawn))
 | 
			
		||||
				return null;
 | 
			
		||||
 | 
			
		||||
			return $"{Keyed.MemeStatFactor}: x{GetModifier(pawn).ToStringPercent()}";
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void TransformValue(StatRequest req, ref float val)
 | 
			
		||||
		{
 | 
			
		||||
			if (!req.HasThing || !(req.Thing is Pawn pawn))
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			val *= GetModifier(pawn);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private float GetModifier(Pawn pawn)
 | 
			
		||||
		{
 | 
			
		||||
			if (pawn.Ideo == null)
 | 
			
		||||
				return 1f;
 | 
			
		||||
 | 
			
		||||
			Gender supremeGender = pawn.Ideo.SupremeGender;
 | 
			
		||||
 | 
			
		||||
			if (pawn.gender == supremeGender)
 | 
			
		||||
				return modifier;
 | 
			
		||||
			else if (pawn.gender == supremeGender.Opposite())
 | 
			
		||||
				return 1f / modifier;
 | 
			
		||||
 | 
			
		||||
			return 1f;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								Source/IdeologyAddon/Ideology/Thought_IncreaseRecord.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								Source/IdeologyAddon/Ideology/Thought_IncreaseRecord.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology
 | 
			
		||||
{
 | 
			
		||||
	public class Thought_IncreaseRecord : Thought_Recordbased
 | 
			
		||||
	{
 | 
			
		||||
		protected float recordIncrement;
 | 
			
		||||
 | 
			
		||||
		public override void ExposeData()
 | 
			
		||||
		{
 | 
			
		||||
			base.ExposeData();
 | 
			
		||||
			Scribe_Values.Look(ref recordIncrement, "recordIncrement", recordIncrement, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void ThoughtInterval()
 | 
			
		||||
		{
 | 
			
		||||
			base.ThoughtInterval();
 | 
			
		||||
			if (recordIncrement != 0)
 | 
			
		||||
			{
 | 
			
		||||
				pawn.records.AddTo(RecordDef, recordIncrement);
 | 
			
		||||
				recordIncrement = 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool TryMergeWithExistingMemory(out bool showBubble)
 | 
			
		||||
		{
 | 
			
		||||
			ThoughtHandler thoughts = pawn.needs.mood.thoughts;
 | 
			
		||||
			if (thoughts.memories.NumMemoriesInGroup(this) >= def.stackLimit)
 | 
			
		||||
			{
 | 
			
		||||
				Thought_IncreaseRecord thought_Memory = (Thought_IncreaseRecord)thoughts.memories.OldestMemoryInGroup(this);
 | 
			
		||||
				if (thought_Memory != null)
 | 
			
		||||
				{
 | 
			
		||||
					showBubble = (thought_Memory.age > thought_Memory.def.DurationTicks / 2);
 | 
			
		||||
					thought_Memory.Merged();
 | 
			
		||||
					return true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			showBubble = true;
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void Init()
 | 
			
		||||
		{
 | 
			
		||||
			base.Init();
 | 
			
		||||
			recordIncrement = Def.increment;
 | 
			
		||||
		}
 | 
			
		||||
		protected virtual void Merged()
 | 
			
		||||
		{
 | 
			
		||||
			age = 0;
 | 
			
		||||
			recordIncrement += Def.increment;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								Source/IdeologyAddon/Ideology/Thought_Opinionbased.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								Source/IdeologyAddon/Ideology/Thought_Opinionbased.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience.Ideology
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// ThoughtDef using opinion
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public class ThoughtDef_Opinionbased : ThoughtDef
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public List<float> minimumValueforStage = new List<float>();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Thought class using record.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public class Thought_Opinionbased : Thought_Memory
 | 
			
		||||
	{
 | 
			
		||||
		protected ThoughtDef_Opinionbased Def => (ThoughtDef_Opinionbased)def;
 | 
			
		||||
		protected List<float> MinimumValueforStage => Def.minimumValueforStage;
 | 
			
		||||
 | 
			
		||||
		public override int CurStageIndex
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				float value = 0f;
 | 
			
		||||
				if (otherPawn != null) value = pawn.relations?.OpinionOf(otherPawn) ?? 0f;
 | 
			
		||||
				for (int i = MinimumValueforStage.Count - 1; i > 0; i--)
 | 
			
		||||
				{
 | 
			
		||||
					if (MinimumValueforStage[i] < value) return i;
 | 
			
		||||
				}
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								Source/IdeologyAddon/Ideology/TwoPawnFilter.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Source/IdeologyAddon/Ideology/TwoPawnFilter.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
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;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								Source/IdeologyAddon/Ideology/VariousDefOf.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								Source/IdeologyAddon/Ideology/VariousDefOf.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										99
									
								
								Source/IdeologyAddon/IdeologyAddon.csproj
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								Source/IdeologyAddon/IdeologyAddon.csproj
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,99 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
 | 
			
		||||
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
 | 
			
		||||
    <ProjectGuid>{B4481C38-31B1-422D-B5AA-0059FE7CCA1C}</ProjectGuid>
 | 
			
		||||
    <OutputType>Library</OutputType>
 | 
			
		||||
    <AppDesignerFolder>Properties</AppDesignerFolder>
 | 
			
		||||
    <RootNamespace>RJWSexperience.Ideology</RootNamespace>
 | 
			
		||||
    <AssemblyName>RJWSexperience.Ideology</AssemblyName>
 | 
			
		||||
    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
 | 
			
		||||
    <FileAlignment>512</FileAlignment>
 | 
			
		||||
    <Deterministic>true</Deterministic>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
 | 
			
		||||
    <DebugSymbols>true</DebugSymbols>
 | 
			
		||||
    <DebugType>full</DebugType>
 | 
			
		||||
    <Optimize>false</Optimize>
 | 
			
		||||
    <OutputPath>..\..\RJWSexperience_Ideology\Assemblies\</OutputPath>
 | 
			
		||||
    <DefineConstants>DEBUG;TRACE</DefineConstants>
 | 
			
		||||
    <ErrorReport>prompt</ErrorReport>
 | 
			
		||||
    <WarningLevel>4</WarningLevel>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
 | 
			
		||||
    <DebugType>pdbonly</DebugType>
 | 
			
		||||
    <Optimize>true</Optimize>
 | 
			
		||||
    <OutputPath>..\..\1.3\Assemblies\</OutputPath>
 | 
			
		||||
    <DefineConstants>TRACE</DefineConstants>
 | 
			
		||||
    <ErrorReport>prompt</ErrorReport>
 | 
			
		||||
    <WarningLevel>4</WarningLevel>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Reference Include="RJW">
 | 
			
		||||
      <HintPath>..\..\..\rjw\1.3\Assemblies\RJW.dll</HintPath>
 | 
			
		||||
      <Private>False</Private>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="System.Core" />
 | 
			
		||||
    <Reference Include="System.Data.DataSetExtensions" />
 | 
			
		||||
    <Reference Include="Microsoft.CSharp" />
 | 
			
		||||
    <Reference Include="System.Data" />
 | 
			
		||||
    <Reference Include="System.Net.Http" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Compile Include="GlobalSuppressions.cs" />
 | 
			
		||||
    <Compile Include="Ideology\HistoryEvents\DefExtension_SecondaryEvents.cs" />
 | 
			
		||||
    <Compile Include="Ideology\HistoryEvents\DefExtension_EventOverrides.cs" />
 | 
			
		||||
    <Compile Include="Ideology\HistoryEvents\TwoPawnEventRule.cs" />
 | 
			
		||||
    <Compile Include="Ideology\InteractionDefExtension_HistoryEvents.cs" />
 | 
			
		||||
    <Compile Include="Ideology\GoodwillSituationWorker_MemeCompatibility.cs" />
 | 
			
		||||
    <Compile Include="Harmony.cs" />
 | 
			
		||||
    <Compile Include="Ideology\HistoryEvents\ArgsNamesCustom.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Keyed.cs" />
 | 
			
		||||
    <Compile Include="Ideology\RelationFilter.cs" />
 | 
			
		||||
    <Compile Include="Ideology\RsiHistoryEventDefOf.cs" />
 | 
			
		||||
    <Compile Include="Ideology\TwoPawnFilter.cs" />
 | 
			
		||||
    <Compile Include="Ideology\SinglePawnFilter.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Precepts\Comp_SelfTookMemoryThought_Gendered.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Precepts\Comp_KnowsMemoryThought_Gendered.cs" />
 | 
			
		||||
    <Compile Include="Ideology\HistoryEvents\HistoryEventDefExtensionMethods.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Patches\RJW_Patch_ChancePerHour.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Precepts\DefExtension_ModifyMtb.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Precepts\DefExtension_ModifyFappinMtb.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Precepts\DefExtension_ModifyRapeCPMtb.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Precepts\DefExtension_ModifyNecroMtb.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Precepts\DefExtension_ModifyBestialityMtb.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Precepts\DefExtension_ModifyPreference.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Precepts\DefExtension_MultipleMemesRequired.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Rituals\JobGiver_GangbangConsensual.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Rituals\LordJob_Rituals.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Patches\RJW_Patch_Ideo.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Patches\Sexperience_Patch.cs" />
 | 
			
		||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Patches\Rimworld_Patch.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Rituals\JobGiver_DrugOrgy.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Rituals\JobGiver_GangbangVictim.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Rituals\RitualBehaviorWorkers.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Rituals\RitualOutcomeComps.cs" />
 | 
			
		||||
    <Compile Include="Ideology\Rituals\RitualRoles.cs" />
 | 
			
		||||
    <Compile Include="Ideology\StatParts.cs" />
 | 
			
		||||
    <Compile Include="Ideology\IdeoUtility.cs" />
 | 
			
		||||
    <Compile Include="Thoughts\ThoughtDefExtension_IncreaseRecord.cs" />
 | 
			
		||||
    <Compile Include="Thoughts\ThoughtDefExtension_StageFromOpinion.cs" />
 | 
			
		||||
    <Compile Include="Thoughts\Thought_IncreaseRecord.cs" />
 | 
			
		||||
    <Compile Include="Thoughts\Thought_Opinionbased.cs" />
 | 
			
		||||
    <Compile Include="Ideology\VariousDefOf.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Krafs.Rimworld.Ref">
 | 
			
		||||
      <Version>1.3.3389</Version>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="Lib.Harmony">
 | 
			
		||||
      <Version>2.2.1</Version>
 | 
			
		||||
      <ExcludeAssets>runtime</ExcludeAssets>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup />
 | 
			
		||||
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										36
									
								
								Source/IdeologyAddon/Properties/AssemblyInfo.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Source/IdeologyAddon/Properties/AssemblyInfo.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
using System.Reflection;
 | 
			
		||||
using System.Runtime.CompilerServices;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해 
 | 
			
		||||
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
 | 
			
		||||
// 이러한 특성 값을 변경하세요.
 | 
			
		||||
[assembly: AssemblyTitle("IdeologyAddon")]
 | 
			
		||||
[assembly: AssemblyDescription("")]
 | 
			
		||||
[assembly: AssemblyConfiguration("")]
 | 
			
		||||
[assembly: AssemblyCompany("")]
 | 
			
		||||
[assembly: AssemblyProduct("IdeologyAddon")]
 | 
			
		||||
[assembly: AssemblyCopyright("Copyright ©  2021")]
 | 
			
		||||
[assembly: AssemblyTrademark("")]
 | 
			
		||||
[assembly: AssemblyCulture("")]
 | 
			
		||||
 | 
			
		||||
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에 
 | 
			
		||||
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
 | 
			
		||||
// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
 | 
			
		||||
[assembly: ComVisible(false)]
 | 
			
		||||
 | 
			
		||||
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
 | 
			
		||||
[assembly: Guid("b4481c38-31b1-422d-b5aa-0059fe7cca1c")]
 | 
			
		||||
 | 
			
		||||
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
 | 
			
		||||
//
 | 
			
		||||
//      주 버전
 | 
			
		||||
//      부 버전 
 | 
			
		||||
//      빌드 번호
 | 
			
		||||
//      수정 버전
 | 
			
		||||
//
 | 
			
		||||
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
 | 
			
		||||
// 기본값으로 할 수 있습니다.
 | 
			
		||||
// [assembly: AssemblyVersion("1.0.*")]
 | 
			
		||||
[assembly: AssemblyVersion("1.0.0.0")]
 | 
			
		||||
[assembly: AssemblyFileVersion("1.0.0.0")]
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience
 | 
			
		||||
{
 | 
			
		||||
	public class ThoughtDefExtension_IncreaseRecord : DefModExtension
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public RecordDef recordDef;
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public float increment;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics.CodeAnalysis;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience
 | 
			
		||||
{
 | 
			
		||||
	public class ThoughtDefExtension_StageFromOpinion : DefModExtension
 | 
			
		||||
	{
 | 
			
		||||
		[SuppressMessage("Minor Code Smell", "S1104:Fields should not have public accessibility", Justification = "Field value loaded from XML")]
 | 
			
		||||
		public List<float> minimumValueforStage = new List<float>();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								Source/IdeologyAddon/Thoughts/Thought_IncreaseRecord.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								Source/IdeologyAddon/Thoughts/Thought_IncreaseRecord.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience
 | 
			
		||||
{
 | 
			
		||||
	public class Thought_IncreaseRecord : Thought_Memory
 | 
			
		||||
	{
 | 
			
		||||
		private ThoughtDefExtension_IncreaseRecord extension;
 | 
			
		||||
 | 
			
		||||
		protected ThoughtDefExtension_IncreaseRecord Extension
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				if (extension == null)
 | 
			
		||||
					extension = def.GetModExtension<ThoughtDefExtension_IncreaseRecord>();
 | 
			
		||||
				return extension;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected RecordDef RecordDef => Extension.recordDef;
 | 
			
		||||
		protected float Increment => Extension.increment;
 | 
			
		||||
 | 
			
		||||
		protected float recordIncrement;
 | 
			
		||||
 | 
			
		||||
		public override void ExposeData()
 | 
			
		||||
		{
 | 
			
		||||
			base.ExposeData();
 | 
			
		||||
			Scribe_Values.Look(ref recordIncrement, "recordIncrement", recordIncrement, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void ThoughtInterval()
 | 
			
		||||
		{
 | 
			
		||||
			base.ThoughtInterval();
 | 
			
		||||
			if (recordIncrement != 0)
 | 
			
		||||
			{
 | 
			
		||||
				pawn.records.AddTo(RecordDef, recordIncrement);
 | 
			
		||||
				recordIncrement = 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool TryMergeWithExistingMemory(out bool showBubble)
 | 
			
		||||
		{
 | 
			
		||||
			ThoughtHandler thoughts = pawn.needs.mood.thoughts;
 | 
			
		||||
			if (thoughts.memories.NumMemoriesInGroup(this) >= def.stackLimit)
 | 
			
		||||
			{
 | 
			
		||||
				Thought_IncreaseRecord thought_Memory = (Thought_IncreaseRecord)thoughts.memories.OldestMemoryInGroup(this);
 | 
			
		||||
				if (thought_Memory != null)
 | 
			
		||||
				{
 | 
			
		||||
					showBubble = (thought_Memory.age > thought_Memory.def.DurationTicks / 2);
 | 
			
		||||
					thought_Memory.Merged();
 | 
			
		||||
					return true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			showBubble = true;
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void Init()
 | 
			
		||||
		{
 | 
			
		||||
			base.Init();
 | 
			
		||||
			recordIncrement = Increment;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected virtual void Merged()
 | 
			
		||||
		{
 | 
			
		||||
			age = 0;
 | 
			
		||||
			recordIncrement += Increment;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								Source/IdeologyAddon/Thoughts/Thought_Opinionbased.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Source/IdeologyAddon/Thoughts/Thought_Opinionbased.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
using RimWorld;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace RJWSexperience
 | 
			
		||||
{
 | 
			
		||||
	public class Thought_Opinionbased : Thought_Memory
 | 
			
		||||
	{
 | 
			
		||||
		private ThoughtDefExtension_StageFromOpinion extension;
 | 
			
		||||
 | 
			
		||||
		protected ThoughtDefExtension_StageFromOpinion Extension
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				if (extension == null)
 | 
			
		||||
					extension = def.GetModExtension<ThoughtDefExtension_StageFromOpinion>();
 | 
			
		||||
				return extension;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected List<float> MinimumValueforStage => Extension.minimumValueforStage;
 | 
			
		||||
 | 
			
		||||
		public override int CurStageIndex
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				float value = 0f;
 | 
			
		||||
				if (otherPawn != null) value = pawn.relations?.OpinionOf(otherPawn) ?? 0f;
 | 
			
		||||
				for (int i = MinimumValueforStage.Count - 1; i > 0; i--)
 | 
			
		||||
				{
 | 
			
		||||
					if (MinimumValueforStage[i] < value) return i;
 | 
			
		||||
				}
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								Source/RJWSexperienceIdeology.sln
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								Source/RJWSexperienceIdeology.sln
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
 | 
			
		||||
Microsoft Visual Studio Solution File, Format Version 12.00
 | 
			
		||||
# Visual Studio Version 16
 | 
			
		||||
VisualStudioVersion = 16.0.31424.327
 | 
			
		||||
MinimumVisualStudioVersion = 10.0.40219.1
 | 
			
		||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IdeologyAddon", "IdeologyAddon\IdeologyAddon.csproj", "{B4481C38-31B1-422D-B5AA-0059FE7CCA1C}"
 | 
			
		||||
EndProject
 | 
			
		||||
Global
 | 
			
		||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
			
		||||
		Debug|Any CPU = Debug|Any CPU
 | 
			
		||||
		Release|Any CPU = Release|Any CPU
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 | 
			
		||||
		{B4481C38-31B1-422D-B5AA-0059FE7CCA1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{B4481C38-31B1-422D-B5AA-0059FE7CCA1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
			
		||||
		{B4481C38-31B1-422D-B5AA-0059FE7CCA1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{B4481C38-31B1-422D-B5AA-0059FE7CCA1C}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(SolutionProperties) = preSolution
 | 
			
		||||
		HideSolutionNode = FALSE
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ExtensibilityGlobals) = postSolution
 | 
			
		||||
		SolutionGuid = {03C87A93-F76D-49B3-AE25-67E14F20EACD}
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
EndGlobal
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue