mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-10-02 05:28:34 -05:00
Minor clean
This commit is contained in:
@@ -3,23 +3,57 @@
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Logic for checking shiny state.
|
||||
/// </summary>
|
||||
public static class ShinyUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// Computes a shiny PID from the provided values.
|
||||
/// </summary>
|
||||
/// <param name="tid">Trainer ID.</param>
|
||||
/// <param name="sid">Trainer Secret ID.</param>
|
||||
/// <param name="pid">Entity PID.</param>
|
||||
/// <param name="type">Shiny XOR type.</param>
|
||||
/// <returns>Shiny PID.</returns>
|
||||
public static uint GetShinyPID(in ushort tid, in ushort sid, in uint pid, in uint type)
|
||||
{
|
||||
var low = pid & 0xFFFF;
|
||||
return ((type ^ tid ^ sid ^ low) << 16) | low;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the PID is shiny.
|
||||
/// </summary>
|
||||
/// <param name="id32">Combined Trainer ID and Secret ID.</param>
|
||||
/// <param name="pid">Entity PID.</param>
|
||||
/// <param name="cmp">Comparison threshold.</param>
|
||||
/// <returns>True if shiny, false otherwise.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool GetIsShiny(in uint id32, in uint pid, [ConstantExpected(Max = 16, Min = 8)] uint cmp = 16) => GetShinyXor(id32, pid) < cmp;
|
||||
|
||||
public static uint GetShinyXor(in uint pid, in uint id32)
|
||||
{
|
||||
var xor = pid ^ id32;
|
||||
return (xor ^ (xor >> 16)) & 0xFFFF;
|
||||
}
|
||||
/// <summary>
|
||||
/// Computes the shiny XOR value.
|
||||
/// </summary>
|
||||
/// <param name="pid">Entity PID.</param>
|
||||
/// <param name="id32">Combined Trainer ID and Secret ID.</param>
|
||||
/// <returns>Shiny XOR value.</returns>
|
||||
public static uint GetShinyXor(in uint pid, in uint id32) => GetShinyXor(pid ^ id32);
|
||||
|
||||
/// <summary>
|
||||
/// Computes the shiny XOR value.
|
||||
/// </summary>
|
||||
/// <param name="component">Combined/raw value to compute with.</param>
|
||||
/// <returns>Shiny XOR value.</returns>
|
||||
public static uint GetShinyXor(in uint component) => (component ^ (component >> 16)) & 0xFFFF;
|
||||
|
||||
/// <summary>
|
||||
/// Forces the shiny state of the PID.
|
||||
/// </summary>
|
||||
/// <param name="isShiny">Indicates if the PID should be shiny.</param>
|
||||
/// <param name="pid">Entity PID.</param>
|
||||
/// <param name="id32">Combined Trainer ID and Secret ID.</param>
|
||||
/// <param name="xorType">Shiny XOR type.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void ForceShinyState(bool isShiny, ref uint pid, uint id32, in uint xorType)
|
||||
{
|
||||
@@ -35,5 +69,11 @@ public static void ForceShinyState(bool isShiny, ref uint pid, uint id32, in uin
|
||||
}
|
||||
}
|
||||
|
||||
public static bool GetIsShinyGB(ushort dv16) => ((dv16 & 0xFFF) == 0xAAA) && (((dv16 >> 12) & 2) != 0);
|
||||
/// <summary>
|
||||
/// Checks if the PID is shiny.
|
||||
/// </summary>
|
||||
/// <remarks>Used for Gen 2.</remarks>
|
||||
/// <param name="dv16">16-bit DVs.</param>
|
||||
/// <returns>True if shiny, false otherwise.</returns>
|
||||
public static bool GetIsShinyGB(ushort dv16) => (dv16 & 0x2FFF) == 0x2AAA;
|
||||
}
|
||||
|
||||
@@ -79,6 +79,9 @@ internal static class GBRestrictions
|
||||
_ => false,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the species will always evolve if traded to a Generation 1 player.
|
||||
/// </summary>
|
||||
internal static bool IsTradeEvolution1(ushort species) => species is (int)Kadabra or (int)Machoke or (int)Graveler or (int)Haunter;
|
||||
|
||||
public static bool RateMatchesEncounter(ushort species, GameVersion version, byte rate)
|
||||
@@ -121,7 +124,7 @@ private static bool GetCatchRateMatchesPreEvolution(PK1 pk, byte rate)
|
||||
/// </summary>
|
||||
/// <param name="pk">Data to check</param>
|
||||
/// <returns>true if it can inhabit, false if it can not.</returns>
|
||||
internal static bool CanInhabitGen1(this PKM pk)
|
||||
private static bool CanOriginateGen1(this PKM pk)
|
||||
{
|
||||
// Korean Gen2 games can't trade-back because there are no Gen1 Korean games released
|
||||
if (pk.Korean || pk.IsEgg)
|
||||
@@ -131,14 +134,17 @@ internal static bool CanInhabitGen1(this PKM pk)
|
||||
// If you put a Pokémon in the N64 box, the met info is retained, even if you switch over to a Gen1 game to teach it TMs
|
||||
// You can use rare candies from within the lab, so level-up moves from RBY context can be learned this way as well
|
||||
// Stadium 2 is GB Cart Era only (not 3DS Virtual Console).
|
||||
if (pk is ICaughtData2 {CaughtData: not 0} && !ParseSettings.AllowGBStadium2)
|
||||
// This method is only called for Encounter enumeration; if it has Gen2 data, it is not a Gen1 encounter.
|
||||
if (pk is ICaughtData2 {CaughtData: not 0})
|
||||
return false;
|
||||
|
||||
// Sanity check species, if it could have existed as a pre-evolution.
|
||||
ushort species = pk.Species;
|
||||
if (species <= MaxSpeciesID_1)
|
||||
return true;
|
||||
return IsEvolvedFromGen1Species(species);
|
||||
return CanVisitGen1(pk.Species);
|
||||
}
|
||||
|
||||
internal static bool CanVisitGen1(ushort species)
|
||||
{
|
||||
return species <= MaxSpeciesID_1 || IsEvolvedFromGen1Species(species);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -151,7 +157,7 @@ internal static PotentialGBOrigin GetTradebackStatusInitial(PKM pk)
|
||||
return GetTradebackStatusRBY(pk1);
|
||||
|
||||
if (pk.Format == 2 || pk.VC2) // Check for impossible Tradeback scenarios
|
||||
return !pk.CanInhabitGen1() ? Gen2Only : Either;
|
||||
return !pk.CanOriginateGen1() ? Gen2Only : Either;
|
||||
|
||||
// VC2 is released, we can assume it will be TradebackType.Any.
|
||||
// Is impossible to differentiate a VC1 Pokémon traded to Gen7 after VC2 is available.
|
||||
@@ -183,50 +189,26 @@ private static PotentialGBOrigin GetTradebackStatusRBY(PK1 pk)
|
||||
return Gen1Only;
|
||||
}
|
||||
|
||||
public static TimeCapsuleEvaluation IsTimeCapsuleTransferred(PKM pk, ReadOnlySpan<MoveResult> moves, IEncounterTemplate enc)
|
||||
public static TimeCapsuleEvaluation IsTimeCapsuleTransferred(PK1 pk, ReadOnlySpan<MoveResult> moves, IEncounterTemplate enc)
|
||||
{
|
||||
foreach (var z in moves)
|
||||
if (enc.Generation == 2)
|
||||
return Transferred21;
|
||||
|
||||
var rate = pk.CatchRate;
|
||||
if (rate == 0)
|
||||
return Transferred12;
|
||||
|
||||
if (MoveInfo.IsAnyFromGeneration(2, moves))
|
||||
{
|
||||
if (z.Generation == enc.Generation || z.Generation is not (1 or 2))
|
||||
continue;
|
||||
if (pk is PK1 {CatchRate: not 0} g1 && !IsTradebackCatchRate(g1.CatchRate))
|
||||
if (pk is {CatchRate: not 0} && !IsTradebackCatchRate(pk.CatchRate))
|
||||
return BadCatchRate;
|
||||
return enc.Generation == 2 ? Transferred21 : Transferred12;
|
||||
return Transferred12;
|
||||
}
|
||||
|
||||
if (pk is not GBPKM gb)
|
||||
{
|
||||
return enc.Generation switch
|
||||
{
|
||||
1 when pk.VC2 => Transferred12,
|
||||
2 when pk.VC1 => Transferred21,
|
||||
_ => NotTransferred,
|
||||
};
|
||||
}
|
||||
|
||||
if (gb is ICaughtData2 pk2)
|
||||
{
|
||||
if (enc.Generation == 1)
|
||||
return Transferred12;
|
||||
if (pk2.CaughtData != 0)
|
||||
return NotTransferred;
|
||||
if (enc.Version == C)
|
||||
return Transferred21;
|
||||
return Indeterminate;
|
||||
}
|
||||
|
||||
if (gb is PK1 pk1)
|
||||
{
|
||||
var rate = pk1.CatchRate;
|
||||
if (rate == 0)
|
||||
return Transferred12;
|
||||
|
||||
bool isTradebackItem = IsTradebackCatchRate(rate);
|
||||
if (IsCatchRateMatchEncounter(enc, pk1))
|
||||
return isTradebackItem ? Indeterminate : NotTransferred;
|
||||
return isTradebackItem ? Transferred12 : BadCatchRate;
|
||||
}
|
||||
return Indeterminate;
|
||||
bool isTradebackItem = IsTradebackCatchRate(rate);
|
||||
if (IsCatchRateMatchEncounter(enc, pk))
|
||||
return isTradebackItem ? Indeterminate : NotTransferred;
|
||||
return isTradebackItem ? Transferred12 : BadCatchRate;
|
||||
}
|
||||
|
||||
private static bool IsCatchRateMatchEncounter(IEncounterTemplate enc, PK1 pk1) => enc switch
|
||||
@@ -291,14 +273,3 @@ public enum TimeCapsuleEvaluation
|
||||
/// </summary>
|
||||
BadCatchRate,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="TimeCapsuleEvaluation"/>.
|
||||
/// </summary>
|
||||
public static class TimeCapsuleEvlautationExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates if the <see cref="eval"/> definitely transferred via Time Capsule.
|
||||
/// </summary>
|
||||
public static bool WasTimeCapsuleTransferred(this TimeCapsuleEvaluation eval) => eval is not (Indeterminate or NotTransferred or BadCatchRate);
|
||||
}
|
||||
|
||||
@@ -42,16 +42,12 @@ public SimpleTrainerInfo(ITrainerInfo other, GameVersion specified) : this(speci
|
||||
Language = other.Language;
|
||||
Generation = other.Generation;
|
||||
Context = other.Context;
|
||||
|
||||
if (Context is not (EntityContext.Gen6 or EntityContext.Gen7))
|
||||
{
|
||||
ConsoleRegion = Region = Country = 0;
|
||||
}
|
||||
else if (other is IRegionOriginReadOnly r)
|
||||
{
|
||||
ConsoleRegion = r.ConsoleRegion;
|
||||
Region = r.Region;
|
||||
Country = r.Country;
|
||||
}
|
||||
return;
|
||||
|
||||
var geo = other.GetRegionOrigin(other.Language);
|
||||
ConsoleRegion = geo.ConsoleRegion;
|
||||
Region = geo.Region;
|
||||
Country = geo.Country;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user