Several genes and changes

- Succubus wings now have the flight abilty (same as longjump)
- Modified aphrodisiac pheromones to increase with strenght based on carrier's sexdrive.
- Added paralysing kiss, touch range stun which uses fertilin
- Added seduce, beckon like ability which results in sex if target reached caster. Uses fertilin
This commit is contained in:
Shabakur 2023-01-06 12:42:04 +01:00
parent 5555083bc2
commit 400b48787d
25 changed files with 687 additions and 171 deletions

Binary file not shown.

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<AbilityDef>
<defName>rjw_genes_flight</defName>
<label>fly</label>
<description>Fly to a distant location using wings.</description>
<iconPath>Genes/Icons/Succubus_Wings</iconPath>
<cooldownTicksRange>1250</cooldownTicksRange>
<hostile>false</hostile>
<verbProperties>
<verbClass>Verb_CastAbilityJump</verbClass>
<label>fly</label>
<violent>false</violent>
<forceNormalTimeSpeed>false</forceNormalTimeSpeed>
<warmupTime>0.5</warmupTime>
<range>19.9</range>
<requireLineOfSight>true</requireLineOfSight>
<soundCast>Longjump_Jump</soundCast>
<soundLanding>Longjump_Land</soundLanding>
<targetParams>
<canTargetLocations>true</canTargetLocations>
<canTargetPawns>false</canTargetPawns>
<canTargetBuildings>false</canTargetBuildings>
</targetParams>
</verbProperties>
<jobDef>CastJump</jobDef>
</AbilityDef>
</Defs>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<AbilityDef ParentName="AbilityTouchBase">
<defName>rjw_genes_paralysingkiss</defName>
<label>paralysing kiss</label>
<description>Paralyse someone briefly with a kiss.</description>
<iconPath>Things/Mote/Heart</iconPath>
<stunTargetWhileCasting>true</stunTargetWhileCasting>
<displayGizmoWhileUndrafted>true</displayGizmoWhileUndrafted>
<disableGizmoWhileUndrafted>false</disableGizmoWhileUndrafted>
<statBases>
<Ability_Duration>5</Ability_Duration>
</statBases>
<warmupMote>Mote_CoagulateStencil</warmupMote>
<warmupEffecter>Coagulate</warmupEffecter>
<warmupStartSound>Coagulate_Cast</warmupStartSound>
<displayOrder>402</displayOrder>
<verbProperties>
<verbClass>Verb_CastAbilityTouch</verbClass>
<drawAimPie>false</drawAimPie>
<range>-1</range>
<warmupTime>1</warmupTime>
<targetParams>
<canTargetAnimals>true</canTargetAnimals>
<canTargetSelf>false</canTargetSelf>
<canTargetBuildings>false</canTargetBuildings>
<canTargetMechs>false</canTargetMechs>
<canTargetBloodfeeders>true</canTargetBloodfeeders>
</targetParams>
</verbProperties>
<comps>
<li Class = "CompProperties_AbilityEffectWithDuration">
<compClass>CompAbilityEffect_Stun</compClass>
<goodwillImpact>-15</goodwillImpact>
</li>
<li Class="CompProperties_AbilityFleckOnTarget">
<fleckDef>Heart</fleckDef> <!--Will change to kiss when I have a good icon/fleck for it-->.
</li>
<li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
<fertilinCost>0.05</fertilinCost>
</li>
</comps>
</AbilityDef>
</Defs>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<AbilityDef>
<defName>rjw_genes_seduce</defName>
<label>seduce</label>
<description>Seduce the target to approach the caster.</description>
<iconPath>Things/Mote/Heart</iconPath>
<writeCombatLog>True</writeCombatLog>
<stunTargetWhileCasting>true</stunTargetWhileCasting>
<displayGizmoWhileUndrafted>true</displayGizmoWhileUndrafted>
<disableGizmoWhileUndrafted>false</disableGizmoWhileUndrafted>
<statBases>
<Ability_Duration>10</Ability_Duration>
</statBases>
<warmupMote>Mote_CoagulateStencil</warmupMote>
<warmupEffecter>Coagulate</warmupEffecter>
<warmupStartSound>Coagulate_Cast</warmupStartSound>
<verbProperties>
<verbClass>Verb_CastAbility</verbClass>
<range>10</range>
<warmupTime>1</warmupTime>
<targetParams>
<canTargetAnimals>false</canTargetAnimals>
<canTargetSelf>false</canTargetSelf>
<canTargetBuildings>false</canTargetBuildings>
<canTargetMechs>false</canTargetMechs>
<canTargetBloodfeeders>true</canTargetBloodfeeders>
</targetParams>
</verbProperties>
<comps>
<li Class = "RJW_Genes.CompProperties_Seduce">
<compClass>RJW_Genes.CompAbilityEffect_Seduce</compClass>
<destination>Caster</destination>
</li>
<li Class="CompProperties_AbilityFleckOnTarget">
<fleckDef>Heart</fleckDef>
</li>
<li Class="RJW_Genes.CompProperties_AbilityLifeForceCost">
<fertilinCost>0.1</fertilinCost>
</li>
</comps>
</AbilityDef>
</Defs>

View File

@ -19,6 +19,12 @@
<iconPath>Genes/Icons/Succubus_Wings</iconPath>
<iconColor>(0.75, 0.75, 0.75)</iconColor>
<displayOrderInCategory>1000</displayOrderInCategory>
<abilities>
<li>rjw_genes_flight</li>
</abilities>
<descriptionHyperlinks>
<AbilityDef>rjw_genes_flight</AbilityDef>
</descriptionHyperlinks>
<biostatCpx>1</biostatCpx>
<graphicData>
<graphicPath>Things/Pawn/Humanlike/BodyAttachments/rjw_genes_Succubus_Wings/Succubus_Wings</graphicPath>

View File

@ -44,20 +44,20 @@
<displayOrderInCategory>10</displayOrderInCategory>
<displayCategory>rjw_genes_fertilin</displayCategory>
<abilities>
<li>rjw_genes_pussyheal</li>
<li>rjw_genes_pussyheal</li>
</abilities>
<descriptionHyperlinks>
<AbilityDef>rjw_genes_pussyheal</AbilityDef>
<AbilityDef>rjw_genes_pussyheal</AbilityDef>
</descriptionHyperlinks>
<biostatCpx>1</biostatCpx>
<biostatMet>-1</biostatMet>
<minAgeActive>18</minAgeActive>
<symbolPack>
<suffixSymbols>
<li><symbol>life</symbol></li>
<li><symbol>pussy</symbol></li>
<li><symbol>heal</symbol></li>
</suffixSymbols>
<suffixSymbols>
<li><symbol>life</symbol></li>
<li><symbol>pussy</symbol></li>
<li><symbol>heal</symbol></li>
</suffixSymbols>
</symbolPack>
</GeneDef>
@ -71,20 +71,72 @@
<displayOrderInCategory>11</displayOrderInCategory>
<displayCategory>rjw_genes_fertilin</displayCategory>
<abilities>
<li>rjw_genes_cockeater</li>
<li>rjw_genes_cockeater</li>
</abilities>
<descriptionHyperlinks>
<AbilityDef>rjw_genes_cockeater</AbilityDef>
<AbilityDef>rjw_genes_cockeater</AbilityDef>
</descriptionHyperlinks>
<biostatCpx>1</biostatCpx>
<biostatMet>-1</biostatMet>
<minAgeActive>18</minAgeActive>
<symbolPack>
<suffixSymbols>
<li><symbol>life</symbol></li>
<li><symbol>cock</symbol></li>
<li><symbol>eat</symbol></li>
</suffixSymbols>
<suffixSymbols>
<li><symbol>life</symbol></li>
<li><symbol>cock</symbol></li>
<li><symbol>eat</symbol></li>
</suffixSymbols>
</symbolPack>
</GeneDef>
<GeneDef>
<defName>rjw_genes_paralysingkiss</defName>
<label>paralysing kiss</label>
<labelShortAdj>paralysing kiss</labelShortAdj>
<description>Carriers of this gene are able to briefly stun an enemy with a kiss.</description>
<iconPath>Things/Mote/Heart</iconPath>
<prerequisite>rjw_genes_lifeforce</prerequisite>
<displayOrderInCategory>11</displayOrderInCategory>
<displayCategory>rjw_genes_fertilin</displayCategory>
<abilities>
<li>rjw_genes_paralysingkiss</li>
</abilities>
<descriptionHyperlinks>
<AbilityDef>rjw_genes_paralysingkiss</AbilityDef>
</descriptionHyperlinks>
<biostatCpx>1</biostatCpx>
<biostatMet>-1</biostatMet>
<minAgeActive>18</minAgeActive>
<symbolPack>
<suffixSymbols>
<li><symbol>stun</symbol></li>
<li><symbol>kiss</symbol></li>
</suffixSymbols>
</symbolPack>
</GeneDef>
<GeneDef>
<defName>rjw_genes_seduce</defName>
<label>seduction</label>
<labelShortAdj>seduction</labelShortAdj>
<description>Carriers of this gene are able to seduce a pawn into having sex with them.</description>
<iconPath>Things/Mote/Heart</iconPath>
<prerequisite>rjw_genes_lifeforce</prerequisite>
<displayOrderInCategory>11</displayOrderInCategory>
<displayCategory>rjw_genes_fertilin</displayCategory>
<abilities>
<li>rjw_genes_seduce</li>
</abilities>
<descriptionHyperlinks>
<AbilityDef>rjw_genes_seduce</AbilityDef>
</descriptionHyperlinks>
<biostatCpx>1</biostatCpx>
<biostatMet>-1</biostatMet>
<minAgeActive>18</minAgeActive>
<symbolPack>
<suffixSymbols>
<li><symbol>stun</symbol></li>
<li><symbol>kiss</symbol></li>
</suffixSymbols>
</symbolPack>
</GeneDef>

View File

@ -15,7 +15,7 @@
<label>Aphrodisiac Pheromones</label>
<displayCategory>rjw_genes_special</displayCategory>
<geneClass>RJW_Genes.Gene_Aphrodisiac_Pheromones</geneClass>
<description>Pheremones of this pawn induce an increased sexdrive to others nearby.</description>
<description>Carriers of this gene create an aphrodisiac pheremones which induce an increased sexdrive to others nearby, increasing in strength as the sexdrive of the carrier increases.\nCarriers are unaffected by others with this gene.</description>
<iconPath>UI/Memes/FleshPurity</iconPath>
<displayOrderInCategory>2</displayOrderInCategory>
<biostatCpx>1</biostatCpx>

View File

@ -1,6 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--all pregnancies-->
<Defs>
<HediffDef>
<defName>Aphrodisiac_Pheromone</defName>
@ -16,7 +14,7 @@
</comps>
<stages>
<li>
<becomeVisible>false</becomeVisible>
<becomeVisible>true</becomeVisible>
<statFactors>
<SexFrequency>2</SexFrequency>
</statFactors>
@ -88,4 +86,24 @@
</li>
</stages>
</HediffDef>
<HediffDef>
<defName>rjw_genes_sexually_exhausted</defName>
<hediffClass>HediffWithComps</hediffClass>
<label>Exhausted</label>
<description>Has been exhaused due to sexual activities and needs a little break before being able to stand up again.\n\nWill remove submitting hediff.</description>
<defaultLabelColor>(1,1,1)</defaultLabelColor>
<stages>
<li>
<becomeVisible>true</becomeVisible>
</li>
</stages>
<comps>
<li Class="HediffCompProperties_Disappears">
<disappearsAfterTicks>300~900</disappearsAfterTicks>
<showRemainingTime>true</showRemainingTime>
</li>
<li Class="RJW_Genes.HediffCompProperties_RemoveSubmit"/>
</comps>
</HediffDef>
</Defs>

View File

@ -14,4 +14,12 @@
<reportString>Healing someone with sex.</reportString>
<casualInterruptible>false</casualInterruptible>
</JobDef>
<JobDef>
<defName>rjw_genes_lifeforce_seduced</defName>
<driverClass>RJW_Genes.JobDriver_Seduced</driverClass>
<reportString>Seduced.</reportString>
<casualInterruptible>false</casualInterruptible>
<playerInterruptible>false</playerInterruptible>
</JobDef>
</Defs>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<JobDef>
<defName>sex_on_spot</defName>
<driverClass>RJW_Genes.JobDriver_SexOnSpot</driverClass>
<reportString>Making love on the spot.</reportString>
<casualInterruptible>false</casualInterruptible>
</JobDef>
<JobDef>
<defName>sex_on_spot_reciever</defName>
<driverClass>RJW_Genes.JobDriver_SexOnSpotReciever</driverClass>
<reportString>lovin'.</reportString>
<casualInterruptible>false</casualInterruptible>
</JobDef>
</Defs>

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using Verse.AI;
using rjw;
namespace RJW_Genes
{
public class CompAbilityEffect_Seduce : CompAbilityEffect_WithDest
{
private new CompProperties_Seduce Props
{
get
{
return (CompProperties_Seduce)this.props;
}
}
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
{
base.Apply(target, dest);
Pawn pawn = target.Thing as Pawn;
Pawn pawn2 = this.parent.pawn;
if (pawn != null && pawn2 != null && !pawn.Downed)
{
Job job = JobMaker.MakeJob(JobDefOf.rjw_genes_lifeforce_seduced, pawn2);//ChooseJob(pawn, pawn2);
job.mote = MoteMaker.MakeThoughtBubble(pawn, this.parent.def.iconPath, true); //make this image of pawn or else heart
pawn.jobs.StopAll(false, true);
pawn.jobs.StartJob(job, JobCondition.InterruptForced, null, false, true, null, null, false, false, null, false, true);
}
}
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
{
Pawn pawn = target.Pawn;
if (pawn != null)
{
if (!xxx.can_be_fucked(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;
}
else if (pawn.Downed)
{
if (throwMessages)
{
Messages.Message(pawn.Name + " is unable to move", pawn, MessageTypeDefOf.RejectInput, false);
}
return false;
}
}
return base.Valid(target, throwMessages);
}
public override bool GizmoDisabled(out string reason)
{
reason = null;
if (!RJWSettings.rape_enabled)
{
reason = "Rape is disabled";
return true;
}
return false;
}
}
}

View File

@ -0,0 +1,21 @@
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_Seduce : CompProperties_EffectWithDest
{
public CompProperties_Seduce()
{
this.compClass = typeof(CompAbilityEffect_Seduce);
}
public StatDef durationMultiplier;
}
}

View File

@ -29,13 +29,10 @@ namespace RJW_Genes
{
yield return gizmo;
}
IEnumerator<Gizmo> enumerator = null;
foreach (Gizmo gizmo2 in GeneResourceDrainUtility.GetResourceDrainGizmos(this))
{
yield return gizmo2;
}
enumerator = null;
yield break;
yield break;
}

View File

@ -0,0 +1,18 @@
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 HediffCompProperties_RemoveSubmit :HediffCompProperties
{
public HediffCompProperties_RemoveSubmit()
{
this.compClass = typeof(HediffComp_RemoveSubmit);
}
}
}

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using rjw;
namespace RJW_Genes
{
public class HediffComp_RemoveSubmit : HediffComp
{
public HediffCompProperties_RemoveSubmit Props
{
get
{
return (HediffCompProperties_RemoveSubmit)this.props;
}
}
public override void CompPostPostRemoved()
{
base.CompPostPostRemoved();
HediffWithComps submitting = this.Pawn.health.hediffSet.GetFirstHediffOfDef(xxx.submitting) as HediffWithComps;
submitting.CurStage.becomeVisible = false;
if (submitting != null)
{
foreach (HediffComp comp in submitting.comps)
{
HediffComp_Disappears hediffComp = comp as HediffComp_Disappears;
if (hediffComp != null)
{
hediffComp.ticksToDisappear = 1;
//pawn.health.RemoveHediff(submitting);
//removing the hediff directly gives an error, ArgementOutOrRange, making the remaining time 1 ticks should have the same effect without the error
}
}
}
}
}
}

View File

@ -1,131 +0,0 @@
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;
using rjw.Modules.Interactions.Enums;
using rjw.Modules.Interactions.Helpers;
using rjw.Modules.Interactions.Objects;
using rjw.Modules.Interactions.Contexts;
using rjw.Modules.Interactions.Implementation;
namespace RJW_Genes
{
public class JobDriver_DrinkCumflation : JobDriver_SexBaseInitiator
{
//Summary//
//WIP is for custom interaction
protected override IEnumerable<Toil> MakeNewToils()
{
base.setup_ticks();
this.rape = !LovePartnerRelationUtility.LovePartnerRelationExists(this.pawn, this.Partner);
JobDef PartnerJob = rape? xxx.gettin_raped: xxx.getting_quickie;
this.FailOnDestroyedNullOrForbidden(TargetIndex.A);
this.FailOnSomeonePhysicallyInteracting(TargetIndex.A);
this.FailOn(() => this.pawn.Drafted);
this.FailOn(() => this.pawn.IsFighting());
this.FailOn(() => this.Partner.IsFighting());
yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch);
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.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;
this.SetInteraction();
this.cumflation = this.Partner.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("Cumflation"));
this.gene_LifeForce = (this.pawn.genes != null) ? this.pawn.genes.GetFirstGeneOfType<Gene_LifeForce>() : null;
this.Start();
};
toil.tickAction = 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, 2f);
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 break;
}
public void Reduce_Cumflation()
{
this.reductiontick--;
if (reductiontick <= 0)
{
if (this.cumflation != null && this.gene_LifeForce != null)
{
this.cumflation.Severity =+ 0.01f;
gene_LifeForce.Resource.Value += 0.01f;
}
this.reductiontick = 60;
}
}
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
return this.pawn.Reserve(this.job.GetTarget(TargetIndex.A), this.job, 1, -1, null, errorOnFailed);
}
public void SetInteraction()
{
InteractionDef interaction = rape ? DefDatabase<InteractionDef>.GetNamed("Rape_Reverse_Cunnilingus") : DefDatabase<InteractionDef>.GetNamed("Sex_Reverse_Cunnilingus");
SpecificInteractionInputs inputs = new SpecificInteractionInputs
{
Initiator = this.pawn,
Partner = this.Partner,
Interaction = interaction
};
InteractionOutputs interactionOutputs = SpecificLewdInteractionService.Instance.GenerateSpecificInteraction(inputs);
this.Sexprops.sexType = interactionOutputs.Generated.RjwSexType;
this.Sexprops.rulePack = interactionOutputs.Generated.RulePack.defName;
this.Sexprops.dictionaryKey = interaction;
this.Sexprops.isRapist = rape;
this.Sexprops.isWhoring = false;
this.Sexprops.isRevese = true;
}
public Hediff cumflation;
public Gene_LifeForce gene_LifeForce;
int reductiontick = 60;
bool rape = false;
}
}

View File

@ -0,0 +1,54 @@
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;
using rjw.Modules.Interactions.Enums;
using rjw.Modules.Interactions.Helpers;
using rjw.Modules.Interactions.Objects;
using rjw.Modules.Interactions.Contexts;
using rjw.Modules.Interactions.Implementation;
namespace RJW_Genes
{
public class JobDriver_Seduced : JobDriver
{
//Summary//
//Makes a pawn move to seducing pawn and then tries to rape them.
protected override IEnumerable<Toil> MakeNewToils()
{
this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
this.FailOn(() => !this.pawn.CanReserve(TargetA, xxx.max_rapists_per_prisoner, 0, null, false));
this.FailOn(() => this.pawn.IsFighting());
this.FailOn(() => this.pawn.Drafted);
Pawn partner = this.job.GetTarget(TargetIndex.A).Pawn;
yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);
yield return new Toil
{
defaultCompleteMode = ToilCompleteMode.Instant,
socialMode = RandomSocialMode.Off,
initAction = delegate ()
{
if(partner != null)
{
partner.drafter.Drafted = false;
Job newJob = JobMaker.MakeJob(JobDefOf.sex_on_spot, pawn);
partner.jobs.StartJob(newJob, JobCondition.InterruptForced, null, false, true, null, null, false, false, null, false, true);
}
}
};
yield break;
}
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
return this.pawn.Reserve(TargetA, this.job, xxx.max_rapists_per_prisoner, 0, null, errorOnFailed);
}
}
}

View File

