Reworked Healpussy so that it now does rjw sex and the sex is vaginal

This commit is contained in:
Shabakur 2022-11-20 12:59:42 +01:00
parent f548a48152
commit 4181d80d5d
22 changed files with 390 additions and 6 deletions

View File

@ -11,13 +11,13 @@
<warmupMote>Mote_CoagulateStencil</warmupMote>
<warmupEffecter>Coagulate</warmupEffecter>
<warmupStartSound>Coagulate_Cast</warmupStartSound>
<jobDef>CastAbilityOnThingMelee</jobDef>
<jobDef>HealPussy</jobDef>
<displayOrder>401</displayOrder>
<verbProperties>
<verbClass>Verb_CastAbilityTouch</verbClass>
<drawAimPie>false</drawAimPie>
<range>-1</range>
<warmupTime>1</warmupTime>
<warmupTime>0</warmupTime>
<targetParams>
<canTargetAnimals>false</canTargetAnimals>
<canTargetSelf>false</canTargetSelf>
@ -27,12 +27,23 @@
</targetParams>
</verbProperties>
<comps>
<li Class="shabe_genesaddons.CompProperties_AbilityPussyHeal"> <!-- needs to be changed when copied to another mod-->
<tendQualityRange>0.4~0.8</tendQualityRange>
<li Class="shabe_genesaddons.CompProperties_AbilityPussyHeal"> <!-- namespace needs to be changed when copied to another mod-->
<tendQualityRange>0.4~0.8</tendQualityRange>
</li>
<li Class="CompProperties_AbilityRequiresCapacity">
<capacity>Manipulation</capacity>
</li>
<li Class="shabe_genesaddons.CompProperties_SexInteractionRequirements">
<tags>
<li>Consensual</li>
<li>Rape</li>
</tags>
<dominantRequirement>
<families>
<li>Vagina</li>
</families>
</dominantRequirement>
</li>
</comps>
</AbilityDef>
</Defs>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<JobDef>
<defName>HealPussy</defName>
<driverClass>shabe_genesaddons.JobDriver_CastAbilityAfterSex</driverClass>
<reportString>Healing someone with sex.</reportString>
<casualInterruptible>false</casualInterruptible>
</JobDef>
</Defs>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ThoughtDef>
<defName>Pussy_Healed</defName>
<thoughtClass>Thought_Memory</thoughtClass>
<durationDays>3.0</durationDays>
<stackLimit>1</stackLimit>
<stages>
<li>
<label>Healed with sex</label>
<description>Someone tended to my wound through having sex.</description>
<baseMoodEffect>5</baseMoodEffect>
</li>
</stages>
</ThoughtDef>
</Defs>

View File

@ -7,6 +7,7 @@ using Verse;
using UnityEngine;
using RimWorld;
using rjw;
using rjw.Modules.Interactions.Helpers;
namespace shabe_genesaddons
{
@ -41,7 +42,24 @@ namespace shabe_genesaddons
{
MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, "NumWoundsTended".Translate(num), 3.65f);
}
FleckMaker.AttachedOverlay(pawn, FleckDefOf.FlashHollow, Vector3.zero, 1.5f, -1f);
this.AfterSex(this.parent.pawn, pawn);
//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)
@ -49,6 +67,8 @@ namespace shabe_genesaddons
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))
{
@ -58,6 +78,15 @@ namespace shabe_genesaddons
}
return false;
}
Pawn parent = this.parent.pawn;
if (parent == null || !Genital_Helper.has_vagina(parent))
{
if (throwMessages && parent != null)
{
Messages.Message(parent.Name + " has no vagina to use", pawn, MessageTypeDefOf.RejectInput, false);
}
return false;
}
AbilityUtility.ValidateHasTendableWound(pawn, throwMessages, this.parent);
}

View 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 shabe_genesaddons
{
public class CompAbility_SexInteractionRequirements : AbilityComp
{
public CompProperties_SexInteractionRequirements Props
{
get
{
return (CompProperties_SexInteractionRequirements)this.props;
}
}
}
}

View File

