/// <summary> /// Returns true and sets size and hediff if pawn has natural breasts. /// Hediff will still be null for nipples only. /// Otherwise returns false. /// </summary> public static bool TryGetBreastSize(Pawn pawn, out int size, out Hediff hediff) { var chest = Genital_Helper.get_breasts(pawn); if (pawn.health.hediffSet.PartIsMissing(chest)) { size = 0; hediff = null; return(false); } foreach (var candidate_hediff in pawn.health.hediffSet.hediffs) { if (SizeByHediffDef.TryGetValue(candidate_hediff.def, out size)) { hediff = candidate_hediff; return(true); } } if (HasNipplesOnly(pawn, chest)) { size = NipplesOnlyBreastSize; hediff = null; return(true); } size = 0; hediff = null; return(false); }
private static bool on_begin_matin(JobDriver_Mate __instance) { //only reproductive male starts mating job __instance.FailOn(() => !(Genital_Helper.has_penis(__instance.pawn) || Genital_Helper.has_penis_infertile(__instance.pawn))); return(true); }
public static void add_breasts(Pawn pawn, Pawn parent = null, Gender gender = Gender.None) { //--Log.Message("[RJW] add_breasts( " + xxx.get_pawnname(pawn) + " ) called"); BodyPartRecord partBPR = Genital_Helper.get_breastsBPR(pawn); if (partBPR == null) { //--Log.Message("[RJW] add_breasts( " + xxx.get_pawnname(pawn) + " ) - pawn doesn't have a breasts"); return; } else if (pawn.health.hediffSet.PartIsMissing(partBPR)) { //--Log.Message("[RJW] add_breasts( " + xxx.get_pawnname(pawn) + " ) had breasts but were removed."); return; } if (Genital_Helper.has_breasts(pawn)) { //--Log.Message("[RJW] add_breasts( " + xxx.get_pawnname(pawn) + " ) - pawn already has breasts"); return; } //TODO: figure out how to add (flat) breasts to males var racePartType = (pawn.gender == Gender.Female || gender == Gender.Female) ? SexPartType.FemaleBreast : SexPartType.MaleBreast; if (pawn.TryAddRacePart(racePartType)) { return; } LegacySexPartAdder.AddBreasts(pawn, partBPR, parent); }
public static void add_anus(Pawn pawn, Pawn parent = null) { BodyPartRecord partBPR = Genital_Helper.get_anusBPR(pawn); if (partBPR == null) { //--Log.Message("[RJW] add_anus( " + xxx.get_pawnname(pawn) + " ) doesn't have an anus"); return; } else if (pawn.health.hediffSet.PartIsMissing(partBPR)) { //--Log.Message("[RJW] add_anus( " + xxx.get_pawnname(pawn) + " ) had an anus but was removed."); return; } if (Genital_Helper.has_anus(pawn)) { //--Log.Message("[RJW] add_anus( " + xxx.get_pawnname(pawn) + " ) already has an anus"); return; } if (pawn.TryAddRacePart(SexPartType.Anus)) { return; } LegacySexPartAdder.AddAnus(pawn, partBPR, parent); }
public override IEnumerable <BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r) { var gen_blo = Genital_Helper.genitals_blocked(p); if (p.gender == Gender.Male) { foreach (var part in base.GetPartsToApplyOn(p, r)) { if ((!gen_blo) || (part != xxx.genitals)) { yield return(part); } } } else if (xxx.is_female(p)) //This allows futas { foreach (var part in base.GetPartsToApplyOn(p, r)) { if ((!gen_blo) || (part != xxx.genitals)) { yield return(part); } } } }
public static void UpdateBoobitis(Pawn pawn) { var hediff = std.get_infection(pawn, std.boobitis); if (hediff == null || !(hediff.Severity >= 0.20f) || hediff.FullyImmune() || !BreastSize_Helper.TryGetBreastSize(pawn, out var oldSize, out var oldBoobs) || oldSize >= BreastSize_Helper.MaxSize || !RollFor(hediff.Severity > 0.90f ? 1f : 5f)) { return; } var chest = Genital_Helper.get_breasts(pawn); var newSize = oldSize + 1; var newBoobs = BreastSize_Helper.GetHediffDef(newSize); GenderHelper.ChangeSex(pawn, () => { if (oldBoobs != null) { pawn.health.RemoveHediff(oldBoobs); } pawn.health.AddHediff(newBoobs, chest); }); var message = "RJW_BreastsHaveGrownFromBoobitis".Translate(pawn); Messages.Message(message, pawn, MessageTypeDefOf.SilentInput); }
// Should move these function to common public static bool PlantSomething(HediffDef def, Pawn target, bool isToAnal = false, int amount = 1) { if (def == null) { return(false); } if (!isToAnal && !Genital_Helper.has_vagina(target)) { return(false); } if (isToAnal && !Genital_Helper.has_anus(target)) { return(false); } BodyPartRecord genitalPart = (isToAnal) ? Genital_Helper.get_anus(target) : Genital_Helper.get_genitals(target); if (genitalPart != null || genitalPart.parts.Count != 0) { for (int i = 0; i < amount; i++) { target.health.AddHediff(def, genitalPart); } return(true); } return(false); }
public override void MapComponentOnGUI() { if (!triggered_after_load) { triggered_after_load = true; //--Log.Message("[RJW]MapCom_Injector::triggered after load"); if (Genital_Helper.pawns_require_sexualization()) { //--Log.Message("[RJW]MapCom_Injector::sexualize everyone"); Genital_Helper.sexualize_everyone(); } } var currently_visible = Find.VisibleMap == map; if ((!injected_designator) && currently_visible) { Find.ReverseDesignatorDatabase.AllDesignators.Add(new Designator_ComfortPrisoner()); injected_designator = true; } else if (injected_designator && (!currently_visible)) { injected_designator = false; } }
public static void CopyPsychologySexuality(Pawn pawn) { try { int kinsey = pawn.TryGetComp <CompPsychology>().Sexuality.kinseyRating; //Orientation originalOrientation = Comp(pawn).orientation; if (!Genital_Helper.has_genitals(pawn) && pawn.kindDef.race.defName.ToLower().Contains("droid")) { Comp(pawn).orientation = Orientation.Asexual; } else if (kinsey == 0) { Comp(pawn).orientation = Orientation.Heterosexual; } else if (kinsey == 1) { Comp(pawn).orientation = Orientation.MostlyHeterosexual; } else if (kinsey == 2) { Comp(pawn).orientation = Orientation.LeaningHeterosexual; } else if (kinsey == 3) { Comp(pawn).orientation = Orientation.Bisexual; } else if (kinsey == 4) { Comp(pawn).orientation = Orientation.LeaningHomosexual; } else if (kinsey == 5) { Comp(pawn).orientation = Orientation.MostlyHomosexual; } else if (kinsey == 6) { Comp(pawn).orientation = Orientation.Homosexual; } else { Comp(pawn).orientation = Orientation.Asexual; } /*else * Log.Error("RJW::ERRROR - unknown kinsey scale value: " + kinsey);/* * * /*if (Comp(pawn).orientation != originalOrientation) * Log.Message("RJW + Psychology: Inherited pawn " + xxx.get_pawnname(pawn) + " sexuality from Psychology - " + Comp(pawn).orientation);*/ } catch { if (!pawn.IsAnimal()) { Log.Warning("CopyPsychologySexuality " + pawn?.Name + ", def: " + pawn?.def?.defName + ", kindDef: " + pawn?.kindDef?.race.defName); } } }
public static bool AndroidVaginaFertility(Pawn pawn) { //androids only fertile with archotech parts BodyPartRecord Part = Genital_Helper.get_genitalsBPR(pawn); return(pawn.health.hediffSet.hediffs.Any((Hediff hed) => (hed.Part == Part) && (hed.def == Genital_Helper.archotech_vagina) )); }
public override IEnumerable <BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r) { foreach (var part in p.health.hediffSet.GetNotMissingParts()) { if (r.appliedOnFixedBodyParts.Contains(part.def) && ((part != xxx.genitals) || (!Genital_Helper.genitals_blocked(p)))) { yield return(part); } } }
//Plant Insect eggs/mech chips/other preg mod hediff? public static bool PlantSomething(HediffDef def, Pawn target, bool isToAnal = false, int amount = 1) { if (def == null) { return(false); } if (!isToAnal && !Genital_Helper.has_vagina(target)) { return(false); } if (isToAnal && !Genital_Helper.has_anus(target)) { return(false); } BodyPartRecord Part = (isToAnal) ? Genital_Helper.get_anusBPR(target) : Genital_Helper.get_genitalsBPR(target); if (Part != null || Part.parts.Count != 0) { //killoff normal preg if (!isToAnal) { if (RJWSettings.DevMode) { Log.Message("[RJW] removing other pregnancies"); } var preg = GetPregnancy(target); if (preg != null) { if (preg is Hediff_BasePregnancy) { (preg as Hediff_BasePregnancy).Kill(); } else { target.health.RemoveHediff(preg); } } } for (int i = 0; i < amount; i++) { if (RJWSettings.DevMode) { Log.Message("[RJW] planting something weird"); } target.health.AddHediff(def, Part); } return(true); } return(false); }
static bool on_begin_Tick(Hediff_Pregnant __instance) { if (__instance.pawn.IsHashIntervalTick(1000)) { if (!Genital_Helper.has_vagina(__instance.pawn)) { __instance.pawn.health.RemoveHediff(__instance); } } return(true); }
public static void add_genitals(Pawn pawn, Pawn parent = null, Gender gender = Gender.None) { //--Log.Message("Genital_Helper::add_genitals( " + xxx.get_pawnname(pawn) + " ) called"); BodyPartRecord partBPR = Genital_Helper.get_genitalsBPR(pawn); var parts = Genital_Helper.get_PartsHediffList(pawn, partBPR); //--Log.Message("Genital_Helper::add_genitals( " + xxx.get_pawnname(pawn) + " ) - checking genitals"); if (partBPR == null) { //--Log.Message("[RJW] add_genitals( " + xxx.get_pawnname(pawn) + " ) doesn't have a genitals"); return; } else if (pawn.health.hediffSet.PartIsMissing(partBPR)) { //--Log.Message("[RJW] add_genitals( " + xxx.get_pawnname(pawn) + " ) had a genital but was removed."); return; } if (Genital_Helper.has_genitals(pawn, parts) && gender == Gender.None) //allow to add gender specific genitals(futa) { //--Log.Message("[RJW] add_genitals( " + xxx.get_pawnname(pawn) + " ) already has genitals"); return; } HediffDef part; // maybe add some check based on bodysize of pawn for genitals size limit //Log.Message("Genital_Helper::add_genitals( " + pawn.RaceProps.baseBodySize + " ) - 1"); //Log.Message("Genital_Helper::add_genitals( " + pawn.kindDef.race.size. + " ) - 2"); part = (IsAddingPenis(pawn, gender)) ? Genital_Helper.generic_penis : Genital_Helper.generic_vagina; if (Genital_Helper.has_vagina(pawn, parts) && part == Genital_Helper.generic_vagina) { //--Log.Message("[RJW] add_genitals( " + xxx.get_pawnname(pawn) + " ) already has v****a"); return; } if ((Genital_Helper.has_penis_fertile(pawn, parts) || Genital_Helper.has_penis_infertile(pawn, parts)) && part == Genital_Helper.generic_penis) { //--Log.Message("[RJW] add_genitals( " + xxx.get_pawnname(pawn) + " ) already has penis"); return; } //override race genitals if (part == Genital_Helper.generic_vagina && pawn.TryAddRacePart(SexPartType.FemaleGenital)) { return; } if (part == Genital_Helper.generic_penis && pawn.TryAddRacePart(SexPartType.MaleGenital)) { return; } LegacySexPartAdder.AddGenitals(pawn, parent, gender, partBPR, part); }
public override IEnumerable <BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r) { var gen_blo = Genital_Helper.genitals_blocked(p); foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r)) { if ((!gen_blo) || (part != xxx.genitals)) { yield return(part); } } }
//Plant Insect eggs/mech chips/other preg mod hediff? public static bool PlantSomething(HediffDef def, Pawn target, bool isToAnal = false, int amount = 1) { if (def == null) { return(false); } if (!isToAnal && !Genital_Helper.has_vagina(target)) { return(false); } if (isToAnal && !Genital_Helper.has_anus(target)) { return(false); } BodyPartRecord Part = (isToAnal) ? Genital_Helper.get_anus(target) : Genital_Helper.get_genitals(target); if (Part != null || Part.parts.Count != 0) { for (int i = 0; i < amount; i++) { if (RJWSettings.DevMode) { Log.Message("[RJW] planting something weird"); } target.health.AddHediff(def, Part); } //killoff normal preg if (!isToAnal) { if (RJWSettings.DevMode) { Log.Message("[RJW] removing other pregnancies"); } if (target.health.hediffSet.HasHediff(HediffDef.Named("RJW_pregnancy"))) { target.health.RemoveHediff(target.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("RJW_pregnancy"))); } if (target.health.hediffSet.HasHediff(HediffDef.Named("RJW_pregnancy_beast"))) { target.health.RemoveHediff(target.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("RJW_pregnancy_beast"))); } if (target.health.hediffSet.HasHediff(HediffDef.Named("Pregnant"))) { target.health.RemoveHediff(target.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("Pregnant"))); } } return(true); } return(false); }
// Generate a BodyPartRecord for the genitals part and inject it into the Human BodyDef. By adding the // genitals at the end of the list of body parts we can hopefully avoid breaking existing saves with // mods that also modify the human BodyDef. // I don't think this is used anymore public static void inject_genitals(BodyDef target = null) { //--Log.Message("[RJW] First::inject_genitals() called"); if (target == null) { target = BodyDefOf.Human; } Genital_Helper.inject_genitals(target); Genital_Helper.inject_breasts(target); Genital_Helper.inject_anus(target); }
/// <summary> /// Count only fertile penises /// </summary> /// <param name="pawn"></param> /// <returns></returns> public static bool is_futa(Pawn pawn, List <Hediff> parts = null) { if (parts == null) { parts = get_PartsHediffList(pawn, get_genitalsBPR(pawn)); } if (parts.NullOrEmpty()) { return(false); } return(Genital_Helper.has_penis_fertile(pawn, parts) && has_vagina(pawn, parts)); }
//Comments from nizhuan-jjr to previous authors: Why do you want to sexualize WorldPawns? Why not simply sexualize visible pawns? //I don't remove this but want to. public static bool pawns_require_sexualization() { int count_sexualized = 0; bool found_one = false; foreach (var p in Find.WorldPawns.AllPawnsAliveOrDead) //Comments from nizhuan-jjr to previous authors: Really not sure why you want to sexualize dead pawns, do you want to harvest organs from those dead? This is done by Harvest Organ Post Mortem 2.0. { if ((!p.Dead) || p.Spawned) { if (Genital_Helper.is_sexualized(p)) { ++count_sexualized; if (count_sexualized > 50) //Late game worlds can have thousands of pawns. There's probably no point in checking all of them, and doing so could cause poor performance { break; } } else { found_one = true; break; } } } if (!found_one) { foreach (var m in Find.Maps) { count_sexualized = 0; foreach (var p in m.mapPawns.AllPawns) { if (Genital_Helper.is_sexualized(p)) { ++count_sexualized; if (count_sexualized > 50) { break; } } else { found_one = true; break; } } } } return(found_one); }
public static void Postfix(ref Job __result, Pawn pawn) { //Log.Message("[RJW]patches_lovin::JobGiver_Mate fail, try rjw for " + xxx.get_pawnname(pawn)); var partBPR = Genital_Helper.get_genitalsBPR(pawn); var parts = Genital_Helper.get_PartsHediffList(pawn, partBPR); if (!(Genital_Helper.has_penis_fertile(pawn, parts) || Genital_Helper.has_penis_infertile(pawn, parts)) || !pawn.ageTracker.CurLifeStage.reproductive) { //Log.Message("[RJW]patches_lovin::JobGiver_Mate " + xxx.get_pawnname(pawn) + ", has no penis " + (Genital_Helper.has_penis(pawn) || Genital_Helper.has_penis_infertile(pawn))); //Log.Message("[RJW]patches_lovin::JobGiver_Mate " + xxx.get_pawnname(pawn) + ", not reproductive " + !pawn.ageTracker.CurLifeStage.reproductive); return; } Predicate <Thing> validator = delegate(Thing t) { Pawn pawn3 = t as Pawn; var valid = !pawn3.Downed && pawn3 != pawn && pawn3.CanCasuallyInteractNow() && !pawn3.IsForbidden(pawn) && !pawn3.HostileTo(pawn) && PawnUtility.FertileMateTarget(pawn, pawn3); if (!valid && pawn3 != pawn) { //Log.Message("[RJW]patches_lovin::JobGiver_Mate " + xxx.get_pawnname(pawn3) + ", not valid"); //Log.Message("[RJW]patches_lovin::JobGiver_Mate Downed " + pawn3.Downed); //Log.Message("[RJW]patches_lovin::JobGiver_Mate CanCasuallyInteractNow " + pawn3.CanCasuallyInteractNow()); //Log.Message("[RJW]patches_lovin::JobGiver_Mate IsForbidden " + pawn3.IsForbidden(pawn)); //Log.Message("[RJW]patches_lovin::JobGiver_Mate FertileMateTarget " + PawnUtility.FertileMateTarget(pawn, pawn3)); } return(valid); }; ThingRequest request = ThingRequest.ForDef(pawn.def); // mate sames species if (RJWSettings.WildMode) // go wild xD { request = ThingRequest.ForGroup(ThingRequestGroup.Pawn); // mate everyone } //add animal check? Pawn pawn2 = (Pawn)GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, request, PathEndMode.Touch, TraverseParms.For(pawn), 30f, validator); if (pawn2 == null) { //Log.Message("[RJW]patches_lovin::JobGiver_Mate " + xxx.get_pawnname(pawn) + ", no valid partner found"); return; } //__result = JobMaker.MakeJob(xxx.animalBreed, pawn2); __result = JobMaker.MakeJob(JobDefOf.Mate, pawn2); //Log.Message("[RJW]patches_lovin::JobGiver_Mate " + xxx.get_pawnname(pawn) + ", female " + xxx.get_pawnname(pawn2) + ", job " + __result); }
public override IEnumerable <BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r) { bool blocked = Genital_Helper.genitals_blocked(p) || xxx.is_slime(p); //|| xxx.is_demon(p); bool has_vag = Genital_Helper.has_vagina(p); bool has_cock = Genital_Helper.has_penis(p) || Genital_Helper.has_penis_infertile(p) || Genital_Helper.has_ovipositorF(p); foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r)) { if (r.appliedOnFixedBodyParts.Contains(part.def) && !blocked && (!has_vag && has_cock)) { yield return(part); } } }
public override void PostAdd(DamageInfo?dinfo) { //--Log.Message("[RJW]Hediff_InitPrivates::PostAdd is called0 - pawn is " + pawn.NameStringShort); if (!Genital_Helper.is_sexualized(pawn)) { Genital_Helper.sexualize(pawn); //--Log.Message("[RJW]Hediff_InitPrivates::PostAdd is called1 - pawn is " + pawn.NameStringShort); std.generate_on(pawn); } // Remove the dummy hediff pawn.health.RemoveHediff(this); }
public Orientation RollOrientation(Pawn pawn) { //Rand.PopState(); //Rand.PushState(RJW_Multiplayer.PredictableSeed()); float random = Rand.Range(0f, 1f); float checkpoint = RJWPreferenceSettings.asexual_ratio / RJWPreferenceSettings.GetTotal(); float checkpoint_pan = checkpoint + (RJWPreferenceSettings.pansexual_ratio / RJWPreferenceSettings.GetTotal()); float checkpoint_het = checkpoint_pan + (RJWPreferenceSettings.heterosexual_ratio / RJWPreferenceSettings.GetTotal()); float checkpoint_bi = checkpoint_het + (RJWPreferenceSettings.bisexual_ratio / RJWPreferenceSettings.GetTotal()); float checkpoint_gay = checkpoint_bi + (RJWPreferenceSettings.homosexual_ratio / RJWPreferenceSettings.GetTotal()); if (random < checkpoint || !Genital_Helper.has_genitals(pawn)) { return(Orientation.Asexual); } else if (random < checkpoint_pan) { return(Orientation.Pansexual); } else if (random < checkpoint_het) { return(Orientation.Heterosexual); } else if (random < checkpoint_het + ((checkpoint_bi - checkpoint_het) * 0.33f)) { return(Orientation.MostlyHeterosexual); } else if (random < checkpoint_het + ((checkpoint_bi - checkpoint_het) * 0.66f)) { return(Orientation.LeaningHeterosexual); } else if (random < checkpoint_bi) { return(Orientation.Bisexual); } else if (random < checkpoint_bi + ((checkpoint_gay - checkpoint_bi) * 0.33f)) { return(Orientation.LeaningHomosexual); } else if (random < checkpoint_bi + ((checkpoint_gay - checkpoint_bi) * 0.66f)) { return(Orientation.MostlyHomosexual); } else { return(Orientation.Homosexual); } }
public override IEnumerable <BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r) { var gen_blo = Genital_Helper.breasts_blocked(p); if (p.gender == Gender.Female) { foreach (var part in base.GetPartsToApplyOn(p, r)) { if ((!gen_blo) || (part != xxx.breasts)) { yield return(part); } } } }
public override IEnumerable <BodyPartRecord> GetPartsToApplyOn(Pawn pawn, RecipeDef recipe) { bool blocked = Genital_Helper.genitals_blocked(pawn) || xxx.is_slime(pawn); if (!blocked) { foreach (BodyPartRecord record in pawn.RaceProps.body.AllParts.Where(x => recipe.appliedOnFixedBodyParts.Contains(x.def))) { if (!pawn.health.hediffSet.hediffs.Any((Hediff x) => x.def == recipe.addsHediff)) { yield return(record); } } } }
public override IEnumerable <BodyPartRecord> GetPartsToApplyOn(Pawn pawn, RecipeDef recipeDef) { var chest = Genital_Helper.get_breasts(pawn); if (Genital_Helper.breasts_blocked(pawn)) { yield break; } if (BreastSize_Helper.TryGetBreastSize(pawn, out var size) && size > BreastSize_Helper.GetSize(Genital_Helper.flat_breasts)) { yield return(chest); } }
public override IEnumerable <BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r) { if (Genital_Helper.has_penis(p) || Genital_Helper.has_penis_infertile(p) || Genital_Helper.has_ovipositorF(p)) { bool blocked = Genital_Helper.genitals_blocked(p) || xxx.is_slime(p); foreach (var part in p.health.hediffSet.GetNotMissingParts()) { if (r.appliedOnFixedBodyParts.Contains(part.def) && (!blocked)) { yield return(part); } } } }
public override IEnumerable <BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r) { if (Genital_Helper.has_breasts(p)) { bool blocked = Genital_Helper.breasts_blocked(p) || xxx.is_slime(p); //|| xxx.is_demon(p) foreach (BodyPartRecord part in p.health.hediffSet.GetNotMissingParts()) { if (r.appliedOnFixedBodyParts.Contains(part.def) && (!blocked)) { yield return(part); } } } }
public override IEnumerable <BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r) { //dont add artifical - peg, hydraulics, bionics, archo, ovi if (r.addsHediff.addedPartProps?.solid ?? false) { yield break; } //dont add if artifical parts present if (p.health.hediffSet.hediffs.Any((Hediff hed) => (hed.Part != null) && r.appliedOnFixedBodyParts.Contains(hed.Part.def) && (hed.def.addedPartProps?.solid ?? false))) { yield break; } var partBPR = Genital_Helper.get_genitalsBPR(p); var parts = Genital_Helper.get_PartsHediffList(p, partBPR); //dont add if no ovi //if (Genital_Helper.has_ovipositorF(p, parts) || Genital_Helper.has_ovipositorM(p, parts)) // yield break; //dont add if same part type not present yet if (!Genital_Helper.has_vagina(p, parts) && r.defName.ToLower().Contains("v****a")) { yield break; } if (!Genital_Helper.has_penis_fertile(p, parts) && r.defName.ToLower().Contains("penis")) { yield break; } //cant install parts when part blocked, on slimes, on demons bool blocked = (xxx.is_slime(p) || //|| xxx.is_demon(p) (Genital_Helper.genitals_blocked(p) && r.appliedOnFixedBodyParts.Contains(xxx.genitalsDef)) || (Genital_Helper.anus_blocked(p) && r.appliedOnFixedBodyParts.Contains(xxx.anusDef)) || (Genital_Helper.breasts_blocked(p) && r.appliedOnFixedBodyParts.Contains(xxx.breastsDef))); foreach (BodyPartRecord part in base.GetPartsToApplyOn(p, r)) { if (r.appliedOnFixedBodyParts.Contains(part.def) && !blocked) { yield return(part); } } }
public static Sex GetSex(Pawn pawn) { var partBPR = Genital_Helper.get_genitalsBPR(pawn); var parts = Genital_Helper.get_PartsHediffList(pawn, partBPR); bool has_vagina = Genital_Helper.has_vagina(pawn, parts); bool has_penis = Genital_Helper.has_penis_fertile(pawn, parts); bool has_penis_infertile = Genital_Helper.has_penis_infertile(pawn, parts); bool has_breasts = Genital_Helper.has_breasts(pawn); bool has_male_breasts = Genital_Helper.has_male_breasts(pawn); //BodyType? bt = pawn.story?.bodyType; //if (bt != null) // bt = BodyType.Undefined; Sex res; if (has_vagina && !has_penis && !has_penis_infertile) { res = Sex.female; } else if (has_vagina && (has_penis || has_penis_infertile)) { res = Sex.futa; } else if ((has_penis || has_penis_infertile) && has_breasts && !has_male_breasts) { res = Sex.trap; } else if (has_penis || has_penis_infertile) //probably should change this later { res = Sex.male; } else if (pawn.gender == Gender.Male) { res = Sex.male; } else if (pawn.gender == Gender.Female) { res = Sex.female; } else { res = Sex.none; } return(res); }