mirror of
				https://github.com/vegapnk/RJW-Genes.git
				synced 2024-08-15 00:23:31 +00:00 
			
		
		
		
	Pawns will now seek for hemogen when below target
- Made a jobgiver similar to Jobgiver GetHemogen - currently only job is to eat cum from sexperience - other thinks are done via thinktree - Made thinknodes and thinktrees so that a succubus will seek sex when below target value and try and rape when critically low.
This commit is contained in:
		
							parent
							
								
									2a124bfbb9
								
							
						
					
					
						commit
						5555083bc2
					
				
					 11 changed files with 362 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -60,6 +60,8 @@ namespace RJW_Genes
 | 
			
		|||
			//GeneResourceDrainUtility.TickResourceDrain(this);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool StoredCumAllowed = true;
 | 
			
		||||
 | 
			
		||||
		public Gene_Resource Resource
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										131
									
								
								Source/Genes/Life_Force/JobDriver_Drink_Cumflation.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								Source/Genes/Life_Force/JobDriver_Drink_Cumflation.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,131 @@
 | 
			
		|||
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_DrinkCumflation : JobDriver_SexBaseInitiator
 | 
			
		||||
	{
 | 
			
		||||
		//Summary//
 | 
			
		||||
		//WIP is for custom interaction
 | 
			
		||||
		protected override IEnumerable<Toil> MakeNewToils()
 | 
			
		||||
		{
 | 
			
		||||
			base.setup_ticks();
 | 
			
		||||
			this.rape = !LovePartnerRelationUtility.LovePartnerRelationExists(this.pawn, this.Partner);
 | 
			
		||||
			JobDef PartnerJob =  rape? xxx.gettin_raped: xxx.getting_quickie;
 | 
			
		||||
			this.FailOnDestroyedNullOrForbidden(TargetIndex.A);
 | 
			
		||||
			this.FailOnSomeonePhysicallyInteracting(TargetIndex.A);
 | 
			
		||||
			this.FailOn(() => this.pawn.Drafted);
 | 
			
		||||
			this.FailOn(() => this.pawn.IsFighting());
 | 
			
		||||
			this.FailOn(() => this.Partner.IsFighting());
 | 
			
		||||
			yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch);
 | 
			
		||||
			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.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.SetInteraction();
 | 
			
		||||
				this.cumflation = this.Partner.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("Cumflation"));
 | 
			
		||||
				this.gene_LifeForce = (this.pawn.genes != null) ? this.pawn.genes.GetFirstGeneOfType<Gene_LifeForce>() : null;
 | 
			
		||||
				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;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Reduce_Cumflation()
 | 
			
		||||
        {
 | 
			
		||||
			this.reductiontick--;
 | 
			
		||||
			if (reductiontick <= 0)
 | 
			
		||||
            {
 | 
			
		||||
				if (this.cumflation != null && this.gene_LifeForce != null)
 | 
			
		||||
				{
 | 
			
		||||
					this.cumflation.Severity =+ 0.01f;
 | 
			
		||||
					gene_LifeForce.Resource.Value += 0.01f;
 | 
			
		||||
				}
 | 
			
		||||
				this.reductiontick = 60;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
		public override bool TryMakePreToilReservations(bool errorOnFailed)
 | 
			
		||||
		{
 | 
			
		||||
			return this.pawn.Reserve(this.job.GetTarget(TargetIndex.A), this.job, 1, -1, null, errorOnFailed);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void SetInteraction()
 | 
			
		||||
		{
 | 
			
		||||
			InteractionDef interaction = rape ? DefDatabase<InteractionDef>.GetNamed("Rape_Reverse_Cunnilingus") : DefDatabase<InteractionDef>.GetNamed("Sex_Reverse_Cunnilingus");
 | 
			
		||||
 | 
			
		||||
			SpecificInteractionInputs inputs = new SpecificInteractionInputs
 | 
			
		||||
			{
 | 
			
		||||
				Initiator = this.pawn,
 | 
			
		||||
				Partner = this.Partner,
 | 
			
		||||
				Interaction = interaction
 | 
			
		||||
			};
 | 
			
		||||
			InteractionOutputs interactionOutputs = SpecificLewdInteractionService.Instance.GenerateSpecificInteraction(inputs);
 | 
			
		||||
			this.Sexprops.sexType = interactionOutputs.Generated.RjwSexType;
 | 
			
		||||
			this.Sexprops.rulePack = interactionOutputs.Generated.RulePack.defName;
 | 
			
		||||
			this.Sexprops.dictionaryKey = interaction;
 | 
			
		||||
			this.Sexprops.isRapist = rape;
 | 
			
		||||
			this.Sexprops.isWhoring = false;
 | 
			
		||||
			this.Sexprops.isRevese = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Hediff cumflation;
 | 
			
		||||
		public Gene_LifeForce gene_LifeForce;
 | 
			
		||||
		int reductiontick = 60; 
 | 
			
		||||
		bool rape = false; 
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										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);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								Source/Genes/Life_Force/Patch_SexTicks_ChangePsyfocus.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								Source/Genes/Life_Force/Patch_SexTicks_ChangePsyfocus.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
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)
 | 
			
		||||
        {
 | 
			
		||||
			Log.Message("Firese");
 | 
			
		||||
			Log.Message(dom.Name.ToString());
 | 
			
		||||
			Log.Message(sub.Name.ToString());
 | 
			
		||||
			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 instance 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);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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)));
 | 
			
		||||
                    }
 | 
			
		||||
                }))();
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,6 @@ namespace RJW_Genes
 | 
			
		|||
 | 
			
		||||
			InteractionRequirement dominantRequirement = sexpropsreq.dominantRequirement;
 | 
			
		||||
			InteractionRequirement submissiveRequirement = sexpropsreq.submissiveRequirement;
 | 
			
		||||
			List<InteractionDef> sexinteractions = SexUtility.SexInterractions;
 | 
			
		||||
			List<InteractionDef> list = new List<InteractionDef>();
 | 
			
		||||
			//List<InteractionDef> a = from interaction in sexinteractions
 | 
			
		||||
			//where InteractionHelper.GetWithExtension(interaction).DominantHasFamily(dominantRequirement.families.)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -119,6 +119,11 @@
 | 
			
		|||
    <Compile Include="Genes\Life_Force\CompAbilityEffect_CockEater.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\CompProperties_AbilityCockEater.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\IngestionOutcomeDoer_LifeForceOffset.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\JobDriver_Drink_Cumflation.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="Interactions\CompAbility_SexInteractionRequirements.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\CompAbilityEffect_PussyHeal.cs" />
 | 
			
		||||
    <Compile Include="Genes\Life_Force\CompProperties_AbilityLifeForceCost.cs" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue