public CharacterNote AddNewFamilyMember(CharacterRelationshipOption relationship, bool manual) { if (relationship == null) return null; CharacterNote newNote = new CharacterNote(); AddChild(newNote); // First see if the relationship specified is a gender-neutral option with gender-specific child options. // If so, choose a gender first, then select the appropriate child relationship. bool genderChosen = false; if (relationship.Genders?.Count == 0 && relationship.ChildOptions.Cast<CharacterRelationshipOption>().Count(c => c.Genders?.Count > 0) > 1) { newNote.SetRelationshipMatchingGender(this, relationship); genderChosen = true; } // If no gender-specific options were selected, the choice will // fall back on the gender-neutral original below. if (newNote.Relationship == null) newNote.Relationship = relationship; // False return means no valid age range exists for the relationship (min > max). // Ignored when adding manually. if (!newNote.ChooseAge() && !manual) { Ideas.Remove(newNote); return null; } if (!genderChosen) newNote.ChooseGender(); newNote.SetInheritedRaces(); newNote.AssignFamilySurname(); newNote.AssignFamilyFirstName(); if (RootSaveFile?.Template?.CharacterTemplate?.Traits != null) newNote.Traits.MergeWithOption(RootSaveFile.Template.CharacterTemplate.Traits, true); newNote.Traits.Choose(); if (newNote.Relationship.RequiresOrientationMatch) { newNote.ReconcileOrientation(this, newNote.Relationship); CharacterRelationshipOption reciprocalRelationship = RootSaveFile.Template.CharacterTemplate.Relationships.FindOption(newNote.Relationship.ReciprocalRelationship) as CharacterRelationshipOption; ReconcileOrientation(newNote, reciprocalRelationship); } return newNote; }
/// <summary> /// Allows generating a parent for this character as if generating a spouse for one of their existing parents. /// This allows generating correct gender and orientation matching for between the 'spouses.' /// </summary> /// <param name="spouse">The character to be used as the hypothetical spouse.</param> private void GenerateParentAsSpouse(CharacterNote spouse) { if (RootSaveFile?.Template?.CharacterTemplate?.Relationships == null) return; CharacterRelationshipOption relationship = RootSaveFile.Template.CharacterTemplate.Relationships.FindOption("Parent") as CharacterRelationshipOption; CharacterRelationshipOption spouseRelationship = RootSaveFile.Template.CharacterTemplate.Relationships.FindOption("Significant Other\\Spouse") as CharacterRelationshipOption; if (relationship == null || spouseRelationship == null) return; CharacterNote newNote = new CharacterNote(); AddChild(newNote); newNote.Relationship = relationship; int? spouseMinAge = spouseRelationship.MinAge; if (spouseRelationship.MinAgeOffset.HasValue) spouseMinAge = Math.Max(spouseMinAge ?? int.MinValue, spouse.AgeYears + spouseRelationship.MinAgeOffset.Value); int? spouseMaxAge = spouseRelationship.MaxAge; if (spouseRelationship.MaxAgeOffset.HasValue) spouseMaxAge = Math.Min(spouseMaxAge ?? int.MaxValue, spouse.AgeYears + spouseRelationship.MaxAgeOffset.Value); if (!newNote.ChooseAge(false, spouseMinAge, spouseMaxAge)) // False return means no valid age range exists for the relationship (min > max). { Ideas.Remove(newNote); return; } if (!spouseRelationship.RequiresOrientationMatch || !newNote.SetSignificantOtherGender(spouse, spouseRelationship)) newNote.ChooseGender(); newNote.SetInheritedRaces(); newNote.AssignFamilySurname(); newNote.AssignFamilyFirstName(); if (RootSaveFile?.Template?.CharacterTemplate?.Traits != null) newNote.Traits.MergeWithOption(RootSaveFile.Template.CharacterTemplate.Traits, true); newNote.Traits.Choose(); // There is a chance that a character of any orientation will be in a // heterosexual marriage (or ex-marriage), due to societal pressure. // Otherwise, the new character's orientation will be adjusted, if necessary, to // fit the relationship. if (spouseRelationship.RequiresOrientationMatch && (random.Next(101) > chanceOfForcedHeteroMarriage || spouse.EffectiveGender?.Archetype != newNote.EffectiveGender?.Opposite)) newNote.ReconcileOrientation(spouse, spouseRelationship); }
private bool GenerateSignificantOther(CharacterRelationshipOption relationship, int numAlready) { if (relationship.IsInPath("Spouse")) { if (!CheckForSpouse(relationship, numAlready)) return false; } else if (relationship.IsInPath("Ex-Spouse")) { if (!CheckForExSpouse(relationship, numAlready)) return false; } else if (relationship.IsInPath("Lover")) { if (!CheckForLover(relationship, numAlready)) return false; } else if (!CheckForRelationship(relationship, numAlready)) return false; CharacterNote newNote = new CharacterNote(); AddChild(newNote); newNote.Relationship = relationship; if (!relationship.RequiresOrientationMatch || !newNote.SetSignificantOtherGender(this, relationship)) newNote.ChooseGender(); int? minimum, maximum; GetSignificantOtherAgeRange(newNote.EffectiveGender, out minimum, out maximum); if (!newNote.ChooseAge(false, minimum, maximum)) // False return means no valid age range exists for the relationship (min > max). { Ideas.Remove(newNote); return false; } newNote.SetInheritedRaces(); newNote.AssignFamilySurname(); newNote.AssignFamilyFirstName(); if (RootSaveFile?.Template?.CharacterTemplate?.Traits != null) newNote.Traits.MergeWithOption(RootSaveFile.Template.CharacterTemplate.Traits, true); newNote.Traits.Choose(); // There is a chance that a character of any orientation will be in a // heterosexual marriage (or ex-marriage), due to societal pressure. // Otherwise, the new character's orientation will be adjusted, if necessary, to // fit the relationship. if (relationship.RequiresOrientationMatch && (!relationship.Path.Contains("Spouse") || random.Next(101) > chanceOfForcedHeteroMarriage || EffectiveGender?.Archetype != newNote.EffectiveGender?.Opposite)) newNote.ReconcileOrientation(this, newNote.Relationship); return true; }