コード例 #1
0
 public static void SecondaryLovinChanceFactor_Postfix(ref float __result, Pawn ___pawn, Pawn otherPawn, Pawn_RelationsTracker __instance)
 {
     if (!SyrIndividuality.RomanceDisabled)
     {
         CompIndividuality comp         = ___pawn.TryGetComp <CompIndividuality>();
         float             genderFactor = 1f;
         if (___pawn == otherPawn)
         {
             __result = 0f;
         }
         if (comp != null && ___pawn.gender != otherPawn.gender)
         {
             if (comp.sexuality == CompIndividuality.Sexuality.Straight)
             {
                 genderFactor = 1.0f;
             }
             else if (comp.sexuality == CompIndividuality.Sexuality.Bisexual)
             {
                 genderFactor = 0.75f;
             }
             else if (comp.sexuality == CompIndividuality.Sexuality.Gay)
             {
                 genderFactor = 0.1f;
             }
             else if (comp.sexuality == CompIndividuality.Sexuality.Asexual)
             {
                 genderFactor = 0f;
             }
         }
         else if (comp != null && ___pawn.gender == otherPawn.gender)
         {
             if (comp.sexuality == CompIndividuality.Sexuality.Gay)
             {
                 genderFactor = 1.0f;
             }
             else if (comp.sexuality == CompIndividuality.Sexuality.Bisexual)
             {
                 genderFactor = 0.75f;
             }
             else if (comp.sexuality == CompIndividuality.Sexuality.Straight)
             {
                 genderFactor = 0.1f;
             }
             else if (comp.sexuality == CompIndividuality.Sexuality.Asexual)
             {
                 genderFactor = 0f;
             }
         }
         float agePawn      = ___pawn.ageTracker.AgeBiologicalYearsFloat;
         float ageOtherPawn = otherPawn.ageTracker.AgeBiologicalYearsFloat;
         float ageFactor    = 1f;
         if (___pawn.gender == Gender.Male)
         {
             float min   = agePawn - 30f;
             float lower = agePawn - 10f;
             float upper = agePawn + 5f;
             float max   = agePawn + 15f;
             ageFactor = GenMath.FlatHill(0.2f, min, lower, upper, max, 0.2f, ageOtherPawn);
         }
         else if (___pawn.gender == Gender.Female)
         {
             float min2   = agePawn - 20f;
             float lower2 = agePawn - 10f;
             float upper2 = agePawn + 10f;
             float max2   = agePawn + 30f;
             ageFactor = GenMath.FlatHill(0.2f, min2, lower2, upper2, max2, 0.2f, ageOtherPawn);
         }
         float healthFactor = 1f;
         healthFactor *= Mathf.Lerp(0.2f, 1f, otherPawn.health.capacities.GetLevel(PawnCapacityDefOf.Talking));
         float beauty = 0;
         if (otherPawn.RaceProps.Humanlike)
         {
             beauty = otherPawn.GetStatValue(StatDefOf.PawnBeauty, true);
         }
         float beautyFactor = 1f;
         beautyFactor = beautyCurve.Evaluate(beauty);
         float youthFactorPawn      = Mathf.InverseLerp(16f, 18f, agePawn);
         float youthFactorOtherPawn = Mathf.InverseLerp(16f, 18f, ageOtherPawn);
         __result = genderFactor * ageFactor * healthFactor * beautyFactor * youthFactorPawn * youthFactorOtherPawn;
     }
 }
コード例 #2
0
 public static void GRSecondaryRomanceChanceFactor(Pawn_RelationsTracker __instance, ref float __result, ref Pawn ___pawn, Pawn otherPawn)
 {
     __result = AttractionUtility.CalculateAttraction(___pawn, otherPawn, false, true);
 }
