Healpussy gene and succubus wing retexture
Brought over the healpussy gene from my mod and changed the succubus wings to a lighter version
							
								
								
									
										47
									
								
								Common/Defs/AbilityDefs/Ability_PussyHeal.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,47 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="utf-8" ?>
 | 
				
			||||||
 | 
					<Defs>
 | 
				
			||||||
 | 
					  <AbilityDef ParentName="AbilityTouchBase">
 | 
				
			||||||
 | 
					    <defName>rjw_genes_pussyheal</defName>
 | 
				
			||||||
 | 
					    <label>SexHeal</label>
 | 
				
			||||||
 | 
					    <description>Rape another pawn, so you can heal them with your vagina's special healing power.</description>
 | 
				
			||||||
 | 
					    <iconPath>Things/Mote/Heart</iconPath>
 | 
				
			||||||
 | 
					    <stunTargetWhileCasting>false</stunTargetWhileCasting>
 | 
				
			||||||
 | 
					    <displayGizmoWhileUndrafted>true</displayGizmoWhileUndrafted>
 | 
				
			||||||
 | 
					    <disableGizmoWhileUndrafted>false</disableGizmoWhileUndrafted>
 | 
				
			||||||
 | 
						<cooldownTicksRange>60000</cooldownTicksRange>
 | 
				
			||||||
 | 
					    <warmupMote>Mote_CoagulateStencil</warmupMote>
 | 
				
			||||||
 | 
					    <warmupEffecter>Coagulate</warmupEffecter>
 | 
				
			||||||
 | 
					    <warmupStartSound>Coagulate_Cast</warmupStartSound>
 | 
				
			||||||
 | 
					    <jobDef>rjw_genes_lifeforce_healpussy</jobDef>
 | 
				
			||||||
 | 
					    <displayOrder>401</displayOrder>
 | 
				
			||||||
 | 
					    <verbProperties>
 | 
				
			||||||
 | 
					      <verbClass>Verb_CastAbilityTouch</verbClass>
 | 
				
			||||||
 | 
					      <drawAimPie>false</drawAimPie>
 | 
				
			||||||
 | 
					      <range>-1</range>
 | 
				
			||||||
 | 
					      <warmupTime>0</warmupTime>
 | 
				
			||||||
 | 
					      <targetParams>
 | 
				
			||||||
 | 
					        <canTargetAnimals>true</canTargetAnimals>
 | 
				
			||||||
 | 
					        <canTargetSelf>false</canTargetSelf>
 | 
				
			||||||
 | 
					        <canTargetBuildings>false</canTargetBuildings>
 | 
				
			||||||
 | 
					        <canTargetMechs>false</canTargetMechs>
 | 
				
			||||||
 | 
					        <canTargetBloodfeeders>true</canTargetBloodfeeders>
 | 
				
			||||||
 | 
					      </targetParams>
 | 
				
			||||||
 | 
					    </verbProperties>
 | 
				
			||||||
 | 
					    <comps>
 | 
				
			||||||
 | 
					      <li Class="RJW_Genes.CompProperties_AbilityPussyHeal"> <!-- namespace needs to be changed when copied to another mod-->
 | 
				
			||||||
 | 
					        <tendQualityRange>0.4~0.8</tendQualityRange> 
 | 
				
			||||||
 | 
					      </li>
 | 
				
			||||||
 | 
						  <li Class="RJW_Genes.CompProperties_SexInteractionRequirements"> 
 | 
				
			||||||
 | 
							<tags>
 | 
				
			||||||
 | 
								<!-- <li>Consensual</li> -->
 | 
				
			||||||
 | 
								<li>Rape</li>
 | 
				
			||||||
 | 
							</tags>
 | 
				
			||||||
 | 
							<dominantRequirement>
 | 
				
			||||||
 | 
								<families>
 | 
				
			||||||
 | 
									<li>Vagina</li>
 | 
				
			||||||
 | 
								</families>
 | 
				
			||||||
 | 
							</dominantRequirement> 
 | 
				
			||||||
 | 
						  </li> 
 | 
				
			||||||
 | 
					    </comps>
 | 
				
			||||||
 | 
					  </AbilityDef>
 | 
				
			||||||
 | 
					</Defs>
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@
 | 
				
			||||||
    <defName>rjw_genes_Succubus_Wings</defName>
 | 
					    <defName>rjw_genes_Succubus_Wings</defName>
 | 
				
			||||||
    <label>succubus wings</label>
 | 
					    <label>succubus wings</label>
 | 
				
			||||||
    <description>Carriers of this gene grow succubus wings.</description>
 | 
					    <description>Carriers of this gene grow succubus wings.</description>
 | 
				
			||||||
    <iconPath>UI/Icons/Genes/Gene_TailFurry</iconPath>
 | 
					    <iconPath>Genes/Icons/Succubus_Wings</iconPath>
 | 
				
			||||||
    <iconColor>(0.75, 0.75, 0.75)</iconColor>
 | 
					    <iconColor>(0.75, 0.75, 0.75)</iconColor>
 | 
				
			||||||
    <displayOrderInCategory>1000</displayOrderInCategory>
 | 
					    <displayOrderInCategory>1000</displayOrderInCategory>
 | 
				
			||||||
    <biostatCpx>1</biostatCpx>
 | 
					    <biostatCpx>1</biostatCpx>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,4 +33,28 @@
 | 
				
			||||||
		<biostatCpx>1</biostatCpx>
 | 
							<biostatCpx>1</biostatCpx>
 | 
				
			||||||
		<biostatMet>1</biostatMet>
 | 
							<biostatMet>1</biostatMet>
 | 
				
			||||||
	</GeneDef>
 | 
						</GeneDef>
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						<GeneDef>
 | 
				
			||||||
 | 
					    <defName>rjw_genes_pussyhealer</defName>
 | 
				
			||||||
 | 
					    <label>Pussy Healer</label>
 | 
				
			||||||
 | 
					    <labelShortAdj>pussyhealer</labelShortAdj>
 | 
				
			||||||
 | 
					    <description>Carriers of this gene are able use vaginal sex to tend to other's wounds.</description>
 | 
				
			||||||
 | 
					    <iconPath>Things/Mote/Heart</iconPath>
 | 
				
			||||||
 | 
					    <displayCategory>Ability</displayCategory>
 | 
				
			||||||
 | 
					    <abilities>
 | 
				
			||||||
 | 
					      <li>rjw_genes_pussyheal</li>
 | 
				
			||||||
 | 
					    </abilities>
 | 
				
			||||||
 | 
					    <descriptionHyperlinks>
 | 
				
			||||||
 | 
					      <AbilityDef>rjw_genes_pussyheal</AbilityDef>
 | 
				
			||||||
 | 
					    </descriptionHyperlinks>
 | 
				
			||||||
 | 
					    <biostatMet>1</biostatMet>
 | 
				
			||||||
 | 
					    <minAgeActive>13</minAgeActive>
 | 
				
			||||||
 | 
					    <symbolPack>
 | 
				
			||||||
 | 
					      <suffixSymbols>
 | 
				
			||||||
 | 
					        <li><symbol>life</symbol></li>
 | 
				
			||||||
 | 
					        <li><symbol>clotter</symbol></li>
 | 
				
			||||||
 | 
					        <li><symbol>tender</symbol></li>
 | 
				
			||||||
 | 
					      </suffixSymbols>
 | 
				
			||||||
 | 
					    </symbolPack>
 | 
				
			||||||
 | 
					  </GeneDef>
 | 
				
			||||||
