// Gets random Redguard name which follows 0+1+2+3 (male), 0+1+2+4 (female) pattern string GetRandomRedguardName(NameBank nameBank, Genders gender) { // Get set parts string[] partsA, partsB, partsC, partsD; if (gender == Genders.Male) { partsA = nameBank.sets[0].parts; partsB = nameBank.sets[1].parts; partsC = nameBank.sets[2].parts; partsD = nameBank.sets[3].parts; } else { partsA = nameBank.sets[0].parts; partsB = nameBank.sets[1].parts; partsC = nameBank.sets[2].parts; partsD = nameBank.sets[4].parts; } // Generate strings string stringA = partsA[DFRandom.random_range(partsA.Length)]; string stringB = partsB[DFRandom.random_range(partsB.Length)]; string stringC = partsC[DFRandom.random_range(partsC.Length)]; string stringD = partsD[DFRandom.random_range(partsD.Length)]; return(stringA + stringB + stringC + stringD); }
void SetFoeName() { // Set type name with fallback MobileEnemy enemy; if (EnemyBasics.GetEnemy(foeType, out enemy)) { typeName = enemy.Name; } else { typeName = foeType.ToString(); } // Monster types get a random monster name // Always treating monsters as male for now as they don't have any gender in game files if ((int)foeType < 128) { DFRandom.srand(DateTime.Now.Millisecond + DFRandom.random_range(1, 1000000)); displayName = DaggerfallUnity.Instance.NameHelper.MonsterName(); return; } // Randomly assign a gender for humanoid foes humanoidGender = (UnityEngine.Random.Range(0.0f, 1.0f) < 0.55f) ? Genders.Male : Genders.Female; // Create a random display name for humanoid foes DFRandom.srand(DateTime.Now.Millisecond); NameHelper.BankTypes nameBank = GameManager.Instance.PlayerGPS.GetNameBankOfCurrentRegion(); displayName = DaggerfallUnity.Instance.NameHelper.FullName(nameBank, humanoidGender); }
// Gets random surname for names that follow 4+5 pattern string GetRandomSurname(NameBank nameBank) { // Get set parts string[] partsA, partsB; partsA = nameBank.sets[4].parts; partsB = nameBank.sets[5].parts; // Generate strings string stringA = partsA[DFRandom.random_range(partsA.Length)]; string stringB = partsB[DFRandom.random_range(partsB.Length)]; return(stringA + stringB); }
// Get random monster name which follows 0+1 (50% +2) string GetRandomMonsterName(Genders gender) { NameBank nameBank = bankDict[BankTypes.MonsterName]; // Get set parts string[] partsA, partsB, partsC; partsA = nameBank.sets[0].parts; partsB = nameBank.sets[1].parts; partsC = nameBank.sets[2].parts; // Generate strings string stringA = partsA[DFRandom.random_range(partsA.Length)]; string stringB = partsB[DFRandom.random_range(partsB.Length)]; string stringC = (UnityEngine.Random.Range(0f, 1f) < 0.5f) ? partsC[DFRandom.random_range(partsC.Length)] : string.Empty; return(stringA + stringB + stringC); }
// // -= Rules For Name Generation, By Bank =- // // Breton: // Male FirstName : Sets 0 + 1 // Female FirstName : Sets 2 + 3 // Surname : Sets 4 + 5 // // Redguard: // Male FullName : Sets 0 + 1 + 2 + 3 // Female FullName : Sets 0 + 1 + 2 + 4 // // Nord: // Male FirstName : Sets 0 + 1 // Female FirstName : Sets 2 + 3 // Surname (Use Breton) : Sets 4 + 5 // // Noble: // Title : Sets 0 // FullName : Sets 1 + 2 + 3 // // Imperial: // Male FirstName : Sets 0 + 1 // Female FirstName : Sets 2 + 3 // Surname : Sets 4 + 5 // // DarkElf: // Male FirstName : Sets 0 + 1 // Female FirstName : Sets 2 + 3 // Surname : Sets 4 + 5 // // HighElf: // Male FirstName : Sets 0 + 1 // Female FirstName : Sets 2 + 3 // Surname : Sets 4 + 5 // // WoodElf: // Male FirstName : Sets 0 + 1 // Female FirstName : Sets 2 + 3 // Surname : Sets 4 + 5 // // Location1: // Masculine FirstName : Sets 0 + 1 // Feminine FirstName : Sets 2 + 3 // Surname : Sets 4 + 5 // // Location2: // FullName : Sets 0 + 1 + 2 // // Location3: // Masculine FullName : Sets 0 + 1 + 2 // Feminine FullName : Sets 0 + 1 + 2 + 3 // // -= END =- // // Gets random first name by gender for names that follow 0+1 (male), 2+3 (female) pattern string GetRandomFirstName(NameBank nameBank, Genders gender) { // Get set parts string[] partsA, partsB; if (gender == Genders.Male) { partsA = nameBank.sets[0].parts; partsB = nameBank.sets[1].parts; } else { partsA = nameBank.sets[2].parts; partsB = nameBank.sets[3].parts; } // Generate strings string stringA = partsA[DFRandom.random_range(partsA.Length)]; string stringB = partsB[DFRandom.random_range(partsB.Length)]; return(stringA + stringB); }
// Get random monster name which follows 0+(random 1 or 2) + 3 (if feminine) string GetRandomMonsterName(Genders gender) { NameBank nameBank = bankDict[BankTypes.MonsterName]; // Get set parts string[] partsA, partsB; partsA = nameBank.sets[0].parts; partsB = (UnityEngine.Random.Range(0f, 1f) < 0.5f) ? nameBank.sets[1].parts : nameBank.sets[2].parts; // Generate strings string stringA = partsA[DFRandom.random_range(partsA.Length)]; string stringB = partsB[DFRandom.random_range(partsB.Length)]; // Attach femimine suffix string stringC = string.Empty; if (gender == Genders.Female) { string[] partsC = nameBank.sets[3].parts; stringC = partsC[DFRandom.random_range(partsC.Length)]; } return(stringA + stringB + stringC); }
public static string GetName(int seed, DFLocation.BuildingTypes type, int factionID, string locationName, string regionName) { const string firstNameTitleVar = "%ef"; const string cityNameTitleVar = "%cn"; const string royalTitleVar = "%rt"; string a = string.Empty, b = string.Empty; string result = string.Empty; bool singleton = false; FactionFile.FactionData factionData; DFRandom.srand(seed); switch (type) { case DFLocation.BuildingTypes.HouseForSale: return("House for sale"); case DFLocation.BuildingTypes.Tavern: b = TavernsB[DFRandom.random_range(0, TavernsB.Length)]; a = TavernsA[DFRandom.random_range(0, TavernsA.Length)]; break; case DFLocation.BuildingTypes.GeneralStore: b = GeneralStoresB[DFRandom.random_range(0, GeneralStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.WeaponSmith: b = WeaponStoresB[DFRandom.random_range(0, WeaponStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Armorer: b = ArmorStoresB[DFRandom.random_range(0, ArmorStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Bookseller: b = BookStoresB[DFRandom.random_range(0, BookStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.ClothingStore: b = ClothingStoresB[DFRandom.random_range(0, ClothingStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Alchemist: b = AlchemyStoresB[DFRandom.random_range(0, AlchemyStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.GemStore: b = GemStoresB[DFRandom.random_range(0, GemStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.PawnShop: b = PawnStoresB[DFRandom.random_range(0, PawnStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.FurnitureStore: b = FurnitureStoresB[DFRandom.random_range(0, FurnitureStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Library: b = LibraryStoresB[DFRandom.random_range(0, LibraryStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Bank: // Banks always appear to be named "The Bank of RegionName" b = regionName; a = "The Bank of"; break; case DFLocation.BuildingTypes.GuildHall: // Guild halls get the name from faction data if (DaggerfallUnity.Instance.ContentReader.FactionFileReader.GetFactionData(factionID, out factionData)) { a = factionData.name; singleton = true; } break; case DFLocation.BuildingTypes.Temple: // Temples get name from faction data - always seem to be first child of factionID if (DaggerfallUnity.Instance.ContentReader.FactionFileReader.GetFactionData(factionID, out factionData)) { if (factionData.children.Count > 0) { FactionFile.FactionData firstChild; if (DaggerfallUnity.Instance.ContentReader.FactionFileReader.GetFactionData(factionData.children[0], out firstChild)) { a = firstChild.name; singleton = true; } } } break; case DFLocation.BuildingTypes.Palace: // Main palace names come from TEXT.RSC (e.g. "Castle Daggerfall") // Other palaces are just named "Palace" (still need to confirm behaviour) int textId = 0; if (locationName == "Daggerfall") { textId = 475; } else if (locationName == "Wayrest") { textId = 476; } else if (locationName == "Sentinel") { textId = 477; } if (textId > 0) { TextFile.Token[] nameTokens = DaggerfallUnity.Instance.TextProvider.GetRSCTokens(textId); foreach (TextFile.Token token in nameTokens) { if (token.formatting == TextFile.Formatting.Text) { a = token.text; break; } } a = a.TrimEnd('.'); // remove character '.' from castle text record entry if it is last character } else { a = "Palace"; } singleton = true; break; default: // Do nothing for unknown/unsupported building type // Houses can actually change names based on active quests return(string.Empty); } // Replace %cn a = a.Replace(cityNameTitleVar, locationName); // Replace %ef if (a.Contains(firstNameTitleVar)) { // Need to burn a rand() for %ef roll to be correct // What is Daggerfall rolling here? DFRandom.rand(); // Observation finds nameplates only seem to use male Breton namebank string firstName = DaggerfallUnity.Instance.NameHelper.FirstName(NameHelper.BankTypes.Breton, Game.Entity.Genders.Male); a = a.Replace(firstNameTitleVar, firstName); } // Replace %rt based on faction ruler if (a.Contains(royalTitleVar)) { a = a.Replace(royalTitleVar, MacroHelper.RegentTitle(null)); } // Final text is "{a} {b}" for two-part names or just "{a}" for singleton names if (!singleton) { result = string.Format("{0} {1}", a, b); } else { result = a; } return(result); }
public static string GetName(int seed, DFLocation.BuildingTypes type, int factionID, string locationName, string regionName) { const string firstNameTitleVar = "%ef"; const string cityNameTitleVar = "%cn"; const string royalTitleVar = "%rt"; string a = string.Empty, b = string.Empty; string result = string.Empty; bool singleton = false; FactionFile.FactionData factionData; DFRandom.srand(seed); switch (type) { case DFLocation.BuildingTypes.HouseForSale: return("House for sale"); case DFLocation.BuildingTypes.Tavern: b = TavernsB[DFRandom.random_range(0, TavernsB.Length)]; a = TavernsA[DFRandom.random_range(0, TavernsA.Length)]; break; case DFLocation.BuildingTypes.GeneralStore: b = GeneralStoresB[DFRandom.random_range(0, GeneralStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.WeaponSmith: b = WeaponStoresB[DFRandom.random_range(0, WeaponStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Armorer: b = ArmorStoresB[DFRandom.random_range(0, ArmorStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Bookseller: b = BookStoresB[DFRandom.random_range(0, BookStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.ClothingStore: b = ClothingStoresB[DFRandom.random_range(0, ClothingStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Alchemist: b = AlchemyStoresB[DFRandom.random_range(0, AlchemyStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.GemStore: b = GemStoresB[DFRandom.random_range(0, GemStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.PawnShop: b = PawnStoresB[DFRandom.random_range(0, PawnStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.FurnitureStore: b = FurnitureStoresB[DFRandom.random_range(0, FurnitureStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Library: b = LibraryStoresB[DFRandom.random_range(0, LibraryStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Bank: // Banks always appear to be named "The Bank of RegionName" b = regionName; a = "The Bank of"; break; case DFLocation.BuildingTypes.GuildHall: // Guild halls get the name from faction data if (DaggerfallUnity.Instance.ContentReader.FactionFileReader.GetFactionData(factionID, out factionData)) { a = factionData.name; singleton = true; } break; case DFLocation.BuildingTypes.Temple: // Temples get name from faction data - always seem to be first child of factionID if (DaggerfallUnity.Instance.ContentReader.FactionFileReader.GetFactionData(factionID, out factionData)) { if (factionData.children.Count > 0) { FactionFile.FactionData firstChild; if (DaggerfallUnity.Instance.ContentReader.FactionFileReader.GetFactionData(factionData.children[0], out firstChild)) { a = firstChild.name; singleton = true; } } } break; case DFLocation.BuildingTypes.Palace: // Main palace names (e.g. "Castle Daggerfall" appear to be hardcoded in FALL.EXE // Other palaces are just named "Palace" // Need to confirm behaviour before implementing // Just calling everything "Palace" for now. a = "Palace"; singleton = true; break; default: // Do nothing for unknown/unsupported building type // Houses can actually change names based on active quests return(string.Empty); } // Replace %cn a = a.Replace(cityNameTitleVar, locationName); // Replace %ef if (a.Contains(firstNameTitleVar)) { // Need to burn a rand() for %ef roll to be correct // What is Daggerfall rolling here? DFRandom.rand(); // Observation finds nameplates only seem to use male Breton namebank string firstName = DaggerfallUnity.Instance.NameHelper.FirstName(NameHelper.BankTypes.Breton, Game.Entity.Genders.Male); a = a.Replace(firstNameTitleVar, firstName); } // Replace %rt based on faction ruler if (a.Contains(royalTitleVar)) { // Get factionID of this region FactionFile factionFile = DaggerfallUnity.Instance.ContentReader.FactionFileReader; int regionalFactionID = factionFile.GetFactionID(regionName); if (regionalFactionID != -1) { // Get faction data if (factionFile.GetFactionData(factionID, out factionData)) { // Get ruler title for this region string royalTile = RoyalTitles[factionData.ruler]; a = a.Replace(royalTitleVar, royalTile); } } } // Final text is "{a} {b}" for two-part names or just "{a}" for singleton names if (!singleton) { result = string.Format("{0} {1}", a, b); } else { result = a; } return(result); }
public static string GetName(int seed, DFLocation.BuildingTypes type, int factionID, string locationName, string regionName) { const string firstNameTitleVar = "%ef"; const string cityNameTitleVar = "%cn"; const string royalTitleVar = "%rt"; string a = string.Empty, b = string.Empty; string result = string.Empty; bool singleton = false; FactionFile.FactionData factionData; DFRandom.srand(seed); switch (type) { case DFLocation.BuildingTypes.HouseForSale: return("House for sale"); case DFLocation.BuildingTypes.Tavern: b = TavernsB[DFRandom.random_range(0, TavernsB.Length)]; a = TavernsA[DFRandom.random_range(0, TavernsA.Length)]; break; case DFLocation.BuildingTypes.GeneralStore: b = GeneralStoresB[DFRandom.random_range(0, GeneralStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.WeaponSmith: b = WeaponStoresB[DFRandom.random_range(0, WeaponStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Armorer: b = ArmorStoresB[DFRandom.random_range(0, ArmorStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Bookseller: b = BookStoresB[DFRandom.random_range(0, BookStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.ClothingStore: b = ClothingStoresB[DFRandom.random_range(0, ClothingStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Alchemist: b = AlchemyStoresB[DFRandom.random_range(0, AlchemyStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.GemStore: b = GemStoresB[DFRandom.random_range(0, GemStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.PawnShop: b = PawnStoresB[DFRandom.random_range(0, PawnStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.FurnitureStore: b = FurnitureStoresB[DFRandom.random_range(0, FurnitureStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Library: b = LibraryStoresB[DFRandom.random_range(0, LibraryStoresB.Length)]; a = StoresA[DFRandom.random_range(0, StoresA.Length)]; break; case DFLocation.BuildingTypes.Bank: // Banks always appear to be named "The Bank of RegionName" b = regionName; a = "The Bank of"; break; case DFLocation.BuildingTypes.GuildHall: // Guild halls get the name from faction data if (DaggerfallUnity.Instance.ContentReader.FactionFileReader.GetFactionData(factionID, out factionData)) { a = factionData.name; singleton = true; } break; case DFLocation.BuildingTypes.Temple: // Temples get name from faction data - always seem to be first child of factionID if (DaggerfallUnity.Instance.ContentReader.FactionFileReader.GetFactionData(factionID, out factionData)) { if (factionData.children.Count > 0) { FactionFile.FactionData firstChild; if (DaggerfallUnity.Instance.ContentReader.FactionFileReader.GetFactionData(factionData.children[0], out firstChild)) { a = firstChild.name; singleton = true; } } } break; case DFLocation.BuildingTypes.Palace: // Main palace names come from TEXT.RSC (e.g. "Castle Daggerfall") // Other palaces are just named "Palace" (still need to confirm behaviour) int textId = 0; if (locationName == "Daggerfall") { textId = 475; } else if (locationName == "Wayrest") { textId = 476; } else if (locationName == "Sentinel") { textId = 477; } if (textId > 0) { TextFile.Token[] nameTokens = DaggerfallUnity.Instance.TextProvider.GetRSCTokens(textId); foreach (TextFile.Token token in nameTokens) { if (token.formatting == TextFile.Formatting.Text) { a = token.text; break; } } a = a.TrimEnd('.'); // remove character '.' from castle text record entry if it is last character } else { a = "Palace"; } singleton = true; break; default: // Do nothing for unknown/unsupported building type // Houses can actually change names based on active quests return(string.Empty); } // Replace %cn a = a.Replace(cityNameTitleVar, locationName); // Replace %ef if (a.Contains(firstNameTitleVar)) { // Need to burn a rand() for %ef roll to be correct. // Classic is always doing this when expanding a macro. DFRandom.rand(); // In classic, the function expanding the %ef macro uses a global variable containing the current // region race. However, this variable is never updated when the character travels // and remains at 0. This explains why the Breton name bank is always used for shops. // This global variable is probably a leftover from Daggerfall early development as, // with the exception of %lp, which presents a similar issue and always returns // "High Rock", all naming functions use a global array of 62 fixed race values, one for each region. // As with %lp, we choose to fix the original bug in DFU and use this array, meaning that // all shops in Hammerfell now use Redguard names. NameHelper.BankTypes nameBank = (NameHelper.BankTypes)MapsFile.RegionRaces[GameManager.Instance.PlayerGPS.CurrentRegionIndex]; string firstName = DaggerfallUnity.Instance.NameHelper.FirstName(nameBank, Game.Entity.Genders.Male); a = a.Replace(firstNameTitleVar, firstName); } // Replace %rt based on faction ruler if (a.Contains(royalTitleVar)) { a = a.Replace(royalTitleVar, MacroHelper.RegentTitle(null)); } // Final text is "{a} {b}" for two-part names or just "{a}" for singleton names if (!singleton) { result = string.Format("{0} {1}", a, b); } else { result = a; } return(result); }