コード例 #3
0
        internal static float               _AttractionTo(this Pawn_RelationsTracker _this, Pawn otherPawn)
        {
            var pawn = _this.GetPawn();

            if (!PawnsAreValidMatches(pawn, otherPawn))
            {
                return(0f);
            }
            float num  = 1f;
            float num2 = 1f;
            float ageBiologicalYearsFloat  = pawn.ageTracker.AgeBiologicalYearsFloat;
            float ageBiologicalYearsFloat2 = otherPawn.ageTracker.AgeBiologicalYearsFloat;

            if (pawn.gender == Gender.Male)
            {
                if (
                    (pawn.RaceProps.Humanlike) &&
                    (pawn.story.traits.HasTrait(TraitDefOf.Gay))
                    )
                {
                    if (otherPawn.gender == Gender.Female)
                    {
                        return(0f);
                    }
                }
                else if (otherPawn.gender == Gender.Male)
                {
                    return(0f);
                }
                num2 = GenMath.FlatHill(16f, 20f, ageBiologicalYearsFloat, ageBiologicalYearsFloat + 15f, ageBiologicalYearsFloat2);
            }
            else if (pawn.gender == Gender.Female)
            {
                if (
                    (pawn.RaceProps.Humanlike) &&
                    (pawn.story.traits.HasTrait(TraitDefOf.Gay))
                    )
                {
                    if (otherPawn.gender == Gender.Male)
                    {
                        return(0f);
                    }
                }
                else if (otherPawn.gender == Gender.Female)
                {
                    num = 0.15f;
                }
                if (ageBiologicalYearsFloat2 < ageBiologicalYearsFloat - 10f)
                {
                    return(0f);
                }
                if (ageBiologicalYearsFloat2 < ageBiologicalYearsFloat - 3f)
                {
                    num2 = Mathf.InverseLerp(ageBiologicalYearsFloat - 10f, ageBiologicalYearsFloat - 3f, ageBiologicalYearsFloat2) * 0.2f;
                }
                else
                {
                    num2 = GenMath.FlatHill(0.2f, ageBiologicalYearsFloat - 3f, ageBiologicalYearsFloat, ageBiologicalYearsFloat + 10f, ageBiologicalYearsFloat + 40f, 0.1f, ageBiologicalYearsFloat2);
                }
            }
            float num3 = 1f;

            num3 *= Mathf.Lerp(0.2f, 1f, otherPawn.health.capacities.GetEfficiency(PawnCapacityDefOf.Talking));
            num3 *= Mathf.Lerp(0.2f, 1f, otherPawn.health.capacities.GetEfficiency(PawnCapacityDefOf.Manipulation));
            num3 *= Mathf.Lerp(0.2f, 1f, otherPawn.health.capacities.GetEfficiency(PawnCapacityDefOf.Moving));
            float num4 = 1f;

            foreach (PawnRelationDef current in pawn.GetRelations(otherPawn))
            {
                num4 *= current.attractionFactor;
            }
            int num5 = 0;

            if (otherPawn.RaceProps.Humanlike)
            {
                num5 = otherPawn.story.traits.DegreeOfTrait(TraitDefOf.Beauty);
            }
            float num6 = 1f;

            if (num5 < 0)
            {
                num6 = 0.3f;
            }
            else if (num5 > 0)
            {
                num6 = 2.3f;
            }
            float num7 = Mathf.InverseLerp(15f, 18f, ageBiologicalYearsFloat);
            float num8 = Mathf.InverseLerp(15f, 18f, ageBiologicalYearsFloat2);

            return(num * num2 * num3 * num4 * num7 * num8 * num6);
        }
