mirror of
https://github.com/kwsch/PKHeX
synced 2025-02-17 05:48:44 +00:00
Misc updates
Detect channel, only detect Channel PIDIV for RS origin (only really care about method1/2/4 being used when it shouldn't) Channel does this weird thing called not setting the met level. Refactor set suggested met location to a method that can suppress popups.
This commit is contained in:
parent
9f9f0e4ab3
commit
1c4a1af633
9 changed files with 125 additions and 65 deletions
|
@ -618,7 +618,7 @@ namespace PKHeX.Core
|
||||||
{
|
{
|
||||||
switch (gift)
|
switch (gift)
|
||||||
{
|
{
|
||||||
case WC3 wc3 when wc3.IsEgg && pkm.Met_Level == 0:
|
case WC3 wc3 when wc3.Met_Level == pkm.Met_Level:
|
||||||
break;
|
break;
|
||||||
case WC7 wc7 when wc7.MetLevel == pkm.Met_Level:
|
case WC7 wc7 when wc7.MetLevel == pkm.Met_Level:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace PKHeX.Core
|
||||||
// Special cases
|
// Special cases
|
||||||
if (GetLCRNGRoamerMatch(top, bot, IVs, out pidiv))
|
if (GetLCRNGRoamerMatch(top, bot, IVs, out pidiv))
|
||||||
return pidiv;
|
return pidiv;
|
||||||
if (GetChannelMatch(top, bot, IVs, out pidiv))
|
if (GetChannelMatch(top, bot, IVs, out pidiv, pk))
|
||||||
return pidiv;
|
return pidiv;
|
||||||
if (GetMG4Match(pid, IVs, out pidiv))
|
if (GetMG4Match(pid, IVs, out pidiv))
|
||||||
return pidiv;
|
return pidiv;
|
||||||
|
@ -200,15 +200,35 @@ namespace PKHeX.Core
|
||||||
pidiv = null;
|
pidiv = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
private static bool GetChannelMatch(uint top, uint bot, uint[] IVs, out PIDIV pidiv)
|
private static bool GetChannelMatch(uint top, uint bot, uint[] IVs, out PIDIV pidiv, PKM pk)
|
||||||
{
|
{
|
||||||
|
var ver = pk.Version;
|
||||||
|
if (ver != (int) GameVersion.R && ver != (int) GameVersion.S)
|
||||||
|
{
|
||||||
|
pidiv = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var channel = GetSeedsFromPID(RNG.XDRNG, bot, top ^ 0x8000);
|
var channel = GetSeedsFromPID(RNG.XDRNG, bot, top ^ 0x8000);
|
||||||
foreach (var seed in channel)
|
foreach (var seed in channel)
|
||||||
{
|
{
|
||||||
var E = RNG.XDRNG.Advance(seed, 5);
|
var C = RNG.XDRNG.Advance(seed, 3); // held item
|
||||||
|
// no checks, held item can be swapped
|
||||||
|
|
||||||
|
var D = RNG.XDRNG.Next(C); // Version
|
||||||
|
if ((D >> 31) + 1 != ver) // (0-Sapphire, 1-Ruby)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var E = RNG.XDRNG.Next(D); // OT Gender
|
||||||
|
if (E >> 31 != pk.OT_Gender)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!GetIVs(RNG.XDRNG, E).SequenceEqual(IVs))
|
if (!GetIVs(RNG.XDRNG, E).SequenceEqual(IVs))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (seed >> 16 != pk.SID)
|
||||||
|
continue;
|
||||||
|
|
||||||
pidiv = new PIDIV {OriginSeed = RNG.XDRNG.Prev(seed), RNG = RNG.XDRNG, Type = PIDType.Channel};
|
pidiv = new PIDIV {OriginSeed = RNG.XDRNG.Prev(seed), RNG = RNG.XDRNG, Type = PIDType.Channel};
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
/// <summary> The RNG seed which immediately generates the PIDIV (starting with PID or IVs, whichever comes first). </summary>
|
/// <summary> The RNG seed which immediately generates the PIDIV (starting with PID or IVs, whichever comes first). </summary>
|
||||||
public uint OriginSeed;
|
public uint OriginSeed;
|
||||||
|
|
||||||
|
/// <summary> Indicates that there is no <see cref="OriginSeed"/> to refer to. </summary>
|
||||||
|
/// <remarks> Some PIDIVs may be generated without a single seed, but may follow a traceable pattern. </remarks>
|
||||||
public bool NoSeed;
|
public bool NoSeed;
|
||||||
|
|
||||||
/// <summary> Type of PIDIV correlation </summary>
|
/// <summary> Type of PIDIV correlation </summary>
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
{
|
{
|
||||||
if (encounter.EggEncounter)
|
if (encounter.EggEncounter)
|
||||||
return pkm.CurrentLevel == Legal.GetEggHatchLevel(pkm);
|
return pkm.CurrentLevel == Legal.GetEggHatchLevel(pkm);
|
||||||
|
if (encounter is MysteryGift g)
|
||||||
|
return pkm.CurrentLevel == g.Level;
|
||||||
return pkm.CurrentLevel == pkm.Met_Level;
|
return pkm.CurrentLevel == pkm.Met_Level;
|
||||||
}
|
}
|
||||||
return encounter.IsWithinRange(pkm.CurrentLevel);
|
return encounter.IsWithinRange(pkm.CurrentLevel);
|
||||||
|
|
|
@ -299,11 +299,14 @@ namespace PKHeX.Core
|
||||||
|
|
||||||
// Berry Glitch Fix
|
// Berry Glitch Fix
|
||||||
// PCJP - (December 29, 2003 to March 31, 2004)
|
// PCJP - (December 29, 2003 to March 31, 2004)
|
||||||
new WC3 { Species = 263, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.BACD_R_S, TID = 21121, OT_Name = "ルビー", Language = 1 },
|
new WC3 { Species = 263, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.BACD_R_S, TID = 21121, OT_Name = "ルビー", Language = 1, OT_Gender = 1 },
|
||||||
new WC3 { Species = 263, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.BACD_R_S, TID = 21121, OT_Name = "サファイア", Language = 1 },
|
new WC3 { Species = 263, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.BACD_R_S, TID = 21121, OT_Name = "サファイア", Language = 1, OT_Gender = 0 },
|
||||||
// EBGames/GameStop (March 1, 2004 to April 22, 2007), also via multi-game discs
|
// EBGames/GameStop (March 1, 2004 to April 22, 2007), also via multi-game discs
|
||||||
new WC3 { Species = 263, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.BACD_R_S, TID = 30317, OT_Name = "RUBY", Language = 2 },
|
new WC3 { Species = 263, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.BACD_R_S, TID = 30317, OT_Name = "RUBY", Language = 2, OT_Gender = 1 },
|
||||||
new WC3 { Species = 263, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.BACD_R_S, TID = 30317, OT_Name = "SAPHIRE", Language = 2 },
|
new WC3 { Species = 263, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.BACD_R_S, TID = 30317, OT_Name = "SAPHIRE", Language = 2, OT_Gender = 0 },
|
||||||
|
|
||||||
|
// Channel Jirachi
|
||||||
|
new WC3 { Species = 385, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.Channel, TID = 40122, SID = -1, OT_Name = "CHANNEL", Met_Level = 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static readonly MysteryGift[] Encounter_Event3_Common =
|
internal static readonly MysteryGift[] Encounter_Event3_Common =
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace PKHeX.Core
|
||||||
public int SID { get; set; }
|
public int SID { get; set; }
|
||||||
public int Met_Location { get; internal set; } = 255;
|
public int Met_Location { get; internal set; } = 255;
|
||||||
public int Version { get; set; }
|
public int Version { get; set; }
|
||||||
public int Language { get; set; }
|
public int Language { get; set; } = -1;
|
||||||
public override int Species { get; set; }
|
public override int Species { get; set; }
|
||||||
public override bool IsEgg { get; set; }
|
public override bool IsEgg { get; set; }
|
||||||
public override int[] Moves { get; set; }
|
public override int[] Moves { get; set; }
|
||||||
|
@ -41,6 +41,19 @@ namespace PKHeX.Core
|
||||||
public override int ItemID { get; set; }
|
public override int ItemID { get; set; }
|
||||||
public override bool IsPokémon { get; set; }
|
public override bool IsPokémon { get; set; }
|
||||||
|
|
||||||
|
// Synthetic
|
||||||
|
private int _metLevel = -1;
|
||||||
|
public int Met_Level
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (IsEgg)
|
||||||
|
return 0;
|
||||||
|
return _metLevel < 0 ? Level : _metLevel;
|
||||||
|
}
|
||||||
|
set => _metLevel = value;
|
||||||
|
}
|
||||||
|
|
||||||
public override PKM ConvertToPKM(SaveFile SAV)
|
public override PKM ConvertToPKM(SaveFile SAV)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
|
@ -372,7 +372,7 @@ namespace PKHeX.Core
|
||||||
InvalidLines.Add("Unknown EV input.");
|
InvalidLines.Add("Unknown EV input.");
|
||||||
for (int i = 0; i < evlist.Length / 2; i++)
|
for (int i = 0; i < evlist.Length / 2; i++)
|
||||||
{
|
{
|
||||||
bool valid = ushort.TryParse(evlist[i * 2 + 0], out ushort EV);
|
bool valid = ushort.TryParse(evlist[i * 2 + 0], out ushort EV);
|
||||||
int index = Array.IndexOf(StatNames, evlist[i * 2 + 1]);
|
int index = Array.IndexOf(StatNames, evlist[i * 2 + 1]);
|
||||||
if (valid && index > -1)
|
if (valid && index > -1)
|
||||||
EVs[index] = EV;
|
EVs[index] = EV;
|
||||||
|
|
|
@ -646,51 +646,8 @@ namespace PKHeX.WinForms.Controls
|
||||||
UpdateLegality(skipMoveRepop: true);
|
UpdateLegality(skipMoveRepop: true);
|
||||||
if (Legality.Valid)
|
if (Legality.Valid)
|
||||||
return;
|
return;
|
||||||
|
if (!SetSuggestedMetLocation())
|
||||||
var encounter = Legality.GetSuggestedMetInfo();
|
|
||||||
if (encounter == null || (pkm.Format >= 3 && encounter.Location < 0))
|
|
||||||
{
|
|
||||||
WinFormsUtil.Alert("Unable to provide a suggestion.");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
int level = encounter.Level;
|
|
||||||
int location = encounter.Location;
|
|
||||||
int minlvl = Legal.GetLowestLevel(pkm, encounter.Species);
|
|
||||||
if (minlvl == 0)
|
|
||||||
minlvl = level;
|
|
||||||
|
|
||||||
if (pkm.CurrentLevel >= minlvl && pkm.Met_Level == level && pkm.Met_Location == location)
|
|
||||||
return;
|
|
||||||
if (minlvl < level)
|
|
||||||
minlvl = level;
|
|
||||||
|
|
||||||
var suggestion = new List<string> { "Suggested:" };
|
|
||||||
if (pkm.Format >= 3)
|
|
||||||
{
|
|
||||||
var met_list = GameInfo.GetLocationList((GameVersion)pkm.Version, pkm.Format, egg: false);
|
|
||||||
var locstr = met_list.FirstOrDefault(loc => loc.Value == location).Text;
|
|
||||||
suggestion.Add($"Met Location: {locstr}");
|
|
||||||
suggestion.Add($"Met Level: {level}");
|
|
||||||
}
|
|
||||||
if (pkm.CurrentLevel < minlvl)
|
|
||||||
suggestion.Add($"Current Level: {minlvl}");
|
|
||||||
|
|
||||||
if (suggestion.Count == 1) // no suggestion
|
|
||||||
return;
|
|
||||||
|
|
||||||
string suggest = string.Join(Environment.NewLine, suggestion);
|
|
||||||
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNo, suggest) != DialogResult.Yes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pkm.Format >= 3)
|
|
||||||
{
|
|
||||||
TB_MetLevel.Text = level.ToString();
|
|
||||||
CB_MetLocation.SelectedValue = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pkm.CurrentLevel < minlvl)
|
|
||||||
TB_Level.Text = minlvl.ToString();
|
|
||||||
|
|
||||||
pkm = PreparePKM();
|
pkm = PreparePKM();
|
||||||
UpdateLegality();
|
UpdateLegality();
|
||||||
|
@ -733,12 +690,13 @@ namespace PKHeX.WinForms.Controls
|
||||||
|
|
||||||
UpdateLegality();
|
UpdateLegality();
|
||||||
}
|
}
|
||||||
private bool SetSuggestedMoves(bool random = false)
|
private bool SetSuggestedMoves(bool random = false, bool silent = false)
|
||||||
{
|
{
|
||||||
int[] m = Legality.GetSuggestedMoves(tm: random, tutor: random, reminder: random);
|
int[] m = Legality.GetSuggestedMoves(tm: random, tutor: random, reminder: random);
|
||||||
if (m == null)
|
if (m == null)
|
||||||
{
|
{
|
||||||
WinFormsUtil.Alert("Suggestions are not enabled for this PKM format.");
|
if (!silent)
|
||||||
|
WinFormsUtil.Alert("Suggestions are not enabled for this PKM format.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,10 +709,13 @@ namespace PKHeX.WinForms.Controls
|
||||||
if (pkm.Moves.SequenceEqual(m))
|
if (pkm.Moves.SequenceEqual(m))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
string r = string.Join(Environment.NewLine,
|
if (!silent)
|
||||||
m.Select(v => v >= GameInfo.Strings.movelist.Length ? "ERROR" : GameInfo.Strings.movelist[v]));
|
{
|
||||||
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Apply suggested current moves?", r))
|
var movestrings = m.Select(v => v >= GameInfo.Strings.movelist.Length ? "ERROR" : GameInfo.Strings.movelist[v]);
|
||||||
return false;
|
string r = string.Join(Environment.NewLine, movestrings);
|
||||||
|
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Apply suggested current moves?", r))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CB_Move1.SelectedValue = m[0];
|
CB_Move1.SelectedValue = m[0];
|
||||||
CB_Move2.SelectedValue = m[1];
|
CB_Move2.SelectedValue = m[1];
|
||||||
|
@ -764,6 +725,9 @@ namespace PKHeX.WinForms.Controls
|
||||||
}
|
}
|
||||||
private bool SetSuggestedRelearnMoves(bool silent = false)
|
private bool SetSuggestedRelearnMoves(bool silent = false)
|
||||||
{
|
{
|
||||||
|
if (pkm.Format < 6)
|
||||||
|
return false;
|
||||||
|
|
||||||
int[] m = Legality.GetSuggestedRelearn();
|
int[] m = Legality.GetSuggestedRelearn();
|
||||||
if (m.All(z => z == 0))
|
if (m.All(z => z == 0))
|
||||||
if (!pkm.WasEgg && !pkm.WasEvent && !pkm.WasEventEgg && !pkm.WasLink)
|
if (!pkm.WasEgg && !pkm.WasEvent && !pkm.WasEventEgg && !pkm.WasLink)
|
||||||
|
@ -776,10 +740,13 @@ namespace PKHeX.WinForms.Controls
|
||||||
if (pkm.RelearnMoves.SequenceEqual(m))
|
if (pkm.RelearnMoves.SequenceEqual(m))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
string r = string.Join(Environment.NewLine,
|
if (!silent)
|
||||||
m.Select(v => v >= GameInfo.Strings.movelist.Length ? "ERROR" : GameInfo.Strings.movelist[v]));
|
{
|
||||||
if (!silent && DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Apply suggested relearn moves?", r))
|
var movestrings = m.Select(v => v >= GameInfo.Strings.movelist.Length ? "ERROR" : GameInfo.Strings.movelist[v]);
|
||||||
return false;
|
string r = string.Join(Environment.NewLine, movestrings);
|
||||||
|
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Apply suggested relearn moves?", r))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CB_RelearnMove1.SelectedValue = m[0];
|
CB_RelearnMove1.SelectedValue = m[0];
|
||||||
CB_RelearnMove2.SelectedValue = m[1];
|
CB_RelearnMove2.SelectedValue = m[1];
|
||||||
|
@ -787,6 +754,59 @@ namespace PKHeX.WinForms.Controls
|
||||||
CB_RelearnMove4.SelectedValue = m[3];
|
CB_RelearnMove4.SelectedValue = m[3];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
private bool SetSuggestedMetLocation(bool silent = false)
|
||||||
|
{
|
||||||
|
var encounter = Legality.GetSuggestedMetInfo();
|
||||||
|
if (encounter == null || pkm.Format >= 3 && encounter.Location < 0)
|
||||||
|
{
|
||||||
|
if (!silent)
|
||||||
|
WinFormsUtil.Alert("Unable to provide a suggestion.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int level = encounter.Level;
|
||||||
|
int location = encounter.Location;
|
||||||
|
int minlvl = Legal.GetLowestLevel(pkm, encounter.Species);
|
||||||
|
if (minlvl == 0)
|
||||||
|
minlvl = level;
|
||||||
|
|
||||||
|
if (pkm.CurrentLevel >= minlvl && pkm.Met_Level == level && pkm.Met_Location == location)
|
||||||
|
return false;
|
||||||
|
if (minlvl < level)
|
||||||
|
minlvl = level;
|
||||||
|
|
||||||
|
if (!silent)
|
||||||
|
{
|
||||||
|
var suggestion = new List<string> { "Suggested:" };
|
||||||
|
if (pkm.Format >= 3)
|
||||||
|
{
|
||||||
|
var met_list = GameInfo.GetLocationList((GameVersion)pkm.Version, pkm.Format, egg: false);
|
||||||
|
var locstr = met_list.FirstOrDefault(loc => loc.Value == location).Text;
|
||||||
|
suggestion.Add($"Met Location: {locstr}");
|
||||||
|
suggestion.Add($"Met Level: {level}");
|
||||||
|
}
|
||||||
|
if (pkm.CurrentLevel < minlvl)
|
||||||
|
suggestion.Add($"Current Level: {minlvl}");
|
||||||
|
|
||||||
|
if (suggestion.Count == 1) // no suggestion
|
||||||
|
return false;
|
||||||
|
|
||||||
|
string suggest = string.Join(Environment.NewLine, suggestion);
|
||||||
|
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNo, suggest) != DialogResult.Yes)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkm.Format >= 3)
|
||||||
|
{
|
||||||
|
TB_MetLevel.Text = level.ToString();
|
||||||
|
CB_MetLocation.SelectedValue = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkm.CurrentLevel < minlvl)
|
||||||
|
TB_Level.Text = minlvl.ToString();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateIVs(object sender, EventArgs e)
|
private void UpdateIVs(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace PKHeX.Tests.PKM
|
||||||
Assert.AreEqual(PIDType.CXD, MethodFinder.Analyze(pk3)?.Type, "Unable to match PID to CXD spread");
|
Assert.AreEqual(PIDType.CXD, MethodFinder.Analyze(pk3)?.Type, "Unable to match PID to CXD spread");
|
||||||
|
|
||||||
// Channel Jirachi
|
// Channel Jirachi
|
||||||
var pkC = new PK3 {PID = 0x9E27D2F6, IVs = new[] {04, 15, 21, 14, 18, 29}};
|
var pkC = new PK3 {PID = 0x264750D9, IVs = new[] {06, 31, 14, 27, 05, 27}, SID = 45819, OT_Gender = 1, Version = (int)GameVersion.R};
|
||||||
Assert.AreEqual(PIDType.Channel, MethodFinder.Analyze(pkC)?.Type, "Unable to match PID to Channel spread");
|
Assert.AreEqual(PIDType.Channel, MethodFinder.Analyze(pkC)?.Type, "Unable to match PID to Channel spread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue