mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-09-09 10:17:54 -05:00
Misc updates
Add global link mission stats (thanks Holla!) remove some ToArray() linq in favor of direct copies Relocate encounter suggestion logic to separate class Closes #1396, addresses other edge cases like entree-non HA & happiny egg.
This commit is contained in:
@@ -20,8 +20,8 @@ public partial class LegalityAnalysis
|
||||
private string EncounterName => $"{(EncounterOriginalGB ?? EncounterMatch).GetEncounterTypeName()} ({SpeciesStrings[EncounterMatch.Species]})";
|
||||
private CheckResult Encounter, History;
|
||||
|
||||
public bool Parsed { get; }
|
||||
public bool Valid { get; }
|
||||
public readonly bool Parsed;
|
||||
public readonly bool Valid;
|
||||
public LegalInfo Info { get; private set; }
|
||||
public bool ParsedValid => Parsed && Valid;
|
||||
public bool ParsedInvalid => Parsed && !Valid;
|
||||
@@ -360,6 +360,7 @@ private string GetVerboseLegalityReport()
|
||||
return GetLegalityReport() + string.Join(Environment.NewLine, lines);
|
||||
}
|
||||
|
||||
// Suggestions
|
||||
public int[] GetSuggestedRelearn()
|
||||
{
|
||||
if (Info.RelearnBase == null || pkm.GenNumber < 6 || !pkm.IsOriginValid)
|
||||
@@ -369,12 +370,13 @@ public int[] GetSuggestedRelearn()
|
||||
return Info.RelearnBase;
|
||||
|
||||
List<int> window = new List<int>(Info.RelearnBase);
|
||||
var vMoves = Info.Moves;
|
||||
window.AddRange(pkm.Moves.Where((v, i) => !vMoves[i].Valid || vMoves[i].Flag));
|
||||
window.AddRange(pkm.Moves.Where((v, i) => !Info.Moves[i].Valid || Info.Moves[i].Flag));
|
||||
window = window.Distinct().ToList();
|
||||
if (window.Count < 4)
|
||||
window.AddRange(new int[4 - window.Count]);
|
||||
return window.Skip(window.Count - 4).ToArray();
|
||||
int[] moves = new int[4];
|
||||
int start = Math.Max(0, window.Count - 4);
|
||||
int count = Math.Min(4, window.Count);
|
||||
window.CopyTo(start, moves, 0, count);
|
||||
return moves;
|
||||
}
|
||||
public int[] GetSuggestedMoves(bool tm, bool tutor, bool reminder)
|
||||
{
|
||||
@@ -384,102 +386,6 @@ public int[] GetSuggestedMoves(bool tm, bool tutor, bool reminder)
|
||||
return new int[4];
|
||||
return Legal.GetValidMoves(pkm, Info.EvoChainsAllGens, Tutor: tutor, Machine: tm, MoveReminder: reminder).Skip(1).ToArray(); // skip move 0
|
||||
}
|
||||
|
||||
public EncounterStatic GetSuggestedMetInfo()
|
||||
{
|
||||
if (pkm == null)
|
||||
return null;
|
||||
|
||||
int loc = GetSuggestedTransferLocation(pkm);
|
||||
if (pkm.WasEgg)
|
||||
{
|
||||
int lvl = 1; // gen5+
|
||||
if (!pkm.IsNative)
|
||||
lvl = pkm.CurrentLevel; // be generous with transfer conditions
|
||||
else if (pkm.Format < 5) // and native
|
||||
lvl = 0;
|
||||
return new EncounterStatic
|
||||
{
|
||||
Species = Legal.GetBaseSpecies(pkm),
|
||||
Location = loc != -1 ? loc : GetSuggestedEggMetLocation(pkm),
|
||||
Level = lvl,
|
||||
};
|
||||
}
|
||||
|
||||
var area = EncounterGenerator.GetCaptureLocation(pkm);
|
||||
if (area != null)
|
||||
{
|
||||
var slots = area.Slots.OrderBy(s => s.LevelMin);
|
||||
return new EncounterStatic
|
||||
{
|
||||
Species = slots.First().Species,
|
||||
Location = loc != -1 ? loc : area.Location,
|
||||
Level = slots.First().LevelMin,
|
||||
};
|
||||
}
|
||||
|
||||
var encounter = EncounterGenerator.GetStaticLocation(pkm);
|
||||
if (loc != -1 && encounter != null)
|
||||
encounter.Location = loc;
|
||||
return encounter;
|
||||
}
|
||||
private static int GetSuggestedEggMetLocation(PKM pkm)
|
||||
{
|
||||
// Return one of legal hatch locations for game
|
||||
switch ((GameVersion)pkm.Version)
|
||||
{
|
||||
case GameVersion.R:
|
||||
case GameVersion.S:
|
||||
case GameVersion.E:
|
||||
case GameVersion.FR:
|
||||
case GameVersion.LG:
|
||||
switch (pkm.Format)
|
||||
{
|
||||
case 3:
|
||||
return pkm.FRLG ? 146 /* Four Island */ : 32; // Route 117
|
||||
case 4:
|
||||
return 0x37; // Pal Park
|
||||
default:
|
||||
return 30001; // Transporter
|
||||
}
|
||||
|
||||
case GameVersion.D:
|
||||
case GameVersion.P:
|
||||
case GameVersion.Pt:
|
||||
return pkm.Format > 4 ? 30001 /* Transporter */ : 4; // Solaceon Town
|
||||
case GameVersion.HG:
|
||||
case GameVersion.SS:
|
||||
return pkm.Format > 4 ? 30001 /* Transporter */ : 182; // Route 34
|
||||
|
||||
case GameVersion.B:
|
||||
case GameVersion.W:
|
||||
return 16; // Route 3
|
||||
|
||||
case GameVersion.X:
|
||||
case GameVersion.Y:
|
||||
return 38; // Route 7
|
||||
case GameVersion.AS:
|
||||
case GameVersion.OR:
|
||||
return 318; // Battle Resort
|
||||
|
||||
case GameVersion.SN:
|
||||
case GameVersion.MN:
|
||||
return 50; // Route 4
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
private static int GetSuggestedTransferLocation(PKM pkm)
|
||||
{
|
||||
// Return one of legal hatch locations for game
|
||||
if (pkm.HasOriginalMetLocation)
|
||||
return -1;
|
||||
if (pkm.VC1)
|
||||
return 30013;
|
||||
if (pkm.Format == 4) // Pal Park
|
||||
return 0x37;
|
||||
if (pkm.Format == 5) // Transporter
|
||||
return 30001;
|
||||
return -1;
|
||||
}
|
||||
public EncounterStatic GetSuggestedMetInfo() => EncounterSuggestion.GetSuggestedMetInfo(pkm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,13 +85,22 @@ private void VerifyECPID()
|
||||
case EncounterStatic s:
|
||||
if (s.Shiny != null && (bool)s.Shiny ^ pkm.IsShiny)
|
||||
AddLine(Severity.Invalid, V209, CheckIdentifier.Shiny);
|
||||
if (pkm.GenNumber == 5 && !s.Gift && !s.Roaming && s.Ability != 4)
|
||||
VerifyG5PID_IDCorrelation();
|
||||
|
||||
// gen5 correlation
|
||||
if (pkm.GenNumber != 5)
|
||||
break;
|
||||
if (s.Location == 75) // Entree Forest
|
||||
break;
|
||||
if (s.Gift || s.Roaming || s.Ability != 4)
|
||||
break;
|
||||
if (s.NSparkle)
|
||||
break;
|
||||
VerifyG5PID_IDCorrelation();
|
||||
break;
|
||||
case EncounterSlot w:
|
||||
if (pkm.IsShiny && w.Type == SlotType.HiddenGrotto)
|
||||
AddLine(Severity.Invalid, V221, CheckIdentifier.Shiny);
|
||||
if (pkm.GenNumber == 5 && pkm.AbilityNumber != 4)
|
||||
if (pkm.GenNumber == 5 && w.Type != SlotType.HiddenGrotto)
|
||||
VerifyG5PID_IDCorrelation();
|
||||
break;
|
||||
case PCD d: // fixed PID
|
||||
|
||||
@@ -354,7 +354,10 @@ private static IEnumerable<EncounterStatic> GetMatchingStaticEncounters(PKM pkm,
|
||||
if (e.Nature != Nature.Random && pkm.Nature != (int)e.Nature)
|
||||
continue;
|
||||
if (pkm.WasEgg ^ e.EggEncounter && pkm.Egg_Location == 0 && pkm.Format > 3)
|
||||
continue;
|
||||
{
|
||||
if (!pkm.IsEgg)
|
||||
continue;
|
||||
}
|
||||
if (pkm.Gen3 && e.EggLocation != 0) // Gen3 Egg
|
||||
{
|
||||
if (pkm.Format == 3 && pkm.IsEgg && e.EggLocation != pkm.Met_Location)
|
||||
|
||||
133
PKHeX.Core/Legality/Encounters/EncounterSuggestion.cs
Normal file
133
PKHeX.Core/Legality/Encounters/EncounterSuggestion.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
internal static class EncounterSuggestion
|
||||
{
|
||||
public static EncounterStatic GetSuggestedMetInfo(PKM pkm)
|
||||
{
|
||||
if (pkm == null)
|
||||
return null;
|
||||
|
||||
int loc = GetSuggestedTransferLocation(pkm);
|
||||
|
||||
if (pkm.WasEgg)
|
||||
return GetSuggestedEncounterEgg(pkm, loc);
|
||||
|
||||
var w = EncounterGenerator.GetCaptureLocation(pkm);
|
||||
if (w != null)
|
||||
return GetSuggestedEncounterWild(w, loc);
|
||||
|
||||
var s = EncounterGenerator.GetStaticLocation(pkm);
|
||||
if (s != null)
|
||||
return GetSuggestedEncounterStatic(s, loc);
|
||||
|
||||
return null;
|
||||
}
|
||||
private static EncounterStatic GetSuggestedEncounterEgg(PKM pkm, int loc)
|
||||
{
|
||||
int lvl = 1; // gen5+
|
||||
if (!pkm.IsNative)
|
||||
lvl = pkm.CurrentLevel; // be generous with transfer conditions
|
||||
else if (pkm.Format < 5) // and native
|
||||
lvl = 0;
|
||||
return new EncounterStatic
|
||||
{
|
||||
Species = Legal.GetBaseSpecies(pkm),
|
||||
Location = loc != -1 ? loc : GetSuggestedEggMetLocation(pkm),
|
||||
Level = lvl,
|
||||
};
|
||||
}
|
||||
private static EncounterStatic GetSuggestedEncounterWild(EncounterArea area, int loc)
|
||||
{
|
||||
var slots = area.Slots.OrderBy(s => s.LevelMin);
|
||||
var first = slots.First();
|
||||
var encounter = new EncounterStatic
|
||||
{
|
||||
Species = first.Species,
|
||||
Location = first.Location,
|
||||
Level = first.LevelMin,
|
||||
};
|
||||
if (loc != -1) // forced location
|
||||
encounter.Location = loc;
|
||||
return encounter;
|
||||
}
|
||||
private static EncounterStatic GetSuggestedEncounterStatic(EncounterStatic s, int loc)
|
||||
{
|
||||
if (loc == -1)
|
||||
loc = s.Location;
|
||||
|
||||
// don't leak out the original EncounterStatic object
|
||||
var encounter = s.Clone(loc);
|
||||
return encounter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a valid Egg hatch location for the origin game.
|
||||
/// </summary>
|
||||
private static int GetSuggestedEggMetLocation(PKM pkm)
|
||||
{
|
||||
// Return one of legal hatch locations for game
|
||||
switch ((GameVersion)pkm.Version)
|
||||
{
|
||||
case GameVersion.R:
|
||||
case GameVersion.S:
|
||||
case GameVersion.E:
|
||||
case GameVersion.FR:
|
||||
case GameVersion.LG:
|
||||
switch (pkm.Format)
|
||||
{
|
||||
case 3:
|
||||
return pkm.FRLG ? 146 /* Four Island */ : 32; // Route 117
|
||||
case 4:
|
||||
return 0x37; // Pal Park
|
||||
default:
|
||||
return 30001; // Transporter
|
||||
}
|
||||
|
||||
case GameVersion.D:
|
||||
case GameVersion.P:
|
||||
case GameVersion.Pt:
|
||||
return pkm.Format > 4 ? 30001 /* Transporter */ : 4; // Solaceon Town
|
||||
case GameVersion.HG:
|
||||
case GameVersion.SS:
|
||||
return pkm.Format > 4 ? 30001 /* Transporter */ : 182; // Route 34
|
||||
|
||||
case GameVersion.B:
|
||||
case GameVersion.W:
|
||||
return 16; // Route 3
|
||||
|
||||
case GameVersion.X:
|
||||
case GameVersion.Y:
|
||||
return 38; // Route 7
|
||||
case GameVersion.AS:
|
||||
case GameVersion.OR:
|
||||
return 318; // Battle Resort
|
||||
|
||||
case GameVersion.SN:
|
||||
case GameVersion.MN:
|
||||
return 50; // Route 4
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the correct Met location for the origin game.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Returns -1 if the met location is not overriden with a transfer location
|
||||
/// </remarks>
|
||||
private static int GetSuggestedTransferLocation(PKM pkm)
|
||||
{
|
||||
// Return one of legal hatch locations for game
|
||||
if (pkm.HasOriginalMetLocation)
|
||||
return -1;
|
||||
if (pkm.VC1)
|
||||
return 30013;
|
||||
if (pkm.Format == 4) // Pal Park
|
||||
return 0x37;
|
||||
if (pkm.Format == 5) // Transporter
|
||||
return 30001;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,11 @@ public WC6(byte[] data = null)
|
||||
Data = (byte[])(data?.Clone() ?? new byte[Size]);
|
||||
if (Data.Length == SizeFull)
|
||||
{
|
||||
if (Data[0x205] == 0)
|
||||
Data = new byte[Data.Length]; // Invalidate
|
||||
Data = Data.Skip(SizeFull - Size).ToArray();
|
||||
byte[] wc6 = new byte[Size];
|
||||
if (Data[0x205] != 0) // Valid data
|
||||
Array.Copy(Data, SizeFull - Size, wc6, 0, wc6.Length);
|
||||
Data = wc6;
|
||||
|
||||
DateTime now = DateTime.Now;
|
||||
Year = (uint)now.Year;
|
||||
Month = (uint)now.Month;
|
||||
|
||||
@@ -15,7 +15,9 @@ public WC7(byte[] data = null)
|
||||
Data = (byte[])(data?.Clone() ?? new byte[Size]);
|
||||
if (Data.Length == SizeFull)
|
||||
{
|
||||
Data = Data.Skip(SizeFull - Size).ToArray();
|
||||
byte[] wc6 = new byte[Size];
|
||||
Array.Copy(Data, SizeFull - Size, wc6, 0, wc6.Length);
|
||||
Data = wc6;
|
||||
DateTime now = DateTime.Now;
|
||||
Year = (uint)now.Year;
|
||||
Month = (uint)now.Month;
|
||||
|
||||
@@ -656,6 +656,19 @@ private void B_GenTID_Click(object sender, EventArgs e)
|
||||
{172, "Berry Tree Battles won"},
|
||||
{173, "Bubbling Spot Encounters/Items"},
|
||||
{174, "Times laid down in Own Bed"},
|
||||
|
||||
{175, "Trade Pokémon at the GTS!"},
|
||||
{176, "176 - Global Mission"},
|
||||
{177, "Hatch a lot of Eggs!"},
|
||||
{178, "Harvest Poké Beans!"},
|
||||
{179, "179 - Global Mission"},
|
||||
{180, "Find Pokémon using Island Scan!"},
|
||||
{181, "181 - Global Mission"},
|
||||
{182, "Defend your Champion title!"},
|
||||
{183, "Fish Pokémon at rare spots!"},
|
||||
{185, "Try your luck!"},
|
||||
{186, "186 - Global Mission"},
|
||||
{187, "Catch a lot of Pokémon!"},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user