//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 void Twoda_rando(KPaths paths) { BIF b = new BIF(Path.Combine(paths.data, "2da.bif")); KEY k = new KEY(paths.chitin_backup); b.AttachKey(k, "data\\2da.bif"); var filesInOverride = paths.FilesInOverride.ToList(); foreach (BIF.VariableResourceEntry VRE in b.VariableResourceTable.Where(x => Globals.Selected2DAs.Keys.Contains(x.ResRef))) { // Check to see if this table is already in the override directory. TwoDA t; if (filesInOverride.Any(fi => fi.Name == $"{VRE.ResRef}.2da")) { // Modify the existing table. t = new TwoDA(File.ReadAllBytes(filesInOverride.First(fi => fi.Name == $"{VRE.ResRef}.2da").FullName), VRE.ResRef); } else { // Fetch the table from the 2DA BIF file. t = new TwoDA(VRE.EntryData, VRE.ResRef); } if (!LookupTable.ContainsKey(VRE.ResRef)) { // Add 2DA to the table. LookupTable.Add(VRE.ResRef, new Dictionary <string, List <Tuple <string, string> > >()); } foreach (string col in Globals.Selected2DAs[VRE.ResRef]) { if (!LookupTable[VRE.ResRef].ContainsKey(col)) { // Add column to the table. LookupTable[VRE.ResRef].Add(col, new List <Tuple <string, string> >()); } var old = t.Data[col].ToList(); // Save list of old data. Randomize.FisherYatesShuffle(t.Data[col]); // Randomize 2DA column data. for (int i = 0; i < old.Count; i++) { // Add old and new data to the table. LookupTable[VRE.ResRef][col].Add(new Tuple <string, string>(old[i], t.Data[col][i])); } } t.WriteToDirectory(paths.Override); // Write new 2DA data to file. } }
public static void Twoda_rando(KPaths paths) { BIF b = new BIF(Path.Combine(paths.data, "2da.bif")); KEY k = new KEY(paths.chitin_backup); b.AttachKey(k, "data\\2da.bif"); foreach (BIF.VariableResourceEntry VRE in b.VariableResourceTable.Where(x => Globals.Selected2DAs.Keys.Contains(x.ResRef))) { TwoDA t = new TwoDA(VRE.EntryData, VRE.ResRef); foreach (string col in Globals.Selected2DAs[VRE.ResRef]) { Randomize.FisherYatesShuffle(t.Data[col]); } t.WriteToDirectory(paths.Override); } }
/// <summary> /// LookupTable is created from the global BoundModules after shuffling included modules. /// </summary> private static void CreateLookupTableShuffle() { List <string> excluded = Globals.BoundModules.Where(x => x.Omitted).Select(x => x.Code).ToList(); List <string> included = Globals.BoundModules.Where(x => !x.Omitted).Select(x => x.Code).ToList(); // Shuffle the list of included modules. List <string> shuffle = new List <string>(included); Randomize.FisherYatesShuffle(shuffle); LookupTable.Clear(); for (int i = 0; i < included.Count; i++) { LookupTable.Add(included[i], shuffle[i]); } // Include the unmodified list of excluded modules. foreach (string name in excluded) { LookupTable.Add(name, name); } }
public static void item_rando(KPaths paths) { // Prepare lists for new randomization. Max_Rando.Clear(); Type_Lists.Clear(); LookupTable.Clear(); // Load KEY file. KEY k = new KEY(paths.chitin); // Handle categories HandleCategory(k, ArmbandsRegs, Properties.Settings.Default.RandomizeArmbands); HandleCategory(k, ArmorRegs, Properties.Settings.Default.RandomizeArmor); HandleCategory(k, BeltsRegs, Properties.Settings.Default.RandomizeBelts); HandleCategory(k, BlastersRegs, Properties.Settings.Default.RandomizeBlasters); HandleCategory(k, HidesRegs, Properties.Settings.Default.RandomizeHides); HandleCategory(k, CreatureRegs, Properties.Settings.Default.RandomizeCreature); HandleCategory(k, DroidRegs, Properties.Settings.Default.RandomizeDroid); HandleCategory(k, GlovesRegs, Properties.Settings.Default.RandomizeGloves); HandleCategory(k, GrenadesRegs, Properties.Settings.Default.RandomizeGrenades); HandleCategory(k, ImplantsRegs, Properties.Settings.Default.RandomizeImplants); HandleCategory(k, LightsabersRegs, Properties.Settings.Default.RandomizeLightsabers); HandleCategory(k, MaskRegs, Properties.Settings.Default.RandomizeMask); HandleCategory(k, MeleeRegs, Properties.Settings.Default.RandomizeMelee); HandleCategory(k, MinesRegs, Properties.Settings.Default.RandomizeMines); HandleCategory(k, PazRegs, Properties.Settings.Default.RandomizePaz); HandleCategory(k, StimsRegs, Properties.Settings.Default.RandomizeStims); HandleCategory(k, UpgradeRegs, Properties.Settings.Default.RandomizeUpgrade); // Handle Various switch (Properties.Settings.Default.RandomizeVarious) { default: case RandomizationLevel.None: break; case RandomizationLevel.Type: List <string> type = new List <string>(k.KeyTable.Where(x => Matches_None(x.ResRef) && !Is_Forbidden(x.ResRef) && x.ResourceType == (short)ResourceType.UTI).Select(x => x.ResRef)); Type_Lists.Add(type); break; case RandomizationLevel.Max: Max_Rando.AddRange(k.KeyTable.Where(x => Matches_None(x.ResRef) && !Is_Forbidden(x.ResRef) && x.ResourceType == (short)ResourceType.UTI).Select(x => x.ResRef)); break; } // Omitted Items foreach (var item in Globals.OmitItems) { LookupTable.Add(new Tuple <string, string>(item, item)); } // Max Rando List <string> Max_Rando_Iterator = new List <string>(Max_Rando); Randomize.FisherYatesShuffle(Max_Rando); int j = 0; foreach (KEY.KeyEntry ke in k.KeyTable.Where(x => Max_Rando_Iterator.Contains(x.ResRef))) { LookupTable.Add(new Tuple <string, string>(ke.ResRef, Max_Rando[j])); ke.ResRef = Max_Rando[j]; j++; } // Type Rando foreach (List <string> li in Type_Lists) { List <string> type_copy = new List <string>(li); Randomize.FisherYatesShuffle(type_copy); j = 0; foreach (KEY.KeyEntry ke in k.KeyTable.Where(x => li.Contains(x.ResRef))) { LookupTable.Add(new Tuple <string, string>(ke.ResRef, type_copy[j])); ke.ResRef = type_copy[j]; j++; } } k.WriteToFile(paths.chitin); }
public static void texture_rando(KPaths paths) { // Prepare lists for new randomization. MaxRando.Clear(); TypeLists.Clear(); // Load in texture pack. string pack_name; switch (Properties.Settings.Default.TexturePack) { default: case TexturePack.HighQuality: pack_name = "\\swpc_tex_tpa.erf"; break; case TexturePack.MedQuality: pack_name = "\\swpc_tex_tpb.erf"; break; case TexturePack.LowQuality: pack_name = "\\swpc_tex_tpc.erf"; break; } ERF e = new ERF(paths.TexturePacks + pack_name); foreach (var key in e.Key_List) { if (!NameLookup.ContainsKey(key.ResID)) { NameLookup.Add(key.ResID, key.ResRef); } } // Handle categories. HandleCategory(e, RegexCubeMaps, Properties.Settings.Default.TextureRandomizeCubeMaps); HandleCategory(e, RegexCreatures, Properties.Settings.Default.TextureRandomizeCreatures); HandleCategory(e, RegexEffects, Properties.Settings.Default.TextureRandomizeEffects); HandleCategory(e, RegexItems, Properties.Settings.Default.TextureRandomizeItems); HandleCategory(e, RegexPlanetary, Properties.Settings.Default.TextureRandomizePlanetary); HandleCategory(e, RegexNPC, Properties.Settings.Default.TextureRandomizeNPC); HandleCategory(e, RegexPlayHeads, Properties.Settings.Default.TextureRandomizePlayHeads); HandleCategory(e, RegexPlayBodies, Properties.Settings.Default.TextureRandomizePlayBodies); HandleCategory(e, RegexPlaceables, Properties.Settings.Default.TextureRandomizePlaceables); HandleCategory(e, RegexParty, Properties.Settings.Default.TextureRandomizeParty); HandleCategory(e, RegexStunt, Properties.Settings.Default.TextureRandomizeStunt); HandleCategory(e, RegexVehicles, Properties.Settings.Default.TextureRandomizeVehicles); HandleCategory(e, RegexWeapons, Properties.Settings.Default.TextureRandomizeWeapons); // Handle other. switch (Properties.Settings.Default.TextureRandomizeOther) { default: case RandomizationLevel.None: break; // Do nothing. case RandomizationLevel.Type: List <int> type = new List <int>(e.Key_List.Where(x => Matches_None(x.ResRef) && !Is_Forbidden(x.ResRef)).Select(x => x.ResID)); TypeLists.Add(type); break; case RandomizationLevel.Max: MaxRando.AddRange(e.Key_List.Where(x => Matches_None(x.ResRef) && !Is_Forbidden(x.ResRef)).Select(x => x.ResID)); break; } // Max Rando. List <int> Max_Rando_Iterator = new List <int>(MaxRando); Randomize.FisherYatesShuffle(MaxRando); int j = 0; foreach (ERF.Key k in e.Key_List.Where(x => Max_Rando_Iterator.Contains(x.ResID))) { LookupTable.Add(k.ResID, MaxRando[j]); k.ResID = MaxRando[j]; j++; } // Type Rando. foreach (List <int> li in TypeLists) { List <int> type_copy = new List <int>(li); Randomize.FisherYatesShuffle(type_copy); j = 0; foreach (ERF.Key k in e.Key_List.Where(x => li.Contains(x.ResID))) { LookupTable.Add(k.ResID, type_copy[j]); k.ResID = type_copy[j]; j++; } } e.WriteToFile(paths.TexturePacks + pack_name); }
// Populates and shuffles the the modules flagged to be randomized. Returns true if override files should be added. public static void Module_rando(KPaths paths) { // Set up the bound module collection if it hasn't been already. if (!Properties.Settings.Default.ModulesInitialized) { Globals.BoundModules.Clear(); foreach (string s in Globals.MODULES) { Globals.BoundModules.Add(new Globals.Mod_Entry(s, true)); } Properties.Settings.Default.ModulesInitialized = true; } //if (!Properties.Settings.Default.ModulePresetSelected) //{ // //Figure something out here //} // Split the Bound modules into their respective lists. List <string> ExcludedModules = Globals.BoundModules.Where(x => x.Omitted).Select(x => x.Name).ToList(); List <string> IncludedModules = Globals.BoundModules.Where(x => !x.Omitted).Select(x => x.Name).ToList(); // Shuffle the list of included modules. List <string> ShuffledModules = IncludedModules.ToList(); Randomize.FisherYatesShuffle(ShuffledModules); // Copy shuffled modules into the base directory. Dictionary <string, string> LookupTable = new Dictionary <string, string>(); // Create lookup table to find a given module's new "name". for (int i = 0; i < IncludedModules.Count; i++) { LookupTable.Add(IncludedModules[i], ShuffledModules[i]); File.Copy($"{paths.modules_backup}{IncludedModules[i]}.rim", $"{paths.modules}{ShuffledModules[i]}.rim", true); File.Copy($"{paths.modules_backup}{IncludedModules[i]}_s.rim", $"{paths.modules}{ShuffledModules[i]}_s.rim", true); File.Copy($"{paths.lips_backup}{IncludedModules[i]}_loc.mod", $"{paths.lips}{ShuffledModules[i]}_loc.mod", true); } // Copy excluded, untouched modules into the base directory. foreach (string name in ExcludedModules) { LookupTable.Add(name, name); File.Copy($"{paths.modules_backup}{name}.rim", $"{paths.modules}{name}.rim", true); File.Copy($"{paths.modules_backup}{name}_s.rim", $"{paths.modules}{name}_s.rim", true); File.Copy($"{paths.lips_backup}{name}_loc.mod", $"{paths.lips}{name}_loc.mod", true); } // Copy lips extras into the base directory. foreach (string name in Globals.lipXtras) { File.Copy($"{paths.lips_backup}{name}", $"{paths.lips}{name}", true); } // Write additional override files. string moduleSavePath = Path.Combine(paths.Override, TwoDA_MODULE_SAVE); ModuleExtras saveFileExtras = Properties.Settings.Default.ModuleExtrasValue & (ModuleExtras.SaveAllModules | ModuleExtras.SaveMiniGames | ModuleExtras.NoSaveDelete); //if (0 == (saveFileExtras ^ (ModuleExtras.Default))) //{ // // 0b000 - Milestone Delete (Default) // // Do nothing. //} if (0 == (saveFileExtras ^ (ModuleExtras.NoSaveDelete))) { // 0b001 - No Milestone Delete File.WriteAllBytes(moduleSavePath, Properties.Resources.NODELETE_modulesave); } if (0 == (saveFileExtras ^ (ModuleExtras.SaveMiniGames))) { // 0b010 - Include Minigames | Milestone Delete File.WriteAllBytes(moduleSavePath, Properties.Resources.MGINCLUDED_modulesave); } if (0 == (saveFileExtras ^ (ModuleExtras.NoSaveDelete | ModuleExtras.SaveMiniGames))) { // 0b011 - Include Minigames | No Milestone Delete File.WriteAllBytes(moduleSavePath, Properties.Resources.NODELETE_MGINCLUDED_modulesave); } if (0 == (saveFileExtras ^ (ModuleExtras.SaveAllModules)) || 0 == (saveFileExtras ^ (ModuleExtras.SaveMiniGames | ModuleExtras.SaveAllModules))) { // Treat both the same. // 0b100 - Include All Modules | Milestone Delete // 0b110 - Include All Modules | Include Minigames | Milestone Delete File.WriteAllBytes(moduleSavePath, Properties.Resources.ALLINCLUDED_modulesave); } if (0 == (saveFileExtras ^ (ModuleExtras.NoSaveDelete | ModuleExtras.SaveAllModules)) || 0 == (saveFileExtras ^ (ModuleExtras.NoSaveDelete | ModuleExtras.SaveMiniGames | ModuleExtras.SaveAllModules))) { // Treat both the same. // 0b101 - Include All Modules | No Milestone Delete // 0b111 - Include All Modules | Include Minigames | No Milestone Delete File.WriteAllBytes(moduleSavePath, Properties.Resources.NODELETE_ALLINCLUDED_modulesave); } if (Properties.Settings.Default.ModuleExtrasValue.HasFlag(ModuleExtras.FixDream)) { File.WriteAllBytes(Path.Combine(paths.Override, FIXED_DREAM_OVERRIDE), Properties.Resources.k_ren_visionland); } if (Properties.Settings.Default.ModuleExtrasValue.HasFlag(ModuleExtras.UnlockGalaxyMap)) { File.WriteAllBytes(Path.Combine(paths.Override, UNLOCK_MAP_OVERRIDE), Properties.Resources.k_pebn_galaxy); } // Fix warp coordinates. if (Properties.Settings.Default.ModuleExtrasValue.HasFlag(ModuleExtras.FixCoordinates)) { // Create a lookup for modules needing coordinate fix with their newly shuffled FileInfos. var shuffleFileLookup = new Dictionary <string, FileInfo>(); foreach (var key in Globals.FIXED_COORDINATES.Keys) { shuffleFileLookup.Add(key, paths.FilesInModules.FirstOrDefault(fi => fi.Name.Contains(LookupTable[key]))); } foreach (var kvp in shuffleFileLookup) { // Set up objects. RIM r = new RIM(kvp.Value.FullName); RIM.rFile rf = r.File_Table.Where(x => x.TypeID == (int)ResourceType.IFO).FirstOrDefault(); GFF g = new GFF(rf.File_Data); // Update coordinate data. g.Field_Array.Where(x => x.Label == Properties.Resources.ModuleEntryX).FirstOrDefault().DataOrDataOffset = Globals.FIXED_COORDINATES[kvp.Key].Item1; g.Field_Array.Where(x => x.Label == Properties.Resources.ModuleEntryY).FirstOrDefault().DataOrDataOffset = Globals.FIXED_COORDINATES[kvp.Key].Item2; g.Field_Array.Where(x => x.Label == Properties.Resources.ModuleEntryZ).FirstOrDefault().DataOrDataOffset = Globals.FIXED_COORDINATES[kvp.Key].Item3; // Write updated data to RIM file. rf.File_Data = g.ToRawData(); r.WriteToFile(kvp.Value.FullName); } } // Fixed Rakata riddle Man in Mind Prison. if (Properties.Settings.Default.ModuleExtrasValue.HasFlag(ModuleExtras.FixMindPrison)) { // Find the files associated with AREA_MYSTERY_BOX. var files = paths.FilesInModules.Where(fi => fi.Name.Contains(LookupTable[AREA_MYSTERY_BOX])); foreach (FileInfo fi in files) { // Skip any files that don't end in "s.rim". if (fi.Name[fi.Name.Length - 5] != 's') { continue; } // Check the RIM's File_Table for any rFiles labeled with LABEL_MIND_PRISON. RIM r = new RIM(fi.FullName); if (r.File_Table.Where(x => x.Label == LABEL_MIND_PRISON).Any()) { bool offadjust = false; foreach (RIM.rFile rf in r.File_Table) { // For the rFile with LABEL_MIND_PRISON, update the file data with the fix. if (rf.Label == LABEL_MIND_PRISON) { rf.File_Data = Properties.Resources.g_brakatan003; rf.DataSize += 192; offadjust = true; continue; } // For rFiles after LABEL_MIND_PRISON, add the additional data offset. if (offadjust) { rf.DataOffset += 192; } } // Write updated RIM data to file. r.WriteToFile(fi.FullName); } } } }