mirror of
https://github.com/kwsch/pk3DS.git
synced 2026-08-03 18:19:44 -05:00
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:
parent
24775fba68
commit
8d8546047d
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user