mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-23 04:23:12 +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)
|
||||
{
|
||||
case WC3 wc3 when wc3.IsEgg && pkm.Met_Level == 0:
|
||||
case WC3 wc3 when wc3.Met_Level == pkm.Met_Level:
|
||||
break;
|
||||
case WC7 wc7 when wc7.MetLevel == pkm.Met_Level:
|
||||
break;
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace PKHeX.Core
|
|||
// Special cases
|
||||
if (GetLCRNGRoamerMatch(top, bot, IVs, out pidiv))
|
||||
return pidiv;
|
||||
if (GetChannelMatch(top, bot, IVs, out pidiv))
|
||||
if (GetChannelMatch(top, bot, IVs, out pidiv, pk))
|
||||
return pidiv;
|
||||
if (GetMG4Match(pid, IVs, out pidiv))
|
||||
return pidiv;
|
||||
|
@ -200,15 +200,35 @@ namespace PKHeX.Core
|
|||
pidiv = null;
|
||||
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);
|
||||
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))
|
||||
continue;
|
||||
|
||||
if (seed >> 16 != pk.SID)
|
||||
continue;
|
||||
|
||||
pidiv = new PIDIV {OriginSeed = RNG.XDRNG.Prev(seed), RNG = RNG.XDRNG, Type = PIDType.Channel};
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
/// <summary> The RNG seed which immediately generates the PIDIV (starting with PID or IVs, whichever comes first). </summary>
|
||||
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;
|
||||
|
||||
/// <summary> Type of PIDIV correlation </summary>
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
{
|
||||
if (encounter.EggEncounter)
|
||||
return pkm.CurrentLevel == Legal.GetEggHatchLevel(pkm);
|
||||
if (encounter is MysteryGift g)
|
||||
return pkm.CurrentLevel == g.Level;
|
||||
return pkm.CurrentLevel == pkm.Met_Level;
|
||||
}
|
||||
return encounter.IsWithinRange(pkm.CurrentLevel);
|
||||
|
|
|
@ -299,11 +299,14 @@ namespace PKHeX.Core
|
|||
|
||||
// Berry Glitch Fix
|
||||
// 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 },
|
||||
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, OT_Gender = 0 },
|
||||
// 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 = "SAPHIRE", 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, 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 =
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace PKHeX.Core
|
|||
public int SID { get; set; }
|
||||
public int Met_Location { get; internal set; } = 255;
|
||||
public int Version { get; set; }
|
||||
public int Language { get; set; }
|
||||
public int Language { get; set; } = -1;
|
||||
public override int Species { get; set; }
|
||||
public override bool IsEgg { get; set; }
|
||||
public override int[] Moves { get; set; }
|
||||
|
@ -41,6 +41,19 @@ namespace PKHeX.Core
|
|||
public override int ItemID { 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)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
|
|
@ -372,7 +372,7 @@ namespace PKHeX.Core
|
|||
InvalidLines.Add("Unknown EV input.");
|
||||
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]);
|
||||
if (valid && index > -1)
|
||||
EVs[index] = EV;
|
||||
|
|
|
@ -646,51 +646,8 @@ namespace PKHeX.WinForms.Controls
|
|||
UpdateLegality(skipMoveRepop: true);
|
||||
if (Legality.Valid)
|
||||
return;
|
||||
|
||||
var encounter = Legality.GetSuggestedMetInfo();
|
||||
if (encounter == null || (pkm.Format >= 3 && encounter.Location < 0))
|
||||
{
|
||||
WinFormsUtil.Alert("Unable to provide a suggestion.");
|
||||
if (!SetSuggestedMetLocation())
|
||||
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();
|
||||
UpdateLegality();
|
||||
|
@ -733,12 +690,13 @@ namespace PKHeX.WinForms.Controls
|
|||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -751,10 +709,13 @@ namespace PKHeX.WinForms.Controls
|
|||
if (pkm.Moves.SequenceEqual(m))
|
||||
return false;
|
||||
|
||||
string r = string.Join(Environment.NewLine,
|
||||
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))
|
||||
return false;
|
||||
if (!silent)
|
||||
{
|
||||
var movestrings = m.Select(v => v >= GameInfo.Strings.movelist.Length ? "ERROR" : GameInfo.Strings.movelist[v]);
|
||||
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_Move2.SelectedValue = m[1];
|
||||
|
@ -764,6 +725,9 @@ namespace PKHeX.WinForms.Controls
|
|||
}
|
||||
private bool SetSuggestedRelearnMoves(bool silent = false)
|
||||
{
|
||||
if (pkm.Format < 6)
|
||||
return false;
|
||||
|
||||
int[] m = Legality.GetSuggestedRelearn();
|
||||
if (m.All(z => z == 0))
|
||||
if (!pkm.WasEgg && !pkm.WasEvent && !pkm.WasEventEgg && !pkm.WasLink)
|
||||
|
@ -776,10 +740,13 @@ namespace PKHeX.WinForms.Controls
|
|||
if (pkm.RelearnMoves.SequenceEqual(m))
|
||||
return false;
|
||||
|
||||
string r = string.Join(Environment.NewLine,
|
||||
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))
|
||||
return false;
|
||||
if (!silent)
|
||||
{
|
||||
var movestrings = m.Select(v => v >= GameInfo.Strings.movelist.Length ? "ERROR" : GameInfo.Strings.movelist[v]);
|
||||
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_RelearnMove2.SelectedValue = m[1];
|
||||
|
@ -787,6 +754,59 @@ namespace PKHeX.WinForms.Controls
|
|||
CB_RelearnMove4.SelectedValue = m[3];
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace PKHeX.Tests.PKM
|
|||
Assert.AreEqual(PIDType.CXD, MethodFinder.Analyze(pk3)?.Type, "Unable to match PID to CXD spread");
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue