mirror of
				https://github.com/vegapnk/RJW-Genes.git
				synced 2024-08-15 00:23:31 +00:00 
			
		
		
		
	Resolved Merge Conflicts
This commit is contained in:
		
						commit
						0e20e00150
					
				
					 88 changed files with 3886 additions and 31 deletions
				
			
		| 
						 | 
				
			
			@ -35,7 +35,7 @@ namespace RJW_BGS
 | 
			
		|||
                {
 | 
			
		||||
                    __result.AddGene(gene);
 | 
			
		||||
                }
 | 
			
		||||
            }        
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										32
									
								
								Source/First.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								Source/First.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using rjw;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw.Modules.Interactions.Rules.PartKindUsageRules;
 | 
			
		||||
using rjw.Modules.Interactions.Internals.Implementation;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    [StaticConstructorOnStartup]
 | 
			
		||||
    internal static class First
 | 
			
		||||
    {
 | 
			
		||||
        static First()
 | 
			
		||||
        {
 | 
			
		||||
            AddtoIPartPreferenceRule();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Modified code from https://gitgud.io/lutepickle/rjw_menstruation/-/tree/main/1.4/source/RJW_Menstruation/RJW_Menstruation
 | 
			
		||||
        //Summary//
 | 
			
		||||
        //Adds our own partpreferences to rjw's list. Our partpreferences are under Interactions.GenesPartKindUsageRule
 | 
			
		||||
        //
 | 
			
		||||
        private static void AddtoIPartPreferenceRule()
 | 
			
		||||
        {
 | 
			
		||||
            List<IPartPreferenceRule> partPreferenceRules = Unprivater.GetProtectedValue<List<IPartPreferenceRule>>("_partKindUsageRules", typeof(PartPreferenceDetectorService));
 | 
			
		||||
            partPreferenceRules.Add(new Interactions.GenesPartKindUsageRule());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -76,8 +76,21 @@ namespace RJW_Genes
 | 
			
		|||
		public static readonly GeneDef rjw_genes_youth_fountain;
 | 
			
		||||
		public static readonly GeneDef rjw_genes_sex_age_drain;
 | 
			
		||||
		public static readonly GeneDef rjw_genes_aphrodisiac_pheromones;
 | 
			
		||||
		public static readonly GeneDef rjw_genes_aphrodisiac_pheromones;
 | 
			
		||||
		public static readonly GeneDef rjw_genes_youth_fountain;
 | 
			
		||||
		public static readonly GeneDef rjw_genes_sex_age_drain;
 | 
			
		||||
 | 
			
		||||
    // Others & Non-Genes
 | 
			
		||||
		// LifeForce
 | 
			
		||||
		public static readonly GeneDef rjw_genes_lifeforce;
 | 
			
		||||
		public static readonly GeneDef rjw_genes_pussyhealer;
 | 
			
		||||
		public static readonly GeneDef rjw_genes_vaginal_absorber;
 | 
			
		||||
		public static readonly GeneDef rjw_genes_anal_absorber;
 | 
			
		||||
		public static readonly GeneDef rjw_genes_drainer;
 | 
			
		||||
 | 
			
		||||
		// Cosmetic
 | 
			
		||||
		public static readonly GeneDef rjw_genes_succubus_tail;
 | 
			
		||||
 | 
			
		||||
    	// Others & Non-Genes
 | 
			
		||||
		public static readonly HediffDef rjw_genes_orgasm_rush_hediff;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,5 +33,35 @@ namespace RJW_Genes
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//Get total fluidamount a person has.
 | 
			
		||||
		public static float GetTotalFluidAmount(Pawn pawn, float multiplier = 1f)
 | 
			
		||||
		{
 | 
			
		||||
			var partBPR = Genital_Helper.get_genitalsBPR(pawn);
 | 
			
		||||
			var parts = Genital_Helper.get_PartsHediffList(pawn, partBPR);
 | 
			
		||||
			float total_cum = 0;
 | 
			
		||||
			if (!parts.NullOrEmpty())
 | 
			
		||||
			{
 | 
			
		||||
				CompHediffBodyPart CompHediff;
 | 
			
		||||
 | 
			
		||||
				foreach (Hediff part in parts)
 | 
			
		||||
				{
 | 
			
		||||
					if (GenitaliaChanger.IsArtificial(part))
 | 
			
		||||
						continue;
 | 
			
		||||
 | 
			
		||||
					if (rjw.Genital_Helper.is_penis(part))
 | 
			
		||||
					{
 | 
			
		||||
						CompHediff = part.TryGetComp<rjw.CompHediffBodyPart>();
 | 
			
		||||
						if (CompHediff != null)
 | 
			
		||||
						{
 | 
			
		||||
							total_cum += CompHediff.FluidAmmount * CompHediff.FluidModifier * multiplier;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
			return total_cum;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,46 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
using RimWorld;
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    public class GeneUtility
 | 
			
		||||
    {
 | 
			
		||||
        //Instead of seperate functions this should be simpeler
 | 
			
		||||
        public static bool HasGeneNullCheck(Pawn pawn, GeneDef genedef)
 | 
			
		||||
        {
 | 
			
		||||
            if (pawn.genes == null)
 | 
			
		||||
            {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            return pawn.genes.HasGene(genedef);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Split function so I can offsetlifeforce from gene without needing to look for the gene agian (for the constant drain tick)
 | 
			
		||||
        public static Gene_LifeForce GetLifeForceGene(Pawn pawn)
 | 
			
		||||
        {
 | 
			
		||||
            Pawn_GeneTracker genes = pawn.genes;
 | 
			
		||||
            Gene_LifeForce gene_LifeForce = genes.GetFirstGeneOfType<Gene_LifeForce>();
 | 
			
		||||
            return gene_LifeForce;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void OffsetLifeForce(IGeneResourceDrain drain, float offset)
 | 
			
		||||
        {                
 | 
			
		||||
            float old_value = drain.Resource.Value;
 | 
			
		||||
            drain.Resource.Value += offset;
 | 
			
		||||
            //PostOffSetLifeForce(drain, old_value);     
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void PostOffSetLifeForce(IGeneResourceDrain drain, float old_value)
 | 
			
		||||
        {
 | 
			
		||||
            if (old_value > 0.2f && drain.Resource.Value <= 0.2f)
 | 
			
		||||
            {
 | 
			
		||||
                Pawn pawn = drain.Pawn;
 | 
			
		||||
                
 | 
			
		||||
                //Do things
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool IsMechbreeder(Pawn pawn)
 | 
			
		||||
        {
 | 
			
		||||
            if (pawn.genes == null)
 | 
			
		||||
| 
						 | 
				
			
			@ -15,6 +50,41 @@ namespace RJW_Genes
 | 
			
		|||
            return pawn.genes.HasGene(GeneDefOf.rjw_genes_mechbreeder);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool HasLifeForce(Pawn pawn)
 | 
			
		||||
        {
 | 
			
		||||
            if (pawn.genes == null)
 | 
			
		||||
            {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            return pawn.genes.HasGene(GeneDefOf.rjw_genes_lifeforce);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool HasLowLifeForce(Pawn pawn)
 | 
			
		||||
        {
 | 
			
		||||
            if (HasLifeForce(pawn))
 | 
			
		||||
            {
 | 
			
		||||
                Gene_LifeForce gene = pawn.genes.GetFirstGeneOfType<Gene_LifeForce>();
 | 
			
		||||
                if (gene.Resource.Value < gene.targetValue)
 | 
			
		||||
                {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool HasCriticalLifeForce(Pawn pawn)
 | 
			
		||||
        {
 | 
			
		||||
            if (HasLifeForce(pawn))
 | 
			
		||||
            {
 | 
			
		||||
                Gene_LifeForce gene = pawn.genes.GetFirstGeneOfType<Gene_LifeForce>();
 | 
			
		||||
                if (gene.Resource.Value < gene.MinLevelForAlert)
 | 
			
		||||
                {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool IsInsectIncubator(Pawn pawn)
 | 
			
		||||
        {
 | 
			
		||||
            if (pawn.genes == null)
 | 
			
		||||
| 
						 | 
				
			
			@ -87,6 +157,15 @@ namespace RJW_Genes
 | 
			
		|||
            return pawn.genes.HasGene(GeneDefOf.rjw_genes_generous_donor);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool isPussyHealer(Pawn pawn)
 | 
			
		||||
        {
 | 
			
		||||
            if (pawn.genes == null)
 | 
			
		||||
            {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            return pawn.genes.HasGene(GeneDefOf.rjw_genes_pussyhealer);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool IsUnbreakable(Pawn pawn)
 | 
			
		||||
        {
 | 
			
		||||
            if (pawn.genes == null)
 | 
			
		||||
| 
						 | 
				
			
			@ -95,6 +174,7 @@ namespace RJW_Genes
 | 
			
		|||
            }
 | 
			
		||||
            return pawn.genes.HasGene(GeneDefOf.rjw_genes_unbreakable);
 | 
			
		||||
        }
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public static bool HasGenitaliaResizingGenes(Pawn pawn)
 | 
			
		||||
| 
						 | 
				
			
			@ -116,5 +196,7 @@ namespace RJW_Genes
 | 
			
		|||
 | 
			
		||||
            return ResizingGenes;
 | 
			
		||||
        }
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> 09157e923d5c4c4cf71d79cb0af665ffd6a7c536
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										71
									
								
								Source/Genes/Life_Force/Abilities/AbilityUtility.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								Source/Genes/Life_Force/Abilities/AbilityUtility.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse.Sound;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw;
 | 
			
		||||
using rjw.Modules.Interactions.Helpers;
 | 
			
		||||
using rjw.Modules.Interactions.Enums;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    public class AbilityUtility
 | 
			
		||||
    {
 | 
			
		||||
        public static void PussyHeal(SexProps props)
 | 
			
		||||
        {
 | 
			
		||||
            if (InteractionHelper.GetWithExtension(props.dictionaryKey).DominantHasFamily(GenitalFamily.Vagina) || InteractionHelper.GetWithExtension(props.dictionaryKey).SubmissiveHasFamily(GenitalFamily.Vagina))
 | 
			
		||||
            {
 | 
			
		||||
                Pawn pawn = props.pawn;
 | 
			
		||||
                Pawn partner = props.partner;
 | 
			
		||||
                FloatRange tendQualityRange;
 | 
			
		||||
                tendQualityRange.min = 0.4f;
 | 
			
		||||
                tendQualityRange.max = 0.8f;
 | 
			
		||||
                if (GeneUtility.isPussyHealer(pawn))
 | 
			
		||||
                {
 | 
			
		||||
                    Heal(partner, tendQualityRange);
 | 
			
		||||
                }
 | 
			
		||||
                if (GeneUtility.isPussyHealer(partner))
 | 
			
		||||
                {
 | 
			
		||||
                    Heal(pawn, tendQualityRange);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool Heal(Pawn pawn, FloatRange tendQualityRange)
 | 
			
		||||
        {
 | 
			
		||||
            bool any_wound_tended = false;
 | 
			
		||||
            List<Hediff> hediffs = pawn.health.hediffSet.hediffs;
 | 
			
		||||
            for (int i = hediffs.Count - 1; i >= 0; i--)
 | 
			
		||||
            {
 | 
			
		||||
                if ((hediffs[i] is Hediff_Injury || hediffs[i] is Hediff_MissingPart) && hediffs[i].TendableNow(false))
 | 
			
		||||
                {
 | 
			
		||||
                    hediffs[i].Tended(tendQualityRange.RandomInRange, tendQualityRange.TrueMax, 1);
 | 
			
		||||
                    any_wound_tended = true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return any_wound_tended;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static float LifeForceCost(Ability ability)
 | 
			
		||||
        {
 | 
			
		||||
            if (ability.comps != null)
 | 
			
		||||
            {
 | 
			
		||||
                using (List<AbilityComp>.Enumerator enumerator = ability.comps.GetEnumerator())
 | 
			
		||||
                {
 | 
			
		||||
                    while (enumerator.MoveNext())
 | 
			
		||||
                    {
 | 
			
		||||
                        CompAbilityEffect_LifeForceCost compAbilityEffect_HemogenCost;
 | 
			
		||||
                        if ((compAbilityEffect_HemogenCost = (enumerator.Current as CompAbilityEffect_LifeForceCost)) != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            return compAbilityEffect_HemogenCost.Props.fertilinCost;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return 0f;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,99 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw;
 | 
			
		||||
using rjw.Modules.Interactions.Helpers;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class CompAbilityEffect_CockEater : CompAbilityEffect
 | 
			
		||||
	{
 | 
			
		||||
		private new CompProperties_AbilityCockEater Props
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return (CompProperties_AbilityCockEater)this.props;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
 | 
			
		||||
		{
 | 
			
		||||
			base.Apply(target, dest);
 | 
			
		||||
			Pawn pawn = target.Pawn;
 | 
			
		||||
			if (pawn == null)
 | 
			
		||||
			{
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			var partBPR = Genital_Helper.get_genitalsBPR(pawn);
 | 
			
		||||
			var parts = Genital_Helper.get_PartsHediffList(pawn, partBPR);
 | 
			
		||||
			if (!parts.NullOrEmpty())
 | 
			
		||||
			{
 | 
			
		||||
				foreach (Hediff part in parts)
 | 
			
		||||
				{
 | 
			
		||||
					if (GenitaliaChanger.IsArtificial(part))
 | 
			
		||||
						continue;
 | 
			
		||||
 | 
			
		||||
					if (Genital_Helper.is_penis(part))
 | 
			
		||||
					{
 | 
			
		||||
						GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(this.parent.pawn), part.Severity); ;
 | 
			
		||||
						pawn.health.RemoveHediff(part);
 | 
			
		||||
						pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.rjw_genes_cock_eaten, pawn, null);
 | 
			
		||||
						break; //Only one penis at the time
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
 | 
			
		||||
		{
 | 
			
		||||
			Pawn pawn = target.Pawn;
 | 
			
		||||
			if (pawn != null)
 | 
			
		||||
			{
 | 
			
		||||
				bool flag = pawn.Faction == this.parent.pawn.Faction || pawn.IsPrisonerOfColony;
 | 
			
		||||
				bool flag2 = pawn.HostileTo(this.parent.pawn);
 | 
			
		||||
				bool flag3 = pawn.Downed;
 | 
			
		||||
				if (!flag && !(flag2 && flag3))
 | 
			
		||||
				{
 | 
			
		||||
					if (throwMessages)
 | 
			
		||||
					{
 | 
			
		||||
						if(flag2 && !flag3)
 | 
			
		||||
                        {
 | 
			
		||||
							Messages.Message(pawn.Name + " is hostile, but not downed.", pawn, MessageTypeDefOf.RejectInput, false);
 | 
			
		||||
						}
 | 
			
		||||
						else if (!flag)
 | 
			
		||||
						{
 | 
			
		||||
							Messages.Message(pawn.Name + " is not a part of the colony or hostile.", pawn, MessageTypeDefOf.RejectInput, false);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				if (!Genital_Helper.has_penis_fertile(pawn))
 | 
			
		||||
				{
 | 
			
		||||
					if (throwMessages)
 | 
			
		||||
					{
 | 
			
		||||
						Messages.Message(pawn.Name + " has no penis", pawn, MessageTypeDefOf.RejectInput, false);
 | 
			
		||||
					}
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return base.Valid(target, throwMessages);
 | 
			
		||||
		}
 | 
			
		||||
		public override bool GizmoDisabled(out string reason)
 | 
			
		||||
		{
 | 
			
		||||
			Pawn_GeneTracker genes = this.parent.pawn.genes;
 | 
			
		||||
			Gene_LifeForce gene_LifeForce = (genes != null) ? genes.GetFirstGeneOfType<Gene_LifeForce>() : null;
 | 
			
		||||
			if (gene_LifeForce == null)
 | 
			
		||||
			{
 | 
			
		||||
				reason = "AbilityDisabledNoFertilinGene".Translate(this.parent.pawn);
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			reason = null;
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,112 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Runtime.CompilerServices;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class CompAbilityEffect_LifeForceCost : CompAbilityEffect
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
		public new CompProperties_AbilityLifeForceCost Props
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return (CompProperties_AbilityLifeForceCost)this.props;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool HasEnoughFertilin
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				Pawn_GeneTracker genes = this.parent.pawn.genes;
 | 
			
		||||
				Gene_LifeForce gene_lifeforce = (genes != null) ? genes.GetFirstGeneOfType < Gene_LifeForce>() : null;
 | 
			
		||||
				return gene_lifeforce != null && gene_lifeforce.Value >= this.Props.fertilinCost;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
 | 
			
		||||
		{
 | 
			
		||||
			base.Apply(target, dest);
 | 
			
		||||
			GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(this.parent.pawn), -this.Props.fertilinCost);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		public override bool GizmoDisabled(out string reason)
 | 
			
		||||
		{
 | 
			
		||||
			Pawn_GeneTracker genes = this.parent.pawn.genes;
 | 
			
		||||
			Gene_LifeForce gene_LifeForce = (genes != null) ? genes.GetFirstGeneOfType<Gene_LifeForce>() : null;
 | 
			
		||||
			if (gene_LifeForce == null)
 | 
			
		||||
			{
 | 
			
		||||
				reason = "AbilityDisabledNoFertilinGene".Translate(this.parent.pawn);
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			if (gene_LifeForce.Value < this.Props.fertilinCost)
 | 
			
		||||
			{
 | 
			
		||||
				reason = "AbilityDisabledNoFertilin".Translate(this.parent.pawn);
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			float num = this.TotalLifeForceCostOfQueuedAbilities();
 | 
			
		||||
			float num2 = this.Props.fertilinCost + num;
 | 
			
		||||
			if (this.Props.fertilinCost > 1E-45f && num2 > gene_LifeForce.Value)
 | 
			
		||||
			{
 | 
			
		||||
				reason = "AbilityDisabledNoFertilin".Translate(this.parent.pawn);
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			reason = null;
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool AICanTargetNow(LocalTargetInfo target)
 | 
			
		||||
		{
 | 
			
		||||
			return this.HasEnoughFertilin;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private float TotalLifeForceCostOfQueuedAbilities()
 | 
			
		||||
		{
 | 
			
		||||
			Pawn_JobTracker jobs = this.parent.pawn.jobs;
 | 
			
		||||
			object obj;
 | 
			
		||||
			if (jobs == null)
 | 
			
		||||
			{
 | 
			
		||||
				obj = null;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				Job curJob = jobs.curJob;
 | 
			
		||||
				obj = ((curJob != null) ? curJob.verbToUse : null);
 | 
			
		||||
			}
 | 
			
		||||
			Verb_CastAbility verb_CastAbility = obj as Verb_CastAbility;
 | 
			
		||||
			float num;
 | 
			
		||||
			if (verb_CastAbility == null)
 | 
			
		||||
			{
 | 
			
		||||
				num = 0f;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				Ability ability = verb_CastAbility.ability;
 | 
			
		||||
				num = ((ability != null) ? AbilityUtility.LifeForceCost(ability) : 0f);
 | 
			
		||||
			}
 | 
			
		||||
			float num2 = num;
 | 
			
		||||
			if (this.parent.pawn.jobs != null)
 | 
			
		||||
			{
 | 
			
		||||
				for (int i = 0; i < this.parent.pawn.jobs.jobQueue.Count; i++)
 | 
			
		||||
				{
 | 
			
		||||
					Verb_CastAbility verb_CastAbility2;
 | 
			
		||||
					if ((verb_CastAbility2 = (this.parent.pawn.jobs.jobQueue[i].job.verbToUse as Verb_CastAbility)) != null)
 | 
			
		||||
					{
 | 
			
		||||
						float num3 = num2;
 | 
			
		||||
						Ability ability2 = verb_CastAbility2.ability;
 | 
			
		||||
						num2 = num3 + ((ability2 != null) ? AbilityUtility.LifeForceCost(ability2) : 0f);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return num2;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								Source/Genes/Life_Force/Abilities/CompAbilityEffect_PussyHeal.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								Source/Genes/Life_Force/Abilities/CompAbilityEffect_PussyHeal.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw;
 | 
			
		||||
using rjw.Modules.Interactions.Helpers;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class CompAbilityEffect_PussyHeal : CompAbilityEffect
 | 
			
		||||
	{
 | 
			
		||||
		private new CompProperties_AbilityPussyHeal Props
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return (CompProperties_AbilityPussyHeal)this.props;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
 | 
			
		||||
		{
 | 
			
		||||
			base.Apply(target, dest);
 | 
			
		||||
			Pawn pawn = target.Pawn;
 | 
			
		||||
			if (pawn == null)
 | 
			
		||||
			{
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			bool any_wound_tended = AbilityUtility.Heal(pawn, this.Props.tendQualityRange);
 | 
			
		||||
			if (any_wound_tended)
 | 
			
		||||
			{
 | 
			
		||||
				MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, "Sex healed wounds", 3.65f);
 | 
			
		||||
				//pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.Pussy_Healed, pawn, null);
 | 
			
		||||
			}
 | 
			
		||||
			//this.AfterSex(any_wound_tended);
 | 
			
		||||
			//FleckMaker.AttachedOverlay(pawn, FleckDefOf.FlashHollow, Vector3.zero, 1.5f, -1f);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//Not yet implemented, but the heal should also trigger after normal sex
 | 
			
		||||
		public void AfterSex(Pawn pawn, Pawn target)
 | 
			
		||||
		{
 | 
			
		||||
			List<Hediff> hediffs = target.health.hediffSet.hediffs;
 | 
			
		||||
			for (int i = 0; i < hediffs.Count; i++)
 | 
			
		||||
			{
 | 
			
		||||
				if ((hediffs[i] is Hediff_Injury || hediffs[i] is Hediff_MissingPart) && hediffs[i].TendableNow(false))
 | 
			
		||||
				{
 | 
			
		||||
					//target.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.Pussy_Healed, pawn, null);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			//InteractionHelper.GetWithExtension(dictionaryKey).DominantHasTag("CanBePenetrated")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
 | 
			
		||||
		{
 | 
			
		||||
			Pawn pawn = target.Pawn;
 | 
			
		||||
			if (pawn != null)
 | 
			
		||||
			{
 | 
			
		||||
				//to be replaced with severel checks to make it clear why target is unable to have sex
 | 
			
		||||
				if (!CasualSex_Helper.CanHaveSex(pawn))
 | 
			
		||||
				{
 | 
			
		||||
					if (throwMessages)
 | 
			
		||||
					{
 | 
			
		||||
						Messages.Message(pawn.Name + " is unable to have sex", pawn, MessageTypeDefOf.RejectInput, false);
 | 
			
		||||
					}
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				else if (pawn.IsAnimal() && !RJWSettings.bestiality_enabled)
 | 
			
		||||
				{
 | 
			
		||||
					if (throwMessages)
 | 
			
		||||
					{
 | 
			
		||||
						Messages.Message("bestiality is disabled", pawn, MessageTypeDefOf.RejectInput, false);
 | 
			
		||||
					}
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				//AbilityUtility.ValidateHasTendableWound(pawn, throwMessages, this.parent);
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
			return base.Valid(target, throwMessages);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool GizmoDisabled(out string reason)
 | 
			
		||||
		{
 | 
			
		||||
			reason = null;
 | 
			
		||||
			if (!Genital_Helper.has_vagina(this.parent.pawn))
 | 
			
		||||
			{
 | 
			
		||||
				reason = this.parent.pawn.Name + " has no vagina to use.";
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			else if (!RJWSettings.rape_enabled)
 | 
			
		||||
			{
 | 
			
		||||
				reason = "Rape is disabled";
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,82 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
using rjw;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class CompAbilityEffect_Seduce : CompAbilityEffect_WithDest
 | 
			
		||||
	{
 | 
			
		||||
		private new CompProperties_Seduce Props
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return (CompProperties_Seduce)this.props;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
 | 
			
		||||
		{
 | 
			
		||||
			base.Apply(target, dest);
 | 
			
		||||
			Pawn pawn = target.Thing as Pawn;
 | 
			
		||||
			Pawn pawn2 = this.parent.pawn;
 | 
			
		||||
			if (pawn != null && pawn2 != null && !pawn.Downed)
 | 
			
		||||
			{
 | 
			
		||||
				Job job = JobMaker.MakeJob(JobDefOf.rjw_genes_lifeforce_seduced, pawn2);
 | 
			
		||||
				job.mote = MoteMaker.MakeThoughtBubble(pawn, this.parent.def.iconPath, true);
 | 
			
		||||
				pawn.jobs.StopAll(false, true);
 | 
			
		||||
				pawn.jobs.StartJob(job, JobCondition.InterruptForced, null, false, true, null, null, false, false, null, false, true);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
			Pawn pawn = target.Pawn;
 | 
			
		||||
			if (pawn != null)
 | 
			
		||||
			{
 | 
			
		||||
				if (!xxx.can_be_fucked(pawn))
 | 
			
		||||
				{
 | 
			
		||||
					if (throwMessages)
 | 
			
		||||
					{
 | 
			
		||||
						Messages.Message(pawn.Name + " is unable to have sex", pawn, MessageTypeDefOf.RejectInput, false);
 | 
			
		||||
					}
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				else if (pawn.IsAnimal() && !RJWSettings.bestiality_enabled)
 | 
			
		||||
				{
 | 
			
		||||
					if (throwMessages)
 | 
			
		||||
					{
 | 
			
		||||
						Messages.Message("bestiality is disabled", pawn, MessageTypeDefOf.RejectInput, false);
 | 
			
		||||
					}
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				else if (pawn.Downed)
 | 
			
		||||
                {
 | 
			
		||||
					if (throwMessages)
 | 
			
		||||
					{
 | 
			
		||||
						Messages.Message(pawn.Name + " is unable to move", pawn, MessageTypeDefOf.RejectInput, false);
 | 
			
		||||
					}
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
			return base.Valid(target, throwMessages);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool GizmoDisabled(out string reason)
 | 
			
		||||
		{
 | 
			
		||||
			reason = null;
 | 
			
		||||
			if (!RJWSettings.rape_enabled)
 | 
			
		||||
			{
 | 
			
		||||
				reason = "Rape is disabled";
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			return false;
 | 
			
		||||
		} 
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class CompProperties_AbilityCockEater : CompProperties_AbilityEffect
 | 
			
		||||
	{
 | 
			
		||||
		public CompProperties_AbilityCockEater()
 | 
			
		||||
		{
 | 
			
		||||
			this.compClass = typeof(CompAbilityEffect_CockEater);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	// Token: 0x02000F65 RID: 3941
 | 
			
		||||
	public class CompProperties_AbilityLifeForceCost : CompProperties_AbilityEffect
 | 
			
		||||
	{
 | 
			
		||||
		// Token: 0x06005D16 RID: 23830 RVA: 0x001FA73F File Offset: 0x001F893F
 | 
			
		||||
		public CompProperties_AbilityLifeForceCost()
 | 
			
		||||
		{
 | 
			
		||||
			this.compClass = typeof(CompAbilityEffect_LifeForceCost);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Token: 0x06005D17 RID: 23831 RVA: 0x001FA757 File Offset: 0x001F8957
 | 
			
		||||
		public override IEnumerable<string> ExtraStatSummary()
 | 
			
		||||
		{
 | 
			
		||||
			yield return "AbilityFertilinCost" + ": " + Mathf.RoundToInt(this.fertilinCost * 100f);
 | 
			
		||||
			yield break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Token: 0x040038CD RID: 14541
 | 
			
		||||
		public float fertilinCost;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class CompProperties_AbilityPussyHeal : CompProperties_AbilityEffect
 | 
			
		||||
	{
 | 
			
		||||
		public CompProperties_AbilityPussyHeal()
 | 
			
		||||
		{
 | 
			
		||||
			this.compClass = typeof(CompAbilityEffect_PussyHeal);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public FloatRange tendQualityRange;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								Source/Genes/Life_Force/Abilities/CompProperties_Seduce.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Source/Genes/Life_Force/Abilities/CompProperties_Seduce.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class CompProperties_Seduce : CompProperties_EffectWithDest
 | 
			
		||||
	{
 | 
			
		||||
		public CompProperties_Seduce()
 | 
			
		||||
		{
 | 
			
		||||
			this.compClass = typeof(CompAbilityEffect_Seduce);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public StatDef durationMultiplier;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										70
									
								
								Source/Genes/Life_Force/Alert_LowFertilin.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								Source/Genes/Life_Force/Alert_LowFertilin.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using RimWorld.Planet;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    public class Alert_CriticalFertilin : Alert
 | 
			
		||||
    {
 | 
			
		||||
		private List<GlobalTargetInfo> Targets
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				this.CalculateTargets();
 | 
			
		||||
				return this.targets;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override string GetLabel()
 | 
			
		||||
		{
 | 
			
		||||
			if (this.Targets.Count == 1)
 | 
			
		||||
			{
 | 
			
		||||
				return "AlertLowFertilin".Translate() + ": " + this.targetLabels[0];
 | 
			
		||||
			}
 | 
			
		||||
			return "AlertLowFertilin".Translate();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void CalculateTargets()
 | 
			
		||||
		{
 | 
			
		||||
			this.targets.Clear();
 | 
			
		||||
			this.targetLabels.Clear();
 | 
			
		||||
			if (!ModsConfig.BiotechActive)
 | 
			
		||||
			{
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			foreach (Pawn pawn in PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive)
 | 
			
		||||
			{
 | 
			
		||||
				if (pawn.RaceProps.Humanlike && pawn.Faction == Faction.OfPlayer)
 | 
			
		||||
				{
 | 
			
		||||
					Pawn_GeneTracker genes = pawn.genes;
 | 
			
		||||
					Gene_LifeForce gene_Lifeforce = (genes != null) ? genes.GetFirstGeneOfType<Gene_LifeForce>() : null;
 | 
			
		||||
					if (gene_Lifeforce != null && gene_Lifeforce.Value < gene_Lifeforce.MinLevelForAlert)
 | 
			
		||||
					{
 | 
			
		||||
						this.targets.Add(pawn);
 | 
			
		||||
						this.targetLabels.Add(pawn.NameShortColored.Resolve());
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override TaggedString GetExplanation()
 | 
			
		||||
		{
 | 
			
		||||
			return "AlertLowFertilinDesc".Translate() + ":\n" + this.targetLabels.ToLineList("  - ");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override AlertReport GetReport()
 | 
			
		||||
		{
 | 
			
		||||
			return AlertReport.CulpritsAre(this.Targets);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Token: 0x04004B5C RID: 19292
 | 
			
		||||
		private List<GlobalTargetInfo> targets = new List<GlobalTargetInfo>();
 | 
			
		||||
 | 
			
		||||
		// Token: 0x04004B5D RID: 19293
 | 
			
		||||
		private List<string> targetLabels = new List<string>();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										83
									
								
								Source/Genes/Life_Force/GeneGizmo_ResourceLifeForce.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								Source/Genes/Life_Force/GeneGizmo_ResourceLifeForce.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,83 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	//Copied from GeneGizmo_ResourceHemogen, with small modifications 
 | 
			
		||||
	public class GeneGizmo_ResourceLifeForce : GeneGizmo_Resource
 | 
			
		||||
    {
 | 
			
		||||
        public GeneGizmo_ResourceLifeForce(Gene_Resource gene, List<IGeneResourceDrain> drainGenes, Color barColor, Color barhighlightColor) : base(gene, drainGenes, barColor, barhighlightColor)
 | 
			
		||||
        {
 | 
			
		||||
            this.draggableBar = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override GizmoResult GizmoOnGUI(Vector2 topLeft, float maxWidth, GizmoRenderParms parms)
 | 
			
		||||
        {
 | 
			
		||||
            return base.GizmoOnGUI(topLeft, maxWidth, parms);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override string GetTooltip()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
			this.tmpDrainGenes.Clear();
 | 
			
		||||
			string text = string.Format("{0}: {1} / {2}\n", this.gene.ResourceLabel.CapitalizeFirst().Colorize(ColoredText.TipSectionTitleColor), this.gene.ValueForDisplay, this.gene.MaxForDisplay);
 | 
			
		||||
			if (this.gene.pawn.IsColonistPlayerControlled || this.gene.pawn.IsPrisonerOfColony)
 | 
			
		||||
			{
 | 
			
		||||
				if (this.gene.targetValue <= 0f)
 | 
			
		||||
				{
 | 
			
		||||
					text += "NeverSeekFertilin";
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					text = text + ("SeekFertilinBelow" + ": ") + this.gene.PostProcessValue(this.gene.targetValue);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (!this.drainGenes.NullOrEmpty<IGeneResourceDrain>())
 | 
			
		||||
			{
 | 
			
		||||
				float num = 0f;
 | 
			
		||||
				foreach (IGeneResourceDrain geneResourceDrain in this.drainGenes)
 | 
			
		||||
				{
 | 
			
		||||
					if (geneResourceDrain.CanOffset)
 | 
			
		||||
					{
 | 
			
		||||
						this.tmpDrainGenes.Add(new Pair<IGeneResourceDrain, float>(geneResourceDrain, geneResourceDrain.ResourceLossPerDay));
 | 
			
		||||
						num += geneResourceDrain.ResourceLossPerDay;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (num != 0f)
 | 
			
		||||
				{
 | 
			
		||||
					string text2 = (num < 0f) ? "RegenerationRate".Translate() : "DrainRate".Translate();
 | 
			
		||||
					text = string.Concat(new string[]
 | 
			
		||||
					{
 | 
			
		||||
				text,
 | 
			
		||||
				"\n\n",
 | 
			
		||||
				text2,
 | 
			
		||||
				": ",
 | 
			
		||||
				"PerDay".Translate(Mathf.Abs(this.gene.PostProcessValue(num))).Resolve()
 | 
			
		||||
					});
 | 
			
		||||
					foreach (Pair<IGeneResourceDrain, float> pair in this.tmpDrainGenes)
 | 
			
		||||
					{
 | 
			
		||||
						text = string.Concat(new string[]
 | 
			
		||||
						{
 | 
			
		||||
					text,
 | 
			
		||||
					"\n  - ",
 | 
			
		||||
					pair.First.DisplayLabel.CapitalizeFirst(),
 | 
			
		||||
					": ",
 | 
			
		||||
					"PerDay".Translate(this.gene.PostProcessValue(-pair.Second).ToStringWithSign()).Resolve()
 | 
			
		||||
						});
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (!this.gene.def.resourceDescription.NullOrEmpty())
 | 
			
		||||
			{
 | 
			
		||||
				text = text + "\n\n" + this.gene.def.resourceDescription.Formatted(this.gene.pawn.Named("PAWN")).Resolve();
 | 
			
		||||
			}
 | 
			
		||||
			return text;
 | 
			
		||||
		}
 | 
			
		||||
		private List<Pair<IGeneResourceDrain, float>> tmpDrainGenes = new List<Pair<IGeneResourceDrain, float>>();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										153
									
								
								Source/Genes/Life_Force/Gene_LifeForce.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								Source/Genes/Life_Force/Gene_LifeForce.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,153 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    public class Gene_LifeForce : Gene_Resource, IGeneResourceDrain
 | 
			
		||||
	{
 | 
			
		||||
        //Gene should only be active if sex is allowed for this pawn 
 | 
			
		||||
        public override bool Active
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				if (this.Overridden)
 | 
			
		||||
				{
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				Pawn pawn = this.pawn;
 | 
			
		||||
				
 | 
			
		||||
				return ((pawn != null) ? pawn.ageTracker : null) == null || 
 | 
			
		||||
					((float)this.pawn.ageTracker.AgeBiologicalYears >= this.def.minAgeActive && this.pawn.ageTracker.AgeBiologicalYears >= (RJWSettings.AllowYouthSex ? 13f : 18f));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public override void ExposeData()
 | 
			
		||||
        {
 | 
			
		||||
            base.ExposeData();
 | 
			
		||||
			Scribe_Values.Look<bool>(ref this.StoredCumAllowed, "StoredCumAllowed", true, false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        public bool ShouldConsumeLifeForceNow()
 | 
			
		||||
		{
 | 
			
		||||
			return this.Value < this.targetValue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//Same as Gene_Hemogen
 | 
			
		||||
		public override IEnumerable<Gizmo> GetGizmos()
 | 
			
		||||
		{
 | 
			
		||||
			foreach (Gizmo gizmo in base.GetGizmos())
 | 
			
		||||
			{
 | 
			
		||||
				yield return gizmo;
 | 
			
		||||
			}
 | 
			
		||||
			foreach (Gizmo gizmo2 in GeneResourceDrainUtility.GetResourceDrainGizmos(this))
 | 
			
		||||
			{
 | 
			
		||||
				yield return gizmo2;
 | 
			
		||||
			}
 | 
			
		||||
			yield break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//Depending on how low the value is it will increase sexdrive and if it reaches zero it will create a mental break which will make the pawn rape others.
 | 
			
		||||
		//Not using base.Tick() as it is used to start mental breaks, but we have another way to do it.
 | 
			
		||||
		public override void Tick()
 | 
			
		||||
		{
 | 
			
		||||
			//base.Tick();
 | 
			
		||||
			if (this.CanOffset && this.Resource != null)
 | 
			
		||||
            {
 | 
			
		||||
				GeneUtility.OffsetLifeForce(this, -this.ResourceLossPerDay / 60000f);
 | 
			
		||||
				//this.Resource.Value -= this.ResourceLossPerDay / 60000;
 | 
			
		||||
				if (this.Resource.Value <= 0 && this.pawn.IsHashIntervalTick(300))
 | 
			
		||||
				{
 | 
			
		||||
					if (ModsConfig.BiotechActive && this.def.mentalBreakDef != null && 
 | 
			
		||||
						this.pawn.Spawned && !this.pawn.InMentalState && !this.pawn.Downed && 
 | 
			
		||||
						this.def.mentalBreakDef.Worker.BreakCanOccur(this.pawn))
 | 
			
		||||
                    {
 | 
			
		||||
						this.def.mentalBreakDef.Worker.TryStart(this.pawn, "MentalStateReason_Gene".Translate() + ": " + this.LabelCap, false);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
            }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool StoredCumAllowed = true;
 | 
			
		||||
		public Gene_Resource Resource
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return this;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public Pawn Pawn
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return this.pawn;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public bool CanOffset
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return this.pawn.Spawned && this.Active;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float ResourceLossPerDay
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return this.def.resourceLossPerDay;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string DisplayLabel
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return this.def.resourceLabel;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override float InitialResourceMax
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return 1f;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override float MinLevelForAlert
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return 0.2f;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public override float MaxLevelOffset
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return base.MaxLevelOffset;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		protected override Color BarColor
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return Color.grey;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		protected override Color BarHighlightColor
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return Color.white;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										79
									
								
								Source/Genes/Life_Force/Gene_LifeForceDrain.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								Source/Genes/Life_Force/Gene_LifeForceDrain.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,79 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class Gene_LifeForceDrain : Gene, IGeneResourceDrain
 | 
			
		||||
	{
 | 
			
		||||
		public Gene_Resource Resource
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				if (this.cachedLifeForceGene == null || !this.cachedLifeForceGene.Active)
 | 
			
		||||
				{
 | 
			
		||||
					this.cachedLifeForceGene = this.pawn.genes.GetFirstGeneOfType<Gene_LifeForce>();
 | 
			
		||||
				}
 | 
			
		||||
				return this.cachedLifeForceGene;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool CanOffset
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return this.Active && this.Resource != null && this.Resource.Active;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public float ResourceLossPerDay
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return this.def.resourceLossPerDay;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Pawn Pawn
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return this.pawn;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string DisplayLabel
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return this.Label + " (" + "Gene".Translate() + ")";
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void Tick()
 | 
			
		||||
		{
 | 
			
		||||
			base.Tick();
 | 
			
		||||
			if (this.CanOffset && this.Resource != null)
 | 
			
		||||
            {
 | 
			
		||||
				GeneUtility.OffsetLifeForce(this, -this.ResourceLossPerDay / 60000);
 | 
			
		||||
			}			
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override IEnumerable<Gizmo> GetGizmos()
 | 
			
		||||
		{
 | 
			
		||||
			foreach (Gizmo gizmo in GeneResourceDrainUtility.GetResourceDrainGizmos(this))
 | 
			
		||||
			{
 | 
			
		||||
				yield return gizmo;
 | 
			
		||||
			}
 | 
			
		||||
			IEnumerator<Gizmo> enumerator = null;
 | 
			
		||||
			yield break;
 | 
			
		||||
			yield break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[Unsaved(false)]
 | 
			
		||||
		private Gene_LifeForce cachedLifeForceGene;
 | 
			
		||||
 | 
			
		||||
		private const float MinAgeForDrain = 3f;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								Source/Genes/Life_Force/HediffWithComps_tank.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								Source/Genes/Life_Force/HediffWithComps_tank.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    internal class HediffWithComps_tank : HediffWithComps
 | 
			
		||||
    {
 | 
			
		||||
		public override string LabelInBrackets
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				StringBuilder stringBuilder = new StringBuilder();
 | 
			
		||||
				stringBuilder.Append(base.LabelInBrackets);
 | 
			
		||||
				stringBuilder.Append(this.Severity.ToStringPercent());
 | 
			
		||||
				return stringBuilder.ToString();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    public class IngestionOutcomeDoer_LifeForceOffset : IngestionOutcomeDoer
 | 
			
		||||
    {
 | 
			
		||||
		protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested)
 | 
			
		||||
		{
 | 
			
		||||
			if (GeneUtility.HasLifeForce(pawn))
 | 
			
		||||
            {
 | 
			
		||||
				float num = ingested.stackCount * this.FertilinPerUnit / 100;
 | 
			
		||||
				GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(pawn), num);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public float FertilinPerUnit = 1f;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,90 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
using rjw;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class JobDriver_CastAbilityAfterSex : JobDriver_SexBaseInitiator
 | 
			
		||||
	{
 | 
			
		||||
		//Summary//
 | 
			
		||||
		//Similar to jobdriver rape, but it cast an ability after sex and tries to limit what kind of sexinteractions are allowed.
 | 
			
		||||
		protected override IEnumerable<Toil> MakeNewToils()
 | 
			
		||||
		{
 | 
			
		||||
			base.setup_ticks();
 | 
			
		||||
			//this.FailOnDespawnedOrNull(TargetIndex.A);
 | 
			
		||||
			//this.FailOnCannotTouch(TargetIndex.B, PathEndMode.OnCell);
 | 
			
		||||
			this.FailOnDespawnedNullOrForbidden(this.iTarget);
 | 
			
		||||
			//this.FailOn(() => !target.health.capacities.CanBeAwake);
 | 
			
		||||
			JobDef PartnerJob = xxx.gettin_raped;
 | 
			
		||||
			yield return Toils_Goto.Goto(TargetIndex.A, PathEndMode.OnCell);
 | 
			
		||||
			yield return new Toil
 | 
			
		||||
			{
 | 
			
		||||
				defaultCompleteMode = ToilCompleteMode.Instant,
 | 
			
		||||
				socialMode = RandomSocialMode.Off,
 | 
			
		||||
				initAction = delegate ()
 | 
			
		||||
				{
 | 
			
		||||
					Job newJob = JobMaker.MakeJob(PartnerJob, this.pawn, this.Partner);
 | 
			
		||||
					this.Partner.jobs.StartJob(newJob, JobCondition.InterruptForced, null, false, true, null, null, false, false, null, false, true);
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
			Toil toil = new Toil();
 | 
			
		||||
			toil.defaultCompleteMode = ToilCompleteMode.Never;
 | 
			
		||||
			toil.socialMode = RandomSocialMode.Off;
 | 
			
		||||
			toil.defaultDuration = this.duration;
 | 
			
		||||
			toil.handlingFacing = true;
 | 
			
		||||
			toil.FailOn(() => this.Partner.CurJob.def != PartnerJob);
 | 
			
		||||
			toil.initAction = delegate ()
 | 
			
		||||
			{
 | 
			
		||||
				this.Partner.pather.StopDead();
 | 
			
		||||
				this.Partner.jobs.curDriver.asleep = false;
 | 
			
		||||
 | 
			
		||||
				//Tries to find CompProperties_SexInteractionRequirements and if it finds it it will try and generate sexprops based on the sexpropsrequirements.
 | 
			
		||||
				foreach (AbilityComp comp in this.job.ability.comps)
 | 
			
		||||
				{
 | 
			
		||||
					if (comp.props is CompProperties_SexInteractionRequirements)
 | 
			
		||||
					{
 | 
			
		||||
						CompProperties_SexInteractionRequirements sexpropsreq = comp.props as CompProperties_SexInteractionRequirements;
 | 
			
		||||
						this.Sexprops = CustomSexInteraction_Helper.GenerateSexProps(this.pawn, this.Partner, sexpropsreq);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				this.Start();
 | 
			
		||||
				this.Sexprops.usedCondom = (CondomUtility.TryUseCondom(this.pawn) || CondomUtility.TryUseCondom(this.Partner));
 | 
			
		||||
			};
 | 
			
		||||
			toil.AddPreTickAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				if (this.pawn.IsHashIntervalTick(this.ticks_between_hearts))
 | 
			
		||||
				{
 | 
			
		||||
					this.ThrowMetaIconF(this.pawn.Position, this.pawn.Map, FleckDefOf.Heart);
 | 
			
		||||
				}
 | 
			
		||||
				this.SexTick(this.pawn, this.Partner, true, true);
 | 
			
		||||
				SexUtility.reduce_rest(this.Partner, 1f);
 | 
			
		||||
				SexUtility.reduce_rest(this.pawn, 1f);
 | 
			
		||||
				if (this.ticks_left <= 0)
 | 
			
		||||
				{
 | 
			
		||||
					this.ReadyForNextToil();
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
			toil.AddFinishAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				this.End();
 | 
			
		||||
			});
 | 
			
		||||
			yield return toil;
 | 
			
		||||
			yield return new Toil
 | 
			
		||||
			{
 | 
			
		||||
				initAction = delegate ()
 | 
			
		||||
				{
 | 
			
		||||
					SexUtility.ProcessSex(this.Sexprops);
 | 
			
		||||
				},
 | 
			
		||||
				defaultCompleteMode = ToilCompleteMode.Instant
 | 
			
		||||
			};
 | 
			
		||||
			yield return Toils_Combat.CastVerb(TargetIndex.A, TargetIndex.B, false);
 | 
			
		||||
			yield break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								Source/Genes/Life_Force/JobDrivers/JobDriver_Seduced.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								Source/Genes/Life_Force/JobDrivers/JobDriver_Seduced.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
using rjw;
 | 
			
		||||
using rjw.Modules.Interactions.Enums;
 | 
			
		||||
using rjw.Modules.Interactions.Helpers;
 | 
			
		||||
using rjw.Modules.Interactions.Objects;
 | 
			
		||||
using rjw.Modules.Interactions.Contexts;
 | 
			
		||||
using rjw.Modules.Interactions.Implementation;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class JobDriver_Seduced : JobDriver
 | 
			
		||||
	{
 | 
			
		||||
		//Summary//
 | 
			
		||||
		//Makes a pawn move to seducing pawn and then tries to rape them.
 | 
			
		||||
		protected override IEnumerable<Toil> MakeNewToils()
 | 
			
		||||
		{
 | 
			
		||||
			
 | 
			
		||||
			this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
 | 
			
		||||
			this.FailOn(() => !this.pawn.CanReserve(TargetA, xxx.max_rapists_per_prisoner, 0, null, false));
 | 
			
		||||
			this.FailOn(() => this.pawn.IsFighting());
 | 
			
		||||
			this.FailOn(() => this.pawn.Drafted);
 | 
			
		||||
	
 | 
			
		||||
			Pawn partner = this.job.GetTarget(TargetIndex.A).Pawn;
 | 
			
		||||
			yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);
 | 
			
		||||
			yield return new Toil
 | 
			
		||||
			{
 | 
			
		||||
				defaultCompleteMode = ToilCompleteMode.Instant,
 | 
			
		||||
				socialMode = RandomSocialMode.Off,
 | 
			
		||||
				initAction = delegate ()
 | 
			
		||||
				{
 | 
			
		||||
					if(partner != null)
 | 
			
		||||
                    {
 | 
			
		||||
						partner.drafter.Drafted = false;
 | 
			
		||||
						this.pawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.rjw_genes_seduced, partner, null);
 | 
			
		||||
						Job newJob = JobMaker.MakeJob(JobDefOf.sex_on_spot, pawn);
 | 
			
		||||
						partner.jobs.StartJob(newJob, JobCondition.InterruptForced, null, false, true, null, null, false, false, null, false, true);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
			yield break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool TryMakePreToilReservations(bool errorOnFailed)
 | 
			
		||||
		{
 | 
			
		||||
			return this.pawn.Reserve(TargetA, this.job, xxx.max_rapists_per_prisoner, 0, null, errorOnFailed);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										108
									
								
								Source/Genes/Life_Force/JobDrivers/JobDriver_SexOnSpot.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								Source/Genes/Life_Force/JobDrivers/JobDriver_SexOnSpot.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,108 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
using rjw;
 | 
			
		||||
using rjw.Modules.Interactions.Enums;
 | 
			
		||||
using rjw.Modules.Interactions.Helpers;
 | 
			
		||||
using rjw.Modules.Interactions.Objects;
 | 
			
		||||
using rjw.Modules.Interactions.Contexts;
 | 
			
		||||
using rjw.Modules.Interactions.Implementation;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class JobDriver_SexOnSpot : JobDriver_SexBaseInitiator
 | 
			
		||||
	{
 | 
			
		||||
		protected override IEnumerable<Toil> MakeNewToils()
 | 
			
		||||
		{
 | 
			
		||||
			if (RJWSettings.DebugRape)
 | 
			
		||||
			{
 | 
			
		||||
				ModLog.Message(base.GetType().ToString() + "::MakeNewToils() called");
 | 
			
		||||
			}
 | 
			
		||||
			base.setup_ticks();
 | 
			
		||||
			JobDef PartnerJob = JobDefOf.sex_on_spot_reciever;
 | 
			
		||||
			this.FailOnDespawnedNullOrForbidden(this.iTarget);
 | 
			
		||||
			this.FailOn(() => !this.pawn.CanReserve(this.Partner, xxx.max_rapists_per_prisoner, 0, null, false));
 | 
			
		||||
			this.FailOn(() => this.pawn.IsFighting());
 | 
			
		||||
			this.FailOn(() => this.Partner.IsFighting());
 | 
			
		||||
			this.FailOn(() => this.pawn.Drafted);
 | 
			
		||||
			yield return Toils_Goto.GotoThing(this.iTarget, PathEndMode.Touch);
 | 
			
		||||
			if (this.pawn.HostileTo(this.Partner))
 | 
			
		||||
            {
 | 
			
		||||
				Partner.health.AddHediff(xxx.submitting);
 | 
			
		||||
            }
 | 
			
		||||
			yield return Toils_Goto.GotoThing(this.iTarget, PathEndMode.OnCell);
 | 
			
		||||
			//Give thought malus to partner (I was seduced into having sex against my will)
 | 
			
		||||
			yield return new Toil
 | 
			
		||||
			{
 | 
			
		||||
				defaultCompleteMode = ToilCompleteMode.Instant,
 | 
			
		||||
				socialMode = RandomSocialMode.Off,
 | 
			
		||||
				initAction = delegate ()
 | 
			
		||||
				{
 | 
			
		||||
					if (!(this.Partner.jobs.curDriver is JobDriver_SexOnSpotReciever))
 | 
			
		||||
					{
 | 
			
		||||
						Job newJob = JobMaker.MakeJob(PartnerJob, this.pawn);
 | 
			
		||||
						Building_Bed building_Bed = null;
 | 
			
		||||
						if (this.Partner.GetPosture() == PawnPosture.LayingInBed)
 | 
			
		||||
						{
 | 
			
		||||
							building_Bed = this.Partner.CurrentBed();
 | 
			
		||||
						}
 | 
			
		||||
						this.Partner.jobs.StartJob(newJob, JobCondition.InterruptForced, null, false, true, null, null, false, false, null, false, true);
 | 
			
		||||
						if (building_Bed != null)
 | 
			
		||||
						{
 | 
			
		||||
							JobDriver_SexOnSpotReciever jobDriver_SexOnSpotReciever = this.Partner.jobs.curDriver as JobDriver_SexOnSpotReciever;
 | 
			
		||||
							if (jobDriver_SexOnSpotReciever == null)
 | 
			
		||||
							{
 | 
			
		||||
								return;
 | 
			
		||||
							}
 | 
			
		||||
							jobDriver_SexOnSpotReciever.Set_bed(building_Bed);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
			Toil toil = new Toil();
 | 
			
		||||
			toil.defaultCompleteMode = ToilCompleteMode.Never;
 | 
			
		||||
			toil.defaultDuration = this.duration;
 | 
			
		||||
			toil.handlingFacing = true;
 | 
			
		||||
			toil.FailOn(() => this.Partner.CurJob.def != PartnerJob);
 | 
			
		||||
			toil.initAction = delegate ()
 | 
			
		||||
			{
 | 
			
		||||
				this.Partner.pather.StopDead();
 | 
			
		||||
				this.Partner.jobs.curDriver.asleep = false;
 | 
			
		||||
				this.Start();
 | 
			
		||||
			};
 | 
			
		||||
			toil.tickAction = delegate ()
 | 
			
		||||
			{
 | 
			
		||||
				if (this.pawn.IsHashIntervalTick(this.ticks_between_hearts))
 | 
			
		||||
				{
 | 
			
		||||
					this.ThrowMetaIconF(this.pawn.Position, this.pawn.Map, FleckDefOf.Heart);
 | 
			
		||||
				}
 | 
			
		||||
				this.SexTick(this.pawn, this.Partner, true, true);
 | 
			
		||||
				SexUtility.reduce_rest(this.Partner, 1f);
 | 
			
		||||
				SexUtility.reduce_rest(this.pawn, 2f);
 | 
			
		||||
				if (this.ticks_left <= 0)
 | 
			
		||||
				{
 | 
			
		||||
					this.ReadyForNextToil();
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
			toil.AddFinishAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				this.End();
 | 
			
		||||
			});
 | 
			
		||||
			yield return toil;
 | 
			
		||||
			yield return new Toil
 | 
			
		||||
			{
 | 
			
		||||
				initAction = delegate ()
 | 
			
		||||
				{
 | 
			
		||||
					SexUtility.ProcessSex(this.Sexprops);
 | 
			
		||||
				},
 | 
			
		||||
				defaultCompleteMode = ToilCompleteMode.Instant
 | 
			
		||||
			};
 | 
			
		||||
			yield break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
using rjw;
 | 
			
		||||
using rjw.Modules.Interactions.Enums;
 | 
			
		||||
using rjw.Modules.Interactions.Helpers;
 | 
			
		||||
using rjw.Modules.Interactions.Objects;
 | 
			
		||||
using rjw.Modules.Interactions.Contexts;
 | 
			
		||||
using rjw.Modules.Interactions.Implementation;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	//Modified JobDriver_SexBaseRecieverLoved from rjw
 | 
			
		||||
	public class JobDriver_SexOnSpotReciever : JobDriver_SexBaseReciever
 | 
			
		||||
	{
 | 
			
		||||
		protected override IEnumerable<Toil> MakeNewToils()
 | 
			
		||||
		{
 | 
			
		||||
			base.setup_ticks();
 | 
			
		||||
			this.parteners.Add(base.Partner);
 | 
			
		||||
			if (this.pawn.relations.OpinionOf(base.Partner) < 0)
 | 
			
		||||
			{
 | 
			
		||||
				this.ticks_between_hearts += 50;
 | 
			
		||||
			}
 | 
			
		||||
			else if (this.pawn.relations.OpinionOf(base.Partner) > 60)
 | 
			
		||||
			{
 | 
			
		||||
				this.ticks_between_hearts -= 25;
 | 
			
		||||
			}
 | 
			
		||||
			this.FailOnDespawnedOrNull(this.iTarget);
 | 
			
		||||
			this.FailOn(() => !base.Partner.health.capacities.CanBeAwake);
 | 
			
		||||
			this.FailOn(() => this.pawn.Drafted);
 | 
			
		||||
			this.FailOn(() => base.Partner.Drafted);
 | 
			
		||||
			yield return Toils_Reserve.Reserve(this.iTarget, 1, 0, null);
 | 
			
		||||
			Toil toil2 = this.MakeSexToil();
 | 
			
		||||
			toil2.handlingFacing = false;
 | 
			
		||||
			yield return toil2;
 | 
			
		||||
			yield break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Token: 0x06000420 RID: 1056 RVA: 0x00024190 File Offset: 0x00022390
 | 
			
		||||
		private Toil MakeSexToil()
 | 
			
		||||
		{
 | 
			
		||||
			Toil toil = new Toil();
 | 
			
		||||
			toil.defaultCompleteMode = ToilCompleteMode.Never;
 | 
			
		||||
			toil.socialMode = RandomSocialMode.Off;
 | 
			
		||||
			toil.handlingFacing = true;
 | 
			
		||||
			toil.tickAction = delegate ()
 | 
			
		||||
			{
 | 
			
		||||
				if (this.pawn.IsHashIntervalTick(this.ticks_between_hearts))
 | 
			
		||||
				{
 | 
			
		||||
					base.ThrowMetaIconF(this.pawn.Position, this.pawn.Map, FleckDefOf.Heart);
 | 
			
		||||
				}
 | 
			
		||||
			};
 | 
			
		||||
			toil.AddEndCondition(delegate
 | 
			
		||||
			{
 | 
			
		||||
				if (this.parteners.Count <= 0)
 | 
			
		||||
				{
 | 
			
		||||
					return JobCondition.Succeeded;
 | 
			
		||||
				}
 | 
			
		||||
				return JobCondition.Ongoing;
 | 
			
		||||
			});
 | 
			
		||||
			toil.AddFinishAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				if (xxx.is_human(this.pawn))
 | 
			
		||||
				{
 | 
			
		||||
					this.pawn.Drawer.renderer.graphics.ResolveApparelGraphics();
 | 
			
		||||
				}
 | 
			
		||||
				GlobalTextureAtlasManager.TryMarkPawnFrameSetDirty(this.pawn);
 | 
			
		||||
				Hediff submitting = this.pawn.health.hediffSet.GetFirstHediffOfDef(xxx.submitting);
 | 
			
		||||
				if (submitting != null)
 | 
			
		||||
				{
 | 
			
		||||
					this.pawn.health.RemoveHediff(submitting);
 | 
			
		||||
					this.pawn.stances.stunner.StunFor(60, this.pawn, true, true);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
			toil.socialMode = RandomSocialMode.Off;
 | 
			
		||||
			return toil;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										87
									
								
								Source/Genes/Life_Force/JobGiver_GetLifeForce.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								Source/Genes/Life_Force/JobGiver_GetLifeForce.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,87 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    public class JobGiver_GetLifeForce : ThinkNode_JobGiver
 | 
			
		||||
	{
 | 
			
		||||
		protected override Job TryGiveJob(Pawn pawn)
 | 
			
		||||
		{
 | 
			
		||||
			Pawn_GeneTracker genes = pawn.genes;
 | 
			
		||||
			Gene_LifeForce gene_lifeforce = (genes != null) ? genes.GetFirstGeneOfType<Gene_LifeForce>() : null;
 | 
			
		||||
			if (gene_lifeforce == null)
 | 
			
		||||
			{
 | 
			
		||||
				return null;
 | 
			
		||||
			}
 | 
			
		||||
			if (!gene_lifeforce.ShouldConsumeLifeForceNow())
 | 
			
		||||
			{
 | 
			
		||||
				return null;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			if (ModsConfig.IsActive("LustLicentia.RJWLabs") && gene_lifeforce.StoredCumAllowed)
 | 
			
		||||
            {
 | 
			
		||||
				Thing gatheredCum = this.GetStoredCum(pawn);
 | 
			
		||||
				if (gatheredCum == null)
 | 
			
		||||
				{
 | 
			
		||||
					return null;
 | 
			
		||||
				}
 | 
			
		||||
				IngestionOutcomeDoer_LifeForceOffset ingestionOutcomeDoer = (IngestionOutcomeDoer_LifeForceOffset)gatheredCum.def.ingestible.outcomeDoers.First((IngestionOutcomeDoer x) => x is IngestionOutcomeDoer_LifeForceOffset);
 | 
			
		||||
				if (ingestionOutcomeDoer == null)
 | 
			
		||||
                {
 | 
			
		||||
					return null;
 | 
			
		||||
                }
 | 
			
		||||
				int num = Mathf.RoundToInt(((gene_lifeforce.targetValue - gene_lifeforce.Value) * 100 + 10) / ingestionOutcomeDoer.FertilinPerUnit);
 | 
			
		||||
				if (gatheredCum != null && num > 0)
 | 
			
		||||
				{
 | 
			
		||||
					Job job = JobMaker.MakeJob(RimWorld.JobDefOf.Ingest, gatheredCum);
 | 
			
		||||
					job.count = Mathf.Min(gatheredCum.stackCount, num);
 | 
			
		||||
					job.ingestTotalCount = true;
 | 
			
		||||
					return job;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//From JobGiver_GetHemogen, dont know exactly what this influences
 | 
			
		||||
		public override float GetPriority(Pawn pawn)
 | 
			
		||||
		{
 | 
			
		||||
			if (!ModsConfig.BiotechActive)
 | 
			
		||||
			{
 | 
			
		||||
				return 0f;
 | 
			
		||||
			}
 | 
			
		||||
			Pawn_GeneTracker genes = pawn.genes;
 | 
			
		||||
			if (((genes != null) ? genes.GetFirstGeneOfType<Gene_LifeForce>() : null) == null)
 | 
			
		||||
			{
 | 
			
		||||
				return 0f;
 | 
			
		||||
			}
 | 
			
		||||
			return 9.1f;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private Thing GetStoredCum(Pawn pawn)
 | 
			
		||||
		{
 | 
			
		||||
			Thing carriedThing = pawn.carryTracker.CarriedThing;
 | 
			
		||||
			ThingDef gatheredCum = ThingDef.Named("GatheredCum");
 | 
			
		||||
			if (carriedThing != null && carriedThing.def == gatheredCum)
 | 
			
		||||
			{
 | 
			
		||||
				return carriedThing;
 | 
			
		||||
			}
 | 
			
		||||
			for (int i = 0; i < pawn.inventory.innerContainer.Count; i++)
 | 
			
		||||
			{
 | 
			
		||||
				if (pawn.inventory.innerContainer[i].def == gatheredCum)
 | 
			
		||||
				{
 | 
			
		||||
					return pawn.inventory.innerContainer[i];
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, pawn.Map.listerThings.ThingsOfDef(gatheredCum), PathEndMode.OnCell, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false, false, false), 9999f, (Thing t) => pawn.CanReserve(t, 1, -1, null, false) && !t.IsForbidden(pawn), null);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								Source/Genes/Life_Force/JobGiver_LifeForce_RandomRape.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								Source/Genes/Life_Force/JobGiver_LifeForce_RandomRape.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    public class JobGiver_LifeForce_RandomRape : JobGiver_RandomRape
 | 
			
		||||
    {
 | 
			
		||||
		protected override Job TryGiveJob(Pawn pawn)
 | 
			
		||||
		{
 | 
			
		||||
			if (!can_rape(pawn, false))
 | 
			
		||||
			{
 | 
			
		||||
				return null;
 | 
			
		||||
			}
 | 
			
		||||
			Pawn pawn2 = this.find_victim(pawn, pawn.Map);
 | 
			
		||||
			if (pawn2 == null)
 | 
			
		||||
			{
 | 
			
		||||
				return null;
 | 
			
		||||
			}
 | 
			
		||||
			return JobMaker.MakeJob(JobDefOf.rjw_genes_lifeforce_randomrape, pawn2);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//same as xxx.canrape from rjw, but without last requirements.
 | 
			
		||||
		public static bool can_rape(Pawn pawn, bool forced = false)
 | 
			
		||||
		{
 | 
			
		||||
			return RJWSettings.rape_enabled && (xxx.is_mechanoid(pawn) || ((xxx.can_fuck(pawn) || 
 | 
			
		||||
				(!xxx.is_male(pawn) && xxx.get_vulnerability(pawn) < RJWSettings.nonFutaWomenRaping_MaxVulnerability && 
 | 
			
		||||
				xxx.can_be_fucked(pawn))) && (!xxx.is_human(pawn) || ((pawn.ageTracker.Growth >= 1f || pawn.ageTracker.CurLifeStage.reproductive)))));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								Source/Genes/Life_Force/LifeForceMentalBreakWorker.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								Source/Genes/Life_Force/LifeForceMentalBreakWorker.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    public class LifeForceMentalBreakWorker : MentalBreakWorker
 | 
			
		||||
	{
 | 
			
		||||
		public override bool BreakCanOccur(Pawn pawn)
 | 
			
		||||
		{
 | 
			
		||||
			if (pawn.Spawned && base.BreakCanOccur(pawn))
 | 
			
		||||
			{
 | 
			
		||||
				if (!GeneUtility.HasLifeForce(pawn))
 | 
			
		||||
                {
 | 
			
		||||
					return false;
 | 
			
		||||
                }
 | 
			
		||||
				Gene_LifeForce gene = pawn.genes.GetFirstGeneOfType<Gene_LifeForce>();
 | 
			
		||||
				if( gene.Resource.Value <= 0)
 | 
			
		||||
                {
 | 
			
		||||
					return true;
 | 
			
		||||
                }
 | 
			
		||||
			}
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								Source/Genes/Life_Force/LifeForceMentalState.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								Source/Genes/Life_Force/LifeForceMentalState.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
using System;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
using rjw;
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class LifeForceMentalState : MentalState
 | 
			
		||||
	{
 | 
			
		||||
		public override void MentalStateTick()
 | 
			
		||||
		{
 | 
			
		||||
			if (this.pawn.IsHashIntervalTick(150) && !GeneUtility.HasCriticalLifeForce(this.pawn))
 | 
			
		||||
			{
 | 
			
		||||
				Pawn_JobTracker jobs = this.pawn.jobs;
 | 
			
		||||
				if (!(((jobs != null) ? jobs.curDriver : null) is JobDriver_Sex))
 | 
			
		||||
				{
 | 
			
		||||
					base.RecoverFromState();
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			base.MentalStateTick();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								Source/Genes/Life_Force/LifeForceMentalStateWorker.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Source/Genes/Life_Force/LifeForceMentalStateWorker.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
using System;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
using rjw;
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class LifeForceMentalStateWorker : MentalStateWorker
 | 
			
		||||
	{
 | 
			
		||||
		public override bool StateCanOccur(Pawn pawn)
 | 
			
		||||
		{
 | 
			
		||||
			return base.StateCanOccur(pawn) && (xxx.is_human(pawn) && JobGiver_LifeForce_RandomRape.can_rape(pawn));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										180
									
								
								Source/Genes/Life_Force/Patch_LifeForce.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								Source/Genes/Life_Force/Patch_LifeForce.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,180 @@
 | 
			
		|||
using HarmonyLib;
 | 
			
		||||
using rjw;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(SexUtility), nameof(SexUtility.SatisfyPersonal))]
 | 
			
		||||
	public static class Patch_LifeForce
 | 
			
		||||
	{
 | 
			
		||||
		public static void Postfix(SexProps props)
 | 
			
		||||
		{
 | 
			
		||||
			// ShortCuts: Exit Early if Pawn or Partner are null (can happen with Animals or Masturbation)
 | 
			
		||||
			if (props.pawn == null || !props.hasPartner())
 | 
			
		||||
				return;
 | 
			
		||||
 | 
			
		||||
			// Exit if pawn has fertilin themself, it won't give any if it has lifeforce themself.
 | 
			
		||||
			if (GeneUtility.HasLifeForce(props.pawn))
 | 
			
		||||
			{
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			//Summary//
 | 
			
		||||
			//We use the positions of the pawn (dom or sub) and based on that which interactions will transfer fertilin 
 | 
			
		||||
			//By checking isreceiver we know if the succubus is the dom or the sub and if the situation is reverse we also swap the function we use
 | 
			
		||||
			//
 | 
			
		||||
			float absorb_factor = 0f;
 | 
			
		||||
			if (GeneUtility.HasLifeForce(props.partner))
 | 
			
		||||
			{
 | 
			
		||||
				Pawn succubus = props.partner;
 | 
			
		||||
 | 
			
		||||
				if (!props.isRevese)
 | 
			
		||||
				{
 | 
			
		||||
					if (props.isReceiver)
 | 
			
		||||
					{
 | 
			
		||||
						// Scenario Dom Succubus, normal
 | 
			
		||||
						absorb_factor = BaseDom(props, succubus);
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						// Scenario Sub Succubus, normal
 | 
			
		||||
						absorb_factor = BaseSub(props, succubus);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					if (props.isReceiver)
 | 
			
		||||
					{
 | 
			
		||||
						// Scenario Dom Succubus, Reverse
 | 
			
		||||
						absorb_factor = BaseSub(props, succubus);
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						// Scenario Sub Succubus, Reverse
 | 
			
		||||
						absorb_factor = BaseDom(props, succubus);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				//If we remove this check fertelin is always lost, but the succubus doesn't always gain any
 | 
			
		||||
				if (absorb_factor != 0f)
 | 
			
		||||
				{
 | 
			
		||||
					AbsorbFertilin(props, absorb_factor);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (GeneUtility.HasGeneNullCheck(succubus, GeneDefOf.rjw_genes_drainer) && !props.pawn.health.hediffSet.HasHediff(HediffDefOf.Succubus_Drained))
 | 
			
		||||
				{
 | 
			
		||||
					props.pawn.health.AddHediff(HediffDefOf.Succubus_Drained);
 | 
			
		||||
					GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(succubus), 0.25f);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public static void AbsorbFertilin(SexProps props, float absorb_factor = 1f)
 | 
			
		||||
		{
 | 
			
		||||
			Pawn_GeneTracker genes = props.partner.genes;
 | 
			
		||||
			Gene_LifeForce gene = genes.GetFirstGeneOfType<Gene_LifeForce>();
 | 
			
		||||
			Hediff fertilin_lost = props.pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Fertilin_Lost);
 | 
			
		||||
			//Around quarter get ejected everytime pawn cums
 | 
			
		||||
			float multiplier = Rand.Range(0.10f, 0.40f); 
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			//Create a new ferilin_lost hediff or reduce multiplier
 | 
			
		||||
			if (fertilin_lost == null)
 | 
			
		||||
			{
 | 
			
		||||
				Hediff new_fertilin_lost = HediffMaker.MakeHediff(HediffDefOf.Fertilin_Lost, props.pawn);
 | 
			
		||||
				props.pawn.health.AddHediff(new_fertilin_lost);
 | 
			
		||||
				new_fertilin_lost.Severity = multiplier;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				multiplier *= 1 - fertilin_lost.Severity;
 | 
			
		||||
				fertilin_lost.Severity += multiplier;
 | 
			
		||||
			}
 | 
			
		||||
			//More in the tank means more to give
 | 
			
		||||
			if (props.pawn.Has(Quirk.Messy))
 | 
			
		||||
			{
 | 
			
		||||
				multiplier *= 2;
 | 
			
		||||
			}
 | 
			
		||||
			//Currently taking the sum of all penises, maybe I should just consider one at random
 | 
			
		||||
			float valuechange = CumUtility.GetTotalFluidAmount(props.pawn) / 100 * absorb_factor * multiplier;
 | 
			
		||||
			GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(props.partner), valuechange);
 | 
			
		||||
			//gene.Resource.Value += CumUtility.GetTotalFluidAmount(props.pawn) / 100 * absorb_factor * multiplier;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		public static float BaseDom(SexProps props, Pawn succubus)
 | 
			
		||||
		{
 | 
			
		||||
			float absorb_factor = 0f;
 | 
			
		||||
			if (props.sexType == xxx.rjwSextype.Sixtynine)
 | 
			
		||||
			{
 | 
			
		||||
				absorb_factor += 1f;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
			else if (props.sexType == xxx.rjwSextype.Vaginal)
 | 
			
		||||
			{
 | 
			
		||||
				//with insertion absorbtion or vaginal cum absorbtion 
 | 
			
		||||
				//absorb_factor += 1f;
 | 
			
		||||
			}
 | 
			
		||||
			else if (props.sexType == xxx.rjwSextype.DoublePenetration)
 | 
			
		||||
			{
 | 
			
		||||
				if (GeneUtility.HasGeneNullCheck(succubus, GeneDefOf.rjw_genes_vaginal_absorber))
 | 
			
		||||
				{
 | 
			
		||||
					//with insertion absorbtion?
 | 
			
		||||
					//absorb_factor += 0.5f;
 | 
			
		||||
				}
 | 
			
		||||
				if (GeneUtility.HasGeneNullCheck(succubus, GeneDefOf.rjw_genes_anal_absorber))
 | 
			
		||||
				{
 | 
			
		||||
					//with insertion absorbtion?
 | 
			
		||||
					//absorb_factor += 0.5f;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (props.sexType == xxx.rjwSextype.Scissoring)
 | 
			
		||||
			{
 | 
			
		||||
				//with vaginal cum absorption && vaginal absorbtion
 | 
			
		||||
				//absorb_factor += 1f;
 | 
			
		||||
			}
 | 
			
		||||
			return absorb_factor;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static float BaseSub(SexProps props, Pawn succubus)
 | 
			
		||||
        {
 | 
			
		||||
			float absorb_factor = 0f;
 | 
			
		||||
			if (props.sexType == xxx.rjwSextype.Oral || props.sexType == xxx.rjwSextype.Fellatio || props.sexType == xxx.rjwSextype.Sixtynine)
 | 
			
		||||
			{
 | 
			
		||||
				absorb_factor += 1f;
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
			else if (props.sexType == xxx.rjwSextype.Vaginal && GeneUtility.HasGeneNullCheck(succubus, GeneDefOf.rjw_genes_vaginal_absorber))
 | 
			
		||||
			{
 | 
			
		||||
				absorb_factor += 1f;
 | 
			
		||||
			}
 | 
			
		||||
			else if (props.sexType == xxx.rjwSextype.Anal && GeneUtility.HasGeneNullCheck(succubus, GeneDefOf.rjw_genes_anal_absorber))
 | 
			
		||||
			{
 | 
			
		||||
				absorb_factor += 1f;
 | 
			
		||||
			}
 | 
			
		||||
			else if (props.sexType == xxx.rjwSextype.DoublePenetration)
 | 
			
		||||
			{
 | 
			
		||||
				if (GeneUtility.HasGeneNullCheck(succubus, GeneDefOf.rjw_genes_vaginal_absorber))
 | 
			
		||||
				{
 | 
			
		||||
					absorb_factor += 0.5f;
 | 
			
		||||
				}
 | 
			
		||||
				if (GeneUtility.HasGeneNullCheck(succubus, GeneDefOf.rjw_genes_anal_absorber))
 | 
			
		||||
				{
 | 
			
		||||
					absorb_factor += 0.5f;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (props.sexType == xxx.rjwSextype.Scissoring || props.sexType == xxx.rjwSextype.Cunnilingus)
 | 
			
		||||
			{
 | 
			
		||||
				//with vaginal cum absorbtion 
 | 
			
		||||
				//absorb_factor += 1f;
 | 
			
		||||
			}
 | 
			
		||||
			return absorb_factor;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										57
									
								
								Source/Genes/Life_Force/Patch_SexTicks_ChangePsyfocus.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								Source/Genes/Life_Force/Patch_SexTicks_ChangePsyfocus.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
using HarmonyLib;
 | 
			
		||||
using rjw;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	//[HarmonyPatch(typeof(JobDriver_Sex), nameof(JobDriver_Sex.ChangePsyfocus))]
 | 
			
		||||
	public static class Patch_SexTicks_ChangePsyfocus
 | 
			
		||||
	{
 | 
			
		||||
		//Using ChangePsyfocus as it is something that fires every 60 ticks
 | 
			
		||||
		public static void Postfix(ref JobDriver_Sex __instance, ref Pawn pawn, ref Thing target)
 | 
			
		||||
		{
 | 
			
		||||
			if (__instance.Sexprops.sexType == xxx.rjwSextype.Cunnilingus)
 | 
			
		||||
			{
 | 
			
		||||
				if (target != null)
 | 
			
		||||
				{
 | 
			
		||||
					Pawn pawn2 = target as Pawn;
 | 
			
		||||
					if (pawn2 != null)
 | 
			
		||||
					{
 | 
			
		||||
						//We need who the pawn on top is and if reverse we need to make the sub the pawn on top
 | 
			
		||||
						if (__instance.Sexprops.isRevese)
 | 
			
		||||
						{
 | 
			
		||||
							
 | 
			
		||||
							DrinkCumflation(pawn2, pawn);
 | 
			
		||||
						}
 | 
			
		||||
						else
 | 
			
		||||
						{
 | 
			
		||||
							//
 | 
			
		||||
							DrinkCumflation(pawn, pawn2);
 | 
			
		||||
							return;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void DrinkCumflation(Pawn dom, Pawn sub)
 | 
			
		||||
        {
 | 
			
		||||
			if (GeneUtility.HasLifeForce(sub) && dom.health.hediffSet.HasHediff(HediffDef.Named("Cumflation")))
 | 
			
		||||
			{
 | 
			
		||||
				Hediff cumflation = dom.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("Cumflation"));
 | 
			
		||||
				Gene_LifeForce gene_LifeForce = sub.genes.GetFirstGeneOfType<Gene_LifeForce>();
 | 
			
		||||
				cumflation.Severity -= 0.1f;
 | 
			
		||||
				gene_LifeForce.Resource.Value += 0.05f;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		//Maybe I can store gene and hediff so I dont need to look them up every time
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
using System;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class ThinkNode_ConditionalCritcalLifeForce : ThinkNode_Conditional
 | 
			
		||||
	{
 | 
			
		||||
		protected override bool Satisfied(Pawn p)
 | 
			
		||||
		{
 | 
			
		||||
			return GeneUtility.HasCriticalLifeForce(p);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								Source/Genes/Life_Force/ThinkNode_ConditionalLowLifeForce.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Source/Genes/Life_Force/ThinkNode_ConditionalLowLifeForce.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
using System;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class ThinkNode_ConditionalLowLifeForce : ThinkNode_Conditional
 | 
			
		||||
	{
 | 
			
		||||
		protected override bool Satisfied(Pawn p)
 | 
			
		||||
		{
 | 
			
		||||
			return GeneUtility.HasLowLifeForce(p);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -12,23 +12,31 @@ namespace RJW_Genes
 | 
			
		|||
{
 | 
			
		||||
    public class Gene_Aphrodisiac_Pheromones : Gene
 | 
			
		||||
    {   
 | 
			
		||||
 | 
			
		||||
        //Summary one every one check for all pawns nearby and in line of sight and add/renew a hediff which increases sexdrive for six hours.
 | 
			
		||||
        public override void Tick()
 | 
			
		||||
        {
 | 
			
		||||
            base.Tick();
 | 
			
		||||
            if (this.pawn.IsHashIntervalTick(2500))
 | 
			
		||||
            {
 | 
			
		||||
                foreach (Pawn pawn in this.AffectedPawns(this.pawn.Position, this.pawn.Map))
 | 
			
		||||
                { 
 | 
			
		||||
                    this.InduceAphrodisiac(pawn);
 | 
			
		||||
                }
 | 
			
		||||
                //Only spread pheromones if sexdrive above 1
 | 
			
		||||
                float sexfrequency = this.pawn.GetStatValue(StatDef.Named("SexFrequency"));
 | 
			
		||||
                if(sexfrequency > 1f)
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (Pawn pawn in this.AffectedPawns(this.pawn.Position, this.pawn.Map))
 | 
			
		||||
                    {
 | 
			
		||||
                        this.InduceAphrodisiac(pawn, sexfrequency);
 | 
			
		||||
                    }
 | 
			
		||||
                }               
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Creatus an IEnumerable of all pawns which are closeby and in lineofsight, self and other pawns with aphrodisiac pheromones gene are skipped.
 | 
			
		||||
        private IEnumerable<Pawn> AffectedPawns(IntVec3 pos, Map map)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (Pawn pawn in map.mapPawns.AllPawns)
 | 
			
		||||
            {
 | 
			
		||||
                if (pos.DistanceTo(pawn.Position) < 5)
 | 
			
		||||
                if (this.pawn != null && pawn != this.pawn && pos.DistanceTo(pawn.Position) < 5 && GenSight.LineOfSight(pos, pawn.Position, pawn.Map) && !GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_aphrodisiac_pheromones))
 | 
			
		||||
                {
 | 
			
		||||
                    yield return pawn;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -37,17 +45,36 @@ namespace RJW_Genes
 | 
			
		|||
            yield break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void InduceAphrodisiac(Pawn pawn)
 | 
			
		||||
        //Applies er renews a hediff which increases sexdrive for 6 hours
 | 
			
		||||
        private void InduceAphrodisiac(Pawn pawn, float sexfrequency)
 | 
			
		||||
        {
 | 
			
		||||
            Hediff hediff = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Aphrodisiac_Pheromone);
 | 
			
		||||
            
 | 
			
		||||
            if (hediff != null)
 | 
			
		||||
            {
 | 
			
		||||
                hediff.Severity = 1f;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                pawn.health.AddHediff(HediffDefOf.Aphrodisiac_Pheromone);
 | 
			
		||||
                Hediff aphrodisiac = HediffMaker.MakeHediff(HediffDefOf.Aphrodisiac_Pheromone, pawn);
 | 
			
		||||
                foreach (StatModifier stat in aphrodisiac.CurStage.statFactors)
 | 
			
		||||
                {
 | 
			
		||||
                    //Log.Message(pawn.Name.ToString());
 | 
			
		||||
                    //Log.Message(stat.stat.defName);
 | 
			
		||||
                    //Log.Message(stat.value.ToString());
 | 
			
		||||
                    if (stat.stat.defName == "SexFrequency")
 | 
			
		||||
                    {
 | 
			
		||||
                        stat.value = ModifySexfrequency(pawn, sexfrequency);
 | 
			
		||||
                        pawn.health.AddHediff(aphrodisiac);
 | 
			
		||||
                    }                    
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Function to modify aphrodisiac strength, currently has no effect, but it's an easy hook for other modders.
 | 
			
		||||
        public float ModifySexfrequency(Pawn pawn, float sexfrequency)
 | 
			
		||||
        {
 | 
			
		||||
            return sexfrequency;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,8 @@ namespace RJW_Genes
 | 
			
		|||
                        // Gene: Generous Donor [Postfix Patch]
 | 
			
		||||
                        harmony.Patch(AccessTools.Method(typeof(LicentiaLabs.CumflationHelper), nameof(LicentiaLabs.CumflationHelper.TransferNutrition)),
 | 
			
		||||
                            postfix: new HarmonyMethod(typeof(Patch_TransferNutrition), nameof(Patch_TransferNutrition.Postfix)));
 | 
			
		||||
                        harmony.Patch(AccessTools.Method(typeof(rjw.JobDriver_Sex), nameof(rjw.JobDriver_Sex.ChangePsyfocus)),
 | 
			
		||||
                            postfix: new HarmonyMethod(typeof(Patch_SexTicks_ChangePsyfocus), nameof(Patch_SexTicks_ChangePsyfocus.Postfix)));
 | 
			
		||||
                    }
 | 
			
		||||
                }))();
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,5 +12,7 @@ namespace RJW_Genes
 | 
			
		|||
    public static class HediffDefOf
 | 
			
		||||
    {
 | 
			
		||||
        public static readonly HediffDef Aphrodisiac_Pheromone;
 | 
			
		||||
        public static readonly HediffDef Fertilin_Lost;
 | 
			
		||||
        public static readonly HediffDef Succubus_Drained;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	public class CompAbility_SexInteractionRequirements : AbilityComp
 | 
			
		||||
	{
 | 
			
		||||
		public CompProperties_SexInteractionRequirements Props
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return (CompProperties_SexInteractionRequirements)this.props;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw;
 | 
			
		||||
using rjw.Modules.Interactions.Defs.DefFragment;
 | 
			
		||||
using rjw.Modules.Interactions.Enums;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    public class CompProperties_SexInteractionRequirements : AbilityCompProperties
 | 
			
		||||
    {
 | 
			
		||||
        public CompProperties_SexInteractionRequirements()
 | 
			
		||||
        {
 | 
			
		||||
            this.compClass = typeof(CompAbility_SexInteractionRequirements);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<InteractionTag> tags = new List<InteractionTag>();
 | 
			
		||||
        public InteractionRequirement dominantRequirement;
 | 
			
		||||
        public InteractionRequirement submissiveRequirement;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										146
									
								
								Source/Interactions/CustomSexInteraction_Helper.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								Source/Interactions/CustomSexInteraction_Helper.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,146 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw;
 | 
			
		||||
using rjw.Modules.Interactions.Objects;
 | 
			
		||||
using rjw.Modules.Interactions.Helpers;
 | 
			
		||||
using rjw.Modules.Interactions.Enums;
 | 
			
		||||
using rjw.Modules.Interactions.Implementation;
 | 
			
		||||
using rjw.Modules.Interactions.Defs.DefFragment;
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    public class CustomSexInteraction_Helper
 | 
			
		||||
    {
 | 
			
		||||
		public static List<InteractionDef> GenerateInteractionDefList(Pawn pawn, Pawn pawn2, CompProperties_SexInteractionRequirements sexpropsreq)
 | 
			
		||||
		{
 | 
			
		||||
			List<InteractionTag> tags = new List<InteractionTag>();
 | 
			
		||||
			if (pawn2.IsAnimal())
 | 
			
		||||
			{
 | 
			
		||||
				tags.Add(InteractionTag.Animal);
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				tags = sexpropsreq.tags;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			InteractionRequirement dominantRequirement = sexpropsreq.dominantRequirement;
 | 
			
		||||
			InteractionRequirement submissiveRequirement = sexpropsreq.submissiveRequirement;
 | 
			
		||||
			List<InteractionDef> list = new List<InteractionDef>();
 | 
			
		||||
			//List<InteractionDef> a = from interaction in sexinteractions
 | 
			
		||||
			//where InteractionHelper.GetWithExtension(interaction).DominantHasFamily(dominantRequirement.families.)
 | 
			
		||||
			//						 select interaction;
 | 
			
		||||
 | 
			
		||||
			//should use where select but dont fully understand that, so I am using this.
 | 
			
		||||
			foreach (InteractionDef interactionDef in SexUtility.SexInterractions)
 | 
			
		||||
			{
 | 
			
		||||
				//Use rjw function to check if the interaction would be valid
 | 
			
		||||
				if (!LewdInteractionValidatorService.Instance.IsValid(interactionDef, pawn, pawn2))
 | 
			
		||||
				{
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				InteractionWithExtension withExtension = InteractionHelper.GetWithExtension(interactionDef);
 | 
			
		||||
				bool add_interaction = false;
 | 
			
		||||
				//only add interactions which have a correct tag
 | 
			
		||||
				foreach (InteractionTag tag in tags)
 | 
			
		||||
				{
 | 
			
		||||
					if (withExtension.HasInteractionTag(tag))
 | 
			
		||||
					{
 | 
			
		||||
						add_interaction = true;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				//In case of failure go to next interaction
 | 
			
		||||
				if (!add_interaction)
 | 
			
		||||
				{
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				//goes to next interaction if it doesn't have the required genitals
 | 
			
		||||
				if (dominantRequirement != null)
 | 
			
		||||
				{
 | 
			
		||||
					foreach (GenitalFamily genitalFamily in dominantRequirement.families)
 | 
			
		||||
					{
 | 
			
		||||
						if (!withExtension.DominantHasFamily(genitalFamily))
 | 
			
		||||
						{
 | 
			
		||||
							add_interaction = false;
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					if (!add_interaction)
 | 
			
		||||
					{
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
					foreach (GenitalTag tag in dominantRequirement.tags)
 | 
			
		||||
					{
 | 
			
		||||
						if (!withExtension.DominantHasTag(tag))
 | 
			
		||||
						{
 | 
			
		||||
							add_interaction = false;
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				//goes to next interaction if it doesn't have the required genitals
 | 
			
		||||
				if (submissiveRequirement != null)
 | 
			
		||||
				{
 | 
			
		||||
					foreach (GenitalFamily genitalFamily in submissiveRequirement.families)
 | 
			
		||||
					{
 | 
			
		||||
						if (!withExtension.SubmissiveHasFamily(genitalFamily))
 | 
			
		||||
						{
 | 
			
		||||
							add_interaction = false;
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					if (!add_interaction)
 | 
			
		||||
					{
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
					foreach (GenitalTag tag in submissiveRequirement.tags)
 | 
			
		||||
					{
 | 
			
		||||
						if (!withExtension.SubmissiveHasTag(tag))
 | 
			
		||||
						{
 | 
			
		||||
							add_interaction = false;
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (add_interaction)
 | 
			
		||||
				{
 | 
			
		||||
					list.Add(interactionDef);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
			return list;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//Generates a valid interaction for the requirements and assigns sexprops based on that
 | 
			
		||||
		public static SexProps GenerateSexProps(Pawn pawn, Pawn pawn2, CompProperties_SexInteractionRequirements sexpropsreq)
 | 
			
		||||
		{
 | 
			
		||||
			List<InteractionDef> interactionlist = GenerateInteractionDefList(pawn, pawn2, sexpropsreq);
 | 
			
		||||
			if (!interactionlist.Any())
 | 
			
		||||
			{
 | 
			
		||||
				return null;
 | 
			
		||||
			}
 | 
			
		||||
			InteractionDef dictionaryKey = interactionlist.RandomElement();
 | 
			
		||||
			bool rape = InteractionHelper.GetWithExtension(dictionaryKey).HasInteractionTag(InteractionTag.Rape);
 | 
			
		||||
			SexProps sexProps = new SexProps();
 | 
			
		||||
			sexProps.pawn = pawn;
 | 
			
		||||
			sexProps.partner = pawn2;
 | 
			
		||||
			sexProps.sexType = SexUtility.rjwSextypeGet(dictionaryKey);
 | 
			
		||||
			sexProps.isRape = rape;
 | 
			
		||||
			sexProps.isRapist = rape;
 | 
			
		||||
			sexProps.canBeGuilty = false;
 | 
			
		||||
			sexProps.dictionaryKey = dictionaryKey;
 | 
			
		||||
			sexProps.rulePack = SexUtility.SexRulePackGet(dictionaryKey);
 | 
			
		||||
			return sexProps;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,52 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw.Modules.Interactions;
 | 
			
		||||
using rjw.Modules.Interactions.Internals.Implementation;
 | 
			
		||||
using rjw.Modules.Interactions.Objects;
 | 
			
		||||
using rjw;
 | 
			
		||||
using rjw.Modules.Interactions.Enums;
 | 
			
		||||
 | 
			
		||||
//Modefied code based of RJW-AI code at https://gitgud.io/Ed86/rjw-ia/-/tree/master/
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	[StaticConstructorOnStartup]
 | 
			
		||||
	public class DomSuccubusTailCustomRequirementHandler : ICustomRequirementHandler
 | 
			
		||||
	{
 | 
			
		||||
		public string HandlerKey
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return "DomSuccubusTailCustomRequirementHandler";
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
		static DomSuccubusTailCustomRequirementHandler()
 | 
			
		||||
		{
 | 
			
		||||
			Register();
 | 
			
		||||
		}
 | 
			
		||||
		public static void Register()
 | 
			
		||||
		{
 | 
			
		||||
			InteractionRequirementService.CustomRequirementHandlers.Add(new DomSuccubusTailCustomRequirementHandler());
 | 
			
		||||
			if (Prefs.DevMode)
 | 
			
		||||
			{
 | 
			
		||||
				Log.Message("DomSuccubusTailCustomRequirementHandler registered: ");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool FufillRequirements(InteractionWithExtension interaction, InteractionPawn dominant, InteractionPawn submissive)
 | 
			
		||||
		{
 | 
			
		||||
			if (GeneUtility.HasGeneNullCheck(dominant.Pawn, GeneDefOf.rjw_genes_succubus_tail))
 | 
			
		||||
            {
 | 
			
		||||
				return true;
 | 
			
		||||
            }
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		//public static readonly StringListDef filter = DefDatabase<StringListDef>.GetNamed("DomSuccubusTailFilter");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								Source/Interactions/GenesPartKindUsageRule.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								Source/Interactions/GenesPartKindUsageRule.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using rjw;
 | 
			
		||||
using rjw.Modules.Interactions.Contexts;
 | 
			
		||||
using rjw.Modules.Interactions.Enums;
 | 
			
		||||
using rjw.Modules.Interactions.Rules.PartKindUsageRules;
 | 
			
		||||
using rjw.Modules.Shared;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace RJW_Genes.Interactions
 | 
			
		||||
{
 | 
			
		||||
	//Summary//
 | 
			
		||||
	//Set custom preferences for pawn. Gets integrated to rjw by AddtoIPartPreferenceRule in First
 | 
			
		||||
	//Depending on the level of lifeforce increase the chance for using the mouth.
 | 
			
		||||
	public class GenesPartKindUsageRule : IPartPreferenceRule
 | 
			
		||||
    {
 | 
			
		||||
		public IEnumerable<Weighted<LewdablePartKind>> ModifiersForDominant(InteractionContext context)
 | 
			
		||||
		{
 | 
			
		||||
			Pawn pawn = context.Internals.Dominant.Pawn;
 | 
			
		||||
			if (GeneUtility.HasCriticalLifeForce(pawn))
 | 
			
		||||
			{
 | 
			
		||||
				yield return new Weighted<LewdablePartKind>(50f, LewdablePartKind.Mouth);
 | 
			
		||||
			}
 | 
			
		||||
			else if (GeneUtility.HasLowLifeForce(pawn))
 | 
			
		||||
			{
 | 
			
		||||
				yield return new Weighted<LewdablePartKind>(10f, LewdablePartKind.Mouth);
 | 
			
		||||
			}
 | 
			
		||||
			else if (GeneUtility.HasLifeForce(pawn))
 | 
			
		||||
			{
 | 
			
		||||
				yield return new Weighted<LewdablePartKind>(2f, LewdablePartKind.Mouth);
 | 
			
		||||
			}
 | 
			
		||||
			yield break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IEnumerable<Weighted<LewdablePartKind>> ModifiersForSubmissive(InteractionContext context)
 | 
			
		||||
		{
 | 
			
		||||
			Pawn pawn = context.Internals.Submissive.Pawn;
 | 
			
		||||
			if (GeneUtility.HasCriticalLifeForce(pawn))
 | 
			
		||||
			{
 | 
			
		||||
				yield return new Weighted<LewdablePartKind>(50f, LewdablePartKind.Mouth);
 | 
			
		||||
			}
 | 
			
		||||
			else if (GeneUtility.HasLowLifeForce(pawn))
 | 
			
		||||
			{
 | 
			
		||||
				yield return new Weighted<LewdablePartKind>(10f, LewdablePartKind.Mouth);
 | 
			
		||||
			}
 | 
			
		||||
			else if (GeneUtility.HasLifeForce(pawn))
 | 
			
		||||
			{
 | 
			
		||||
				yield return new Weighted<LewdablePartKind>(2f, LewdablePartKind.Mouth);
 | 
			
		||||
			}
 | 
			
		||||
			yield break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,52 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using rjw.Modules.Interactions;
 | 
			
		||||
using rjw.Modules.Interactions.Internals.Implementation;
 | 
			
		||||
using rjw.Modules.Interactions.Objects;
 | 
			
		||||
using rjw;
 | 
			
		||||
using rjw.Modules.Interactions.Enums;
 | 
			
		||||
 | 
			
		||||
//Modefied code based of RJW-AI code at https://gitgud.io/Ed86/rjw-ia/-/tree/master/
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	[StaticConstructorOnStartup]
 | 
			
		||||
	public class SubSuccubusTailCustomRequirementHandler : ICustomRequirementHandler
 | 
			
		||||
	{
 | 
			
		||||
		public string HandlerKey
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return "SubSuccubusTailCustomRequirementHandler";
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
		static SubSuccubusTailCustomRequirementHandler()
 | 
			
		||||
		{
 | 
			
		||||
			Register();
 | 
			
		||||
		}
 | 
			
		||||
		public static void Register()
 | 
			
		||||
		{
 | 
			
		||||
			InteractionRequirementService.CustomRequirementHandlers.Add(new SubSuccubusTailCustomRequirementHandler());
 | 
			
		||||
			if (Prefs.DevMode)
 | 
			
		||||
			{
 | 
			
		||||
				Log.Message("SubSuccubusTailCustomRequirementHandler registered: ");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool FufillRequirements(InteractionWithExtension interaction, InteractionPawn dominant, InteractionPawn submissive)
 | 
			
		||||
		{
 | 
			
		||||
			if (GeneUtility.HasGeneNullCheck(submissive.Pawn, GeneDefOf.rjw_genes_succubus_tail))
 | 
			
		||||
            {
 | 
			
		||||
				return true;
 | 
			
		||||
            }
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		//public static readonly StringListDef filter = DefDatabase<StringListDef>.GetNamed("SubSuccubusTailFilter");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								Source/JobDefOf.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								Source/JobDefOf.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
    [DefOf]
 | 
			
		||||
    public static class JobDefOf
 | 
			
		||||
    {
 | 
			
		||||
        public static readonly JobDef rjw_genes_lifeforce_randomrape;
 | 
			
		||||
        public static readonly JobDef rjw_genes_lifeforce_seduced;
 | 
			
		||||
        public static readonly JobDef sex_on_spot;
 | 
			
		||||
        public static readonly JobDef sex_on_spot_reciever;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -27,14 +27,14 @@
 | 
			
		|||
      <Private>False</Private>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Assembly-CSharp">
 | 
			
		||||
      <HintPath>..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll</HintPath>
 | 
			
		||||
      <HintPath>..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\RimWorld\RimWorldWin64_Data\Managed\Assembly-CSharp.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="LicentiaLabs">
 | 
			
		||||
      <HintPath>..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\RimWorld\Mods\licentia-labs-master\Assemblies\LicentiaLabs.dll</HintPath>
 | 
			
		||||
      <Private>False</Private>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="RJW">
 | 
			
		||||
      <HintPath>..\..\rjw\1.4\Assemblies\RJW.dll</HintPath>
 | 
			
		||||
      <HintPath>..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\RimWorld\Mods\rjw-master\1.4\Assemblies\RJW.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="System" />
 | 
			
		||||
    <Reference Include="System.Core" />
 | 
			
		||||
| 
						 | 
				
			
			@ -49,11 +49,11 @@
 | 
			
		|||
    <None Include="..\Common\Languages\**" />
 | 
			
		||||
    <None Include="..\Common\Patches\**" />
 | 
			
		||||
    <Reference Include="UnityEngine">
 | 
			
		||||
      <HintPath>..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll</HintPath>
 | 
			
		||||
      <HintPath>..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\RimWorld\RimWorldWin64_Data\Managed\UnityEngine.dll</HintPath>
 | 
			
		||||
      <Private>False</Private>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="UnityEngine.CoreModule">
 | 
			
		||||
      <HintPath>..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
 | 
			
		||||
      <HintPath>..\..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\RimWorld\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="UnityEngine.IMGUIModule">
 | 
			
		||||
      <HintPath>..\..\..\RimWorldWin64_Data\Managed\UnityEngine.IMGUIModule.dll</HintPath>
 | 
			
		||||
| 
						 | 
				
			
			@ -117,19 +117,59 @@
 | 
			
		|||
    <Compile Include="Genes\Genitalia\Gene_DemonicGenitalia.cs" />
 | 
			
		||||
    <Compile Include="Genes\Genitalia\Gene_EquineGenitalia.cs" />
 | 
			
		||||
    <Compile Include="Genes\Genitalia\GenitaliaChanger.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Abilities\AbilityUtility.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Alert_LowFertilin.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Abilities\CompAbilityEffect_Seduce.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Abilities\CompAbilityEffect_LifeForceCost.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Abilities\CompAbilityEffect_CockEater.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Abilities\CompProperties_Seduce.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Abilities\CompProperties_AbilityCockEater.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Gene_LifeForceDrain.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\IngestionOutcomeDoer_LifeForceOffset.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\JobDrivers\JobDriver_SexOnSpotReceiver.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\JobDrivers\JobDriver_SexOnSpot.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\JobDrivers\JobDriver_Seduced.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Patch_SexTicks_ChangePsyfocus.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\ThinkNode_ConditionalLowLifeForce.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\ThinkNode_ConditionalCritcalLifeForce.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\JobGiver_GetLifeForce.cs" />
 | 
			
		||||
    <Compile Include="Genes\Damage\Gene_Unbreakable.cs" />
 | 
			
		||||
    <Compile Include="Genes\Special\Patch_AgeDrain.cs" />
 | 
			
		||||
    <Compile Include="Genes\Special\Patch_Youth_Fountain.cs" />
 | 
			
		||||
    <Compile Include="Interactions\CompAbility_SexInteractionRequirements.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Abilities\CompAbilityEffect_PussyHeal.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Abilities\CompProperties_AbilityLifeForceCost.cs" />
 | 
			
		||||
    <Compile Include="Interactions\CompProperties_SexInteractionRequirements.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Abilities\CompProperties_AbilityPussyHeal.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\GeneGizmo_ResourceLifeForce.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\HediffWithComps_tank.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\JobDrivers\JobDriver_CastAbilityAfterSex.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\LifeForceMentalState.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\LifeForceMentalStateWorker.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\JobGiver_LifeForce_RandomRape.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\LifeForceMentalBreakWorker.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Gene_LifeForce.cs" />
 | 
			
		||||
    <Compile Include="Genes\RJW_Gene.cs" />
 | 
			
		||||
    <Compile Include="Genes\Genitalia\GenitaliaUtility.cs" />
 | 
			
		||||
    <Compile Include="Genes\Special\Gene_Aphrodisiac_Pheromones_.cs" />
 | 
			
		||||
    <Compile Include="Genes\Special\Patch_AgeDrain.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\Patch_LifeForce.cs" />
 | 
			
		||||
    <Compile Include="Genes\Special\Patch_OrgasmRush.cs" />
 | 
			
		||||
    <Compile Include="Genes\Special\Patch_Youth_Fountain.cs" />
 | 
			
		||||
    <Compile Include="HarmonyInit.cs" />
 | 
			
		||||
    <Compile Include="HediffDefOf.cs" />
 | 
			
		||||
    <Compile Include="Interactions\CustomSexInteraction_Helper.cs" />
 | 
			
		||||
    <Compile Include="Interactions\GenesPartKindUsageRule.cs" />
 | 
			
		||||
    <Compile Include="Interactions\SubSuccubusTailCustomRequirementHandler - Copy.cs" />
 | 
			
		||||
    <Compile Include="Interactions\DomSuccubusTailCustomRequirementHandler.cs" />
 | 
			
		||||
    <Compile Include="JobDefOf.cs" />
 | 
			
		||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
			
		||||
    <Compile Include="RJW_Genes.cs" />
 | 
			
		||||
    <Compile Include="ThoughtDefOf.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Content Include="GeneDefs_GenitaliaTypeEndogenes.xml" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup />
 | 
			
		||||
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										17
									
								
								Source/ThoughtDefOf.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Source/ThoughtDefOf.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
namespace RJW_Genes
 | 
			
		||||
{
 | 
			
		||||
	[DefOf]
 | 
			
		||||
	public static class ThoughtDefOf
 | 
			
		||||
    {
 | 
			
		||||
        public static readonly ThoughtDef rjw_genes_cock_eaten;
 | 
			
		||||
        public static readonly ThoughtDef rjw_genes_seduced;
 | 
			
		||||
        public static readonly ThoughtDef rjw_critical_fertilin;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue