Ejemplo n.º 1
0
        /// <summary>
        /// Expands any macros found inside quest message tokens.
        /// </summary>
        /// <param name="parentQuest">Parent quest of message.</param>
        /// <param name="tokens">Array of message tokens to expand macros inside of.</param>
        public void ExpandQuestMessage(Quest parentQuest, ref TextFile.Token[] tokens)
        {
            // Iterate message tokens
            for (int token = 0; token < tokens.Length; token++)
            {
                // Split token text into individual words
                string[] words = GetWords(tokens[token].text);

                // Iterate words to find macros
                for (int word = 0; word < words.Length; word++)
                {
                    Macro macro = GetMacro(words[word]);
                    if (macro.type == MacroTypes.ContextMacro)
                    {
                        words[word] = words[word].Replace(macro.token, MacroHelper.GetValue(macro.token, parentQuest));
                    }
                    else
                    {
                        // Ask resource to expand macro if possible
                        QuestResource resource = parentQuest.GetResource(macro.symbol);
                        if (resource != null)
                        {
                            string result;
                            if (resource.ExpandMacro(macro.type, out result))
                            {
                                words[word] = words[word].Replace(macro.token, result);
                            }
                        }
                    }

                    // TODO: Need to store previous macro resource for pronomial context expansions
                }

                // Reassemble words and expanded macros back into final token text
                string final = string.Empty;
                for (int i = 0; i < words.Length; i++)
                {
                    final += words[i];
                    if (i != words.Length - 1)
                    {
                        final += " ";
                    }
                }

                // Store result back into token
                tokens[token].text = final;
            }
        }
        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);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Expands any macros found inside quest message tokens.
        /// </summary>
        /// <param name="parentQuest">Parent quest of message.</param>
        /// <param name="tokens">Array of message tokens to expand macros inside of.</param>
        /// <param name="resolveDialogLinks">will reveal dialog linked resources in talk window (this must be false for all calls to this function except if caller is talk manager when expanding answers).</param>
        public void ExpandQuestMessage(Quest parentQuest, ref TextFile.Token[] tokens, bool revealDialogLinks = false)
        {
            // Iterate message tokens
            for (int token = 0; token < tokens.Length; token++)
            {
                // Split token text into individual words
                string[] words = GetWords(tokens[token].text);

                // Iterate words to find macros
                for (int word = 0; word < words.Length; word++)
                {
                    Macro macro = GetMacro(words[word]);
                    if (macro.type == MacroTypes.ContextMacro)
                    {
                        words[word] = words[word].Replace(macro.token, MacroHelper.GetValue(macro.token, parentQuest));
                    }
                    else
                    {
                        // Ask resource to expand macro if possible
                        QuestResource resource = parentQuest.GetResource(macro.symbol);
                        if (resource != null)
                        {
                            string result;
                            if (resource.ExpandMacro(macro.type, out result))
                            {
                                words[word] = words[word].Replace(macro.token, result);
                            }

                            // reveal dialog linked resources in talk window
                            if (revealDialogLinks)
                            {
                                System.Type t = resource.GetType();
                                if (t.Equals(typeof(DaggerfallWorkshop.Game.Questing.Place)))
                                {
                                    GameManager.Instance.TalkManager.AddDialogForQuestInfoResource(parentQuest.UID, result, TalkManager.QuestInfoResourceType.Location);
                                }
                                else if (t.Equals(typeof(DaggerfallWorkshop.Game.Questing.Person)))
                                {
                                    GameManager.Instance.TalkManager.AddDialogForQuestInfoResource(parentQuest.UID, result, TalkManager.QuestInfoResourceType.Person);
                                }
                                else if (t.Equals(typeof(DaggerfallWorkshop.Game.Questing.Item)))
                                {
                                    GameManager.Instance.TalkManager.AddDialogForQuestInfoResource(parentQuest.UID, result, TalkManager.QuestInfoResourceType.Thing);
                                }
                            }
                        }
                    }

                    // TODO: Need to store previous macro resource for pronomial context expansions
                }

                // Reassemble words and expanded macros back into final token text
                string final = string.Empty;
                for (int i = 0; i < words.Length; i++)
                {
                    final += words[i];
                    if (i != words.Length - 1)
                    {
                        final += " ";
                    }
                }

                // Store result back into token
                tokens[token].text = final;
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Expands any macros found inside quest message tokens.
        /// </summary>
        /// <param name="parentQuest">Parent quest of message.</param>
        /// <param name="tokens">Array of message tokens to expand macros inside of.</param>
        /// <param name="resolveDialogLinks">will reveal dialog linked resources in talk window (this must be false for all calls to this function except if caller is talk manager when expanding answers or for quest popups).</param>
        public void ExpandQuestMessage(Quest parentQuest, ref TextFile.Token[] tokens, bool revealDialogLinks = false)
        {
            // Iterate message tokens
            for (int token = 0; token < tokens.Length; token++)
            {
                // Split token text into individual words
                string[] words = GetWords(tokens[token].text);

                // Iterate words to find macros
                for (int word = 0; word < words.Length; word++)
                {
                    Macro macro = GetMacro(words[word]);
                    if (macro.type == MacroTypes.ContextMacro)
                    {
                        words[word] = words[word].Replace(macro.token, MacroHelper.GetValue(macro.token, parentQuest, parentQuest.ExternalMCP));
                    }
                    else
                    {
                        // fix for bug when parent quest is no longer available (http://forums.dfworkshop.net/viewtopic.php?f=24&t=1002) in case
                        // quest injected entries and rumors stay in list due to other bugs
                        // so parentQuest is no longer available
                        if (parentQuest == null)
                        {
                            return;
                        }

                        // Ask resource to expand macro if possible
                        QuestResource resource = parentQuest.GetResource(macro.symbol);
                        if (resource != null)
                        {
                            string result;
                            if (resource.ExpandMacro(macro.type, out result))
                            {
                                words[word] = words[word].Replace(macro.token, result);
                            }

                            // reveal dialog linked resources in talk window
                            if (revealDialogLinks && macro.type == MacroTypes.NameMacro1) // only resolve if their true name was expanded (given) which is MacroTypes.NameMacro1
                            {
                                System.Type t = resource.GetType();
                                if (t.Equals(typeof(DaggerfallWorkshop.Game.Questing.Place)))
                                {
                                    GameManager.Instance.TalkManager.AddDialogForQuestInfoResource(parentQuest.UID, macro.symbol, TalkManager.QuestInfoResourceType.Location);
                                }
                                else if (t.Equals(typeof(DaggerfallWorkshop.Game.Questing.Person)))
                                {
                                    GameManager.Instance.TalkManager.AddDialogForQuestInfoResource(parentQuest.UID, macro.symbol, TalkManager.QuestInfoResourceType.Person);
                                }
                                else if (t.Equals(typeof(DaggerfallWorkshop.Game.Questing.Item)))
                                {
                                    GameManager.Instance.TalkManager.AddDialogForQuestInfoResource(parentQuest.UID, macro.symbol, TalkManager.QuestInfoResourceType.Thing);
                                }
                            }
                        }
                    }

                    // TODO: Need to store previous macro resource for pronomial context expansions
                }

                // Reassemble words and expanded macros back into final token text
                string final = string.Empty;
                for (int i = 0; i < words.Length; i++)
                {
                    final += words[i];
                    if (i != words.Length - 1)
                    {
                        final += " ";
                    }
                }

                // Store result back into token
                tokens[token].text = final;
            }
        }
Ejemplo n.º 5
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);
        }