예제 #1
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);
        }
예제 #2
0
        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.
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        /// <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);
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        // 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);
                    }
                }
            }
        }