Пример #1
0
        // Sets gender and display name
        // Has some logic to handle individual faction objects and certain flat limitations
        void AssignDisplayName()
        {
            // Witches and prostitutes only have female flats in Daggerfall
            if (factionData.type == (int)FactionFile.FactionTypes.WitchesCoven ||
                factionData.id == 512)
            {
                npcGender = Genders.Female;
            }

            // Assign name - some types have their own individual name to use
            if ((factionData.type == (int)FactionFile.FactionTypes.Individual ||
                 factionData.type == (int)FactionFile.FactionTypes.Daedra) &&
                factionData.id != 0)
            {
                // Use individual name
                displayName = factionData.name;
            }
            else
            {
                // Set a name seed if not configured
                if (nameSeed == -1)
                {
                    nameSeed = DateTime.Now.Millisecond;
                }

                // Generate a random name based on gender and race name bank
                DFRandom.srand(nameSeed);
                displayName = DaggerfallUnity.Instance.NameHelper.FullName(nameBank, npcGender);
            }
        }
Пример #2
0
        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);
                displayName = DaggerfallUnity.Instance.NameHelper.MonsterName();
                return;
            }

            // TODO: Create a random humanoid foe name
            // Will get to this testing quests that assign player to defeat and return a class-based NPC Foe
            // Have more problems to solve before getting to name
        }
Пример #3
0
        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);
                displayName = DaggerfallUnity.Instance.NameHelper.MonsterName();
                return;
            }

            // Randomly assign a gender for humanoid foes
            humanoidGender = (UnityEngine.Random.Range(0.0f, 1.0f) < 0.5f) ? 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);
        }
Пример #4
0
        // Sets gender and display name
        // Has some logic to handle individual faction objects and certain flat limitations
        void AssignDisplayName(string genderName)
        {
            // Set gender
            npcGender = GetGender(genderName);

            // Witches only have female flats
            if (factionData.type == (int)FactionFile.FactionTypes.WitchesCoven)
            {
                npcGender = Genders.Female;
            }

            // Get name bank
            NameHelper.BankTypes bankType = GameManager.Instance.PlayerGPS.GetNameBankOfCurrentRegion();

            // Assign name - some types have their own individual name to use
            if (factionData.type == (int)FactionFile.FactionTypes.Individual ||
                factionData.type == (int)FactionFile.FactionTypes.Daedra)
            {
                // Use individual name
                displayName = factionData.name;
            }
            else
            {
                // Set a name seed if not configured
                if (nameSeed == -1)
                {
                    nameSeed = DateTime.Now.Millisecond;
                }

                // Generate a random name based on gender and race name bank
                DFRandom.srand(nameSeed);
                displayName = DaggerfallUnity.Instance.NameHelper.FullName(bankType, npcGender);
            }
        }
Пример #5
0
        // Creates a career-based NPC like a Shopkeeper or Banker
        void SetupCareerAllianceNPC(string careerAllianceName)
        {
            // Special handling for Questor class
            // Will revisit this later when guilds are more integrated
            if (careerAllianceName.Equals("Questor", StringComparison.InvariantCultureIgnoreCase))
            {
                if (SetupQuestorNPC())
                {
                    return;
                }
            }

            // Get faction data
            int factionID = GetCareerFactionID(careerAllianceName);

            if (factionID != -1)
            {
                FactionFile.FactionData factionData = GetFactionData(factionID);

                // Setup Person resource
                DFRandom.srand(Time.frameCount);
                this.factionData = factionData;
            }
            else
            {
                Debug.LogErrorFormat("SetupCareerAllianceNPC() failed to setup {0}", careerAllianceName);
            }
        }
Пример #6
0
        // Sets gender and display name
        // Has some logic to handle individual faction objects and certain flat limitations
        void AssignDisplayName()
        {
            // Witches only have female flats
            if (factionData.type == (int)FactionFile.FactionTypes.WitchesCoven)
            {
                npcGender = Genders.Female;
            }

            // Get name bank - supports more races than are found in FACTION.TXT
            NameHelper.BankTypes bankType;
            switch (race)
            {
            case Races.Redguard:
                bankType = NameHelper.BankTypes.Redguard;
                break;

            case Races.Nord:
                bankType = NameHelper.BankTypes.Nord;
                break;

            case Races.DarkElf:
                bankType = NameHelper.BankTypes.DarkElf;
                break;

            case Races.HighElf:
                bankType = NameHelper.BankTypes.HighElf;
                break;

            case Races.WoodElf:
                bankType = NameHelper.BankTypes.WoodElf;
                break;

            case Races.Breton:
            default:
                bankType = NameHelper.BankTypes.Breton;
                break;
            }

            // Assign name - some types have their own individual name to use
            if (factionData.type == (int)FactionFile.FactionTypes.Individual ||
                factionData.type == (int)FactionFile.FactionTypes.Daedra)
            {
                // Use individual name
                displayName = factionData.name;
            }
            else
            {
                // Set a name seed if not configured
                if (nameSeed == -1)
                {
                    nameSeed = DateTime.Now.Millisecond;
                }

                // Generate a random name based on gender and race name bank
                DFRandom.srand(nameSeed);
                displayName = DaggerfallUnity.Instance.NameHelper.FullName(bankType, npcGender);
            }
        }
Пример #7
0
        /// <summary>
        /// Gets display name of NPC as fixed individual or from random seed.
        /// </summary>
        string GetDisplayName()
        {
            FactionFile.FactionData factionData;
            bool foundFaction = GameManager.Instance.PlayerEntity.FactionData.GetFactionData(npcData.factionID, out factionData);

            if (foundFaction && factionData.type == (int)FactionFile.FactionTypes.Individual)
            {
                return(factionData.name);
            }
            else
            {
                DFRandom.srand(npcData.nameSeed);
                return(DaggerfallUnity.Instance.NameHelper.FullName(npcData.nameBank, npcData.gender));
            }
        }
        public TextFile.Token[] InitPaintingInfo(int paintingTextId = 250)
        {
            GetMacroDataSource();
            if (ItemGroup == ItemGroups.Paintings && dataSource.paintingInfo == null)
            {
                DFRandom.srand(message);
                uint paintingIndex = DFRandom.rand() % 180;
                dataSource.paintingFileIdx = paintingIndex & 7;
                char paintingFileChar = (char)((paintingIndex >> 3) + 97);
                dataSource.paintingFilename = paintingFileChar + "paint.cif";

                byte[] paintingRecord = DaggerfallUnity.Instance.ContentReader.PaintFileReader.Read(paintingIndex);
                Debug.LogFormat("painting file: {0}, index: {1}, cif idx: {2}, record: {3} {4} {5}", dataSource.paintingFilename, paintingIndex, dataSource.paintingFileIdx, paintingRecord[0], paintingRecord[1], paintingRecord[2]);

                dataSource.paintingSub = GetPaintingRecordPart(paintingRecord, 0, 9) + 6100;   // for %sub macro
                dataSource.paintingAdj = GetPaintingRecordPart(paintingRecord, 10, 19) + 6200; // for %adj macro
                dataSource.paintingPp1 = GetPaintingRecordPart(paintingRecord, 20, 29) + 6300; // for %pp1 macro
                dataSource.paintingPp2 = GetPaintingRecordPart(paintingRecord, 30, 39) + 6400; // for %pp2 macro

                ITextProvider textProvider = DaggerfallUnity.Instance.TextProvider;
                dataSource.paintingInfo = textProvider.GetRandomTokens(paintingTextId, true);
            }
            return(dataSource.paintingInfo);
        }
        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);
        }
Пример #10
0
        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);
        }
Пример #11
0
 public override string Name()
 {
     // Set seed to the quest UID before falling through to random name generation. (See t=2108)
     DFRandom.srand((int)parent.UID);
     return(null);
 }
Пример #12
0
        void SelectCurrentSong()
        {
            if (currentPlaylist == null || currentPlaylist.Length == 0)
            {
                return;
            }

            int index = 0;

            // General MIDI song selection
            {
                uint gameMinutes = DaggerfallUnity.Instance.WorldTime.DaggerfallDateTime.ToClassicDaggerfallTime();
                DFRandom.srand(gameMinutes / 1440);
                uint random = DFRandom.rand();
                if (currentPlaylist == NightSongs)
                {
                    index = (int)(random % NightSongs.Length);
                }
                else if (currentPlaylist == SunnySongs)
                {
                    index = (int)(random % SunnySongs.Length);
                }
                else if (currentPlaylist == CloudySongs)
                {
                    index = (int)(random % CloudySongs.Length);
                }
                else if (currentPlaylist == OvercastSongs)
                {
                    index = (int)(random % OvercastSongs.Length);
                }
                else if (currentPlaylist == RainSongs)
                {
                    index = (int)(random % RainSongs.Length);
                }
                else if (currentPlaylist == SnowSongs)
                {
                    index = (int)(random % SnowSongs.Length);
                }
                else if (currentPlaylist == TempleSongs && playerEnterExit)
                {
                    byte[] templeFactions             = { 0x52, 0x54, 0x58, 0x5C, 0x5E, 0x62, 0x6A, 0x24 };
                    uint   factionOfPlayerEnvironment = playerEnterExit.FactionID;
                    index = Array.IndexOf(templeFactions, (byte)factionOfPlayerEnvironment);
                    if (index < 0)
                    {
                        byte[] godFactions = { 0x15, 0x16, 0x18, 0x1A, 0x1B, 0x1D, 0x21, 0x23 };
                        index = Array.IndexOf(godFactions, (byte)factionOfPlayerEnvironment);
                    }
                }
                else if (currentPlaylist == TavernSongs)
                {
                    index = (int)(gameMinutes / 1440 % TavernSongs.Length);
                }
                else if (currentPlaylist == DungeonInteriorSongs)
                {
                    PlayerGPS gps      = GameManager.Instance.PlayerGPS;
                    ushort    unknown2 = 0;
                    int       region   = 0;
                    if (gps.HasCurrentLocation)
                    {
                        unknown2 = (ushort)gps.CurrentLocation.Dungeon.RecordElement.Header.Unknown2;
                        region   = gps.CurrentRegionIndex;
                    }
                    DFRandom.srand(unknown2 ^ ((byte)region << 8));
                    random = DFRandom.rand();
                    index  = (int)(random % 15);
                }
                else if (currentPlaylist == SneakingSongs)
                {
                    index = UnityEngine.Random.Range(0, SneakingSongs.Length);
                }
            }
            currentSong      = currentPlaylist[index];
            currentSongIndex = index;
        }
Пример #13
0
        /// <summary>
        /// Generate a list of potential sites based on building type.
        /// This uses actual map layout and block data rather than the (often inaccurate) list of building in map data.
        /// Specify BuildingTypes.AllValid to find all valid building types
        /// </summary>
        SiteDetails[] CollectQuestSitesOfBuildingType(DFLocation location, DFLocation.BuildingTypes buildingType)
        {
            // Valid building types for valid search
            int[] validBuildingTypes = { 0, 2, 3, 5, 6, 8, 9, 11, 12, 13, 14, 15, 17, 18, 19, 20 };

            List <SiteDetails> foundSites = new List <SiteDetails>();

            // Iterate through all blocks
            DFBlock[] blocks;
            RMBLayout.GetLocationBuildingData(location, out blocks);
            int width  = location.Exterior.ExteriorData.Width;
            int height = location.Exterior.ExteriorData.Height;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    // Iterate through all buildings in this block
                    int index = y * width + x;
                    BuildingSummary[] buildingSummary = RMBLayout.GetBuildingData(blocks[index], x, y);
                    for (int i = 0; i < buildingSummary.Length; i++)
                    {
                        // When enumAllValid is specified accept all valid building types
                        bool forceAccept = false;
                        if (buildingType == DFLocation.BuildingTypes.AllValid)
                        {
                            for (int j = 0; j < validBuildingTypes.Length; j++)
                            {
                                if (validBuildingTypes[j] == (int)buildingSummary[i].BuildingType)
                                {
                                    forceAccept = true;
                                    break;
                                }
                            }
                        }

                        // Match building against required type
                        if (buildingSummary[i].BuildingType == buildingType || forceAccept)
                        {
                            // Building must be a valid quest site
                            QuestMarker[] questSpawnMarkers, questItemMarkers;
                            EnumerateBuildingQuestMarkers(blocks[index], i, out questSpawnMarkers, out questItemMarkers);
                            if (!ValidateQuestMarkers(questSpawnMarkers, questItemMarkers))
                            {
                                continue;
                            }

                            // Get building name based on type
                            string buildingName;
                            if (RMBLayout.IsResidence(buildingType))
                            {
                                // Generate a random surname for this residence
                                DFRandom.srand(Time.renderedFrameCount);
                                string surname = DaggerfallUnity.Instance.NameHelper.Surname(Utility.NameHelper.BankTypes.Breton);
                                buildingName = HardStrings.theNamedResidence.Replace("%s", surname);
                            }
                            else
                            {
                                // Use fixed name
                                buildingName = BuildingNames.GetName(
                                    buildingSummary[i].NameSeed,
                                    buildingSummary[i].BuildingType,
                                    buildingSummary[i].FactionId,
                                    location.Name,
                                    location.RegionName);
                            }

                            // Configure new site details
                            SiteDetails site = new SiteDetails();
                            site.questUID          = ParentQuest.UID;
                            site.siteType          = SiteTypes.Building;
                            site.mapId             = location.MapTableData.MapId;
                            site.locationId        = location.Exterior.ExteriorData.LocationId;
                            site.regionName        = location.RegionName;
                            site.locationName      = location.Name;
                            site.buildingKey       = buildingSummary[i].buildingKey;
                            site.buildingName      = buildingName;
                            site.questSpawnMarkers = questSpawnMarkers;
                            site.questItemMarkers  = questItemMarkers;

                            // Asssign markers only if available
                            if (questSpawnMarkers != null)
                            {
                                siteDetails.selectedQuestSpawnMarker = UnityEngine.Random.Range(0, questSpawnMarkers.Length);
                            }
                            if (questItemMarkers != null)
                            {
                                siteDetails.selectedQuestItemMarker = UnityEngine.Random.Range(0, questItemMarkers.Length);
                            }

                            foundSites.Add(site);
                        }
                    }
                }
            }

            return(foundSites.ToArray());
        }
Пример #14
0
        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);
        }