public void AddInjury(InjuryOption option) { if (!injuryOptionsByHediff.ContainsKey(option.HediffDef)) { this.injuryOptionsByHediff.Add(option.HediffDef, option); this.injuryOptions.Add(option); } }
public IEnumerable <BodyPartRecord> BodyPartsForInjury(InjuryOption option) { if (option.ValidParts == null || option.ValidParts.Count == 0) { return(SkinCoveredBodyParts.Select((UniqueBodyPart p) => { return p.Record; })); } else { List <BodyPartRecord> records = new List <BodyPartRecord>(); foreach (var part in option.ValidParts) { records.AddRange(FindBodyPartsForDef(part).ConvertAll(p => p.Record)); } return(records); } }
protected void AddInjuryToPawn(CustomPawn pawn, InjuryOption option, InjurySeverity severity, BodyPartRecord bodyPart) { Injury injury = new Injury(); injury.BodyPartRecord = bodyPart; injury.Option = option; if (severity != null) { injury.Severity = severity.Value; } else { injury.Severity = option.HediffDef.initialSeverity; } pawn.AddInjury(injury); }
protected void InitializeHediffGiverInjuries(OptionsHealth options, HediffGiver giver) { if (giver == null) { Logger.Warning("Could not add injury/health condition because a HediffGiver was null"); return; } if (giver.hediff == null) { Logger.Warning("Could not add injury/health condition because the hediff for " + giver.GetType().FullName + " was null"); return; } InjuryOption option = new InjuryOption(); option.HediffDef = giver.hediff; option.Label = giver.hediff.LabelCap; option.Giver = giver; if (giver.partsToAffect == null) { option.WholeBody = true; } if (giver.canAffectAnyLivePart) { option.WholeBody = false; } if (giver.partsToAffect != null && !giver.canAffectAnyLivePart) { List <BodyPartDef> validParts = new List <BodyPartDef>(); foreach (var def in giver.partsToAffect) { List <UniqueBodyPart> parts = options.FindBodyPartsForDef(def); if (parts != null) { validParts.Add(def); } } if (validParts.Count == 0) { return; } else { option.ValidParts = validParts; } } options.AddInjury(option); }
protected void ResetDisabledInjuryOptions(CustomPawn pawn) { disabledInjuryOptions.Clear(); foreach (var injuryOption in PrepareCarefully.Instance.Providers.Health.GetOptions(pawn).InjuryOptions) { InjuryOption option = injuryOption; if (option.IsOldInjury) { continue; } Injury injury = pawn.Injuries.FirstOrDefault((Injury i) => { return(i.Option == option); }); if (injury != null) { disabledInjuryOptions.Add(injuryOption); } } }
public void InitializePawnInjuries(Pawn pawn, CustomPawn customPawn) { foreach (var x in pawn.health.hediffSet.hediffs) { InjuryOption option = FindOptionByHediffDef(x.def); if (option != null) { Injury injury = new Injury(); injury.BodyPartRecord = x.Part; injury.Option = option; injury.Severity = x.Severity; customPawn.AddInjury(injury); } else { Log.Warning("Could not find injury option for hediff: " + x.def); } } }
protected void ResetInjuryOptionEnabledState(CustomPawn pawn) { disabledInjuryOptions.Clear(); InjuryManager injuryManager = PrepareCarefully.Instance.HealthManager.InjuryManager; foreach (var injuryOption in injuryManager.Options) { InjuryOption option = injuryOption; if (option.IsOldInjury) { continue; } Injury injury = pawn.Injuries.FirstOrDefault((Injury i) => { return(i.Option == option); }); if (injury != null) { disabledInjuryOptions.Add(injuryOption); } } }
protected void InitializeHediffGiverInjuries(OptionsHealth options, HediffGiver giver) { InjuryOption option = new InjuryOption(); option.HediffDef = giver.hediff; option.Label = giver.hediff.LabelCap; option.Giver = giver; if (giver.partsToAffect == null) { option.WholeBody = true; } if (giver.canAffectAnyLivePart) { option.WholeBody = false; } if (giver.partsToAffect != null && !giver.canAffectAnyLivePart) { List <BodyPartDef> validParts = new List <BodyPartDef>(); foreach (var def in giver.partsToAffect) { List <UniqueBodyPart> parts = options.FindBodyPartsForDef(def); if (parts != null) { validParts.Add(def); } } if (validParts.Count == 0) { return; } else { option.ValidParts = validParts; } } options.AddInjury(option); }
public CustomPawn LoadPawn(SaveRecordPawnV3 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; } } Pawn source; if (pawnKindDef != null) { source = new Randomizer().GenerateKindOfColonist(pawnKindDef); } else { source = new Randomizer().GenerateColonist(); } source.health.Reset(); CustomPawn pawn = new CustomPawn(source); if (pawn.Id == null) { pawn.GenerateId(); } else { pawn.Id = record.id; } 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; 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; 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 (only for Alien Races). if (pawn.AlienRace != null) { pawn.SkinColor = record.skinColor; } 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; } } // Get the body type from the save record. If there's no value in the save, then assign the // default body type from the pawn's backstories. // TODO: 1.0 /* * BodyType? bodyType = null; * try { * bodyType = (BodyType)Enum.Parse(typeof(BodyType), record.bodyType); * } * catch (Exception) { * } * if (!bodyType.HasValue) { * if (pawn.Adulthood != null) { * bodyType = pawn.Adulthood.BodyTypeFor(pawn.Gender); * } * else { * bodyType = pawn.Childhood.BodyTypeFor(pawn.Gender); * } * } * if (bodyType.HasValue) { * pawn.BodyType = bodyType.Value; * } */ 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; } } for (int i = 0; i < record.skillNames.Count; i++) { string name = record.skillNames[i]; SkillDef def = FindSkillDef(pawn.Pawn, name); if (def == null) { Log.Warning("Could not load skill definition \"" + name + "\""); Failed = true; continue; } pawn.currentPassions[def] = record.passions[i]; pawn.originalPassions[def] = record.passions[i]; pawn.SetOriginalSkillLevel(def, record.skillValues[i]); pawn.SetUnmodifiedSkillLevel(def, record.skillValues[i]); } if (record.originalPassions != null && record.originalPassions.Count == record.skillNames.Count) { for (int i = 0; i < record.skillNames.Count; i++) { string name = record.skillNames[i]; SkillDef def = FindSkillDef(pawn.Pawn, name); if (def == null) { Log.Warning("Could not load skill definition \"" + name + "\""); Failed = true; continue; } //pawn.originalPassions[def] = record.originalPassions[i]; } } foreach (var layer in PrepareCarefully.Instance.Providers.PawnLayers.GetLayersForPawn(pawn)) { if (layer.Apparel) { pawn.SetSelectedApparel(layer, null); pawn.SetSelectedStuff(layer, null); } } for (int i = 0; i < record.apparelLayers.Count; i++) { int layerIndex = record.apparelLayers[i]; PawnLayer layer = PrepareCarefully.Instance.Providers.PawnLayers.FindLayerFromDeprecatedIndex(layerIndex); if (layer == null) { Log.Warning("Could not find pawn layer from saved pawn layer index: \"" + layerIndex + "\""); Failed = true; continue; } ThingDef def = DefDatabase <ThingDef> .GetNamedSilentFail(record.apparel[i]); if (def == null) { Log.Warning("Could not load thing definition for apparel \"" + record.apparel[i] + "\""); Failed = true; continue; } ThingDef stuffDef = null; if (!string.IsNullOrEmpty(record.apparelStuff[i])) { stuffDef = DefDatabase <ThingDef> .GetNamedSilentFail(record.apparelStuff[i]); if (stuffDef == null) { Log.Warning("Could not load stuff definition \"" + record.apparelStuff[i] + "\" for apparel \"" + record.apparel[i] + "\""); Failed = true; continue; } } pawn.SetSelectedApparel(layer, def); pawn.SetSelectedStuff(layer, stuffDef); pawn.SetColor(layer, record.apparelColors[i]); } 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); }
protected void InitializeInjuryOptions(OptionsHealth options, ThingDef pawnThingDef) { HashSet <HediffDef> addedDefs = new HashSet <HediffDef>(); // Go through all of the hediff giver sets for the pawn's race and intialize injuries from // each giver. if (pawnThingDef.race.hediffGiverSets != null) { foreach (var giverSetDef in pawnThingDef.race.hediffGiverSets) { foreach (var giver in giverSetDef.hediffGivers) { InitializeHediffGiverInjuries(options, giver); } } } // Go through all hediff stages, looking for hediff givers. foreach (var hd in DefDatabase <HediffDef> .AllDefs) { if (hd.stages != null) { foreach (var stage in hd.stages) { if (stage.hediffGivers != null) { foreach (var giver in stage.hediffGivers) { InitializeHediffGiverInjuries(options, giver); } } } } } // Go through all of the chemical defs, looking for hediff givers. foreach (var chemicalDef in DefDatabase <ChemicalDef> .AllDefs) { if (chemicalDef.onGeneratedAddictedEvents != null) { foreach (var giver in chemicalDef.onGeneratedAddictedEvents) { InitializeHediffGiverInjuries(options, giver); } } } // Get all of the hediffs that can be added via the "forced hediff" scenario part and // add them to a hash set so that we can quickly look them up. ScenPart_ForcedHediff scenPart = new ScenPart_ForcedHediff(); IEnumerable <HediffDef> scenPartDefs = Reflection.ScenPart_ForcedHediff.PossibleHediffs(scenPart); HashSet <HediffDef> scenPartDefSet = new HashSet <HediffDef>(scenPartDefs); // Add injury options. foreach (var hd in DefDatabase <HediffDef> .AllDefs) { // TODO: Missing body part seems to be a special case. The hediff giver doesn't itself remove // limbs, so disable it until we can add special-case handling. if (hd.defName == "MissingBodyPart") { continue; } // Filter out defs that were already added via the hediff giver sets. if (addedDefs.Contains(hd)) { continue; } // Filter out implants. if (hd.hediffClass == typeof(Hediff_AddedPart)) { continue; } // If it's an old injury, use the old injury properties to get the label. HediffCompProperties p = hd.CompPropsFor(typeof(HediffComp_GetsPermanent)); HediffCompProperties_GetsPermanent getsPermanentProperties = p as HediffCompProperties_GetsPermanent; String label; if (getsPermanentProperties != null) { if (getsPermanentProperties.permanentLabel != null) { label = getsPermanentProperties.permanentLabel.CapitalizeFirst(); } else { Log.Warning("Prepare Carefully could not find label for old injury: " + hd.defName); continue; } } // If it's not an old injury, make sure it's one of the available hediffs that can // be added via ScenPart_ForcedHediff. If it's not, filter it out. else { if (!scenPartDefSet.Contains(hd)) { continue; } label = hd.LabelCap; } // Add the injury option.. InjuryOption option = new InjuryOption(); option.HediffDef = hd; option.Label = label; if (getsPermanentProperties != null) { option.IsOldInjury = true; } else { option.ValidParts = new List <BodyPartDef>(); } options.AddInjury(option); } // Disambiguate duplicate injury labels. HashSet <string> labels = new HashSet <string>(); HashSet <string> duplicateLabels = new HashSet <string>(); foreach (var option in options.InjuryOptions) { if (labels.Contains(option.Label)) { duplicateLabels.Add(option.Label); } else { labels.Add(option.Label); } } foreach (var option in options.InjuryOptions) { HediffCompProperties p = option.HediffDef.CompPropsFor(typeof(HediffComp_GetsPermanent)); HediffCompProperties_GetsPermanent props = p as HediffCompProperties_GetsPermanent; if (props != null) { if (duplicateLabels.Contains(option.Label)) { string label = "EdB.PC.Dialog.Injury.OldInjury.Label".Translate(props.permanentLabel.CapitalizeFirst(), option.HediffDef.LabelCap); option.Label = label; } } } }
public CustomPawn LoadPawn(SaveRecordPawnV3 record) { // TODO: Ahlpa 14 Evaluate Pawn source = new Randomizer().GenerateColonist(); //Pawn source = PawnGenerator.GeneratePawn(PawnKindDefOf.Colonist, Faction.OfPlayer); CustomPawn pawn = new CustomPawn(source); 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; 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; pawn.SetColor(PawnLayers.Hair, record.hairColor); pawn.SetColor(PawnLayers.HeadType, record.skinColor); Backstory backstory = FindBackstory(record.childhood); if (backstory != null) { pawn.Childhood = backstory; } else { Log.Warning("Could not load childhood backstory definition \"" + record.childhood + "\""); Failed = true; } backstory = FindBackstory(record.adulthood); if (backstory != null) { pawn.Adulthood = backstory; } else { Log.Warning("Could not load adulthood backstory definition \"" + record.adulthood + "\""); Failed = true; } int traitCount = pawn.Traits.Count(); for (int i = 0; i < traitCount; i++) { pawn.ClearTrait(i); } for (int i = 0; i < record.traitNames.Count; i++) { string traitName = record.traitNames[i]; if (i >= traitCount) { break; } Trait trait = FindTrait(traitName, record.traitDegrees[i]); if (trait != null) { pawn.SetTrait(i, trait); } else { Log.Warning("Could not load trait definition \"" + traitName + "\""); Failed = true; } } for (int i = 0; i < record.skillNames.Count; i++) { string name = record.skillNames[i]; SkillDef def = FindSkillDef(pawn.Pawn, name); if (def == null) { Log.Warning("Could not load skill definition \"" + name + "\""); Failed = true; continue; } pawn.currentPassions[def] = record.passions[i]; pawn.originalPassions[def] = record.passions[i]; pawn.SetOriginalSkillLevel(def, record.skillValues[i]); pawn.SetUnmodifiedSkillLevel(def, record.skillValues[i]); } if (record.originalPassions != null && record.originalPassions.Count == record.skillNames.Count) { for (int i = 0; i < record.skillNames.Count; i++) { string name = record.skillNames[i]; SkillDef def = FindSkillDef(pawn.Pawn, name); if (def == null) { Log.Warning("Could not load skill definition \"" + name + "\""); Failed = true; continue; } //pawn.originalPassions[def] = record.originalPassions[i]; } } for (int i = 0; i < PawnLayers.Count; i++) { if (PawnLayers.IsApparelLayer(i)) { pawn.SetSelectedApparel(i, null); pawn.SetSelectedStuff(i, null); } } for (int i = 0; i < record.apparelLayers.Count; i++) { int layer = record.apparelLayers[i]; ThingDef def = DefDatabase <ThingDef> .GetNamedSilentFail(record.apparel[i]); if (def == null) { Log.Warning("Could not load thing definition for apparel \"" + record.apparel[i] + "\""); Failed = true; continue; } ThingDef stuffDef = null; if (!string.IsNullOrEmpty(record.apparelStuff[i])) { stuffDef = DefDatabase <ThingDef> .GetNamedSilentFail(record.apparelStuff[i]); if (stuffDef == null) { Log.Warning("Could not load stuff definition \"" + record.apparelStuff[i] + "\" for apparel \"" + record.apparel[i] + "\""); Failed = true; continue; } } pawn.SetSelectedApparel(layer, def); pawn.SetSelectedStuff(layer, stuffDef); pawn.SetColor(layer, record.apparelColors[i]); } for (int i = 0; i < record.implants.Count; i++) { SaveRecordImplantV3 implantRecord = record.implants[i]; BodyPartRecord bodyPart = PrepareCarefully.Instance.HealthManager.ImplantManager.FindReplaceableBodyPartByName(implantRecord.bodyPart); if (bodyPart == null) { Log.Warning("Could not find replaceable body part definition \"" + implantRecord.bodyPart + "\""); Failed = true; continue; } if (implantRecord.recipe != null) { RecipeDef recipeDef = FindRecipeDef(implantRecord.recipe); if (recipeDef == null) { Log.Warning("Could not find 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("Body part \"" + bodyPart.def.defName + "\" does not match recipe used to replace it"); 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("Could not find hediff definition \"" + injuryRecord.hediffDef + "\""); Failed = true; continue; } InjuryOption option = PrepareCarefully.Instance.HealthManager.InjuryManager.FindOptionByHediffDef(def); if (option == null) { Log.Warning("Could not find injury option for \"" + injuryRecord.hediffDef + "\""); Failed = true; continue; } BodyPartRecord bodyPart = null; if (injuryRecord.bodyPart != null) { bodyPart = PrepareCarefully.Instance.HealthManager.FirstBodyPartRecord(injuryRecord.bodyPart); if (bodyPart == null) { Log.Warning("Could not find body part \"" + injuryRecord.bodyPart + "\""); Failed = true; continue; } } Injury injury = new Injury(); injury.Option = option; injury.BodyPartRecord = bodyPart; if (injuryRecord.severity != null) { injury.Severity = injuryRecord.Severity; } pawn.AddInjury(injury); } pawn.RandomInjuries = record.randomInjuries; pawn.RandomRelations = record.randomRelations; pawn.ClearCachedAbilities(); pawn.ClearCachedLifeStage(); return(pawn); }
public void DrawAddButton() { if (RectButtonAdd.Contains(Event.current.mousePosition)) { GUI.color = Style.ColorButtonHighlight; } else { GUI.color = Style.ColorButton; } GUI.DrawTexture(RectButtonAdd, Textures.TextureButtonAdd); // Add button. if (Widgets.ButtonInvisible(RectButtonAdd, false)) { CustomPawn customPawn = PrepareCarefully.Instance.State.CurrentPawn; Action addEntryAction = () => { }; OptionsHealth healthOptions = PrepareCarefully.Instance.Providers.Health.GetOptions(customPawn); string selectedHediffType = this.selectedHediffType; RecipeDef selectedRecipe = null; InjuryOption selectedInjury = null; BodyPartRecord selectedBodyPart = null; bool bodyPartSelectionRequired = true; InjurySeverity selectedSeverity = null; Dialog_Options <InjurySeverity> severityDialog; Dialog_Options <BodyPartRecord> bodyPartDialog; Dialog_Options <InjuryOption> injuryOptionDialog; //Dialog_Options<RecipeDef> implantRecipeDialog; DialogManageImplants manageImplantsDialog; Dialog_Options <string> hediffTypeDialog; ResetDisabledInjuryOptions(customPawn); Action addInjuryAction = () => { if (bodyPartSelectionRequired) { AddInjuryToPawn(selectedInjury, selectedSeverity, selectedBodyPart); } else { if (selectedInjury.ValidParts != null && selectedInjury.ValidParts.Count > 0) { foreach (var p in selectedInjury.ValidParts) { var part = healthOptions.FindBodyPartsForDef(p).FirstOrDefault(); if (part != null) { AddInjuryToPawn(selectedInjury, selectedSeverity, part.Record); } else { Log.Warning("Could not find body part record for definition: " + p.defName); } } } else { AddInjuryToPawn(selectedInjury, selectedSeverity, null); } } }; severityDialog = new Dialog_Options <InjurySeverity>(severityOptions) { ConfirmButtonLabel = "EdB.PC.Common.Add".Translate(), CancelButtonLabel = "EdB.PC.Common.Cancel".Translate(), HeaderLabel = "EdB.PC.Panel.Health.SelectSeverity".Translate(), NameFunc = (InjurySeverity option) => { if (!string.IsNullOrEmpty(option.Label)) { return(option.Label); } else { return(selectedInjury.HediffDef.LabelCap); } }, SelectedFunc = (InjurySeverity option) => { return(option == selectedSeverity); }, SelectAction = (InjurySeverity option) => { selectedSeverity = option; }, ConfirmValidation = () => { if (selectedSeverity == null) { return("EdB.PC.Panel.Health.Error.MustSelectSeverity"); } else { return(null); } }, CloseAction = () => { addInjuryAction(); } }; bodyPartDialog = new Dialog_Options <BodyPartRecord>(null) { ConfirmButtonLabel = "EdB.PC.Common.Add".Translate(), CancelButtonLabel = "EdB.PC.Common.Cancel".Translate(), HeaderLabel = "EdB.PC.Dialog.BodyPart.Header".Translate(), NameFunc = (BodyPartRecord option) => { return(option.LabelCap); }, SelectedFunc = (BodyPartRecord option) => { return(option == selectedBodyPart); }, SelectAction = (BodyPartRecord option) => { selectedBodyPart = option; }, EnabledFunc = (BodyPartRecord option) => { return(!disabledBodyParts.Contains(option)); }, ConfirmValidation = () => { if (selectedBodyPart == null) { return("EdB.PC.Dialog.BodyPart.Error.Required"); } else { return(null); } }, CloseAction = () => { if (selectedHediffType == HediffTypeInjury) { if (this.severityOptions.Count > 1) { Find.WindowStack.Add(severityDialog); } else { if (severityOptions.Count > 0) { selectedSeverity = this.severityOptions[0]; } addInjuryAction(); } } else if (selectedHediffType == HediffTypeImplant) { ImplantAdded(new Implant(selectedBodyPart, selectedRecipe)); } } }; injuryOptionDialog = new Dialog_Options <InjuryOption>(healthOptions.InjuryOptions) { ConfirmButtonLabel = "EdB.PC.Common.Next".Translate(), CancelButtonLabel = "EdB.PC.Common.Cancel".Translate(), HeaderLabel = "EdB.PC.Dialog.Injury.Header".Translate(), NameFunc = (InjuryOption option) => { return(option.Label); }, SelectedFunc = (InjuryOption option) => { return(selectedInjury == option); }, SelectAction = (InjuryOption option) => { selectedInjury = option; if (option.ValidParts == null && !option.WholeBody) { bodyPartSelectionRequired = true; } else if (option.ValidParts != null && option.ValidParts.Count > 0) { bodyPartSelectionRequired = true; } else { bodyPartSelectionRequired = false; } }, EnabledFunc = (InjuryOption option) => { return(!disabledInjuryOptions.Contains(option)); }, ConfirmValidation = () => { if (selectedInjury == null) { return("EdB.PC.Dialog.Injury.Error.Required"); } else { return(null); } }, CloseAction = () => { ResetSeverityOptions(selectedInjury); if (bodyPartSelectionRequired) { bodyPartDialog.Options = healthOptions.BodyPartsForInjury(selectedInjury); int count = bodyPartDialog.Options.Count(); if (count > 1) { ResetDisabledBodyParts(bodyPartDialog.Options, customPawn); Find.WindowStack.Add(bodyPartDialog); return; } else if (count == 1) { selectedBodyPart = bodyPartDialog.Options.First(); } } if (severityOptions.Count > 1) { Find.WindowStack.Add(severityDialog); } else { if (severityOptions.Count > 0) { selectedSeverity = this.severityOptions[0]; } addInjuryAction(); } } }; hediffTypeDialog = new Dialog_Options <string>(new string[] { HediffTypeInjury, HediffTypeImplant }) { ConfirmButtonLabel = "EdB.PC.Common.Next".Translate(), CancelButtonLabel = "EdB.PC.Common.Cancel".Translate(), NameFunc = (string type) => { return(("EdB.PC.Panel.Health." + type).Translate()); }, SelectedFunc = (string type) => { return(selectedHediffType == type); }, SelectAction = (string type) => { selectedHediffType = type; }, ConfirmValidation = () => { if (selectedHediffType == null) { return("EdB.PC.Panel.Health.Error.MustSelectOption"); } else { return(null); } }, CloseAction = () => { this.selectedHediffType = selectedHediffType; if (selectedHediffType == HediffTypeInjury) { Find.WindowStack.Add(injuryOptionDialog); } else { ResetDisabledImplantRecipes(customPawn); manageImplantsDialog = new DialogManageImplants(customPawn) { HeaderLabel = "EdB.PC.Dialog.Implant.Header".Translate(), CloseAction = (List <Implant> implants) => { ApplyImplantsToPawn(customPawn, implants); } }; Find.WindowStack.Add(manageImplantsDialog); } } }; Find.WindowStack.Add(hediffTypeDialog); } }
public IEnumerable <BodyPartRecord> BodyPartsForInjury(InjuryOption option) { return(SkinCoveredBodyParts.Select((UniqueBodyPart p) => { return p.Record; })); }
protected void ResetSeverityOptions(InjuryOption injuryOption) { severityOptions.Clear(); // Don't add stages for addictions since they are handled sort of differently. if (injuryOption.HediffDef.hediffClass != null && typeof(Hediff_Addiction).IsAssignableFrom(injuryOption.HediffDef.hediffClass)) { return; } // If the injury has no stages, add the old injury severity options. // TODO: Is this right? if (injuryOption.HediffDef.stages == null || injuryOption.HediffDef.stages.Count == 0) { severityOptions.AddRange(oldInjurySeverities); return; } int variant = 1; InjurySeverity previous = null; foreach (var stage in injuryOption.HediffDef.stages) { // Filter out a stage if it will definitely kill the pawn. if (PrepareCarefully.Instance.HealthManager.InjuryManager.DoesStageKillPawn(injuryOption.HediffDef, stage)) { continue; } if (!stage.everVisible) { continue; } InjurySeverity value = null; if (stage.minSeverity == 0) { float severity = injuryOption.HediffDef.initialSeverity > 0 ? injuryOption.HediffDef.initialSeverity : 0.001f; value = new InjurySeverity(severity, stage); } else { value = new InjurySeverity(stage.minSeverity, stage); } if (previous == null) { previous = value; variant = 1; } else { if (previous.Stage.label == stage.label) { previous.Variant = variant; variant++; value.Variant = variant; } else { previous = value; variant = 1; } } severityOptions.Add(value); } }
public void DrawHeader() { GUI.BeginGroup(RectHeader); GUI.color = Color.white; // Injury button. if (Widgets.ButtonText(new Rect(0, 0, 120, 28), "EdB.PrepareCarefully.AddInjury".Translate(), true, true, true)) { CustomPawn customPawn = PrepareCarefully.Instance.State.CurrentPawn; InjuryOption selectedInjury = null; BodyPartRecord selectedBodyPart = null; bool bodyPartSelectionRequired = true; InjurySeverity selectedSeverity = null; Dialog_Options <InjurySeverity> severityDialog; Dialog_Options <BodyPartRecord> bodyPartDialog; ResetInjuryOptionEnabledState(customPawn); Action addInjuryAction = () => { if (bodyPartSelectionRequired) { AddInjuryToPawn(customPawn, selectedInjury, selectedSeverity, selectedBodyPart); } else { if (selectedInjury.ValidParts.Count > 0) { foreach (var p in selectedInjury.ValidParts) { BodyPartRecord record = PrepareCarefully.Instance.HealthManager.FirstBodyPartRecord(customPawn, p); if (record != null) { AddInjuryToPawn(customPawn, selectedInjury, selectedSeverity, record); } else { Log.Warning("Could not find body part record for definition: " + p.defName); } } } else { AddInjuryToPawn(customPawn, selectedInjury, selectedSeverity, null); } } }; severityDialog = new Dialog_Options <InjurySeverity>(severityOptions) { ConfirmButtonLabel = "EdB.PrepareCarefully.Add", CancelButtonLabel = "EdB.PrepareCarefully.Cancel", HeaderLabel = "EdB.PrepareCarefully.SelectSeverity", NameFunc = (InjurySeverity option) => { if (!string.IsNullOrEmpty(option.Label)) { return(option.Label); } else { return(selectedInjury.HediffDef.LabelCap); } }, SelectedFunc = (InjurySeverity option) => { return(option == selectedSeverity); }, SelectAction = (InjurySeverity option) => { selectedSeverity = option; }, ConfirmValidation = () => { if (selectedSeverity == null) { return("EdB.PrepareCarefully.ErrorMustSelectSeverity"); } else { return(null); } }, CloseAction = () => { addInjuryAction(); } }; bodyPartDialog = new Dialog_Options <BodyPartRecord>(null) { ConfirmButtonLabel = "EdB.PrepareCarefully.Add", CancelButtonLabel = "EdB.PrepareCarefully.Cancel", HeaderLabel = "EdB.PrepareCarefully.SelectBodyPart", NameFunc = (BodyPartRecord option) => { return(option.def.LabelCap); }, SelectedFunc = (BodyPartRecord option) => { return(option == selectedBodyPart); }, SelectAction = (BodyPartRecord option) => { selectedBodyPart = option; }, EnabledFunc = (BodyPartRecord option) => { return(!disabledBodyParts.Contains(option)); }, ConfirmValidation = () => { if (selectedBodyPart == null) { return("EdB.PrepareCarefully.ErrorMustSelectBodyPart"); } else { return(null); } }, CloseAction = () => { if (this.severityOptions.Count > 1) { Find.WindowStack.Add(severityDialog); } else { if (severityOptions.Count > 0) { selectedSeverity = this.severityOptions[0]; } addInjuryAction(); } } }; Dialog_Options <InjuryOption> injuryOptionDialog = new Dialog_Options <InjuryOption>(PrepareCarefully.Instance.HealthManager.InjuryManager.Options) { ConfirmButtonLabel = "EdB.PrepareCarefully.Next", CancelButtonLabel = "EdB.PrepareCarefully.Cancel", HeaderLabel = "EdB.PrepareCarefully.SelectInjury", NameFunc = (InjuryOption option) => { return(option.Label); }, SelectedFunc = (InjuryOption option) => { return(selectedInjury == option); }, SelectAction = (InjuryOption option) => { selectedInjury = option; if (option.ValidParts == null) { bodyPartSelectionRequired = true; } else { bodyPartSelectionRequired = false; } }, EnabledFunc = (InjuryOption option) => { return(!disabledInjuryOptions.Contains(option)); }, ConfirmValidation = () => { if (selectedInjury == null) { return("EdB.PrepareCarefully.ErrorMustSelectInjury"); } else { return(null); } }, CloseAction = () => { ResetSeverityOptions(selectedInjury); if (bodyPartSelectionRequired) { bodyPartDialog.Options = PrepareCarefully.Instance.HealthManager.AllSkinCoveredBodyParts(customPawn); ResetBodyPartEnabledState(bodyPartDialog.Options, customPawn); Find.WindowStack.Add(bodyPartDialog); } else if (severityOptions.Count > 1) { Find.WindowStack.Add(severityDialog); } else { if (severityOptions.Count > 0) { selectedSeverity = this.severityOptions[0]; } addInjuryAction(); } } }; Find.WindowStack.Add(injuryOptionDialog); } // Implant button. if (Widgets.ButtonText(new Rect(RectHeader.width - 120, 0, 120, 28), "EdB.PrepareCarefully.AddImplant".Translate(), true, true, true)) { CustomPawn customPawn = PrepareCarefully.Instance.State.CurrentPawn; RecipeDef selectedRecipe = null; BodyPartRecord selectedBodyPart = null; bool bodyPartSelectionRequired = true; Dialog_Options <BodyPartRecord> bodyPartDialog = new Dialog_Options <BodyPartRecord>(null) { ConfirmButtonLabel = "EdB.PrepareCarefully.Add", CancelButtonLabel = "EdB.PrepareCarefully.Cancel", HeaderLabel = "EdB.PrepareCarefully.SelectBodyPart", NameFunc = (BodyPartRecord record) => { return(record.def.LabelCap); }, SelectedFunc = (BodyPartRecord record) => { return(record == selectedBodyPart); }, SelectAction = (BodyPartRecord record) => { selectedBodyPart = record; }, EnabledFunc = (BodyPartRecord record) => { return(!disabledBodyParts.Contains(record)); }, ConfirmValidation = () => { if (selectedBodyPart == null) { return("EdB.PrepareCarefully.ErrorMustSelectBodyPart"); } else { return(null); } }, CloseAction = () => { customPawn.AddImplant(new Implant(selectedBodyPart, selectedRecipe)); } }; Dialog_Options <RecipeDef> implantRecipeDialog = new Dialog_Options <RecipeDef>(PrepareCarefully.Instance.HealthManager.ImplantManager.RecipesForPawn(customPawn)) { ConfirmButtonLabel = "EdB.PrepareCarefully.Next", CancelButtonLabel = "EdB.PrepareCarefully.Cancel", HeaderLabel = "EdB.PrepareCarefully.SelectImplant", NameFunc = (RecipeDef recipe) => { return(recipe.LabelCap); }, SelectedFunc = (RecipeDef recipe) => { return(selectedRecipe == recipe); }, SelectAction = (RecipeDef recipe) => { selectedRecipe = recipe; IEnumerable <BodyPartRecord> bodyParts = PrepareCarefully.Instance.HealthManager.ImplantManager.PartsForRecipe(customPawn.Pawn, recipe); int bodyPartCount = bodyParts.Count(); if (bodyParts != null && bodyPartCount > 0) { if (bodyPartCount > 1) { selectedBodyPart = null; bodyPartDialog.Options = bodyParts; bodyPartSelectionRequired = true; ResetBodyPartEnabledState(bodyParts, customPawn); } else { selectedBodyPart = bodyParts.First(); bodyPartSelectionRequired = false; } } else { selectedBodyPart = null; bodyPartSelectionRequired = false; } }, ConfirmValidation = () => { if (selectedRecipe == null) { return("EdB.PrepareCarefully.ErrorMustSelectImplant"); } else { return(null); } }, CloseAction = () => { if (bodyPartSelectionRequired) { Find.WindowStack.Add(bodyPartDialog); } else { customPawn.AddImplant(new Implant(selectedBodyPart, selectedRecipe)); } } }; Find.WindowStack.Add(implantRecipeDialog); } GUI.EndGroup(); }
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); }
public void InitializeOptions() { // Add long-term chronic conditions from the giver that adds new hediffs as pawns age. HediffGiverSetDef giverSetDef = DefDatabase <HediffGiverSetDef> .GetNamedSilentFail("OrganicStandard"); HashSet <HediffDef> addedDefs = new HashSet <HediffDef>(); if (giverSetDef != null) { foreach (var g in giverSetDef.hediffGivers) { if (g.GetType() == typeof(HediffGiver_Birthday)) { InjuryOption option = new InjuryOption(); option.Chronic = true; option.HediffDef = g.hediff; option.Label = g.hediff.LabelCap; option.Giver = g; if (!g.canAffectAnyLivePart) { option.ValidParts = new List <BodyPartDef>(); option.ValidParts.AddRange(g.partsToAffect); } options.Add(option); if (!addedDefs.Contains(g.hediff)) { addedDefs.Add(g.hediff); } } } } // Get all of the hediffs that can be added via the "forced hediff" scenario part and // add them to a hash set so that we can quickly look them up. ScenPart_ForcedHediff scenPart = new ScenPart_ForcedHediff(); IEnumerable <HediffDef> scenPartDefs = (IEnumerable <HediffDef>) typeof(ScenPart_ForcedHediff).GetMethod("PossibleHediffs", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(scenPart, null); HashSet <HediffDef> scenPartDefSet = new HashSet <HediffDef>(scenPartDefs); // Add injury options. List <InjuryOption> oldInjuries = new List <InjuryOption>(); foreach (var hd in DefDatabase <HediffDef> .AllDefs) { // TODO: Missing body part seems to be a special case. The hediff giver doesn't itself remove // limbs, so disable it until we can add special-case handling. if (hd.defName == "MissingBodyPart") { continue; } // Filter out defs that were already added as a chronic condition. if (addedDefs.Contains(hd)) { continue; } // Filter out implants. if (hd.hediffClass == typeof(Hediff_AddedPart)) { continue; } // If it's old injury, use the old injury properties to get the label. HediffCompProperties getsOldProperties = hd.CompPropsFor(typeof(HediffComp_GetsOld)); String label; if (getsOldProperties != null) { if (getsOldProperties.oldLabel != null) { label = getsOldProperties.oldLabel.CapitalizeFirst(); } else { Log.Warning("Could not find label for old injury: " + hd.defName); continue; } } // If it's not an old injury, make sure it's one of the available hediffs that can // be added via ScenPart_ForcedHediff. If it's not, filter it out. else { if (!scenPartDefSet.Contains(hd)) { continue; } label = hd.LabelCap; } // Add the injury option. InjuryOption option = new InjuryOption(); option.HediffDef = hd; option.Label = label; if (getsOldProperties != null) { option.IsOldInjury = true; } else { option.ValidParts = new List <BodyPartDef>(); } oldInjuries.Add(option); } // Disambiguate duplicate injury labels. HashSet <string> labels = new HashSet <string>(); HashSet <string> duplicateLabels = new HashSet <string>(); foreach (var option in oldInjuries) { if (labels.Contains(option.Label)) { duplicateLabels.Add(option.Label); } else { labels.Add(option.Label); } } foreach (var option in oldInjuries) { HediffCompProperties props = option.HediffDef.CompPropsFor(typeof(HediffComp_GetsOld)); if (props != null) { if (duplicateLabels.Contains(option.Label)) { string label = "EdB.PrepareCarefully.InjuryLabel".Translate(new string[] { props.oldLabel.CapitalizeFirst(), option.HediffDef.LabelCap }); option.Label = label; } } } // Add old injuries to the full list of injury options options.AddRange(oldInjuries); // Sort by name. options.Sort((InjuryOption x, InjuryOption y) => { return(string.Compare(x.Label, y.Label)); }); }
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); }