Ejemplo n.º 1
0
 protected void Select(CustomFaction faction)
 {
     this.SelectedFaction = faction;
     if (SelectAction != null)
     {
         SelectAction(faction);
     }
 }
Ejemplo n.º 2
0
        protected void AddPawnToWorld(CustomPawn pawn)
        {
            // Don't add colonists to the world.
            if (pawn.Type == CustomPawnType.Colonist)
            {
                return;
            }

            // If we have a custom faction setting, handle that.
            CustomFaction randomFaction = PrepareCarefully.Instance.Providers.Factions.RandomFaction;

            if (pawn.Faction != null && pawn.Faction != PrepareCarefully.Instance.Providers.Factions.RandomFaction)
            {
                // If they are assigned to a specific faction, assign them either as a leader or as a regular pawn.
                if (pawn.Faction.Faction != null)
                {
                    if (pawn.Faction.Leader)
                    {
                        MakePawnIntoFactionLeader(pawn);
                    }
                    try {
                        pawn.Pawn.SetFaction(pawn.Faction.Faction, null);
                    }
                    catch (Exception) {
                        Logger.Warning("Failed to add a world pawn to the expected faction");
                    }
                }
                // If they are assigned to a random faction of a specific def, choose the random faction and assign it.
                else
                {
                    try {
                        Faction faction = PrepareCarefully.Instance.Providers.Factions.GetFactions(pawn.Faction.Def).RandomElement();
                        pawn.Pawn.SetFaction(pawn.Faction.Faction, null);
                    }
                    catch (Exception) {
                        Logger.Warning("Failed to add a world pawn to the expected faction");
                    }
                }
            }
            // If they are assigned to a completely random faction, set their faction to null.  It will get reassigned automatically.
            else
            {
                pawn.Pawn.SetFactionDirect(null);
            }

            // Don't add pawns to the world if they have already been added.
            if (Find.World.worldPawns.Contains(pawn.Pawn) || Find.GameInitData.startingAndOptionalPawns.Contains(pawn.Pawn))
            {
                return;
            }
            else
            {
                Find.GameInitData.startingAndOptionalPawns.Add(pawn.Pawn);
            }
        }
        public void AddCustomFaction(CustomFaction customFaction)
        {
            if (customFaction.Def == null)
            {
                return;
            }
            if (customFaction.Index == null)
            {
                return;
            }
            int count;

            if (factionCounts.TryGetValue(customFaction.Def, out count))
            {
                if (count <= customFaction.Index)
                {
                    customFactions.Add(customFaction);
                }
            }
        }
Ejemplo n.º 4
0
        protected void ShowFactionDialog(CustomPawn pawn)
        {
            CustomFaction           selectedFaction = pawn.Faction != null ? pawn.Faction : PrepareCarefully.Instance.Providers.Factions.RandomFaction;
            HashSet <CustomFaction> disabled        = new HashSet <CustomFaction>();

            rowGroups.Clear();
            rowGroups.Add(new WidgetTable <CustomFaction> .RowGroup("<b>" + "EdB.PC.Dialog.Faction.SelectRandomFaction".Translate() + "</b>", providerFactions.RandomCustomFactions));
            rowGroups.Add(new WidgetTable <CustomFaction> .RowGroup("<b>" + "EdB.PC.Dialog.Faction.SelectSpecificFaction".Translate() + "</b>", providerFactions.SpecificCustomFactions));
            rowGroups.Add(new WidgetTable <CustomFaction> .RowGroup("<b>" + "EdB.PC.Dialog.Faction.SelectLeaderFaction".Translate() + "</b>", providerFactions.LeaderCustomFactions));
            DialogFactions factionDialog = new DialogFactions()
            {
                HeaderLabel      = "EdB.PC.Dialog.Faction.ChooseFaction".Translate(),
                SelectAction     = (CustomFaction faction) => { selectedFaction = faction; },
                RowGroups        = rowGroups,
                DisabledFactions = disabled,
                CloseAction      = () => {
                    pawn.Faction = selectedFaction;
                },
                SelectedFaction = selectedFaction
            };

            factionDialog.ScrollTo(selectedFaction);
            Find.WindowStack.Add(factionDialog);
        }
Ejemplo n.º 5
0
        public void AddFactionPawn(PawnKindDef kindDef, bool startingPawn)
        {
            FactionDef factionDef = kindDef.defaultFactionType;
            Faction    faction    = PrepareCarefully.Instance.Providers.Factions.GetFaction(factionDef);

            // Workaround to force pawn generation to skip adding weapons to the pawn.
            // Might be a slightly risky hack, but the finally block should guarantee that
            // the weapons money range always gets set back to its original value.
            // TODO: Try to remove this at a later date.  It would be nice if the pawn generation
            // request gave you an option to skip weapon and equipment generation.
            FloatRange savedWeaponsMoney = kindDef.weaponMoney;

            kindDef.weaponMoney = new FloatRange(0, 0);
            Pawn pawn = null;

            try {
                pawn = randomizer.GeneratePawn(new PawnGenerationRequestWrapper()
                {
                    Faction = faction,
                    KindDef = kindDef,
                    Context = PawnGenerationContext.NonPlayer,
                    WorldPawnFactionDoesntMatter = true
                }.Request);
                if (pawn.equipment != null)
                {
                    pawn.equipment.DestroyAllEquipment(DestroyMode.Vanish);
                }
                if (pawn.inventory != null)
                {
                    pawn.inventory.DestroyAll(DestroyMode.Vanish);
                }
            }
            catch (Exception e) {
                Log.Warning("Failed to create faction pawn of kind " + kindDef.defName);
                Log.Message(e.Message);
                Log.Message(e.StackTrace);
                if (pawn != null)
                {
                    pawn.Destroy();
                }
                state.AddError("EdB.PC.Panel.PawnList.Error.FactionPawnFailed".Translate());
                return;
            }
            finally {
                kindDef.weaponMoney = savedWeaponsMoney;
            }
            // Reset the quality and damage of all apparel.
            foreach (var a in pawn.apparel.WornApparel)
            {
                a.SetQuality(QualityCategory.Normal);
                a.HitPoints = a.MaxHitPoints;
            }

            CustomPawn customPawn = new CustomPawn(pawn);

            customPawn.Type = startingPawn ? CustomPawnType.Colonist : CustomPawnType.World;
            if (!startingPawn)
            {
                CustomFaction customFaction = PrepareCarefully.Instance.Providers.Factions.FindRandomCustomFactionByDef(factionDef);
                if (customFaction != null)
                {
                    customPawn.Faction = customFaction;
                }
            }

            PrepareCarefully.Instance.AddPawn(customPawn);
            state.CurrentPawn = customPawn;
            PawnAdded(customPawn);
        }
