Initial implementation of pheromone system

This commit is contained in:
lutepickle 2023-05-09 10:40:42 -07:00
parent d67592e245
commit 35adcf87ee
6 changed files with 159 additions and 4 deletions

Binary file not shown.

View File

@ -83,7 +83,14 @@
<SexSatisfaction>1.5</SexSatisfaction>
</statFactors>
</li>
</stages>
</stages>
<comps>
<li Class="RJW_Menstruation.CompProperties_Pheromones">
<daysToMaxSeverity>0.5</daysToMaxSeverity> <!-- The amount of time spent near someone in estrus for full effect -->
<range>6</range>
<intensity>1</intensity>
</li>
</comps>
</HediffDef>
<HediffDef Name="Hediff_Estrus_Concealed">
@ -113,6 +120,52 @@
</stages>
</HediffDef>
<HediffDef Name="Hediff_AffectedByPheromones">
<hediffClass>HediffWithComps</hediffClass>
<defName>Hediff_AffectedByPheromones</defName>
<label>Affected by pheromones</label>
<description>A condition caused by being around someone in estrus. Sex drive and satisfaction is increased by the scent of heat.</description>
<defaultLabelColor>(1.00,0.60,0.75)</defaultLabelColor>
<isBad>false</isBad>
<tendable>false</tendable>
<makesSickThought>false</makesSickThought>
<makesAlert>false</makesAlert>
<maxSeverity>1.0</maxSeverity>
<injuryProps>
<canMerge>true</canMerge>
</injuryProps>
<stages>
<li>
<label>weak</label>
<statFactors>
<SexFrequency>1.1</SexFrequency>
<SexSatisfaction>1.0</SexSatisfaction>
</statFactors>
</li>
<li>
<minSeverity>0.4</minSeverity>
<label>moderate</label>
<statFactors>
<SexFrequency>1.4</SexFrequency>
<SexSatisfaction>1.1</SexSatisfaction>
</statFactors>
</li>
<li>
<minSeverity>0.8</minSeverity>
<label>strong</label>
<statFactors>
<SexFrequency>2.0</SexFrequency>
<SexSatisfaction>1.2</SexSatisfaction>
</statFactors>
</li>
</stages>
<comps>
<li Class="HediffCompProperties_SeverityPerDay">
<severityPerDay>-1.0</severityPerDay>
</li>
</comps>
</HediffDef>
<HediffDef Name="Hediff_PainReliever">
<hediffClass>HediffWithComps</hediffClass>

View File

@ -0,0 +1,102 @@

