protected void Select(CustomFaction faction) { this.SelectedFaction = faction; if (SelectAction != null) { SelectAction(faction); } }
protected void AddPawnToWorld(CustomPawn pawn) { // Don't add colonists to the world. if (pawn.Type == CustomPawnType.Colonist) { return; } // If we have a custom faction setting, handle that. CustomFaction randomFaction = PrepareCarefully.Instance.Providers.Factions.RandomFaction; if (pawn.Faction != null && pawn.Faction != PrepareCarefully.Instance.Providers.Factions.RandomFaction) { // If they are assigned to a specific faction, assign them either as a leader or as a regular pawn. if (pawn.Faction.Faction != null) { if (pawn.Faction.Leader) { MakePawnIntoFactionLeader(pawn); } try { pawn.Pawn.SetFaction(pawn.Faction.Faction, null); } catch (Exception) { Logger.Warning("Failed to add a world pawn to the expected faction"); } } // If they are assigned to a random faction of a specific def, choose the random faction and assign it. else { try { Faction faction = PrepareCarefully.Instance.Providers.Factions.GetFactions(pawn.Faction.Def).RandomElement(); pawn.Pawn.SetFaction(pawn.Faction.Faction, null); } catch (Exception) { Logger.Warning("Failed to add a world pawn to the expected faction"); } } } // If they are assigned to a completely random faction, set their faction to null. It will get reassigned automatically. else { pawn.Pawn.SetFactionDirect(null); } // Don't add pawns to the world if they have already been added. if (Find.World.worldPawns.Contains(pawn.Pawn) || Find.GameInitData.startingAndOptionalPawns.Contains(pawn.Pawn)) { return; } else { Find.GameInitData.startingAndOptionalPawns.Add(pawn.Pawn); } }
public void AddCustomFaction(CustomFaction customFaction) { if (customFaction.Def == null) { return; } if (customFaction.Index == null) { return; } int count; if (factionCounts.TryGetValue(customFaction.Def, out count)) { if (count <= customFaction.Index) { customFactions.Add(customFaction); } } }
protected void ShowFactionDialog(CustomPawn pawn) { CustomFaction selectedFaction = pawn.Faction != null ? pawn.Faction : PrepareCarefully.Instance.Providers.Factions.RandomFaction; HashSet <CustomFaction> disabled = new HashSet <CustomFaction>(); rowGroups.Clear(); rowGroups.Add(new WidgetTable <CustomFaction> .RowGroup("<b>" + "EdB.PC.Dialog.Faction.SelectRandomFaction".Translate() + "</b>", providerFactions.RandomCustomFactions)); rowGroups.Add(new WidgetTable <CustomFaction> .RowGroup("<b>" + "EdB.PC.Dialog.Faction.SelectSpecificFaction".Translate() + "</b>", providerFactions.SpecificCustomFactions)); rowGroups.Add(new WidgetTable <CustomFaction> .RowGroup("<b>" + "EdB.PC.Dialog.Faction.SelectLeaderFaction".Translate() + "</b>", providerFactions.LeaderCustomFactions)); DialogFactions factionDialog = new DialogFactions() { HeaderLabel = "EdB.PC.Dialog.Faction.ChooseFaction".Translate(), SelectAction = (CustomFaction faction) => { selectedFaction = faction; }, RowGroups = rowGroups, DisabledFactions = disabled, CloseAction = () => { pawn.Faction = selectedFaction; }, SelectedFaction = selectedFaction }; factionDialog.ScrollTo(selectedFaction); Find.WindowStack.Add(factionDialog); }
public void AddFactionPawn(PawnKindDef kindDef, bool startingPawn) { FactionDef factionDef = kindDef.defaultFactionType; Faction faction = PrepareCarefully.Instance.Providers.Factions.GetFaction(factionDef); // Workaround to force pawn generation to skip adding weapons to the pawn. // Might be a slightly risky hack, but the finally block should guarantee that // the weapons money range always gets set back to its original value. // TODO: Try to remove this at a later date. It would be nice if the pawn generation // request gave you an option to skip weapon and equipment generation. FloatRange savedWeaponsMoney = kindDef.weaponMoney; kindDef.weaponMoney = new FloatRange(0, 0); Pawn pawn = null; try { pawn = randomizer.GeneratePawn(new PawnGenerationRequestWrapper() { Faction = faction, KindDef = kindDef, Context = PawnGenerationContext.NonPlayer, WorldPawnFactionDoesntMatter = true }.Request); if (pawn.equipment != null) { pawn.equipment.DestroyAllEquipment(DestroyMode.Vanish); } if (pawn.inventory != null) { pawn.inventory.DestroyAll(DestroyMode.Vanish); } } catch (Exception e) { Log.Warning("Failed to create faction pawn of kind " + kindDef.defName); Log.Message(e.Message); Log.Message(e.StackTrace); if (pawn != null) { pawn.Destroy(); } state.AddError("EdB.PC.Panel.PawnList.Error.FactionPawnFailed".Translate()); return; } finally { kindDef.weaponMoney = savedWeaponsMoney; } // Reset the quality and damage of all apparel. foreach (var a in pawn.apparel.WornApparel) { a.SetQuality(QualityCategory.Normal); a.HitPoints = a.MaxHitPoints; } CustomPawn customPawn = new CustomPawn(pawn); customPawn.Type = startingPawn ? CustomPawnType.Colonist : CustomPawnType.World; if (!startingPawn) { CustomFaction customFaction = PrepareCarefully.Instance.Providers.Factions.FindRandomCustomFactionByDef(factionDef); if (customFaction != null) { customPawn.Faction = customFaction; } } PrepareCarefully.Instance.AddPawn(customPawn); state.CurrentPawn = customPawn; PawnAdded(customPawn); }
public override void DoWindowContents(Rect inRect) { if (resizeDirtyFlag) { Resize(); } if (scrollTo != null) { table.ScrollTo(scrollTo); scrollTo = null; } GUI.color = Color.white; Text.Font = GameFont.Medium; if (HeaderLabel != null) { Widgets.Label(HeaderRect, HeaderLabel); } Text.Font = GameFont.Small; GUI.BeginGroup(ContentRect); try { if (RowGroups != null) { table.Draw(RowGroups); } else { table.Draw(Pawns); } } finally { GUI.EndGroup(); GUI.color = Color.white; } GUI.BeginGroup(FooterRect); try { Rect buttonRect = SingleButtonRect; if (CancelButtonLabel != null) { if (Widgets.ButtonText(CancelButtonRect, CancelButtonLabel.Translate(), true, true, true)) { this.Close(true); } buttonRect = ConfirmButtonRect; } if (Widgets.ButtonText(buttonRect, ConfirmButtonLabel.Translate(), true, true, true)) { string validationMessage = ConfirmValidation(); if (validationMessage != null) { Messages.Message(validationMessage.Translate(), MessageTypeDefOf.RejectInput); } else { this.Confirm(); } } } finally { GUI.EndGroup(); } }
public void ScrollTo(CustomFaction customFaction) { scrollTo = customFaction; }
public CustomPawn LoadPawn(SaveRecordPawnV4 record) { PawnKindDef pawnKindDef = null; if (record.pawnKindDef != null) { pawnKindDef = DefDatabase <PawnKindDef> .GetNamedSilentFail(record.pawnKindDef); if (pawnKindDef == null) { Log.Warning("Prepare Carefully could not find the pawn kind definition for the saved character: \"" + record.pawnKindDef + "\""); return(null); } } ThingDef pawnThingDef = ThingDefOf.Human; if (record.thingDef != null) { ThingDef thingDef = DefDatabase <ThingDef> .GetNamedSilentFail(record.thingDef); if (thingDef != null) { pawnThingDef = thingDef; } } PawnGenerationRequestWrapper generationRequest = new PawnGenerationRequestWrapper() { FixedBiologicalAge = record.biologicalAge, FixedChronologicalAge = record.chronologicalAge, FixedGender = record.gender }; if (pawnKindDef != null) { generationRequest.KindDef = pawnKindDef; } Pawn source = PawnGenerator.GeneratePawn(generationRequest.Request); if (source.health != null) { source.health.Reset(); } CustomPawn pawn = new CustomPawn(source); if (record.id == null) { pawn.GenerateId(); } else { pawn.Id = record.id; } if (record.type != null) { try { pawn.Type = (CustomPawnType)Enum.Parse(typeof(CustomPawnType), record.type); } catch (Exception) { pawn.Type = CustomPawnType.Colonist; } } else { pawn.Type = CustomPawnType.Colonist; } pawn.Gender = record.gender; if (record.age > 0) { pawn.ChronologicalAge = record.age; pawn.BiologicalAge = record.age; } if (record.chronologicalAge > 0) { pawn.ChronologicalAge = record.chronologicalAge; } if (record.biologicalAge > 0) { pawn.BiologicalAge = record.biologicalAge; } pawn.FirstName = record.firstName; pawn.NickName = record.nickName; pawn.LastName = record.lastName; if (record.originalFactionDef != null) { pawn.OriginalFactionDef = DefDatabase <FactionDef> .GetNamedSilentFail(record.originalFactionDef); } pawn.OriginalKindDef = pawnKindDef; if (pawn.Type == CustomPawnType.World) { if (record.faction != null) { if (record.faction.def != null) { FactionDef factionDef = DefDatabase <FactionDef> .GetNamedSilentFail(record.faction.def); if (factionDef != null) { bool randomFaction = false; if (record.faction.index != null) { CustomFaction customFaction = null; if (!record.faction.leader) { customFaction = PrepareCarefully.Instance.Providers.Factions.FindCustomFactionByIndex(factionDef, record.faction.index.Value); } else { customFaction = PrepareCarefully.Instance.Providers.Factions.FindCustomFactionWithLeaderOptionByIndex(factionDef, record.faction.index.Value); } if (customFaction != null) { pawn.Faction = customFaction; } else { Log.Warning("Prepare Carefully could not place at least one preset character into a saved faction because there were not enough available factions of that type in the world"); randomFaction = true; } } else { randomFaction = true; } if (randomFaction) { CustomFaction customFaction = PrepareCarefully.Instance.Providers.Factions.FindRandomCustomFactionByDef(factionDef); if (customFaction != null) { pawn.Faction = customFaction; } } } else { Log.Warning("Prepare Carefully could not place at least one preset character into a saved faction because that faction is not available in the world"); } } } } HairDef h = FindHairDef(record.hairDef); if (h != null) { pawn.HairDef = h; } else { Log.Warning("Could not load hair definition \"" + record.hairDef + "\""); Failed = true; } pawn.HeadGraphicPath = record.headGraphicPath; if (pawn.Pawn.story != null) { pawn.Pawn.story.hairColor = record.hairColor; } if (record.melanin >= 0.0f) { pawn.MelaninLevel = record.melanin; } else { pawn.MelaninLevel = PawnColorUtils.FindMelaninValueFromColor(record.skinColor); } // Set the skin color for Alien Races and alien comp values. if (pawn.AlienRace != null) { pawn.SkinColor = record.skinColor; if (record.alien != null) { ThingComp alienComp = ProviderAlienRaces.FindAlienCompForPawn(pawn.Pawn); if (alienComp != null) { ProviderAlienRaces.SetCrownTypeOnComp(alienComp, record.alien.crownType); ProviderAlienRaces.SetSkinColorOnComp(alienComp, record.alien.skinColor); ProviderAlienRaces.SetSkinColorSecondOnComp(alienComp, record.alien.skinColorSecond); ProviderAlienRaces.SetHairColorSecondOnComp(alienComp, record.alien.hairColorSecond); } } } Backstory backstory = FindBackstory(record.childhood); if (backstory != null) { pawn.Childhood = backstory; } else { Log.Warning("Could not load childhood backstory definition \"" + record.childhood + "\""); Failed = true; } if (record.adulthood != null) { backstory = FindBackstory(record.adulthood); if (backstory != null) { pawn.Adulthood = backstory; } else { Log.Warning("Could not load adulthood backstory definition \"" + record.adulthood + "\""); Failed = true; } } BodyTypeDef bodyType = null; try { bodyType = DefDatabase <BodyTypeDef> .GetNamedSilentFail(record.bodyType); } catch (Exception) { } if (bodyType == null) { if (pawn.Adulthood != null) { bodyType = pawn.Adulthood.BodyTypeFor(pawn.Gender); } else { bodyType = pawn.Childhood.BodyTypeFor(pawn.Gender); } } if (bodyType != null) { pawn.BodyType = bodyType; } pawn.ClearTraits(); for (int i = 0; i < record.traitNames.Count; i++) { string traitName = record.traitNames[i]; Trait trait = FindTrait(traitName, record.traitDegrees[i]); if (trait != null) { pawn.AddTrait(trait); } else { Log.Warning("Could not load trait definition \"" + traitName + "\""); Failed = true; } } foreach (var skill in record.skills) { SkillDef def = FindSkillDef(pawn.Pawn, skill.name); if (def == null) { Log.Warning("Could not load skill definition \"" + skill.name + "\" from saved preset"); Failed = true; continue; } pawn.currentPassions[def] = skill.passion; pawn.originalPassions[def] = skill.passion; pawn.SetOriginalSkillLevel(def, skill.value); pawn.SetUnmodifiedSkillLevel(def, skill.value); } foreach (var layer in PrepareCarefully.Instance.Providers.PawnLayers.GetLayersForPawn(pawn)) { if (layer.Apparel) { pawn.SetSelectedApparel(layer, null); pawn.SetSelectedStuff(layer, null); } } List <PawnLayer> apparelLayers = PrepareCarefully.Instance.Providers.PawnLayers.GetLayersForPawn(pawn).FindAll((layer) => { return(layer.Apparel); }); foreach (var apparelRecord in record.apparel) { // Find the pawn layer for the saved apparel record. PawnLayer layer = apparelLayers.FirstOrDefault((apparelLayer) => { return(apparelLayer.Name == apparelRecord.layer); }); if (layer == null) { Log.Warning("Could not find a matching pawn layer for the saved apparel \"" + apparelRecord.layer + "\""); Failed = true; continue; } if (apparelRecord.apparel.NullOrEmpty()) { Log.Warning("Saved apparel entry for layer \"" + apparelRecord.layer + "\" had an empty apparel def"); Failed = true; continue; } // Set the defaults. pawn.SetSelectedApparel(layer, null); pawn.SetSelectedStuff(layer, null); pawn.SetColor(layer, Color.white); ThingDef def = DefDatabase <ThingDef> .GetNamedSilentFail(apparelRecord.apparel); if (def == null) { Log.Warning("Could not load thing definition for apparel \"" + apparelRecord.apparel + "\""); Failed = true; continue; } ThingDef stuffDef = null; if (!string.IsNullOrEmpty(apparelRecord.stuff)) { stuffDef = DefDatabase <ThingDef> .GetNamedSilentFail(apparelRecord.stuff); if (stuffDef == null) { Log.Warning("Could not load stuff definition \"" + apparelRecord.stuff + "\" for apparel \"" + apparelRecord.apparel + "\""); Failed = true; continue; } } pawn.SetSelectedApparel(layer, def); pawn.SetSelectedStuff(layer, stuffDef); pawn.SetColor(layer, apparelRecord.color); } OptionsHealth healthOptions = PrepareCarefully.Instance.Providers.Health.GetOptions(pawn); for (int i = 0; i < record.implants.Count; i++) { SaveRecordImplantV3 implantRecord = record.implants[i]; UniqueBodyPart uniqueBodyPart = healthOptions.FindBodyPartByName(implantRecord.bodyPart, implantRecord.bodyPartIndex != null ? implantRecord.bodyPartIndex.Value : 0); if (uniqueBodyPart == null) { uniqueBodyPart = FindReplacementBodyPart(healthOptions, implantRecord.bodyPart); } if (uniqueBodyPart == null) { Log.Warning("Prepare Carefully could not add the implant because it could not find the needed body part \"" + implantRecord.bodyPart + "\"" + (implantRecord.bodyPartIndex != null ? " with index " + implantRecord.bodyPartIndex : "")); Failed = true; continue; } BodyPartRecord bodyPart = uniqueBodyPart.Record; if (implantRecord.recipe != null) { RecipeDef recipeDef = FindRecipeDef(implantRecord.recipe); if (recipeDef == null) { Log.Warning("Prepare Carefully could not add the implant because it could not find the recipe definition \"" + implantRecord.recipe + "\""); Failed = true; continue; } bool found = false; foreach (var p in recipeDef.appliedOnFixedBodyParts) { if (p.defName.Equals(bodyPart.def.defName)) { found = true; break; } } if (!found) { Log.Warning("Prepare carefully could not apply the saved implant recipe \"" + implantRecord.recipe + "\" to the body part \"" + bodyPart.def.defName + "\". Recipe does not support that part."); Failed = true; continue; } Implant implant = new Implant(); implant.BodyPartRecord = bodyPart; implant.recipe = recipeDef; implant.label = implant.Label; pawn.AddImplant(implant); } } foreach (var injuryRecord in record.injuries) { HediffDef def = DefDatabase <HediffDef> .GetNamedSilentFail(injuryRecord.hediffDef); if (def == null) { Log.Warning("Prepare Carefully could not add the injury because it could not find the hediff definition \"" + injuryRecord.hediffDef + "\""); Failed = true; continue; } InjuryOption option = healthOptions.FindInjuryOptionByHediffDef(def); if (option == null) { Log.Warning("Prepare Carefully could not add the injury because it could not find a matching injury option for the saved hediff \"" + injuryRecord.hediffDef + "\""); Failed = true; continue; } BodyPartRecord bodyPart = null; if (injuryRecord.bodyPart != null) { UniqueBodyPart uniquePart = healthOptions.FindBodyPartByName(injuryRecord.bodyPart, injuryRecord.bodyPartIndex != null ? injuryRecord.bodyPartIndex.Value : 0); if (uniquePart == null) { uniquePart = FindReplacementBodyPart(healthOptions, injuryRecord.bodyPart); } if (uniquePart == null) { Log.Warning("Prepare Carefully could not add the injury because it could not find the needed body part \"" + injuryRecord.bodyPart + "\"" + (injuryRecord.bodyPartIndex != null ? " with index " + injuryRecord.bodyPartIndex : "")); Failed = true; continue; } bodyPart = uniquePart.Record; } Injury injury = new Injury(); injury.Option = option; injury.BodyPartRecord = bodyPart; if (injuryRecord.severity != null) { injury.Severity = injuryRecord.Severity; } if (injuryRecord.painFactor != null) { injury.PainFactor = injuryRecord.PainFactor; } pawn.AddInjury(injury); } pawn.CopySkillsAndPassionsToPawn(); pawn.ClearPawnCaches(); return(pawn); }
protected override void DrawPanelContent(State state) { base.DrawPanelContent(state); CustomPawn customPawn = state.CurrentPawn; if (currentPawn != state.CurrentPawn) { ChangePawn(state.CurrentPawn); } if (currentPawnLayers == null) { UpdatePawnLayers(); } string label = this.selectedPawnLayer.Label; if (WidgetDropdown.Button(RectLayerSelector, label, true, false, true)) { List <FloatMenuOption> list = new List <FloatMenuOption>(); int layerCount = this.pawnLayerActions.Count; int i = 0; foreach (var layer in currentPawnLayers) { label = layer.Label; list.Add(new FloatMenuOption(label, this.pawnLayerActions[i], MenuOptionPriority.Default, null, null, 0, null, null)); i++; } Find.WindowStack.Add(new FloatMenu(list, null, false)); } GUI.DrawTexture(RectPortrait, Textures.TexturePortraitBackground); customPawn.UpdatePortrait(); DrawPawn(customPawn, RectPortrait); GUI.color = ColorPortraitBorder; Widgets.DrawBox(RectPortrait, 1); GUI.color = Color.white; // Draw world pawn alert if (state.CurrentPawn.Type == CustomPawnType.World && this.selectedPawnLayer.Apparel) { CustomFaction faction = state.CurrentPawn.Faction; if (faction == null || !faction.Leader) { Rect alertRect = new Rect(RectPortrait.x + 77, RectPortrait.y + 150, 36, 32); GUI.DrawTexture(alertRect, Textures.TextureAlert); TooltipHandler.TipRegion(alertRect, "EdB.PC.Panel.Appearance.WorldPawnAlert".Translate()); } } // Apparel conflict alert else if (customPawn.ApparelConflict != null) { GUI.color = Color.white; Rect alertRect = new Rect(RectPortrait.x + 77, RectPortrait.y + 150, 36, 32); GUI.DrawTexture(alertRect, Textures.TextureAlert); TooltipHandler.TipRegion(alertRect, customPawn.ApparelConflict); } // Draw selector field. Rect fieldRect = new Rect(RectPortrait.x, RectPortrait.y + RectPortrait.height + 5, RectPortrait.width, 40); Action previousSelectionAction = null; Action nextSelectionAction = null; Action clickAction = null; OptionsApparel apparelOptions = null; List <ThingDef> apparelList = null; if (this.selectedPawnLayer.Apparel) { apparelOptions = PrepareCarefully.Instance.Providers.Apparel.GetApparelForRace(customPawn); apparelList = apparelOptions.GetApparel(this.selectedPawnLayer); } if (this.selectedPawnLayer.Options != null) { if (this.selectedPawnLayer.Options.Count > 1) { previousSelectionAction = () => { SoundDefOf.Tick_Tiny.PlayOneShotOnCamera(); SelectNextPawnLayerOption(customPawn, -1); }; nextSelectionAction = () => { SoundDefOf.Tick_Tiny.PlayOneShotOnCamera(); SelectNextPawnLayerOption(customPawn, 1); }; } if (this.selectedPawnLayer.Options.Count > 0) { clickAction = () => { ShowPawnLayerOptionsDialog(customPawn); }; } } else { if (apparelList.Count > 1) { previousSelectionAction = () => { SoundDefOf.Tick_Tiny.PlayOneShotOnCamera(); SelectNextApparel(customPawn, -1); }; nextSelectionAction = () => { SelectNextApparel(customPawn, 1); SoundDefOf.Tick_Tiny.PlayOneShotOnCamera(); }; } if (apparelList.Count > 0) { clickAction = () => { ShowApparelDialog(customPawn, this.selectedPawnLayer); }; } } string selectorLabel = PawnLayerLabel.CapitalizeFirst(); //if (hairList != null && hairList.Count == 0) { // selectorLabel = "EdB.PC.Common.NoOptionAvailable".Translate(); //} if (apparelList != null && apparelList.Count == 0) { selectorLabel = "EdB.PC.Common.NoOptionAvailable".Translate(); } DrawFieldSelector(fieldRect, selectorLabel, previousSelectionAction, nextSelectionAction, clickAction); float cursorY = fieldRect.yMax + 6; // Draw stuff selector for apparel if (this.selectedPawnLayer.Apparel) { ThingDef apparelDef = customPawn.GetSelectedApparel(selectedPawnLayer); if (apparelDef != null && apparelDef.MadeFromStuff) { if (customPawn.GetSelectedStuff(selectedPawnLayer) == null) { Log.Error("Selected stuff for " + selectedPawnLayer.ApparelLayer + " is null"); } Rect stuffFieldRect = new Rect(RectPortrait.x, cursorY, RectPortrait.width, 28); DrawFieldSelector(stuffFieldRect, customPawn.GetSelectedStuff(selectedPawnLayer).LabelCap, () => { ThingDef selected = customPawn.GetSelectedStuff(selectedPawnLayer); int index = this.apparelStuffLookup[apparelDef].FindIndex((ThingDef d) => { return(selected == d); }); index--; if (index < 0) { index = this.apparelStuffLookup[apparelDef].Count - 1; } customPawn.SetSelectedStuff(selectedPawnLayer, apparelStuffLookup[apparelDef][index]); }, () => { ThingDef selected = customPawn.GetSelectedStuff(selectedPawnLayer); int index = this.apparelStuffLookup[apparelDef].FindIndex((ThingDef d) => { return(selected == d); }); index++; if (index >= this.apparelStuffLookup[apparelDef].Count) { index = 0; } customPawn.SetSelectedStuff(selectedPawnLayer, this.apparelStuffLookup[apparelDef][index]); }, () => { ShowApparelStuffDialog(customPawn, this.selectedPawnLayer); } ); cursorY += stuffFieldRect.height; } } cursorY += 8; // Draw Color Selector if (selectedPawnLayer.Apparel) { if (apparelList != null && apparelList.Count > 0) { ThingDef def = customPawn.GetSelectedApparel(selectedPawnLayer); if (def != null && def.HasComp(typeof(CompColorable))) { if (def.MadeFromStuff) { DrawColorSelector(customPawn, cursorY, null); } else { DrawColorSelector(customPawn, cursorY, def.colorGenerator); } } } } else if (selectedPawnLayer.ColorSelectorType == ColorSelectorType.RGB) { DrawColorSelectorForPawnLayer(customPawn, cursorY, selectedPawnLayer.ColorSwatches, true); } else if (selectedPawnLayer.ColorSelectorType == ColorSelectorType.Skin) { AlienRace alienRace = customPawn.AlienRace; if (alienRace == null || alienRace.UseMelaninLevels) { DrawHumanlikeColorSelector(customPawn, cursorY); } else { DrawAlienPawnColorSelector(customPawn, cursorY, alienRace.PrimaryColors, true); } } // Random button if (RectButtonRandomize.Contains(Event.current.mousePosition)) { GUI.color = Style.ColorButtonHighlight; } else { GUI.color = Style.ColorButton; } GUI.DrawTexture(RectButtonRandomize, Textures.TextureButtonRandom); if (Widgets.ButtonInvisible(RectButtonRandomize, false)) { SoundDefOf.Tick_Low.PlayOneShotOnCamera(); RandomizeAppearance(); } // Gender buttons. if (state.CurrentPawn.Pawn.RaceProps != null && state.CurrentPawn.Pawn.RaceProps.hasGenders) { bool genderFemaleSelected = state.CurrentPawn.Gender == Gender.Female; Style.SetGUIColorForButton(RectGenderFemale, genderFemaleSelected); GUI.DrawTexture(RectGenderFemale, Textures.TextureButtonGenderFemale); if (!genderFemaleSelected && Widgets.ButtonInvisible(RectGenderFemale, false)) { SoundDefOf.Tick_Tiny.PlayOneShotOnCamera(); GenderUpdated(Gender.Female); } bool genderMaleSelected = state.CurrentPawn.Gender == Gender.Male; Style.SetGUIColorForButton(RectGenderMale, genderMaleSelected); GUI.DrawTexture(RectGenderMale, Textures.TextureButtonGenderMale); if (!genderMaleSelected && Widgets.ButtonInvisible(RectGenderMale, false)) { SoundDefOf.Tick_Tiny.PlayOneShotOnCamera(); GenderUpdated(Gender.Male); } } GUI.color = Color.white; }
private void InitializeCustomFactions() { // Add the random faction. randomFaction = new CustomFaction(); customFactions.Add(randomFaction); // Create a lookup with all eligible faction defs. foreach (var def in nonPlayerHumanlikeFactionDefs) { eligibleFactionLookup.Add(def); } // Add the random custom faction for each eligible faction def. foreach (var def in NonPlayerHumanlikeFactionDefs) { CustomFaction faction = new CustomFaction(); faction.Def = def; customFactions.Add(faction); } // Go through all of the individual factions to create the specific custom factions and the corresponding leader options. // While doing it, build up the data structures to keep track of how many of each faction def there are. foreach (var faction in Find.World.factionManager.AllFactions) { // Update the number of each faction def in a lookup. int currentIndex = 0; if (factionCounts.ContainsKey(faction.def)) { int count = factionCounts[faction.def]; count++; factionCounts[faction.def] = count; currentIndex = count - 1; } else { factionCounts[faction.def] = 1; currentIndex = 0; } // Create the custom faction for each faction if it's an eligible faction def. if (eligibleFactionLookup.Contains(faction.def)) { CustomFaction customFaction = new CustomFaction(); customFaction.Def = faction.def; customFaction.Index = currentIndex; customFaction.Name = faction.Name; customFaction.Faction = faction; customFaction.Leader = false; customFactions.Add(customFaction); if (faction.leader != null) { // Create the leader version of the faction CustomFaction leaderFaction = new CustomFaction(); leaderFaction.Def = faction.def; leaderFaction.Index = currentIndex; leaderFaction.Name = faction.Name; leaderFaction.Faction = faction; leaderFaction.Leader = true; customFactions.Add(leaderFaction); } } } // Go through all of the specific custom factions and add it to a lookup so that we can find it // based on an index/faction def pair. foreach (var faction in customFactions) { if (faction.Faction != null && faction.Index != null && faction.Leader == false) { factionIndexLookup.Add(new Pair <FactionDef, int>(faction.Def, faction.Index.Value), faction); } } // Go through all of the specific custom factions and set on it the total number of factions of the same def. foreach (var faction in customFactions) { if (faction.Faction != null && faction.Index != null && faction.Leader == false) { int result; if (factionCounts.TryGetValue(faction.Def, out result)) { faction.SimilarFactionCount = result; } else { result = 0; } } } // Go through all of the factions and set their names. foreach (var faction in customFactions) { if (faction.Faction != null && faction.Index != null) { faction.Name = faction.Name.CapitalizeFirst(); if (faction.Faction.Name.ToLower() == faction.Def.label.ToLower()) { if (faction.SimilarFactionCount > 1) { faction.Name = "EdB.PC.Dialog.Faction.NumberedFaction".Translate(new object[] { faction.Def.LabelCap, (faction.Index.Value + 1) }); } } if (faction.Leader) { faction.Name = "EdB.PC.Dialog.Faction.LeaderFaction".Translate(new object[] { faction.Name }); } } else if (faction.Def != null) { faction.Name = "EdB.PC.Dialog.Faction.RandomFaction".Translate(new object[] { faction.Def.LabelCap }); } else { faction.Name = "EdB.PC.Dialog.Faction.Random".Translate(); } } }
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); }