Ejemplo n.º 6
0
        public override void DoWindowContents(Rect inRect)
        {
            if (resizeDirtyFlag)
            {
                Resize();
            }

            if (scrollTo != null)
            {
                table.ScrollTo(scrollTo);
                scrollTo = null;
            }

            GUI.color = Color.white;
            Text.Font = GameFont.Medium;
            if (HeaderLabel != null)
            {
                Widgets.Label(HeaderRect, HeaderLabel);
            }

            Text.Font = GameFont.Small;
            GUI.BeginGroup(ContentRect);

            try {
                if (RowGroups != null)
                {
                    table.Draw(RowGroups);
                }
                else
                {
                    table.Draw(Pawns);
                }
            }
            finally {
                GUI.EndGroup();
                GUI.color = Color.white;
            }

            GUI.BeginGroup(FooterRect);
            try {
                Rect buttonRect = SingleButtonRect;
                if (CancelButtonLabel != null)
                {
                    if (Widgets.ButtonText(CancelButtonRect, CancelButtonLabel.Translate(), true, true, true))
                    {
                        this.Close(true);
                    }
                    buttonRect = ConfirmButtonRect;
                }
                if (Widgets.ButtonText(buttonRect, ConfirmButtonLabel.Translate(), true, true, true))
                {
                    string validationMessage = ConfirmValidation();
                    if (validationMessage != null)
                    {
                        Messages.Message(validationMessage.Translate(), MessageTypeDefOf.RejectInput);
                    }
                    else
                    {
                        this.Confirm();
                    }
                }
            }
            finally {
                GUI.EndGroup();
            }
        }
