예제 #1
0
        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);
        }
예제 #2
0
        // 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);
        }
예제 #4
0
        //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);
        }
예제 #5
0
        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);
                    }
                }
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }