Exemplo n.º 1
0
        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);
     }
 }
Exemplo n.º 4
0
 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;
 }
Exemplo n.º 16
0
        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);
                                }
                            }
                        }
                    }
                }
            }
        }