+
+
+ Tailbone
+
+
+
+
+ rjw_genes_Succubus_Wings
+
+ Carriers of this gene grow succubus wings.
+ UI/Icons/Genes/Gene_TailFurry
+ (0.75, 0.75, 0.75)
+ 1000
+ 1
+
+ Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Wings/Succubus_Wings
+ Hair
+ 2
+ (0.0, 0.19, -0.1)
+ (0.0, 0.0, -0.1)
+ (0.1, 0.0, 0.0)
+
+
+
\ No newline at end of file
diff --git a/Common/Defs/Genes/GeneDefs_LifeForce.xml b/Common/Defs/Genes/GeneDefs_LifeForce.xml
new file mode 100644
index 0000000..1428ec2
--- /dev/null
+++ b/Common/Defs/Genes/GeneDefs_LifeForce.xml
@@ -0,0 +1,36 @@
+
+
+
+ rjw_genes_lifeforce
+
+ Carriers of this gene have a reserve of biological strength powered by a resource called lifeforce. The resource can be gained and spent in various ways, all of which are unlocked by other genes.\n\nCarriers lose 10 lifeforce per day from biological entropy.
+ RJW_Genes.Gene_LifeForce
+ RJW_Genes.GeneGizmo_ResourceLifeForce
+ lifeforce
+
+
0.25
+
0.5
+
0.75
+
+ true
+ true
+ A reserve of biological strength which can be gained and spent in a variety of ways. \n\nLifeforce can be increased by absorbing cum, typically through oral sex or stored cum. \n\nIf lifeforce reaches zero, {PAWN_nameDef} will become very unhappy and may try to obtain some forcefully.
+ UI/Icons/Genes/Gene_Hemogenic
+ 0
+ Hemogen
+ -2
+
+
Gives lifeforce supply.
+
+
+
+
hemo
+
+
+ rjw_genes_lifeforce_randomrape
+ 13
+ 0.02
+ 1
+ 1
+
+
\ No newline at end of file
diff --git a/Common/Defs/JobDefs/Jobs_LifeForce.xml b/Common/Defs/JobDefs/Jobs_LifeForce.xml
new file mode 100644
index 0000000..274ade7
--- /dev/null
+++ b/Common/Defs/JobDefs/Jobs_LifeForce.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ rjw_genes_lifeforce_randomrape
+ rjw.JobDriver_RandomRape
+ Raping
+ false
+
+
\ No newline at end of file
diff --git a/Common/Defs/MentalStateDefs/MentalState_Lifeforce.xml b/Common/Defs/MentalStateDefs/MentalState_Lifeforce.xml
new file mode 100644
index 0000000..1da6e15
--- /dev/null
+++ b/Common/Defs/MentalStateDefs/MentalState_Lifeforce.xml
@@ -0,0 +1,30 @@
+
+
+
+
+ rjw_genes_lifeforce_randomrape
+ rjw_genes_lifeforce_randomrape
+ 1.5
+ Extreme
+
+
+
+ rjw_genes_lifeforce_randomrape
+ RJW_Genes.LifeForceMentalState
+ RJW_Genes.LifeForceMentalStateWorker
+
+ Malicious
+ true
+ false
+ 30000
+ 0.8
+ 80000
+ (0.5, 0.9, 0.5)
+ random rape
+ {0} has run out of lifeforce and is looking to obtain some.
+ ThreatSmall
+ {0} is no longer raping randomly.
+ Mental state: Random Rape
+ true
+
+
\ No newline at end of file
diff --git a/Common/Patches/ThinkTree/MentalStateCritical_LifeForceRandomRape.xml b/Common/Patches/ThinkTree/MentalStateCritical_LifeForceRandomRape.xml
new file mode 100644
index 0000000..9532df8
--- /dev/null
+++ b/Common/Patches/ThinkTree/MentalStateCritical_LifeForceRandomRape.xml
@@ -0,0 +1,35 @@
+
+
+
+
+ Defs/ThinkTreeDef[defName="MentalStateCritical"]/thinkRoot[@Class="ThinkNode_Tagger"]/subNodes
+
+
+ rjw_genes_lifeforce_randomrape
+
+
+ Rest
+ 0.05
+ true
+
+
+
+
+
+ 0.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Common/Textures/Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Wings/Succubus_Wings_east.png b/Common/Textures/Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Wings/Succubus_Wings_east.png
new file mode 100644
index 0000000..19ecc3e
Binary files /dev/null and b/Common/Textures/Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Wings/Succubus_Wings_east.png differ
diff --git a/Common/Textures/Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Wings/Succubus_Wings_north.png b/Common/Textures/Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Wings/Succubus_Wings_north.png
new file mode 100644
index 0000000..92c4a01
Binary files /dev/null and b/Common/Textures/Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Wings/Succubus_Wings_north.png differ
diff --git a/Common/Textures/Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Wings/Succubus_Wings_south.png b/Common/Textures/Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Wings/Succubus_Wings_south.png
new file mode 100644
index 0000000..92c4a01
Binary files /dev/null and b/Common/Textures/Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Wings/Succubus_Wings_south.png differ
diff --git a/Rjw-Genes.sln b/Rjw-Genes.sln
index 858f9a2..3706653 100644
--- a/Rjw-Genes.sln
+++ b/Rjw-Genes.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 17.0.32014.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rjw-Genes", "Source\Rjw-Genes.csproj", "{D7D21B4A-1DA7-41D8-B202-C58CA8FA62AA}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FB09ADF4-FC35-4C1F-9135-2B4C4E4ED347}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
diff --git a/Source/Animal_Inheritance/First.cs b/Source/Animal_Inheritance/First.cs
deleted file mode 100644
index 8194ab3..0000000
--- a/Source/Animal_Inheritance/First.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using rjw;
-using Verse;
-using RimWorld;
-
-namespace RJW_BGS
-{
- [StaticConstructorOnStartup]
- internal static class First
- {
- static First()
- {
- //RJWcopy.Racegroupdictbuilder();
- //Prints all found race dicts (debugging only)
- //logAllFoundRaceGroupGenes
-
- }
-
- private static void logAllFoundRaceGroupGenes()
- {
- foreach (RaceGroupDef def in DefDatabase.AllDefs)
- {
- Log.Message("defName = " + def.defName);
- if (def.raceNames != null)
- {
- foreach (string race in def.raceNames)
- {
- Log.Message(race);
- }
- }
- }
- }
- }
-}
diff --git a/Source/First.cs b/Source/First.cs
new file mode 100644
index 0000000..aa366ab
--- /dev/null
+++ b/Source/First.cs
@@ -0,0 +1,29 @@
+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
+ private static void AddtoIPartPreferenceRule()
+ {
+ List partPreferenceRules = Unprivater.GetProtectedValue>("_partKindUsageRules", typeof(PartPreferenceDetectorService));
+ partPreferenceRules.Add(new Interactions.GenesPartKindUsageRule());
+ }
+ }
+}
diff --git a/Source/GeneDefOf.cs b/Source/GeneDefOf.cs
index e592100..726bb53 100644
--- a/Source/GeneDefOf.cs
+++ b/Source/GeneDefOf.cs
@@ -71,5 +71,8 @@ namespace RJW_Genes
// Special
public static readonly GeneDef rjw_genes_orgasm_rush;
public static readonly GeneDef rjw_genes_aphrodisiac_pheromones;
+
+ // LifeForce
+ public static readonly GeneDef rjw_genes_lifeforce;
}
}
diff --git a/Source/Genes/Cum/CumUtility.cs b/Source/Genes/Cum/CumUtility.cs
index ea049cc..9ad535a 100644
--- a/Source/Genes/Cum/CumUtility.cs
+++ b/Source/Genes/Cum/CumUtility.cs
@@ -33,5 +33,35 @@ namespace RJW_Genes
}
}
+
+ //Get total fluidamount a persom 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();
+ if (CompHediff != null)
+ {
+ total_cum += CompHediff.FluidAmmount * multiplier;
+ }
+ }
+ }
+
+ }
+ return total_cum;
+
+ }
}
}
diff --git a/Source/Genes/GeneUtility.cs b/Source/Genes/GeneUtility.cs
index ce022ba..3bea9a6 100644
--- a/Source/Genes/GeneUtility.cs
+++ b/Source/Genes/GeneUtility.cs
@@ -14,6 +14,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();
+ 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();
+ if (gene.Resource.Value < gene.MinLevelForAlert)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
public static bool IsInsectIncubator(Pawn pawn)
{
if (pawn.genes == null)
diff --git a/Source/Genes/Life_Force/GeneGizmo_ResourceLifeForce.cs b/Source/Genes/Life_Force/GeneGizmo_ResourceLifeForce.cs
new file mode 100644
index 0000000..1dee43d
--- /dev/null
+++ b/Source/Genes/Life_Force/GeneGizmo_ResourceLifeForce.cs
@@ -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 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 += "NeverConsumeCum";
+ }
+ else
+ {
+ text = text + ("ConsumeCumBelow" + ": ") + this.gene.PostProcessValue(this.gene.targetValue);
+ }
+ }
+ if (!this.drainGenes.NullOrEmpty())
+ {
+ float num = 0f;
+ foreach (IGeneResourceDrain geneResourceDrain in this.drainGenes)
+ {
+ if (geneResourceDrain.CanOffset)
+ {
+ this.tmpDrainGenes.Add(new Pair(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 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> tmpDrainGenes = new List>();
+ }
+}
diff --git a/Source/Genes/Life_Force/Gene_LifeForce.cs b/Source/Genes/Life_Force/Gene_LifeForce.cs
new file mode 100644
index 0000000..fcc5bcb
--- /dev/null
+++ b/Source/Genes/Life_Force/Gene_LifeForce.cs
@@ -0,0 +1,138 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using UnityEngine;
+using Verse;
+using RimWorld;
+
+
+namespace RJW_Genes
+{
+ public class Gene_LifeForce : Gene_Resource, IGeneResourceDrain
+ {
+ public override void ExposeData()
+ {
+ base.ExposeData();
+ }
+
+ public bool ShouldConsumeLifeForceNow()
+ {
+ return this.Value < this.targetValue;
+ }
+
+ //Same as Gene_Hemogen
+ public override IEnumerable GetGizmos()
+ {
+ foreach (Gizmo gizmo in base.GetGizmos())
+ {
+ yield return gizmo;
+ }
+ IEnumerator enumerator = null;
+ foreach (Gizmo gizmo2 in GeneResourceDrainUtility.GetResourceDrainGizmos(this))
+ {
+ yield return gizmo2;
+ }
+ enumerator = null;
+ yield break;
+ yield break;
+ }
+
+ //Depending on how low the value is it will increase sexdrive and if it reaches zero it will create a random rape mental break.
+ //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)
+ {
+ 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);
+ }
+ }
+ }
+ //GeneResourceDrainUtility.TickResourceDrain(this);
+ }
+
+ 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.15f;
+ }
+ }
+ public override float MaxLevelOffset
+ {
+ get
+ {
+ return base.MaxLevelOffset;
+ }
+ }
+ protected override Color BarColor
+ {
+ get
+ {
+ return Color.grey;
+ }
+ }
+ protected override Color BarHighlightColor
+ {
+ get
+ {
+ return Color.white;
+ }
+ }
+ }
+}
diff --git a/Source/Genes/Life_Force/JobGiver_LifeForce_RandomRape.cs b/Source/Genes/Life_Force/JobGiver_LifeForce_RandomRape.cs
new file mode 100644
index 0000000..f710c62
--- /dev/null
+++ b/Source/Genes/Life_Force/JobGiver_LifeForce_RandomRape.cs
@@ -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)))));
+ }
+ }
+}
diff --git a/Source/Genes/Life_Force/LifeForceMentalBreakWorker.cs b/Source/Genes/Life_Force/LifeForceMentalBreakWorker.cs
new file mode 100644
index 0000000..36b47b0
--- /dev/null
+++ b/Source/Genes/Life_Force/LifeForceMentalBreakWorker.cs
@@ -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();
+ if( gene.Resource.Value <= 0)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/Source/Genes/Life_Force/LifeForceMentalState.cs b/Source/Genes/Life_Force/LifeForceMentalState.cs
new file mode 100644
index 0000000..9c22f4e
--- /dev/null
+++ b/Source/Genes/Life_Force/LifeForceMentalState.cs
@@ -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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Genes/Life_Force/LifeForceMentalStateWorker.cs b/Source/Genes/Life_Force/LifeForceMentalStateWorker.cs
new file mode 100644
index 0000000..e9ed20f
--- /dev/null
+++ b/Source/Genes/Life_Force/LifeForceMentalStateWorker.cs
@@ -0,0 +1,15 @@
+using System;
+using Verse;
+using Verse.AI;
+using rjw;
+namespace RJW_Genes
+{
+ // Token: 0x020000FB RID: 251
+ public class LifeForceMentalStateWorker : MentalStateWorker
+ {
+ public override bool StateCanOccur(Pawn pawn)
+ {
+ return base.StateCanOccur(pawn) && (xxx.is_human(pawn) && JobGiver_LifeForce_RandomRape.can_rape(pawn));
+ }
+ }
+}
diff --git a/Source/Genes/Life_Force/Patch_LifeForce.cs b/Source/Genes/Life_Force/Patch_LifeForce.cs
new file mode 100644
index 0000000..3aa953e
--- /dev/null
+++ b/Source/Genes/Life_Force/Patch_LifeForce.cs
@@ -0,0 +1,36 @@
+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;
+
+ if (GeneUtility.HasLifeForce(props.pawn))
+ {
+ if (props.sexType == xxx.rjwSextype.Oral || props.sexType == xxx.rjwSextype.Fellatio || props.sexType == xxx.rjwSextype.Sixtynine)
+ {
+ Pawn_GeneTracker genes = props.pawn.genes;
+ Gene_LifeForce gene = genes.GetFirstGeneOfType();
+ gene.Resource.Value += CumUtility.GetTotalFluidAmount(props.partner); //total amount may need to be modified to be balanced
+ }
+ }
+ }
+ }
+
+}
diff --git a/Source/Interactions/GenesPartKindUsageRule.cs b/Source/Interactions/GenesPartKindUsageRule.cs
new file mode 100644
index 0000000..f3f5196
--- /dev/null
+++ b/Source/Interactions/GenesPartKindUsageRule.cs
@@ -0,0 +1,56 @@
+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
+{
+ public class GenesPartKindUsageRule : IPartPreferenceRule
+ {
+ public IEnumerable> ModifiersForDominant(InteractionContext context)
+ {
+ Pawn pawn = context.Internals.Dominant.Pawn;
+ if (GeneUtility.HasCriticalLifeForce(pawn))
+ {
+ Log.Message("Critical");
+ yield return new Weighted(50f, LewdablePartKind.Mouth);
+ }
+ else if (GeneUtility.HasLowLifeForce(pawn))
+ {
+ Log.Message("Low");
+ yield return new Weighted(10f, LewdablePartKind.Mouth);
+ }
+ else if (GeneUtility.HasLifeForce(pawn))
+ {
+ Log.Message("normal");
+ yield return new Weighted(2f, LewdablePartKind.Mouth);
+ }
+ yield break;
+ }
+
+ public IEnumerable> ModifiersForSubmissive(InteractionContext context)
+ {
+ Pawn pawn = context.Internals.Submissive.Pawn;
+ if (GeneUtility.HasCriticalLifeForce(pawn))
+ {
+ Log.Message("Critical");
+ yield return new Weighted(50f, LewdablePartKind.Mouth);
+ }
+ else if (GeneUtility.HasLowLifeForce(pawn))
+ {
+ Log.Message("Low");
+ yield return new Weighted(10f, LewdablePartKind.Mouth);
+ }
+ else if (GeneUtility.HasLifeForce(pawn))
+ {
+ Log.Message("normal");
+ yield return new Weighted(2f, LewdablePartKind.Mouth);
+ }
+ yield break;
+ }
+ }
+}
diff --git a/Source/JobDefOf.cs b/Source/JobDefOf.cs
new file mode 100644
index 0000000..fc64b2d
--- /dev/null
+++ b/Source/JobDefOf.cs
@@ -0,0 +1,15 @@
+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;
+ }
+}
diff --git a/Source/Rjw-Genes.csproj b/Source/Rjw-Genes.csproj
index f98d314..3f24101 100644
--- a/Source/Rjw-Genes.csproj
+++ b/Source/Rjw-Genes.csproj
@@ -60,7 +60,7 @@
-
+
@@ -114,12 +114,21 @@
+
+
+
+
+
+
+
+
+