示例#1
0
        // We just use the FeedPatient Job from the medical branch for non-breastfeeding
        public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            Pawn pawn2 = (Pawn)t;

            if (pawn2 != null)
            {
                if (ChildrenUtility.CanBreastfeed(pawn))
                {
                    //Log.Message("Deciding to breastfeed baby.");
                    return(new Job(DefDatabase <JobDef> .GetNamed("BreastfeedBaby"))
                    {
                        targetA = pawn2,
                    });
                }
                else
                {
                    Thing    t2;
                    ThingDef def1;
                    if (FoodUtility.TryFindBestFoodSourceFor(pawn, pawn2, pawn2.needs.food.CurCategory == HungerCategory.UrgentlyHungry, out t2, out def1, false, true, false, false, false))
                    {
                        //Log.Message("Deciding to feed normal food to baby.");
                        return(new Job(JobDefOf.FeedPatient)
                        {
                            targetA = t2,
                            targetB = pawn2,
                            count = FoodUtility.WillIngestStackCountOf(pawn2, def1, t2.def.ingestible.CachedNutrition)
                        });
                    }
                }
            }
            return(null);
        }
示例#2
0
        //
        // Methods
        //
        public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            Pawn pawn2 = t as Pawn;

            // Make sure pawn can actually breastfeed before wasting time checking anything else
            if (!ChildrenUtility.CanBreastfeed(pawn))
            {
                return(false);
            }
            if (pawn2 == null || pawn2 == pawn)
            {
                return(false);
            }
            if (!pawn2.RaceProps.Humanlike)
            {
                return(false);
            }
            if (pawn2.needs.food == null || pawn2.needs.food.CurLevelPercentage > pawn2.needs.food.PercentageThreshHungry + 0.02)
            {
                return(false);
            }
            if (!FeedPatientUtility.ShouldBeFed(pawn2))
            {
                return(false);
            }
            if (!pawn.CanReserveAndReach(t, PathEndMode.ClosestTouch, Danger.Deadly, 1, -1, null, forced))
            {
                return(false);
            }
            return(true);
        }
示例#3
0
        internal static void CanGetThought_Patch(ref Pawn pawn, ref ThoughtDef def, ref bool __result)
        {
            // Toddlers and younger can't get these thoughts
            if (pawn.ageTracker.CurLifeStageIndex <= 1 && ChildrenUtility.RaceUsesChildren(pawn))
            {
                List <ThoughtDef> thoughtlist = new List <ThoughtDef> {
                    ThoughtDefOf.AteWithoutTable,
                    ThoughtDefOf.KnowPrisonerDiedInnocent,
                    ThoughtDefOf.KnowPrisonerSold,
                    ThoughtDefOf.Naked,
                    ThoughtDefOf.SleepDisturbed,
                    ThoughtDefOf.SleptOnGround,
                    ThoughtDef.Named("CabinFever"),
                    //ThoughtDef.Named("SharedBedroom")
                };

                foreach (ThoughtDef thought in thoughtlist)
                {
                    if (def == thought)
                    {
                        __result = false;
                    }
                }
            }
        }
        //
        // Methods
        //
        protected override ThoughtState CurrentStateInternal(Pawn p)
        {
            if (p.ageTracker.CurLifeStageIndex > AgeStage.Toddler || !ChildrenUtility.RaceUsesChildren(p))
            {
                return(false);
            }
            Pawn mother = p.relations.GetFirstDirectRelationPawn(PawnRelationDefOf.Parent, x => x.gender == Gender.Female);
            Pawn father = p.relations.GetFirstDirectRelationPawn(PawnRelationDefOf.Parent, x => x.gender == Gender.Male);

            if (ArePawnsNear(p, mother) && ArePawnsNear(p, father))
            {
                return(ThoughtState.ActiveAtStage(2));
            }
            else if (ArePawnsNear(p, mother))
            {
                return(ThoughtState.ActiveAtStage(0));
            }
            else if (ArePawnsNear(p, father))
            {
                return(ThoughtState.ActiveAtStage(1));
            }
            else
            {
                return(false);
            }
        }
示例#5
0
        public static Building_Bed FindCribFor(Pawn baby, Pawn traveler)
        {
            Building_Bed crib = null;

            // Is a crib already assigned to the baby?
            if (baby.ownership != null && baby.ownership.OwnedBed != null && ChildrenUtility.IsBedCrib(baby.ownership.OwnedBed))
            {
                Building_Bed bedThing = baby.ownership.OwnedBed;
                if (RestUtility.IsValidBedFor(bedThing, baby, traveler, false, false))
                {
                    crib = baby.ownership.OwnedBed;
                }
            }
            // If not, let's look for one
            else
            {
                foreach (var thingDef in RestUtility.AllBedDefBestToWorst)
                {
                    if (RestUtility.CanUseBedEver(baby, thingDef) && thingDef.building.bed_maxBodySize <= 0.6f)
                    {
                        Building_Bed find_crib = (Building_Bed)GenClosest.ClosestThingReachable(baby.Position, baby.Map, ThingRequest.ForDef(thingDef), PathEndMode.OnCell, TraverseParms.For(traveler), 9999f, (Thing b) => (RestUtility.IsValidBedFor(b, baby, traveler, false, false)), null);
                        if (find_crib != null)
                        {
                            crib = find_crib;
                        }
                    }
                }
            }
            return(crib);
        }
示例#6
0
        //
        // Methods
        //
        public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            Pawn pawn2 = t as Pawn;

            if (pawn2 == null || pawn2 == pawn)
            {
                return(false);
            }
            if (!pawn2.RaceProps.Humanlike || pawn2.ageTracker.CurLifeStageIndex > AgeStage.Toddler)
            {
                return(false);
            }
            if (pawn2.needs.food == null || pawn2.needs.food.CurLevelPercentage > pawn2.needs.food.PercentageThreshHungry + 0.02)
            {
                return(false);
            }
            if (!pawn2.InBed())
            {
                return(false);
            }
            if (!FeedPatientUtility.ShouldBeFed(pawn2))
            {
                return(false);
            }
            if (!pawn.CanReserveAndReach(t, PathEndMode.ClosestTouch, Danger.Deadly, 1, -1, null, forced))
            {
                return(false);
            }
            if (!ChildrenUtility.CanBreastfeed(pawn))
            {
                JobFailReason.Is("ReasonCannotBreastfeed".Translate(pawn.LabelShort));
                return(false);
            }
            return(true);
        }
示例#7
0
            internal static void SBD(ref Pawn_HealthTracker __instance, ref bool __result)
            {
                Pawn pawn = (Pawn)AccessTools.Field(typeof(Pawn_HealthTracker), "pawn").GetValue(__instance);

                if (ChildrenUtility.RaceUsesChildren(pawn) && pawn.ageTracker.CurLifeStageIndex <= 2)
                {
                    __result = __instance.hediffSet.PainTotal > 0.4f || !__instance.capacities.CanBeAwake || !__instance.capacities.CapableOf(PawnCapacityDefOf.Moving);
                }
            }