using RimWorld;
using rjw;
using System;
using System.Collections.Generic;
using System.Linq;
using Verse;
namespace RJW_Menstruation
{
public class CompProperties_Pheromones : HediffCompProperties
{
public float daysToMaxSeverity;
public float range;
public float intensity = 1.0f;
public CompProperties_Pheromones()
{
compClass = typeof(HediffComp_Pheromones);
}
}
public class HediffComp_Pheromones : HediffComp
{
public CompProperties_Pheromones Props => (CompProperties_Pheromones)props;
public const int emitInterval = GenTicks.TickRareInterval;
public float emitRatio => (float)emitInterval / GenDate.TicksPerDay;
public override void CompPostTick(ref float severityAdjustment)
{
try
{
if (!Pawn.RaceProps.Humanlike) return;
if (!Pawn.IsHashIntervalTick(emitInterval)) return;
if (!Pawn.SpawnedOrAnyParentSpawned) return;
foreach (Pawn pawn in AffectedPawns())
ApplyEffectToPawn(pawn);
}
catch (Exception ex)
{
Log.Error($"Error when trying to emit pheromones: {ex}");
}
}
protected IEnumerable<Pawn> AffectedPawns()
{
Map mapHeld = Pawn.MapHeld;
if (mapHeld == null) yield break;
foreach (Pawn pawn in mapHeld.mapPawns.AllPawnsSpawned)
{
if (pawn == Pawn) continue;
if (!pawn.RaceProps.Humanlike) continue;
if (Pawn.PositionHeld.InHorDistOf(pawn.PositionHeld, Props.range) && Pawn.GetRoom() == pawn.GetRoom())
yield return pawn;
}
}
protected float GetEffectOnPawn(Pawn target)
{
if (target.Suspended || target.Dead) return 0.0f;
if (target.needs?.TryGetNeed(VariousDefOf.SexNeed) == null) return 0.0f;
if (!xxx.can_do_loving(target)) return 0.0f;
if (target.story?.traits.HasTrait(TraitDefOf.Asexual) ?? true) return 0.0f;
float penisEffect;
if (Genital_Helper.has_penis_fertile(target)) penisEffect = 1.0f;
else if (target.gender == Gender.Male) penisEffect = 0.25f;
else return 0.0f;
BodyDef body = target.RaceProps.body;
if (!PawnCapacityUtility.BodyCanEverDoCapacity(body, PawnCapacityDefOf.Breathing)) return 0.0f;
HediffSet hediffs = target.health.hediffSet;
float breathingEffect = PawnCapacityUtility.CalculateCapacityLevel(hediffs, PawnCapacityDefOf.Breathing);
float noseEffect = 1.0f;
List<BodyPartRecord> noses = body.GetPartsWithDef(BodyPartDefOf.Nose);
if (noses.Any()) // if the body doesn't have a nose but still breathes, then let it be affected
noseEffect = noses.Average(nose => PawnCapacityUtility.CalculatePartEfficiency(hediffs, nose));
return penisEffect * breathingEffect * noseEffect;
}
protected void ApplyEffectToPawn(Pawn target)
{
float intensity = Props.intensity * GetEffectOnPawn(target);
if (intensity <= 0.0f) return;
Hediff pheromones = target.health.hediffSet.GetFirstHediffOfDef(VariousDefOf.Hediff_AffectedByPheromones);
float decay = VariousDefOf.Hediff_AffectedByPheromones.CompProps<HediffCompProperties_SeverityPerDay>().severityPerDay;
float raiseSeverityPerDay = intensity / Props.daysToMaxSeverity - decay; // Desired increase plus enough to overcome pheromone decay
float amountToApply = emitRatio * raiseSeverityPerDay;
if (pheromones != null)
pheromones.Severity += amountToApply;
else
{
pheromones = HediffMaker.MakeHediff(VariousDefOf.Hediff_AffectedByPheromones, target);
pheromones.Severity = amountToApply;
target.health.AddHediff(pheromones);
}
return;
}
}
}

View File

@ -69,6 +69,7 @@
<Compile Include="EstrusPartKindUsageRule.cs" />
<Compile Include="HediffComps\HediffComp_InducedOvulator.cs" />
<Compile Include="HediffComps\HediffComp_PeriodicOvulator.cs" />
<Compile Include="HediffComps\HediffComp_Pheromones.cs" />
<Compile Include="HediffComps\HediffComp_PregeneratedBabies.cs" />
<Compile Include="HediffComps\MenstruationUtility.cs" />
<Compile Include="Hediff_Estrus.cs" />

View File

@ -1,7 +1,5 @@
using RimWorld;
using rjw;
using rjw.Modules.Interactions.Rules.PartKindUsageRules.Implementation;
using System;
using System.Collections.Generic;
using System.Linq;
using Verse;
@ -20,6 +18,7 @@ namespace RJW_Menstruation
public static readonly HediffDef Hediff_MenstrualCramp = DefDatabase<HediffDef>.GetNamed("Hediff_MenstrualCramp");
public static readonly HediffDef Hediff_Estrus = DefDatabase<HediffDef>.GetNamed("Hediff_Estrus");
public static readonly HediffDef Hediff_Estrus_Concealed = DefDatabase<HediffDef>.GetNamed("Hediff_Estrus_Concealed");
public static readonly HediffDef Hediff_AffectedByPheromones = DefDatabase<HediffDef>.GetNamed("Hediff_AffectedByPheromones");
public static readonly HediffDef Hediff_ASA = DefDatabase<HediffDef>.GetNamed("Hediff_ASA");
public static readonly StatDef MaxAbsorbable = DefDatabase<StatDef>.GetNamed("MaxAbsorbable");
public static readonly NeedDef SexNeed = DefDatabase<NeedDef>.GetNamed("Sex");

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Manifest>
<identifier>RJW Menstruation</identifier>
<version>1.0.9.0</version>
<version>1.0.9.1</version>
<dependencies>
</dependencies>
<incompatibleWith />