2022-11-14 14:55:52 +00:00
|
|
|
|
using RimWorld;
|
|
|
|
|
using Verse;
|
|
|
|
|
using rjw;
|
2022-11-14 16:47:43 +00:00
|
|
|
|
using System;
|
2022-11-14 14:55:52 +00:00
|
|
|
|
|
|
|
|
|
namespace RJW_Genes
|
|
|
|
|
{
|
|
|
|
|
public class GenitaliaUtility
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Returns the first (non) overwritten gene from the rjw_genes genitalia genes.
|
|
|
|
|
/// In case the pawn has none, as default the human one is returned.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pawn">the pawn whom to find genitaliagenes for</param>
|
|
|
|
|
/// <returns>The first GeneDef of the pawn related to GenitaliaTypes</returns>
|
|
|
|
|
public static GeneDef GetGenitaliaTypeGeneForPawn(Pawn pawn)
|
|
|
|
|
{
|
2024-06-04 11:08:37 +00:00
|
|
|
|
foreach (var gene in pawn.genes.GenesListForReading)
|
|
|
|
|
{
|
2024-05-26 22:57:57 +00:00
|
|
|
|
if (gene is Gene_GenitaliaType)
|
2022-11-14 14:55:52 +00:00
|
|
|
|
if (!gene.Overridden)
|
2024-06-04 11:08:37 +00:00
|
|
|
|
return gene.def;
|
2022-11-14 14:55:52 +00:00
|
|
|
|
}
|
2022-12-18 21:05:52 +00:00
|
|
|
|
return null;
|
2022-11-14 14:55:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static HediffDef GetPenisForGene(GeneDef gene)
|
|
|
|
|
{
|
2024-05-27 08:42:09 +00:00
|
|
|
|
return gene?.GetModExtension<GenitaliaTypeExtension>()?.penis ?? Genital_Helper.average_penis;
|
2022-11-14 14:55:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-11-14 16:47:43 +00:00
|
|
|
|
public static HediffDef GetVaginaForGene(GeneDef gene)
|
|
|
|
|
{
|
2024-05-27 08:42:09 +00:00
|
|
|
|
return gene?.GetModExtension<GenitaliaTypeExtension>()?.vagina ?? Genital_Helper.average_vagina;
|
2022-11-14 16:47:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static HediffDef GetAnusForGene(GeneDef gene)
|
|
|
|
|
{
|
2024-05-26 22:57:57 +00:00
|
|
|
|
//TODO: Do I want the default to be generic or average for feline,equine and canine?
|
2024-05-27 08:42:09 +00:00
|
|
|
|
return gene?.GetModExtension<GenitaliaTypeExtension>()?.anus ?? Genital_Helper.average_anus;
|
2022-11-14 16:47:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static HediffDef GetBreastsForGene(GeneDef gene)
|
|
|
|
|
{
|
2024-06-04 11:08:37 +00:00
|
|
|
|
return gene?.GetModExtension<GenitaliaTypeExtension>()?.breasts ?? Genital_Helper.average_breasts;
|
2022-11-14 16:47:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-14 14:55:52 +00:00
|
|
|
|
public static bool PawnStillNeedsGenitalia(Pawn pawn)
|
|
|
|
|
{
|
|
|
|
|
// There is the issue that the genes fire in a pseudo-random order
|
|
|
|
|
// Hence it can happen that the pawn still needs genitalia
|
|
|
|
|
// I wanted to make a simple lookup, but I think the genes are applied for all humans encountered so it could be huge
|
|
|
|
|
// So the heuristic is to check if the pawn has any of the 3 standard genitalia OR has all genes ticked that says "I don't want genitalia".
|
|
|
|
|
if (pawn == null) return false;
|
|
|
|
|
|
|
|
|
|
bool pawn_has_any_genitalia =
|
|
|
|
|
Genital_Helper.has_genitals(pawn) || Genital_Helper.has_anus(pawn) || Genital_Helper.has_breasts(pawn);
|
|
|
|
|
|
|
|
|
|
bool pawn_is_not_supposed_to_have_genitalia =
|
|
|
|
|
pawn.genes.GenesListForReading.Any(x => x.def.defName == "rjw_genes_no_penis");
|
|
|
|
|
|
|
|
|
|
if (pawn_is_not_supposed_to_have_genitalia)
|
|
|
|
|
return false;
|
|
|
|
|
else
|
|
|
|
|
return !pawn_has_any_genitalia;
|
|
|
|
|
|
|
|
|
|
}
|
2022-11-14 16:47:43 +00:00
|
|
|
|
|
|
|
|
|
public static bool IsBreasts(Hediff candidate)
|
|
|
|
|
{
|
|
|
|
|
return candidate.def.defName.ToLower().Contains("breast");
|
|
|
|
|
}
|
2024-07-03 17:54:03 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Returns the biggest penis of a pawn.
|
|
|
|
|
/// In case of a identical severity, the highest body size is returned.
|
|
|
|
|
/// For women, or pawns without a penis, null is returned.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pawn"></param>
|
|
|
|
|
/// <returns>The biggest penis of a pawn. Null on women or error.</returns>
|
|
|
|
|
public static Hediff GetBiggestPenis(Pawn pawn)
|
|
|
|
|
{
|
|
|
|
|
Hediff best = null;
|
|
|
|
|
var parts = Genital_Helper.get_AllPartsHediffList(pawn);
|
|
|
|
|
|
|
|
|
|
foreach (var part in parts)
|
|
|
|
|
{
|
|
|
|
|
if (Genital_Helper.is_sex_part(part) && Genital_Helper.is_penis(part))
|
|
|
|
|
{
|
|
|
|
|
if (best == null) best = part;
|
|
|
|
|
|
|
|
|
|
// On a draw of size, we check the body-size.
|
|
|
|
|
if (part.Severity == best.Severity) {
|
|
|
|
|
var partSize = part.TryGetComp<rjw.CompHediffBodyPart>();
|
|
|
|
|
var bestSize = part.TryGetComp<rjw.CompHediffBodyPart>();
|
|
|
|
|
if (partSize == null || bestSize == null) { continue; }
|
|
|
|
|
|
|
|
|
|
best = partSize.SizeOwner > bestSize.SizeOwner ? part : best;
|
|
|
|
|
} else if (part.Severity > best.Severity) {
|
|
|
|
|
best = part;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return best;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static float GetBodySizeOfSexPart(Hediff part)
|
|
|
|
|
{
|
|
|
|
|
if (part == null || part.TryGetComp<rjw.CompHediffBodyPart>() == null)
|
|
|
|
|
return 0.0f;
|
|
|
|
|
else
|
|
|
|
|
return part.TryGetComp<rjw.CompHediffBodyPart>().SizeOwner;
|
|
|
|
|
}
|
2022-11-14 14:55:52 +00:00
|
|
|
|
}
|
2024-07-03 17:54:03 +00:00
|
|
|
|
|
2022-11-14 14:55:52 +00:00
|
|
|
|
}
|