示例#8
0
        internal static void Notify_EquipmentAdded_Patch(ref ThingWithComps eq, ref Pawn_EquipmentTracker __instance)
        {
            Pawn pawn = __instance.ParentHolder as Pawn;

            if (pawn != null && ChildrenUtility.RaceUsesChildren(pawn) && eq.def.BaseMass > ChildrenUtility.ChildMaxWeaponMass(pawn) && pawn.ageTracker.CurLifeStageIndex <= AgeStage.Child && pawn.Faction.IsPlayer)
            {
                Messages.Message("MessageWeaponTooLarge".Translate(new object[] { eq.def.label, ((Pawn)__instance.ParentHolder).NameStringShort }), MessageTypeDefOf.CautionInput);
            }
        }
        internal static void Notify_EquipmentAdded_Patch(ref ThingWithComps eq, ref Pawn_EquipmentTracker __instance)
        {
            Pawn pawn = __instance.ParentHolder as Pawn;

            if (eq.def.BaseMass > ChildrenUtility.ChildMaxWeaponMass(pawn) && pawn.ageTracker.CurLifeStageIndex <= AgeStage.Child)
            {
                Messages.Message("MessageWeaponTooLarge".Translate(new object[] { eq.def.label, ((Pawn)__instance.ParentHolder).NameStringShort }), MessageSound.Negative);
            }
        }
        //
        // Fields
        //

        //
        // Methods
        //

        public override IEnumerable <BodyPartRecord> GetPartsToApplyOn(Pawn pawn, RecipeDef recipe)
        {
            BodyPartRecord part = pawn.RaceProps.body.corePart;

            if (recipe.appliedOnFixedBodyParts[0] != null)
            {
                part = pawn.RaceProps.body.AllParts.Find(x => x.def == recipe.appliedOnFixedBodyParts[0]);
            }
            if (part != null && ChildrenUtility.RaceUsesChildren(pawn) && pawn.gender == Gender.Female &&
                pawn.ageTracker.CurLifeStageIndex >= AgeStage.Teenager)
            {
                yield return(part);
            }
        }
示例#11
0
 public static T FailOnBaby <T>(this T f) where T : IJobEndable
 {
     f.AddEndCondition(delegate {
         //				return JobCondition.Incompletable;
         if (f.GetActor().ageTracker.CurLifeStageIndex <= 1 && ChildrenUtility.RaceUsesChildren(f.GetActor()))
         {
             return(JobCondition.Incompletable);
         }
         else
         {
             return(JobCondition.Ongoing);
         }
     });
     return(f);
 }
示例#12
0
        internal static List <ThingStuffPair> FilterChildWeapons(Pawn pawn, List <ThingStuffPair> weapons)
        {
            var weapons_out = new List <ThingStuffPair>();

            if (weapons.Count > 0)
            {
                foreach (ThingStuffPair weapon in weapons)
                {
                    if (weapon.thing.BaseMass < ChildrenUtility.ChildMaxWeaponMass(pawn))
                    {
                        weapons_out.Add(weapon);
                    }
                }
            }
            return(weapons_out);
        }
示例#13
0
        // My own methods
        internal static Graphic GetChildHeadGraphics(PawnGraphicSet graphicSet, Shader shader, Color skinColor)
        {
            Graphic_Multi graphic = null;
            Pawn          pawn    = graphicSet.pawn;

            if (ChildrenUtility.IsHumanlikeChild(pawn))
            {
                string str  = "Male_Child";
                string path = "Things/Pawn/Humanlike/Children/Heads/" + str;
                graphic = GraphicDatabase.Get <Graphic_Multi>(path, shader, Vector2.one, skinColor) as Graphic_Multi;
            }
            else
            {
                graphic = graphicSet.headGraphic as Graphic_Multi;
            }
            return(graphic);
        }
示例#14
0
        // We just use the FeedPatient Job from the medical branch for non-breastfeeding
        public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            Pawn pawn2 = (Pawn)t;

            if (pawn2 != null)
            {
                if (ChildrenUtility.CanBreastfeed(pawn))
                {
                    //Log.Message("Deciding to breastfeed baby.");
                    return(new Job(DefDatabase <JobDef> .GetNamed("BreastfeedBaby"))
                    {
                        targetA = pawn2,
                    });
                }
            }
            return(null);
        }
示例#15
0
            internal static void _GeneratePawn(ref PawnGenerationRequest request, ref Pawn __result)
            {
                Pawn pawn = __result;

                if (pawn.ageTracker.CurLifeStageIndex <= AgeStage.Child && ChildrenUtility.RaceUsesChildren(pawn))
                {
                    // hostile children on/off
                    if (!BnC_Settings.option_hostile_children_raider && Faction.OfPlayerSilentFail != null)
                    {
                        if (pawn.Faction != null && pawn.HostileTo(Faction.OfPlayer))
                        {
                            Log.Message("[From BnC] hostile children growup : " + pawn.LabelIndefinite());
                            ChildrenUtility.GrowupHostileChild(ref request, ref pawn);
                            return;
                        }
                    }

                    // give innocence trait
                    ChildrenUtility.Give_Innocent_trait(ref pawn);
                    // give backstory
                    if (pawn.ageTracker.CurLifeStageIndex == 2 && pawn.ageTracker.AgeBiologicalYears < 8 && ChildrenUtility.IsHumanlikeChild(pawn))
                    {
                        pawn.story.childhood = BackstoryDatabase.allBackstories["CustomBackstory_NA_Childhood"];
                    }

                    if (pawn.ageTracker.CurLifeStageIndex == AgeStage.Baby)
                    {
                        // if rjw is on return
                        if (AnotherModCheck.RJW_On)
                        {
                            return;
                        }
                    }

                    // Children hediff being injected
                    pawn.health.AddHediff(HediffDef.Named("BabyState"), null, null);
                    Hediff_Baby babystate = (Hediff_Baby)pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("BabyState"));
                    if (babystate != null)
                    {
                        for (int i = 0; i != pawn.ageTracker.CurLifeStageIndex + 1; i++)
                        {
                            babystate.GrowUpTo(i, true);
                        }
                    }
                }
            }
        internal static void GiveRandomBirthDefect(Pawn baby)
        {
            int r = Rand.Range(1, 9);

            // Bad back defect
            if (r == 1)
            {
                baby.health.AddHediff(HediffDefOf.BadBack, ChildrenUtility.GetPawnBodyPart(baby, "Spine"), null);
            }
            // cataract defect
            if (r == 2)
            {
                int r1 = Rand.Range(1, 3);
                if (r1 == 1 || r1 == 3)
                {
                    baby.health.AddHediff(HediffDefOf.Cataract, ChildrenUtility.GetPawnBodyPart(baby, "LeftEye"), null);
                }
                if (r1 == 2 || r1 == 3)
                {
                    baby.health.AddHediff(HediffDefOf.Cataract, ChildrenUtility.GetPawnBodyPart(baby, "RightEye"), null);
                }
            }
            // frail defect
            if (r == 3)
            {
                baby.health.AddHediff(HediffDefOf.Frail, null, null);
            }
            if (r == 4)
            {
                baby.health.AddHediff(HediffDef.Named("HearingLoss"), ChildrenUtility.GetPawnBodyPart(baby, "Head"), null);
            }
            if (r == 5)
            {
                baby.health.AddHediff(HediffDef.Named("DefectBlind"), ChildrenUtility.GetPawnBodyPart(baby, "LeftEye"), null);
                baby.health.AddHediff(HediffDef.Named("DefectBlind"), ChildrenUtility.GetPawnBodyPart(baby, "RightEye"), null);
            }
            if (r == 6)
            {
                baby.health.AddHediff(HediffDef.Named("DefectHeart"), ChildrenUtility.GetPawnBodyPart(baby, "Heart"), null);
            }
            if (r == 7)
            {
                baby.health.AddHediff(HediffDef.Named("DefectStillborn"), null, null);
            }
        }