コード例 #4
0
        internal static float _SecondaryRomanceChanceFactor(this Pawn_RelationsTracker t, Pawn otherPawn)
        {
            Pawn pawn = t.GetPawn();

            if (pawn.def != otherPawn.def || pawn == otherPawn)
            {
                return(0f);
            }
            Rand.PushSeed();
            Rand.Seed = pawn.HashOffset();
            bool flag = Rand.Value < 0.015f;

            Rand.PopSeed();
            float          num  = 1f;
            float          num2 = 1f;
            float          num9 = 1f;
            float          ageBiologicalYearsFloat  = pawn.ageTracker.AgeBiologicalYearsFloat;
            float          ageBiologicalYearsFloat2 = otherPawn.ageTracker.AgeBiologicalYearsFloat;
            PsychologyPawn realPawn = pawn as PsychologyPawn;

            if (PsychologyBase.ActivateKinsey() && realPawn != null)
            {
                flag = true;
                float kinsey = 3 - realPawn.sexuality.kinseyRating;
                float h**o   = (pawn.gender == otherPawn.gender) ? 1f : -1f;
                num9 = Mathf.InverseLerp(3f, 0f, kinsey * h**o);
            }
            if (pawn.gender == Gender.Male)
            {
                if (!flag)
                {
                    if (pawn.RaceProps.Humanlike && pawn.story.traits.HasTrait(TraitDefOf.Gay))
                    {
                        if (otherPawn.gender == Gender.Female)
                        {
                            return(0f);
                        }
                    }
                    else if (otherPawn.gender == Gender.Male)
                    {
                        return(0f);
                    }
                }
                num2 = GenMath.FlatHill(0f, 16f, 20f, ageBiologicalYearsFloat, ageBiologicalYearsFloat + 15f, 0.07f, ageBiologicalYearsFloat2);
                if (pawn.RaceProps.Humanlike && pawn.story.traits.HasTrait(TraitDefOfPsychology.OpenMinded))
                {
                    num2 = 1f;
                }
            }
            else if (pawn.gender == Gender.Female)
            {
                if (!flag)
                {
                    if (pawn.RaceProps.Humanlike && pawn.story.traits.HasTrait(TraitDefOf.Gay))
                    {
                        if (otherPawn.gender == Gender.Male)
                        {
                            return(0f);
                        }
                    }
                    else if (otherPawn.gender == Gender.Female)
                    {
                        num = 0f;
                    }
                }
                if ((ageBiologicalYearsFloat2 < ageBiologicalYearsFloat - 10f) && (pawn.story.traits.HasTrait(TraitDefOfPsychology.OpenMinded)))
                {
                    return(0f);
                }
                if (ageBiologicalYearsFloat2 < ageBiologicalYearsFloat - 3f)
                {
                    num2 = Mathf.InverseLerp(ageBiologicalYearsFloat - 10f, ageBiologicalYearsFloat - 3f, ageBiologicalYearsFloat2) * 0.2f;
                }
                else
                {
                    num2 = GenMath.FlatHill(0.2f, ageBiologicalYearsFloat - 3f, ageBiologicalYearsFloat, ageBiologicalYearsFloat + 10f, ageBiologicalYearsFloat + 30f, 0.1f, ageBiologicalYearsFloat2);
                }
                if (pawn.RaceProps.Humanlike && pawn.story.traits.HasTrait(TraitDefOfPsychology.OpenMinded))
                {
                    num2 = 1f;
                }
            }
            float num3 = 1f;

            num3 *= Mathf.Lerp(0.2f, 1f, otherPawn.health.capacities.GetEfficiency(PawnCapacityDefOf.Talking));
            num3 *= Mathf.Lerp(0.2f, 1f, otherPawn.health.capacities.GetEfficiency(PawnCapacityDefOf.Manipulation));
            num3 *= Mathf.Lerp(0.2f, 1f, otherPawn.health.capacities.GetEfficiency(PawnCapacityDefOf.Moving));
            if (pawn.RaceProps.Humanlike && pawn.story.traits.HasTrait(TraitDefOfPsychology.OpenMinded))
            {
                num3 = 1f;
            }
            float num4 = 1f;

            foreach (PawnRelationDef current in pawn.GetRelations(otherPawn))
            {
                num4 *= current.attractionFactor;
            }
            int num5 = 0;

            if (otherPawn.RaceProps.Humanlike)
            {
                num5 = otherPawn.story.traits.DegreeOfTrait(TraitDefOf.Beauty);
            }
            if (pawn.RaceProps.Humanlike && pawn.story.traits.HasTrait(TraitDefOfPsychology.OpenMinded) || pawn.health.capacities.GetEfficiency(PawnCapacityDefOf.Sight) == 0f)
            {
                num5 = 0;
            }
            float num6 = 1f;

            if (num5 < 0)
            {
                num6 = 0.3f;
            }
            else if (num5 > 0)
            {
                num6 = 2.3f;
            }
            float num7 = Mathf.InverseLerp(15f, 18f, ageBiologicalYearsFloat);
            float num8 = Mathf.InverseLerp(15f, 18f, ageBiologicalYearsFloat2);

            return(num * num2 * num3 * num4 * num7 * num8 * num6 * num9);
        }
