Speed up RSTE randomization

essentially instant now
may have borked something, lmk; could have rewritten from scratch but
the conversion seemed simple enough
This commit is contained in:
Kurt 2017-10-08 23:01:52 -07:00
parent 24775fba68
commit 8d8546047d
2 changed files with 154 additions and 237 deletions

View File

@ -22,9 +22,8 @@ public GiftEditor6()
Close();
}
InitializeComponent();
MegaDictionary = Main.Config.XY ? MegaDictionaryXY : MegaDictionaryAO.Concat(MegaDictionaryXY)
.ToDictionary(pair => pair.Key, pair => pair.Value);
Dictionary<int, int[]> 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<int, int[]> 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;

View File

@ -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<int> banned = new List<int> { 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<int> GymE4Types = new List<int>();
// 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<int, int[]> 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<int> 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)
{