/// <summary>
    /// Gets the localized string from an already loaded table, taking into account whether we are in edit mode, play mode, or a build.
    /// </summary>
    /// <param name="localizedStringReference">The <see cref="LocalizedString"/>.</param>
    /// <returns>The localized string.</returns>

    public static string GetLocalizedStringImmediateSafe(this LocalizedString localizedStringReference)
    {
        // If we are in the editor in edit mode, we need to find a valid locale and get the localized string from it:
#if UNITY_EDITOR
        if (EditorApplication.isPlaying)
        {
            return(string.Empty);
        }

        string text = null;
        if (!localizedStringReference.IsEmpty)
        {
            var    tableCollection = LocalizationEditorSettings.GetStringTableCollection(localizedStringReference.TableReference);
            Locale locale          = Editor_GetValidLocaleInEditMode(tableCollection);
            if (locale != null)
            {
                StringTable table = (StringTable)tableCollection.GetTable(locale.Identifier);
                if (table != null)
                {
                    if (table.GetEntryFromReference(localizedStringReference.TableEntryReference) != null)
                    {
                        text = table.GetEntryFromReference(localizedStringReference.TableEntryReference).LocalizedValue;
                    }
                }
            }
        }
        return(text);
#else
        // At runtime (build or editor in play mode), we just get the localized string normally:
        return(localizedStringReference.GetLocalizedString());
#endif
    }
Example #2
0
    public void SetupTableOverrideInEditor()
    {
        // Get the 2 table collections. 1 for default and 1 for our chosen platform (PS4).
        var collection    = LocalizationEditorSettings.GetStringTableCollection("My Strings");
        var collectionPs4 = LocalizationEditorSettings.GetStringTableCollection("My Strings PS4");

        var englishTable    = collection.GetTable("en") as StringTable;
        var englishTablePs4 = collectionPs4.GetTable("en") as StringTable;

        // Add the default entry
        var entry = englishTable.AddEntry("COPYRIGHT_NOTICE", "This is some copyright info for general platforms...");

        // Add the entry we want to use on PS4 using the same entry name.
        englishTablePs4.AddEntry("COPYRIGHT_NOTICE", "This is some copyright info for PS4 platforms...");

        // Set up the platform override so that COPYRIGHT_NOTICE redirects to a different table but uses the same key.
        var platformOverride = new PlatformOverride();

        platformOverride.AddPlatformTableOverride(RuntimePlatform.PS4, "My Strings PS4");
        entry.SharedEntry.Metadata.AddMetadata(platformOverride);

        // Mark the assets dirty so changes are saved
        EditorUtility.SetDirty(collection.SharedData);
        EditorUtility.SetDirty(englishTable);
    }
        static void WriteLocalizedValue(string valueName, StreamWriter stream, Locale locale, LocalizedString localizedString, PlistDocument plistDocument)
        {
            if (localizedString.IsEmpty)
            {
                return;
            }

            var tableCollection = LocalizationEditorSettings.GetStringTableCollection(localizedString.TableReference);
            var table           = tableCollection?.GetTable(locale.Identifier) as StringTable;
            var entry           = table?.GetEntryFromReference(localizedString.TableEntryReference);

            if (entry == null || string.IsNullOrWhiteSpace(entry.LocalizedValue))
            {
                // Use fallback?
                var fallBack = FallbackLocaleHelper.GetLocaleFallback(locale);
                if (fallBack != null)
                {
                    WriteLocalizedValue(valueName, stream, fallBack, localizedString, plistDocument);
                    return;
                }

                Debug.LogWarning($"{valueName}: Could not find a localized value for {locale} from {localizedString}");
                return;
            }

            Debug.Assert(!entry.IsSmart, $"Localized App Values ({valueName}) do not support Smart Strings - {localizedString}");
            stream.WriteLine($"\"{valueName}\" = \"{entry.LocalizedValue}\";");

            plistDocument.root.SetString(valueName, string.Empty);
        }
Example #4
0
    void SetDialogueLines()
    {
        _dialogueLines.Clear();

        StringTableCollection collection = LocalizationEditorSettings.GetStringTableCollection("Questline Dialogue");

        if (collection != null)
        {
            int             index         = 0;
            LocalizedString _dialogueLine = null;
            do
            {
                index++;
                string key = "L" + index + "-" + this.name;

                if (collection.SharedData.Contains(key))
                {
                    _dialogueLine = new LocalizedString()
                    {
                        TableReference = "Questline Dialogue", TableEntryReference = key
                    };
                    _dialogueLines.Add(_dialogueLine);
                }
                else
                {
                    _dialogueLine = null;
                }
            } while (_dialogueLine != null);
        }
    }
Example #5
0
        private void Initialize()
        {
            if (ID != UInt32.MaxValue && childId != UInt32.MaxValue)
            {
                // Only get the first dialogue.
                startDialogue = DialogueLine.ConvertRow(TableDatabase.Get.GetRow("dialogues", childId),
                                                        overrideTable ? collection : LocalizationEditorSettings.GetStringTableCollection("Dialogues"));

                var field = TableDatabase.Get.GetField(Name, "data", ID);
                if (field != null)
                {
                    StoryTable.ParseNodeData(this, (JObject)field.Data);
                }
            }

            if (characterID != UInt32.MaxValue)
            {
                TableDatabase          database = TableDatabase.Get;
                Tuple <uint, TableRow> link     = database.FindLink("characters", "name", characterID);
                if (link != null)
                {
                    var field = database.GetField(link.Item2, "name");
                    if (field != null)
                    {
                        characterName = (string)field.Data;
                    }

                    Debug.Log(characterName);
                }
            }
        }
Example #6
0
    public void RemoveLineFromSharedTable()
    {
        StringTableCollection collection = LocalizationEditorSettings.GetStringTableCollection("Questline Dialogue");

        if (collection != null)
        {
            int             index         = 0;
            LocalizedString _dialogueLine = null;



            do
            {
                index++;
                string key = "L" + index + "-" + this.name;

                if (collection.SharedData.Contains(key))
                {
                    collection.SharedData.RemoveKey(key);
                }
                else
                {
                    _dialogueLine = null;
                }
            } while (_dialogueLine != null);
        }
    }
        public static void PullEnglish()
        {
            // Setup the connection to Google
            var sheetServiceProvider = GetServiceProvider();
            var googleSheets         = new GoogleSheets(sheetServiceProvider);

            googleSheets.SpreadSheetId = "My spread sheet id"; // We need to provide the Spreadsheet id. This can be found in the url. See docs for further info.

            // You should provide your String Table Collection name here
            var tableCollection = LocalizationEditorSettings.GetStringTableCollection("My Strings");

            // We need configure what each column contains in the sheet
            var columnMappings = new SheetColumn[]
            {
                // Column A contains the Key
                new KeyColumn {
                    Column = "A"
                },

                // Column B contains any shared comments. These are Comment Metadata in the Shared category.
                new KeyCommentColumn {
                    Column = "B"
                },

                // Column C contains the English Locale and any comments that are just for this Locale.
                new LocaleColumn {
                    Column = "C", LocaleIdentifier = "en", IncludeComments = true
                },
            };

            int mySheetId = 123456; // This it the id of the sheet in the Google Spreadsheet. it will be in the url after `gid=`.

            googleSheets.PullIntoStringTableCollection(mySheetId, tableCollection, columnMappings);
        }
Example #8
0
        // Gets string table from collection name and locale code
        private static StringTable GetSourceStringTable(string source, string locale)
        {
            // Get source string table collection
            var sourceCollection = LocalizationEditorSettings.GetStringTableCollection(source);

            if (sourceCollection == null)
            {
                Debug.LogErrorFormat("GetSourceStringTable() could not find source string table collection '{0}'", source);
                return(null);
            }

            // Find table in source collection with locale code
            StringTable sourceTable = null;

            foreach (StringTable table in sourceCollection.StringTables)
            {
                if (table.LocaleIdentifier == locale)
                {
                    sourceTable = table;
                    break;
                }
            }

            // Handle table not found
            if (sourceTable == null)
            {
                Debug.LogErrorFormat("GetSourceStringTable() could not find source string table with locale code '{0}' in collection '{1}'", locale, source);
                return(null);
            }

            return(sourceTable);
        }
    public LocalizedString GenerateLocalizedStringInEditor()
    {
        // The main advantage to using a table Guid and entry Id is that references will not be lost when changes are made to the Table name or Entry name.
        var collection = LocalizationEditorSettings.GetStringTableCollection("My String Table");
        var entry      = collection.SharedData.GetEntry("Start Game");

        return(new LocalizedString(collection.SharedData.TableCollectionNameGuid, entry.Id));
    }
        /// <summary>
        /// This example show how to export a collection with default settings.
        /// </summary>
        public static void SimpleExport()
        {
            var collection = LocalizationEditorSettings.GetStringTableCollection("My Strings");

            using (var stream = new StreamWriter("My Strings CSV.csv", false, Encoding.UTF8))
            {
                Csv.Export(stream, collection);
            }
        }
        /// <summary>
        /// This example show how to import a collection with default settings.
        /// </summary>
        public static void SimpleImport()
        {
            var collection = LocalizationEditorSettings.GetStringTableCollection("My Strings");

            using (var stream = new StreamReader("My Strings CSV.csv"))
            {
                Csv.ImportInto(stream, collection);
            }
        }
        public static void ImportCustomColumns()
        {
            var collection = LocalizationEditorSettings.GetStringTableCollection("My Strings");

            // Use custom column mappings to control what data gets imported.
            var columns = CreateCustomColumnMapping();

            using (var stream = new StreamReader("My Strings CSV.csv"))
            {
                Csv.ImportInto(stream, collection, columns);
            }
        }
        /// <summary>
        /// This example shows how to configure the data you wish to export in CSV.
        /// </summary>
        public static void ExportCustomColumns()
        {
            var collection = LocalizationEditorSettings.GetStringTableCollection("My Strings");

            // Use custom column mappings to control what data gets exported
            var columns = CreateCustomColumnMapping();

            // Now export
            using (var stream = new StreamWriter("My Strings CSV.csv", false, Encoding.UTF8))
            {
                Csv.Export(stream, collection, columns);
            }
        }
        void DoTableAndEntryGUI(Rect rect, SerializedProperty property)
        {
            var        tableRef = new SerializedTableReference(property.FindPropertyRelative("tableReference"));
            var        entryRef = new SerializedTableEntryReference(property.FindPropertyRelative("tableEntryReference"));
            GUIContent valueLabel;

            if (tableRef.Reference.ReferenceType != TableReference.Type.Empty && entryRef.Reference.ReferenceType != TableEntryReference.Type.Empty)
            {
                LocalizationTableCollection collection = null;
                if (m_TableType == typeof(StringTable))
                {
                    collection = LocalizationEditorSettings.GetStringTableCollection(tableRef.Reference);
                }
                else
                {
                    collection = LocalizationEditorSettings.GetAssetTableCollection(tableRef.Reference);
                }
                valueLabel = new GUIContent($"{GetTableLabel(tableRef.Reference)}/{GetEntryLabel(entryRef.Reference, collection?.SharedData)}");
            }
            else
            {
                valueLabel = Styles.none;
            }

            var dropDownPosition = EditorGUI.PrefixLabel(rect, Styles.reference);

            if (EditorGUI.DropdownButton(dropDownPosition, valueLabel, FocusType.Passive))
            {
                Type assetType;
                if (m_TableType == typeof(AssetTable))
                {
                    var assetTableCollection = m_Collection as AssetTableCollection;
                    assetType = assetTableCollection.GetEntryAssetType(entryRef.Reference);
                }
                else
                {
                    assetType = typeof(string);
                }

                var treeSelection = new TableEntryTreeView(assetType, (c, e) =>
                {
                    entryRef.Reference = e != null ? e.Id : SharedTableData.EmptyId;
                    tableRef.Reference = c != null ? c.TableCollectionNameReference : default(TableReference);
                    property.serializedObject.ApplyModifiedProperties();
                });
                PopupWindow.Show(dropDownPosition, new TreeViewPopupWindow(treeSelection)
                {
                    Width = dropDownPosition.width
                });
            }
        }
        public static void PullWithExtension()
        {
            // You should provide your String Table Collection name here
            var tableCollection = LocalizationEditorSettings.GetStringTableCollection("My Strings");
            var googleExtension = tableCollection.Extensions.FirstOrDefault(e => e is GoogleSheetsExtension) as GoogleSheetsExtension;

            if (googleExtension == null)
            {
                Debug.LogError($"String Table Collection {tableCollection.TableCollectionName} Does not contain a Google Sheets Extension.");
                return;
            }

            PullExtension(googleExtension);
        }
