private void ChangeBodyType(Pawn pawn, BodyTypeDef bt)
        {
            AlienPartGenerator alienPartGenerator = alienRace.alienRace.generalSettings.alienPartGenerator;
            var storyTrv    = Traverse.Create(pawn.story);
            var newStory    = new Pawn_StoryTracker(pawn);
            var newStoryTrv = Traverse.Create(newStory);

            AccessTools.GetFieldNames(typeof(Pawn_StoryTracker))
            .ForEach(f => newStoryTrv.Field(f).SetValue(storyTrv.Field(f).GetValue()));
            newStory.bodyType = bt;
            if (Props.colourSkinTwo || Props.colourSkin)
            {
                if (compAlien != null)
                {
                    ColorChannelGenerator Alienskin = alienRace.alienRace.generalSettings.alienPartGenerator.colorChannels.Find(x => x.name == "skin");
                    AlienPartGenerator.ExposableValueTuple <UnityEngine.Color, UnityEngine.Color> skin;
                    if (compAlien.ColorChannels.TryGetValue("skin", out skin))
                    {
                        if (Props.colourSkin && Alienskin?.first != null)
                        {
                            skin.first = Alienskin.first.NewRandomizedColor();
                        }
                        if (Props.colourSkinTwo && Alienskin?.second != null)
                        {
                            skin.second = Alienskin.second.NewRandomizedColor();
                        }
                        compAlien.ColorChannels.SetOrAdd("skin", skin);
                    }
                    Traverse.Create(newStory).Field("SkinColor").SetValue(skin.first);
                    Pawn.Notify_ColorChanged();
                }
            }
            if (Props.changeHead)
            {
                List <string> heads = new List <string>();
                if (!Props.crownType.NullOrEmpty())
                {
                    heads.Add(Props.crownType);
                }
                else
                {
                    heads.AddRange(alienPartGenerator.aliencrowntypes);
                }
                compAlien.crownType = null;

                if (Pawn.story.HeadGraphicPath.Contains("Average"))
                {
                    newStory.crownType = CrownType.Average;
                }
                else if (Pawn.story.HeadGraphicPath.Contains("Narrow"))
                {
                    newStory.crownType = CrownType.Narrow;
                }
            }
            pawn.story = newStory;
            Traverse.Create(newStory).Field("headGraphicPath").SetValue(alienRace.alienRace.graphicPaths.GetCurrentGraphicPath(pawn.ageTracker.CurLifeStage).head.NullOrEmpty() ? "" : alienPartGenerator.RandomAlienHead(alienRace.alienRace.graphicPaths.GetCurrentGraphicPath(pawn.ageTracker.CurLifeStage).head, Pawn));
            pawn.Drawer.renderer.graphics.ResolveAllGraphics();
            Find.ColonistBar.drawer.Notify_RecachedEntries();
        }
        private void TransformPawn(bool changeDef = true, bool keep = false)
        {
            //sets position, faction and map
            IntVec3 intv    = Pawn.Position;
            Faction faction = Pawn.Faction;
            Map     map     = Pawn.Map;

            RegionListersUpdater.DeregisterInRegions(Pawn, map);

            //Change Race to Props.raceDef
            if (changeDef && alienRace != null && alienRace != Pawn.def)
            {
                Pawn.def = alienRace;
                long ageB = Pawn.ageTracker.AgeBiologicalTicks;
                long ageC = Pawn.ageTracker.AgeChronologicalTicks;
                Pawn.ageTracker = new Pawn_AgeTracker(Pawn);
                Pawn.ageTracker.AgeBiologicalTicks    = ageB;
                Pawn.ageTracker.AgeChronologicalTicks = ageC;
                if (!Pawn.RaceProps.hasGenders)
                {
                    Pawn.gender = Gender.None;
                }
                if (Props.removeHair)
                {
                    //    Pawn.story.hairDef = DefDatabase<HairDef>.GetNamed("Shaved", true);
                    Pawn.story.hairDef = PawnHairChooser.RandomHairDefFor(Pawn, noHairFaction);
                    //   Pawn.Drawer.renderer.graphics.hairGraphic;
                }
                else
                {
                    if (Props.colourHairTwo || Props.colourHair)
                    {
                        if (compAlien != null)
                        {
                            ColorChannelGenerator Alienhair = alienRace.alienRace.generalSettings.alienPartGenerator.colorChannels.Find(x => x.name == "hair");
                            AlienPartGenerator.ExposableValueTuple <UnityEngine.Color, UnityEngine.Color> hair;
                            if (compAlien.ColorChannels.TryGetValue("hair", out hair))
                            {
                                if (Props.colourHair && Alienhair?.first != null)
                                {
                                    hair.first = Alienhair.first.NewRandomizedColor();
                                }
                                if (Props.colourHairTwo && Alienhair?.second != null)
                                {
                                    hair.second = Alienhair.second.NewRandomizedColor();
                                }
                                compAlien.ColorChannels.SetOrAdd("hair", hair);
                            }
                            Pawn.Notify_ColorChanged();
                        }
                    }
                }
                //Change BodyType to Props.bodyTypeDef
                if (Props.changeBody)
                {
                    if (Props.bodyTypeDef != null)
                    {
                        ChangeBodyType(Pawn, Props.bodyTypeDef);
                    }
                    else
                    {
                        ChangeBodyType(Pawn, alienRace.alienRace.generalSettings.alienPartGenerator.alienbodytypes[Rand.Range(0, alienRace.alienRace.generalSettings.alienPartGenerator.alienbodytypes.Count)]);
                    }
                }
            }
            //Remove Disallowed Traits
            int maxTraits;

            if (MoreTraitSlotsUtil.TryGetMaxTraitSlots(out int max))
            {
                maxTraits = max;
            }
            else
            {
                maxTraits = 4;
            }
            if (!Props.traitsToRemove.NullOrEmpty())
            {
                if (Pawn.story.traits.allTraits.Any(x => Props.traitsToRemove.Any(y => y.def == x.def)))
                {
                    foreach (ExtendedTraitEntry item in Props.traitsToRemove)
                    {
                        if (Pawn.story.traits.HasTrait(item.def))
                        {
                            Rand.PushState();
                            if (Rand.Chance(item.Chance))
                            {
                                Pawn.story.traits.allTraits.Remove(Pawn.story.traits.allTraits.Find(x => x.def == item.def));
                            }
                            Rand.PopState();
                        }
                    }
                }
            }
            if (!Props.traitsToAdd.NullOrEmpty())
            {
                if (Props.traitsToAdd.Any(x => !Pawn.story.traits.HasTrait(x.def)))
                {
                    foreach (ExtendedTraitEntry item in Props.traitsToAdd)
                    {
                        if (!Pawn.story.traits.HasTrait(item.def))
                        {
                            Rand.PushState();
                            if (Rand.Chance(item.Chance))
                            {
                                bool replace     = false;
                                int  countTraits = Pawn.story.traits.allTraits.Count;
                                if (countTraits >= maxTraits)
                                {
                                    replace = true;
                                }
                                //   Log.Message(string.Format("i have {0} of a max of {1} traits", countTraits, maxTraits));
                                Trait replacedTrait = Pawn.story.traits.allTraits.Where(x => Props.traitsToAdd.Any(y => y.def != x.def)).RandomElement();
                                if (replace)
                                {
                                    Pawn.story.traits.allTraits.Remove(replacedTrait);
                                }
                                Pawn.story.traits.allTraits.Add(new Trait(item.def, item.degree));
                            }
                            Rand.PopState();
                        }
                    }
                }
            }
            RegionListersUpdater.RegisterInRegions(Pawn, map);
            map.mapPawns.UpdateRegistryForPawn(Pawn);

            //decache graphics
            Pawn.Drawer.renderer.graphics.ResolveAllGraphics();
            Find.ColonistBar.drawer.Notify_RecachedEntries();

            //save the pawn
            Pawn.ExposeData();
            if (Pawn.Faction != faction)
            {
                Pawn.SetFaction(faction);
            }
            //    pawn.Position = intv;
        }