@ -0,0 +1,108 @@
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;
using rjw.Modules.Interactions.Enums;
using rjw.Modules.Interactions.Helpers;
using rjw.Modules.Interactions.Objects;
using rjw.Modules.Interactions.Contexts;
using rjw.Modules.Interactions.Implementation;
namespace RJW_Genes
{
public class JobDriver_SexOnSpot : JobDriver_SexBaseInitiator
{
protected override IEnumerable<Toil> MakeNewToils()
{
if (RJWSettings.DebugRape)
{
ModLog.Message(base.GetType().ToString() + "::MakeNewToils() called");
}
base.setup_ticks();
JobDef PartnerJob = JobDefOf.sex_on_spot_reciever;
this.FailOnDespawnedNullOrForbidden(this.iTarget);
this.FailOn(() => !this.pawn.CanReserve(this.Partner, xxx.max_rapists_per_prisoner, 0, null, false));
this.FailOn(() => this.pawn.IsFighting());
this.FailOn(() => this.Partner.IsFighting());
this.FailOn(() => this.pawn.Drafted);
yield return Toils_Goto.GotoThing(this.iTarget, PathEndMode.Touch);
if (this.pawn.HostileTo(this.Partner))
{
Partner.health.AddHediff(xxx.submitting);
}
yield return Toils_Goto.GotoThing(this.iTarget, PathEndMode.OnCell);
//Give thought malus to partner (I was seduced into having sex against my will)
yield return new Toil
{
defaultCompleteMode = ToilCompleteMode.Instant,
socialMode = RandomSocialMode.Off,
initAction = delegate ()
{
if (!(this.Partner.jobs.curDriver is JobDriver_SexOnSpotReciever))
{
Job newJob = JobMaker.MakeJob(PartnerJob, this.pawn);
Building_Bed building_Bed = null;
if (this.Partner.GetPosture() == PawnPosture.LayingInBed)
{
building_Bed = this.Partner.CurrentBed();
}
this.Partner.jobs.StartJob(newJob, JobCondition.InterruptForced, null, false, true, null, null, false, false, null, false, true);
if (building_Bed != null)
{
JobDriver_SexOnSpotReciever jobDriver_SexOnSpotReciever = this.Partner.jobs.curDriver as JobDriver_SexOnSpotReciever;
if (jobDriver_SexOnSpotReciever == null)
{
return;
}
jobDriver_SexOnSpotReciever.Set_bed(building_Bed);
}
}
}
};
Toil toil = new Toil();
toil.defaultCompleteMode = ToilCompleteMode.Never;
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;
this.Start();
};
toil.tickAction = 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, 2f);
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 break;
}
}
}

View File

@ -0,0 +1,84 @@
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;
using rjw.Modules.Interactions.Enums;
using rjw.Modules.Interactions.Helpers;
using rjw.Modules.Interactions.Objects;
using rjw.Modules.Interactions.Contexts;
using rjw.Modules.Interactions.Implementation;
namespace RJW_Genes
{
//Modified JobDriver_SexBaseRecieverLoved from rjw
public class JobDriver_SexOnSpotReciever : JobDriver_SexBaseReciever
{
protected override IEnumerable<Toil> MakeNewToils()
{
base.setup_ticks();
this.parteners.Add(base.Partner);
if (this.pawn.relations.OpinionOf(base.Partner) < 0)
{
this.ticks_between_hearts += 50;
}
else if (this.pawn.relations.OpinionOf(base.Partner) > 60)
{
this.ticks_between_hearts -= 25;
}
this.FailOnDespawnedOrNull(this.iTarget);
this.FailOn(() => !base.Partner.health.capacities.CanBeAwake);
this.FailOn(() => this.pawn.Drafted);
this.FailOn(() => base.Partner.Drafted);
yield return Toils_Reserve.Reserve(this.iTarget, 1, 0, null);
Toil toil2 = this.MakeSexToil();
toil2.handlingFacing = false;
yield return toil2;
yield break;
}
// Token: 0x06000420 RID: 1056 RVA: 0x00024190 File Offset: 0x00022390
private Toil MakeSexToil()
{
Toil toil = new Toil();
toil.defaultCompleteMode = ToilCompleteMode.Never;
toil.socialMode = RandomSocialMode.Off;
toil.handlingFacing = true;
toil.tickAction = delegate ()
{
if (this.pawn.IsHashIntervalTick(this.ticks_between_hearts))
{
base.ThrowMetaIconF(this.pawn.Position, this.pawn.Map, FleckDefOf.Heart);
}
};
toil.AddEndCondition(delegate
{
if (this.parteners.Count <= 0)
{
return JobCondition.Succeeded;
}
return JobCondition.Ongoing;
});
toil.AddFinishAction(delegate
{
if (xxx.is_human(this.pawn))
{
this.pawn.Drawer.renderer.graphics.ResolveApparelGraphics();
}
GlobalTextureAtlasManager.TryMarkPawnFrameSetDirty(this.pawn);
Hediff submitting = this.pawn.health.hediffSet.GetFirstHediffOfDef(xxx.submitting);
if (submitting != null)
{
this.pawn.health.RemoveHediff(submitting);
this.pawn.stances.stunner.StunFor(60, this.pawn, true, true);
}
});
toil.socialMode = RandomSocialMode.Off;
return toil;
}
}
}

View File

@ -44,9 +44,6 @@ namespace RJW_Genes
public static void DrinkCumflation(Pawn dom, Pawn sub)
{
Log.Message("Firese");
Log.Message(dom.Name.ToString());
Log.Message(sub.Name.ToString());
if (GeneUtility.HasLifeForce(sub) && dom.health.hediffSet.HasHediff(HediffDef.Named("Cumflation")))
{
Hediff cumflation = dom.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("Cumflation"));
@ -55,6 +52,6 @@ namespace RJW_Genes
gene_LifeForce.Resource.Value += 0.05f;
}
}
//Maybe i can store instance and hediff so I dont need to look them up every time
//Maybe I can store gene and hediff so I dont need to look them up every time
}
}

View File

@ -19,19 +19,24 @@ namespace RJW_Genes
base.Tick();
if (this.pawn.IsHashIntervalTick(2500))
{
foreach (Pawn pawn in this.AffectedPawns(this.pawn.Position, this.pawn.Map))
{
this.InduceAphrodisiac(pawn);
}
//Only spread pheromones if sexdrive above 1
float sexfrequency = this.pawn.GetStatValue(StatDef.Named("SexFrequency"));
if(sexfrequency > 1f)
{
foreach (Pawn pawn in this.AffectedPawns(this.pawn.Position, this.pawn.Map))
{
this.InduceAphrodisiac(pawn, sexfrequency);
}
}
}
}
//Creatus an IEnumerable of all pawns which are closeby and in lineofsight
//Creatus an IEnumerable of all pawns which are closeby and in lineofsight, self and other pawns with aphrodisiac pheromones gene are skipped.
private IEnumerable<Pawn> AffectedPawns(IntVec3 pos, Map map)
{
foreach (Pawn pawn in map.mapPawns.AllPawns)
{
if (pos.DistanceTo(pawn.Position) < 5 && GenSight.LineOfSight(pos, pawn.Position, pawn.Map))
if (this.pawn != null && pawn != this.pawn && pos.DistanceTo(pawn.Position) < 5 && GenSight.LineOfSight(pos, pawn.Position, pawn.Map) && !GeneUtility.HasGeneNullCheck(pawn, GeneDefOf.rjw_genes_aphrodisiac_pheromones))
{
yield return pawn;
}
@ -41,17 +46,35 @@ namespace RJW_Genes
}
//Applies er renews a hediff which increases sexdrive for 6 hours
private void InduceAphrodisiac(Pawn pawn)
private void InduceAphrodisiac(Pawn pawn, float sexfrequency)
{
Hediff hediff = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Aphrodisiac_Pheromone);
if (hediff != null)
{
hediff.Severity = 1f;
}
else
{
pawn.health.AddHediff(HediffDefOf.Aphrodisiac_Pheromone);
Hediff aphrodisiac = HediffMaker.MakeHediff(HediffDefOf.Aphrodisiac_Pheromone, pawn);
foreach (StatModifier stat in aphrodisiac.CurStage.statFactors)
{
//Log.Message(pawn.Name.ToString());
//Log.Message(stat.stat.defName);
//Log.Message(stat.value.ToString());
if (stat.stat.defName == "SexFrequency")
{
stat.value = ModifySexfrequency(pawn, sexfrequency);
pawn.health.AddHediff(aphrodisiac);
}
}
}
}
//Function to modify aphrodisiac strength, currently has no effect, but it's an easy hook for other modders.
public float ModifySexfrequency(Pawn pawn, float sexfrequency)
{
return sexfrequency;
}
}
}

