public void RandomizeAppearance(CustomPawn customPawn) { Pawn pawn; int tries = 0; do { pawn = GenerateSameKindOfColonist(customPawn); tries++; }while (pawn.gender != customPawn.Gender && tries < 1000); customPawn.HairDef = pawn.story.hairDef; customPawn.SetColor(PawnLayers.Hair, pawn.story.hairColor); customPawn.HeadGraphicPath = pawn.story.HeadGraphicPath; customPawn.MelaninLevel = pawn.story.melanin; for (int i = 0; i < PawnLayers.Count; i++) { if (PawnLayers.IsApparelLayer(i)) { customPawn.SetSelectedStuff(i, null); customPawn.SetSelectedApparel(i, null); } } foreach (Apparel current in pawn.apparel.WornApparel) { int layer = PawnLayers.ToPawnLayerIndex(current.def.apparel); if (layer != -1) { customPawn.SetSelectedStuff(layer, current.Stuff); customPawn.SetSelectedApparel(layer, current.def); } } }
protected int?LayerForApparel(ThingDef def) { if (def.apparel == null) { return(null); } else { return(PawnLayers.ToPawnLayerIndex(def.apparel)); } }
public void SetColor(int layer, Color color) { this.colors[layer] = color; if (PawnLayers.IsApparelLayer(layer)) { colorCache[new EquipmentKey(selectedApparel[layer], selectedStuff[layer])] = color; } if (layer == PawnLayers.BodyType) { SkinColor = color; } else if (layer == PawnLayers.HeadType) { SkinColor = color; } }
protected void ResetBodyType() { BodyType bodyType = pawn.story.BodyType; Graphic bodyTypeGraphic = GraphicGetter_NakedHumanlike.GetNakedBodyGraphic(bodyType, ShaderDatabase.Cutout, pawn.story.SkinColor); graphics[PawnLayers.BodyType] = bodyTypeGraphic; foreach (ThingDef def in selectedApparel) { if (def != null) { int layer = PawnLayers.ToPawnLayerIndex(def.apparel); if (layer != -1) { graphics[layer] = GraphicsCache.Instance.GetApparel(def, bodyType); } } } }
public CustomPawn CreatePawn() { // TODO: Evaluate //Pawn source = PawnGenerator.GeneratePawn(PawnKindDefOf.Colonist, Faction.OfColony); Pawn source = new Randomizer().GenerateColonist(); source.health = new Pawn_HealthTracker(source); CustomPawn pawn = new CustomPawn(source); pawn.Gender = this.gender; if (age > 0) { pawn.ChronologicalAge = age; pawn.BiologicalAge = age; } if (chronologicalAge > 0) { pawn.ChronologicalAge = chronologicalAge; } if (biologicalAge > 0) { pawn.BiologicalAge = biologicalAge; } pawn.FirstName = this.firstName; pawn.NickName = this.nickName; pawn.LastName = this.lastName; HairDef h = FindHairDef(this.hairDef); if (h != null) { pawn.HairDef = h; } pawn.HeadGraphicPath = this.headGraphicPath; pawn.SetColor(PawnLayers.Hair, hairColor); pawn.SetColor(PawnLayers.HeadType, skinColor); Backstory backstory = FindBackstory(childhood); if (backstory != null) { pawn.Childhood = backstory; } backstory = FindBackstory(adulthood); if (backstory != null) { pawn.Adulthood = backstory; } int traitCount = pawn.Traits.Count(); for (int i = 0; i < traitCount; i++) { pawn.ClearTrait(i); } for (int i = 0; i < traitNames.Count; i++) { string traitName = traitNames[i]; if (i >= traitCount) { break; } Trait trait = FindTrait(traitName, traitDegrees[i]); if (trait != null) { pawn.SetTrait(i, trait); } } for (int i = 0; i < this.skillNames.Count; i++) { string name = this.skillNames[i]; SkillDef def = FindSkillDef(pawn.Pawn, name); if (def == null) { continue; } pawn.currentPassions[def] = this.passions[i]; pawn.SetUnmodifiedSkillLevel(def, this.skillValues[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 < this.apparelLayers.Count; i++) { int layer = this.apparelLayers[i]; ThingDef def = DefDatabase <ThingDef> .GetNamedSilentFail(this.apparel[i]); if (def == null) { continue; } ThingDef stuffDef = null; if (!string.IsNullOrEmpty(this.apparelStuff[i])) { stuffDef = DefDatabase <ThingDef> .GetNamedSilentFail(this.apparelStuff[i]); if (stuffDef == null) { continue; } } pawn.SetSelectedApparel(layer, def); pawn.SetSelectedStuff(layer, stuffDef); pawn.SetColor(layer, this.apparelColors[i]); } return(pawn); }
public void CalculatePawnCost(ColonistCostDetails cost, CustomPawn pawn) { cost.Clear(); cost.name = pawn.NickName; // Start with the market value plus a bit of a mark-up. cost.marketValue = pawn.Pawn.MarketValue; cost.marketValue += 300; // Calculate passion cost. Each passion above 8 makes all passions // cost more. Minor passion counts as one passion. Major passion // counts as 3. double skillCount = pawn.currentPassions.Keys.Count(); double passionLevelCount = 0; double passionLevelCost = 20; double passionateSkillCount = 0; foreach (SkillDef def in pawn.currentPassions.Keys) { Passion passion = pawn.currentPassions[def]; int level = pawn.GetSkillLevel(def); if (passion == Passion.Major) { passionLevelCount += 3.0; passionateSkillCount += 1.0; } else if (passion == Passion.Minor) { passionLevelCount += 1.0; passionateSkillCount += 1.0; } } double levelCost = passionLevelCost; if (passionLevelCount > 8) { double penalty = passionLevelCount - 8; levelCost += penalty * 0.4; } cost.marketValue += levelCost * passionLevelCount; // Calculate trait cost. if (pawn.TraitCount > Constraints.MaxVanillaTraits) { int extraTraitCount = pawn.TraitCount - Constraints.MaxVanillaTraits; double extraTraitCost = 100; for (int i = 0; i < extraTraitCount; i++) { cost.marketValue += extraTraitCost; extraTraitCost = Math.Ceiling(extraTraitCost * 2.5); } } // Calculate cost of worn apparel. for (int layer = 0; layer < PawnLayers.Count; layer++) { if (PawnLayers.IsApparelLayer(layer)) { var def = pawn.GetAcceptedApparel(layer); if (def == null) { continue; } EquipmentKey key = new EquipmentKey(); key.ThingDef = def; key.StuffDef = pawn.GetSelectedStuff(layer); EquipmentRecord record = PrepareCarefully.Instance.EquipmentDatabase.Find(key); if (record == null) { continue; } EquipmentSelection selection = new EquipmentSelection(record, 1); double c = CalculateEquipmentCost(selection); if (def != null) { // TODO: Discounted materials should be based on the faction, not hard-coded. // TODO: Should we continue with the discounting? if (key.StuffDef != null) { if (key.StuffDef.defName == "Synthread") { if (freeApparel.Contains(key.ThingDef.defName)) { c = 0; } else if (cheapApparel.Contains(key.ThingDef.defName)) { c = c * 0.15d; } } } } cost.apparel += c; } } // Calculate cost for any materials needed for implants. OptionsHealth healthOptions = PrepareCarefully.Instance.Providers.Health.GetOptions(pawn); foreach (Implant option in pawn.Implants) { // Check if there are any ancestor parts that override the selection. UniqueBodyPart uniquePart = healthOptions.FindBodyPartsForRecord(option.BodyPartRecord); if (uniquePart == null) { Log.Warning("Prepare Carefully could not find body part record when computing the cost of an implant: " + option.BodyPartRecord.def.defName); continue; } if (pawn.AtLeastOneImplantedPart(uniquePart.Ancestors.Select((UniqueBodyPart p) => { return(p.Record); }))) { continue; } // Figure out the cost of the part replacement based on its recipe's ingredients. if (option.recipe != null) { RecipeDef def = option.recipe; foreach (IngredientCount amount in def.ingredients) { int count = 0; double totalCost = 0; bool skip = false; foreach (ThingDef ingredientDef in amount.filter.AllowedThingDefs) { if (ingredientDef == ThingDefOf.Medicine) { skip = true; break; } count++; EquipmentRecord entry = PrepareCarefully.Instance.EquipmentDatabase[new EquipmentKey(ingredientDef, null)]; if (entry != null) { totalCost += entry.cost * (double)amount.GetBaseCount(); } } if (skip || count == 0) { continue; } cost.bionics += (int)(totalCost / (double)count); } } } cost.apparel = Math.Ceiling(cost.apparel); cost.bionics = Math.Ceiling(cost.bionics); // Use a multiplier to balance pawn cost vs. equipment cost. // Disabled for now. cost.Multiply(1.0); cost.ComputeTotal(); }
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); }
protected override void DrawPanelContent(State state) { base.DrawPanelContent(state); CustomPawn customPawn = state.CurrentPawn; string label = PawnLayers.Label(this.selectedPawnLayer); if (WidgetDropdown.Button(RectLayerSelector, label, true, false, true)) { List <FloatMenuOption> list = new List <FloatMenuOption>(); int layerCount = this.pawnLayerActions.Count; for (int i = 0; i < layerCount; i++) { int pawnLayer = pawnLayers[i]; label = PawnLayers.Label(pawnLayers[i]); list.Add(new FloatMenuOption(label, this.pawnLayerActions[i], MenuOptionPriority.Default, null, null, 0, null, null)); } 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; // Conflict alert 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, 28); Action previousSelectionAction = null; Action nextSelectionAction = null; Action clickAction = null; OptionsApparel apparelOptions = null; List <ThingDef> apparelList = null; OptionsHair hairOptions = null; List <HairDef> hairList = null; if (this.selectedPawnLayer == PawnLayers.Hair) { hairOptions = PrepareCarefully.Instance.Providers.Hair.GetHairsForRace(customPawn); hairList = hairOptions.GetHairs(customPawn.Gender); } else if (PawnLayers.IsApparelLayer(this.selectedPawnLayer)) { apparelOptions = PrepareCarefully.Instance.Providers.Apparel.GetApparelForRace(customPawn); apparelList = apparelOptions.GetApparel(this.selectedPawnLayer); } if (this.selectedPawnLayer == PawnLayers.HeadType) { int headTypeCount = PrepareCarefully.Instance.Providers.HeadTypes.GetHeadTypes(customPawn).Count(); if (customPawn.HeadType != null && headTypeCount > 1) { previousSelectionAction = () => { SoundDefOf.TickTiny.PlayOneShotOnCamera(); SelectNextHead(customPawn, -1); }; nextSelectionAction = () => { SoundDefOf.TickTiny.PlayOneShotOnCamera(); SelectNextHead(customPawn, 1); }; } if (customPawn.HeadType != null && headTypeCount > 0) { clickAction = () => { ShowHeadDialog(customPawn); }; } } else if (this.selectedPawnLayer == PawnLayers.BodyType) { if (PrepareCarefully.Instance.Providers.BodyTypes.GetBodyTypesForPawn(customPawn.Pawn).Count > 1) { previousSelectionAction = () => { SoundDefOf.TickTiny.PlayOneShotOnCamera(); SelectNextBodyType(customPawn, -1); }; nextSelectionAction = () => { SoundDefOf.TickTiny.PlayOneShotOnCamera(); SelectNextBodyType(customPawn, 1); }; } clickAction = () => { ShowBodyTypeDialog(customPawn); }; } else if (this.selectedPawnLayer == PawnLayers.Hair) { if (hairList.Count > 1) { previousSelectionAction = () => { SoundDefOf.TickTiny.PlayOneShotOnCamera(); SelectNextHair(customPawn, -1); }; nextSelectionAction = () => { SoundDefOf.TickTiny.PlayOneShotOnCamera(); SelectNextHair(customPawn, 1); }; } if (hairList.Count > 0) { clickAction = () => { ShowHairDialog(customPawn); }; } } else { if (apparelList.Count > 1) { previousSelectionAction = () => { SoundDefOf.TickTiny.PlayOneShotOnCamera(); SelectNextApparel(customPawn, -1); }; nextSelectionAction = () => { SelectNextApparel(customPawn, 1); SoundDefOf.TickTiny.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.y + 34; // Draw stuff selector for apparel if (PawnLayers.IsApparelLayer(this.selectedPawnLayer)) { ThingDef apparelDef = customPawn.GetSelectedApparel(selectedPawnLayer); if (apparelDef != null && apparelDef.MadeFromStuff) { if (customPawn.GetSelectedStuff(selectedPawnLayer) == null) { Log.Error("Selected stuff for " + PawnLayers.ToApparelLayer(selectedPawnLayer) + " 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 (PawnLayers.IsApparelLayer(selectedPawnLayer)) { 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 == PawnLayers.BodyType || selectedPawnLayer == PawnLayers.HeadType) { AlienRace alienRace = customPawn.AlienRace; if (alienRace == null || alienRace.UseMelaninLevels) { DrawHumanlikeColorSelector(customPawn, cursorY); } else { DrawAlienPawnColorSelector(customPawn, cursorY, alienRace.PrimaryColors, true); } } else if (selectedPawnLayer == PawnLayers.Hair) { if (hairList != null && hairList.Count > 0) { DrawColorSelector(customPawn, cursorY, hairOptions.Colors, 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.TickLow.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.TickTiny.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.TickTiny.PlayOneShotOnCamera(); GenderUpdated(Gender.Male); } } GUI.color = Color.white; }
public void CalculatePawnCost(ColonistCostDetails cost, CustomPawn pawn) { cost.Clear(); cost.name = pawn.NickName; // Start with the market value plus a bit of a mark-up. cost.marketValue = pawn.Pawn.MarketValue; cost.marketValue += 300; // Reduce cost if random injuries have been chosen. if (pawn.RandomInjuries) { float ageMultiplier = pawn.BiologicalAge; if (ageMultiplier > 100) { ageMultiplier = 100; } float injuryValue = Mathf.Pow(ageMultiplier, 1.177455f); injuryValue = injuryValue / 10f; injuryValue = Mathf.Floor(injuryValue) * 10f; cost.marketValue -= injuryValue; } // Calculate passion cost. Each passion above 8 makes all passions // cost more. Minor passion counts as one passion. Major passion // counts as 3. double skillCount = pawn.currentPassions.Keys.Count(); double passionLevelCount = 0; double passionLevelCost = 20; double passionateSkillCount = 0; foreach (SkillDef def in pawn.currentPassions.Keys) { Passion passion = pawn.currentPassions[def]; int level = pawn.GetSkillLevel(def); if (passion == Passion.Major) { passionLevelCount += 3.0; passionateSkillCount += 1.0; } else if (passion == Passion.Minor) { passionLevelCount += 1.0; passionateSkillCount += 1.0; } } double levelCost = passionLevelCost; if (passionLevelCount > 8) { double penalty = passionLevelCount - 8; levelCost += penalty * 0.4; } cost.marketValue += levelCost * passionLevelCount; // Calculat cost of worn apparel. for (int layer = 0; layer < PawnLayers.Count; layer++) { if (PawnLayers.IsApparelLayer(layer)) { var def = pawn.GetAcceptedApparel(layer); SelectedEquipment customPawn = new SelectedEquipment(); customPawn.def = def; customPawn.count = 1; if (def != null) { var stuff = pawn.GetSelectedStuff(layer); customPawn.stuffDef = stuff; } double c = CalculateEquipmentCost(customPawn); if (def != null) { if (customPawn.stuffDef != null) { if (customPawn.stuffDef.defName == "Synthread") { if (freeApparel.Contains(customPawn.def.defName)) { c = 0; } else if (cheapApparel.Contains(customPawn.def.defName)) { c = c * 0.15d; } } } } cost.apparel += c; } } // Calculate cost for any materials needed for implants. foreach (Implant option in pawn.Implants) { // Check if there are any ancestor parts that override the selection. if (PrepareCarefully.Instance.HealthManager.ImplantManager.AncestorIsImplant(pawn, option.BodyPartRecord)) { continue; } // Figure out the cost of the part replacement based on its recipe's ingredients. if (option.recipe != null) { RecipeDef def = option.recipe; foreach (IngredientCount amount in def.ingredients) { int count = 0; double totalCost = 0; bool skip = false; foreach (ThingDef ingredientDef in amount.filter.AllowedThingDefs) { if (ingredientDef == ThingDefOf.Medicine) { skip = true; break; } count++; EquipmentDatabaseEntry entry = PrepareCarefully.Instance.EquipmentEntries[new EquipmentKey(ingredientDef, null)]; if (entry != null) { totalCost += entry.cost * (double)amount.GetBaseCount(); } } if (skip || count == 0) { continue; } cost.bionics += (int)(totalCost / (double)count); } } } cost.apparel = Math.Ceiling(cost.apparel); cost.bionics = Math.Ceiling(cost.bionics); // Use a multiplier to balance pawn cost vs. equipment cost. // Disabled for now. cost.Multiply(1.0); cost.ComputeTotal(); }
protected void ApparelAcceptanceTest() { // Clear out any conflicts from a previous check. apparelConflicts.Clear(); // Assume that each peice of apparel will be accepted. for (int i = PawnLayers.TopClothingLayer; i >= PawnLayers.BottomClothingLayer; i--) { this.acceptedApparel[i] = this.selectedApparel[i]; } // Go through each layer. for (int i = PawnLayers.TopClothingLayer; i >= PawnLayers.BottomClothingLayer; i--) { // If no apparel was selected for this layer, go to the next layer. if (selectedApparel[i] == null) { continue; } ThingDef apparel = selectedApparel[i]; if (apparel.apparel != null && apparel.apparel.layers != null && apparel.apparel.layers.Count > 1) { foreach (ApparelLayer layer in apparel.apparel.layers) { // If the apparel's layer matches the current layer, go to the apparel's next layer. if (layer == PawnLayers.ToApparelLayer(i)) { continue; } // If the apparel covers another layer as well as the current one, check to see // if the user has selected another piece of apparel for that layer. If so, check // to see if it covers any of the same body parts. If it does, it's a conflict. int disallowedLayer = PawnLayers.ToPawnLayerIndex(layer); if (this.selectedApparel[disallowedLayer] != null) { foreach (var group in this.selectedApparel[disallowedLayer].apparel.bodyPartGroups) { if (apparel.apparel.bodyPartGroups.Contains(group)) { ApparelConflict conflict = new ApparelConflict(); conflict.def = selectedApparel[i]; conflict.conflict = selectedApparel[disallowedLayer]; apparelConflicts.Add(conflict); this.acceptedApparel[disallowedLayer] = null; break; } } } } } } if (apparelConflicts.Count > 0) { HashSet <ThingDef> defs = new HashSet <ThingDef>(); foreach (ApparelConflict conflict in apparelConflicts) { defs.Add(conflict.def); } List <ThingDef> sortedDefs = new List <ThingDef>(defs); sortedDefs.Sort((ThingDef a, ThingDef b) => { int c = PawnLayers.ToPawnLayerIndex(a.apparel); int d = PawnLayers.ToPawnLayerIndex(b.apparel); if (c > d) { return(-1); } else if (c < d) { return(1); } else { return(0); } }); StringBuilder builder = new StringBuilder(); int index = 0; foreach (ThingDef def in sortedDefs) { string label = def.label; string message = "EdB.ApparelConflictDescription".Translate(); message = message.Replace("{0}", label); builder.Append(message); builder.AppendLine(); foreach (ApparelConflict conflict in apparelConflicts.FindAll((ApparelConflict c) => { return(c.def == def); })) { builder.Append("EdB.ApparelConflictLineItem".Translate().Replace("{0}", conflict.conflict.label)); builder.AppendLine(); } if (++index < sortedDefs.Count) { builder.AppendLine(); } } this.apparelConflictText = builder.ToString(); } else { this.apparelConflictText = null; } }
public void InitializeWithPawn(Pawn pawn) { this.pawn = this.CopyPawn(pawn); this.birthTicks = this.pawn.ageTracker.BirthAbsTicks % 3600000L; // Set the traits. this.traits.Clear(); for (int i = 0; i < TraitCount; i++) { this.traits.Add(null); } List <Trait> pawnTraits = pawn.story.traits.allTraits; if (pawnTraits.Count > 0) { this.traits[0] = pawnTraits[0]; } if (pawnTraits.Count > 1 && this.traits[0] != pawnTraits[1]) { this.traits[1] = pawnTraits[1]; } if (pawnTraits.Count > 2 && this.traits[0] != pawnTraits[2] && this.traits[1] != pawnTraits[2]) { this.traits[2] = pawnTraits[2]; } // Set the skills. InitializeSkillLevelsAndPassions(); ComputeSkillLevelModifiers(); graphics.Clear(); colors.Clear(); PawnGraphicSet pawnGraphics = pawn.Drawer.renderer.graphics; graphics.Add(GraphicGetter_NakedHumanlike.GetNakedBodyGraphic(pawn.story.BodyType, ShaderDatabase.CutoutSkin, pawn.story.SkinColor)); colors.Add(pawn.story.SkinColor); graphics.Add(null); colors.Add(Color.white); graphics.Add(null); colors.Add(Color.white); graphics.Add(null); colors.Add(Color.white); graphics.Add(null); colors.Add(Color.white); graphics.Add(GraphicDatabaseHeadRecords.GetHeadNamed(pawn.story.HeadGraphicPath, pawn.story.SkinColor)); colors.Add(pawn.story.SkinColor); ResetHead(); graphics.Add(GraphicsCache.Instance.GetHair(pawn.story.hairDef)); colors.Add(pawn.story.hairColor); graphics.Add(null); colors.Add(Color.white); graphics.Add(null); colors.Add(Color.white); for (int i = 0; i < PawnLayers.Count; i++) { selectedApparel.Add(null); acceptedApparel.Add(null); selectedStuff.Add(null); } foreach (Apparel current in this.pawn.apparel.WornApparel) { Graphic graphic = GraphicsCache.Instance.GetApparel(current.def, pawn.story.BodyType); Color color = current.DrawColor; int layer = PawnLayers.ToPawnLayerIndex(current.def.apparel); if (layer != -1) { graphics[layer] = graphic; SetSelectedApparel(layer, current.def); acceptedApparel[layer] = current.def; SetSelectedStuff(layer, current.Stuff); if (ApparelIsTintedByDefault(current.def, current.Stuff)) { SetColor(layer, color); } } } ResetIncapableOf(); pawn.health.capacities.Clear(); }
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.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); 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. 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; } 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]; if (name == "Research") { name = "Intellectual"; } 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]); } 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) { 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) { 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); }