From 8d8546047d0fa22b81e10e6a745288e7ca73da63 Mon Sep 17 00:00:00 2001 From: Kurt Date: Sun, 8 Oct 2017 23:01:52 -0700 Subject: [PATCH] Speed up RSTE randomization essentially instant now may have borked something, lmk; could have rewritten from scratch but the conversion seemed simple enough --- pk3DS/Subforms/Gen6/GiftEditor6.cs | 12 +- pk3DS/Subforms/Gen6/RSTE.cs | 379 +++++++++++------------------ 2 files changed, 154 insertions(+), 237 deletions(-) diff --git a/pk3DS/Subforms/Gen6/GiftEditor6.cs b/pk3DS/Subforms/Gen6/GiftEditor6.cs index 5e5b488..59c675c 100644 --- a/pk3DS/Subforms/Gen6/GiftEditor6.cs +++ b/pk3DS/Subforms/Gen6/GiftEditor6.cs @@ -22,9 +22,8 @@ public GiftEditor6() Close(); } InitializeComponent(); - - MegaDictionary = Main.Config.XY ? MegaDictionaryXY : MegaDictionaryAO.Concat(MegaDictionaryXY) - .ToDictionary(pair => pair.Key, pair => pair.Value); + Dictionary megaDictionary = GetMegaDictionary(Main.Config); + MegaDictionary = megaDictionary; specieslist[0] = "---"; abilitylist[0] = itemlist[0] = movelist[0] = "(None)"; // blank == -1 @@ -38,6 +37,13 @@ public GiftEditor6() loadData(); } + + public static Dictionary GetMegaDictionary(GameConfig config) + { + return config.XY ? MegaDictionaryXY : MegaDictionaryAO.Concat(MegaDictionaryXY) + .ToDictionary(pair => pair.Key, pair => pair.Value); + } + private readonly string FieldPath = Path.Combine(Main.RomFSPath, "DllField.cro"); private byte[] FieldData; private readonly int fieldOffset = Main.Config.ORAS ? 0xF906C : 0xF805C; diff --git a/pk3DS/Subforms/Gen6/RSTE.cs b/pk3DS/Subforms/Gen6/RSTE.cs index c3c8e14..f03d491 100644 --- a/pk3DS/Subforms/Gen6/RSTE.cs +++ b/pk3DS/Subforms/Gen6/RSTE.cs @@ -21,6 +21,7 @@ public RSTE(byte[][] trc, byte[][] trd, byte[][] trp) trdata = trd; trpoke = trp; Array.Resize(ref specieslist, Main.Config.MaxSpeciesID + 1); + MegaDictionary = GiftEditor6.GetMegaDictionary(Main.Config); InitializeComponent(); // String Fetching @@ -355,7 +356,7 @@ private void readFile() changeTrainerType(null, null); // Prompt cleaning update of PKM fields // Refresh Team View - if (!loading && !randomizing) + if (!loading) { for (int i = 0; i < 6; i++) showTeams(i); // showText(); // Commented out for now, have to figure out how text is assigned. @@ -409,7 +410,7 @@ private void writeFile() // Image Displays private void changeTeam(object sender, EventArgs e) { - if (loading || randomizing) return; + if (loading) return; int gendSlot = Array.IndexOf(trpk_gender, sender as ComboBox); int itemSlot = Array.IndexOf(trpk_item, sender as ComboBox); @@ -417,7 +418,7 @@ private void changeTeam(object sender, EventArgs e) } private void showTeams(int i) { - if (tr == null || randomizing) return; + if (tr == null) return; if (i >= tr.Team.Length) { pba[i].Image = null; return; } Bitmap rawImg = WinFormsUtil.getSprite(tr.Team[i].Species, tr.Team[i].Form, tr.Team[i].Gender, tr.Team[i].Item, Main.Config); pba[i].Image = WinFormsUtil.scaleImage(rawImg, 2); @@ -438,11 +439,11 @@ private void Setup() Array.Resize(ref trName, trdata.Length); CB_TrainerID.Items.Clear(); for (int i = 0; i < trdata.Length; i++) - CB_TrainerID.Items.Add(string.Format("{1} - {0}", i.ToString("000"), trName[i] ?? "UNKNOWN")); + CB_TrainerID.Items.Add($"{trName[i] ?? "UNKNOWN"} - {i:000}"); CB_Trainer_Class.Items.Clear(); for (int i = 0; i < trClass.Length; i++) - CB_Trainer_Class.Items.Add(string.Format("{1} - {0}", i.ToString("000"), trClass[i])); + CB_Trainer_Class.Items.Add($"{trClass[i]} - {i:000}"); specieslist[0] = "---"; abilitylist[0] = itemlist[0] = movelist[0] = ""; @@ -520,7 +521,6 @@ private void Setup() readFile(); } - private bool randomizing; public static bool rPKM, rSmart, rLevel, rMove, rNoMove, rAbility, rDiffAI, rDiffIV, rClass, rGift, rItem, rDoRand, rRandomMegas, rGymE4Only, rTypeTheme, rTypeGymTrainers, rOnlySingles, rDMG, rSTAB, r6PKM; @@ -549,16 +549,21 @@ private void Randomize() List banned = new List { 165, 621 }; // Struggle, Hyperspace Fury if (rNoFixedDamage) banned.AddRange(MoveRandomizer.FixedDamageMoves); + var move = new MoveRandomizer(Main.Config) + { + rDMG = rDMG, + rSTAB = rSTAB, + rSTABCount = rSTABCount, + rDMGCount = rDMGCount, + BannedMoves = banned, + }; + rImportant = new string[CB_TrainerID.Items.Count]; rTags = Main.Config.ORAS ? GetTagsORAS() : GetTagsXY(); mEvoTypes = GetMegaEvolvableTypes(); List GymE4Types = new List(); // Fetch Move Stats for more difficult randomization - var moveData = Main.Config.Moves; - int[] moveList = Enumerable.Range(1, movelist.Length - 1).ToArray(); - int mctr = 0; - Util.Shuffle(moveList); if (rEnsureMEvo.Length > 0) { @@ -599,146 +604,147 @@ private void Randomize() } Console.WriteLine(t1 + ": " + types[TagTypes[t1]]); } - randomizing = true; + + CB_TrainerID.SelectedIndex = 0; // fake a writeback + ushort[] itemvals = Main.Config.ORAS ? Legal.Pouch_Items_AO : Legal.Pouch_Items_XY; + itemvals = itemvals.Concat(Legal.Pouch_Berry_XY).ToArray(); + + string[] ImportantClasses = {"GYM", "ELITE", "CHAMPION"}; for (int i = 1; i < CB_TrainerID.Items.Count; i++) { - CB_TrainerID.SelectedIndex = i; // data is loaded - - // Setup - checkBox_Moves.Checked = rMove || !rNoMove && checkBox_Moves.Checked; - checkBox_Item.Checked = rItem || checkBox_Item.Checked; - - if (r6PKM && rImportant[i] != null) // skip the first rival battles - { - // Copy the last slot to random pokemon - int lastPKM = Math.Max(CB_numPokemon.SelectedIndex - 1, 0); // 0,1-6 => 0-5 (never is 0) - CB_numPokemon.SelectedIndex = 6; - for (int f = lastPKM + 1; f < 6; f++) - { - trpk_pkm[f].SelectedIndex = trpk_IV[lastPKM].SelectedIndex; - trpk_lvl[f].SelectedIndex = Math.Min(trpk_lvl[f - 1].SelectedIndex + 1, 100); - } - } - - // Randomize Trainer Stats - if (rDiffAI) - CB_AI.SelectedIndex |= 7; // Set first 3 bits, keep any other flag if present - if (rOnlySingles) - CB_AI.SelectedIndex &= 7; - if ( - rClass // Classes selected to be randomized - && (!rOnlySingles || CB_Battle_Type.SelectedIndex == 0) // Nonsingles only get changed if rOnlySingles - && !rIgnoreClass.Contains(CB_Trainer_Class.SelectedIndex) // Current class isn't a special class - ) - { - int rv = (int)(rnd32() % CB_Trainer_Class.Items.Count); - // Ensure the Random Class isn't an exclusive class - while (rIgnoreClass.Contains(rv) && !trClass[rv].StartsWith("[~")) // don't allow disallowed classes - rv = (int)(rnd32() % CB_Trainer_Class.Items.Count); - - CB_Trainer_Class.SelectedIndex = rv; - } - - if (rGift && rnd32() % 100 < rGiftPercent) - #region Random Prize Logic - { - ushort[] items; - uint rnd = rnd32() % 10; - if (rnd < 2) // held item - items = Main.Config.ORAS ? Legal.Pouch_Items_AO : Legal.Pouch_Items_XY; - else if (rnd < 5) // medicine - items = Main.Config.ORAS ? Legal.Pouch_Medicine_AO : Legal.Pouch_Medicine_XY; - else // berry - items = Legal.Pouch_Berry_XY; - CB_Prize.SelectedIndex = items[rnd32() % items.Length]; - } - #endregion - else if (rGift) - CB_Prize.SelectedIndex = 0; - - ushort[] itemvals = Main.Config.ORAS ? Legal.Pouch_Items_AO : Legal.Pouch_Items_XY; - itemvals = itemvals.Concat(Legal.Pouch_Berry_XY).ToArray(); - int itemC = itemvals.Length; - int ctr = 0; - // Trainer Type/Mega Evo int type = GetRandomType(i); bool mevo = rEnsureMEvo.Contains(i); bool typerand = rTypeTheme && !rGymE4Only || - rTypeTheme && rImportant[i] != null && (rImportant[i].Contains("GYM") || rImportant[i].Contains("ELITE") || rImportant[i].Contains("CHAMPION")); - + rTypeTheme && rImportant[i] != null && ImportantClasses.Contains(rImportant[i]); rSpeciesRand.rType = typerand; - var move = new MoveRandomizer(Main.Config) + byte[] trd = trdata[i]; + byte[] trp = trpoke[i]; + var t = new trdata6(trd, trp, Main.Config.ORAS) { - rDMG = rDMG, - rSTAB = rSTAB, - rSTABCount = rSTABCount, - rDMGCount = rDMGCount, + Moves = rMove || !rNoMove && checkBox_Moves.Checked, + Item = rItem || checkBox_Item.Checked }; - // Randomize Pokemon - for (int p = 0; p < CB_numPokemon.SelectedIndex; p++) - { - if (rPKM) - { - // randomize pokemon - int species = rSpeciesRand.GetRandomSpecies(trpk_pkm[p].SelectedIndex); - if (typerand) - { - species = rSpeciesRand.GetRandomSpeciesType(trpk_pkm[p].SelectedIndex, type); - if (p == CB_numPokemon.SelectedIndex - 1 && mevo) - { - int tries = 0; - while (!megaEvos.Contains(species) && tries < 0x10000) - species = rSpeciesRand.GetRandomSpeciesType(trpk_pkm[p].SelectedIndex, type); - } - } - else if (p == CB_numPokemon.SelectedIndex - 1 && mevo) - species = megaEvos[rnd32() % megaEvos.Length]; + InitializeTrainerTeamInfo(t, rImportant[i] == null); + RandomizeTrainerAIClass(t, trClass); + RandomizeTrainerPrizeItem(t); + RandomizeTeam(t, move, itemvals, type, mevo, typerand); - trpk_pkm[p].SelectedIndex = species; - // Set Gender to Random - trpk_gender[p].SelectedIndex = 0; - - if (trpk_form[p].Items.Count > 0) - trpk_form[p].SelectedIndex = 0; - // Randomize form - if (trpk_form[p].Items.Count > 0 && (!megaEvos.Contains(species) || rRandomMegas)) - trpk_form[p].SelectedIndex = (int)(rnd32() % trpk_form[p].Items.Count); - } - if (rLevel) - trpk_lvl[p].SelectedIndex = Randomizer.getModifiedLevel(trpk_lvl[p].SelectedIndex, rLevelMultiplier); - if (rAbility) - trpk_abil[p].SelectedIndex = (int)(1 + rnd32() % 3); - if (rDiffIV) - trpk_IV[p].SelectedIndex = 255; - if (mevo && p == CB_numPokemon.SelectedIndex - 1) - { - int[] megastones = GetMegaStones(trpk_pkm[p].SelectedIndex); - if (megastones.Length > 0) - trpk_item[p].SelectedIndex = megastones[rnd32() % megastones.Length]; - } - else if (rItem) - trpk_item[p].SelectedIndex = itemvals[rnd32() % itemC]; - - if (rMove) - { - var moves = new[] { trpk_m1[p], trpk_m2[p], trpk_m3[p], trpk_m4[p] }; - int species = trpk_pkm[p].SelectedIndex; - var pkMoves = move.GetRandomMoveset(species, 4); - - // Assign Moves - for (int m = 0; m < 4; m++) - moves[m].SelectedIndex = pkMoves[m]; - } - } + trdata[i] = t.Write(); + trpoke[i] = t.WriteTeam(); } - randomizing = false; CB_TrainerID.SelectedIndex = 1; WinFormsUtil.Alert("Randomized all Trainers according to specification!", "Press the Dump to .TXT button to view the new Trainer information!"); } + private static void RandomizeTeam(trdata6 t, MoveRandomizer move, ushort[] itemvals, int type, bool mevo, bool typerand) + { + int last = t.Team.Length - 1; + for (int p = 0; p < t.Team.Length; p++) + { + var pk = t.Team[p]; + int[] stones = null; + if (rPKM) + { + // randomize pokemon + int species = rSpeciesRand.GetRandomSpecies(pk.Species); + if (typerand) + { + species = rSpeciesRand.GetRandomSpeciesType(pk.Species, type); + if (p == last && mevo) + { + int tries = 0; + while (!megaEvos.Contains(species) && tries++ < 0x10000) + species = rSpeciesRand.GetRandomSpeciesType(pk.Species, type); + } + } + else if (p == last && mevo) + { + stones = GetRandomMega(out species); + species = megaEvos[rnd32() % megaEvos.Length]; + } + + pk.Species = (ushort)species; + pk.Gender = 0; // Set Gender to Random + bool mega = !megaEvos.Contains(species) || rRandomMegas; + pk.Form = (ushort)Randomizer.GetRandomForme(pk.Species, mega, true, Main.SpeciesStat); + } + if (rLevel) + pk.Level = (ushort)Randomizer.getModifiedLevel(pk.Level, rLevelMultiplier); + if (rAbility) + pk.Ability = (int)(1 + rnd32() % 3); + if (rDiffIV) + pk.IVs = 255; + + if (mevo && p == last && stones != null) + pk.Item = (ushort)stones[rnd32() % stones.Length]; + else if (rItem) + pk.Item = itemvals[rnd32() % itemvals.Length]; + + if (rMove) + { + var pkMoves = move.GetRandomMoveset(pk.Species, 4); + for (int m = 0; m < 4; m++) + pk.Moves[m] = (ushort)pkMoves[m]; + } + } + } + private static void InitializeTrainerTeamInfo(trdata6 t, bool important) + { + // skip the first rival battles + if (!r6PKM || important) + return; + + // Copy the last slot to random pokemon + int lastPKM = Math.Max(t.NumPokemon - 1, 0); // 0,1-6 => 0-5 (never is 0) + + t.NumPokemon = 6; + for (int f = lastPKM + 1; f < t.NumPokemon; f++) + { + t.Team[f].Species = t.Team[lastPKM].Species; + t.Team[f].Level = (ushort)Math.Min(t.Team[f - 1].Level + 1, 100); + } + } + private static void RandomizeTrainerAIClass(trdata6 t, string[] trClass) + { + if (rDiffAI) + t.AI |= 7; // Set first 3 bits, keep any other flag if present + if (rOnlySingles) + t.AI &= 7; + + if ( + rClass // Classes selected to be randomized + && (!rOnlySingles || t.BattleType == 0) // Nonsingles only get changed if rOnlySingles + && !rIgnoreClass.Contains(t.Class) // Current class isn't a special class + ) + { + int randClass() => (int)(rnd32() % trClass.Length); + int rv; do { rv = randClass(); } + // Ensure the Random Class isn't an exclusive class + while (rIgnoreClass.Contains(rv) && !trClass[rv].StartsWith("[~")); // don't allow disallowed classes + t.Class = rv; + } + } + private static void RandomizeTrainerPrizeItem(trdata6 t) + { + if (rGift && rnd32() % 100 < rGiftPercent) + { + ushort[] items; + uint rnd = rnd32() % 10; + if (rnd < 2) // held item + items = Main.Config.ORAS ? Legal.Pouch_Items_AO : Legal.Pouch_Items_XY; + else if (rnd < 5) // medicine + items = Main.Config.ORAS ? Legal.Pouch_Medicine_AO : Legal.Pouch_Medicine_XY; + else // berry + items = Legal.Pouch_Berry_XY; + t.Prize = items[rnd32() % items.Length]; + } + else if (rGift) + t.Prize = 0; + } + private string[] GetTagsORAS() { string[] tags = Enumerable.Repeat("", trdata.Length).ToArray(); @@ -875,103 +881,13 @@ private void TagTrainer(string[] trTags, string tag, params int[] ids) foreach (int id in ids) rImportant[id] = tag; } - private int[] GetMegaStones(int species) // This is horrible. + + private static Dictionary MegaDictionary; + private static int[] GetRandomMega(out int species) { - switch (species) - { - case 3: - return new [] { 659 }; - case 6: - return new [] { 660, 678 }; - case 9: - return new [] { 661 }; - case 15: - return new [] { 770 }; - case 18: - return new [] { 762 }; - case 65: - return new [] { 679 }; - case 80: - return new [] { 760 }; - case 94: - return new [] { 656 }; - case 115: - return new [] { 675 }; - case 127: - return new [] { 671 }; - case 130: - return new [] { 676 }; - case 142: - return new [] { 672 }; - case 150: - return new [] { 662, 663 }; - case 181: - return new [] { 658 }; - case 208: - return new [] { 761 }; - case 212: - return new [] { 670 }; - case 214: - return new [] { 680 }; - case 229: - return new [] { 666 }; - case 248: - return new [] { 669 }; - case 254: - return new [] { 753 }; - case 257: - return new [] { 664 }; - case 260: - return new [] { 752 }; - case 282: - return new [] { 657 }; - case 302: - return new [] { 754 }; - case 303: - return new [] { 681 }; - case 306: - return new [] { 667 }; - case 308: - return new [] { 665 }; - case 310: - return new [] { 682 }; - case 319: - return new [] { 759 }; - case 323: - return new [] { 767 }; - case 334: - return new [] { 755 }; - case 354: - return new [] { 668 }; - case 359: - return new [] { 677 }; - case 362: - return new [] { 763 }; - case 373: - return new [] { 769 }; - case 376: - return new [] { 758 }; - case 380: - return new [] { 684 }; - case 381: - return new [] { 685 }; - case 428: - return new [] { 768 }; - case 445: - return new [] { 683 }; - case 448: - return new [] { 673 }; - case 460: - return new [] { 674 }; - case 475: - return new [] { 756 }; - case 531: - return new [] { 757 }; - case 719: - return new [] { 764 }; - default: - return new int[] { }; - } + int rnd = Util.rand.Next(0, MegaDictionary.Count - 1); + species = MegaDictionary.Keys.ElementAt(rnd); + return MegaDictionary.Values.ElementAt(rnd); } private int GetRandomType(int trainer) { @@ -995,11 +911,6 @@ private int[] GetMegaEvolvableTypes() Console.WriteLine("There are " + MEvoTypes.Count + " Types capable of Mega Evolution."); return MEvoTypes.ToArray(); } - private int GetRandomMegaEvolvablePokemon(int type) - { - List valids = megaEvos.Where(spec => (int)Main.SpeciesStat[spec].Types[0] == type || (int)Main.SpeciesStat[spec].Types[1] == type).ToList(); - return valids[(int)(rnd32() % valids.Count)]; - } private void formClosing(object sender, FormClosingEventArgs e) {