void LoadTLK() { tlk = new TLK(); using (Stream stream = File.Open(tlk_location, FileMode.Open)) { tlk.Load(stream, new Dictionary <string, Stream>(), skip: 0); } }
//Randomize TLK static void shuffle_TLK(KPaths paths, bool LengthMatching) { TLK t = new TLK(paths.dialog); if (LengthMatching) { TLK t_ordered = new TLK(paths.dialog); t_ordered.String_Data_Table = t_ordered.String_Data_Table.OrderBy(x => x.StringText.Length).ToList(); for (int i = 0; i < t.String_Data_Table.Count; i++) { try { int index_offset = 0; while (index_offset == 0) { index_offset = Randomize.Rng.Next(-5, 5); } // Could get faster execution time by matching the strings by lenght instead of text, but then there would be bias towards strings earlier in each lenght bracket. var randomString = t_ordered.String_Data_Table[t_ordered.String_Data_Table.FindIndex(x => x.StringText == t.String_Data_Table[i].StringText) + index_offset]; TlkLookupTable.Add(i, new Tuple <string, string>(t.String_Data_Table[i].StringText, randomString.StringText)); t.String_Data_Table[i] = randomString; } catch (Exception ex) { if (ex is IndexOutOfRangeException || ex is ArgumentOutOfRangeException) { continue; //ignoring extreme cases } else { throw; } } } } else { TLK t_orig = new TLK(paths.dialog); Randomize.FisherYatesShuffle(t.String_Data_Table); for (int i = 0; i < t.String_Data_Table.Count; i++) { TlkLookupTable.Add(i, new Tuple <string, string>(t_orig.String_Data_Table[i].StringText, t.String_Data_Table[i].StringText)); } } t.WriteToFile(paths.dialog); }
//public static TLKObject LoadTLK() //{ // string xml = RunXoreosTools(AuroraPrefs.GetKotorLocation() + "/dialog.tlk", "tlk2xml", "--kotor"); // return new TLKObject(xml); //} public static TLK LoadTLK() { string tlk_location = AuroraPrefs.GetKotorLocation() + "/dialog.tlk"; TLK tlk = new TLK(); using (Stream stream = File.OpenRead(tlk_location)) { tlk.Load(stream, new Dictionary <string, Stream>(), skip: 0); } UnityEngine.Debug.Log("Loaded " + tlk.stringCount + " strings"); return(tlk); // UnityEngine.Debug.Log("Dictionary is of size " + tlk.strings.Count); // TLKObject tlkObject = new TLKObject(tlk); // return tlkObject; }
public static void CreateSpoilerLog(XLWorkbook workbook) { if (LookupTable.Count == 0) { return; } var ws = workbook.Worksheets.Add("Item"); var paths = new KPaths(Properties.Settings.Default.Kotor1Path); KEY k = new KEY(paths.chitin_backup); BIF b = new BIF(Path.Combine(paths.data, "templates.bif")); b.AttachKey(k, "data\\templates.bif"); var items = b.VariableResourceTable.Where(x => x.ResourceType == ResourceType.UTI); TLK t = new TLK(File.Exists(paths.dialog_backup) ? paths.dialog_backup : paths.dialog); int i = 1; ws.Cell(i, 1).Value = "Seed"; ws.Cell(i, 2).Value = Properties.Settings.Default.Seed; ws.Cell(i, 1).Style.Font.Bold = true; i++; Version version = typeof(StartForm).Assembly.GetName().Version; ws.Cell(i, 1).Value = "Version"; ws.Cell(i, 1).Style.Font.Bold = true; ws.Cell(i, 2).Value = $"v{version.Major}.{version.Minor}.{version.Build}"; ws.Cell(i, 2).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Right; i += 2; // Skip a row. // Item Randomization Settings ws.Cell(i, 1).Value = "Item Type"; ws.Cell(i, 2).Value = "Rando Level"; ws.Cell(i, 1).Style.Border.BottomBorder = XLBorderStyleValues.Thin; ws.Cell(i, 2).Style.Border.BottomBorder = XLBorderStyleValues.Thin; ws.Cell(i, 1).Style.Font.Bold = true; ws.Cell(i, 2).Style.Font.Bold = true; i++; var settings = new List <Tuple <string, string> >() { new Tuple <string, string>("Armbands", Properties.Settings.Default.RandomizeArmbands.ToString()), new Tuple <string, string>("Armor", Properties.Settings.Default.RandomizeArmor.ToString()), new Tuple <string, string>("Belts", Properties.Settings.Default.RandomizeBelts.ToString()), new Tuple <string, string>("Blasters", Properties.Settings.Default.RandomizeBlasters.ToString()), new Tuple <string, string>("Creature Hides", Properties.Settings.Default.RandomizeHides.ToString()), new Tuple <string, string>("Creature Weapons", Properties.Settings.Default.RandomizeCreature.ToString()), new Tuple <string, string>("Droid Equipment", Properties.Settings.Default.RandomizeDroid.ToString()), new Tuple <string, string>("Gauntlets", Properties.Settings.Default.RandomizeGloves.ToString()), new Tuple <string, string>("Grenades", Properties.Settings.Default.RandomizeGrenades.ToString()), new Tuple <string, string>("Implants", Properties.Settings.Default.RandomizeImplants.ToString()), new Tuple <string, string>("Lightsabers", Properties.Settings.Default.RandomizeLightsabers.ToString()), new Tuple <string, string>("Masks", Properties.Settings.Default.RandomizeMask.ToString()), new Tuple <string, string>("Melee Weapons", Properties.Settings.Default.RandomizeMelee.ToString()), new Tuple <string, string>("Mines", Properties.Settings.Default.RandomizeMines.ToString()), new Tuple <string, string>("Pazaak Cards", Properties.Settings.Default.RandomizePaz.ToString()), new Tuple <string, string>("Stims/Medpacs", Properties.Settings.Default.RandomizeStims.ToString()), new Tuple <string, string>("Upgrades/Crystals", Properties.Settings.Default.RandomizeUpgrade.ToString()), new Tuple <string, string>("Various", Properties.Settings.Default.RandomizeVarious.ToString()), }; foreach (var setting in settings) { ws.Cell(i, 1).Value = setting.Item1; ws.Cell(i, 2).Value = setting.Item2; ws.Cell(i, 1).Style.Font.Italic = true; i++; } i++; // Skip a row. // Omitted Items int iMax = i; i = 3; // Restart at the top of the settings list. ws.Cell(i, 4).Value = "Omitted Items"; ws.Cell(i, 4).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; ws.Cell(i, 4).Style.Font.Bold = true; ws.Range(i, 4, i, 5).Merge(); i++; ws.Cell(i, 4).Value = "ID"; ws.Cell(i, 5).Value = "Label"; ws.Cell(i, 4).Style.Border.BottomBorder = XLBorderStyleValues.Thin; ws.Cell(i, 5).Style.Border.BottomBorder = XLBorderStyleValues.Thin; ws.Cell(i, 4).Style.Font.Italic = true; ws.Cell(i, 5).Style.Font.Italic = true; i++; var sortedList = Globals.OmitItems.ToList(); sortedList.Sort(); foreach (var item in sortedList) { ws.Cell(i, 4).Value = item; var origItemName = ""; var origItemVre = items.FirstOrDefault(x => x.ResRef == item); if (origItemVre != null) { GFF origItem = new GFF(origItemVre.EntryData); if (origItem.Top_Level.Fields.FirstOrDefault(x => x.Label == "LocalizedName") is GFF.CExoLocString field) { origItemName = t.String_Data_Table[field.StringRef].StringText; } } ws.Cell(i, 5).Value = origItemName; i++; } // Handle variable length of omitted items list. if (iMax > i) { i = iMax; // Return to the bottom of the settings list. } else { i++; // Skip a row. } i++; // Skip an additional 2 rows. // Randomized Items ws.Cell(i, 1).Value = "Has Changed"; ws.Cell(i - 1, 2).Value = "Original (New Item)"; ws.Cell(i, 2).Value = "ID"; ws.Cell(i, 3).Value = "Label"; ws.Cell(i - 1, 4).Value = "Randomized (Old Item)"; ws.Cell(i, 4).Value = "ID"; ws.Cell(i, 5).Value = "Label"; ws.Cell(i, 1).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; ws.Cell(i - 1, 2).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; ws.Cell(i - 1, 4).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; ws.Cell(i, 1).Style.Border.BottomBorder = XLBorderStyleValues.Thin; ws.Cell(i, 2).Style.Border.BottomBorder = XLBorderStyleValues.Thin; ws.Cell(i, 3).Style.Border.BottomBorder = XLBorderStyleValues.Thin; ws.Cell(i, 4).Style.Border.BottomBorder = XLBorderStyleValues.Thin; ws.Cell(i, 5).Style.Border.BottomBorder = XLBorderStyleValues.Thin; ws.Cell(i - 1, 2).Style.Border.LeftBorder = XLBorderStyleValues.Thin; ws.Cell(i, 2).Style.Border.LeftBorder = XLBorderStyleValues.Thin; ws.Cell(i - 1, 4).Style.Border.LeftBorder = XLBorderStyleValues.Thin; ws.Cell(i, 4).Style.Border.LeftBorder = XLBorderStyleValues.Thin; ws.Cell(i - 1, 6).Style.Border.LeftBorder = XLBorderStyleValues.Thin; ws.Cell(i, 6).Style.Border.LeftBorder = XLBorderStyleValues.Thin; ws.Cell(i, 1).Style.Font.Bold = true; ws.Cell(i - 1, 2).Style.Font.Bold = true; ws.Cell(i, 2).Style.Font.Italic = true; ws.Cell(i, 3).Style.Font.Italic = true; ws.Cell(i - 1, 4).Style.Font.Bold = true; ws.Cell(i, 4).Style.Font.Italic = true; ws.Cell(i, 5).Style.Font.Italic = true; ws.Range(i - 1, 2, i - 1, 3).Merge(); ws.Range(i - 1, 4, i - 1, 5).Merge(); i++; var sortedLookup = LookupTable.OrderBy(tpl => tpl.Item1); foreach (var tpl in sortedLookup) { string origItemName = ""; string randItemName = ""; var omitted = Globals.OmitItems.Any(x => x == tpl.Item1); var changed = tpl.Item1 != tpl.Item2; // Has the shuffle changed this item? var origItemVre = items.FirstOrDefault(x => x.ResRef == tpl.Item1); if (origItemVre != null) { GFF origItem = new GFF(origItemVre.EntryData); if (origItem.Top_Level.Fields.FirstOrDefault(x => x.Label == "LocalizedName") is GFF.CExoLocString field) { origItemName = t.String_Data_Table[field.StringRef].StringText; } } if (changed) { var randItemVre = items.FirstOrDefault(x => x.ResRef == tpl.Item2); if (randItemVre != null) { GFF randItem = new GFF(randItemVre.EntryData); if (randItem.Top_Level.Fields.FirstOrDefault(x => x.Label == "LocalizedName") is GFF.CExoLocString field) { randItemName = t.String_Data_Table[field.StringRef].StringText; } } } else { randItemName = origItemName; } ws.Cell(i, 1).Value = omitted ? "OMITTED" : changed.ToString(); ws.Cell(i, 2).Style.Border.LeftBorder = XLBorderStyleValues.Thin; ws.Cell(i, 2).Value = tpl.Item1; ws.Cell(i, 3).Value = origItemName; ws.Cell(i, 4).Style.Border.LeftBorder = XLBorderStyleValues.Thin; ws.Cell(i, 4).Value = tpl.Item2; ws.Cell(i, 5).Value = randItemName; ws.Cell(i, 6).Style.Border.LeftBorder = XLBorderStyleValues.Thin; if (omitted) { // Center "OMITTED" text. ws.Cell(i, 1).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; } else { // Set color of "Has Changed" column. Booleans are automatically centered. if (changed) { ws.Cell(i, 1).Style.Font.FontColor = XLColor.Green; } else { ws.Cell(i, 1).Style.Font.FontColor = XLColor.Red; } } i++; } // Resize Columns ws.Column(1).AdjustToContents(); ws.Column(2).AdjustToContents(); ws.Column(3).AdjustToContents(); ws.Column(4).AdjustToContents(); ws.Column(5).AdjustToContents(); }
//Randomize Dialogue static void shuffle_dialogue(KPaths paths, bool Entries, bool Replies, bool SoundMatching) { TLK t = new TLK(paths.dialog); foreach (FileInfo fi in paths.FilesInModules) { if (fi.Name[fi.Name.Length - 5] != 's') { continue; } RIM r = new RIM(fi.FullName); foreach (RIM.rFile RF in r.File_Table.Where(x => x.TypeID == (int)ResourceType.DLG)) { GFF g = new GFF(RF.File_Data); //Entries if (Entries) { foreach (GFF.STRUCT S in (g.Top_Level.Fields.Where(x => x.Label == "EntryList").FirstOrDefault() as GFF.LIST).Structs) { if ((S.Fields.Where(x => x.Label == "Text").FirstOrDefault() as GFF.CExoLocString).StringRef != -1) // Avoid overwriting dialogue end indicators, and animation nodes { int str_ref = 0; // Find valid string while (t.String_Data_Table[str_ref].SoundResRef == "" || t.String_Data_Table[str_ref].SoundResRef[0] == '_' || t.String_Data_Table[str_ref].SoundResRef.ToLower().Contains("comp")) //Ensure the string we have has a sound to go with it, starting with undescord means it's player dialogue, which doesn't have audio in this game { str_ref = Randomize.Rng.Next(TLK_STRING_COUNT); } if (!EntriesLookupTable.ContainsKey(fi.Name)) { EntriesLookupTable.Add(fi.Name, new Dictionary <string, List <Tuple <int, int, string, string, string, string> > >()); } if (!EntriesLookupTable[fi.Name].ContainsKey(RF.Label)) { EntriesLookupTable[fi.Name].Add(RF.Label, new List <Tuple <int, int, string, string, string, string> >()); } // Sound and Text Matching if (SoundMatching) { var text = S.Fields.Where(x => x.Label == "Text").FirstOrDefault() as GFF.CExoLocString; int textOrig = text.StringRef; int textRand = str_ref; text.StringRef = str_ref; string VORefOrig = ""; string VORefRand = ""; string SoundOrig = ""; string SoundRand = ""; try { var voResRef = S.Fields.Where(x => x.Label == "VO_ResRef").FirstOrDefault() as GFF.ResRef; VORefOrig = voResRef.Reference; VORefRand = t.String_Data_Table[str_ref].SoundResRef; voResRef.Reference = VORefRand; } catch { VORefOrig = ""; VORefRand = ""; } try { var sound = S.Fields.Where(x => x.Label == "Sound").FirstOrDefault() as GFF.ResRef; SoundOrig = sound.Reference; SoundRand = t.String_Data_Table[str_ref].SoundResRef; sound.Reference = SoundRand; } catch { SoundOrig = ""; SoundRand = ""; } // If both VO_ResRef and Sound Fail we ignore the entry EntriesLookupTable[fi.Name][RF.Label].Add(new Tuple <int, int, string, string, string, string>(textOrig, textRand, VORefOrig, VORefRand, SoundOrig, SoundRand)); } else { var text = S.Fields.Where(x => x.Label == "Text").FirstOrDefault() as GFF.CExoLocString; EntriesLookupTable[fi.Name][RF.Label].Add(new Tuple <int, int, string, string, string, string>(text.StringRef, str_ref, "", "", "", "")); text.StringRef = str_ref; } } } } //Replies if (Replies) { foreach (GFF.STRUCT S in (g.Top_Level.Fields.Where(x => x.Label == "ReplyList").FirstOrDefault() as GFF.LIST).Structs) { if ((S.Fields.Where(x => x.Label == "Text").FirstOrDefault() as GFF.CExoLocString).StringRef != -1) //Avoid overwriting dialogue end indicators, and animation nodes { if (!RepliesLookupTable.ContainsKey(fi.Name)) { RepliesLookupTable.Add(fi.Name, new Dictionary <string, List <Tuple <int, int> > >()); } if (!RepliesLookupTable[fi.Name].ContainsKey(RF.Label)) { RepliesLookupTable[fi.Name].Add(RF.Label, new List <Tuple <int, int> >()); } int str_ref = Randomize.Rng.Next(TLK_STRING_COUNT); while (t.String_Data_Table[str_ref].StringText == "") { str_ref = Randomize.Rng.Next(TLK_STRING_COUNT); } var text = S.Fields.Where(x => x.Label == "Text").FirstOrDefault() as GFF.CExoLocString; RepliesLookupTable[fi.Name][RF.Label].Add(new Tuple <int, int>(text.StringRef, str_ref)); text.StringRef = str_ref; } } } Array.Clear(RF.File_Data, 0, RF.File_Data.Length); RF.File_Data = g.ToRawData(); } r.WriteToFile(fi.FullName); } }
public static void Main(string[] args) { bool overwriteFiles = false; bool showHelp = false; bool pauseOnError = true; OptionSet options = new OptionSet() { { "np|nopause", "don't pause on errors", v => pauseOnError = v == null }, { "o|overwrite", "overwrite files if they already exist", v => overwriteFiles = v != null }, { "h|help", "show this message and exit", v => showHelp = v != null }, }; List <string> extras; try { extras = options.Parse(args); } catch (OptionException e) { Console.Write("{0}: ", GetExecutableName()); Console.WriteLine(e.Message); Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName()); Pause(pauseOnError); return; } if (extras.Count < 1 || extras.Count > 2 || showHelp == true) { Console.WriteLine("Usage: {0} [OPTIONS]+ input_tlk [output_tlk]", GetExecutableName()); Console.WriteLine("Convert TLK V0.5 files to V0.2."); Console.WriteLine(); Console.WriteLine("Options:"); options.WriteOptionDescriptions(Console.Out); Pause(pauseOnError); return; } string inputPath = extras[0]; string outputPath; if (extras.Count > 1) { outputPath = extras[1]; } else { outputPath = Path.GetFileNameWithoutExtension(inputPath); outputPath += "_downgraded"; outputPath = Path.ChangeExtension(outputPath, Path.GetExtension(inputPath)); outputPath = Path.Combine(Path.GetDirectoryName(inputPath), outputPath); } if (overwriteFiles == false && File.Exists(outputPath)) { Console.WriteLine("'{0}' already exists.", Path.GetFileName(outputPath)); Pause(pauseOnError); return; } using (var gff = new GenericFile_Type()) { using (var input = File.OpenRead(inputPath)) { gff.Deserialize(input); } if (gff.FormatType != GFF.FormatType.TLK || gff.FormatVersion != 0x56302E35) { Console.WriteLine("'{0}' is not a TLK V0.5 file.", Path.GetFileName(outputPath)); Pause(pauseOnError); return; } Console.WriteLine("Importing HTLK..."); var htlk = gff.ExportType <HTLK>(); var tlk = new TLK(); //int cursor = Console.CursorLeft; //Console.Write("Decoding {0} strings... ", htlk.Strings.Count); Console.WriteLine("Decoding {0} strings... ", htlk.Strings.Count); foreach (var str in htlk.Strings) { //Console.CursorLeft = cursor; //Console.Write(str.Id.ToString()); tlk.Strings.Add( new TLK.STRN() { Id = str.Id, String = Decode(htlk, str), }); } //Console.CursorLeft = cursor; //Console.WriteLine("done. "); Console.WriteLine("Exporting TLK..."); gff.ImportType(tlk); gff.FormatVersion = 0x56302E32; using (var output = File.Create(outputPath)) { gff.Serialize(output); } } }
public TLKObject(TLK tlk) { }