public void GenerateLife(Random rand, NPCData data, FantasyDate referenceDate) { GenerateID(); BirthDate = referenceDate - rand.Next((int)(data.Race.AverageLifeSpan * 0.2f), (int)(data.Race.AverageLifeSpan * 0.8f)); DeathDate = BirthDate + (data.Race.AverageLifeSpan - (data.Race.AverageLifeSpan / 4)) + rand.Next(1, data.Race.AverageLifeSpan / 2); Dead = DeathDate < data.CurrentDate; Age = Dead ? DeathDate - BirthDate : data.CurrentDate - BirthDate; Male = rand.Next(0, 2) == 0; Race = data.Race.Name; CityOfOrigin = data.CityOfOrigin; KnewParents = rand.Next(1, 101) <= 95; int birthPlaceRoll = rand.Next(1, 101); List <Birthplace> birthPlaceOptions = new List <Birthplace>((IEnumerable <Birthplace>)System.Enum.GetValues(typeof(Birthplace))); for (int i = 0; i < birthPlaceOptions.Count; i++) { int val = (int)birthPlaceOptions[i]; if (birthPlaceRoll <= val) { BirthPlace = birthPlaceOptions[i]; break; } } int upbringingRoll = rand.Next(1, 101); List <Upbringing> upbringingOptions = new List <Upbringing>((IEnumerable <Upbringing>)System.Enum.GetValues(typeof(Upbringing))); for (int i = 0; i < upbringingOptions.Count; i++) { int val = (int)upbringingOptions[i]; if (upbringingRoll <= val) { Family = upbringingOptions[i]; break; } } Background = (Background)rand.Next(0, System.Enum.GetValues(typeof(Background)).Length); if (!KnewParents || Family != Upbringing.MotherAndFather) { AbsentParentReason = (AbsentParent)rand.Next(1, 5); } else { AbsentParentReason = AbsentParent.NotAbsent; } int childhoodRoll = rand.Next(1, 7) + rand.Next(1, 7) + rand.Next(1, 7); List <Childhood> childhoodOptions = new List <Childhood>((IEnumerable <Childhood>)System.Enum.GetValues(typeof(Childhood))); for (int i = 0; i < childhoodOptions.Count; i++) { int val = (int)childhoodOptions[i]; if (childhoodRoll <= val) { Childhood = childhoodOptions[i]; break; } } int lifeEvents = 1; if (Age > 100) { lifeEvents = rand.Next(1, 13); } else if (Age > 90) { lifeEvents = rand.Next(1, 11); } else if (Age > 70) { lifeEvents = rand.Next(1, 9); } else if (Age > 60) { lifeEvents = rand.Next(1, 7); } else if (Age > 21) { lifeEvents = rand.Next(1, 5); } List <LifeEventOption> lifeEventOptions = new List <LifeEventOption>((IEnumerable <LifeEventOption>)System.Enum.GetValues(typeof(LifeEventOption))); for (int i = 0; i < lifeEvents; i++) { int lifeEventRoll = rand.Next(1, 101); LifeEvent lifeEvent = new LifeEvent(); for (int j = 0; j < lifeEventOptions.Count; j++) { int val = (int)lifeEventOptions[j]; if (lifeEventRoll <= val) { lifeEvent.Event = lifeEventOptions[j]; break; } } switch (lifeEvent.Event) { case LifeEventOption.Tragedy: break; case LifeEventOption.GoodFortune: break; case LifeEventOption.EnemyOfAdventurer: break; case LifeEventOption.MetSomeoneImportant: break; case LifeEventOption.WentOnAdventure: break; case LifeEventOption.SupernaturalExperience: break; case LifeEventOption.Crime: break; case LifeEventOption.MagicEncounter: break; case LifeEventOption.StrangeEvent: break; } LifeEvents.Add(lifeEvent); } }
public List <NPC> CreateLineage(Random rand, NPCData data, FantasyDate referenceDate, ref Queue <string> lastNameCache, int depth = 0, int generations = 3, bool?isMale = null, bool hasSiblings = true) { List <NPC> result = new List <NPC>(); GenerateLife(rand, data, referenceDate); if (isMale != null) { Male = (bool)isMale; } Name = Utility.GenerateName(rand, data.Race, Male ? Utility.NameType.FirstNameMale : Utility.NameType.FirstNameFemale) + " " + data.SurName;//new Faker().Name.FirstName(Male ? Bogus.DataSets.Name.Gender.Male : Bogus.DataSets.Name.Gender.Female) + " " + data.SurName; result.Add(this); int siblingCount = rand.Next(1, 11); if (siblingCount >= 9) { siblingCount = rand.Next(1, 9) + 3; } else if (siblingCount >= 7) { siblingCount = rand.Next(1, 7) + 2; } else if (siblingCount >= 5) { siblingCount = rand.Next(1, 5) + 1; } else if (siblingCount >= 3) { siblingCount = rand.Next(1, 4); } else if (siblingCount >= 0) { siblingCount = 0; } if (!hasSiblings) { siblingCount = 0; } for (int i = 0; i < siblingCount; i++) { NPC sibling = new NPC(); sibling.GenerateLife(rand, data, referenceDate); sibling.Name = Utility.GenerateName(rand, data.Race, sibling.Male ? Utility.NameType.FirstNameMale : Utility.NameType.FirstNameFemale) + " " + data.SurName; sibling.Family = Family; sibling.AbsentParentReason = AbsentParentReason; Siblings.Add(sibling); result.Add(sibling); } FantasyDate youngest = BirthDate; for (int i = 0; i < Siblings.Count; i++) { for (int j = 0; j < Siblings.Count; j++) { if (i != j) { Siblings[i].Siblings.Add(Siblings[j]); } } Siblings[i].Siblings.Add(this); if (Siblings[i].BirthDate < youngest) { youngest = Siblings[i].BirthDate; } } if (depth < generations) { NPC father = new NPC(); result.AddRange(father.CreateLineage(rand, data, youngest, ref lastNameCache, depth + 1, generations: generations, isMale: true)); NPC mother = new NPC(); string surName = string.Empty; if (data.Race.hasLastName && lastNameCache.Count > 0) { surName = lastNameCache.Dequeue(); } data.SurName = surName; result.AddRange(mother.CreateLineage(rand, data, youngest, ref lastNameCache, depth + 1, generations: generations, isMale: false)); Father = father; Mother = mother; for (int i = 0; i < Siblings.Count; i++) { Siblings[i].Father = father; Siblings[i].Mother = mother; Siblings[i].GenerateFamilyScript(); } Father.Children.Add(this); Mother.Children.Add(this); Father.Children.AddRange(Siblings); Mother.Children.AddRange(Siblings); } GenerateFamilyScript(); return(result); }
public static NPC Generate(string primaryPath, int generations, string[] familyLines, Race currentRace, FantasyDate currentDate, string city, string specificFamilyName = "", bool firstHasSiblings = true, string extraText = "") { NPC resultNpc = null; string path = primaryPath + @"\Families\" + city + @"\"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } path += currentRace.Name; Random rand = new Random(); List <NPC> allNpcs = new List <NPC>(); Queue <string> lastNamesCache = new Queue <string>(); if (currentRace.hasLastName) { int namesToMake = (familyLines.Length * generations) * 4000; Console.WriteLine("Creating " + namesToMake + " unique last names"); int safety = 0; while (lastNamesCache.Count < namesToMake) { string lastName = Utility.GenerateName(rand, currentRace, Utility.NameType.LastName); if (!lastNamesCache.Contains(lastName)) { lastNamesCache.Enqueue(lastName); safety = 0; } safety++; if (safety > 5000) { Console.WriteLine("Could only generate " + lastNamesCache.Count + " unique last names before running out of variations."); break; } } } int livingPeople = 0; for (int f = 0; f < familyLines.Length; f++) { List <NPC> living = new List <NPC>(); while (true) { living.Clear(); allNpcs.Clear(); while (allNpcs.Count == 0) { NPC.FamilyScript.Clear(); Console.WriteLine("Creating NPCs"); NPC npc = new NPC(); allNpcs.AddRange(npc.CreateLineage(rand, new NPCData() { CurrentDate = currentDate, Race = currentRace, SurName = specificFamilyName != string.Empty ? specificFamilyName : currentRace.hasLastName ? lastNamesCache.Dequeue() : string.Empty, CityOfOrigin = city }, currentDate, ref lastNamesCache, generations: generations, hasSiblings: firstHasSiblings)); allNpcs.Sort((x, y) => { return(y.BirthDate.CompareTo(x.BirthDate)); }); for (int i = 0; i < allNpcs.Count; i++) { for (int j = 0; j < allNpcs.Count; j++) { if (i != j) { NPC one = allNpcs[i]; NPC two = allNpcs[j]; if (one.Name == two.Name && currentRace.hasLastName && Math.Abs(one.BirthDate.GetYearUniversal() - two.BirthDate.GetYearUniversal()) < currentRace.AverageLifeSpan * 0.1f) { allNpcs.Clear(); Console.WriteLine("Found duplicate, regenerating"); } } } } } for (int i = 0; i < allNpcs.Count; i++) { if (!allNpcs[i].Dead) { living.Add(allNpcs[i]); if (allNpcs[i].Age > currentRace.AverageLifeSpan * 0.3f || resultNpc == null) { resultNpc = allNpcs[i]; } } } if (living.Count >= 5 || !firstHasSiblings) { livingPeople += living.Count; break; } } Console.WriteLine("There are " + living.Count + " living in " + familyLines[f] + "."); Console.WriteLine("Writing NPCs"); using (FileStream stream = new FileStream(path + "_AllGenerationInfo_" + familyLines[f] + ".txt", FileMode.Create)) { using (StreamWriter writer = new StreamWriter(stream)) { for (int i = 0; i < allNpcs.Count; i++) { writer.WriteLine(allNpcs[i].ToString()); if (allNpcs[i] == resultNpc) { writer.WriteLine(extraText); } writer.WriteLine("\n" + new string('-', 20) + "\n"); } } } using (FileStream stream = new FileStream(path + "_FamilyScript_" + familyLines[f] + ".txt", FileMode.Create)) { using (StreamWriter writer = new StreamWriter(stream)) { for (int j = 0; j < NPC.FamilyScript.Count; j++) { writer.WriteLine(NPC.FamilyScript[j]); } } } } Console.WriteLine("Done with " + livingPeople + " citizens"); return(resultNpc); }