Support for multiple vaginas

This commit is contained in:
lutepickle 2022-07-11 11:52:27 -07:00
parent 20692aaf13
commit 699c91106f
16 changed files with 106 additions and 106 deletions

Binary file not shown.

View File

@ -9,28 +9,32 @@ namespace RJW_Menstruation
[DebugAction("RJW Menstruation", "Set pawn's state to follicular", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
private static void SetFollicular(Pawn p)
{
p.GetMenstruationComp().curStage = HediffComp_Menstruation.Stage.Follicular;
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.curStage = HediffComp_Menstruation.Stage.Follicular;
Messages.Message($"{p} is now follicular", MessageTypeDefOf.NeutralEvent, false);
}
[DebugAction("RJW Menstruation", "Set pawn's state to ovulatory", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
private static void SetOvulatory(Pawn p)
{
p.GetMenstruationComp().curStage = HediffComp_Menstruation.Stage.Ovulatory;
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.curStage = HediffComp_Menstruation.Stage.Ovulatory;
Messages.Message($"{p} is now ovulatory", MessageTypeDefOf.NeutralEvent, false);
}
[DebugAction("RJW Menstruation", "Set pawn's state to luteal", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
private static void SetLuteal(Pawn p)
{
p.GetMenstruationComp().curStage = HediffComp_Menstruation.Stage.Luteal;
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.curStage = HediffComp_Menstruation.Stage.Luteal;
Messages.Message($"{p} is now luteal", MessageTypeDefOf.NeutralEvent, false);
}
[DebugAction("RJW Menstruation", "Set pawn's state to bleeding", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
private static void SetBleeding(Pawn p)
{
p.GetMenstruationComp().curStage = HediffComp_Menstruation.Stage.Bleeding;
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.curStage = HediffComp_Menstruation.Stage.Bleeding;
Messages.Message($"{p} is now bleeding", MessageTypeDefOf.NeutralEvent, false);
}
/*
@ -49,21 +53,24 @@ namespace RJW_Menstruation
[DebugAction("RJW Menstruation", "Remove all cum from pawn's womb", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
private static void RemoveCums(Pawn p)
{
p.GetMenstruationComp().RemoveAllCums();
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.RemoveAllCums();
Messages.Message($"All cum removed from {p}'s womb", MessageTypeDefOf.NeutralEvent, false);
}
[DebugAction("RJW Menstruation", "Add egg to pawn's next ovulation", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
private static void AddEgg(Pawn p)
{
p.GetMenstruationComp().eggstack++;
Messages.Message($"1 egg added to {p}'s next ovulation ({p.GetMenstruationComp().eggstack})", MessageTypeDefOf.NeutralEvent, false);
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.eggstack++;
Messages.Message($"1 egg added to {p}'s next ovulation ({p.GetFirstMenstruationComp().eggstack})", MessageTypeDefOf.NeutralEvent, false);
}
[DebugAction("RJW Menstruation", "Recalculate pawn's ovary power", false, false, actionType = DebugActionType.ToolMapForPawns, allowedGameStates = AllowedGameStates.Playing)]
private static void RecalculateOvaryPower(Pawn p)
{
p.GetMenstruationComp().ovarypower = p.GetMenstruationComp().GetOvaryPowerByAge();
Messages.Message($"{p}'s ovarypower recalculated ({p.GetMenstruationComp().ovarypower})", MessageTypeDefOf.NeutralEvent, false);
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
comp.ovarypower = comp.GetOvaryPowerByAge();
Messages.Message($"{p}'s ovarypower recalculated ({p.GetFirstMenstruationComp().ovarypower})", MessageTypeDefOf.NeutralEvent, false);
}
}
}

View File

@ -10,18 +10,18 @@ namespace RJW_Menstruation
{
protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested)
{
HediffComp_Menstruation comp = pawn.GetMenstruationComp();
if (comp != null && (comp.curStage.Equals(HediffComp_Menstruation.Stage.Follicular)
foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps())
if(comp.curStage.Equals(HediffComp_Menstruation.Stage.Follicular)
|| comp.curStage.Equals(HediffComp_Menstruation.Stage.Luteal)
|| comp.curStage.Equals(HediffComp_Menstruation.Stage.ClimactericFollicular)
|| comp.curStage.Equals(HediffComp_Menstruation.Stage.ClimactericLuteal)
|| comp.curStage.Equals(HediffComp_Menstruation.Stage.Anestrus)
))
{
comp.SetEstrus(comp.Props.eggLifespanDays);
comp.curStage = HediffComp_Menstruation.Stage.Ovulatory;
comp.ovarypower--;
}
)
{
comp.SetEstrus(comp.Props.eggLifespanDays);
comp.curStage = HediffComp_Menstruation.Stage.Ovulatory;
comp.ovarypower--;
}
}
}
@ -29,11 +29,11 @@ namespace RJW_Menstruation
{
protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested)
{
HediffComp_Menstruation comp = pawn.GetMenstruationComp();
if (comp != null && (comp.curStage.Equals(HediffComp_Menstruation.Stage.Follicular)
foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps())
if (comp.curStage.Equals(HediffComp_Menstruation.Stage.Follicular)
|| comp.curStage.Equals(HediffComp_Menstruation.Stage.ClimactericFollicular)
|| comp.curStage.Equals(HediffComp_Menstruation.Stage.Anestrus)
))
)
{
comp.SetEstrus(comp.Props.eggLifespanDays);
comp.curStage = HediffComp_Menstruation.Stage.Ovulatory;
@ -62,11 +62,8 @@ namespace RJW_Menstruation
protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested)
{
HediffComp_Menstruation comp = pawn.GetMenstruationComp();
if (Configurations.EnableMenopause && comp != null)
{
comp.RecoverOvary(1 + effectOffset);
}
foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps())
if (Configurations.EnableMenopause) comp.RecoverOvary(1 + effectOffset);
}
}
@ -74,13 +71,8 @@ namespace RJW_Menstruation
{
protected override void DoIngestionOutcomeSpecial(Pawn pawn, Thing ingested)
{
HediffComp_Menstruation comp = pawn.GetMenstruationComp();
if (comp != null)
{
foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps())
comp.eggstack += Rand.Range(1, 4);
}
}
}

View File

@ -188,7 +188,7 @@ namespace RJW_Menstruation
public override void CompPostPostRemoved()
{
HugsLibController.Instance.TickDelayScheduler.TryUnscheduleCallback(action);
Log.Message(parent.pawn.Label + "breast tick scheduler removed");
Log.Message(parent.pawn.Label + " breast tick scheduler removed");
base.CompPostPostRemoved();
}

View File

@ -543,7 +543,7 @@ namespace RJW_Menstruation
public override void CompPostPostRemoved()
{
HugsLibController.Instance.TickDelayScheduler.TryUnscheduleCallback(actionref);
Log.Message(parent.pawn.Label + "tick scheduler removed");
Log.Message(parent.pawn.Label + " tick scheduler removed");
base.CompPostPostRemoved();
}

View File

@ -12,22 +12,38 @@ namespace RJW_Menstruation
{
public static class MenstruationUtility
{
[Obsolete("This method is obsolete. Use GetMenstruationComps or a related function instead", false)]
public static HediffComp_Menstruation GetMenstruationComp(this Pawn pawn)
{
return pawn.GetFirstMenstruationComp();
}
public static IEnumerable<HediffComp_Menstruation> GetMenstruationComps(this Pawn pawn)
{
var hedifflist = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn))?.FindAll((Hediff h) => h.def.defName.ToLower().Contains("vagina"));
HediffComp_Menstruation result;
if (hedifflist.NullOrEmpty()) return null;
else
foreach (Hediff hediff in hedifflist)
{
foreach (Hediff h in hedifflist)
{
result = h.TryGetComp<HediffComp_Menstruation>();
if (result != null) return result;
}
HediffComp_Menstruation result = hediff.TryGetComp<HediffComp_Menstruation>();
if (result != null) yield return result;
}
return null;
}
public static HediffComp_Menstruation GetFirstMenstruationComp(this Pawn pawn)
{
return pawn.GetMenstruationComps().FirstOrDefault();
}
public static HediffComp_Menstruation GetRandomMenstruationComp(this Pawn pawn)
{
return pawn.GetMenstruationComps().RandomElementWithFallback();
}
public static HediffComp_Menstruation GetFertileMenstruationComp(this Pawn pawn)
{
List<HediffComp_Menstruation> comps = pawn.GetMenstruationComps().ToList();
HediffComp_Menstruation comp = comps.Where(c => c.IsDangerDay).RandomElementWithFallback();
if (comp == null) return comps.RandomElementWithFallback();
else return comp;
}
public static HediffComp_Menstruation GetMenstruationComp(this Hediff hediff)
@ -63,18 +79,11 @@ namespace RJW_Menstruation
return null;
}
public static float GetFertilityChance(this HediffComp_Menstruation comp)
{
return 1.0f - Mathf.Pow(1.0f - Configurations.FertilizeChance, comp.TotalFertCum * comp.Props.basefertilizationChanceFactor);
}
public static HediffComp_Menstruation.Stage GetCurStage(this Pawn pawn)
{
return GetMenstruationComp(pawn)?.curStage ?? HediffComp_Menstruation.Stage.Bleeding;
}
public static Texture2D GetPregnancyIcon(this HediffComp_Menstruation comp, Hediff hediff)
{
string icon = "";

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using RimWorld;
using Verse;
using Verse.AI;
@ -16,11 +17,10 @@ namespace RJW_Menstruation
protected override IEnumerable<Toil> MakeNewToils()
{
HediffComp_Menstruation Comp = pawn.GetMenstruationComp();
List<HediffComp_Menstruation> comps = pawn.GetMenstruationComps().ToList();
this.FailOn(delegate
{
return !(Comp.TotalCumPercent > 0.001);
return comps.All(comp => comp.TotalCumPercent < 0.001);
});
Toil excreting = Toils_General.Wait(excretingTime, TargetIndex.None);//duration of
@ -30,8 +30,9 @@ namespace RJW_Menstruation
{
initAction = delegate ()
{
Comp.CumOut(null, 0.5f);
if (Comp.TotalCumPercent > 0.001) JumpToToil(excreting);
foreach (HediffComp_Menstruation comp in comps)
comp.CumOut(null, 0.5f);
if (comps.Any(comp => comp.TotalCumPercent > 0.001)) JumpToToil(excreting);
}
};
//yield return excreting;

View File

@ -29,9 +29,8 @@ namespace RJW_Menstruation.Patch
// foreach(Pawn p in PawnsFinder.All_AliveOrDead)
foreach(Pawn p in PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive_OfPlayerFaction.Union(PawnsFinder.AllMapsCaravansAndTravelingTransportPods_Alive_PrisonersOfColony))
{
HediffComp_Menstruation comp = p.GetMenstruationComp();
if (comp is null) continue;
GetCriticalPawnReason_Patch.cummedPawns.UnionWith(comp.GetCummersAndFertilizers());
foreach (HediffComp_Menstruation comp in p.GetMenstruationComps())
GetCriticalPawnReason_Patch.cummedPawns.UnionWith(comp.GetCummersAndFertilizers());
}
}
}

View File

@ -28,11 +28,9 @@ namespace RJW_Menstruation
foreach (Gizmo gizmo in gizmos)
yield return gizmo;
HediffComp_Menstruation comp = __instance.GetMenstruationComp();
if (comp == null) yield break;
foreach (Gizmo gizmo in GetMenstruationGizmos(__instance, comp))
yield return gizmo;
foreach (HediffComp_Menstruation comp in __instance.GetMenstruationComps())
foreach (Gizmo gizmo in GetMenstruationGizmos(__instance, comp))
yield return gizmo;
}
public static List<Gizmo> GetMenstruationGizmos(Pawn pawn, HediffComp_Menstruation comp)

View File

@ -16,20 +16,18 @@ namespace RJW_Menstruation
public static void Postfix(Pawn __instance)
{
//Log.Message("Initialize on spawnsetup");
HediffComp_Menstruation comp = __instance.GetMenstruationComp();
if (comp != null)
foreach (HediffComp_Menstruation comp in __instance.GetMenstruationComps())
{
HugsLibController.Instance.TickDelayScheduler.TryUnscheduleCallback(comp.actionref);
comp.Initialize();
}
HediffComp_Breast bcomp = __instance.GetBreastComp();
if (bcomp != null)
{
HugsLibController.Instance.TickDelayScheduler.TryUnscheduleCallback(bcomp.action);
bcomp.Initialize();
}
}
}

View File

@ -29,7 +29,10 @@ namespace RJW_Menstruation
var pawnparts = Genital_Helper.get_PartsHediffList(pawn, Genital_Helper.get_genitalsBPR(pawn));
HediffComp_Menstruation comp = partner.GetMenstruationComp();
HediffComp_Menstruation comp;
if (pawn.Has(Quirk.ImpregnationFetish) || partner.Has(Quirk.ImpregnationFetish) || partner.IsInEstrus())
comp = pawn.GetFertileMenstruationComp();
else comp = pawn.GetRandomMenstruationComp();
if (comp == null) return true;
if (Genital_Helper.has_penis_fertile(pawn, pawnparts) && PregnancyHelper.CanImpregnate(pawn, partner, sextype))
@ -85,7 +88,10 @@ namespace RJW_Menstruation
public static bool Prefix(Pawn pawn, Pawn partner) // partner has vagina
{
if (partner.IsAnimal() && !Configurations.EnableAnimalCycle) return true;
HediffComp_Menstruation comp = partner.GetMenstruationComp();
HediffComp_Menstruation comp;
if (pawn.Has(Quirk.ImpregnationFetish) || partner.Has(Quirk.ImpregnationFetish) || partner.IsInEstrus())
comp = pawn.GetFertileMenstruationComp();
else comp = pawn.GetRandomMenstruationComp();
if (comp == null)
{
ModLog.Message("used original rjw method: Comp missing");
@ -123,9 +129,9 @@ namespace RJW_Menstruation
// This is stricter than can_impregnate, so quickly filter out scenarios that are negative anyways.
if (__result == false || __instance != Quirk.ImpregnationFetish) return;
__result =
((PregnancyHelper.CanImpregnate(pawn, partner) && (partner.GetMenstruationComp()?.IsDangerDay ?? true))
(PregnancyHelper.CanImpregnate(pawn, partner) && (partner.GetMenstruationComps()?.Any(comp => comp.IsDangerDay) ?? true))
||
(PregnancyHelper.CanImpregnate(partner, pawn) && (pawn.GetMenstruationComp()?.IsDangerDay ?? true)));
(PregnancyHelper.CanImpregnate(partner, pawn) && (pawn.GetMenstruationComps()?.Any(comp => comp.IsDangerDay) ?? true));
}
}
@ -144,9 +150,9 @@ namespace RJW_Menstruation
else __result--;
if (
(PregnancyHelper.CanImpregnate(pawn, partner, props.sexType) && (partner.GetMenstruationComp()?.IsDangerDay ?? true))
(PregnancyHelper.CanImpregnate(pawn, partner, props.sexType) && (partner.GetMenstruationComps()?.Any(comp => comp.IsDangerDay) ?? true))
||
(PregnancyHelper.CanImpregnate(partner, pawn, props.sexType) && (pawn.GetMenstruationComp()?.IsDangerDay ?? true)))
(PregnancyHelper.CanImpregnate(partner, pawn, props.sexType) && (pawn.GetMenstruationComps()?.Any(comp => comp.IsDangerDay) ?? true)))
__result++;
}
}

View File

@ -92,7 +92,7 @@ namespace RJW_Menstruation
int index = pawns.IndexOf(window.pawn);
SoundDefOf.TabOpen.PlayOneShotOnCamera();
Pawn newpawn = pawns[(index + 1) % pawns.Count];
window.ChangePawn(newpawn, newpawn.GetMenstruationComp());
window.ChangePawn(newpawn, newpawn.GetFirstMenstruationComp());
}
else if (window.pawn != pawn)
{

View File

@ -23,8 +23,6 @@ namespace RJW_Menstruation.Sexperience
protected override IEnumerable<Toil> MakeNewToils()
{
HediffComp_Menstruation Comp = pawn.GetMenstruationComp();
//this.FailOn(delegate
//{
// return !(Comp.TotalCumPercent > 0.001);
@ -38,23 +36,26 @@ namespace RJW_Menstruation.Sexperience
{
initAction = delegate ()
{
if (Comp.TotalCumPercent > 0.001)
{
CumMixture mixture = Comp.MixtureOut(RJWSexperience.VariousDefOf.GatheredCum, 0.5f);
float amount = mixture.Volume;
if (mixture.ispurecum)
bool anyExcreted = false;
foreach (HediffComp_Menstruation comp in pawn.GetMenstruationComps())
if (comp.TotalCumPercent > 0.001)
{
Bucket.AddCum(amount);
CumMixture mixture = comp.MixtureOut(RJWSexperience.VariousDefOf.GatheredCum, 0.5f);
float amount = mixture.Volume;
if (mixture.ispurecum)
{
Bucket.AddCum(amount);
}
else
{
GatheredCumMixture cummixture = (GatheredCumMixture)ThingMaker.MakeThing(VariousDefOf.GatheredCumMixture);
cummixture.InitwithCum(mixture);
Bucket.AddCum(amount, cummixture);
}
anyExcreted = true;
}
else
{
GatheredCumMixture cummixture = (GatheredCumMixture)ThingMaker.MakeThing(VariousDefOf.GatheredCumMixture);
cummixture.InitwithCum(mixture);
Bucket.AddCum(amount, cummixture);
}
}
else ReadyForNextToil();
if (Comp.TotalCumPercent > 0.001) JumpToToil(excreting);
if (!anyExcreted) ReadyForNextToil();
if (pawn.GetMenstruationComps().Any(c => c.TotalCumPercent > 0.001)) JumpToToil(excreting);
}
};

View File

@ -18,9 +18,8 @@ namespace RJW_Menstruation.Sexperience
public static void Postfix(Vector3 clickPos, Pawn pawn, List<FloatMenuOption> opts)
{
var targets = GenUI.TargetsAt(clickPos, TargetingParameters.ForBuilding());
HediffComp_Menstruation comp = pawn.GetMenstruationComp();
if (comp != null && comp.TotalCumPercent > 0.001f)
if (pawn.GetMenstruationComps().Any(comp => comp.TotalCumPercent > 0.001f))
foreach (LocalTargetInfo t in targets)
{
if (t.Thing is Building building)
@ -32,10 +31,6 @@ namespace RJW_Menstruation.Sexperience
}
}
}
}
public static FloatMenuOption MakeMenu(Pawn pawn, LocalTargetInfo target)

View File

@ -20,8 +20,7 @@ namespace RJW_Menstruation.Sexperience
[HarmonyPatch("HasJobOnThing")]
public static bool HasJobOnThing(Pawn pawn, ref bool __result)
{
HediffComp_Menstruation comp = pawn.GetMenstruationComp();
if (comp != null && comp.DoCleanWomb && comp.TotalCumPercent > 0.001f && pawn.Map.listerBuildings.ColonistsHaveBuilding(VariousDefOf.CumBucket))
if (pawn.GetMenstruationComps().Any(comp => comp.DoCleanWomb && comp.TotalCumPercent > 0.001f) && pawn.Map.listerBuildings.ColonistsHaveBuilding(VariousDefOf.CumBucket))
{
__result = true;
return false;
@ -33,8 +32,7 @@ namespace RJW_Menstruation.Sexperience
[HarmonyPatch("JobOnThing")]
public static void JobOnThing(Pawn pawn, ref Job __result)
{
HediffComp_Menstruation comp = pawn.GetMenstruationComp();
if (comp != null && comp.DoCleanWomb && comp.TotalCumPercent > 0.001f)
if (pawn.GetMenstruationComps().Any(comp => comp.DoCleanWomb && comp.TotalCumPercent > 0.001f))
{
Building_CumBucket bucket = pawn.FindClosestBucket();
@ -43,10 +41,6 @@ namespace RJW_Menstruation.Sexperience
__result = JobMaker.MakeJob(VariousDefOf.VaginaWashingwithBucket, null, bucket, bucket.Position);
}
}
}
}
}