Example #16
0
    public void ChangeKeyGenerator()
    {
        var stringTableCollection = LocalizationEditorSettings.GetStringTableCollection("My Game Text");

        // Determine the highest Key Id so Unity can continue generating Ids that do not conflict with existing Ids.
        long maxKeyId = 0;

        if (stringTableCollection.SharedData.Entries.Count > 0)
        {
            maxKeyId = stringTableCollection.SharedData.Entries.Max(e => e.Id);
        }

        stringTableCollection.SharedData.KeyGenerator = new SequentialIDGenerator(maxKeyId + 1);

        // Mark the asset dirty so that Unity saves the changes
        EditorUtility.SetDirty(stringTableCollection.SharedData);
    }
Example #17
0
        static void GenerateLocalizedXmlFile(string valueName, string filePath, Locale locale, AppInfo appinfo)
        {
            var localizedString = appinfo.DisplayName;

            if (localizedString.IsEmpty)
            {
                return;
            }

            var tableCollection = LocalizationEditorSettings.GetStringTableCollection(localizedString.TableReference);
            var table           = tableCollection?.GetTable(locale.Identifier) as StringTable;
            var entry           = table?.GetEntryFromReference(localizedString.TableEntryReference);

            if (entry == null || string.IsNullOrWhiteSpace(entry.LocalizedValue))
            {
                // Use fallback?
                var fallBack = FallbackLocaleHelper.GetLocaleFallback(locale);
                if (fallBack != null)
                {
                    GenerateLocalizedXmlFile(valueName, filePath, fallBack, appinfo);
                    return;
                }

                Debug.LogWarning($"{valueName}: Could not find a localized value for {locale} from {localizedString}");
                return;
            }
            Debug.Assert(!entry.IsSmart, $"Localized App Values ({valueName}) do not support Smart Strings - {localizedString}");
            Debug.Assert(!entry.LocalizedValue.Contains("'"), $"Localized App Value ({valueName}) does not support Single Quote. \nEntry contains invalid character: {localizedString}\n{entry.LocalizedValue}");

            using (var stream = new StreamWriter(filePath, false, Encoding.UTF8))
            {
                stream.WriteLine(
                    $@"<?xml version=""1.0"" encoding=""utf-8""?>" +
                    "<!--" +
                    "\n" +
                    $"\t{k_InfoFile}\n" +
                    $"\tThis file was auto-generated by {LocalizationPackageInfo.name}\n" +
                    $"\tVersion {LocalizationPackageInfo.version}\n" +
                    $"\tChanges to this file may cause incorrect behavior and will be lost if the project is rebuilt.\n" +
                    $"-->" +
                    "\n" +
                    $@"<resources>
                       <string name=""app_name""> {entry.LocalizedValue} </string>
                       </resources>");
            }
        }
        public static void PushProjectLocales()
        {
            // Setup the connection to Google
            var sheetServiceProvider = GetServiceProvider();
            var googleSheets         = new GoogleSheets(sheetServiceProvider);

            googleSheets.SpreadSheetId = "My spread sheet id"; // We need to provide the Spreadsheet id. This can be found in the url. See docs for further info.

            // Prepare the data we want to push.
            // You should provide your String Table Collection name here
            var tableCollection = LocalizationEditorSettings.GetStringTableCollection("My Strings");

            // CreateDefaultMapping will create a KeyColumn and a LocaleColumn for each Locale in the project.
            var columnMappings = ColumnMapping.CreateDefaultMapping();
            int mySheetId      = 123456; // This it the id of the sheet in the Google Spreadsheet. it will be in the url after `gid=`.

            // Now send the update. We can pass in an optional ProgressBarReporter so that we can see updates in the Editor.
            googleSheets.PushStringTableCollection(mySheetId, tableCollection, columnMappings, new ProgressBarReporter());
        }
Example #19
0
    public void CreateLine()
    {
        if (_dialogueLines == null)
        {
            _dialogueLines = new List <LocalizedString>();
        }
        _dialogueLines.Clear();
        StringTableCollection collection = LocalizationEditorSettings.GetStringTableCollection("Questline Dialogue");

        if (collection != null)
        {
            string DefaultKey = "L" + 1 + "-" + this.name;
            if (!collection.SharedData.Contains(DefaultKey))
            {
                collection.SharedData.AddKey(DefaultKey);
            }
        }
        SetDialogueLines();
    }
Example #20
0
        static StringTableCollection FindProjectCollection(IGroup group)
        {
            // Is the Id the Shared table data GUID?
            if (!string.IsNullOrEmpty(group.Id))
            {
                var path = AssetDatabase.GUIDToAssetPath(group.Id);
                if (!string.IsNullOrEmpty(path))
                {
                    var sharedTableData = AssetDatabase.LoadAssetAtPath <SharedTableData>(path);
                    if (sharedTableData != null)
                    {
                        return(LocalizationEditorSettings.GetCollectionForSharedTableData(sharedTableData) as StringTableCollection);
                    }
                }
            }

            // Try table name instead
            return(LocalizationEditorSettings.GetStringTableCollection(group.Id) ?? LocalizationEditorSettings.GetStringTableCollection(group.Name));
        }
Example #21
0
        /// <summary>
        /// Clear a named StringTable collection.
        /// </summary>
        /// <param name="name">StringTable collection to clear.</param>
        public static void ClearStringTables(string name)
        {
            var collection = LocalizationEditorSettings.GetStringTableCollection(name);

            if (collection == null)
            {
                return;
            }

            // Clear tables in collection
            foreach (StringTable table in collection.StringTables)
            {
                table.Clear();
                EditorUtility.SetDirty(table);
            }

            // Clear shared data entries
            collection.SharedData.Entries.Clear();
            EditorUtility.SetDirty(collection.SharedData);
        }
Example #22
0
    public void SetupEntryOverrideInEditor()
    {
        var collection   = LocalizationEditorSettings.GetStringTableCollection("My Strings");
        var englishTable = collection.GetTable("en") as StringTable;

        // Add the default entry
        var entry = englishTable.AddEntry("COPYRIGHT_NOTICE", "This is some copyright info for general platforms...");

        // Add the entry we want to use on PS4
        englishTable.AddEntry("COPYRIGHT_NOTICE_PS4", "This is some copyright info for PS4 platforms...");

        // Set up the platform override so that COPYRIGHT_NOTICE redirects to COPYRIGHT_NOTICE_PS4 when running on PS4.
        var platformOverride = new PlatformOverride();

        platformOverride.AddPlatformEntryOverride(RuntimePlatform.PS4, "COPYRIGHT_NOTICE_PS4");
        entry.SharedEntry.Metadata.AddMetadata(platformOverride);

        // Mark the assets dirty so changes are saved
        EditorUtility.SetDirty(collection.SharedData);
        EditorUtility.SetDirty(englishTable);
    }
Example #23
0
        private void Initialize()
        {
            if (ID != UInt32.MaxValue)
            {
                var entryId = (ID + 1).ToString();

                collection = overrideTable ? collection : LocalizationEditorSettings.GetStringTableCollection("Characters");

                if (collection)
                {
                    characterName = new LocalizedString {
                        TableReference = collection.TableCollectionNameReference, TableEntryReference = entryId
                    }
                }
                ;
                else
                {
                    Debug.LogWarning("Collection not found. Did you create any localization tables");
                }
            }
        }
        public static void PullProjectLocales()
        {
            // Setup the connection to Google
            var sheetServiceProvider = GetServiceProvider();
            var googleSheets         = new GoogleSheets(sheetServiceProvider);

            googleSheets.SpreadSheetId = "My spread sheet id"; // We need to provide the Spreadsheet id. This can be found in the url. See docs for further info.

            // You should provide your String Table Collection name here
            var tableCollection = LocalizationEditorSettings.GetStringTableCollection("My Strings");

            // CreateDefaultMapping will create a KeyColumn and a LocaleColumn for each Locale in the project.
            // This assumes that the table was created and pushed to using the same column mappings.
            var columnMappings = ColumnMapping.CreateDefaultMapping();
            int mySheetId      = 123456; // This it the id of the sheet in the Google Spreadsheet. it will be in the url after `gid=`.

            // Now pull.
            // removeMissingEntries will remove any Keys that we have in the String Table Collection that do not exist in the Pull update.
            // reporter is an optional reporter that can be used to povide feedback in the editor during the Pull.
            googleSheets.PullIntoStringTableCollection(mySheetId, tableCollection, columnMappings, removeMissingEntries: true, reporter: new ProgressBarReporter());
        }
Example #25
0
    public Line(string _name)
    {
        StringTableCollection collection = LocalizationEditorSettings.GetStringTableCollection("Questline Dialogue");

        _textList = null;
        if (collection != null)
        {
            int             lineIndex     = 0;
            LocalizedString _dialogueLine = null;
            do
            {
                lineIndex++;
                string key = "L" + lineIndex + "-" + _name;
                if (collection.SharedData.Contains(key))
                {
                    SetActor(collection.SharedData.GetEntry(key).Metadata.GetMetadata <Comment>());
                    _dialogueLine = new LocalizedString()
                    {
                        TableReference = "Questline Dialogue", TableEntryReference = key
                    };
                    if (_textList == null)
                    {
                        _textList = new List <LocalizedString>();
                    }
                    _textList.Add(_dialogueLine);
                }
                else
                {
                    _dialogueLine = null;
                }
            } while (_dialogueLine != null);

            int    choiceIndex = 0;
            Choice choice      = null;
            do
            {
                choiceIndex++;
                string key = "C" + choiceIndex + "-" + _name;

                if (collection.SharedData.Contains(key))
                {
                    LocalizedString _choiceLine = new LocalizedString()
                    {
                        TableReference = "Questline Dialogue", TableEntryReference = key
                    };
                    choice = new Choice(_choiceLine);
                    choice.SetChoiceAction(collection.SharedData.GetEntry(key).Metadata.GetMetadata <Comment>());

                    if (_choices == null)
                    {
                        _choices = new List <Choice>();
                    }
                    _choices.Add(choice);
                }
                else
                {
                    choice = null;
                }
            } while (choice != null);
        }
        else
        {
            _textList = null;
        }
    }
            /// <summary>
            /// Grab the next dialogue
            /// nextDialogue = ConvertRow(TableDatabase.Get.GetRow("dialogues", nextDialogueID));
            /// Set the dialogue options associated to the dialogue.
            /// CheckDialogueOptions(nextDialogue);
            /// so input has a connection member that consists of three values
            /// node -> reference to the other node.
            /// output -> reference to the key that consist of the value
            /// so in order to grab the data go to the node
            /// fetch the data
            /// if it is an option take options[$`optionOut-key`] and then the value
            /// if it is a dialogue take data["dialogueId"] -> can be Number.MAX_SAFE_INTEGER
            /// so output has a connection member that consists of three values
            /// node -> reference to the other node.
            /// input -> reference to the key that consist of the value
            /// so in order to grab the data go to the node
            /// fetch the data
            /// if it is an option take options[$`optionOut-key`] and then the value
            /// if it is a dialogue take data["dialogueId"] -> can be Number.MAX_SAFE_INTEGER
            /// </summary>
            /// <param name="currentDialogue"></param>
            /// <param name="story"></param>
            /// <param name="node"></param>
            /// <param name="nodes"></param>
            private static void ParseNextNodeData(StorySO story, IDialogueLine currentDialogue, JObject node, JObject nodes)
            {
                if (node["data"] == null)
                {
                    return;
                }

                var data = node["data"].ToObject <JObject>();

                // check what is inside the node
                if (data != null)
                {
                    // get the outputs
                    var outputs = node["outputs"].ToObject <JObject>();

                    // loop through the outputs
                    // Outputs can be
                    // Dialogue to dialogue
                    // option to dialogue
                    foreach (var outputToken in outputs)
                    {
                        var output      = outputToken.Value.ToObject <JObject>();
                        var connections = output["connections"].ToArray();
                        var emptyObj    = new JObject();

                        string  nodeId;
                        JObject otherNode;
                        JObject otherData;
                        if (outputToken.Key.Contains("Exec") && connections.Length > 0)
                        {
                            foreach (var con in connections)
                            {
                                // grab the other node id.
                                nodeId = con["node"]?.ToObject <int>().ToString() ?? String.Empty;
                                // grab the other node object.
                                otherNode = nodeId != String.Empty ? nodes[nodeId].Value <JObject>() : emptyObj;
                                // grab the data from the other node.
                                otherData = otherNode["data"]?.ToObject <JObject>() ?? emptyObj;

                                if (currentDialogue != null)
                                {
                                    // fetch the event name
                                    var eventId   = otherData["eventId"]?.ToObject <uint>() ?? UInt32.MaxValue;
                                    var eventName = "";
                                    if (eventId != UInt32.MaxValue)
                                    {
                                        var row = TableDatabase.Get.GetRow("events", eventId);

                                        // validate the data
                                        if (row.Fields.Count > 0)
                                        {
                                            var field = row.Find("name");
                                            if (field != null)
                                            {
                                                eventName = (string)field.Data;
                                            }
                                        }
                                        // fetch the parameters
                                        //  TODO mark event value as dynamic to support multiple parameters
                                        JObject events = otherData["events"]?.ToObject <JObject>() ?? emptyObj;
                                        foreach (var @event in events)
                                        {
                                            // int value = @event.Value["value"]["value"].ToObject<int>();
                                            currentDialogue.DialogueEvent = new DialogueEventSO(eventName, story);
                                        }
                                    }
                                }
                            }
                        }

                        // see if we have a connection
                        // if (connections.Length == 0)
                        // continue;

                        // See if we are dealing with an option
                        bool containsOption = outputToken.Key.Contains("option");

                        var connection = connections.Length > 0 ? connections[0] : emptyObj;
                        // grab the other node id.
                        nodeId = connection["node"]?.ToObject <int>().ToString() ?? String.Empty;
                        // grab the other node object.
                        otherNode = nodeId != String.Empty ? nodes[nodeId].Value <JObject>() : emptyObj;
                        // grab the data from the other node.
                        otherData = otherNode["data"]?.ToObject <JObject>() ?? emptyObj;

                        if (currentDialogue != null)
                        {
                            // Fetch the other dialogueId
                            var nextId = otherData["dialogueId"]?.ToObject <uint>() ?? UInt32.MaxValue;

                            // if this node does not consist of any choices
                            // go this way
                            if (!containsOption)
                            {
                                // validate the data
                                currentDialogue.NextDialogue = nextId != UInt32.MaxValue ?
                                                               DialogueLine.ConvertRow(TableDatabase.Get.GetRow("dialogues", nextId),
                                                                                       story.overrideTable ? story.collection : LocalizationEditorSettings.GetStringTableCollection("Dialogues"))
                                                                        : null;

                                // Debug.Log(" Next: " + currentDialogue.NextDialogue);

                                // now we have the next id check if we have a node that comes after.
                                ParseNextNodeData(story, currentDialogue.NextDialogue, otherNode, nodes);
                            }
                            else
                            {
                                // grab the choice id from the current node.
                                var optionId = data["options"][outputToken.Key]["value"].ToObject <uint>();

                                // Grab the choice
                                DialogueChoiceSO choice = DialogueChoiceSO.ConvertRow(TableDatabase.Get.GetRow("dialogueOptions", optionId),
                                                                                      story.overrideDialogueOptionsTable ? story.dialogueOptionsCollection : LocalizationEditorSettings.GetStringTableCollection("DialogueOptions")
                                                                                      );

                                // find the next dialogue of this choice.
                                choice.NextDialogue = nextId != UInt32.MaxValue ?
                                                      DialogueLine.ConvertRow(TableDatabase.Get.GetRow("dialogues", nextId),
                                                                              story.overrideTable ? story.collection : LocalizationEditorSettings.GetStringTableCollection("Dialogues"))
                                                                        : null;

                                // Debug.Log(" Choice: " + choice);

                                // add the choices to the currentDialogue
                                currentDialogue.Choices.Add(choice);

                                // Set the nextDialogue to null because we are dealing with a choice
                                currentDialogue.NextDialogue = null;

                                // Find the next dialogue for the choice
                                ParseNextNodeData(story, choice.NextDialogue, otherNode, nodes);
                            }
                        }
                    }
                }
            }
        /// <summary>
        /// Helper to import TEXT.RSC from classic game data into specified StringTable.
        /// WARNING: Named StringTable collection will be cleared and replaced with data from game files.
        /// </summary>
        /// <param name="name">StringTable collection name to receive TEXT.RSC data.</param>
        public static void ImportTextRSCToStringTables(string name)
        {
            // Clear all tables
            ClearStringTables(name);

            // Load character mapping table
            Table     charMappingTable = null;
            TextAsset mappingTableText = Resources.Load <TextAsset>(textMappingTableFilename);

            if (mappingTableText)
            {
                charMappingTable = new Table(mappingTableText.text);
            }

            // Load default TEXT.RSC file
            TextFile defaultRSC = new TextFile(DaggerfallUnity.Instance.Arena2Path, TextFile.Filename);

            if (defaultRSC == null || defaultRSC.IsLoaded == false)
            {
                throw new Exception("Could not load default TEXT.RSC");
            }

            // Get string tables collection
            var collection = LocalizationEditorSettings.GetStringTableCollection(name);

            if (collection == null)
            {
                return;
            }

            // Add all text records to each table
            foreach (StringTable table in collection.StringTables)
            {
                bool en = table.LocaleIdentifier.Code == enLocaleCode;

                TextFile rsc       = defaultRSC;
                TextFile localeRSC = LoadCustomLocaleTextRSC(table.LocaleIdentifier.Code);
                if (localeRSC != null)
                {
                    rsc = localeRSC;
                }

                for (int i = 0; i < defaultRSC.RecordCount; i++)
                {
                    // Extract this record to tokens
                    byte[]           buffer = rsc.GetBytesByIndex(i);
                    TextFile.Token[] tokens = TextFile.ReadTokens(ref buffer, 0, TextFile.Formatting.EndOfRecord);

                    // Get token key and text
                    int id = rsc.IndexToId(i);
                    if (id == -1)
                    {
                        continue;
                    }
                    string key  = MakeTextRSCKey(id);
                    string text = ConvertRSCTokensToString(tokens);

                    // Remap characters when mapping table present
                    if (charMappingTable != null)
                    {
                        text = RemapCharacters(table.LocaleIdentifier.Code, text, charMappingTable);
                    }

                    // Add text to table
                    table.AddEntry(key, text);

                    // Add shared keys only when reading en table
                    // These keys match across entire collection
                    if (en)
                    {
                        collection.SharedData.AddKey(key);
                    }
                }

                // Set table dirty
                EditorUtility.SetDirty(table);
                Debug.LogFormat("Added {0} TEXT.RSC entries to table {1}", rsc.RecordCount, table.LocaleIdentifier.Code);
            }

            // Set shared data dirty
            EditorUtility.SetDirty(collection.SharedData);
        }
Example #28
0
        /// <summary>
        /// Copies default Internal_Strings EN to all string tables in target collection.
        /// </summary>
        /// <param name="target">Target string table collection name.</param>
        /// <param name="overwriteExistingKeys">When true will overwrite existing keys with source string. When false existing keys are left unchanged.</param>
        public static void CopyInternalStringTable(string target, bool overwriteExistingKeys)
        {
            // Use default Internal_Strings collection with EN locale code as source
            string sourceCollectionName = TextManager.defaultInternalStringsCollectionName;
            string sourceLocaleCode     = enLocaleCode;

            // Do nothing if target not set
            if (string.IsNullOrEmpty(target))
            {
                return;
            }

            // Target cannot be same as default
            if (string.Compare(target, sourceCollectionName, true) == 0)
            {
                Debug.LogError("CopyInternalStringTable() target cannot be same as default");
                return;
            }

            // Get target string table collection
            var targetCollection = LocalizationEditorSettings.GetStringTableCollection(target);

            if (targetCollection == null)
            {
                Debug.LogErrorFormat("CopyInternalStringTable() could not find target string table collection '{0}'", target);
                return;
            }

            // Get source string table
            StringTable sourceTable = GetSourceStringTable(sourceCollectionName, sourceLocaleCode);

            if (!sourceTable)
            {
                Debug.LogErrorFormat("CopyInternalStringTable() could not find source table '{0}' with locale '{1}'", sourceCollectionName, sourceLocaleCode);
                return;
            }

            // Copy source strings to all tables in target collection
            int totalSourceEntries = sourceTable.SharedData.Entries.Count;
            int copiedNew          = 0;
            int copiedOverwrite    = 0;

            foreach (StringTable targetTable in targetCollection.StringTables)
            {
                // Iterate through all string table values found in source table
                foreach (var item in sourceTable.SharedData.Entries)
                {
                    string key         = item.Key;
                    var    sourceEntry = sourceTable.GetEntry(key);
                    if (sourceEntry == null)
                    {
                        Debug.LogWarningFormat("CopyInternalStringTable() could not find source table entry for key '{0}'", key);
                        continue;
                    }

                    var targetEntry = targetTable.GetEntry(key);
                    if (targetEntry == null)
                    {
                        targetTable.AddEntry(key, sourceEntry.Value);
                        copiedNew++;
                    }
                    else if (targetEntry != null && overwriteExistingKeys)
                    {
                        if (targetTable.RemoveEntry(key))
                        {
                            targetTable.AddEntry(key, sourceEntry.Value);
                            copiedOverwrite++;
                        }
                        else
                        {
                            Debug.LogErrorFormat("CopyInternalStringTable() could not remove key '{0}'. Overwrite failed.", key);
                        }
                    }
                }

                // Set table dirty
                EditorUtility.SetDirty(targetTable);
            }

            // Set target collection shared data dirty
            EditorUtility.SetDirty(targetCollection.SharedData);

            Debug.LogFormat("Source collection '{0}' has a total of {1} entries.\nTarget collection '{2}' received {3} new entries, {4} entries were overwritten.", sourceCollectionName, totalSourceEntries, target, copiedNew, copiedOverwrite);
        }
Example #29
0
        /// <summary>
        /// Imports TEXT.RSC strings from classic game data into specified StringTable.
        /// </summary>
        /// <param name="target">Target string table collection name.</param>
        /// <param name="overwriteExistingKeys">When true will overwrite existing keys with source string. When false existing keys are left unchanged.</param>
        public static void CopyTextRSCToStringTable(string target, bool overwriteExistingKeys)
        {
            // Use default Internal_RSC collection with EN locale code as source
            // Note: Internal_RSC is reserved for future use
            string sourceCollectionName = TextManager.defaultInternalRSCCollectionName;

            // Do nothing if target not set
            if (string.IsNullOrEmpty(target))
            {
                return;
            }

            // Target cannot be same as default
            if (string.Compare(target, sourceCollectionName, true) == 0)
            {
                Debug.LogError("CopyTextRSCToStringTable() target cannot be same as default");
                return;
            }

            // Load character mapping table
            Table     charMappingTable = null;
            TextAsset mappingTableText = Resources.Load <TextAsset>(textMappingTableFilename);

            if (mappingTableText)
            {
                charMappingTable = new Table(mappingTableText.text);
            }

            // Load default TEXT.RSC file
            TextFile defaultRSC = new TextFile(DaggerfallUnity.Instance.Arena2Path, TextFile.Filename);

            if (defaultRSC == null || defaultRSC.IsLoaded == false)
            {
                Debug.LogError("CopyTextRSCToStringTable() could not find default TEXT.RSC file");
                return;
            }

            // Get target string table collection
            var targetCollection = LocalizationEditorSettings.GetStringTableCollection(target);

            if (targetCollection == null)
            {
                Debug.LogErrorFormat("CopyTextRSCToStringTable() could not find target string table collection '{0}'", target);
                return;
            }

            // Copy source strings to all tables in target collection
            int totalSourceEntries = defaultRSC.RecordCount;
            int copiedNew          = 0;
            int copiedOverwrite    = 0;

            foreach (StringTable targetTable in targetCollection.StringTables)
            {
                TextFile rsc       = defaultRSC;
                TextFile localeRSC = LoadCustomLocaleTextRSC(targetTable.LocaleIdentifier.Code);
                if (localeRSC != null)
                {
                    rsc = localeRSC;
                }

                for (int i = 0; i < defaultRSC.RecordCount; i++)
                {
                    // Extract this record to tokens
                    byte[]           buffer = rsc.GetBytesByIndex(i);
                    TextFile.Token[] tokens = TextFile.ReadTokens(ref buffer, 0, TextFile.Formatting.EndOfRecord);

                    // Get token key and text
                    int id = rsc.IndexToId(i);
                    if (id == -1)
                    {
                        continue;
                    }
                    string key  = MakeTextRSCKey(id);
                    string text = ConvertRSCTokensToString(id, tokens);

                    // Remap characters when mapping table present
                    if (charMappingTable != null)
                    {
                        text = RemapCharacters(targetTable.LocaleIdentifier.Code, text, charMappingTable);
                    }

                    // ID 9000 is diverted to multiple records after initial conversion
                    // Otherwise this record is too long for string table editor
                    // Multiple records also make questionnaire easier to maintain
                    if (id == 9000)
                    {
                        SplitQuestionnaireRecord(text, key, targetTable, overwriteExistingKeys, ref copiedNew, ref copiedOverwrite);
                        continue;
                    }

                    var targetEntry = targetTable.GetEntry(key);
                    if (targetEntry == null)
                    {
                        targetTable.AddEntry(key, text);
                        copiedNew++;
                    }
                    else if (targetEntry != null && overwriteExistingKeys)
                    {
                        if (targetTable.RemoveEntry(key))
                        {
                            targetTable.AddEntry(key, text);
                            copiedOverwrite++;
                        }
                        else
                        {
                            Debug.LogErrorFormat("CopyTextRSCToStringTable() could not remove key '{0}'. Overwrite failed.", key);
                        }
                    }
                }

                // Set table dirty
                EditorUtility.SetDirty(targetTable);
            }

            // Set target collection shared data dirty
            EditorUtility.SetDirty(targetCollection.SharedData);

            Debug.LogFormat("Source collection TEXT.RSC has a total of {0} entries.\nTarget collection '{1}' received {2} new entries, {3} entries were overwritten.", totalSourceEntries, target, copiedNew, copiedOverwrite);
        }
Example #30
0
        /// <summary>
        /// Imports FLATS.CFG EN strings from embedded classic game data into specified StringTable.
        /// </summary>
        /// <param name="target">Target string table collection name.</param>
        /// <param name="overwriteExistingKeys">When true will overwrite existing keys with source string. When false existing keys are left unchanged.</param>
        public static void CopyTextFlatsToStringTable(string target, bool overwriteExistingKeys)
        {
            // Use default Internal_Flat collection with EN locale code as source
            // Note: Internal_Flats is reserved for future use
            string sourceCollectionName = TextManager.defaultInternalFlatsCollectionName;

            // Do nothing if target not set
            if (string.IsNullOrEmpty(target))
            {
                return;
            }

            // Target cannot be same as default
            if (string.Compare(target, sourceCollectionName, true) == 0)
            {
                Debug.LogError("CopyTextFlatsToStringTable() target cannot be same as default");
                return;
            }

            // Load default FLATS.CFG file
            FlatsFile flatsFile = new FlatsFile(Path.Combine(DaggerfallUnity.Instance.Arena2Path, FlatsFile.Filename), DaggerfallConnect.FileUsage.UseMemory, true);

            if (flatsFile == null)
            {
                Debug.LogError("CopyTextFlatsToStringTable() could not find default FLATS.CFG file");
                return;
            }

            // Get target string table collection
            var targetCollection = LocalizationEditorSettings.GetStringTableCollection(target);

            if (targetCollection == null)
            {
                Debug.LogErrorFormat("CopyTextFlatsToStringTable() could not find target string table collection '{0}'", target);
                return;
            }

            // Copy source strings to all tables in target collection
            int totalSourceEntries = flatsFile.FlatsDict.Count;
            int copiedNew          = 0;
            int copiedOverwrite    = 0;

            foreach (StringTable targetTable in targetCollection.StringTables)
            {
                foreach (var item in flatsFile.FlatsDict)
                {
                    string key  = item.Key.ToString();
                    string text = item.Value.caption;

                    var targetEntry = targetTable.GetEntry(key);
                    if (targetEntry == null)
                    {
                        targetTable.AddEntry(key, text);
                        copiedNew++;
                    }
                    else if (targetEntry != null && overwriteExistingKeys)
                    {
                        if (targetTable.RemoveEntry(key))
                        {
                            targetTable.AddEntry(key, text);
                            copiedOverwrite++;
                        }
                        else
                        {
                            Debug.LogErrorFormat("CopyTextFlatsToStringTable() could not remove key '{0}'. Overwrite failed.", key);
                        }
                    }
                }

                // Set table dirty
                EditorUtility.SetDirty(targetTable);
            }

            // Set target collection shared data dirty
            EditorUtility.SetDirty(targetCollection.SharedData);

            Debug.LogFormat("Source collection FLATS.CFG has a total of {0} entries.\nTarget collection '{1}' received {2} new entries, {3} entries were overwritten.", totalSourceEntries, target, copiedNew, copiedOverwrite);
        }