mirror of
https://github.com/vegapnk/RJW-Genes.git
synced 2024-08-15 00:23:31 +00:00
1.5 update
This commit is contained in:
parent
7d9e399a47
commit
e6db43f31d
231 changed files with 95 additions and 6968 deletions
|
@ -1,203 +0,0 @@
|
|||
using HarmonyLib;
|
||||
using rjw;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace RJW_Genes
|
||||
{
|
||||
/// <summary>
|
||||
/// This Patch hooks after "SatisfyPersonal"(i.E. when the pawn finished fucking) and covers LifeForceGain.
|
||||
/// If the pawn has LifeForce, all relevant Genes are checked and applied.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(SexUtility), nameof(SexUtility.SatisfyPersonal))]
|
||||
public static class Patch_SatisfyPersonal_LifeForceGain
|
||||
{
|
||||
public const float LIFEFORCE_GAINED_FROM_DRAINER_GENE = 0.25f;
|
||||
|
||||
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 PawnWithLifeForce = props.partner;
|
||||
|
||||
if (!props.isRevese)
|
||||
{
|
||||
if (props.isReceiver)
|
||||
{
|
||||
// Scenario Dom Succubus, normal
|
||||
absorb_factor = BaseDom(props, PawnWithLifeForce);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Scenario Sub Succubus, normal
|
||||
absorb_factor = BaseSub(props, PawnWithLifeForce);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (props.isReceiver)
|
||||
{
|
||||
// Scenario Dom Succubus, Reverse
|
||||
absorb_factor = BaseSub(props, PawnWithLifeForce);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Scenario Sub Succubus, Reverse
|
||||
absorb_factor = BaseDom(props, PawnWithLifeForce);
|
||||
}
|
||||
}
|
||||
|
||||
// If we remove this check fertilin is always lost, but the succubus doesn't always gain any
|
||||
if (absorb_factor != 0f)
|
||||
{
|
||||
TransferFertilin(props, absorb_factor);
|
||||
}
|
||||
|
||||
// Handle Gene: Sexual_Drainer
|
||||
// to be drained, a pawn must not-be-drained-already and drainers cannot be drained either.
|
||||
if (GeneUtility.IsSexualDrainer(PawnWithLifeForce)
|
||||
&& !props.pawn.health.hediffSet.HasHediff(HediffDefOf.rjw_genes_succubus_drained)
|
||||
&& !GeneUtility.IsSexualDrainer(props.pawn))
|
||||
{
|
||||
if (GeneUtility.IsGenerousDonor(props.pawn) && RJW_Genes_Settings.rjw_genes_generous_donor_cheatmode)
|
||||
{
|
||||
// Cheatmode is on, do not drain but give life
|
||||
GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(PawnWithLifeForce), LIFEFORCE_GAINED_FROM_DRAINER_GENE);
|
||||
if (RJW_Genes_Settings.rjw_genes_detailed_debug)
|
||||
ModLog.Message($"{props.pawn.Name} was not (sexually) drained by {PawnWithLifeForce.Name}, because Cheatmode for Generous Donors is on");
|
||||
} else
|
||||
{
|
||||
if (RJW_Genes_Settings.rjw_genes_detailed_debug)
|
||||
ModLog.Message($"{props.pawn.Name} has been (sexually) drained by {PawnWithLifeForce.Name}");
|
||||
props.pawn.health.AddHediff(HediffDefOf.rjw_genes_succubus_drained);
|
||||
GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(PawnWithLifeForce), LIFEFORCE_GAINED_FROM_DRAINER_GENE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void TransferFertilin(SexProps props, float absorb_percentage = 1f)
|
||||
{
|
||||
Pawn_GeneTracker genes = props.partner.genes;
|
||||
Gene_LifeForce gene = genes.GetFirstGeneOfType<Gene_LifeForce>();
|
||||
|
||||
Hediff fertilin_lost = props.pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.rjw_genes_fertilin_lost);
|
||||
//Around quarter get ejected everytime pawn cums
|
||||
float multiplier = Rand.Range(0.10f, 0.40f);
|
||||
|
||||
if (GeneUtility.IsGenerousDonor(props.pawn) && RJW_Genes_Settings.rjw_genes_generous_donor_cheatmode)
|
||||
{
|
||||
// Do nothing, Cheatmode is on
|
||||
multiplier = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Create a new ferilin_lost hediff or increase it
|
||||
if (fertilin_lost == null)
|
||||
{
|
||||
Hediff new_fertilin_lost = HediffMaker.MakeHediff(HediffDefOf.rjw_genes_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;
|
||||
}
|
||||
}
|
||||
|
||||
multiplier *= absorb_percentage;
|
||||
//Currently taking the sum of all penises, maybe I should just consider one at random
|
||||
float valuechange = TotalFertilinAmount(props, multiplier);
|
||||
|
||||
if (props.partner.IsAnimal())
|
||||
{
|
||||
if (RJW_Genes_Settings.rjw_genes_detailed_debug)
|
||||
ModLog.Message($"Fertilin-Source of {props.pawn.Name} was an Animal, Fertilin-Gain is being adjusted by {RJW_Genes_Settings.rjw_genes_fertilin_from_animals_factor}%");
|
||||
valuechange *= RJW_Genes_Settings.rjw_genes_fertilin_from_animals_factor;
|
||||
}
|
||||
|
||||
GeneUtility.OffsetLifeForce(GeneUtility.GetLifeForceGene(props.partner), valuechange);
|
||||
}
|
||||
|
||||
public static float TotalFertilinAmount(SexProps props, float multiplier)
|
||||
{
|
||||
float total_fluid = CumUtility.GetTotalFluidAmount(props.pawn) / 100;
|
||||
|
||||
//More in the tank means more to give
|
||||
if (props.pawn.Has(Quirk.Messy))
|
||||
{
|
||||
total_fluid *= 2;
|
||||
}
|
||||
if (props.pawn.RaceProps.Animal)
|
||||
{
|
||||
total_fluid *= 0.1f; //Should make this settable in settings
|
||||
}
|
||||
|
||||
return total_fluid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the Case that the Life-Force wielder initiated the Sex (They are "Dom").
|
||||
/// </summary>
|
||||
/// <param name="props">The summary of the sex act, used for checking conditions.</param>
|
||||
/// <param name="PawnWithLifeForce">The pawn that might gain LifeForce through this method.</param>
|
||||
/// <returns>A factor between 0 and 1 how much of output-fertilin will be used for input-lifeforce</returns>
|
||||
public static float BaseDom(SexProps props, Pawn PawnWithLifeForce)
|
||||
{
|
||||
float absorb_factor = 0f;
|
||||
if (props.sexType == xxx.rjwSextype.Sixtynine && GeneUtility.IsCumEater(PawnWithLifeForce))
|
||||
{
|
||||
absorb_factor += 1f;
|
||||
}
|
||||
return absorb_factor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the Case that the Life-Force wielder got initiated into sex (They are "Sub").
|
||||
/// </summary>
|
||||
/// <param name="props">The summary of the sex act, used for checking conditions.</param>
|
||||
/// <param name="PawnWithLifeForce">The pawn that might gain LifeForce through this method.</param>
|
||||
/// <returns>A factor between 0 and 1 how much of output-fertilin will be used for input-lifeforce</returns>
|
||||
public static float BaseSub(SexProps props, Pawn PawnWithLifeForce)
|
||||
{
|
||||
float absorb_factor = 0f;
|
||||
if ((props.sexType == xxx.rjwSextype.Oral || props.sexType == xxx.rjwSextype.Fellatio || props.sexType == xxx.rjwSextype.Sixtynine)
|
||||
&& GeneUtility.IsCumEater(PawnWithLifeForce))
|
||||
{
|
||||
absorb_factor += 1f;
|
||||
}
|
||||
else if (props.sexType == xxx.rjwSextype.Vaginal && GeneUtility.HasGeneNullCheck(PawnWithLifeForce, GeneDefOf.rjw_genes_fertilin_absorber))
|
||||
{
|
||||
absorb_factor += 1f;
|
||||
}
|
||||
else if (props.sexType == xxx.rjwSextype.Anal && GeneUtility.HasGeneNullCheck(PawnWithLifeForce, GeneDefOf.rjw_genes_fertilin_absorber))
|
||||
{
|
||||
absorb_factor += 1f;
|
||||
}
|
||||
else if (props.sexType == xxx.rjwSextype.DoublePenetration && GeneUtility.HasGeneNullCheck(PawnWithLifeForce, GeneDefOf.rjw_genes_fertilin_absorber))
|
||||
{
|
||||
absorb_factor += 1f;
|
||||
}
|
||||
else if (props.sexType == xxx.rjwSextype.Scissoring || props.sexType == xxx.rjwSextype.Cunnilingus)
|
||||
{
|
||||
//with vaginal cum absorbtion
|
||||
//absorb_factor += 1f;
|
||||
}
|
||||
return absorb_factor;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
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
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This patch enables cum-eater pawns to drain cumflations for more fertilin drain by passively having sex.
|
||||
/// It is hooked after RJWs Change-Psyfocus so that pawns that are having prolonged sex (e.g. by overdrive) can fully drain the cumflation over time.
|
||||
///
|
||||
/// It is conditionally loaded only when LicentiaLabs is enabled, as this is the necessary source for cumflation-hediffs.
|
||||
/// The patched function is: [HarmonyPatch(typeof(JobDriver_Sex), nameof(JobDriver_Sex.ChangePsyfocus))]
|
||||
/// </summary>
|
||||
public static class Patch_SexTicks_ChangePsyfocus
|
||||
{
|
||||
public const float LIFEFORCE_GAIN_PER_TICK = 0.05f;
|
||||
public const float CUMFLATION_SEVERITY_LOSS_PER_TICK = 0.1f;
|
||||
|
||||
//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)
|
||||
{
|
||||
SexProps props = __instance.Sexprops;
|
||||
if (props != null && props.sexType == xxx.rjwSextype.Cunnilingus && props.partner != null && target != null)
|
||||
{
|
||||
Pawn pawn2 = target as Pawn;
|
||||
// Case 1: Pawn is "drinking" and has CumEater Gene
|
||||
if (props.isRevese && GeneUtility.IsCumEater(pawn))
|
||||
{
|
||||
if (RJW_Genes_Settings.rjw_genes_detailed_debug)
|
||||
ModLog.Message($"{pawn.Name} is draining {pawn2.Name}'s cumflation for additional fertilin (CumEater-Gene ChangePsyFocus-Trigger).");
|
||||
DrinkCumflation(pawn2, pawn);
|
||||
}
|
||||
// Case 2: Pawn2 is "drinking" and has CumEater Gene
|
||||
else if (GeneUtility.IsCumEater(pawn2))
|
||||
{
|
||||
if (RJW_Genes_Settings.rjw_genes_detailed_debug)
|
||||
ModLog.Message($"{pawn.Name} is draining {pawn2.Name}'s cumflation for additional fertilin (CumEater-Gene ChangePsyFocus-Trigger).");
|
||||
DrinkCumflation(pawn, pawn2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrinkCumflation(Pawn source, Pawn consumer)
|
||||
{
|
||||
if (GeneUtility.HasLifeForce(consumer) && GeneUtility.IsCumEater(consumer)
|
||||
&& source.health.hediffSet.HasHediff(HediffDef.Named("Cumflation")))
|
||||
{
|
||||
Hediff cumflation = source.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("Cumflation"));
|
||||
Gene_LifeForce gene_LifeForce = consumer.genes.GetFirstGeneOfType<Gene_LifeForce>();
|
||||
cumflation.Severity = Math.Max(0f,cumflation.Severity - CUMFLATION_SEVERITY_LOSS_PER_TICK);
|
||||
gene_LifeForce.Resource.Value += LIFEFORCE_GAIN_PER_TICK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using HarmonyLib;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace RJW_Genes
|
||||
{
|
||||
/// <summary>
|
||||
/// This Patch is applied to add a absorption gene for fertilin if it has none, but it does have the fertilin gene
|
||||
/// First tries to get one from the parents else chooses one of them at random
|
||||
/// the genes are determined and "simply added".
|
||||
///
|
||||
/// This fixes the potential problem that Pawns could inherit Fertilin, but no gene to gain Fertilin.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(PregnancyUtility), "GetInheritedGeneSet", new Type[]
|
||||
{
|
||||
typeof(Pawn),
|
||||
typeof(Pawn)
|
||||
}
|
||||
)]
|
||||
public static class Patch_Vanilla_Inheritance_Fertilin
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
public static void InheritedGenes(Pawn father, Pawn mother, ref GeneSet __result)
|
||||
{
|
||||
//Also make a setting for this
|
||||
if (__result.GenesListForReading.Contains(GeneDefOf.rjw_genes_lifeforce))
|
||||
{
|
||||
List<GeneDef> babies_genes = __result.GenesListForReading;
|
||||
|
||||
//If there is no absorption gene get one from the parents, else a random one
|
||||
if(!Has_Fertilin_Source_Gene(babies_genes))
|
||||
{
|
||||
if (RJW_Genes_Settings.rjw_genes_detailed_debug)
|
||||
ModLog.Message($"Child of ({father.Name};{mother.Name}) has Genes with LifeForce-Resource but no Source-Gene, adding one of parents random if possible or any random otherwise.");
|
||||
// Gather Parents Source-Genes
|
||||
List<GeneDef> absorption_genes_parents = new List<GeneDef>();
|
||||
foreach (GeneDef geneDef in FertilinSourceGenes)
|
||||
{
|
||||
if(mother.genes != null && mother.genes.HasGene(geneDef))
|
||||
absorption_genes_parents.Add(geneDef);
|
||||
|
||||
if (father.genes != null && father.genes.HasGene(geneDef))
|
||||
absorption_genes_parents.Add(geneDef);
|
||||
}
|
||||
// Parents had Genes - Pick a random one of them
|
||||
if (!absorption_genes_parents.NullOrEmpty())
|
||||
__result.AddGene(absorption_genes_parents.RandomElement());
|
||||
// Create a fully random one for your little Cumfueled missbreed
|
||||
else
|
||||
__result.AddGene(FertilinSourceGenes.RandomElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<GeneDef> FertilinSourceGenes = new List<GeneDef>() {
|
||||
GeneDefOf.rjw_genes_drainer,
|
||||
GeneDefOf.rjw_genes_cum_eater,
|
||||
GeneDefOf.rjw_genes_fertilin_absorber,
|
||||
GeneDefOf.rjw_genes_cockeater
|
||||
};
|
||||
|
||||
private static bool Has_Fertilin_Source_Gene(List<GeneDef> genes)
|
||||
{
|
||||
foreach (GeneDef gene in genes)
|
||||
{
|
||||
if (FertilinSourceGenes.Contains(gene))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue