Standardize using FormRandomizer for all randomizers

This commit is contained in:
sora10pls
2020-06-27 14:59:59 -04:00
parent 4299e5d88b
commit 2e600b9080
10 changed files with 64 additions and 94 deletions

View File

@@ -10,14 +10,16 @@ public class EvolutionRandomizer : Randomizer
private readonly EvolutionSet[] Evolutions;
private readonly GameInfo Game;
private readonly PersonalTable Personal;
public readonly SpeciesRandomizer Randomizer;
public readonly SpeciesRandomizer RandSpec;
public readonly FormRandomizer RandForm;
public EvolutionRandomizer(GameInfo game, EvolutionSet[] evolutions, PersonalTable t)
{
Game = game;
Personal = t;
Evolutions = evolutions;
Randomizer = new SpeciesRandomizer(Game, t);
RandSpec = new SpeciesRandomizer(Game, t);
RandForm = new FormRandomizer(t);
}
public override void Execute()
@@ -44,8 +46,8 @@ private void Randomize(EvolutionSet evos, int species)
{
if (evo.Method != 0)
{
evo.Species = Randomizer.GetRandomSpecies(evo.Species, species);
evo.Form = Legal.GetRandomForme(evo.Species, false, true, Game.SWSH, Personal);
evo.Species = RandSpec.GetRandomSpecies(evo.Species, species);
evo.Form = RandForm.GetRandomForme(evo.Species, false, true, Game.SWSH, Personal.Table);
}
}
}

View File

@@ -1,4 +1,5 @@
using pkNX.Structures;
using System;
using System.Linq;
using static pkNX.Structures.Species;
@@ -13,11 +14,7 @@ public FormRandomizer(PersonalTable t)
Personal = t;
}
public bool AllowMega { get; set; } = false;
public bool AllowAlolanForm { get; set; } = true;
public bool AllowGalarianForm { get; set; } = true;
public int GetRandomForme(int species, PersonalInfo[] stats = null)
public int GetRandomForme(int species, bool mega, bool alola, bool galar, PersonalInfo[] stats = null)
{
if (stats == null)
stats = Personal.Table;
@@ -30,7 +27,7 @@ public int GetRandomForme(int species, PersonalInfo[] stats = null)
case Deerling:
case Sawsbuck:
return 31; // Random
case Greninja when !AllowMega:
case Greninja when !mega:
case Eternatus:
return 0;
case Scatterbug:
@@ -41,26 +38,42 @@ public int GetRandomForme(int species, PersonalInfo[] stats = null)
return Util.Random.Next(7); // keep the core color a surprise
// Galarian Forms
case Meowth when AllowGalarianForm: // Kanto, Alola, Galar
case Meowth when galar: // Kanto, Alola, Galar
return Util.Random.Next(3);
case Darmanitan when AllowGalarianForm: // Standard, Zen, Galar Standard, Galar Zen
case Darmanitan when galar: // Standard, Zen, Galar Standard, Galar Zen
return Util.Random.Next(4);
case Slowbro when AllowGalarianForm: // Slowbro-1 is Mega and Slowbro-2 is Galar, so only return 0 or 2
{
int form = Util.Random.Next(2);
if (form == 1)
form++;
return form;
}
// some species have 1 invalid form among several other valid forms, handle them here
case Pikachu when Personal.TableLength == 1181:
case Slowbro when galar:
{
int form = Util.Random.Next(stats[species].FormeCount - 1);
int banned = GetInvalidForm(species, galar, Personal);
if (form == banned)
form++;
return form;
}
}
if (AllowAlolanForm && Legal.EvolveToAlolanForms.Contains(species))
if (Personal.TableLength == 980 && (species == (int)Pikachu || species == (int)Eevee)) // gg tableB -- no starters, they crash trainer battles.
return 0;
if (alola && Legal.EvolveToAlolanForms.Contains(species))
return Util.Random.Next(2);
if (AllowGalarianForm && Legal.EvolveToGalarForms.Contains(species))
if (galar && Legal.EvolveToGalarForms.Contains(species))
return Util.Random.Next(2);
if (!Legal.BattleExclusiveForms.Contains(species) || AllowMega)
if (!Legal.BattleExclusiveForms.Contains(species) || mega)
return Util.Random.Next(stats[species].FormeCount); // Slot-Random
return 0;
}
public int GetInvalidForm(int species, bool galar, PersonalTable stats)
{
return species switch
{
(int)Pikachu when stats.TableLength == 1181 => 8, // LGPE Partner Pikachu
(int)Slowbro when galar => 1, // Mega Slowbro
_ => throw new ArgumentOutOfRangeException(nameof(species))
};
}
}
}

View File

@@ -20,6 +20,7 @@ public class TrainerRandomizer : Randomizer
public GenericRandomizer<int> Class { get; set; }
public LearnsetRandomizer Learn { get; set; }
public SpeciesRandomizer RandSpec { get; set; }
public FormRandomizer RandForm { get; set; }
public MoveRandomizer RandMove { get; set; }
public int ClassCount { get; set; }
public Func<TrainerPoke> GetBlank { get; set; }
@@ -161,7 +162,7 @@ private void RandomizeSpecFormItem(IPokeData pk, int Type)
else // every other pkm
{
pk.Species = RandSpec.GetRandomSpeciesType(pk.Species, Type);
pk.Form = Legal.GetRandomForme(pk.Species, Settings.AllowRandomMegaForms, true, true, Personal);
pk.Form = RandForm.GetRandomForme(pk.Species, Settings.AllowRandomMegaForms, true, true, Personal.Table);
}
}
@@ -180,7 +181,7 @@ private void RandomizeSpecForm(TrainerPoke7b pk, int type)
else
{
pk.Species = RandSpec.GetRandomSpeciesType(pk.Species, type);
pk.Form = Legal.GetRandomForme(pk.Species, Settings.AllowRandomMegaForms, true, false, Personal);
pk.Form = RandForm.GetRandomForme(pk.Species, Settings.AllowRandomMegaForms, true, false, Personal.Table);
}
}
@@ -254,7 +255,7 @@ private void UpdatePKMFromSettings(TrainerPoke pk)
return;
c.Species = AllowedGigantamaxes[Util.Random.Next(AllowedGigantamaxes.Length)];
c.Form = c.Species == (int)Species.Pikachu || c.Species == (int)Species.Meowth ? 0 : Legal.GetRandomForme(c.Species, false, false, false, Personal); // Pikachu & Meowth altforms can't gmax
c.Form = c.Species == (int)Species.Pikachu || c.Species == (int)Species.Meowth ? 0 : RandForm.GetRandomForme(c.Species, false, false, false, Personal.Table); // Pikachu & Meowth altforms can't gmax
}
if (Settings.MaxDynamaxLevel && c.CanDynamax)
c.DynamaxLevel = 10;

View File

