Beispiel #1
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);
            }
        }
Beispiel #3
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);
            }
        }
Beispiel #4
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);
                }
            }
        //
        // 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);
            }
        }
Beispiel #6
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);
 }
Beispiel #7
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);
                        }
                    }
                }
            }
Beispiel #8
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--;
                        }
                    }
                }
            }
        }
        //
        // 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);
        }
        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);
                }
            });
        }
Beispiel #11
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));
     }
 }
        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);
        }
 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;
                 }
             }
         }
     }
 }
Beispiel #14
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);
        }