View File

@ -14,5 +14,6 @@ namespace RJW_Genes
public static readonly HediffDef Aphrodisiac_Pheromone;
public static readonly HediffDef Fertilin_Lost;
public static readonly HediffDef Succubus_Drained;
public static readonly HediffDef rjw_genes_sexually_exhausted;
}
}

View File

@ -19,17 +19,14 @@ namespace RJW_Genes.Interactions
Pawn pawn = context.Internals.Dominant.Pawn;
if (GeneUtility.HasCriticalLifeForce(pawn))
{
Log.Message("Critical");
yield return new Weighted<LewdablePartKind>(50f, LewdablePartKind.Mouth);
}
else if (GeneUtility.HasLowLifeForce(pawn))
{
Log.Message("Low");
yield return new Weighted<LewdablePartKind>(10f, LewdablePartKind.Mouth);
}
else if (GeneUtility.HasLifeForce(pawn))
{
Log.Message("normal");
yield return new Weighted<LewdablePartKind>(2f, LewdablePartKind.Mouth);
}
yield break;
@ -40,17 +37,14 @@ namespace RJW_Genes.Interactions
Pawn pawn = context.Internals.Submissive.Pawn;
if (GeneUtility.HasCriticalLifeForce(pawn))
{
Log.Message("Critical");
yield return new Weighted<LewdablePartKind>(50f, LewdablePartKind.Mouth);
}
else if (GeneUtility.HasLowLifeForce(pawn))
{
Log.Message("Low");
yield return new Weighted<LewdablePartKind>(10f, LewdablePartKind.Mouth);
}
else if (GeneUtility.HasLifeForce(pawn))
{
Log.Message("normal");
yield return new Weighted<LewdablePartKind>(2f, LewdablePartKind.Mouth);
}
yield break;

View File

@ -11,5 +11,8 @@ namespace RJW_Genes
public static class JobDefOf
{
public static readonly JobDef rjw_genes_lifeforce_randomrape;
public static readonly JobDef rjw_genes_lifeforce_seduced;
public static readonly JobDef sex_on_spot;
public static readonly JobDef sex_on_spot_reciever;
}
}

View File

@ -115,11 +115,17 @@
<Compile Include="Genes\Genitalia\Gene_EquineGenitalia.cs" />
<Compile Include="Genes\Genitalia\GenitaliaChanger.cs" />
<Compile Include="Genes\Life_Force\AbilityUtility.cs" />
<Compile Include="Genes\Life_Force\CompAbilityEffect_Seduce.cs" />
<Compile Include="Genes\Life_Force\CompAbilityEffect_LifeForceCost.cs" />
<Compile Include="Genes\Life_Force\CompAbilityEffect_CockEater.cs" />
<Compile Include="Genes\Life_Force\CompProperties_Seduce.cs" />
<Compile Include="Genes\Life_Force\CompProperties_AbilityCockEater.cs" />
<Compile Include="Genes\Life_Force\HediffCompProperties_RemoveSubmit.cs" />
<Compile Include="Genes\Life_Force\HediffComp_RemoveSubmit.cs" />
<Compile Include="Genes\Life_Force\IngestionOutcomeDoer_LifeForceOffset.cs" />
<Compile Include="Genes\Life_Force\JobDriver_Drink_Cumflation.cs" />
<Compile Include="Genes\Life_Force\JobDriver_SexOnSpotReceiver.cs" />
<Compile Include="Genes\Life_Force\JobDriver_SexOnSpot.cs" />
<Compile Include="Genes\Life_Force\JobDriver_Seduced.cs" />
<Compile Include="Genes\Life_Force\Patch_SexTicks_ChangePsyfocus.cs" />
<Compile Include="Genes\Life_Force\ThinkNode_ConditionalLowLifeForce.cs" />
<Compile Include="Genes\Life_Force\ThinkNode_ConditionalCritcalLifeForce.cs" />
@ -157,5 +163,6 @@
<ItemGroup>
<Content Include="GeneDefs_GenitaliaTypeEndogenes.xml" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>