private CustomParentChildPawn CreateParent(Gender?gender, List <CustomParentChildPawn> children) { int ageOfOldestChild = 0; CustomPawn firstChild = null; foreach (var child in children) { if (child.Pawn.BiologicalAge > ageOfOldestChild) { ageOfOldestChild = child.Pawn.BiologicalAge; firstChild = child.Pawn; } } float lifeExpectancy = firstChild.Pawn.def.race.lifeExpectancy; float minAge = lifeExpectancy * 0.1625f; float maxAge = lifeExpectancy * 0.625f; float meanAge = lifeExpectancy * 0.325f; float leftDistance = meanAge - minAge; float rightDistance = maxAge - meanAge; int age = (int)(Verse.Rand.GaussianAsymmetric(meanAge, leftDistance, rightDistance) + ageOfOldestChild); CustomPawn parent = new CustomPawn(new Randomizer().GeneratePawn(new PawnGenerationRequestWrapper() { KindDef = firstChild.Pawn.kindDef, FixedBiologicalAge = age, FixedGender = gender }.Request)); CustomParentChildPawn result = new CustomParentChildPawn(parent); result.Hidden = true; return(result); }
public void AddChildToParentChildGroup(CustomParentChildGroup group, CustomParentChildPawn pawn) { if (!group.Parents.Contains(pawn) && !group.Children.Contains(pawn)) { group.Children.Add(pawn); } }
public void RemoveChildFromParentChildGroup(CustomParentChildGroup group, CustomParentChildPawn pawn) { group.Children.Remove(pawn); if (group.Parents.Count == 0 && group.Children.Count == 0) { PrepareCarefully.Instance.RelationshipManager.RemoveParentChildGroup(group); } }
protected void Select(CustomParentChildPawn pawn) { this.SelectedPawn = pawn; if (SelectAction != null) { SelectAction(pawn); } }
public CustomParentChildPawn AddVisibleParentChildPawn(Pawn pawn, CustomPawn customPawn) { CustomParentChildPawn parentChildPawn = new CustomParentChildPawn(customPawn, false); parentChildPawns.Add(parentChildPawn); parentChildPawnLookup.Add(pawn, parentChildPawn); parentChildCustomPawnLookup.Add(customPawn, parentChildPawn); return(parentChildPawn); }
public CustomParentChildPawn AddHiddenParentChildPawn(CustomPawn customPawn) { CustomParentChildPawn parentChildPawn = new CustomParentChildPawn(customPawn, true); parentChildPawns.Add(parentChildPawn); parentChildPawnLookup.Add(customPawn.Pawn, parentChildPawn); parentChildCustomPawnLookup.Add(customPawn, parentChildPawn); return(parentChildPawn); }
protected CustomParentChildPawn ReplaceNewHiddenCharacter(int index) { var pawn = newPawns[index]; newPawns[index] = CreateNewHiddenPawn(pawn.Pawn.Gender); CustomParentChildPawn result = PrepareCarefully.Instance.RelationshipManager.AddHiddenParentChildPawn(pawn.Pawn); result.Index = PrepareCarefully.Instance.RelationshipManager.NextHiddenParentChildIndex; return(result); }
protected CustomParentChildPawn CreateNewHiddenPawn(Gender gender) { CustomPawn pawn = new CustomPawn(new Randomizer().GeneratePawn(new PawnGenerationRequestWrapper() { FixedGender = gender }.Request)); CustomParentChildPawn result = new CustomParentChildPawn(pawn, true); result.Name = "EdB.PC.AddParentChild.NewHiddenCharacter".Translate(); return(result); }
protected void ShowChildDialogForGroup(CustomParentChildGroup group, CustomParentChildPawn selected, Action <CustomParentChildPawn> action) { CustomParentChildPawn selectedPawn = selected; HashSet <CustomParentChildPawn> disabled = new HashSet <CustomParentChildPawn>(); if (group != null) { disabled.AddRange(group.Parents); disabled.AddRange(group.Children); } rowGroups.Clear(); rowGroups.Add(new WidgetTable <CustomParentChildPawn> .RowGroup("EdB.PC.AddParentChild.Header.SelectColonist".Translate(), PrepareCarefully.Instance.RelationshipManager.ColonyPawns)); rowGroups.Add(new WidgetTable <CustomParentChildPawn> .RowGroup("EdB.PC.AddParentChild.Header.SelectHidden".Translate(), PrepareCarefully.Instance.RelationshipManager.HiddenPawns)); WidgetTable <CustomParentChildPawn> .RowGroup newPawnGroup = new WidgetTable <CustomParentChildPawn> .RowGroup(null, newPawns); rowGroups.Add(newPawnGroup); DialogSelectParentChildPawn pawnDialog = new DialogSelectParentChildPawn() { HeaderLabel = "EdB.PC.AddParentChild.Header.AddChild".Translate(), SelectAction = (CustomParentChildPawn pawn) => { selectedPawn = pawn; }, RowGroups = rowGroups, DisabledPawns = disabled, ConfirmValidation = () => { if (selectedPawn == null) { return("EdB.PC.AddParentChild.Error.ChildRequired"); } else { return(null); } }, CloseAction = () => { // If the user selected a new pawn, replace the pawn in the new pawn list with another one. int index = newPawnGroup.Rows.FirstIndexOf((CustomParentChildPawn p) => { return(p == selectedPawn); }); if (index > -1 && index < newPawns.Count) { selectedPawn = ReplaceNewHiddenCharacter(index); } action(selectedPawn); } }; Find.WindowStack.Add(pawnDialog); }
protected void DrawPortrait(CustomParentChildPawn pawn, Rect rect) { Rect parentNameRect = new Rect(rect.x, rect.yMax - 34, rect.width, 26); Text.Font = GameFont.Small; Text.Anchor = TextAnchor.UpperCenter; GUI.color = Style.ColorText; Widgets.Label(parentNameRect, pawn.Name); GUI.color = Color.white; Rect parentProfessionRect = new Rect(rect.x, rect.yMax - 18, rect.width, 18); Text.Font = GameFont.Tiny; Text.Anchor = TextAnchor.LowerCenter; GUI.color = Style.ColorText; Widgets.Label(parentProfessionRect, GetProfessionLabel(pawn)); GUI.color = Color.white; Text.Font = GameFont.Small; Text.Anchor = TextAnchor.UpperLeft; if (!pawn.Hidden) { Rect parentPortraitRect = rect.InsetBy(6); parentPortraitRect.y -= 8; var parentPortraitTexture = pawn.Pawn.GetPortrait(parentPortraitRect.size); GUI.DrawTexture(parentPortraitRect.OffsetBy(0, -4), parentPortraitTexture); } else { GUI.color = Style.ColorButton; Rect parentPortraitRect = new Rect(rect.MiddleX() - SizeGender.HalfX(), rect.y + SpacingGender, SizeGender.x, SizeGender.y); if (pawn.Pawn.Gender == Gender.Female) { GUI.DrawTexture(parentPortraitRect, Textures.TextureGenderFemaleLarge); } else if (pawn.Pawn.Gender == Gender.Male) { GUI.DrawTexture(parentPortraitRect, Textures.TextureGenderMaleLarge); } else { GUI.DrawTexture(parentPortraitRect, Textures.TextureGenderlessLarge); } } TooltipHandler.TipRegion(rect, GetTooltipText(pawn)); }
private string GetProfessionLabel(CustomParentChildPawn pawn) { if (!pawn.Hidden) { return(pawn.Pawn.ProfessionLabelShort); } if (pawn.Pawn.IsAdult && visibleBackstories.Contains(pawn.Pawn.Adulthood)) { return(pawn.Pawn.ProfessionLabelShort); } else if (!pawn.Pawn.IsAdult && visibleBackstories.Contains(pawn.Pawn.Childhood)) { return(pawn.Pawn.ProfessionLabelShort); } else { return("Unknown"); } }
private void InitializeParentChildGroupRelationships(List <CustomRelationship> relationships) { Dictionary <CustomParentChildPawn, CustomParentChildGroup> groupLookup = new Dictionary <CustomParentChildPawn, CustomParentChildGroup>(); foreach (var relationship in relationships) { CustomParentChildPawn parent = null; CustomParentChildPawn child = null; if (relationship.def == PawnRelationDefOf.Parent) { parentChildCustomPawnLookup.TryGetValue(relationship.source, out child); parentChildCustomPawnLookup.TryGetValue(relationship.target, out parent); } else if (relationship.def == PawnRelationDefOf.Child) { parentChildCustomPawnLookup.TryGetValue(relationship.target, out child); parentChildCustomPawnLookup.TryGetValue(relationship.source, out parent); } if (parent == null) { Log.Warning("Could not add relationship because of missing parent"); continue; } if (child == null) { Log.Warning("Could not add relationship because of missing child"); continue; } // See if the child has an existing parent/child group. If not, create the group. // If so, just add the parent. CustomParentChildGroup group; if (!groupLookup.TryGetValue(child, out group)) { group = new CustomParentChildGroup(); group.Children.Add(child); groupLookup.Add(child, group); } group.Parents.Add(parent); } SortAndDedupeParentChildGroups(groupLookup.Values); }
private void InitializeParentChildGroupsForStartingPawns(List <Pawn> pawns, List <CustomPawn> correspondingFacades) { // Create a map so that we can look up custom pawns based on their matching original pawn. Dictionary <Pawn, CustomPawn> pawnToFacadeMap = new Dictionary <Pawn, CustomPawn>(); int pawnCount = pawns.Count; for (int i = 0; i < pawns.Count; i++) { pawnToFacadeMap.Add(pawns[i], correspondingFacades[i]); } // Go through each pawn and look for a child/parent relationship between it and all other pawns. Dictionary <Pawn, CustomParentChildGroup> groupLookup = new Dictionary <Pawn, CustomParentChildGroup>(); foreach (Pawn child in pawns) { foreach (var r in child.relations.DirectRelations) { //Log.Message("Relationship: " + r.def.defName + ", " + child.LabelShort + " & " + r.otherPawn.LabelShort); if (r.def == PawnRelationDefOf.Parent) { Pawn parent = r.otherPawn; CustomParentChildPawn parentCustomPawn = parentChildPawnLookup[parent]; CustomParentChildPawn childCustomPawn = parentChildPawnLookup[child]; // See if the child has an existing parent/child group. If not, create the group. // If so, just add the parent. CustomParentChildGroup group; if (!groupLookup.TryGetValue(child, out group)) { group = new CustomParentChildGroup(); group.Children.Add(childCustomPawn); groupLookup.Add(child, group); } group.Parents.Add(parentCustomPawn); } } } SortAndDedupeParentChildGroups(groupLookup.Values); }
protected string GetTooltipText(CustomParentChildPawn parentChildPawn) { CustomPawn pawn = parentChildPawn.Pawn; string description; if (!parentChildPawn.Hidden) { string age = pawn.BiologicalAge != pawn.ChronologicalAge ? "EdB.PC.Pawn.AgeWithChronological".Translate(new object[] { pawn.BiologicalAge, pawn.ChronologicalAge }) : "EdB.PC.Pawn.AgeWithoutChronological".Translate(new object[] { pawn.BiologicalAge }); description = pawn.Gender != Gender.None ? "EdB.PC.Pawn.PawnDescriptionWithGender".Translate(new object[] { pawn.ProfessionLabel, pawn.Gender.GetLabel(), age }) : "EdB.PC.Pawn.PawnDescriptionNoGender".Translate(new object[] { pawn.ProfessionLabel, age }); } else { string profession = "EdB.PC.Pawn.HiddenPawnProfession".Translate(); description = pawn.Gender != Gender.None ? "EdB.PC.Pawn.HiddenPawnDescriptionWithGender".Translate(new object[] { profession, pawn.Gender.GetLabel() }) : "EdB.PC.Pawn.HiddenPawnDescriptionNoGender".Translate(new object[] { profession }); } return(parentChildPawn.FullName + "\n" + description); }
public PawnGroupPair(CustomParentChildPawn Pawn, CustomParentChildGroup Group) { this.Pawn = Pawn; this.Group = Group; }
public void Build() { // These include all the pawns that have relationships with them. HashSet <CustomPawn> relevantPawns = new HashSet <CustomPawn>(); foreach (var rel in relationships) { relevantPawns.Add(rel.source); relevantPawns.Add(rel.target); } foreach (var group in parentChildGroups) { foreach (var parent in group.Parents) { relevantPawns.Add(parent.Pawn); } foreach (var child in group.Children) { relevantPawns.Add(child.Pawn); } } // Remove all relationships. foreach (var pawn in relevantPawns) { pawn.Pawn.relations.ClearAllRelations(); } FieldInfo directRelationsField = typeof(Pawn_RelationsTracker).GetField("directRelations", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo pawnsWithField = typeof(Pawn_RelationsTracker).GetField("pawnsWithDirectRelationsWithMe", BindingFlags.Instance | BindingFlags.NonPublic); // Add direct relationships. foreach (var rel in relationships) { AddRelationship(rel.source.Pawn, rel.target.Pawn, rel.def); } // For any parent/child group that is missing parents, create them. foreach (var group in parentChildGroups) { if (group.Children.Count > 1) { // Siblings need to have 2 parents, or they will be considered half-siblings. if (group.Parents.Count == 0) { CustomParentChildPawn parent1 = CreateParent(Gender.Female, group.Children); CustomParentChildPawn parent2 = CreateParent(Gender.Male, group.Children); group.Parents.Add(parent1); group.Parents.Add(parent2); } else if (group.Parents.Count == 1) { if (group.Parents[0].Gender == Gender.Male) { CustomParentChildPawn parent = CreateParent(Gender.Female, group.Children); group.Parents.Add(parent); } else { CustomParentChildPawn parent = CreateParent(Gender.Male, group.Children); group.Parents.Add(parent); } } } } // Validate that any hidden parents are a reasonable age. foreach (var group in parentChildGroups) { if (group.Children.Count == 0) { continue; } float age = 0; CustomPawn oldestChild = null; foreach (var child in group.Children) { if (child.Pawn.BiologicalAge > age) { age = child.Pawn.BiologicalAge; oldestChild = child.Pawn; } } if (oldestChild == null) { continue; } foreach (var parent in group.Parents) { if (parent.Hidden) { int validAge = GetValidParentAge(parent.Pawn, oldestChild); if (validAge != parent.Pawn.BiologicalAge) { int diff = parent.Pawn.ChronologicalAge - parent.Pawn.BiologicalAge; parent.Pawn.BiologicalAge = validAge; parent.Pawn.ChronologicalAge = validAge + diff; } } } } // Add parent/child relationships. PawnRelationDef childDef = PawnRelationDefOf.Child; PawnRelationDef parentDef = PawnRelationDefOf.Parent; foreach (var group in parentChildGroups) { foreach (var parent in group.Parents) { foreach (var child in group.Children) { AddRelationship(child.Pawn.Pawn, parent.Pawn.Pawn, parentDef); AddRelationship(parent.Pawn.Pawn, child.Pawn.Pawn, childDef); } } } // Add pawns to the world. // TODO: Killing a pawn adds it to the world and doesn't force us to figure out which // faction we want to assign the pawn to (not sure that I understand why all relatives need // to live on the planet or be available in a spacer faction). Should revisit this to // decide if that's really what we want to do. // Start by assigning each hidden pawn to a random faction that's not the player faction. // If the pawn ends up assigned to the player faction, the stats screen will count the pawn // as a killed colonist--we don't want that to happen. FactionManager factionManager = Find.World.factionManager; Faction newPawnFaction = factionManager.FirstFactionOfDef(FactionDefOf.Spacer); if (newPawnFaction == null) { if (!factionManager.TryGetRandomNonColonyHumanlikeFaction(out newPawnFaction, false, true)) { newPawnFaction = factionManager.AllFactions.RandomElementWithFallback(Faction.OfPlayer); } } // Kill the pawns (but only if they are not already in the world). HashSet <Pawn> pawnsAddedToWorld = new HashSet <Pawn>(); foreach (var group in parentChildGroups) { foreach (var parent in group.Parents) { if (parent.Hidden) { Pawn newPawn = parent.Pawn.Pawn; if (!Find.World.worldPawns.Contains(newPawn)) { newPawn.SetFactionDirect(newPawnFaction); if (!pawnsAddedToWorld.Contains(newPawn)) { newPawn.Kill(null); pawnsAddedToWorld.Add(newPawn); } } } foreach (var child in group.Children) { if (child.Hidden) { Pawn newPawn = child.Pawn.Pawn; if (!Find.World.worldPawns.Contains(newPawn)) { newPawn.SetFactionDirect(newPawnFaction); if (!pawnsAddedToWorld.Contains(newPawn)) { newPawn.Kill(null); pawnsAddedToWorld.Add(newPawn); } } } } } } }