mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-05-12 06:37:20 -05:00
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
123 lines
5.3 KiB
C#
123 lines
5.3 KiB
C#
using System.Linq;
|
|
using static PKHeX.Core.LegalityCheckStrings;
|
|
|
|
namespace PKHeX.Core
|
|
{
|
|
/// <summary>
|
|
/// Finds matching <see cref="IEncounterable"/> data and relevant <see cref="LegalInfo"/> for a <see cref="PKM"/>.
|
|
/// </summary>
|
|
public static class EncounterFinder
|
|
{
|
|
/// <summary>
|
|
/// Iterates through all possible encounters until a sufficient match is found
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The iterator lazily finds matching encounters, then verifies secondary checks to weed out any nonexact matches.
|
|
/// </remarks>
|
|
/// <param name="pkm">Source data to find a match for</param>
|
|
/// <returns>
|
|
/// Information containing the matched encounter and any parsed checks.
|
|
/// If no clean match is found, the last checked match is returned.
|
|
/// If no match is found, an invalid encounter object is returned.
|
|
/// </returns>
|
|
public static LegalInfo FindVerifiedEncounter(PKM pkm)
|
|
{
|
|
var info = new LegalInfo(pkm);
|
|
var encounters = EncounterGenerator.GetEncounters(pkm, info);
|
|
|
|
using var encounter = new PeekEnumerator<IEncounterable>(encounters);
|
|
if (!encounter.PeekIsNext())
|
|
return VerifyWithoutEncounter(pkm, info);
|
|
|
|
var EncounterValidator = EncounterVerifier.GetEncounterVerifierMethod(pkm);
|
|
while (encounter.MoveNext())
|
|
{
|
|
info.EncounterMatch = encounter.Current;
|
|
var e = EncounterValidator(pkm, info);
|
|
if (!e.Valid && encounter.PeekIsNext())
|
|
{
|
|
info.Reject(e);
|
|
continue;
|
|
}
|
|
info.Parse.Add(e);
|
|
|
|
if (VerifySecondaryChecks(pkm, info, encounter))
|
|
break; // passes
|
|
}
|
|
|
|
if (!info.FrameMatches && info.EncounterMatch is EncounterSlot && pkm.Version != (int)GameVersion.CXD) // if false, all valid RNG frame matches have already been consumed
|
|
info.Parse.Add(new CheckResult(ParseSettings.RNGFrameNotFound, LEncConditionBadRNGFrame, CheckIdentifier.PID)); // todo for further confirmation
|
|
if (!info.PIDIVMatches) // if false, all valid PIDIV matches have already been consumed
|
|
info.Parse.Add(new CheckResult(Severity.Invalid, LPIDTypeMismatch, CheckIdentifier.PID));
|
|
|
|
return info;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks supplementary info to see if the encounter is still valid.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// When an encounter is initially validated, only encounter-related checks are performed.
|
|
/// By checking Moves, Evolution, and <see cref="PIDIV"/> data, a best match encounter can be found.
|
|
/// If the encounter is not valid, the method will not reject it unless another encounter is available to check.
|
|
/// </remarks>
|
|
/// <param name="pkm">Source data to check the match for</param>
|
|
/// <param name="info">Information containing the matched encounter</param>
|
|
/// <param name="iterator">Peekable iterator </param>
|
|
/// <returns>Indication whether or not the encounter passes secondary checks</returns>
|
|
private static bool VerifySecondaryChecks(PKM pkm, LegalInfo info, PeekEnumerator<IEncounterable> iterator)
|
|
{
|
|
if (pkm.Format >= 6)
|
|
{
|
|
info.Relearn = VerifyRelearnMoves.VerifyRelearn(pkm, info);
|
|
if (info.Relearn.Any(z => !z.Valid) && iterator.PeekIsNext())
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < 4; i++)
|
|
info.Relearn[i] = new CheckResult(CheckIdentifier.RelearnMove);
|
|
}
|
|
|
|
info.Moves = VerifyCurrentMoves.VerifyMoves(pkm, info);
|
|
if (info.Moves.Any(z => !z.Valid) && iterator.PeekIsNext())
|
|
return false;
|
|
|
|
var evo = EvolutionVerifier.VerifyEvolution(pkm, info);
|
|
if (!evo.Valid && iterator.PeekIsNext())
|
|
return false;
|
|
info.Parse.Add(evo);
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns legality info for an unmatched encounter scenario, including a hint as to what the actual match could be.
|
|
/// </summary>
|
|
/// <param name="pkm">Source data to check the match for</param>
|
|
/// <param name="info">Information containing the unmatched encounter</param>
|
|
/// <returns>Updated information pertaining to the unmatched encounter</returns>
|
|
private static LegalInfo VerifyWithoutEncounter(PKM pkm, LegalInfo info)
|
|
{
|
|
info.EncounterMatch = new EncounterInvalid(pkm);
|
|
string hint = GetHintWhyNotFound(pkm);
|
|
|
|
info.Parse.Add(new CheckResult(Severity.Invalid, hint, CheckIdentifier.Encounter));
|
|
info.Relearn = VerifyRelearnMoves.VerifyRelearn(pkm, info);
|
|
info.Moves = VerifyCurrentMoves.VerifyMoves(pkm, info);
|
|
return info;
|
|
}
|
|
|
|
private static string GetHintWhyNotFound(PKM pkm)
|
|
{
|
|
if (pkm.WasGiftEgg)
|
|
return LEncGift;
|
|
if (pkm.WasEventEgg)
|
|
return LEncGiftEggEvent;
|
|
if (pkm.WasEvent)
|
|
return LEncGiftNotFound;
|
|
return LEncInvalid;
|
|
}
|
|
}
|
|
}
|