PKHeX/PKHeX.Core/Editing/Applicators/CatchRateApplicator.cs
Kurt f632aedd15
Encounter Templates: Searching and Creating (#3955)
We implement simple state machine iterators to iterate through every split type encounter array, and more finely control the path we iterate through. And, by using generics, we can have the compiler generate optimized code to avoid virtual calls.

In addition to this, we shift away from the big-5 encounter types and not inherit from an abstract class. This allows for creating a PK* of a specific type and directly writing properties (no virtual calls). Plus we can now fine-tune each encounter type to call specific code, and not have to worry about future game encounter types bothering the generation routines.
2023-08-12 16:01:16 -07:00

52 lines
1.8 KiB
C#

namespace PKHeX.Core;
/// <summary>
/// Logic for applying a <see cref="PK1.Catch_Rate"/> value.
/// </summary>
public static class CatchRateApplicator
{
/// <summary>
/// Gets the suggested <see cref="PK1.Catch_Rate"/> for the entity.
/// </summary>
public static int GetSuggestedCatchRate(PK1 pk, SaveFile sav)
{
var la = new LegalityAnalysis(pk);
return GetSuggestedCatchRate(pk, sav, la);
}
/// <summary>
/// Gets the suggested <see cref="PK1.Catch_Rate"/> for the entity.
/// </summary>
public static byte GetSuggestedCatchRate(PK1 pk, SaveFile sav, LegalityAnalysis la)
{
// If it is already valid, just use the current value.
if (la.Valid)
return pk.Catch_Rate;
// If it has ever visited generation 2, the Held Item can be removed prior to trade back.
if (la.Info.Generation == 2)
return 0;
// Return the encounter's original value.
var enc = la.EncounterMatch;
switch (enc)
{
case EncounterGift1 { Version: GameVersion.Stadium, Species: (int)Species.Psyduck }:
return pk.Japanese ? (byte)167 : (byte)168; // Amnesia Psyduck has different catch rates depending on language
default:
var pt = GetPersonalTable(sav, enc);
var pi = pt[enc.Species];
return (byte)pi.CatchRate;
}
}
private static PersonalTable1 GetPersonalTable(SaveFile sav, IEncounterable v)
{
if (sav.Personal is PersonalTable1 pt && (sav.Version.Contains(v.Version) || v.Version.Contains(sav.Version)))
return pt;
if (!GameVersion.RB.Contains(v.Version))
return PersonalTable.Y;
return PersonalTable.RB;
}
}