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); }
// 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); }
//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); }
//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); }
public override IEnumerable <BodyPartRecord> GetPartsToApplyOn(Pawn p, RecipeDef r) { if (Genital_Helper.has_anus(p)) { bool blocked = Genital_Helper.anus_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 static Pawn find_breeder_animal(Pawn pawn, Map m) { DebugText("BreederHelper::find_breeder_animal( " + xxx.get_pawnname(pawn) + " ) called"); float min_fuckability = 0.10f; // Don't rape pawns with <10% fuckability float avg_fuckability = 0f; // Average targets fuckability, choose target higher than that var valid_targets = new Dictionary <Pawn, float>(); // Valid pawns and their fuckability Pawn chosentarget = null; // Final target pawn //Pruning initial pawn list. IEnumerable <Pawn> targets = m.mapPawns.AllPawnsSpawned.Where(x => x != pawn && xxx.is_animal(x) && xxx.can_get_raped(x) && !x.IsForbidden(pawn) && !x.Suspended && !x.HostileTo(pawn) && pawn.CanReserveAndReach(x, PathEndMode.Touch, Danger.Some, max_animals_at_once) //&& SameRace ? pawn.kindDef.race == x.kindDef.race : true ); if (targets.Any()) { var partBPR = Genital_Helper.get_genitalsBPR(pawn); var parts = Genital_Helper.get_PartsHediffList(pawn, partBPR); //filter pawns for female, who can f**k her //not sure if faction check should be but w/e if (!Genital_Helper.has_penis_fertile(pawn, parts) && !Genital_Helper.has_penis_infertile(pawn, parts) && (Genital_Helper.has_vagina(pawn, parts) || Genital_Helper.has_anus(pawn))) { targets = targets.Where(x => xxx.can_fuck(x) && x.Faction == pawn.Faction); } //for humans, animals dont have need - always = 3f //if not horny, seek only targets with safe temp if (xxx.need_some_sex(pawn) < 3.0f) { targets = targets.Where(x => pawn.CanReach(x, PathEndMode.Touch, Danger.None)); } //Used for interspecies animal-on-animal. //Animals will only go for targets they can see. if (xxx.is_animal(pawn)) { targets = targets.Where(x => pawn.CanSee(x) && pawn.def.defName != x.def.defName); } else { // Pickier about the targets if the pawn has no prior experience. if (pawn.records.GetValue(xxx.CountOfSexWithAnimals) < 3 && !xxx.is_zoophile(pawn)) { min_fuckability *= 2f; } if (xxx.is_frustrated(pawn)) { // Less picky when frustrated... min_fuckability *= 0.6f; } else if (!xxx.is_hornyorfrustrated(pawn)) { // ...and far more picky when satisfied. min_fuckability *= 2.5f; } } } DebugText("[RJW]BreederHelper::find_breeder_animal::" + targets.Count() + " targets found on map."); if (!targets.Any()) { return(null); //None found. } foreach (Pawn target in targets) { DebugText("[RJW]BreederHelper::find_breeder_animal::Checking target " + target.kindDef.race.defName.ToLower()); if (!xxx.can_path_to_target(pawn, target.Position)) { continue; // too far } float fuc = SexAppraiser.would_fuck_animal(pawn, target); // 0.0 to ~3.0, orientation checks etc. if (!(fuc > min_fuckability)) { continue; } DebugText("Adding target" + target.kindDef.race.defName.ToLower()); valid_targets.Add(target, fuc); } DebugText(valid_targets.Count() + " valid targets found on map."); //Rand.PopState(); //Rand.PushState(RJW_Multiplayer.PredictableSeed()); if (valid_targets.Any()) { avg_fuckability = valid_targets.Average(x => x.Value); // choose pawns to f**k with above average fuckability var valid_targetsFilteredAnimals = valid_targets.Where(x => x.Value >= avg_fuckability); if (valid_targetsFilteredAnimals.Any()) { chosentarget = valid_targetsFilteredAnimals.RandomElement().Key; } } return(chosentarget); }
public static Pawn find_breeder_animal(Pawn pawn, Map m) { DebugText("BreederHelper::find_breeder_animal( " + xxx.get_pawnname(pawn) + " ) called"); float base_fuckability = 0.1f; //Determines how picky the pawns are. Could be added as config. List <Pawn> valid_targets = new List <Pawn>(); //Pruning initial pawn list. IEnumerable <Pawn> targets = m.mapPawns.AllPawnsSpawned.Where(x => x != pawn && xxx.is_animal(x) && xxx.can_get_raped(x) && !x.IsForbidden(pawn) && !x.Suspended && !x.HostileTo(pawn) && pawn.CanReserveAndReach(x, PathEndMode.Touch, Danger.Some, max_animals_at_once) //&& SameRace ? pawn.kindDef.race == x.kindDef.race : true ); if (targets.Any()) { //filter pawns for female, who can f**k her //not sure if faction check should be but w/e if (!Genital_Helper.has_penis(pawn) && !Genital_Helper.has_penis_infertile(pawn) && (Genital_Helper.has_vagina(pawn) || Genital_Helper.has_anus(pawn))) { targets = targets.Where(x => xxx.can_fuck(x) && x.Faction == pawn.Faction); } //for humans, animals dont have need - always = 3f //if not horny, seek only targets with safe temp if (xxx.need_some_sex(pawn) < 3.0f) { targets = targets.Where(x => pawn.CanReach(x, PathEndMode.Touch, Danger.None)); } //Used for interspecies animal-on-animal. //Animals will only go for targets they can see. if (xxx.is_animal(pawn)) { targets = targets.Where(x => pawn.CanSee(x) && pawn.def.defName != x.def.defName); } else { // Pickier about the targets if the pawn has no prior experience. if (pawn.records.GetValue(xxx.CountOfSexWithAnimals) < 3 && !xxx.is_zoophile(pawn)) { base_fuckability *= 2f; } if (xxx.need_some_sex(pawn) > 2f) { // Less picky when frustrated... base_fuckability *= 0.6f; } else if (xxx.need_some_sex(pawn) < 2f) { // ...and far more picky when satisfied. base_fuckability *= 2.5f; } } } DebugText("[RJW]BreederHelper::find_breeder_animal::" + targets.Count() + " targets found on map."); if (!targets.Any()) { return(null); //None found. } foreach (Pawn target in targets) { DebugText("[RJW]BreederHelper::find_breeder_animal::Checking target " + target.kindDef.race.defName.ToLower()); if (!xxx.can_path_to_target(pawn, target.Position)) { continue; // too far } float fuc = xxx.would_fuck_animal(pawn, target); // 0.0 to ~3.0, orientation checks etc. if (!(fuc > base_fuckability)) { continue; } DebugText("Adding target" + target.kindDef.race.defName.ToLower()); valid_targets.Add(target); } DebugText(valid_targets.Count() + " valid targets found on map."); //Rand.PopState(); //Rand.PushState(RJW_Multiplayer.PredictableSeed()); return(valid_targets.Any() ? valid_targets.RandomElement() : null); }
public static float would_fuck_animal(Pawn pawn, Pawn target, bool invert_opinion = false, bool ignore_bleeding = false, bool ignore_gender = false) { float wildness_modifier = 1.0f; List <float> size_preference = new List <float>() { pawn.BodySize * 0.75f, pawn.BodySize * 1.6f }; float fuc = would_fuck(pawn, target, invert_opinion, ignore_bleeding, ignore_gender); // 0.0 to ~3.0, orientation checks etc. if (fuc < 0.1f) { // Would not f**k return(0); } if (xxx.has_quirk(pawn, "Teratophile")) { // Teratophiles prefer more 'monstrous' partners. size_preference[0] = pawn.BodySize * 0.8f; size_preference[1] = pawn.BodySize * 2.0f; wildness_modifier = 0.3f; } if (pawn.health.hediffSet.HasHediff(HediffDef.Named("AlcoholHigh"))) { wildness_modifier = 0.5f; //Drunk and making poor judgments. size_preference[1] *= 1.5f; } else if (pawn.health.hediffSet.HasHediff(HediffDef.Named("YayoHigh"))) { wildness_modifier = 0.2f; //This won't end well. size_preference[1] *= 2.5f; } var partBPR = Genital_Helper.get_genitalsBPR(pawn); var parts = Genital_Helper.get_PartsHediffList(pawn, partBPR); if (Genital_Helper.has_vagina(pawn, parts) || Genital_Helper.has_anus(pawn)) { if (!(Genital_Helper.has_penis_fertile(pawn, parts) || Genital_Helper.has_penis_infertile(pawn, parts))) { size_preference[1] = pawn.BodySize * 1.3f; } } if (xxx.is_animal(pawn)) { size_preference[1] = pawn.BodySize * 1.3f; wildness_modifier = 0.4f; } else { if (pawn.story.traits.HasTrait(TraitDefOf.Tough) || pawn.story.traits.HasTrait(TraitDefOf.Brawler)) { size_preference[1] += 0.2f; wildness_modifier -= 0.2f; } else if (pawn.story.traits.HasTrait(TraitDef.Named("Wimp"))) { size_preference[0] -= 0.2f; size_preference[1] -= 0.2f; wildness_modifier += 0.25f; } } float wildness = target.RaceProps.wildness; // 0.0 to 1.0 float petness = target.RaceProps.petness; // 0.0 to 1.0 float distance = pawn.Position.DistanceToSquared(target.Position); //Log.Message("[RJW]would_fuck_animal:: base: " + fuc + ", wildness: " + wildness + ", petness: " + petness + ", distance: " + distance); fuc = fuc + fuc * petness - fuc * wildness * wildness_modifier; if (fuc < 0.1f) { // Would not f**k return(0); } // Adjust by distance, nearby targets preferred. fuc *= 1.0f - Mathf.Max(distance / 10000, 0.1f); // Adjust by size difference. if (target.BodySize < size_preference[0]) { fuc *= Mathf.Lerp(0.1f, size_preference[0], target.BodySize); } else if (target.BodySize > size_preference[1]) { fuc *= Mathf.Lerp(size_preference[1] * 10, size_preference[1], target.BodySize); } if (target.Faction != pawn.Faction) { //Log.Message("[RJW]would_fuck_animal(NT):: base: " + fuc + ", bound1: " + fuc * 0.75f); //Log.Message("[RJW]would_fuck_animal(NT):: base: " + fuc + ", bound2: " + fuc + 0.25f); fuc *= 0.75f; // Less likely to target wild animals. } else if (pawn.relations.DirectRelationExists(PawnRelationDefOf.Bond, target)) { //Log.Message("[RJW]would_fuck_animal(T):: base: " + fuc + ", bound1: " + fuc * 1.25f); //Log.Message("[RJW]would_fuck_animal(T):: base: " + fuc + ", bound2: " + fuc + 0.25f); fuc *= 1.25f; // Bonded animals preferred. } return(fuc); }