Ejemplo n.º 7
0
 public void ScrollTo(CustomFaction customFaction)
 {
     scrollTo = customFaction;
 }
        public CustomPawn LoadPawn(SaveRecordPawnV4 record)
        {
            PawnKindDef pawnKindDef = null;

            if (record.pawnKindDef != null)
            {
                pawnKindDef = DefDatabase <PawnKindDef> .GetNamedSilentFail(record.pawnKindDef);

                if (pawnKindDef == null)
                {
                    Log.Warning("Prepare Carefully could not find the pawn kind definition for the saved character: \"" + record.pawnKindDef + "\"");
                    return(null);
                }
            }

            ThingDef pawnThingDef = ThingDefOf.Human;

            if (record.thingDef != null)
            {
                ThingDef thingDef = DefDatabase <ThingDef> .GetNamedSilentFail(record.thingDef);

                if (thingDef != null)
                {
                    pawnThingDef = thingDef;
                }
            }

            PawnGenerationRequestWrapper generationRequest = new PawnGenerationRequestWrapper()
            {
                FixedBiologicalAge    = record.biologicalAge,
                FixedChronologicalAge = record.chronologicalAge,
                FixedGender           = record.gender
            };

            if (pawnKindDef != null)
            {
                generationRequest.KindDef = pawnKindDef;
            }
            Pawn source = PawnGenerator.GeneratePawn(generationRequest.Request);

            if (source.health != null)
            {
                source.health.Reset();
            }

            CustomPawn pawn = new CustomPawn(source);

            if (record.id == null)
            {
                pawn.GenerateId();
            }
            else
            {
                pawn.Id = record.id;
            }

            if (record.type != null)
            {
                try {
                    pawn.Type = (CustomPawnType)Enum.Parse(typeof(CustomPawnType), record.type);
                }
                catch (Exception) {
                    pawn.Type = CustomPawnType.Colonist;
                }
            }
            else
            {
                pawn.Type = CustomPawnType.Colonist;
            }

            pawn.Gender = record.gender;
            if (record.age > 0)
            {
                pawn.ChronologicalAge = record.age;
                pawn.BiologicalAge    = record.age;
            }
            if (record.chronologicalAge > 0)
            {
                pawn.ChronologicalAge = record.chronologicalAge;
            }
            if (record.biologicalAge > 0)
            {
                pawn.BiologicalAge = record.biologicalAge;
            }

            pawn.FirstName = record.firstName;
            pawn.NickName  = record.nickName;
            pawn.LastName  = record.lastName;

            if (record.originalFactionDef != null)
            {
                pawn.OriginalFactionDef = DefDatabase <FactionDef> .GetNamedSilentFail(record.originalFactionDef);
            }
            pawn.OriginalKindDef = pawnKindDef;

            if (pawn.Type == CustomPawnType.World)
            {
                if (record.faction != null)
                {
                    if (record.faction.def != null)
                    {
                        FactionDef factionDef = DefDatabase <FactionDef> .GetNamedSilentFail(record.faction.def);

                        if (factionDef != null)
                        {
                            bool randomFaction = false;
                            if (record.faction.index != null)
                            {
                                CustomFaction customFaction = null;
                                if (!record.faction.leader)
                                {
                                    customFaction = PrepareCarefully.Instance.Providers.Factions.FindCustomFactionByIndex(factionDef, record.faction.index.Value);
                                }
                                else
                                {
                                    customFaction = PrepareCarefully.Instance.Providers.Factions.FindCustomFactionWithLeaderOptionByIndex(factionDef, record.faction.index.Value);
                                }
                                if (customFaction != null)
                                {
                                    pawn.Faction = customFaction;
                                }
                                else
                                {
                                    Log.Warning("Prepare Carefully could not place at least one preset character into a saved faction because there were not enough available factions of that type in the world");
                                    randomFaction = true;
                                }
                            }
                            else
                            {
                                randomFaction = true;
                            }
                            if (randomFaction)
                            {
                                CustomFaction customFaction = PrepareCarefully.Instance.Providers.Factions.FindRandomCustomFactionByDef(factionDef);
                                if (customFaction != null)
                                {
                                    pawn.Faction = customFaction;
                                }
                            }
                        }
                        else
                        {
                            Log.Warning("Prepare Carefully could not place at least one preset character into a saved faction because that faction is not available in the world");
                        }
                    }
                }
            }

            HairDef h = FindHairDef(record.hairDef);

            if (h != null)
            {
                pawn.HairDef = h;
            }
            else
            {
                Log.Warning("Could not load hair definition \"" + record.hairDef + "\"");
                Failed = true;
            }

            pawn.HeadGraphicPath = record.headGraphicPath;
            if (pawn.Pawn.story != null)
            {
                pawn.Pawn.story.hairColor = record.hairColor;
            }

            if (record.melanin >= 0.0f)
            {
                pawn.MelaninLevel = record.melanin;
            }
            else
            {
                pawn.MelaninLevel = PawnColorUtils.FindMelaninValueFromColor(record.skinColor);
            }
            // Set the skin color for Alien Races and alien comp values.
            if (pawn.AlienRace != null)
            {
                pawn.SkinColor = record.skinColor;
                if (record.alien != null)
                {
                    ThingComp alienComp = ProviderAlienRaces.FindAlienCompForPawn(pawn.Pawn);
                    if (alienComp != null)
                    {
                        ProviderAlienRaces.SetCrownTypeOnComp(alienComp, record.alien.crownType);
                        ProviderAlienRaces.SetSkinColorOnComp(alienComp, record.alien.skinColor);
                        ProviderAlienRaces.SetSkinColorSecondOnComp(alienComp, record.alien.skinColorSecond);
                        ProviderAlienRaces.SetHairColorSecondOnComp(alienComp, record.alien.hairColorSecond);
                    }
                }
            }

            Backstory backstory = FindBackstory(record.childhood);

            if (backstory != null)
            {
                pawn.Childhood = backstory;
            }
            else
            {
                Log.Warning("Could not load childhood backstory definition \"" + record.childhood + "\"");
                Failed = true;
            }
            if (record.adulthood != null)
            {
                backstory = FindBackstory(record.adulthood);
                if (backstory != null)
                {
                    pawn.Adulthood = backstory;
                }
                else
                {
                    Log.Warning("Could not load adulthood backstory definition \"" + record.adulthood + "\"");
                    Failed = true;
                }
            }

            BodyTypeDef bodyType = null;

            try {
                bodyType = DefDatabase <BodyTypeDef> .GetNamedSilentFail(record.bodyType);
            }
            catch (Exception) {
            }
            if (bodyType == null)
            {
                if (pawn.Adulthood != null)
                {
                    bodyType = pawn.Adulthood.BodyTypeFor(pawn.Gender);
                }
                else
                {
                    bodyType = pawn.Childhood.BodyTypeFor(pawn.Gender);
                }
            }
            if (bodyType != null)
            {
                pawn.BodyType = bodyType;
            }

            pawn.ClearTraits();
            for (int i = 0; i < record.traitNames.Count; i++)
            {
                string traitName = record.traitNames[i];
                Trait  trait     = FindTrait(traitName, record.traitDegrees[i]);
                if (trait != null)
                {
                    pawn.AddTrait(trait);
                }
                else
                {
                    Log.Warning("Could not load trait definition \"" + traitName + "\"");
                    Failed = true;
                }
            }

            foreach (var skill in record.skills)
            {
                SkillDef def = FindSkillDef(pawn.Pawn, skill.name);
                if (def == null)
                {
                    Log.Warning("Could not load skill definition \"" + skill.name + "\" from saved preset");
                    Failed = true;
                    continue;
                }
                pawn.currentPassions[def]  = skill.passion;
                pawn.originalPassions[def] = skill.passion;
                pawn.SetOriginalSkillLevel(def, skill.value);
                pawn.SetUnmodifiedSkillLevel(def, skill.value);
            }

            foreach (var layer in PrepareCarefully.Instance.Providers.PawnLayers.GetLayersForPawn(pawn))
            {
                if (layer.Apparel)
                {
                    pawn.SetSelectedApparel(layer, null);
                    pawn.SetSelectedStuff(layer, null);
                }
            }
            List <PawnLayer> apparelLayers = PrepareCarefully.Instance.Providers.PawnLayers.GetLayersForPawn(pawn).FindAll((layer) => { return(layer.Apparel); });

            foreach (var apparelRecord in record.apparel)
            {
                // Find the pawn layer for the saved apparel record.
                PawnLayer layer = apparelLayers.FirstOrDefault((apparelLayer) => { return(apparelLayer.Name == apparelRecord.layer); });
                if (layer == null)
                {
                    Log.Warning("Could not find a matching pawn layer for the saved apparel \"" + apparelRecord.layer + "\"");
                    Failed = true;
                    continue;
                }
                if (apparelRecord.apparel.NullOrEmpty())
                {
                    Log.Warning("Saved apparel entry for layer \"" + apparelRecord.layer + "\" had an empty apparel def");
                    Failed = true;
                    continue;
                }
                // Set the defaults.
                pawn.SetSelectedApparel(layer, null);
                pawn.SetSelectedStuff(layer, null);
                pawn.SetColor(layer, Color.white);

                ThingDef def = DefDatabase <ThingDef> .GetNamedSilentFail(apparelRecord.apparel);

                if (def == null)
                {
                    Log.Warning("Could not load thing definition for apparel \"" + apparelRecord.apparel + "\"");
                    Failed = true;
                    continue;
                }
                ThingDef stuffDef = null;
                if (!string.IsNullOrEmpty(apparelRecord.stuff))
                {
                    stuffDef = DefDatabase <ThingDef> .GetNamedSilentFail(apparelRecord.stuff);

                    if (stuffDef == null)
                    {
                        Log.Warning("Could not load stuff definition \"" + apparelRecord.stuff + "\" for apparel \"" + apparelRecord.apparel + "\"");
                        Failed = true;
                        continue;
                    }
                }
                pawn.SetSelectedApparel(layer, def);
                pawn.SetSelectedStuff(layer, stuffDef);
                pawn.SetColor(layer, apparelRecord.color);
            }

            OptionsHealth healthOptions = PrepareCarefully.Instance.Providers.Health.GetOptions(pawn);

            for (int i = 0; i < record.implants.Count; i++)
            {
                SaveRecordImplantV3 implantRecord  = record.implants[i];
                UniqueBodyPart      uniqueBodyPart = healthOptions.FindBodyPartByName(implantRecord.bodyPart, implantRecord.bodyPartIndex != null ? implantRecord.bodyPartIndex.Value : 0);
                if (uniqueBodyPart == null)
                {
                    uniqueBodyPart = FindReplacementBodyPart(healthOptions, implantRecord.bodyPart);
                }
                if (uniqueBodyPart == null)
                {
                    Log.Warning("Prepare Carefully could not add the implant because it could not find the needed body part \"" + implantRecord.bodyPart + "\""
                                + (implantRecord.bodyPartIndex != null ? " with index " + implantRecord.bodyPartIndex : ""));
                    Failed = true;
                    continue;
                }
                BodyPartRecord bodyPart = uniqueBodyPart.Record;
                if (implantRecord.recipe != null)
                {
                    RecipeDef recipeDef = FindRecipeDef(implantRecord.recipe);
                    if (recipeDef == null)
                    {
                        Log.Warning("Prepare Carefully could not add the implant because it could not find the recipe definition \"" + implantRecord.recipe + "\"");
                        Failed = true;
                        continue;
                    }
                    bool found = false;
                    foreach (var p in recipeDef.appliedOnFixedBodyParts)
                    {
                        if (p.defName.Equals(bodyPart.def.defName))
                        {
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        Log.Warning("Prepare carefully could not apply the saved implant recipe \"" + implantRecord.recipe + "\" to the body part \"" + bodyPart.def.defName + "\".  Recipe does not support that part.");
                        Failed = true;
                        continue;
                    }
                    Implant implant = new Implant();
                    implant.BodyPartRecord = bodyPart;
                    implant.recipe         = recipeDef;
                    implant.label          = implant.Label;
                    pawn.AddImplant(implant);
                }
            }

            foreach (var injuryRecord in record.injuries)
            {
                HediffDef def = DefDatabase <HediffDef> .GetNamedSilentFail(injuryRecord.hediffDef);

                if (def == null)
                {
                    Log.Warning("Prepare Carefully could not add the injury because it could not find the hediff definition \"" + injuryRecord.hediffDef + "\"");
                    Failed = true;
                    continue;
                }
                InjuryOption option = healthOptions.FindInjuryOptionByHediffDef(def);
                if (option == null)
                {
                    Log.Warning("Prepare Carefully could not add the injury because it could not find a matching injury option for the saved hediff \"" + injuryRecord.hediffDef + "\"");
                    Failed = true;
                    continue;
                }
                BodyPartRecord bodyPart = null;
                if (injuryRecord.bodyPart != null)
                {
                    UniqueBodyPart uniquePart = healthOptions.FindBodyPartByName(injuryRecord.bodyPart,
                                                                                 injuryRecord.bodyPartIndex != null ? injuryRecord.bodyPartIndex.Value : 0);
                    if (uniquePart == null)
                    {
                        uniquePart = FindReplacementBodyPart(healthOptions, injuryRecord.bodyPart);
                    }
                    if (uniquePart == null)
                    {
                        Log.Warning("Prepare Carefully could not add the injury because it could not find the needed body part \"" + injuryRecord.bodyPart + "\""
                                    + (injuryRecord.bodyPartIndex != null ? " with index " + injuryRecord.bodyPartIndex : ""));
                        Failed = true;
                        continue;
                    }
                    bodyPart = uniquePart.Record;
                }
                Injury injury = new Injury();
                injury.Option         = option;
                injury.BodyPartRecord = bodyPart;
                if (injuryRecord.severity != null)
                {
                    injury.Severity = injuryRecord.Severity;
                }
                if (injuryRecord.painFactor != null)
                {
                    injury.PainFactor = injuryRecord.PainFactor;
                }
                pawn.AddInjury(injury);
            }

            pawn.CopySkillsAndPassionsToPawn();
            pawn.ClearPawnCaches();

            return(pawn);
        }
Ejemplo n.º 9
0
        protected override void DrawPanelContent(State state)
        {
            base.DrawPanelContent(state);
            CustomPawn customPawn = state.CurrentPawn;

            if (currentPawn != state.CurrentPawn)
            {
                ChangePawn(state.CurrentPawn);
            }
            if (currentPawnLayers == null)
            {
                UpdatePawnLayers();
            }
            string label = this.selectedPawnLayer.Label;

            if (WidgetDropdown.Button(RectLayerSelector, label, true, false, true))
            {
                List <FloatMenuOption> list = new List <FloatMenuOption>();
                int layerCount = this.pawnLayerActions.Count;
                int i          = 0;
                foreach (var layer in currentPawnLayers)
                {
                    label = layer.Label;
                    list.Add(new FloatMenuOption(label, this.pawnLayerActions[i], MenuOptionPriority.Default, null, null, 0, null, null));
                    i++;
                }
                Find.WindowStack.Add(new FloatMenu(list, null, false));
            }
            GUI.DrawTexture(RectPortrait, Textures.TexturePortraitBackground);

            customPawn.UpdatePortrait();
            DrawPawn(customPawn, RectPortrait);

            GUI.color = ColorPortraitBorder;
            Widgets.DrawBox(RectPortrait, 1);
            GUI.color = Color.white;

            // Draw world pawn alert
            if (state.CurrentPawn.Type == CustomPawnType.World && this.selectedPawnLayer.Apparel)
            {
                CustomFaction faction = state.CurrentPawn.Faction;
                if (faction == null || !faction.Leader)
                {
                    Rect alertRect = new Rect(RectPortrait.x + 77, RectPortrait.y + 150, 36, 32);
                    GUI.DrawTexture(alertRect, Textures.TextureAlert);
                    TooltipHandler.TipRegion(alertRect, "EdB.PC.Panel.Appearance.WorldPawnAlert".Translate());
                }
            }
            // Apparel conflict alert
            else if (customPawn.ApparelConflict != null)
            {
                GUI.color = Color.white;
                Rect alertRect = new Rect(RectPortrait.x + 77, RectPortrait.y + 150, 36, 32);
                GUI.DrawTexture(alertRect, Textures.TextureAlert);
                TooltipHandler.TipRegion(alertRect, customPawn.ApparelConflict);
            }

            // Draw selector field.
            Rect   fieldRect = new Rect(RectPortrait.x, RectPortrait.y + RectPortrait.height + 5, RectPortrait.width, 40);
            Action previousSelectionAction = null;
            Action nextSelectionAction     = null;
            Action clickAction             = null;

            OptionsApparel  apparelOptions = null;
            List <ThingDef> apparelList    = null;

            if (this.selectedPawnLayer.Apparel)
            {
                apparelOptions = PrepareCarefully.Instance.Providers.Apparel.GetApparelForRace(customPawn);
                apparelList    = apparelOptions.GetApparel(this.selectedPawnLayer);
            }

            if (this.selectedPawnLayer.Options != null)
            {
                if (this.selectedPawnLayer.Options.Count > 1)
                {
                    previousSelectionAction = () => {
                        SoundDefOf.Tick_Tiny.PlayOneShotOnCamera();
                        SelectNextPawnLayerOption(customPawn, -1);
                    };
                    nextSelectionAction = () => {
                        SoundDefOf.Tick_Tiny.PlayOneShotOnCamera();
                        SelectNextPawnLayerOption(customPawn, 1);
                    };
                }
                if (this.selectedPawnLayer.Options.Count > 0)
                {
                    clickAction = () => {
                        ShowPawnLayerOptionsDialog(customPawn);
                    };
                }
            }
            else
            {
                if (apparelList.Count > 1)
                {
                    previousSelectionAction = () => {
                        SoundDefOf.Tick_Tiny.PlayOneShotOnCamera();
                        SelectNextApparel(customPawn, -1);
                    };
                    nextSelectionAction = () => {
                        SelectNextApparel(customPawn, 1);
                        SoundDefOf.Tick_Tiny.PlayOneShotOnCamera();
                    };
                }
                if (apparelList.Count > 0)
                {
                    clickAction = () => {
                        ShowApparelDialog(customPawn, this.selectedPawnLayer);
                    };
                }
            }

            string selectorLabel = PawnLayerLabel.CapitalizeFirst();

            //if (hairList != null && hairList.Count == 0) {
            //    selectorLabel = "EdB.PC.Common.NoOptionAvailable".Translate();
            //}
            if (apparelList != null && apparelList.Count == 0)
            {
                selectorLabel = "EdB.PC.Common.NoOptionAvailable".Translate();
            }
            DrawFieldSelector(fieldRect, selectorLabel, previousSelectionAction, nextSelectionAction, clickAction);

            float cursorY = fieldRect.yMax + 6;

            // Draw stuff selector for apparel
            if (this.selectedPawnLayer.Apparel)
            {
                ThingDef apparelDef = customPawn.GetSelectedApparel(selectedPawnLayer);
                if (apparelDef != null && apparelDef.MadeFromStuff)
                {
                    if (customPawn.GetSelectedStuff(selectedPawnLayer) == null)
                    {
                        Log.Error("Selected stuff for " + selectedPawnLayer.ApparelLayer + " is null");
                    }
                    Rect stuffFieldRect = new Rect(RectPortrait.x, cursorY, RectPortrait.width, 28);
                    DrawFieldSelector(stuffFieldRect, customPawn.GetSelectedStuff(selectedPawnLayer).LabelCap,
                                      () => {
                        ThingDef selected = customPawn.GetSelectedStuff(selectedPawnLayer);
                        int index         = this.apparelStuffLookup[apparelDef].FindIndex((ThingDef d) => { return(selected == d); });
                        index--;
                        if (index < 0)
                        {
                            index = this.apparelStuffLookup[apparelDef].Count - 1;
                        }
                        customPawn.SetSelectedStuff(selectedPawnLayer, apparelStuffLookup[apparelDef][index]);
                    },
                                      () => {
                        ThingDef selected = customPawn.GetSelectedStuff(selectedPawnLayer);
                        int index         = this.apparelStuffLookup[apparelDef].FindIndex((ThingDef d) => { return(selected == d); });
                        index++;
                        if (index >= this.apparelStuffLookup[apparelDef].Count)
                        {
                            index = 0;
                        }
                        customPawn.SetSelectedStuff(selectedPawnLayer, this.apparelStuffLookup[apparelDef][index]);
                    },
                                      () => {
                        ShowApparelStuffDialog(customPawn, this.selectedPawnLayer);
                    }
                                      );

                    cursorY += stuffFieldRect.height;
                }
            }
            cursorY += 8;

            // Draw Color Selector
            if (selectedPawnLayer.Apparel)
            {
                if (apparelList != null && apparelList.Count > 0)
                {
                    ThingDef def = customPawn.GetSelectedApparel(selectedPawnLayer);
                    if (def != null && def.HasComp(typeof(CompColorable)))
                    {
                        if (def.MadeFromStuff)
                        {
                            DrawColorSelector(customPawn, cursorY, null);
                        }
                        else
                        {
                            DrawColorSelector(customPawn, cursorY, def.colorGenerator);
                        }
                    }
                }
            }
            else if (selectedPawnLayer.ColorSelectorType == ColorSelectorType.RGB)
            {
                DrawColorSelectorForPawnLayer(customPawn, cursorY, selectedPawnLayer.ColorSwatches, true);
            }
            else if (selectedPawnLayer.ColorSelectorType == ColorSelectorType.Skin)
            {
                AlienRace alienRace = customPawn.AlienRace;
                if (alienRace == null || alienRace.UseMelaninLevels)
                {
                    DrawHumanlikeColorSelector(customPawn, cursorY);
                }
                else
                {
                    DrawAlienPawnColorSelector(customPawn, cursorY, alienRace.PrimaryColors, true);
                }
            }

            // Random button
            if (RectButtonRandomize.Contains(Event.current.mousePosition))
            {
                GUI.color = Style.ColorButtonHighlight;
            }
            else
            {
                GUI.color = Style.ColorButton;
            }
            GUI.DrawTexture(RectButtonRandomize, Textures.TextureButtonRandom);
            if (Widgets.ButtonInvisible(RectButtonRandomize, false))
            {
                SoundDefOf.Tick_Low.PlayOneShotOnCamera();
                RandomizeAppearance();
            }

            // Gender buttons.
            if (state.CurrentPawn.Pawn.RaceProps != null && state.CurrentPawn.Pawn.RaceProps.hasGenders)
            {
                bool genderFemaleSelected = state.CurrentPawn.Gender == Gender.Female;
                Style.SetGUIColorForButton(RectGenderFemale, genderFemaleSelected);
                GUI.DrawTexture(RectGenderFemale, Textures.TextureButtonGenderFemale);
                if (!genderFemaleSelected && Widgets.ButtonInvisible(RectGenderFemale, false))
                {
                    SoundDefOf.Tick_Tiny.PlayOneShotOnCamera();
                    GenderUpdated(Gender.Female);
                }
                bool genderMaleSelected = state.CurrentPawn.Gender == Gender.Male;
                Style.SetGUIColorForButton(RectGenderMale, genderMaleSelected);
                GUI.DrawTexture(RectGenderMale, Textures.TextureButtonGenderMale);
                if (!genderMaleSelected && Widgets.ButtonInvisible(RectGenderMale, false))
                {
                    SoundDefOf.Tick_Tiny.PlayOneShotOnCamera();
                    GenderUpdated(Gender.Male);
                }
            }

            GUI.color = Color.white;
        }
        private void InitializeCustomFactions()
        {
            // Add the random faction.
            randomFaction = new CustomFaction();
            customFactions.Add(randomFaction);

            // Create a lookup with all eligible faction defs.
            foreach (var def in nonPlayerHumanlikeFactionDefs)
            {
                eligibleFactionLookup.Add(def);
            }
            // Add the random custom faction for each eligible faction def.
            foreach (var def in NonPlayerHumanlikeFactionDefs)
            {
                CustomFaction faction = new CustomFaction();
                faction.Def = def;
                customFactions.Add(faction);
            }
            // Go through all of the individual factions to create the specific custom factions and the corresponding leader options.
            // While doing it, build up the data structures to keep track of how many of each faction def there are.
            foreach (var faction in Find.World.factionManager.AllFactions)
            {
                // Update the number of each faction def in a lookup.
                int currentIndex = 0;
                if (factionCounts.ContainsKey(faction.def))
                {
                    int count = factionCounts[faction.def];
                    count++;
                    factionCounts[faction.def] = count;
                    currentIndex = count - 1;
                }
                else
                {
                    factionCounts[faction.def] = 1;
                    currentIndex = 0;
                }
                // Create the custom faction for each faction if it's an eligible faction def.
                if (eligibleFactionLookup.Contains(faction.def))
                {
                    CustomFaction customFaction = new CustomFaction();
                    customFaction.Def     = faction.def;
                    customFaction.Index   = currentIndex;
                    customFaction.Name    = faction.Name;
                    customFaction.Faction = faction;
                    customFaction.Leader  = false;
                    customFactions.Add(customFaction);

                    if (faction.leader != null)
                    {
                        // Create the leader version of the faction
                        CustomFaction leaderFaction = new CustomFaction();
                        leaderFaction.Def     = faction.def;
                        leaderFaction.Index   = currentIndex;
                        leaderFaction.Name    = faction.Name;
                        leaderFaction.Faction = faction;
                        leaderFaction.Leader  = true;
                        customFactions.Add(leaderFaction);
                    }
                }
            }
            // Go through all of the specific custom factions and add it to a lookup so that we can find it
            // based on an index/faction def pair.
            foreach (var faction in customFactions)
            {
                if (faction.Faction != null && faction.Index != null && faction.Leader == false)
                {
                    factionIndexLookup.Add(new Pair <FactionDef, int>(faction.Def, faction.Index.Value), faction);
                }
            }
            // Go through all of the specific custom factions and set on it the total number of factions of the same def.
            foreach (var faction in customFactions)
            {
                if (faction.Faction != null && faction.Index != null && faction.Leader == false)
                {
                    int result;
                    if (factionCounts.TryGetValue(faction.Def, out result))
                    {
                        faction.SimilarFactionCount = result;
                    }
                    else
                    {
                        result = 0;
                    }
                }
            }
            // Go through all of the factions and set their names.
            foreach (var faction in customFactions)
            {
                if (faction.Faction != null && faction.Index != null)
                {
                    faction.Name = faction.Name.CapitalizeFirst();
                    if (faction.Faction.Name.ToLower() == faction.Def.label.ToLower())
                    {
                        if (faction.SimilarFactionCount > 1)
                        {
                            faction.Name = "EdB.PC.Dialog.Faction.NumberedFaction".Translate(new object[] { faction.Def.LabelCap, (faction.Index.Value + 1) });
                        }
                    }
                    if (faction.Leader)
                    {
                        faction.Name = "EdB.PC.Dialog.Faction.LeaderFaction".Translate(new object[] { faction.Name });
                    }
                }
                else if (faction.Def != null)
                {
                    faction.Name = "EdB.PC.Dialog.Faction.RandomFaction".Translate(new object[] { faction.Def.LabelCap });
                }
                else
                {
                    faction.Name = "EdB.PC.Dialog.Faction.Random".Translate();
                }
            }
        }
Ejemplo n.º 11
0
        public CustomPawn ConvertSaveRecordToPawn(SaveRecordPawnV5 record)
        {
            bool partialFailure = false;

            PawnKindDef pawnKindDef = null;

            if (record.pawnKindDef != null)
            {
                pawnKindDef = DefDatabase <PawnKindDef> .GetNamedSilentFail(record.pawnKindDef);

                if (pawnKindDef == null)
                {
                    Logger.Warning("Pawn kind definition for the saved character (" + record.pawnKindDef + ") not found.  Picking a random player colony pawn kind definition.");
                    pawnKindDef = PrepareCarefully.Instance.Providers.Factions.GetPawnKindsForFactionDef(FactionDefOf.PlayerColony).RandomElement();
                    if (pawnKindDef == null)
                    {
                        return(null);
                    }
                }
            }

            ThingDef pawnThingDef = ThingDefOf.Human;

            if (record.thingDef != null)
            {
                ThingDef thingDef = DefDatabase <ThingDef> .GetNamedSilentFail(record.thingDef);

                if (thingDef != null)
                {
                    pawnThingDef = thingDef;
                }
                else
                {
                    Logger.Warning("Pawn's thing definition {" + record.thingDef + "} was not found.  Defaulting to the thing definition for humans.");
                }
            }
            else
            {
                Logger.Warning("Pawn's thing definition was null.  Defaulting to the thing definition for humans.");
            }

            // Create the pawn generation request.
            PawnGenerationRequestWrapper generationRequest = new PawnGenerationRequestWrapper()
            {
                FixedBiologicalAge    = record.biologicalAge,
                FixedChronologicalAge = record.chronologicalAge,
                FixedGender           = record.gender
            };

            // Add a faction to the generation request, if possible.
            if (record.originalFactionDef != null)
            {
                FactionDef factionDef = DefDatabase <FactionDef> .GetNamedSilentFail(record.originalFactionDef);

                if (factionDef != null)
                {
                    Faction faction = PrepareCarefully.Instance.Providers.Factions.GetFaction(factionDef);
                    if (faction != null)
                    {
                        generationRequest.Faction = faction;
                    }
                    else
                    {
                        Logger.Warning("No faction found for faction definition {" + record.originalFactionDef + "}");
                    }
                }
                else
                {
                    Logger.Warning("No faction defition defition found for {" + record.originalFactionDef + "}");
                }
            }
            // Add a pawn kind definition to the generation request, if possible.
            if (pawnKindDef != null)
            {
                generationRequest.KindDef = pawnKindDef;
            }

            // Create the pawn.
            Pawn source = null;

            try {
                source = PawnGenerator.GeneratePawn(generationRequest.Request);
            }
            catch (Exception e) {
                Logger.Warning("Failed to generate a pawn from preset for pawn {" + (record.nickName) + "}. Will try to create it using fallback settings", e);
                generationRequest = new PawnGenerationRequestWrapper()
                {
                    FixedBiologicalAge    = record.biologicalAge,
                    FixedChronologicalAge = record.chronologicalAge,
                    FixedGender           = record.gender
                };
                try {
                    source = PawnGenerator.GeneratePawn(generationRequest.Request);
                }
                catch (Exception) {
                    Logger.Warning("Failed to generate a pawn using fallback settings from preset for pawn {" + (record.nickName) + "}", e);
                    return(null);
                }
            }

            if (source.health != null)
            {
                source.health.Reset();
            }

            CustomPawn pawn = new CustomPawn(source);

            if (record.id == null)
            {
                pawn.GenerateId();
            }
            else
            {
                pawn.Id = record.id;
            }

            if (record.type != null)
            {
                try {
                    pawn.Type = (CustomPawnType)Enum.Parse(typeof(CustomPawnType), record.type);
                }
                catch (Exception) {
                    pawn.Type = CustomPawnType.Colonist;
                }
            }
            else
            {
                pawn.Type = CustomPawnType.Colonist;
            }

            pawn.Gender = record.gender;
            if (record.age > 0)
            {
                pawn.ChronologicalAge = record.age;
                pawn.BiologicalAge    = record.age;
            }
            if (record.chronologicalAge > 0)
            {
                pawn.ChronologicalAge = record.chronologicalAge;
            }
            if (record.biologicalAge > 0)
            {
                pawn.BiologicalAge = record.biologicalAge;
            }

            pawn.FirstName = record.firstName;
            pawn.NickName  = record.nickName;
            pawn.LastName  = record.lastName;

            if (record.originalFactionDef != null)
            {
                pawn.OriginalFactionDef = DefDatabase <FactionDef> .GetNamedSilentFail(record.originalFactionDef);
            }
            pawn.OriginalKindDef = pawnKindDef;

            if (pawn.Type == CustomPawnType.Colonist)
            {
                Faction playerFaction = Faction.OfPlayerSilentFail;
                if (playerFaction != null)
                {
                    pawn.Pawn.SetFactionDirect(playerFaction);
                }
            }
            else if (pawn.Type == CustomPawnType.World)
            {
                if (record.faction != null)
                {
                    if (record.faction.def != null)
                    {
                        FactionDef factionDef = DefDatabase <FactionDef> .GetNamedSilentFail(record.faction.def);

                        if (factionDef != null)
                        {
                            bool randomFaction = false;
                            if (record.faction.index != null)
                            {
                                CustomFaction customFaction = null;
                                if (!record.faction.leader)
                                {
                                    customFaction = PrepareCarefully.Instance.Providers.Factions.FindCustomFactionByIndex(factionDef, record.faction.index.Value);
                                }
                                else
                                {
                                    customFaction = PrepareCarefully.Instance.Providers.Factions.FindCustomFactionWithLeaderOptionByIndex(factionDef, record.faction.index.Value);
                                }
                                if (customFaction != null)
                                {
                                    pawn.Faction = customFaction;
                                }
                                else
                                {
                                    Logger.Warning("Could not place at least one preset character into a saved faction because there were not enough available factions of that type in the world");
                                    randomFaction = true;
                                }
                            }
                            else
                            {
                                randomFaction = true;
                            }
                            if (randomFaction)
                            {
                                CustomFaction customFaction = PrepareCarefully.Instance.Providers.Factions.FindRandomCustomFactionByDef(factionDef);
                                if (customFaction != null)
                                {
                                    pawn.Faction = customFaction;
                                }
                            }
                        }
                        else
                        {
                            Logger.Warning("Could not place at least one preset character into a saved faction because that faction is not available in the world");
                        }
                    }
                }
            }

            HairDef h = DefDatabase <HairDef> .GetNamedSilentFail(record.hairDef);

            if (h != null)
            {
                pawn.HairDef = h;
            }
            else
            {
                Logger.Warning("Could not load hair definition \"" + record.hairDef + "\"");
                partialFailure = true;
            }

            pawn.HeadGraphicPath = record.headGraphicPath;
            if (pawn.Pawn.story != null)
            {
                pawn.Pawn.story.hairColor = record.hairColor;
            }

            if (record.melanin >= 0.0f)
            {
                pawn.MelaninLevel = record.melanin;
            }
            else
            {
                pawn.MelaninLevel = PawnColorUtils.FindMelaninValueFromColor(record.skinColor);
            }

            Backstory backstory = FindBackstory(record.childhood);

            if (backstory != null)
            {
                pawn.Childhood = backstory;
            }
            else
            {
                Logger.Warning("Could not load childhood backstory definition \"" + record.childhood + "\"");
                partialFailure = true;
            }
            if (record.adulthood != null)
            {
                backstory = FindBackstory(record.adulthood);
                if (backstory != null)
                {
                    pawn.Adulthood = backstory;
                }
                else
                {
                    Logger.Warning("Could not load adulthood backstory definition \"" + record.adulthood + "\"");
                    partialFailure = true;
                }
            }

            BodyTypeDef bodyType = null;

            try {
                bodyType = DefDatabase <BodyTypeDef> .GetNamedSilentFail(record.bodyType);
            }
            catch (Exception) {
            }
            if (bodyType == null)
            {
                if (pawn.Adulthood != null)
                {
                    bodyType = pawn.Adulthood.BodyTypeFor(pawn.Gender);
                }
                else
                {
                    bodyType = pawn.Childhood.BodyTypeFor(pawn.Gender);
                }
            }
            if (bodyType != null)
            {
                pawn.BodyType = bodyType;
            }

            // Load pawn comps
            //Logger.Debug("pre-copy comps xml: " + record.compsXml);
            String compsXml = "<saveable Class=\"" + typeof(PawnCompsLoader).FullName + "\">" + record.compsXml + "</saveable>";
            PawnCompInclusionRules rules = new PawnCompInclusionRules();

            rules.IncludeComps(record.savedComps);
            UtilityCopy.DeserializeExposable <PawnCompsLoader>(compsXml, new object[] { pawn.Pawn, rules });
            Dictionary <string, ThingComp> compLookup = new Dictionary <string, ThingComp>();

            foreach (var c in pawn.Pawn.AllComps)
            {
                if (!compLookup.ContainsKey(c.GetType().FullName))
                {
                    //Logger.Debug("Added comp to comp lookup with key: " + c.GetType().FullName);
                    compLookup.Add(c.GetType().FullName, c);
                }
            }
            HashSet <string> savedComps = record.savedComps != null ? new HashSet <string>(record.savedComps) : new HashSet <string>();

            DefaultPawnCompRules.PostLoadModifiers.Apply(pawn.Pawn, compLookup, savedComps);

            pawn.ClearTraits();
            if (record.traits != null)
            {
                for (int i = 0; i < record.traits.Count; i++)
                {
                    string traitName = record.traits[i].def;
                    Trait  trait     = FindTrait(traitName, record.traits[i].degree);
                    if (trait != null)
                    {
                        pawn.AddTrait(trait);
                    }
                    else
                    {
                        Logger.Warning("Could not load trait definition \"" + traitName + "\"");
                        partialFailure = true;
                    }
                }
            }
            else if (record.traitNames != null && record.traitDegrees != null && record.traitNames.Count == record.traitDegrees.Count)
            {
                for (int i = 0; i < record.traitNames.Count; i++)
                {
                    string traitName = record.traitNames[i];
                    Trait  trait     = FindTrait(traitName, record.traitDegrees[i]);
                    if (trait != null)
                    {
                        pawn.AddTrait(trait);
                    }
                    else
                    {
                        Logger.Warning("Could not load trait definition \"" + traitName + "\"");
                        partialFailure = true;
                    }
                }
            }

            foreach (var skill in record.skills)
            {
                SkillDef def = FindSkillDef(pawn.Pawn, skill.name);
                if (def == null)
                {
                    Logger.Warning("Could not load skill definition \"" + skill.name + "\" from saved preset");
                    partialFailure = true;
                    continue;
                }
                pawn.currentPassions[def]  = skill.passion;
                pawn.originalPassions[def] = skill.passion;
                pawn.SetOriginalSkillLevel(def, skill.value);
                pawn.SetUnmodifiedSkillLevel(def, skill.value);
            }

            foreach (var layer in PrepareCarefully.Instance.Providers.PawnLayers.GetLayersForPawn(pawn))
            {
                if (layer.Apparel)
                {
                    pawn.SetSelectedApparel(layer, null);
                    pawn.SetSelectedStuff(layer, null);
                }
            }
            List <PawnLayer> apparelLayers = PrepareCarefully.Instance.Providers.PawnLayers.GetLayersForPawn(pawn).FindAll((layer) => { return(layer.Apparel); });

            foreach (var apparelRecord in record.apparel)
            {
                // Find the pawn layer for the saved apparel record.
                PawnLayer layer = apparelLayers.FirstOrDefault((apparelLayer) => { return(apparelLayer.Name == apparelRecord.layer); });
                if (layer == null)
                {
                    Logger.Warning("Could not find a matching pawn layer for the saved apparel \"" + apparelRecord.layer + "\"");
                    partialFailure = true;
                    continue;
                }
                if (apparelRecord.apparel.NullOrEmpty())
                {
                    Logger.Warning("Saved apparel entry for layer \"" + apparelRecord.layer + "\" had an empty apparel def");
                    partialFailure = true;
                    continue;
                }
                // Set the defaults.
                pawn.SetSelectedApparel(layer, null);
                pawn.SetSelectedStuff(layer, null);
                pawn.SetColor(layer, Color.white);

                ThingDef def = DefDatabase <ThingDef> .GetNamedSilentFail(apparelRecord.apparel);

                if (def == null)
                {
                    Logger.Warning("Could not load thing definition for apparel \"" + apparelRecord.apparel + "\"");
                    partialFailure = true;
                    continue;
                }
                ThingDef stuffDef = null;
                if (!string.IsNullOrEmpty(apparelRecord.stuff))
                {
                    stuffDef = DefDatabase <ThingDef> .GetNamedSilentFail(apparelRecord.stuff);

                    if (stuffDef == null)
                    {
                        Logger.Warning("Could not load stuff definition \"" + apparelRecord.stuff + "\" for apparel \"" + apparelRecord.apparel + "\"");
                        partialFailure = true;
                        continue;
                    }
                }
                pawn.SetSelectedApparel(layer, def);
                pawn.SetSelectedStuff(layer, stuffDef);
                pawn.SetColor(layer, apparelRecord.color);
            }

            OptionsHealth healthOptions = PrepareCarefully.Instance.Providers.Health.GetOptions(pawn);

            for (int i = 0; i < record.implants.Count; i++)
            {
                SaveRecordImplantV3 implantRecord  = record.implants[i];
                UniqueBodyPart      uniqueBodyPart = healthOptions.FindBodyPartByName(implantRecord.bodyPart, implantRecord.bodyPartIndex != null ? implantRecord.bodyPartIndex.Value : 0);
                if (uniqueBodyPart == null)
                {
                    uniqueBodyPart = FindReplacementBodyPart(healthOptions, implantRecord.bodyPart);
                }
                if (uniqueBodyPart == null)
                {
                    Logger.Warning("Could not add the implant because it could not find the needed body part \"" + implantRecord.bodyPart + "\""
                                   + (implantRecord.bodyPartIndex != null ? " with index " + implantRecord.bodyPartIndex : ""));
                    partialFailure = true;
                    continue;
                }
                BodyPartRecord bodyPart = uniqueBodyPart.Record;
                if (implantRecord.recipe != null)
                {
                    RecipeDef recipeDef = FindRecipeDef(implantRecord.recipe);
                    if (recipeDef == null)
                    {
                        Logger.Warning("Could not add the implant because it could not find the recipe definition \"" + implantRecord.recipe + "\"");
                        partialFailure = true;
                        continue;
                    }
                    bool found = false;
                    foreach (var p in recipeDef.appliedOnFixedBodyParts)
                    {
                        if (p.defName.Equals(bodyPart.def.defName))
                        {
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        Logger.Warning("Could not apply the saved implant recipe \"" + implantRecord.recipe + "\" to the body part \"" + bodyPart.def.defName + "\".  Recipe does not support that part.");
                        partialFailure = true;
                        continue;
                    }
                    Implant implant = new Implant();
                    implant.BodyPartRecord = bodyPart;
                    implant.recipe         = recipeDef;
                    implant.label          = implant.Label;
                    pawn.AddImplant(implant);
                }
            }

            foreach (var injuryRecord in record.injuries)
            {
                HediffDef def = DefDatabase <HediffDef> .GetNamedSilentFail(injuryRecord.hediffDef);

                if (def == null)
                {
                    Logger.Warning("Could not add the injury because it could not find the hediff definition \"" + injuryRecord.hediffDef + "\"");
                    partialFailure = true;
                    continue;
                }
                InjuryOption option = healthOptions.FindInjuryOptionByHediffDef(def);
                if (option == null)
                {
                    Logger.Warning("Could not add the injury because it could not find a matching injury option for the saved hediff \"" + injuryRecord.hediffDef + "\"");
                    partialFailure = true;
                    continue;
                }
                BodyPartRecord bodyPart = null;
                if (injuryRecord.bodyPart != null)
                {
                    UniqueBodyPart uniquePart = healthOptions.FindBodyPartByName(injuryRecord.bodyPart,
                                                                                 injuryRecord.bodyPartIndex != null ? injuryRecord.bodyPartIndex.Value : 0);
                    if (uniquePart == null)
                    {
                        uniquePart = FindReplacementBodyPart(healthOptions, injuryRecord.bodyPart);
                    }
                    if (uniquePart == null)
                    {
                        Logger.Warning("Could not add the injury because it could not find the needed body part \"" + injuryRecord.bodyPart + "\""
                                       + (injuryRecord.bodyPartIndex != null ? " with index " + injuryRecord.bodyPartIndex : ""));
                        partialFailure = true;
                        continue;
                    }
                    bodyPart = uniquePart.Record;
                }
                Injury injury = new Injury();
                injury.Option         = option;
                injury.BodyPartRecord = bodyPart;
                if (injuryRecord.severity != null)
                {
                    injury.Severity = injuryRecord.Severity;
                }
                if (injuryRecord.painFactor != null)
                {
                    injury.PainFactor = injuryRecord.PainFactor;
                }
                pawn.AddInjury(injury);
            }

            pawn.CopySkillsAndPassionsToPawn();
            pawn.ClearPawnCaches();

            return(pawn);
        }