// update battle archive private static void BattleOps(int seed, SpoilerFile spoilerFile, State settings) { Debug.WriteLine("battle ops start"); while (true) { try { CreateOrRestoreArchiveBackup(Globals.BattlePath); var battleSource = new FileSource(Globals.BattlePath); // boss shuffle if (settings.BossEnable) { var bossMap = Boss.Randomise(seed, settings); if (settings.SpoilerFile) { spoilerFile.AddBosses(bossMap); } Boss.Apply(battleSource, bossMap); } // loot shuffle var drops = settings.LootDrops; var steals = settings.LootSteals; var draws = settings.LootDraws; if (drops || steals || draws) { var shuffle = LootShuffle.Randomise(battleSource, seed, settings); if (settings.SpoilerFile) { spoilerFile.AddLoot(shuffle, drops, steals, draws); } } if (settings.BossEnable || drops || steals || draws) { battleSource.Encode(); } break; } catch (Exception x) { if (x is IOException || x is UnauthorizedAccessException || x is FileNotFoundException) { if (HandleFileException(Globals.BattlePath) == false) { break; } } else { throw; } } } Debug.WriteLine("battle ops end"); }
// update battle archive private static void BattleOps(int seed, SpoilerFile spoilerFile) { Debug.WriteLine("battle ops start"); while (true) { try { CreateOrRestoreArchiveBackup(Globals.BattlePath); var battleSource = new FileSource(Globals.BattlePath); // boss shuffle/rebalance if (Properties.Settings.Default.BossShuffle) { var shuffle = Boss.Shuffle(battleSource, Properties.Settings.Default.BossRebalance, seed); if (Properties.Settings.Default.SpoilerFile) { spoilerFile.AddBosses(shuffle); } } // loot shuffle if (Properties.Settings.Default.LootShuffle) { var shuffle = LootShuffle.Randomise(battleSource, seed); if (Properties.Settings.Default.SpoilerFile) { spoilerFile.AddLoot(shuffle); } } if (Properties.Settings.Default.BossShuffle || Properties.Settings.Default.LootShuffle) { battleSource.Encode(); } break; } catch (Exception x) { if (x is IOException || x is UnauthorizedAccessException || x is FileNotFoundException) { if (HandleFileException(Globals.BattlePath) == false) { break; } } else { throw; } } } Debug.WriteLine("battle ops end"); }
// update menu archive private static void MenuOps(int seed, SpoilerFile spoilerFile) { Debug.WriteLine("menu ops start"); while (true) { try { CreateOrRestoreArchiveBackup(Globals.MenuPath); var menuSource = new FileSource(Globals.MenuPath); // preset names if (Properties.Settings.Default.NameSet) { PresetNames.Apply(menuSource); menuSource.Encode(); } // shop shuffle if (Properties.Settings.Default.ShopShuffle) { var shuffle = ShopShuffle.Randomise(seed); if (Properties.Settings.Default.SpoilerFile) { spoilerFile.AddShops(shuffle); } ShopShuffle.Apply(menuSource, shuffle); menuSource.Encode(); } break; } catch (Exception x) { if (x is IOException || x is UnauthorizedAccessException || x is FileNotFoundException) { if (HandleFileException(Globals.MenuPath) == false) { break; } } else { throw; } } } Debug.WriteLine("menu ops end"); }
// update multiple files on 2nd pass private static void FinalOps(int seed, string seedString, SpoilerFile spoilerFile) { Debug.WriteLine("final ops start"); while (true) { try { // free roam rewards if (Properties.Settings.Default.StorySkip) { var battleSource = new FileSource(Globals.BattlePath); var fieldSource = new FileSource(Globals.FieldPath); Reward.SetRewards(battleSource, fieldSource, seed); battleSource.Encode(); fieldSource.Encode(); } break; } catch (Exception x) { if (x is IOException || x is UnauthorizedAccessException || x is FileNotFoundException) { if (HandleFileException(Globals.BattlePath) == false) { break; } } else { throw; } } } // save spoiler file if (Properties.Settings.Default.SpoilerFile) { // strip illegal chars from filename var invalidChars = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars()); var regex = new Regex(string.Format("[{0}]", Regex.Escape(invalidChars))); File.WriteAllText("spoilers." + regex.Replace(seedString, "_") + ".txt", spoilerFile.ToString()); } Debug.WriteLine("final ops end"); }
// update game executable private static void ExeOps(int seed, SpoilerFile spoilerFile) { Debug.WriteLine("exe ops start"); while (true && !Globals.Remastered) { try { // draw point shuffle if (Properties.Settings.Default.DrawPointShuffle) { var shuffle = DrawPointShuffle.Randomise(seed); if (Properties.Settings.Default.SpoilerFile) { spoilerFile.AddDrawPoints(shuffle); } DrawPointShuffle.GeneratePatch(shuffle).Apply(Globals.ExePath); } else { DrawPointShuffle.RemovePatch(Globals.ExePath); } break; } catch (Exception x) { if (x is IOException || x is UnauthorizedAccessException || x is FileNotFoundException) { if (HandleFileException(Globals.ExePath) == false) { break; } } else { throw; } } } Debug.WriteLine("exe ops end"); }
private static void MainOps(int seed, SpoilerFile spoilerFile, State settings) { Debug.WriteLine("main ops start"); while (true) { try { CreateOrRestoreArchiveBackup(Globals.MainPath); var mainSource = new FileSource(Globals.MainPath); // ability shuffle if (settings.GfAbilitiesEnable) { var shuffle = AbilityShuffle.Randomise(mainSource, seed, settings); if (settings.SpoilerFile) { spoilerFile.AddAbilities(shuffle); } } mainSource.Encode(); break; } catch (Exception x) { if (x is IOException || x is UnauthorizedAccessException || x is FileNotFoundException) { if (HandleFileException(Globals.MainPath) == false) { break; } } else { throw; } } } Debug.WriteLine("main ops end"); }
// update field archive (and af3dn.p) private static void FieldOps(int seed, string seedString, SpoilerFile spoilerFile) { Debug.WriteLine("field ops start"); while (true) { try { CreateOrRestoreArchiveBackup(Globals.FieldPath); var fieldSource = new FileSource(Globals.FieldPath); // apply free roam if (Properties.Settings.Default.StorySkip) { StorySkip.Apply(fieldSource, seedString, seed); } else { StorySkip.Remove(); } // apply card shuffle if (Properties.Settings.Default.CardShuffle) { var shuffle = CardShuffle.Shuffle(seed); if (Properties.Settings.Default.SpoilerFile) { spoilerFile.AddCards(shuffle); } CardShuffle.Apply(fieldSource, shuffle); } // apply music shuffle if (Properties.Settings.Default.MusicShuffle) { var shuffle = MusicShuffle.Shuffle(seed); if (Properties.Settings.Default.SpoilerFile) { spoilerFile.AddMusic(shuffle); } MusicShuffle.Apply(fieldSource, shuffle); } // write to file if (Properties.Settings.Default.StorySkip || Properties.Settings.Default.CardShuffle) { fieldSource.Encode(); } break; } catch (Exception x) { if (x is IOException || x is UnauthorizedAccessException || x is FileNotFoundException) { if (HandleFileException(Globals.FieldPath) == false) { break; } } else { throw; } } } Debug.WriteLine("field ops end"); }
public static void Go(Action callback) { Debug.WriteLine("randomizer start"); Globals.ExePath = Properties.Settings.Default.GameLocation; if (!File.Exists(Globals.ExePath)) { HandleExeException(Globals.ExePath); callback.Invoke(); return; } // detect game version var exeFileName = Path.GetFileName(Globals.ExePath).ToLower(); if (exeFileName == "ffviii.exe") { Globals.Remastered = true; } else if (exeFileName == "ff8_en.exe") { Globals.Remastered = false; } else { HandleExeException(Globals.ExePath); callback.Invoke(); return; } // generate new seed if not fixed if (!Properties.Settings.Default.SeedSet) { Properties.Settings.Default.SeedValue = (new Random().Next(-1, int.MaxValue) + 1).ToString(); } var seedString = Properties.Settings.Default.SeedValue; // use seed string's hash code as the seed (or parse if possible, for compatibility with 0.2.1 and earlier) if (!int.TryParse(seedString, out int seed)) { seed = seedString.GetHashCode(); } var spoilerFile = new SpoilerFile(); Task.Run(() => { if (Globals.Remastered) { UnpackOnFirstRun(); } Parallel.Invoke ( () => BattleOps(seed, spoilerFile), () => FieldOps(seed, seedString, spoilerFile), () => MenuOps(seed, spoilerFile), () => ExeOps(seed, spoilerFile), () => MainOps(seed, spoilerFile) ); FinalOps(seed, seedString, spoilerFile); if (Globals.Remastered) { RepackArchive(); } callback.Invoke(); Debug.WriteLine("randomizer end"); }); }
// update multiple files on 2nd pass private static void FinalOps(int seed, string seedString, SpoilerFile spoilerFile, State settings) { Debug.WriteLine("final ops start"); while (true) { try { // weapon shuffle if (settings.UpgradeEnable) { var mainSource = new FileSource(Globals.MainPath); var menuSource = new FileSource(Globals.MenuPath); var shuffle = WeaponShuffle.Randomise(seed, settings); if (settings.SpoilerFile) { spoilerFile.AddWeapons(mainSource, shuffle); } WeaponShuffle.Apply(menuSource, shuffle); menuSource.Encode(); } // free roam rewards if (settings.FreeRoam || settings.BossEnable) { var battleSource = new FileSource(Globals.BattlePath); var fieldSource = new FileSource(Globals.FieldPath); if (settings.FreeRoam) { Reward.SetRewards(battleSource, fieldSource, seed); } if (settings.BossEnable) { Boss.ApplyEdeaFix(battleSource, fieldSource); } battleSource.Encode(); fieldSource.Encode(); } break; } catch (Exception x) { if (x is IOException || x is UnauthorizedAccessException || x is FileNotFoundException) { if (HandleFileException(Globals.BattlePath) == false) { break; } } else { throw; } } } // save spoiler file if (settings.SpoilerFile) { // strip illegal chars from filename File.WriteAllText("spoilers." + SanitizeFileName(seedString) + ".txt", spoilerFile.ToString()); } Debug.WriteLine("final ops end"); }
// update menu archive private static void MenuOps(int seed, SpoilerFile spoilerFile, State settings) { Debug.WriteLine("menu ops start"); while (true) { try { CreateOrRestoreArchiveBackup(Globals.MenuPath); var menuSource = new FileSource(Globals.MenuPath); // preset names if (settings.NameEnable) { PresetNames.Apply(menuSource, settings); } // shop shuffle if (settings.ShopEnable) { var shuffle = ShopShuffle.Randomise(seed, settings); if (settings.SpoilerFile) { spoilerFile.AddShops(shuffle); } ShopShuffle.Apply(menuSource, shuffle); } // draw point shuffle if (!Globals.Remastered) { if (settings.DrawPointEnable) { var shuffle = DrawPointShuffle.Randomise(seed, settings); if (settings.SpoilerFile) { spoilerFile.AddDrawPoints(shuffle); } DrawPointShuffle.Apply(menuSource, shuffle); } else { DrawPointShuffle.RemovePatch(Globals.ExePath); } } if (settings.NameEnable || settings.ShopEnable || (settings.DrawPointEnable && !Globals.Remastered)) { menuSource.Encode(); } break; } catch (Exception x) { if (x is IOException || x is UnauthorizedAccessException || x is FileNotFoundException) { if (HandleFileException(Globals.MenuPath) == false) { break; } } else { throw; } } } Debug.WriteLine("menu ops end"); }
public static void Go() { Debug.WriteLine("randomizer start"); var settings = State.Current.Clone(); Globals.ExePath = settings.GameLocation; if (!File.Exists(Globals.ExePath)) { HandleExeException(Globals.ExePath); return; } // update game version if (!DetectVersion(Globals.ExePath)) { HandleExeException(Globals.ExePath); return; } // set region Globals.RegionCode = settings.Language; // generate new seed if not fixed if (!settings.SeedFixed) { settings.SeedValue = (new Random().Next(-1, int.MaxValue) + 1).ToString(); } var seedString = settings.SeedValue; // update seed history if (State.Current.History == null) { State.Current.History = new List <string>(); } State.Current.History.RemoveAll(s => s == seedString); State.Current.History.Insert(0, seedString); if (State.Current.History.Count > 50) { State.Current.History = State.Current.History.Take(50).ToList(); } // use seed string's hash code as the seed (or parse if possible) if (!int.TryParse(seedString, out int seed)) { seed = seedString.GetHashCode(); } var spoilerFile = new SpoilerFile(); if (Globals.Remastered) { UnpackOnFirstRun(); } Parallel.Invoke ( () => BattleOps(seed, spoilerFile, settings), () => FieldOps(seed, seedString, spoilerFile, settings), () => MenuOps(seed, spoilerFile, settings), () => MainOps(seed, spoilerFile, settings) ); FinalOps(seed, seedString, spoilerFile, settings); if (Globals.Remastered) { RepackArchive(); } Debug.WriteLine("randomizer end"); }