コード例 #5
0
        internal void MakePermanentlyFeral()
        {
            Hediff fHediff;

            if (StateDef.forcedHediff != null)
            {
                fHediff = Pawn.health.hediffSet.GetFirstHediffOfDef(StateDef.forcedHediff);
            }
            else
            {
                fHediff = null;
            }

            //transfer relationships back if possible
            var  gComp = Find.World.GetComponent <PawnmorphGameComp>();
            Pawn oPawn = gComp.GetTransformedPawnContaining(Pawn)?.Item1?.OriginalPawns.FirstOrDefault();

            if (oPawn == Pawn)
            {
                oPawn = null;
            }

            Pawn_RelationsTracker aRelations = Pawn.relations;

            if (aRelations != null && oPawn != null)
            {
                FormerHumanUtilities.TransferRelationsToOriginal(oPawn, Pawn);
            }

            Pawn.health.AddHediff(TfHediffDefOf.PermanentlyFeral);
            if (fHediff != null)
            {
                Pawn.health.RemoveHediff(fHediff);
            }

            var             loader     = Find.World.GetComponent <PawnmorphGameComp>();
            TransformedPawn inst       = loader.GetTransformedPawnContaining(Pawn)?.Item1;
            var             singleInst = inst as TransformedPawnSingle; //hacky, need to come up with a better solution

            foreach (Pawn instOriginalPawn in inst?.OriginalPawns ?? Enumerable.Empty <Pawn>()
                     ) //needed to handle merges correctly
            {
                ReactionsHelper.OnPawnPermFeral(instOriginalPawn, Pawn,
                                                singleInst?.reactionStatus ?? FormerHumanReactionStatus.Wild);
            }

            //remove the original and destroy the pawns
            foreach (Pawn instOriginalPawn in inst?.OriginalPawns ?? Enumerable.Empty <Pawn>())
            {
                instOriginalPawn.Destroy();
            }

            if (inst != null)
            {
                loader.RemoveInstance(inst);
            }

            if (inst != null || Pawn.Faction == Faction.OfPlayer)
            {
                Find.LetterStack.ReceiveLetter("LetterHediffFromPermanentTFLabel".Translate(Pawn.LabelShort).CapitalizeFirst(),
                                               "LetterHediffFromPermanentTF".Translate(Pawn.LabelShort).CapitalizeFirst(),
                                               LetterDefOf.NegativeEvent, Pawn);
            }

            Pawn.needs?.AddOrRemoveNeedsAsAppropriate(); //make sure any comps get added/removed as appropriate
            PawnComponentsUtility.AddAndRemoveDynamicComponents(Pawn);
        }
コード例 #6
0
 public static IEnumerable <Pawn> getPawnsWithDirectRelationsWithMe(Pawn_RelationsTracker r)
 {
     return((HashSet <Pawn>)field.GetValue(r));
 }
コード例 #7
0
        public static void PsychologyFormula(Pawn_RelationsTracker __instance, ref float __result, Pawn otherPawn)
        {
            Pawn           pawn     = Traverse.Create(__instance).Field("pawn").GetValue <Pawn>();
            PsychologyPawn realPawn = pawn as PsychologyPawn;

            if (realPawn != null)
            {
                if (pawn.def != otherPawn.def || pawn == otherPawn)
                {
                    __result = 0f;
                    return;
                }
                /* Throw away the existing result and substitute our own formula. */
                float ageFactor                = 1f;
                float sexualityFactor          = 1f;
                float ageBiologicalYearsFloat  = pawn.ageTracker.AgeBiologicalYearsFloat;
                float ageBiologicalYearsFloat2 = otherPawn.ageTracker.AgeBiologicalYearsFloat;
                if (PsychologyBase.ActivateKinsey() && realPawn.sexuality != null)
                {
                    float kinsey = 3 - realPawn.sexuality.kinseyRating;
                    float h**o   = (pawn.gender == otherPawn.gender) ? 1f : -1f;
                    sexualityFactor = Mathf.InverseLerp(3f, 0f, kinsey * h**o);
                }
                else if (Rand.ValueSeeded(pawn.thingIDNumber ^ 3273711) >= 0.015f)
                {
                    if (pawn.RaceProps.Humanlike && pawn.story.traits.HasTrait(TraitDefOf.Gay))
                    {
                        if (otherPawn.gender != pawn.gender)
                        {
                            __result = 0f;
                            return;
                        }
                    }
                    else if (otherPawn.gender == pawn.gender)
                    {
                        __result = 0f;
                        return;
                    }
                }
                if (pawn.gender == Gender.Male)
                {
                    if (ageBiologicalYearsFloat2 < 16f)
                    {
                        __result = 0f;
                        return;
                    }
                    float min   = Mathf.Max(16f, ageBiologicalYearsFloat - 30f);
                    float lower = Mathf.Max(20f, ageBiologicalYearsFloat - 10f);
                    ageFactor = GenMath.FlatHill(0.15f, min, lower, ageBiologicalYearsFloat, ageBiologicalYearsFloat + 10f, 0.15f, ageBiologicalYearsFloat2);
                }
                else if (pawn.gender == Gender.Female)
                {
                    if (ageBiologicalYearsFloat2 < 16f)
                    {
                        __result = 0f;
                        return;
                    }
                    if ((ageBiologicalYearsFloat2 < ageBiologicalYearsFloat - 10f) && (!pawn.story.traits.HasTrait(TraitDefOfPsychology.OpenMinded)))
                    {
                        ageFactor *= 0.15f;
                    }
                    if (ageBiologicalYearsFloat2 < ageBiologicalYearsFloat - 3f)
                    {
                        ageFactor *= Mathf.InverseLerp(ageBiologicalYearsFloat - 10f, ageBiologicalYearsFloat - 3f, ageBiologicalYearsFloat2) * 0.3f;
                    }
                    else
                    {
                        ageFactor *= GenMath.FlatHill(0.3f, ageBiologicalYearsFloat - 3f, ageBiologicalYearsFloat, ageBiologicalYearsFloat + 10f, ageBiologicalYearsFloat + 30f, 0.15f, ageBiologicalYearsFloat2);
                    }
                }
                ageFactor = Mathf.Lerp(ageFactor, (1.6f - ageFactor), realPawn.psyche.GetPersonalityRating(PersonalityNodeDefOf.Experimental));
                float disabilityFactor = 1f;
                disabilityFactor *= Mathf.Lerp(0.2f, 1f, otherPawn.health.capacities.GetLevel(PawnCapacityDefOf.Talking));
                disabilityFactor *= Mathf.Lerp(0.2f, 1f, otherPawn.health.capacities.GetLevel(PawnCapacityDefOf.Manipulation));
                disabilityFactor *= Mathf.Lerp(0.2f, 1f, otherPawn.health.capacities.GetLevel(PawnCapacityDefOf.Moving));
                disabilityFactor  = Mathf.Lerp(disabilityFactor, (1.6f - disabilityFactor), realPawn.psyche.GetPersonalityRating(PersonalityNodeDefOf.Experimental));
                if (pawn.RaceProps.Humanlike && pawn.story.traits.HasTrait(TraitDefOfPsychology.OpenMinded))
                {
                    ageFactor        = 1f;
                    disabilityFactor = 1f;
                }
                float relationFactor = 1f;
                foreach (PawnRelationDef current in pawn.GetRelations(otherPawn))
                {
                    relationFactor *= current.attractionFactor;
                }
                int beauty = 0;
                if (otherPawn.RaceProps.Humanlike)
                {
                    beauty = otherPawn.story.traits.DegreeOfTrait(TraitDefOf.Beauty);
                }
                if (pawn.RaceProps.Humanlike && pawn.story.traits.HasTrait(TraitDefOfPsychology.OpenMinded))
                {
                    beauty = 0;
                }
                float beautyFactor = 1f;
                if (beauty < 0)
                {
                    beautyFactor = 0.3f;
                }
                else if (beauty > 0)
                {
                    beautyFactor = 2.3f;
                }
                if (pawn.health.capacities.GetLevel(PawnCapacityDefOf.Sight) < 1f)
                {
                    /* Pawns who can't see as well can't determine beauty as well. */
                    beautyFactor = Mathf.Pow(beautyFactor, pawn.health.capacities.GetLevel(PawnCapacityDefOf.Sight));
                }
                if (realPawn != null && PsychologyBase.ActivateKinsey() && realPawn.sexuality != null && realPawn.sexuality.AdjustedSexDrive < 1f)
                {
                    /* Pawns with low sex drive will care about physical features less. */
                    beautyFactor     = Mathf.Pow(beautyFactor, realPawn.sexuality.AdjustedSexDrive);
                    ageFactor        = Mathf.Pow(ageFactor, realPawn.sexuality.AdjustedSexDrive);
                    disabilityFactor = Mathf.Pow(disabilityFactor, realPawn.sexuality.AdjustedSexDrive);
                }
                float initiatorYouthFactor = Mathf.InverseLerp(15f, 18f, ageBiologicalYearsFloat);
                float recipientYouthFactor = Mathf.InverseLerp(15f, 18f, ageBiologicalYearsFloat2);
                __result = 1f * sexualityFactor * ageFactor * disabilityFactor * relationFactor * beautyFactor * initiatorYouthFactor * recipientYouthFactor;
            }
        }
コード例 #8
0
 private static IEnumerable <Pawn> FamilyByBlood_Internal(Pawn_RelationsTracker __instance)
 {
     if (__instance.RelatedToAnyoneOrAnyoneRelatedToMe)
     {
         familyStack         = null;
         familyChildrenStack = null;
         familyVisited       = null;
         try
         {
             //familyStack = SimplePool<List<Pawn>>.Get();
             if (!pawnListStack.TryPop(out familyStack))
             {
                 familyStack = new List <Pawn>();
             }
             //familyChildrenStack = SimplePool<List<Pawn>>.Get();
             if (!pawnListStack.TryPop(out familyChildrenStack))
             {
                 familyChildrenStack = new List <Pawn>();
             }
             //familyVisited = SimplePool<HashSet<Pawn>>.Get();
             if (!pawnHashsetStack.TryPop(out familyVisited))
             {
                 familyVisited = new HashSet <Pawn>();
             }
             familyStack.Add(pawn(__instance));
             familyVisited.Add(pawn(__instance));
             while (familyStack.Any())
             {
                 Pawn p = familyStack[familyStack.Count - 1];
                 familyStack.RemoveLast();
                 if (p != pawn(__instance))
                 {
                     yield return(p);
                 }
                 Pawn father = p.GetFather();
                 if (father != null && !familyVisited.Contains(father))
                 {
                     familyStack.Add(father);
                     familyVisited.Add(father);
                 }
                 Pawn mother = p.GetMother();
                 if (mother != null && !familyVisited.Contains(mother))
                 {
                     familyStack.Add(mother);
                     familyVisited.Add(mother);
                 }
                 familyChildrenStack.Clear();
                 familyChildrenStack.Add(p);
                 while (familyChildrenStack.Any())
                 {
                     Pawn child = familyChildrenStack[familyChildrenStack.Count - 1];
                     familyChildrenStack.RemoveLast();
                     if (child != p && child != pawn(__instance))
                     {
                         yield return(child);
                     }
                     foreach (Pawn child1 in child.relations.Children)
                     {
                         if (!familyVisited.Contains(child1))
                         {
                             familyChildrenStack.Add(child1);
                             familyVisited.Add(child1);
                         }
                     }
                     child = null;
                 }
                 p = null;
             }
         }
         finally
         {
             familyStack.Clear();
             //SimplePool<List<Pawn>>.Return(familyStack);
             pawnListStack.Push(familyStack);
             familyChildrenStack.Clear();
             //SimplePool<List<Pawn>>.Return(familyChildrenStack);
             pawnListStack.Push(familyChildrenStack);
             familyVisited.Clear();
             //SimplePool<HashSet<Pawn>>.Return(familyVisited);
             pawnHashsetStack.Push(familyVisited);
         }
     }
 }
コード例 #9
0
 public static bool get_RelatedPawns(Pawn_RelationsTracker __instance, ref IEnumerable <Pawn> __result)
 {
     __result = RelatedPawns2(__instance);
     return(false);
 }
コード例 #10
0
        protected override bool TryExecuteWorker(IncidentParms parms)
        {
            Map  map        = parms.target as Map;
            Pawn closestCat = TryGetClosestCatOnMap(map);

            GuardianProperties guardianProps = def.GetModExtension <GuardianProperties>();

            if (closestCat != null)
            {
                //Transform Cat
                //Generate guardian
                Pawn newGuardian = PawnGenerator.GeneratePawn(new PawnGenerationRequest(
                                                                  guardianProps.guardianDef, Faction.OfPlayer, PawnGenerationContext.NonPlayer, -1, true, false, false, false, false,
                                                                  true, 0f, false, true, true, false, false, false, false, null,
                                                                  null, null, closestCat.ageTracker.AgeBiologicalYears, closestCat.ageTracker.AgeChronologicalYears, closestCat.gender, null, null));

                //Transfer over family trees and relations to guardian from old cat.
                Pawn_RelationsTracker oldRelations = closestCat.relations;
                Pawn_RelationsTracker newRelations = newGuardian.relations;

                //Transfer over relations.
                List <DirectPawnRelation> relationList = new List <DirectPawnRelation>(oldRelations.DirectRelations);
                foreach (DirectPawnRelation relation in relationList)
                {
                    newRelations.AddDirectRelation(relation.def, relation.otherPawn);
                    oldRelations.RemoveDirectRelation(relation);
                }

                //Fully train.
                foreach (TrainableDef trainableDef in DefDatabase <TrainableDef> .AllDefs)
                {
                    for (int step = 0; step < trainableDef.steps; step++)
                    {
                        newGuardian.training.Train(trainableDef, null);
                    }
                }

                //Make a new name.
                if (closestCat.Name != null)
                {
                    if (closestCat.gender == Gender.Male)
                    {
                        newGuardian.Name = new NameSingle(NameGenerator.GenerateName(RulePackDef.Named("NamerAnimalGenericMale")), false);
                    }
                    else
                    {
                        newGuardian.Name = new NameSingle(NameGenerator.GenerateName(RulePackDef.Named("NamerAnimalGenericFemale")), false);
                    }
                }

                //Dump inventory, if any.
                closestCat?.inventory.DropAllNearPawn(closestCat.Position);

                Letter letter = LetterMaker.MakeLetter("Cults_BastGuardianTransformationLabel".Translate(closestCat.Name.ToStringShort), "Cults_BastGuardianTransformationDescription".Translate(closestCat.Name.ToStringFull), LetterDefOf.PositiveEvent, new GlobalTargetInfo(newGuardian));

                //Remove old cat.
                IntVec3 catPosition = closestCat.Position;
                closestCat.Destroy(DestroyMode.Vanish);

                //Spawn in guardian.
                GenSpawn.Spawn(newGuardian, catPosition, map);
                MoteMaker.MakePowerBeamMote(catPosition, map);

                Current.Game.letterStack.ReceiveLetter(letter);
            }

            return(true);
        }