protected OptionsHair InitializeHumanlikeHairs() { HashSet <string> nonHumanHairTags = new HashSet <string>(); IEnumerable <ThingDef> alienRaces = DefDatabase <ThingDef> .AllDefs.Where((ThingDef def) => { return(def.race != null && ProviderAlienRaces.IsAlienRace(def)); }); foreach (var alienRaceDef in alienRaces) { AlienRace alienRace = AlienRaceProvider.GetAlienRace(alienRaceDef); if (alienRace == null) { continue; } if (alienRace.HairTags != null) { foreach (var tag in alienRace.HairTags) { nonHumanHairTags.Add(tag); } } } OptionsHair result = new OptionsHair(); foreach (HairDef hairDef in DefDatabase <HairDef> .AllDefs.Where((HairDef def) => { foreach (var tag in def.hairTags) { if (nonHumanHairTags.Contains(tag)) { return(false); } } return(true); })) { result.AddHair(hairDef); } result.Sort(); // Set up default hair colors result.Colors.Add(new Color(0.2f, 0.2f, 0.2f)); result.Colors.Add(new Color(0.31f, 0.28f, 0.26f)); result.Colors.Add(new Color(0.25f, 0.2f, 0.15f)); result.Colors.Add(new Color(0.3f, 0.2f, 0.1f)); result.Colors.Add(new Color(0.3529412f, 0.227451f, 0.1254902f)); result.Colors.Add(new Color(0.5176471f, 0.3254902f, 0.1843137f)); result.Colors.Add(new Color(0.7568628f, 0.572549f, 0.3333333f)); result.Colors.Add(new Color(0.9294118f, 0.7921569f, 0.6117647f)); return(result); }
protected OptionsBodyType InitializeBodyTypes(ThingDef def) { if (!ProviderAlienRaces.IsAlienRace(def)) { return(InitializeHumanlikeBodyTypes()); } else { OptionsBodyType result = InitializeAlienRaceBodyTypes(def); if (result == null) { Logger.Warning("Could not initialize body types for alien race, " + def.defName + ". Defaulting to humanlike body types."); return(InitializeHumanlikeBodyTypes()); } return(result); } }
protected OptionsApparel InitializeHumanlikeApparel() { HashSet <string> nonHumanApparel = new HashSet <string>(); IEnumerable <ThingDef> alienRaces = DefDatabase <ThingDef> .AllDefs.Where((ThingDef def) => { return(def.race != null && ProviderAlienRaces.IsAlienRace(def)); }); foreach (var alienRaceDef in alienRaces) { AlienRace alienRace = AlienRaceProvider.GetAlienRace(alienRaceDef); if (alienRace == null) { continue; } if (alienRace.RestrictedApparel != null) { foreach (var defName in alienRace.RestrictedApparel) { nonHumanApparel.Add(defName); } } } OptionsApparel result = new OptionsApparel(); foreach (ThingDef apparelDef in DefDatabase <ThingDef> .AllDefs) { if (apparelDef.apparel == null) { continue; } if (!nonHumanApparel.Contains(apparelDef.defName)) { AddApparel(result, apparelDef); } } result.Sort(); return(result); }
public CustomHeadType FindHeadTypeForPawn(Pawn pawn) { var alienComp = ProviderAlienRaces.FindAlienCompForPawn(pawn); if (alienComp == null) { var result = FindHeadTypeByGraphicsPath(pawn.story.HeadGraphicPath); if (result == null) { Log.Warning("Did not find head type for path: " + pawn.story.HeadGraphicPath); } return(result); } else { string crownType = ProviderAlienRaces.GetCrownTypeFromComp(alienComp); var result = FindHeadTypeByCrownTypeAndGender(crownType, pawn.gender); if (result == null) { Log.Warning("Did not find head type for alien crown type: " + crownType); } return(result); } }
protected OptionsBodyType InitializeBodyTypes(ThingDef def) { if (!ProviderAlienRaces.IsAlienRace(def)) { return(InitializeHumanlikeBodyTypes()); } else { OptionsBodyType result = InitializeAlienRaceBodyTypes(def); if (result == null) { Log.Warning("Prepare Carefully could not initialize body types for alien race, " + def.defName + ". Defaulting to humanlike body types."); return(InitializeHumanlikeBodyTypes()); } if (result.MaleBodyTypes.Count == 0 || result.FemaleBodyTypes.Count == 0) { return(InitializeHumanlikeBodyTypes()); } else { return(result); } } }
public SaveRecordPawnV4(CustomPawn pawn) { this.id = pawn.Id; this.thingDef = pawn.Pawn.def.defName; this.type = pawn.Type.ToString(); if (pawn.Type == CustomPawnType.World && pawn.Faction != null) { this.faction = new SaveRecordFactionV4(); this.faction.def = pawn.Faction.Def != null ? pawn.Faction.Def.defName : null; this.faction.index = pawn.Faction.Index; this.faction.leader = pawn.Faction.Leader; } this.pawnKindDef = pawn.OriginalKindDef != null ? pawn.OriginalKindDef.defName : pawn.Pawn.kindDef.defName; this.originalFactionDef = pawn.OriginalFactionDef != null ? pawn.OriginalFactionDef.defName : null; this.gender = pawn.Gender; if (pawn.Adulthood != null) { this.adulthood = pawn.Adulthood.identifier; } else { this.adulthood = pawn.LastSelectedAdulthoodBackstory?.identifier; } this.childhood = pawn.Childhood.identifier; this.skinColor = pawn.Pawn.story.SkinColor; this.melanin = pawn.Pawn.story.melanin; this.hairDef = pawn.HairDef.defName; this.hairColor = pawn.Pawn.story.hairColor; this.headGraphicPath = pawn.HeadGraphicPath; this.bodyType = pawn.BodyType.defName; this.firstName = pawn.FirstName; this.nickName = pawn.NickName; this.lastName = pawn.LastName; this.age = 0; this.biologicalAge = pawn.BiologicalAge; this.chronologicalAge = pawn.ChronologicalAge; foreach (var trait in pawn.Traits) { if (trait != null) { this.traitNames.Add(trait.def.defName); this.traitDegrees.Add(trait.Degree); } } foreach (var skill in pawn.Pawn.skills.skills) { SaveRecordSkillV4 skillRecord = new SaveRecordSkillV4(); skillRecord.name = skill.def.defName; skillRecord.value = pawn.GetUnmodifiedSkillLevel(skill.def); skillRecord.passion = pawn.currentPassions[skill.def]; this.skills.Add(skillRecord); } foreach (var layer in PrepareCarefully.Instance.Providers.PawnLayers.GetLayersForPawn(pawn)) { if (layer.Apparel) { ThingDef apparelThingDef = pawn.GetAcceptedApparel(layer); Color color = pawn.GetColor(layer); if (apparelThingDef != null) { ThingDef apparelStuffDef = pawn.GetSelectedStuff(layer); SaveRecordApparelV4 apparelRecord = new SaveRecordApparelV4(); apparelRecord.layer = layer.Name; apparelRecord.apparel = apparelThingDef.defName; apparelRecord.stuff = apparelStuffDef != null ? apparelStuffDef.defName : ""; apparelRecord.color = color; this.apparel.Add(apparelRecord); } } } OptionsHealth healthOptions = PrepareCarefully.Instance.Providers.Health.GetOptions(pawn); foreach (Implant implant in pawn.Implants) { var saveRecord = new SaveRecordImplantV3(implant); if (implant.BodyPartRecord != null) { UniqueBodyPart part = healthOptions.FindBodyPartsForRecord(implant.BodyPartRecord); if (part != null && part.Index > 0) { saveRecord.bodyPartIndex = part.Index; } } this.implants.Add(saveRecord); } foreach (Injury injury in pawn.Injuries) { var saveRecord = new SaveRecordInjuryV3(injury); if (injury.BodyPartRecord != null) { UniqueBodyPart part = healthOptions.FindBodyPartsForRecord(injury.BodyPartRecord); if (part != null && part.Index > 0) { saveRecord.bodyPartIndex = part.Index; } } this.injuries.Add(saveRecord); } ThingComp alienComp = ProviderAlienRaces.FindAlienCompForPawn(pawn.Pawn); if (alienComp != null) { alien = new SaveRecordAlienV4(); alien.crownType = ProviderAlienRaces.GetCrownTypeFromComp(alienComp); alien.skinColor = ProviderAlienRaces.GetSkinColorFromComp(alienComp); alien.skinColorSecond = ProviderAlienRaces.GetSkinColorSecondFromComp(alienComp); alien.hairColorSecond = ProviderAlienRaces.GetHairColorSecondFromComp(alienComp); } }
public static Pawn Copy(this Pawn source) { PawnHealthState savedHealthState = source.health.State; Pawn result = (Pawn)ThingMaker.MakeThing(source.kindDef.race, null); result.kindDef = source.kindDef; result.SetFactionDirect(source.Faction); PawnComponentsUtility.CreateInitialComponents(result); // Copy gender. result.gender = source.gender; // Copy name; NameTriple nameTriple = source.Name as NameTriple; NameSingle nameSingle = source.Name as NameSingle; if (nameTriple != null) { result.Name = new NameTriple(nameTriple.First, nameTriple.Nick, nameTriple.Last); } else if (nameSingle != null) { result.Name = new NameSingle(nameSingle.Name, nameSingle.Numerical); } // Copy trackers. object[] constructorArgs = new object[] { result }; result.ageTracker = UtilityCopy.CopyExposable(source.ageTracker, constructorArgs); result.story = UtilityCopy.CopyExposable(source.story, constructorArgs); result.skills = UtilityCopy.CopyExposable(source.skills, constructorArgs); result.health = UtilityCopy.CopyExposable(source.health, constructorArgs); result.apparel = UtilityCopy.CopyExposable(source.apparel, constructorArgs); // Copy alien comps ThingComp sourceAlienComp = ProviderAlienRaces.FindAlienCompForPawn(source); ThingComp resultAlienComp = ProviderAlienRaces.FindAlienCompForPawn(result); if (sourceAlienComp != null && resultAlienComp != null) { ProviderAlienRaces.SetCrownTypeOnComp(resultAlienComp, ProviderAlienRaces.GetCrownTypeFromComp(sourceAlienComp)); ProviderAlienRaces.SetSkinColorOnComp(resultAlienComp, ProviderAlienRaces.GetSkinColorFromComp(sourceAlienComp)); ProviderAlienRaces.SetSkinColorSecondOnComp(resultAlienComp, ProviderAlienRaces.GetSkinColorSecondFromComp(sourceAlienComp)); ProviderAlienRaces.SetHairColorSecondOnComp(resultAlienComp, ProviderAlienRaces.GetHairColorSecondFromComp(sourceAlienComp)); } // Copy properties added to pawns by mods. CopyModdedProperties(source, result); // Verify the pawn health state. if (result.health.State != savedHealthState) { Log.Warning("Mismatched health state on copied pawn: " + savedHealthState + " != " + result.health.State + "; Resetting value to match."); result.SetHealthState(savedHealthState); } // Clear all of the pawn caches. source.ClearCaches(); return(result); }
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); }