More generator fixes/improvements

Fix/add missing gameversion references (BU instead of BW,
pokewalker=HGSS)
increase reuse of pidgenerator & add more generating methods.

seems like it's generating pkm fine besides the PID edge cases, which is
nice
This commit is contained in:
Kurt 2018-04-29 09:31:13 -07:00
parent 08603c5664
commit 4214b1be7b
5 changed files with 67 additions and 41 deletions

View file

@ -40,7 +40,7 @@ namespace PKHeX.Core
var ylw_fish = EncounterArea.GetArray1_FY(Util.GetBinaryResource("encounter_yellow_f.pkl"));
MarkEncountersVersion(red_gw, GameVersion.RD);
MarkEncountersVersion(blu_gw, GameVersion.BW);
MarkEncountersVersion(blu_gw, GameVersion.BU);
MarkEncountersVersion(ylw_gw, GameVersion.YW);
MarkEncountersVersion(rb_fish, GameVersion.RB);
MarkEncountersVersion(ylw_fish, GameVersion.YW);

View file

@ -154,6 +154,7 @@ namespace PKHeX.Core
{
s.Location = 233; //Pokéwalker
s.Gift = true; //Pokeball only
s.Version = GameVersion.HGSS;
}
}
private static void MarkG4SlotsGreatMarsh(ref EncounterArea[] Areas, int location)

View file

@ -96,8 +96,8 @@ namespace PKHeX.Core
}
pk.Language = lang;
PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, Util.Rand.Next(0, 2), gender);
var pidtype = GetPIDType();
PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, Util.Rand.Next(0, 2), gender, pidtype);
if (Permissions.IsDexNav)
{
@ -106,10 +106,6 @@ namespace PKHeX.Core
if (eggMoves.Length > 0)
pk.RelearnMove1 = eggMoves[Util.Rand.Next(eggMoves.Length)];
}
else
{
pk.RefreshAbility(Util.Rand.Next(2));
}
switch (pk.Format)
{
@ -142,6 +138,14 @@ namespace PKHeX.Core
return pk;
}
private PIDType GetPIDType()
{
if (Version == GameVersion.XD)
return PIDType.PokeSpot;
return PIDType.None; // depends on format, let the program auto-detect.
}
private int GetBall()
{
if (Type == SlotType.BugContest)

View file

@ -113,7 +113,10 @@ namespace PKHeX.Core
pk5.NPokémon = pid.NSparkle;
}
else
PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, Ability, gender);
{
var pidtype = GetPIDType();
PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, Ability >> 1, gender);
}
if (IVs != null)
pk.SetRandomIVs(IVs, FlawlessIVCount);
@ -158,5 +161,14 @@ namespace PKHeX.Core
return pk;
}
private PIDType GetPIDType()
{
if (Roaming)
return PIDType.Method_1_Roamer;
if (Version == GameVersion.HGSS && Location == 233) // Pokéwalker
return PIDType.Pokewalker;
return PIDType.None;
}
}
}

View file

@ -103,45 +103,43 @@ namespace PKHeX.Core
public static void SetValuesFromSeed(PKM pk, PIDType type, uint seed)
{
switch (type)
var method = GetGeneratorMethod(type);
method(pk, seed);
}
private static Action<PKM, uint> GetGeneratorMethod(PIDType t)
{
switch (t)
{
case PIDType.Channel:
SetValuesFromSeedChannel(pk, seed);
break;
return SetValuesFromSeedChannel;
case PIDType.CXD:
SetValuesFromSeedXDRNG(pk, seed);
break;
return SetValuesFromSeedXDRNG;
case PIDType.Method_1:
case PIDType.Method_2:
case PIDType.Method_4:
SetValuesFromSeedLCRNG(pk, type, seed);
break;
case PIDType.Method_1_Unown:
case PIDType.Method_2_Unown:
case PIDType.Method_4_Unown:
case PIDType.Method_1_Roamer:
return (pk, seed) => SetValuesFromSeedLCRNG(pk, t, seed);
case PIDType.BACD_R:
case PIDType.BACD_R_A:
case PIDType.BACD_R_S:
SetValuesFromSeedBACD(pk, type, seed);
break;
return (pk, seed) => SetValuesFromSeedBACD(pk, t, seed & 0xFFFF);
case PIDType.BACD_U:
case PIDType.BACD_U_A:
case PIDType.BACD_U_S:
SetValuesFromSeedBACD(pk, type, seed);
break;
return (pk, seed) => SetValuesFromSeedBACD(pk, t, seed);
case PIDType.PokeSpot:
return SetRandomPIDIV;
// others: unimplemented
case PIDType.ChainShiny:
break;
case PIDType.Method_1_Unown:
case PIDType.Method_2_Unown:
case PIDType.Method_4_Unown:
break;
case PIDType.Method_1_Roamer:
break;
case PIDType.CuteCharm:
break;
case PIDType.PokeSpot:
case PIDType.ChainShiny:
break;
case PIDType.G4MGAntiShiny:
break;
@ -150,6 +148,7 @@ namespace PKHeX.Core
case PIDType.Pokewalker:
break;
}
return (pk, seed) => { };
}
public static uint GetMG5ShinyPID(uint gval, uint av, int TID, int SID)
@ -160,14 +159,13 @@ namespace PKHeX.Core
return PID;
}
public static void SetRandomWildPID(PKM pk, int gen, int nature, int ability, int gender)
public static void SetRandomWildPID(PKM pk, int gen, int nature, int ability, int gender, PIDType specific = PIDType.None)
{
ability >>= 1;
switch (gen)
{
case 3:
case 4:
SetRandomWildPID4(pk, nature, ability, gender);
SetRandomWildPID4(pk, nature, ability, gender, specific);
break;
case 5:
SetRandomWildPID5(pk, nature, ability, gender);
@ -178,15 +176,26 @@ namespace PKHeX.Core
}
}
private static void SetRandomWildPID4(PKM pk, int nature, int ability, int gender, bool roam = false)
/// <summary>
/// Generates a <see cref="PKM.PID"/> and <see cref="PKM.IVs"/> that are unrelated.
/// </summary>
/// <param name="pkm">Pokémon to modify.</param>
/// <param name="seed">Seed which is used for the <see cref="PKM.PID"/>.</param>
private static void SetRandomPIDIV(PKM pkm, uint seed)
{
pkm.PID = seed;
SetRandomIVs(pkm);
}
private static void SetRandomWildPID4(PKM pk, int nature, int ability, int gender, PIDType specific = PIDType.None)
{
pk.RefreshAbility(ability);
var type = GetPIDType(pk, roam);
var method = type == PIDType.CXD ? (Action<PKM, uint>)SetValuesFromSeedXDRNG : (pkm, seed) => SetValuesFromSeedLCRNG(pkm, type, seed);
var type = GetPIDType(pk, specific);
var method = GetGeneratorMethod(type);
while (true)
{
uint seed = Util.Rand32();
method(pk, seed);
method(pk, Util.Rand32());
if (pk.GetSaneGender(gender) != gender)
continue;
@ -194,16 +203,16 @@ namespace PKHeX.Core
if (pk.Nature != nature)
continue;
if (((seed >> 0) & 1) != ability)
if ((pk.PID & 1) != ability)
continue;
return;
}
}
private static PIDType GetPIDType(PKM pk, bool roam)
private static PIDType GetPIDType(PKM pk, PIDType specific)
{
if (roam)
return PIDType.Method_1_Roamer;
if (specific != PIDType.None)
return specific;
if (pk.Version == 15)
return PIDType.CXD;
if (pk.GenNumber == 3 && pk.Species == 201)