示例#17
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedOrNull(TargetIndex.A);
            this.FailOnSomeonePhysicallyInteracting(TargetIndex.A);
            this.FailOn(delegate {
                if (!ChildrenUtility.CanBreastfeed(pawn) || !pawn.CanReserve(TargetA, 1, -1, null, false))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            });

            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null));

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));

            Toil prepare = new Toil();

            prepare.initAction = delegate
            {
                if (Victim.ageTracker.CurLifeStageIndex > AgeStage.Baby)
                {
                    PawnUtility.ForceWait(Victim, breastFeedDuration, Victim);
                }
            };
            prepare.defaultCompleteMode = ToilCompleteMode.Delay;
            prepare.defaultDuration     = breastFeedDuration;
            yield return(prepare);

            yield return(new Toil
            {
                initAction = delegate
                {
                    AddEndCondition(() => JobCondition.Succeeded);
                    // Baby is full
                    Victim.needs.food.CurLevelPercentage = 1f;
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
示例#18
0
        internal static void TryCastShot_Patch(ref Verb_Shoot __instance)
        {
            Pawn pawn = __instance.CasterPawn;

            if (pawn != null && ChildrenUtility.RaceUsesChildren(pawn) && pawn.ageTracker.CurLifeStageIndex <= AgeStage.Child)
            {
                // The weapon is too heavy and the child will (likely) drop it when trying to fire
                if (__instance.ownerEquipment.def.BaseMass > ChildrenUtility.ChildMaxWeaponMass(pawn))
                {
                    ThingWithComps benis;
                    pawn.equipment.TryDropEquipment(__instance.ownerEquipment, out benis, pawn.Position, false);

                    float recoilForce = (__instance.ownerEquipment.def.BaseMass - 3);

                    if (recoilForce > 0)
                    {
                        string[] hitPart =
                        {
                            "Torso",
                            "LeftShoulder",
                            "LeftArm",
                            "LeftHand",
                            "RightShoulder",
                            "RightArm",
                            "RightHand",
                            "Head",
                            "Neck",
                            "LeftEye",
                            "RightEye",
                            "Nose",
                        };
                        int hits = Rand.Range(1, 4);
                        while (hits > 0)
                        {
                            pawn.TakeDamage(new DamageInfo(DamageDefOf.Blunt, (int)((recoilForce + Rand.Range(0f, 3f)) / hits), -1, __instance.ownerEquipment,
                                                           ChildrenUtility.GetPawnBodyPart(pawn, hitPart.RandomElement <String> ()), null));
                            hits--;
                        }
                    }
                }
            }
        }
示例#19
0
        internal static Graphic GetChildBodyGraphics(PawnGraphicSet graphicSet, Shader shader, Color skinColor)
        {
            Graphic_Multi graphic = null;
            Pawn          pawn    = graphicSet.pawn;

            if (ChildrenUtility.IsHumanlikeChild(pawn))
            {
                string str = "Naked_Boy";
                if (graphicSet.pawn.gender == Gender.Female)
                {
                    str = "Naked_Girl";
                }
                string path = "Things/Pawn/Humanlike/Children/Bodies/" + str;
                graphic = GraphicDatabase.Get <Graphic_Multi>(path, shader, Vector2.one, skinColor) as Graphic_Multi;
            }
            else
            {
                graphic = graphicSet.nakedGraphic as Graphic_Multi;
            }
            return(graphic);
        }
        //
        // Methods
        //
        protected override ThoughtState CurrentStateInternal(Pawn p)
        {
            // Does not affect babies and toddlers
            if (p.ageTracker.CurLifeStageIndex < 2 || p.health.capacities.GetLevel(PawnCapacityDefOf.Hearing) <= 0.1f)
            {
                return(ThoughtState.Inactive);
            }

            // Find all crying babies in the vicinity
            int cryingBabies = 0;

            foreach (Pawn mapPawn in p.MapHeld.mapPawns.AllPawnsSpawned)
            {
                if (ChildrenUtility.RaceUsesChildren(mapPawn) &&
                    mapPawn.ageTracker.CurLifeStageIndex == 0 &&
                    mapPawn.health.hediffSet.HasHediff(HediffDef.Named("UnhappyBaby")) &&
                    mapPawn.PositionHeld.InHorDistOf(p.PositionHeld, 24) &&
                    mapPawn.PositionHeld.GetRoomOrAdjacent(mapPawn.MapHeld).ContainedAndAdjacentThings.Contains(p))
                {
                    cryingBabies += 1;
                }
            }
            if (cryingBabies > 0)
            {
                if (cryingBabies == 1)
                {
                    return(ThoughtState.ActiveAtStage(0));
                }
                else if (cryingBabies <= 3)
                {
                    return(ThoughtState.ActiveAtStage(1));
                }
                else if (cryingBabies >= 4)
                {
                    return(ThoughtState.ActiveAtStage(2));
                }
            }
            return(ThoughtState.Inactive);
        }
示例#21
0
 static void AddDirectRelation_GiveLacrating(Pawn_RelationsTracker __instance, PawnRelationDef def, Pawn otherPawn)
 {
     if (def == PawnRelationDefOf.Parent)
     {
         Pawn pawn   = (Pawn)PawnFI.GetValue(__instance);
         Pawn mother = pawn.GetMother();
         //Log.Message("mother : " + pawn.LabelIndefinite());
         if (pawn.ageTracker.CurLifeStageIndex == AgeStage.Baby && mother == otherPawn)
         {
             if (mother.RaceProps.Humanlike && !mother.health.hediffSet.HasHediff(HediffDef.Named("Lactating")))
             {
                 if (AnotherModCheck.RJW_On)
                 {
                     try
                     {
                         ((Action)(() =>
                         {
                             if (Genital_Helper.has_breasts(mother))
                             {
                                 mother.health.AddHediff(HediffDef.Named("Lactating"), ChildrenUtility.GetPawnBodyPart(mother, "Chest"), null);
                             }
                             if (Genital_Helper.has_vagina(mother))
                             {
                                 mother.health.AddHediff(HediffDef.Named("BnC_RJW_PostPregnancy"), ChildrenUtility.GetPawnBodyPart(mother, "Genitals"), null);
                             }
                         }))();
                     }
                     catch (TypeLoadException)
                     {
                     }
                 }
                 else
                 {
                     mother.health.AddHediff(HediffDef.Named("Lactating"), ChildrenUtility.GetPawnBodyPart(mother, "Torso"), null);
                 }
             }
         }
     }
 }
示例#22
0
        //
        // Methods
        //
        public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            Pawn pawn2 = t as Pawn;

            if (pawn2 == null || pawn2 == pawn)
            {
                return(false);
            }
            if (!pawn2.RaceProps.Humanlike || pawn2.ageTracker.CurLifeStageIndex > AgeStage.Toddler)
            {
                return(false);
            }
            if (pawn2.needs.food == null || pawn2.needs.food.CurLevelPercentage > pawn2.needs.food.PercentageThreshHungry + 0.02)
            {
                return(false);
            }
            if (!pawn2.InBed())
            {
                return(false);
            }
            if (!FeedPatientUtility.ShouldBeFed(pawn2))
            {
                return(false);
            }
            if (!pawn.CanReserveAndReach(t, PathEndMode.ClosestTouch, Danger.Deadly, 1, -1, null, forced))
            {
                return(false);
            }
            Thing    thing;
            ThingDef thingDef;

            if (!FoodUtility.TryFindBestFoodSourceFor(pawn, pawn2, pawn2.needs.food.CurCategory == HungerCategory.UrgentlyHungry, out thing, out thingDef, false, true, false, false, false) && !ChildrenUtility.CanBreastfeed(pawn))
            {
                JobFailReason.Is("NoFood".Translate());
                return(false);
            }
            return(true);
        }
示例#23
0
        internal static void ResolveAgeGraphics(PawnGraphicSet graphics)
        {
            LongEventHandler.ExecuteWhenFinished(delegate {
                //if (!graphics.pawn.RaceProps.Humanlike) {
                if (!ChildrenUtility.RaceUsesChildren(graphics.pawn))
                {
                    return;
                }

                // Beards
                String beard = "";
                if (graphics.pawn.story.hairDef != null)
                {
                    if (graphics.pawn.story.hairDef.hairTags.Contains("Beard"))
                    {
                        if (graphics.pawn.apparel.BodyPartGroupIsCovered(BodyPartGroupDefOf.UpperHead) && !graphics.pawn.story.hairDef.hairTags.Contains("DrawUnderHat"))
                        {
                            beard = "_BeardOnly";
                        }
                        if (graphics.pawn.ageTracker.CurLifeStageIndex <= AgeStage.Teenager)
                        {
                            graphics.hairGraphic = GraphicDatabase.Get <Graphic_Multi> (DefDatabase <HairDef> .GetNamed("Mop").texPath, ShaderDatabase.Cutout, Vector2.one, graphics.pawn.story.hairColor);
                        }
                        else
                        {
                            graphics.hairGraphic = GraphicDatabase.Get <Graphic_Multi> (graphics.pawn.story.hairDef.texPath + beard, ShaderDatabase.Cutout, Vector2.one, graphics.pawn.story.hairColor);
                        }
                    }
                    else
                    {
                        graphics.hairGraphic = GraphicDatabase.Get <Graphic_Multi> (graphics.pawn.story.hairDef.texPath, ShaderDatabase.Cutout, Vector2.one, graphics.pawn.story.hairColor);
                    }
                }

                // Reroute the graphics for children
                // For babies and toddlers
                if (graphics.pawn.ageTracker.CurLifeStageIndex <= AgeStage.Baby)
                {
                    string toddler_hair = "Boyish";
                    if (graphics.pawn.gender == Gender.Female)
                    {
                        toddler_hair = "Girlish";
                    }
                    graphics.hairGraphic = GraphicDatabase.Get <Graphic_Multi> ("Things/Pawn/Humanlike/Children/Hairs/Child_" + toddler_hair, ShaderDatabase.Cutout, Vector2.one, graphics.pawn.story.hairColor);
                    graphics.headGraphic = GraphicDatabase.Get <Graphic_Multi> ("Things/Pawn/Humanlike/null", ShaderDatabase.Cutout, Vector2.one, Color.white);

                    // The pawn is a baby
                    if (graphics.pawn.ageTracker.CurLifeStageIndex == AgeStage.Baby)
                    {
                        graphics.nakedGraphic = GraphicDatabase.Get <Graphic_Single> ("Things/Pawn/Humanlike/Children/Bodies/Newborn", ShaderDatabase.CutoutSkin, Vector2.one, graphics.pawn.story.SkinColor);
                    }
                }

                // The pawn is a toddler
                if (graphics.pawn.ageTracker.CurLifeStageIndex == AgeStage.Toddler)
                {
                    string upright = "";
                    if (graphics.pawn.ageTracker.AgeBiologicalYears >= 1)
                    {
                        upright = "Upright";
                    }
                    graphics.nakedGraphic = GraphicDatabase.Get <Graphic_Multi> ("Things/Pawn/Humanlike/Children/Bodies/Toddler" + upright, ShaderDatabase.CutoutSkin, Vector2.one, graphics.pawn.story.SkinColor);
                }
                // The pawn is a child
                else if (graphics.pawn.ageTracker.CurLifeStageIndex == AgeStage.Child)
                {
                    graphics.nakedGraphic = Children_Drawing.GetChildBodyGraphics(graphics, ShaderDatabase.CutoutSkin, graphics.pawn.story.SkinColor);
                    graphics.headGraphic  = Children_Drawing.GetChildHeadGraphics(graphics, ShaderDatabase.CutoutSkin, graphics.pawn.story.SkinColor);
                }
            });
        }
        public override void Tick()
        {
            // Something has gone horribly wrong
            if (pawn.health.hediffSet.HasHediff(HediffDef.Named("PostPregnancy")))
            {
                Log.Error("HumanPregnancy Hediff was not properly removed when pawn " + pawn.NameStringShort + " gave birth.");
                // delet this
                if (pawn.health.hediffSet.HasHediff(HediffDef.Named("GivingBirth")))
                {
                    pawn.health.RemoveHediff(pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth")));
                }
                pawn.health.RemoveHediff(this);
            }

            this.ageTicks++;
            if (this.pawn.IsHashIntervalTick(1000))
            {
                if (this.pawn.needs.food != null && this.pawn.needs.food.CurCategory == HungerCategory.Starving && Rand.MTBEventOccurs(0.5f, TicksPerDay, MiscarryCheckInterval))
                {
                    if (this.Visible && PawnUtility.ShouldSendNotificationAbout(this.pawn))
                    {
                        Messages.Message("MessageMiscarriedStarvation".Translate(new object[] {
                            this.pawn.LabelIndefinite()
                        }).CapitalizeFirst(), this.pawn, MessageSound.Negative);
                    }
                    Miscarry(false);
                    return;
                }
                if (this.IsSeverelyWounded && Rand.MTBEventOccurs(0.5f, TicksPerDay, MiscarryCheckInterval))
                {
                    if (this.Visible && PawnUtility.ShouldSendNotificationAbout(this.pawn))
                    {
                        Messages.Message("MessageMiscarriedPoorHealth".Translate(new object[] {
                            this.pawn.LabelIndefinite()
                        }).CapitalizeFirst(), this.pawn, MessageSound.Negative);
                    }
                    Miscarry(false);
                    return;
                }
            }

            GestationProgress += (1.0f) / (pawn.RaceProps.gestationPeriodDays * TicksPerDay);

            // Check if pregnancy is far enough along to "show" for the body type
            if (!is_discovered)
            {
                if (
                    (pawn.story.bodyType == BodyType.Female && GestationProgress > 0.389f) ||
                    (pawn.story.bodyType == BodyType.Thin && GestationProgress > 0.375f) ||
                    ((pawn.story.bodyType == BodyType.Fat || pawn.story.bodyType == BodyType.Hulk) &&
                     GestationProgress > 0.50f))
                {
                    // Got the numbers by dividing the average show time (in weeks) per body type by 36
                    // (36 weeks being the real human gestation period)
                    // https://www.momtricks.com/pregnancy/when-do-you-start-showing-in-pregnancy/

                    DiscoverPregnancy();
                }
            }

            // Final stage of pregnancy
            if (CurStageIndex == 3)
            {
                if (!pawn.health.hediffSet.HasHediff(HediffDef.Named("GivingBirth")))
                {
                    // Notify the player birth is near
                    if (Visible && PawnUtility.ShouldSendNotificationAbout(pawn))
                    {
                        Messages.Message("MessageHavingContractions".Translate(new object[] { pawn.LabelIndefinite() }).CapitalizeFirst(), pawn, MessageSound.Standard);
                    }
                    // Give the mother the GivingBirth hediff
                    pawn.health.AddHediff(HediffDef.Named("GivingBirth"), ChildrenUtility.GetPawnBodyPart(pawn, "Torso"), null);
                }
                // We're having contractions now
                else
                {
                    // Has the pregnancy been tended to?
                    if (pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth")).IsTended())
                    {
                        // Then we get a safe pregnancy
                        DoBirthSpawn(pawn, father, 1);
                    }
                    // natural birth (probably not a good idea!)
                    else if (GestationProgress >= 1)
                    {
                        // Do risky pregnancy
                        DoBirthSpawn(pawn, father, 0.9f);
                        if (Rand.Value <= 0.1f)
                        {
                            pawn.health.AddHediff(HediffDef.Named("PlacentaBleed"), ChildrenUtility.GetPawnBodyPart(pawn, "Torso"), null);
                        }
                    }
                }
            }


            /*if (this.GestationProgress >= 1) {
             *      if (this.Visible && PawnUtility.ShouldSendNotificationAbout (this.pawn)) {
             *              Messages.Message ("MessageGaveBirth".Translate (new object[] {
             *                      this.pawn.LabelIndefinite ()
             *              }).CapitalizeFirst (), this.pawn, MessageSound.Benefit);
             *      }
             *      Hediff_Pregnant.DoBirthSpawn (this.pawn, this.father);
             * }*/
        }
        //
        // Methods
        //
        public void DoBirthSpawn(Pawn mother, Pawn father, float chance_successful = 1.0f)
        {
            if (mother == null)
            {
                Log.Error("No mother defined");
                return;
            }
            if (father == null)
            {
                Log.Warning("No father defined");
            }

            float birthing_quality = mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth")).TryGetComp <HediffComp_TendDuration> ().tendQuality;

            mother.health.AddHediff(HediffDef.Named("PostPregnancy"), null, null);
            mother.health.AddHediff(HediffDef.Named("Lactating"), ChildrenUtility.GetPawnBodyPart(pawn, "Torso"), null);

            int num = (mother.RaceProps.litterSizeCurve == null) ? 1 : Mathf.RoundToInt(Rand.ByCurve(mother.RaceProps.litterSizeCurve, 300));

            if (num < 1)
            {
                num = 1;
            }

            // Make sure the pawn looks like mommy and daddy
            float skin_whiteness = Rand.Range(0, 1);
            // Pool of "genetic traits" the baby can inherit
            List <Trait> traitpool = new List <Trait>();

            if (mother.RaceProps.Humanlike)
            {
                // Add mom's traits to the pool
                foreach (Trait momtrait in mother.story.traits.allTraits)
                {
                    traitpool.Add(momtrait);
                }
                if (father != null)
                {
                    // Add dad's traits to the pool
                    foreach (Trait dadtrait in father.story.traits.allTraits)
                    {
                        traitpool.Add(dadtrait);
                    }
                    // Blend skin colour between mom and dad
                    skin_whiteness = Rand.Range(mother.story.melanin, father.story.melanin);
                }
                else
                {
                    // If dad doesn't exist, just use mom's skin colour
                    skin_whiteness = mother.story.melanin;
                }

                // Clear out any traits that aren't genetic from the list
                if (traitpool.Count > 0)
                {
                    foreach (Trait trait in traitpool.ToArray())
                    {
                        bool is_genetic = false;
                        foreach (TraitDef gentrait in genetic_traits)
                        {
                            if (gentrait.defName == trait.def.defName)
                            {
                                is_genetic = true;
                            }
                        }
                        if (!is_genetic)
                        {
                            traitpool.Remove(trait);
                        }
                    }
                }
            }

            // Todo: Perhaps add a way to pass on the parent's body build
            // Best way to do it might be to represent thin/fat/normal/hulk
            // as a pair of two values, strength and weight
            // For example, if the mother has an average body type, she would
            // have a strength of .5f and a weight of .5f. A fat pawn would have
            // a strength of .5f and a weight of .75f. A thin pawn would have a
            // strength of .25f and a weight of .25f. A hulk pawn would have
            // strength of .75f and weight of .75f
            //List<float> strength_pool = new List<float>();
            //List<float> weight_pool = new List<float>();

            //// Get mother and fathers info here if possible

            //float avg_strength = strength_pool.Average();
            //float avg_weight = weight_pool.Average();

            // Surname passing
            string last_name = null;

            if (mother.RaceProps.Humanlike)
            {
                if (father == null)
                {
                    last_name = NameTriple.FromString(mother.Name.ToStringFull).Last;
                }
                else
                {
                    last_name = NameTriple.FromString(father.Name.ToStringFull).Last;
                }
                //Log.Message ("Debug: Newborn is born to the " + last_name + " family.");
            }

            //PawnGenerationRequest request = new PawnGenerationRequest (mother.kindDef, mother.Faction, PawnGenerationContext.NonPlayer, mother.Map, false, true, false, false, true, false, 1, false, true, true, null, 0, 0, null, skin_whiteness, last_name);
            PawnGenerationRequest request = new PawnGenerationRequest(mother.kindDef, mother.Faction, PawnGenerationContext.NonPlayer, mother.Map.Tile, false, true, false, false, false, false, 1, false, true, true, false, false, null, 0, 0, null, skin_whiteness, last_name);

            Pawn baby = null;

            for (int i = 0; i < num; i++)
            {
                baby = PawnGenerator.GeneratePawn(request);
                if (PawnUtility.TrySpawnHatchedOrBornPawn(baby, mother))
                {
                    if (baby.playerSettings != null && mother.playerSettings != null)
                    {
                        baby.playerSettings.AreaRestriction = mother.playerSettings.AreaRestriction;
                    }
                    if (baby.RaceProps.IsFlesh)
                    {
                        baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, mother);
                        if (father != null)
                        {
                            baby.relations.AddDirectRelation(PawnRelationDefOf.Parent, father);
                        }
                    }

                    // Good until otherwise proven bad
                    bool successful_birth = true;
                    var  disabledBaby     = BackstoryDatabase.allBackstories ["CustomBackstory_NA_Childhood_Disabled"];
                    if (disabledBaby != null)
                    {
                        baby.story.childhood = disabledBaby;
                    }
                    else
                    {
                        Log.Error("Couldn't find the required Backstory: CustomBackstory_NA_Childhood_Disabled!");
                        baby.story.childhood = null;
                    }
                    baby.story.adulthood = null;
                    baby.workSettings.Disable(WorkTypeDefOf.Hunting);                      //hushes up the "has no ranged weapon" alert
                    // remove all traits
                    baby.story.traits.allTraits.Clear();

                    // Add some genetic traits
                    if (traitpool.Count > 0)
                    {
                        for (int j = 0; j != 2; j++)
                        {
                            Trait gentrait = traitpool.RandomElement();
                            if (!baby.story.traits.HasTrait(gentrait.def))
                            {
                                baby.story.traits.GainTrait(gentrait);
                            }
                        }
                    }
                    // Move the baby in front of the mother, rather than on top
                    if (mother.CurrentBed() != null)
                    {
                        baby.Position = baby.Position + new IntVec3(0, 0, 1).RotatedBy(mother.CurrentBed().Rotation);
                    }
                    // else {
                    //	 baby.Position = baby.Position + new IntVec3 (0, 0, 1).RotatedBy (mother.Rotation);
                    // }

                    // The baby died from bad chance of success
                    if (Rand.Value > chance_successful || chance_successful == 0)
                    {
                        successful_birth = false;
                    }

                    // Birth defects via drugs or alcohol
                    if (mother.health.hediffSet.HasHediff(HediffDef.Named("BirthDefectTracker")))
                    {
                        Hediff_BirthDefectTracker tracker = (Hediff_BirthDefectTracker)mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("BirthDefectTracker"));
                        // The baby died in utero from chemical affect
                        if (tracker.stillbirth)
                        {
                            successful_birth = false;
                        }
                        // The baby lived! So far, anyways
                        else
                        {
                            // Should the baby get fetal alcohol syndrome?
                            if (tracker.fetal_alcohol)
                            {
                                baby.health.AddHediff(HediffDef.Named("FetalAlcoholSyndrome"));
                            }
                            // If the mother got high while pregnant, crongrats retard
                            // now your baby is addicted to crack
                            if (tracker.drug_addictions.Count > 0)
                            {
                                foreach (HediffDef addiction in tracker.drug_addictions)
                                {
                                    baby.health.AddHediff(addiction, null, null);
                                }
                            }
                        }
                    }

                    // Inbred?
                    if (father != null && mother.relations.FamilyByBlood.Contains <Pawn> (father))
                    {
                        // 50% chance to get a birth defect from inbreeding
                        if (Rand.Range(0, 1) == 1)
                        {
                            GiveRandomBirthDefect(baby);
                            if (baby.health.hediffSet.HasHediff(HediffDef.Named("DefectStillborn")))
                            {
                                successful_birth = false;
                            }
                        }
                    }



                    // The baby was born! Yay!
                    if (successful_birth == true)
                    {
                        // Give father a happy memory if the birth was successful and he's not dead
                        if (father != null && !father.health.Dead)
                        {
                            // The father is happy the baby was born
                            father.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("PartnerGaveBirth"));
                        }

                        // Send a message that the baby was born
                        if (mother.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("HumanPregnancy")).Visible&& PawnUtility.ShouldSendNotificationAbout(mother))
                        {
                            //Messages.Message ("MessageGaveBirth".Translate (new object[] {mother.LabelIndefinite ()}).CapitalizeFirst (), mother, MessageSound.Benefit);
                            Find.LetterStack.ReceiveLetter("LabelGaveBirth".Translate(new object[] { baby.LabelIndefinite() }), "MessageHumanBirth".Translate(new object[] {
                                mother.LabelIndefinite(),
                                baby.Name.ToStringShort
                            }), LetterDefOf.Good, baby, null);
                        }

                        // Try to give PPD. If not, give "New baby" thought
                        float chance = 0.2f;
                        if (mother.story.traits.HasTrait(TraitDefOf.Psychopath))
                        {
                            chance -= 1;
                        }
                        if (mother.story.traits.HasTrait(TraitDef.Named("Nerves")))
                        {
                            chance -= 0.2f * mother.story.traits.GetTrait(TraitDef.Named("Nerves")).Degree;
                        }
                        else if (mother.story.traits.HasTrait(TraitDef.Named("NaturalMood")))
                        {
                            if (mother.story.traits.GetTrait(TraitDef.Named("NaturalMood")).Degree == 2)
                            {
                                chance -= 1;
                            }
                            if (mother.story.traits.GetTrait(TraitDef.Named("NaturalMood")).Degree == -2)
                            {
                                chance += 0.6f;
                            }
                            // For some reason this is broken

                            /*} else if (mother.story.traits.HasTrait (TraitDef.Named ("Neurotic"))) {
                             * if (mother.story.traits.GetTrait (TraitDef.Named ("Neurotic")).Degree == 1) {
                             *      chance += 0.2f;
                             * } else
                             *      chance += 0.4f;*/
                        }

                        // Because for whatever dumb reason the Math class doesn't have a Clamp method
                        if (chance < 0)
                        {
                            chance = 0;
                        }

                        if (chance > 1)
                        {
                            chance = 1;
                        }
                        Log.Message("Debugging: Chance of PPD is " + chance * 100 + "%");


                        // Try to give PPD
                        if (Rand.Value < chance)
                        {
                            mother.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("PostPartumDepression"), null);
                            bool verybad = false;
                            if (mother.story.traits.HasTrait(TraitDef.Named("NaturalMood")))
                            {
                                if (mother.story.traits.GetTrait(TraitDef.Named("NaturalMood")).Degree == -2)
                                {
                                    verybad = true;
                                }
                            }
                            else if (mother.story.traits.HasTrait(TraitDef.Named("Neurotic")))
                            {
                                if (mother.story.traits.GetTrait(TraitDef.Named("Neurotic")).Degree == 2)
                                {
                                    verybad = true;
                                }
                            }
                            // This pawn gets an exceptionally bad case of PPD
                            if (verybad)
                            {
                                foreach (Thought_Memory thought in mother.needs.mood.thoughts.memories.Memories)
                                {
                                    if (thought.def.defName == "PostPartumDepression")
                                    {
                                        thought.SetForcedStage(thought.CurStageIndex + 1);
                                    }
                                }
                            }
                        }
                        else
                        {
                            // If we didn't get PPD, then the pawn gets a mood buff
                            if (mother.health.hediffSet.HasHediff(HediffDef.Named("GaveBirthFlag")) == false)
                            {
                                mother.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("IGaveBirthFirstTime"));
                            }
                            else
                            {
                                mother.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("IGaveBirth"));
                            }
                        }
                    }
                    else
                    {
                        bool aborted = false;
                        if (chance_successful < 0f)
                        {
                            aborted = true;
                        }
                        if (baby != null)
                        {
                            Miscarry(baby, aborted);
                        }
                    }
                }
                else
                {
                    Find.WorldPawns.PassToWorld(baby, PawnDiscardDecideMode.Discard);
                }
            }
            // Post birth
            if (mother.Spawned)
            {
                // Spawn guck
                FilthMaker.MakeFilth(mother.Position, mother.Map, ThingDefOf.FilthAmnioticFluid, mother.LabelIndefinite(), 5);
                if (mother.caller != null)
                {
                    mother.caller.DoCall();
                }
                if (baby != null)
                {
                    if (baby.caller != null)
                    {
                        baby.caller.DoCall();
                    }
                }

                Log.Message("Birth quality = " + birthing_quality);
                // Possible tearing from pregnancy
                if (birthing_quality < 0.75f)
                {
                    if (birthing_quality < Rand.Value)
                    {
                        // Add a tear from giving birth
                        if (birthing_quality < Rand.Value)
                        {
                            mother.health.AddHediff(HediffDef.Named("PregnancyTearMajor"), ChildrenUtility.GetPawnBodyPart(mother, "Torso"), null);
                        }
                        else
                        {
                            mother.health.AddHediff(HediffDef.Named("PregnancyTear"), ChildrenUtility.GetPawnBodyPart(mother, "Torso"), null);
                        }
                    }
                }
            }
            pawn.health.RemoveHediff(pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth")));
            pawn.health.RemoveHediff(this);
        }
示例#26
0
        internal static void TryToImpregnate(Pawn initiator, Pawn partner)
        {
            // Lesbian/gay couples. Those cases should never result in pregnancy
            if (initiator.gender == partner.gender)
            {
                return;
            }

            // One of the two is sterile, so don't continue
            foreach (Pawn pawn in new List <Pawn> {
                initiator, partner
            })
            {
                if (pawn.health.hediffSet.HasHediff(HediffDef.Named("Sterile")))
                {
                    return;
                }
            }

            Pawn male   = initiator.gender == Gender.Male? initiator: partner;
            Pawn female = initiator.gender == Gender.Female ? initiator : partner;

            // Only humans can be impregnated for now
            if (!ChildrenUtility.RaceUsesChildren(female))
            {
                return;
            }

            BodyPartRecord torso         = female.RaceProps.body.AllParts.Find(x => x.def == BodyPartDefOf.Torso);
            HediffDef      contraceptive = HediffDef.Named("Contraceptive");

            // Make sure the woman is not pregnanct and not using a contraceptive
            if (female.health.hediffSet.HasHediff(HediffDefOf.Pregnant, torso) || female.health.hediffSet.HasHediff(contraceptive, null) || male.health.hediffSet.HasHediff(contraceptive, null))
            {
                return;
            }
            // Check the pawn's age to see how likely it is she can carry a fetus
            // 25 and below is guaranteed, 50 and above is impossible, 37.5 is 50% chance
            float preg_chance = Math.Max(1 - (Math.Max(female.ageTracker.AgeBiologicalYearsFloat - 25, 0) / 25), 0) * 0.33f;

            // For debug testing
            //float preg_chance = 1;
            if (preg_chance < Rand.Value)
            {
                if (Prefs.DevMode)
                {
                    Log.Message("Impregnation failed. Chance was " + preg_chance);
                }
                return;
            }
            if (Prefs.DevMode)
            {
                Log.Message("Impregnation succeeded. Chance was " + preg_chance);
            }
            // Spawn a bunch of hearts. Sharp eyed players may notice this means impregnation occurred.
            for (int i = 0; i <= 3; i++)
            {
                MoteMaker.ThrowMetaIcon(male.Position, male.MapHeld, ThingDefOf.Mote_Heart);
                MoteMaker.ThrowMetaIcon(female.Position, male.MapHeld, ThingDefOf.Mote_Heart);
            }

            // Do the actual impregnation. We apply it to the torso because Remove_Hediff in operations doesn't work on WholeBody (null body part)
            // for whatever reason.
            female.health.AddHediff(Hediff_HumanPregnancy.Create(female, male), torso);
        }
        public override void Tick()
        {
            // Something has gone horribly wrong
            if (pawn.health.hediffSet.HasHediff(HediffDef.Named("PostPregnancy")))
            {
                Log.Error("HumanPregnancy Hediff was not properly removed when pawn " + pawn.NameStringShort + " gave birth.");
                // delet this
                if (pawn.health.hediffSet.HasHediff(HediffDef.Named("GivingBirth")))
                {
                    pawn.health.RemoveHediff(pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth")));
                }
                pawn.health.RemoveHediff(this);
            }

            this.ageTicks++;
            if (this.pawn.IsHashIntervalTick(1000))
            {
                if (this.pawn.needs.food != null && this.pawn.needs.food.CurCategory == HungerCategory.Starving && Rand.MTBEventOccurs(0.5f, 60000, 1000))
                {
                    if (this.Visible && PawnUtility.ShouldSendNotificationAbout(this.pawn))
                    {
                        Messages.Message("MessageMiscarriedStarvation".Translate(new object[] {
                            this.pawn.LabelIndefinite()
                        }).CapitalizeFirst(), this.pawn, MessageSound.Negative);
                    }
                    Miscarry(false);
                    return;
                }
                if (this.IsSeverelyWounded && Rand.MTBEventOccurs(0.5f, 60000, 1000))
                {
                    if (this.Visible && PawnUtility.ShouldSendNotificationAbout(this.pawn))
                    {
                        Messages.Message("MessageMiscarriedPoorHealth".Translate(new object[] {
                            this.pawn.LabelIndefinite()
                        }).CapitalizeFirst(), this.pawn, MessageSound.Negative);
                    }
                    Miscarry(false);
                    return;
                }
            }
            GestationProgress += 1 / (pawn.RaceProps.gestationPeriodDays * 60000);

            // Discover from
            if (!is_discovered)
            {
                if ((GestationProgress > 0.25f && pawn.story.bodyType != BodyType.Fat) || (GestationProgress > 0.1f && pawn.story.bodyType == BodyType.Thin))
                {
                    DiscoverPregnancy();
                }
            }

            // Final stage of pregnancy
            if (CurStageIndex == 3)
            {
                if (!pawn.health.hediffSet.HasHediff(HediffDef.Named("GivingBirth")))
                {
                    // Notify the player birth is near
                    if (Visible && PawnUtility.ShouldSendNotificationAbout(pawn))
                    {
                        Messages.Message("MessageHavingContractions".Translate(new object[] { pawn.LabelIndefinite() }).CapitalizeFirst(), pawn, MessageSound.Standard);
                    }
                    // Give the mother the GivingBirth hediff
                    pawn.health.AddHediff(HediffDef.Named("GivingBirth"), ChildrenUtility.GetPawnBodyPart(pawn, "Torso"), null);
                }
                // We're having contractions now
                else
                {
                    // Has the pregnancy been tended to?
                    if (pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("GivingBirth")).IsTended())
                    {
                        // Then we get a safe pregnancy
                        DoBirthSpawn(pawn, father, 1);
                    }
                    // natural birth (probably not a good idea!)
                    else if (GestationProgress >= 1)
                    {
                        // Do risky pregnancy
                        DoBirthSpawn(pawn, father, 0.9f);
                        if (Rand.Value <= 0.1f)
                        {
                            pawn.health.AddHediff(HediffDef.Named("PlacentaBleed"), ChildrenUtility.GetPawnBodyPart(pawn, "Torso"), null);
                        }
                    }
                }
            }


            /*if (this.GestationProgress >= 1) {
             *      if (this.Visible && PawnUtility.ShouldSendNotificationAbout (this.pawn)) {
             *              Messages.Message ("MessageGaveBirth".Translate (new object[] {
             *                      this.pawn.LabelIndefinite ()
             *              }).CapitalizeFirst (), this.pawn, MessageSound.Benefit);
             *      }
             *      Hediff_Pregnant.DoBirthSpawn (this.pawn, this.father);
             * }*/
        }
示例#28
0
 static void TryGiveJob_Patch(JobGiver_OptimizeApparel __instance, ref Job __result, Pawn pawn)
 {
     if (__result != null)
     {
         // Stop the game from automatically allocating pawns Wear jobs they cannot fulfil
         if ((pawn.ageTracker.CurLifeStageIndex <= AgeStage.Toddler && __result.targetA.Thing.TryGetComp <CompBabyGear>() == null && ChildrenUtility.RaceUsesChildren(pawn)) ||
             (pawn.ageTracker.CurLifeStageIndex >= AgeStage.Child && __result.targetA.Thing.TryGetComp <CompBabyGear>() != null))
         {
             __result = null;
         }
     }
     else
     {
         // makes pawn to remove baby clothes when too old for them.
         List <Apparel> wornApparel = pawn.apparel.WornApparel;
         if (pawn.ageTracker.CurLifeStageIndex >= AgeStage.Child)
         {
             for (int i = wornApparel.Count - 1; i >= 0; i--)
             {
                 CompBabyGear compBabyGear = wornApparel[i].TryGetComp <CompBabyGear>();
                 if (compBabyGear != null)
                 {
                     __result = new Job(JobDefOf.RemoveApparel, wornApparel[i])
                     {
                         haulDroppedApparel = true
                     };
                     return;
                 }
             }
         }
     }
 }