@ -0,0 +1,24 @@
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 shabe_genesaddons
{
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

@ -0,0 +1,86 @@
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 shabe_genesaddons
{
public class JobDriver_CastAbilityAfterSex : JobDriver_SexBaseInitiator
{
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;
foreach (AbilityComp comp in this.job.ability.comps)
{
if (comp.props is CompProperties_SexInteractionRequirements)
{
CompProperties_SexInteractionRequirements sexpropsreq = comp.props as CompProperties_SexInteractionRequirements;
this.Sexprops = SexInteractionUtility.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;
}
}
}

View File

@ -0,0 +1,167 @@
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;
//using rjw.Modules.Interactions.Enums;
namespace shabe_genesaddons
{
class SexInteractionUtility
{
public static List<InteractionDef> GenerateDomVaginaInteractionDefList(Pawn pawn, Pawn pawn2)
{
List<InteractionDef> list2 = new List<InteractionDef>();
foreach (InteractionDef interactionDef in SexUtility.SexInterractions)
{
InteractionWithExtension withExtension = InteractionHelper.GetWithExtension(interactionDef);
if((withExtension.DominantHasTag(GenitalTag.CanBePenetrated) || withExtension.DominantHasFamily(GenitalFamily.Vagina))
&& LewdInteractionValidatorService.Instance.IsValid(interactionDef, pawn, pawn2))
{
//Log.Message(interactionDef.ToString());
list2.Add(interactionDef);
}
}
return list2;
}
public static List<InteractionDef> GenerateInteractionDefList(Pawn pawn, Pawn pawn2, CompProperties_SexInteractionRequirements sexpropsreq)
{
List<InteractionTag> 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;
foreach (InteractionDef interactionDef in SexUtility.SexInterractions)
{
if (!LewdInteractionValidatorService.Instance.IsValid(interactionDef, pawn, pawn2))
{
continue;
}
InteractionWithExtension withExtension = InteractionHelper.GetWithExtension(interactionDef);
bool add_interaction = false;
foreach (InteractionTag tag in tags)
{
if (withExtension.HasInteractionTag(tag))
{
add_interaction = true;
}
}
if (!add_interaction)
{
continue;
}
if (dominantRequirement != null)
{
foreach (GenitalFamily genitalFamily in dominantRequirement.families)
{
if (!withExtension.DominantHasFamily(genitalFamily))
{
add_interaction = false;
}
}
if (!add_interaction)
{
continue;
}
foreach (GenitalTag tag in dominantRequirement.tags)
{
if (!withExtension.DominantHasTag(tag))
{
add_interaction = false;
}
}
}
if (submissiveRequirement != null)
{
foreach (GenitalFamily genitalFamily in submissiveRequirement.families)
{
if (!withExtension.SubmissiveHasFamily(genitalFamily))
{
add_interaction = false;
}
}
if (!add_interaction)
{
continue;
}
foreach (GenitalTag tag in submissiveRequirement.tags)
{
if (!withExtension.SubmissiveHasTag(tag))
{
add_interaction = false;
}
}
}
if (add_interaction)
{
list.Add(interactionDef);
}
}
return list;
}
public static SexProps GenerateSexProps(Pawn pawn, Pawn pawn2, CompProperties_SexInteractionRequirements sexpropsreq)
{
List<InteractionDef> interactionlist = GenerateInteractionDefList(pawn, pawn2, sexpropsreq);
if (interactionlist == null)
{
return null;
}
//foreach(InteractionDef interaction in interactionlist)
//{
// Log.Message(interaction.ToString());
//}
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;
}
public static SexProps GenerateSexpropsDomVagina(Pawn pawn, Pawn pawn2)
{
List<InteractionDef> interactionlist = GenerateDomVaginaInteractionDefList(pawn, pawn2);
if (interactionlist == null)
{
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

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
namespace shabe_genesaddons
{
[DefOf]
public static class ThoughtDefOf
{
public static readonly ThoughtDef Pussy_Healed;
}
}

View File

@ -1 +1 @@
5a8b4a39089fb64409d7431a53405d599f8307c0
6ecf46e37be50c69fa3cb87cd34ade9851fe6e74

View File

@ -58,14 +58,19 @@
</ItemGroup>
<ItemGroup>
<Compile Include="CompAbilityEffect_PussyHeal.cs" />
<Compile Include="CompAbility_SexInteractionRequirements.cs" />
<Compile Include="CompProperties_AbilityPussyHeal.cs" />
<Compile Include="CompProperties_SexInteractionRequirements.cs" />
<Compile Include="GeneDefOf.cs" />
<Compile Include="HarmonyInit.cs" />
<Compile Include="JobDriver_CastAbilityAfterSex.cs" />
<Compile Include="PatchMechBirth.cs" />
<Compile Include="PatchPawnExtensions.cs" />
<Compile Include="PatchPregnancyHelper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="GeneUtility.cs" />
<Compile Include="SexInteractionUtility.cs" />
<Compile Include="ThoughtDefOf.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>