@@ -6,58 +6,6 @@ namespace pkNX.Structures
{
public static partial class Legal
{
public static int GetRandomForme(int species, bool mega, bool alola, bool galar, PersonalTable stats)
{
if (stats == null)
return 0;
if (stats[species].FormeCount <= 1)
return 0;
if (species == (int)Species.Unown || species == (int)Species.Deerling || species == (int)Species.Sawsbuck)
return 31; // Random
if ((species == (int)Species.Greninja && !mega) || species == (int)Species.Eternatus)
return 0;
if (species == (int)Species.Scatterbug || species == (int)Species.Spewpa || species == (int)Species.Vivillon)
return 30; // save file specific
if (species == (int)Species.Minior)
return Util.Rand.Next(7); // keep the core color a surprise
if (galar)
{
switch ((Species)species)
{
case Species.Meowth:
return Util.Rand.Next(3); // Kanto, Alola, Galar
case Species.Darmanitan:
return Util.Rand.Next(4); // Standard, Zen, Galar Standard, Galar Zen
case Species.Slowbro:
{
int form = Util.Rand.Next(2); // Slowbro-1 is Mega and Slowbro-2 is Galar, so only return 0 or 2
if (form == 1)
form++;
return form;
}
}
}
if (stats.TableLength == 980 && (species == (int)Species.Pikachu || species == (int)Species.Eevee)) // gg tableB -- no starters, they crash trainer battles.
return 0;
if (stats.TableLength == 1181 && species == (int)Species.Pikachu) // SWSH -- disallow Partner Pikachu from LGPE, but allow World Cap
{
int form = Util.Rand.Next(9);
if (form == 8)
form++;
return form;
}
if (EvolveToAlolanForms.Contains(species))
return alola ? Util.Rand.Next(2) : 0;
if (EvolveToGalarForms.Contains(species))
return galar ? Util.Rand.Next(2) : 0;
if (!BattleExclusiveForms.Contains(species) || mega)
return Util.Rand.Next(stats[species].FormeCount); // Slot-Random
return 0;
}
/// <summary>
/// Multiplies the current level with a scaling factor, returning a modified level.
/// </summary>
@@ -176,6 +124,7 @@ public static int[] GetRandomItemList(GameVersion game)
{362, new[] {763}}, // Glalie @ Glalitite
{373, new[] {769}}, // Salamence @ Salamencite
{376, new[] {758}}, // Metagross @ Metagrossite
// Rayquaza requires Dragon Ascent, no Held Item
{428, new[] {768}}, // Lopunny @ Lopunnite
{475, new[] {756}}, // Gallade @ Galladite
{531, new[] {757}}, // Audino @ Audinite

View File

@@ -136,7 +136,7 @@ public PersonalInfo GetFormeEntry(int species, int forme)
}
/// <summary>
/// Count of entries in the table, which includes default species entries and their separate AltForm ID entreis.
/// Count of entries in the table, which includes default species entries and their separate AltForm ID entries.
/// </summary>
public int TableLength => Table.Length;

View File

@@ -120,11 +120,12 @@ void Randomize()
var spec = EditUtil.Settings.Species;
spec.Gen2 = spec.Gen3 = spec.Gen4 = spec.Gen5 = spec.Gen6 = spec.Gen7 = false;
var srand = new SpeciesRandomizer(ROM.Info, ROM.Data.PersonalData);
var frand = new FormRandomizer(ROM.Data.PersonalData);
srand.Initialize(spec);
foreach (var t in objs)
{
t.Species = (Species)srand.GetRandomSpecies((int)t.Species);
t.Form = Legal.GetRandomForme((int)t.Species, false, true, false, ROM.Data.PersonalData);
t.Form = frand.GetRandomForme((int)t.Species, false, true, false, ROM.Data.PersonalData.Table);
t.Nature = Nature.Random25;
t.Gender = FixedGender.Random;
t.Shiny = Shiny.Random;
@@ -155,12 +156,13 @@ void Randomize()
var spec = EditUtil.Settings.Species;
spec.Gen2 = spec.Gen3 = spec.Gen4 = spec.Gen5 = spec.Gen6 = spec.Gen7 = false;
var srand = new SpeciesRandomizer(ROM.Info, ROM.Data.PersonalData);
var frand = new FormRandomizer(ROM.Data.PersonalData);
srand.Initialize(spec, 808, 809); // can only catch 1-151 in wild
foreach (var t in objs)
{
t.Species = (Species)srand.GetRandomSpecies((int)t.Species);
t.RequiredSpecies = (Species)srand.GetRandomSpecies((int)t.Species);
t.Form = Legal.GetRandomForme((int)t.Species, false, true, false, ROM.Data.PersonalData);
t.Form = frand.GetRandomForme((int)t.Species, false, true, false, ROM.Data.PersonalData.Table);
t.RequiredForm = 0; // can't catch wild alolan forms
t.Nature = Nature.Random - 1;
t.Gender = FixedGender.Random;
@@ -192,12 +194,13 @@ void Randomize()
var spec = EditUtil.Settings.Species;
spec.Gen2 = spec.Gen3 = spec.Gen4 = spec.Gen5 = spec.Gen6 = spec.Gen7 = false;
var srand = new SpeciesRandomizer(ROM.Info, ROM.Data.PersonalData);
var frand = new FormRandomizer(ROM.Data.PersonalData);
srand.Initialize(spec);
for (int i = 2; i < objs.Length; i++) // skip starters
{
var t = objs[i];
t.Species = (Species)srand.GetRandomSpecies((int)t.Species);
t.Form = Legal.GetRandomForme((int)t.Species, false, true, false, ROM.Data.PersonalData);
t.Form = frand.GetRandomForme((int)t.Species, false, true, false, ROM.Data.PersonalData.Table);
t.Nature = Nature.Random25;
t.Gender = FixedGender.Random;
t.Shiny = Shiny.Random;

View File

@@ -237,13 +237,14 @@ void Randomize()
var spec = EditUtil.Settings.Species;
var srand = new SpeciesRandomizer(ROM.Info, ROM.Data.PersonalData);
var frand = new FormRandomizer(ROM.Data.PersonalData);
srand.Initialize(spec, ban);
foreach (var t in arr)
{
foreach (var p in t.Entries)
{
p.Species = srand.GetRandomSpecies(p.Species);
p.AltForm = Legal.GetRandomForme(p.Species, false, true, true, ROM.Data.PersonalData);
p.AltForm = frand.GetRandomForme(p.Species, false, true, true, ROM.Data.PersonalData.Table);
p.Ability = 4; // "A4" -- 1, 2, or H
p.Gender = 0; // random
p.IsGigantamax = false; // don't allow gmax flag on non-gmax species
@@ -278,9 +279,7 @@ void Randomize()
foreach (var t in arr)
{
foreach (var i in t.Entries)
{
i.ItemID = (uint)PossibleHeldItems[Randomization.Util.Random.Next(PossibleHeldItems.Length)];
}
}
}
@@ -310,9 +309,7 @@ void Randomize()
foreach (var t in arr)
{
foreach (var i in t.Entries)
{
i.ItemID = (uint)PossibleHeldItems[Randomization.Util.Random.Next(PossibleHeldItems.Length)];
}
}
}
@@ -345,13 +342,14 @@ void Randomize()
var spec = EditUtil.Settings.Species;
var srand = new SpeciesRandomizer(ROM.Info, ROM.Data.PersonalData);
var frand = new FormRandomizer(ROM.Data.PersonalData);
srand.Initialize(spec, ban);
foreach (var t in encounters)
{
if (t.Species >= Species.Zacian && t.Species <= Species.Eternatus) // Eternatus crashes when changed, keep Zacian and Zamazenta to make final boss battle fair
continue;
t.Species = (Species)srand.GetRandomSpecies((int)t.Species);
t.AltForm = Legal.GetRandomForme((int)t.Species, false, true, true, ROM.Data.PersonalData);
t.AltForm = frand.GetRandomForme((int)t.Species, false, true, true, ROM.Data.PersonalData.Table);
t.Ability = Randomization.Util.Random.Next(1, 4); // 1, 2, or H
t.HeldItem = PossibleHeldItems[Randomization.Util.Random.Next(PossibleHeldItems.Length)];
t.Nature = Nature.Random25;
@@ -391,6 +389,7 @@ void Randomize()
var spec = EditUtil.Settings.Species;
var srand = new SpeciesRandomizer(ROM.Info, ROM.Data.PersonalData);
var frand = new FormRandomizer(ROM.Data.PersonalData);
srand.Initialize(spec, ban);
foreach (var t in gifts)
{
@@ -398,12 +397,12 @@ void Randomize()
if (t.CanGigantamax)
{
t.Species = (Species)Legal.GigantamaxForms[Randomization.Util.Random.Next(Legal.GigantamaxForms.Length)];
t.AltForm = t.Species == Species.Pikachu || t.Species == Species.Meowth ? 0 : Legal.GetRandomForme((int)t.Species, false, false, false, ROM.Data.PersonalData); // Pikachu & Meowth altforms can't gmax
t.AltForm = t.Species == Species.Pikachu || t.Species == Species.Meowth ? 0 : frand.GetRandomForme((int)t.Species, false, false, false, ROM.Data.PersonalData.Table); // Pikachu & Meowth altforms can't gmax
}
else
{
t.Species = (Species)srand.GetRandomSpecies((int)t.Species);
t.AltForm = Legal.GetRandomForme((int)t.Species, false, true, true, ROM.Data.PersonalData);
t.AltForm = frand.GetRandomForme((int)t.Species, false, true, true, ROM.Data.PersonalData.Table);
}
t.Ability = Randomization.Util.Random.Next(1, 4); // 1, 2, or H
@@ -445,12 +444,13 @@ void Randomize()
var spec = EditUtil.Settings.Species;
var srand = new SpeciesRandomizer(ROM.Info, ROM.Data.PersonalData);
var frand = new FormRandomizer(ROM.Data.PersonalData);
srand.Initialize(spec, ban);
foreach (var t in trades)
{
// what you receive
t.Species = (Species)srand.GetRandomSpecies((int)t.Species);
t.AltForm = Legal.GetRandomForme((int)t.Species, false, true, true, ROM.Data.PersonalData);
t.AltForm = frand.GetRandomForme((int)t.Species, false, true, true, ROM.Data.PersonalData.Table);
t.Ability = Randomization.Util.Random.Next(1, 4); // 1, 2, or H
t.Ball = (Ball)Randomization.Util.Random.Next(1, 15); // packed bit, only allows for 15 balls
t.HeldItem = PossibleHeldItems[Randomization.Util.Random.Next(PossibleHeldItems.Length)];
@@ -463,7 +463,7 @@ void Randomize()
// what you trade
t.RequiredSpecies = (Species)srand.GetRandomSpecies((int)t.RequiredSpecies);
t.RequiredForm = Legal.GetRandomForme((int)t.RequiredSpecies, false, true, true, ROM.Data.PersonalData);
t.RequiredForm = frand.GetRandomForme((int)t.RequiredSpecies, false, true, true, ROM.Data.PersonalData.Table);
t.RequiredNature = Nature.Random25; // any
}
}

View File

@@ -595,6 +595,7 @@ private TrainerRandomizer GetRandomizer()
}
var rspec = new SpeciesRandomizer(Game.Info, Personal);
var rform = new FormRandomizer(Personal);
rspec.Initialize((SpeciesSettings)PG_Species.SelectedObject, ban);
learn.Moves = moves;
var evos = Game.Data.EvolutionData;
@@ -604,6 +605,7 @@ private TrainerRandomizer GetRandomizer()
Learn = learn,
RandMove = rmove,
RandSpec = rspec,
RandForm = rform,
GetBlank = () => (Game.Info.SWSH ? (TrainerPoke)new TrainerPoke8() : new TrainerPoke7b()), // this should probably be less specific
};
trand.Initialize((TrainerRandSettings)PG_RTrainer.SelectedObject, (SpeciesSettings)PG_Species.SelectedObject);

View File

@@ -489,7 +489,7 @@ private void B_RandEvo_Click(object sender, EventArgs e)
.Where(z => !z.Present).Select(z => z.Species).ToArray();
}
rand.Randomizer.Initialize(settings, ban);
rand.RandSpec.Initialize(settings, ban);
rand.Execute();
LoadIndex(CB_Species.SelectedIndex);
System.Media.SystemSounds.Asterisk.Play();
@@ -502,7 +502,7 @@ private void B_TradeEvo_Click(object sender, EventArgs e)
if (ROM.Info.GG)
settings.Gen2 = settings.Gen3 = settings.Gen4 = settings.Gen5 = settings.Gen6 = settings.Gen7 = settings.Gen8 = false;
var rand = new EvolutionRandomizer(ROM.Info, Editor.Evolve.LoadAll(), Editor.Personal);
rand.Randomizer.Initialize(settings);
rand.RandSpec.Initialize(settings);
rand.ExecuteTrade();
LoadIndex(CB_Species.SelectedIndex);
System.Media.SystemSounds.Asterisk.Play();

View File

@@ -192,7 +192,7 @@ void ApplyRand(IList<EncounterSlot8> slots)
}
s.Species = rand.GetRandomSpecies(s.Species);
s.Form = fr.GetRandomForme(s.Species);
s.Form = fr.GetRandomForme(s.Species, false, true, true, ROM.Data.PersonalData.Table);
if (fill)
s.Probability = RandomScaledRates[slots.Count][i];
}