示例#29
0
 public static IEnumerable <Pawn> BedCandidates(Building_Bed bed)
 {
     if (bed.def.defName.Contains("Crib"))
     {
         IEnumerable <Pawn> candidates = bed.Map.mapPawns.FreeColonists.Where(x => x.ageTracker.CurLifeStageIndex <= 2 && x.Faction == Faction.OfPlayer && ChildrenUtility.RaceUsesChildren(x));
         return(candidates);
     }
     else
     {
         return(bed.Map.mapPawns.FreeHumanlikesOfFaction(Faction.OfPlayer));
     }
 }
示例#30
0
        public static T FailOnBaby <T>(this T f) where T : JobDriver
        {
            f.AddEndCondition(delegate
            {
                //				return JobCondition.Incompletable;
                //CompBabyGear compBabyGear = f.job.GetTarget(TargetIndex.A).Thing.TryGetComp<CompBabyGear>();
                Pawn personDressing = f.GetActor();
                if (f.GetActor().ageTracker.CurLifeStageIndex <= 1 && f.job.GetTarget(TargetIndex.A).Thing.TryGetComp <CompBabyGear>() == null && ChildrenUtility.RaceUsesChildren(f.GetActor()))
                {
                    Messages.Message("MessageAdultClothesOnBaby".Translate(new object[] {
                        personDressing.Name.ToStringShort
                    }), personDressing, MessageTypeDefOf.CautionInput);
                    return(JobCondition.Incompletable);
                }
                //tried testing for bool "isBabyGear" but that caused a null error exception, so I switched to just testing if comp was null, will look into later
                if (f.GetActor().ageTracker.CurLifeStageIndex > 1 && f.job.GetTarget(TargetIndex.A).Thing.TryGetComp <CompBabyGear>() != null)
                {
                    Messages.Message("MessageBabyClothesOnAdult".Translate(new object[] {
                        personDressing.LabelShort
                    }), personDressing, MessageTypeDefOf.CautionInput);

                    return(JobCondition.Incompletable);
                }
                else
                {
                    return(JobCondition.Ongoing);
                }
            });
            return(f);
        }