Custom succubus tail sex interactions and modification to fertilin absorbtion

This commit is contained in:
Shabakur 2022-12-29 16:08:22 +01:00
parent 22892db8e0
commit 3cf2d44c82
17 changed files with 955 additions and 44 deletions

View file

@ -1,155 +0,0 @@
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;
}
}
}

View file

@ -1,25 +0,0 @@
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;
}
}

View file

@ -50,7 +50,7 @@ namespace RJW_Genes
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.Sexprops = CustomSexInteraction_Helper.GenerateSexProps(this.pawn, this.Partner, sexpropsreq);
}
}
this.Start();

View file

@ -20,58 +20,144 @@ namespace RJW_Genes
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))
{
if (props.sexType == xxx.rjwSextype.Oral || props.sexType == xxx.rjwSextype.Fellatio || props.sexType == xxx.rjwSextype.Sixtynine)
Pawn succubus = props.partner;
if (!props.isRevese)
{
absorb_factor += 1f;
//Currently taking the sum of all penises, maybe I should just consider one at random
}
else if (props.sexType == xxx.rjwSextype.Vaginal && GeneUtility.HasGeneNullCheck(props.partner, GeneDefOf.rjw_genes_vaginal_absorber))
{
absorb_factor += 1f;
}
else if (props.sexType == xxx.rjwSextype.Anal && GeneUtility.HasGeneNullCheck(props.partner, GeneDefOf.rjw_genes_anal_absorber))
{
absorb_factor += 1f;
}
else if (props.sexType == xxx.rjwSextype.DoublePenetration)
{
if (GeneUtility.HasGeneNullCheck(props.partner, GeneDefOf.rjw_genes_vaginal_absorber))
if (props.isReceiver)
{
absorb_factor += 0.5f;
// Scenario Dom Succubus, normal
absorb_factor = BaseDom(props, succubus);
}
if (GeneUtility.HasGeneNullCheck(props.partner, GeneDefOf.rjw_genes_anal_absorber))
else
{
absorb_factor += 0.5f;
// Scenario Sub Succubus, normal
absorb_factor = BaseSub(props, succubus);
}
}
if (absorb_factor != 0)
{
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);
}
}
}
public static void AbsorbFertilin(SexProps props, float absorb_factor = 1f)
{
{
Pawn_GeneTracker genes = props.partner.genes;
Gene_LifeForce gene = genes.GetFirstGeneOfType<Gene_LifeForce>();
float multiplier = Rand.Range(0.10f, 0.40f); //Around quarter get ejected everytime pawn cums
Hediff fertelin_lost = props.pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Fertilin_Lost);
if (fertelin_lost == null)
{
{
Hediff new_fertelin_lost = HediffMaker.MakeHediff(HediffDefOf.Fertilin_Lost, props.pawn);
props.pawn.health.AddHediff(new_fertelin_lost);
new_fertelin_lost.Severity = multiplier;
}
else
{
else
{
multiplier *= 1 - fertelin_lost.Severity;
fertelin_lost.Severity += multiplier;
}
gene.Resource.Value += CumUtility.GetTotalFluidAmount(props.partner) / 100 * absorb_factor * multiplier;
}
//Currently taking the sum of all penises, maybe I should just consider one at random
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;
}
}
}