</Defs>
 | 
					</Defs>
 | 
				
			||||||
| 
						 | 
					@ -7,4 +7,11 @@
 | 
				
			||||||
		<reportString>Raping</reportString>
 | 
							<reportString>Raping</reportString>
 | 
				
			||||||
		<casualInterruptible>false</casualInterruptible>
 | 
							<casualInterruptible>false</casualInterruptible>
 | 
				
			||||||
	</JobDef>
 | 
						</JobDef>
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						<JobDef>
 | 
				
			||||||
 | 
							<defName>rjw_genes_lifeforce_healpussy</defName>
 | 
				
			||||||
 | 
							<driverClass>RJW_Genes.JobDriver_CastAbilityAfterSex</driverClass>
 | 
				
			||||||
 | 
							<reportString>Healing someone with sex.</reportString>
 | 
				
			||||||
 | 
							<casualInterruptible>false</casualInterruptible>
 | 
				
			||||||
 | 
						</JobDef>
 | 
				
			||||||
</Defs>
 | 
					</Defs>
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								Common/Textures/Genes/Icons/Succubus_Wings.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1.2 KiB  | 
| 
		 Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.4 KiB  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.4 KiB  | 
| 
						 | 
					@ -74,5 +74,6 @@ namespace RJW_Genes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// LifeForce
 | 
							// LifeForce
 | 
				
			||||||
		public static readonly GeneDef rjw_genes_lifeforce;
 | 
							public static readonly GeneDef rjw_genes_lifeforce;
 | 
				
			||||||
 | 
							public static readonly GeneDef rjw_genes_pussyhealer;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,5 +102,14 @@ namespace RJW_Genes
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return pawn.genes.HasGene(GeneDefOf.rjw_genes_generous_donor);
 | 
					            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);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										52
									
								
								Source/Genes/Life_Force/AbilityUtility.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,52 @@
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										103
									
								
								Source/Genes/Life_Force/CompAbilityEffect_PussyHeal.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,103 @@
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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,155 @@
 | 
				
			||||||
 | 
					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 CompAbility_SexInteractionRequirements : AbilityComp
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							public CompProperties_SexInteractionRequirements Props
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								get
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return (CompProperties_SexInteractionRequirements)this.props;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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> sexinteractions = SexUtility.SexInterractions;
 | 
				
			||||||
 | 
								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;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								Source/Genes/Life_Force/CompProperties_AbilityPussyHeal.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										16
									
								
								Source/Genes/Life_Force/Interactionchances.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					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 Interaction_weights
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public InteractionDef interaction;
 | 
				
			||||||
 | 
					        public int weight = 1;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										90
									
								
								Source/Genes/Life_Force/JobDriver_CastAbilityAfterSex.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -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 = CompAbility_SexInteractionRequirements.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;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -114,7 +114,14 @@
 | 
				
			||||||
    <Compile Include="Genes\Genitalia\Gene_DemonicGenitalia.cs" />
 | 
					    <Compile Include="Genes\Genitalia\Gene_DemonicGenitalia.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Genitalia\Gene_EquineGenitalia.cs" />
 | 
					    <Compile Include="Genes\Genitalia\Gene_EquineGenitalia.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Genitalia\GenitaliaChanger.cs" />
 | 
					    <Compile Include="Genes\Genitalia\GenitaliaChanger.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Life_Force\AbilityUtility.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Life_Force\CompAbility_SexInteractionRequirements.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Life_Force\CompAbilityEffect_PussyHeal.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Life_Force\CompProperties_SexInteractionRequirements.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Life_Force\CompProperties_AbilityPussyHeal.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\GeneGizmo_ResourceLifeForce.cs" />
 | 
					    <Compile Include="Genes\Life_Force\GeneGizmo_ResourceLifeForce.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Life_Force\Interactionchances.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Genes\Life_Force\JobDriver_CastAbilityAfterSex.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\LifeForceMentalState.cs" />
 | 
					    <Compile Include="Genes\Life_Force\LifeForceMentalState.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\LifeForceMentalStateWorker.cs" />
 | 
					    <Compile Include="Genes\Life_Force\LifeForceMentalStateWorker.cs" />
 | 
				
			||||||
    <Compile Include="Genes\Life_Force\JobGiver_LifeForce_RandomRape.cs" />
 | 
					    <Compile Include="Genes\Life_Force\JobGiver_LifeForce_RandomRape.cs" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||