Xmldoc, minor tweaks

Move form-info logic from FormConverter to AltFormInfo; now FormConverter is entirely form=>string[]
Add a bunch of xmldoc
Make pogo no-end-date cmp agaisnt UTCnow rather than local now.
This commit is contained in:
Kurt 2020-11-27 11:51:02 -08:00
parent a437cbb9ca
commit 9b178fefe2
56 changed files with 329 additions and 159 deletions

View file

@ -281,24 +281,4 @@ namespace PKHeX.Core
NotWeather = Shaking_Trees | Fishing, NotWeather = Shaking_Trees | Fishing,
} }
/// <summary>
/// Encounter Slot found in <see cref="GameVersion.SWSH"/>
/// </summary>
public sealed class EncounterSlot8 : EncounterSlot
{
public readonly AreaWeather8 Weather;
public override string LongName => Weather == AreaWeather8.All ? wild : $"{wild} - {Weather.ToString().Replace("_", string.Empty)}";
public override int Generation => 8;
public EncounterSlot8(EncounterArea8 area, int specForm, int min, int max, AreaWeather8 weather) : base(area)
{
Species = specForm & 0x7FF;
Form = specForm >> 11;
LevelMin = min;
LevelMax = max;
Weather = weather;
}
}
} }

View file

@ -5,6 +5,7 @@ namespace PKHeX.Core
/// <summary> /// <summary>
/// Wild Encounter Slot data /// Wild Encounter Slot data
/// </summary> /// </summary>
/// <remarks>Wild encounter slots are found as random encounters in-game.</remarks>
public abstract class EncounterSlot : IEncounterable, ILocation public abstract class EncounterSlot : IEncounterable, ILocation
{ {
public int Species { get; protected set; } public int Species { get; protected set; }
@ -160,15 +161,19 @@ namespace PKHeX.Core
pk.MetDate = DateTime.Today; pk.MetDate = DateTime.Today;
} }
private const int FormDynamic = FormVivillon;
private const int FormVivillon = 30;
private const int FormRandom = 31;
private static int GetWildAltForm(PKM pk, int form, ITrainerInfo sav) private static int GetWildAltForm(PKM pk, int form, ITrainerInfo sav)
{ {
if (form < 30) // specified form if (form < FormDynamic) // specified form
{ {
if (pk.Species == (int) Core.Species.Minior) if (pk.Species == (int) Core.Species.Minior)
return Util.Rand.Next(7, 14); return Util.Rand.Next(7, 14);
return form; return form;
} }
if (form == 31) // flagged as totally random if (form == FormRandom) // flagged as totally random
return Util.Rand.Next(pk.PersonalInfo.FormeCount); return Util.Rand.Next(pk.PersonalInfo.FormeCount);
int spec = pk.Species; int spec = pk.Species;

View file

@ -1,12 +1,13 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary> /// <summary>
/// Generation 1 Wild Encounter Slot data /// Encounter Slot found in <see cref="GameVersion.Gen1"/>.
/// </summary> /// </summary>
/// <inheritdoc cref="EncounterSlot"/>
public sealed class EncounterSlot1 : EncounterSlot, INumberedSlot public sealed class EncounterSlot1 : EncounterSlot, INumberedSlot
{ {
public override int Generation => 1; public override int Generation => 1;
public int SlotNumber { get; set; } public int SlotNumber { get; }
public EncounterSlot1(EncounterArea1 area, int species, int min, int max, int slot) : base(area) public EncounterSlot1(EncounterArea1 area, int species, int min, int max, int slot) : base(area)
{ {
@ -23,6 +24,7 @@
var pk1 = (PK1)pk; var pk1 = (PK1)pk;
if (Version == GameVersion.YW) if (Version == GameVersion.YW)
{ {
// Since we don't keep track of Yellow's Personal Data, just handle any differences here.
pk1.Catch_Rate = Species switch pk1.Catch_Rate = Species switch
{ {
(int) Core.Species.Kadabra => 96, (int) Core.Species.Kadabra => 96,

View file

@ -1,15 +1,16 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary> /// <summary>
/// Generation 2 Wild Encounter Slot data /// Encounter Slot found in <see cref="GameVersion.Gen2"/>.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// Contains Time data which is present in <see cref="GameVersion.C"/> origin data. /// Referenced Area object contains Time data which is used for <see cref="GameVersion.C"/> origin data.
/// </remarks> /// </remarks>
/// <inheritdoc cref="EncounterSlot"/>
public sealed class EncounterSlot2 : EncounterSlot, INumberedSlot public sealed class EncounterSlot2 : EncounterSlot, INumberedSlot
{ {
public override int Generation => 2; public override int Generation => 2;
public int SlotNumber { get; set; } public int SlotNumber { get; }
public EncounterSlot2(EncounterArea2 area, int species, int min, int max, int slot) : base(area) public EncounterSlot2(EncounterArea2 area, int species, int min, int max, int slot) : base(area)
{ {
@ -25,7 +26,7 @@
var pk2 = (PK2)pk; var pk2 = (PK2)pk;
if (Version == GameVersion.C) if (Version == GameVersion.C)
pk2.Met_TimeOfDay = ((EncounterArea2)Area!).Time.RandomValidTime(); pk2.Met_TimeOfDay = ((EncounterArea2)Area).Time.RandomValidTime();
} }
} }
} }

View file

@ -1,15 +1,19 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Encounter Slot found in <see cref="GameVersion.Gen3"/>.
/// </summary>
/// <inheritdoc cref="EncounterSlot"/>
public class EncounterSlot3 : EncounterSlot, IMagnetStatic, INumberedSlot public class EncounterSlot3 : EncounterSlot, IMagnetStatic, INumberedSlot
{ {
public sealed override int Generation => 3; public sealed override int Generation => 3;
public int StaticIndex { get; set; } public int StaticIndex { get; }
public int MagnetPullIndex { get; set; } public int MagnetPullIndex { get; }
public int StaticCount { get; set; } public int StaticCount { get; }
public int MagnetPullCount { get; set; } public int MagnetPullCount { get; }
public int SlotNumber { get; set; } public int SlotNumber { get; }
public EncounterSlot3(EncounterArea3 area, int species, int form, int min, int max, int slot, int mpi, int mpc, int sti, int stc) : base(area) public EncounterSlot3(EncounterArea3 area, int species, int form, int min, int max, int slot, int mpi, int mpc, int sti, int stc) : base(area)
{ {

View file

@ -1,10 +1,14 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Encounter Slot found in <see cref="GameVersion.XD"/>.
/// </summary>
/// <inheritdoc cref="EncounterSlot"/>
public sealed class EncounterSlot3PokeSpot : EncounterSlot, INumberedSlot public sealed class EncounterSlot3PokeSpot : EncounterSlot, INumberedSlot
{ {
public override int Generation => 3; public override int Generation => 3;
public int SlotNumber { get; set; } public int SlotNumber { get; }
public EncounterSlot3PokeSpot(EncounterArea3XD area, int species, int min, int max, int slot) : base(area) public EncounterSlot3PokeSpot(EncounterArea3XD area, int species, int min, int max, int slot) : base(area)
{ {

View file

@ -2,6 +2,13 @@ using System.Collections.Generic;
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Encounter Slot found in <see cref="GameVersion.RSE"/>.
/// </summary>
/// <remarks>
/// Handled differently as these slots have fixed moves that are different from their normal level-up moves.
/// </remarks>
/// <inheritdoc cref="EncounterSlot"/>
internal sealed class EncounterSlot3Swarm : EncounterSlot3, IMoveset internal sealed class EncounterSlot3Swarm : EncounterSlot3, IMoveset
{ {
public IReadOnlyList<int> Moves { get; } public IReadOnlyList<int> Moves { get; }

View file

@ -1,16 +1,20 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Encounter Slot found in <see cref="GameVersion.Gen4"/>.
/// </summary>
/// <inheritdoc cref="EncounterSlot"/>
public sealed class EncounterSlot4 : EncounterSlot, IMagnetStatic, INumberedSlot, IEncounterTypeTile public sealed class EncounterSlot4 : EncounterSlot, IMagnetStatic, INumberedSlot, IEncounterTypeTile
{ {
public override int Generation => 4; public override int Generation => 4;
public EncounterType TypeEncounter => ((EncounterArea4)Area).TypeEncounter; public EncounterType TypeEncounter => ((EncounterArea4)Area).TypeEncounter;
public int StaticIndex { get; set; } public int StaticIndex { get; }
public int MagnetPullIndex { get; set; } public int MagnetPullIndex { get; }
public int StaticCount { get; set; } public int StaticCount { get; }
public int MagnetPullCount { get; set; } public int MagnetPullCount { get; }
public int SlotNumber { get; set; } public int SlotNumber { get; }
public EncounterSlot4(EncounterArea4 area, int species, int form, int min, int max, int slot, int mpi, int mpc, int sti, int stc) : base(area) public EncounterSlot4(EncounterArea4 area, int species, int form, int min, int max, int slot, int mpi, int mpc, int sti, int stc) : base(area)
{ {

View file

@ -1,5 +1,9 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Encounter Slot found in <see cref="GameVersion.Gen5"/>.
/// </summary>
/// <inheritdoc cref="EncounterSlot"/>
public sealed class EncounterSlot5 : EncounterSlot public sealed class EncounterSlot5 : EncounterSlot
{ {
public override int Generation => 5; public override int Generation => 5;

View file

@ -1,8 +1,18 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Encounter Slot found in <see cref="GameVersion.ORAS"/>.
/// </summary>
/// <inheritdoc cref="EncounterSlot"/>
public sealed class EncounterSlot6AO : EncounterSlot public sealed class EncounterSlot6AO : EncounterSlot
{ {
public override int Generation => 6; public override int Generation => 6;
public bool CanDexNav => Area.Type != SlotType.Rock_Smash;
public bool Pressure { get; set; }
public bool DexNav { get; set; }
public bool WhiteFlute { get; set; }
public bool BlackFlute { get; set; }
public EncounterSlot6AO(EncounterArea6AO area, int species, int form, int min, int max) : base(area) public EncounterSlot6AO(EncounterArea6AO area, int species, int form, int min, int max) : base(area)
{ {
@ -12,13 +22,6 @@ namespace PKHeX.Core
LevelMax = max; LevelMax = max;
} }
public bool Pressure { get; set; }
public bool DexNav { get; set; }
public bool WhiteFlute { get; set; }
public bool BlackFlute { get; set; }
public bool CanDexNav => Area.Type != SlotType.Rock_Smash;
protected override void SetFormatSpecificData(PKM pk) protected override void SetFormatSpecificData(PKM pk)
{ {
var pk6 = (PK6)pk; var pk6 = (PK6)pk;

View file

@ -1,5 +1,9 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Encounter Slot found in <see cref="GameVersion.XY"/>.
/// </summary>
/// <inheritdoc cref="EncounterSlot"/>
public sealed class EncounterSlot6XY : EncounterSlot public sealed class EncounterSlot6XY : EncounterSlot
{ {
public override int Generation => 6; public override int Generation => 6;

View file

@ -1,7 +1,13 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Encounter Slot found in <see cref="GameVersion.Gen7"/>.
/// </summary>
/// <inheritdoc cref="EncounterSlot"/>
public sealed class EncounterSlot7 : EncounterSlot public sealed class EncounterSlot7 : EncounterSlot
{ {
public override int Generation => 7;
public EncounterSlot7(EncounterArea7 area, int species, int form, int min, int max) : base(area) public EncounterSlot7(EncounterArea7 area, int species, int form, int min, int max) : base(area)
{ {
Species = species; Species = species;
@ -9,8 +15,5 @@ namespace PKHeX.Core
LevelMin = min; LevelMin = min;
LevelMax = max; LevelMax = max;
} }
public override int Generation => 7;
public bool Pressure { get; set; }
} }
} }

View file

@ -1,5 +1,9 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Encounter Slot found in <see cref="GameVersion.GG"/>.
/// </summary>
/// <inheritdoc cref="EncounterSlot"/>
public sealed class EncounterSlot7b : EncounterSlot public sealed class EncounterSlot7b : EncounterSlot
{ {
public override int Generation => 7; public override int Generation => 7;

View file

@ -0,0 +1,23 @@
namespace PKHeX.Core
{
/// <summary>
/// Encounter Slot found in <see cref="GameVersion.SWSH"/>.
/// </summary>
/// <inheritdoc cref="EncounterSlot"/>
public sealed class EncounterSlot8 : EncounterSlot
{
public readonly AreaWeather8 Weather;
public override string LongName => Weather == AreaWeather8.All ? wild : $"{wild} - {Weather.ToString().Replace("_", string.Empty)}";
public override int Generation => 8;
public EncounterSlot8(EncounterArea8 area, int specForm, int min, int max, AreaWeather8 weather) : base(area)
{
Species = specForm & 0x7FF;
Form = specForm >> 11;
LevelMin = min;
LevelMax = max;
Weather = weather;
}
}
}

View file

@ -1,7 +1,8 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary> /// <summary>
/// Generation 7 Wild Encounter Slot data (GO Park) /// Encounter Slot found in <see cref="GameVersion.Gen7"/> (GO Park, <seealso cref="GameVersion.GG"/>).
/// <inheritdoc/>
/// </summary> /// </summary>
public sealed class EncounterSlot7GO : EncounterSlotGO public sealed class EncounterSlot7GO : EncounterSlotGO
{ {

View file

@ -1,11 +1,20 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary> /// <summary>
/// Generation 8 Wild Encounter Slot data (GO -> HOME) /// Encounter Slot representing data transferred to <see cref="GameVersion.Gen8"/> (HOME).
/// <inheritdoc/>
/// </summary> /// </summary>
public sealed class EncounterSlot8GO : EncounterSlotGO public sealed class EncounterSlot8GO : EncounterSlotGO
{ {
public override int Generation => 8; public override int Generation => 8;
/// <summary>
/// Encounters need a Parent Game to determine the original moves when transferred to HOME.
/// </summary>
/// <remarks>
/// Future game releases might change this value.
/// With respect to date legality, new dates might be incompatible with initial <seealso cref="OriginGroup"/> values.
/// </remarks>
public GameVersion OriginGroup { get; } public GameVersion OriginGroup { get; }
public EncounterSlot8GO(EncounterArea8g area, int species, int form, int start, int end, Shiny shiny, PogoType type, GameVersion originGroup) public EncounterSlot8GO(EncounterArea8g area, int species, int form, int start, int end, Shiny shiny, PogoType type, GameVersion originGroup)
@ -17,7 +26,14 @@ namespace PKHeX.Core
OriginGroup = originGroup; OriginGroup = originGroup;
} }
/// <summary>
/// Gets the minimum IV (in GO) the encounter must have.
/// </summary>
public int GetMinIV() => Type.GetMinIV(); public int GetMinIV() => Type.GetMinIV();
/// <summary>
/// Checks if the <seealso cref="Ball"/> is compatible with the <seealso cref="PogoType"/>.
/// </summary>
public bool IsBallValid(Ball ball) => Type.IsBallValid(ball); public bool IsBallValid(Ball ball) => Type.IsBallValid(ball);
protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteria, PKM pk) protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteria, PKM pk)

View file

@ -3,21 +3,20 @@ using System;
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary> /// <summary>
/// Contains details about an encounter that can be found in <see cref="GameVersion.GO"/> /// Contains details about an encounter that can be found in <see cref="GameVersion.GO"/>.
/// </summary> /// </summary>
public abstract class EncounterSlotGO : EncounterSlot, IPogoSlot public abstract class EncounterSlotGO : EncounterSlot, IPogoSlot
{ {
/// <summary> Start Date timestamp of when the encounter became available. </summary> /// <inheritdoc/>
public int Start { get; } public int Start { get; }
/// <summary> End Date timestamp of when the encounter became unavailable. </summary> /// <inheritdoc/>
/// <remarks> If there is no end date (yet), we'll try to clamp to a date in the near-future to prevent it from being open-ended. </remarks>
public int End { get; } public int End { get; }
/// <summary> Possibility of being shiny. </summary> /// <inheritdoc/>
public Shiny Shiny { get; } public Shiny Shiny { get; }
/// <summary> How the encounter was captured. </summary> /// <inheritdoc/>
public PogoType Type { get; } public PogoType Type { get; }
protected EncounterSlotGO(EncounterArea area, int start, int end, Shiny shiny, PogoType type) : base(area) protected EncounterSlotGO(EncounterArea area, int start, int end, Shiny shiny, PogoType type) : base(area)
@ -56,7 +55,7 @@ namespace PKHeX.Core
public bool IsWithinStartEnd(int stamp) public bool IsWithinStartEnd(int stamp)
{ {
if (End == 0) if (End == 0)
return Start <= stamp && GetDate(stamp) <= DateTime.Now; return Start <= stamp && GetDate(stamp) <= DateTime.UtcNow;
if (Start == 0) if (Start == 0)
return stamp <= End; return stamp <= End;
return Start <= stamp && stamp <= End; return Start <= stamp && stamp <= End;
@ -73,7 +72,7 @@ namespace PKHeX.Core
public DateTime GetRandomValidDate() public DateTime GetRandomValidDate()
{ {
if (Start == 0) if (Start == 0)
return End == 0 ? DateTime.Now : GetDate(End); return End == 0 ? DateTime.UtcNow : GetDate(End);
var start = GetDate(Start); var start = GetDate(Start);
if (End == 0) if (End == 0)

View file

@ -9,6 +9,7 @@ namespace PKHeX.Core
int Start { get; } int Start { get; }
/// <summary> Last day the encounter was available. If zero, no date specified (unbounded finish). </summary> /// <summary> Last day the encounter was available. If zero, no date specified (unbounded finish). </summary>
/// <remarks> If there is no end date (yet), we'll try to clamp to a date in the near-future to prevent it from being open-ended. </remarks>
int End { get; } int End { get; }
/// <summary> Possibility of shiny for the encounter. </summary> /// <summary> Possibility of shiny for the encounter. </summary>

View file

@ -1,7 +1,17 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Contains information pertaining the floor tile the <see cref="IEncounterable"/> was obtained on in <see cref="GameVersion.Gen4"/>.
/// </summary>
/// <remarks>
/// <seealso cref="EncounterSlot4"/>
/// <seealso cref="EncounterStaticTyped"/>
/// </remarks>
public interface IEncounterTypeTile public interface IEncounterTypeTile
{ {
/// <summary>
/// Tile Type the <see cref="IEncounterable"/> was obtained on.
/// </summary>
EncounterType TypeEncounter { get; } EncounterType TypeEncounter { get; }
} }

View file

@ -1,12 +1,24 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Contains information about the RNG restrictions for the slot, and any mutated RNG values.
/// </summary>
/// <remarks>
/// When encountering a Wild Pokémon with a lead that has an ability of <see cref="Ability.Static"/> or <see cref="Ability.MagnetPull"/>,
/// the game picks encounters from the <seealso cref="EncounterArea"/> that match the type.
/// The values in this interface change the <seealso cref="INumberedSlot"/> to allow different values for slot yielding.
/// </remarks>
public interface IMagnetStatic public interface IMagnetStatic
{ {
int StaticIndex { get; set; } /// <summary> <see cref="INumberedSlot.SlotNumber"/> if the lead is <see cref="Ability.Static"/> </summary>
int MagnetPullIndex { get; set; } int StaticIndex { get; }
/// <summary> <see cref="INumberedSlot.SlotNumber"/> if the lead is <see cref="Ability.MagnetPull"/> </summary>
int MagnetPullIndex { get; }
int StaticCount { get; set; } /// <summary> Count of slots in the parent area that can be yielded by <see cref="Ability.Static"/> </summary>
int MagnetPullCount { get; set; } int StaticCount { get; }
/// <summary> Count of slots in the parent area that can be yielded by <see cref="Ability.MagnetPull"/> </summary>
int MagnetPullCount { get; }
} }
public static class MagnetStaticExtensions public static class MagnetStaticExtensions

View file

@ -1,7 +1,16 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// <seealso cref="EncounterSlot"/> that contains information about what Index it is within the <seealso cref="EncounterArea"/>'s type-group of slots.
/// </summary>
/// <remarks>
/// Useful for checking legality (if the RNG can yield this slot).
/// </remarks>
public interface INumberedSlot public interface INumberedSlot
{ {
int SlotNumber { get; set; } /// <summary>
/// Number Index of the <seealso cref="EncounterSlot"/>.
/// </summary>
int SlotNumber { get; }
} }
} }

View file

@ -1,5 +1,9 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Generation 1 Static Encounter
/// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public class EncounterStatic1 : EncounterStatic public class EncounterStatic1 : EncounterStatic
{ {
public override int Generation => 1; public override int Generation => 1;

View file

@ -7,6 +7,7 @@ namespace PKHeX.Core
/// <summary> /// <summary>
/// Event data for Generation 1 /// Event data for Generation 1
/// </summary> /// </summary>
/// <inheritdoc cref="EncounterStatic1"/>
public sealed class EncounterStatic1E : EncounterStatic1 public sealed class EncounterStatic1E : EncounterStatic1
{ {
public EncounterGBLanguage Language { get; set; } = EncounterGBLanguage.Japanese; public EncounterGBLanguage Language { get; set; } = EncounterGBLanguage.Japanese;

View file

@ -3,6 +3,10 @@ using System.Linq;
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Generation 2 Static Encounter
/// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public class EncounterStatic2 : EncounterStatic public class EncounterStatic2 : EncounterStatic
{ {
public sealed override int Generation => 2; public sealed override int Generation => 2;

View file

@ -7,6 +7,7 @@ namespace PKHeX.Core
/// <summary> /// <summary>
/// Event data for Generation 2 /// Event data for Generation 2
/// </summary> /// </summary>
/// <inheritdoc cref="EncounterStatic2"/>
public sealed class EncounterStatic2E : EncounterStatic2 public sealed class EncounterStatic2E : EncounterStatic2
{ {
public EncounterGBLanguage Language { get; set; } = EncounterGBLanguage.Japanese; public EncounterGBLanguage Language { get; set; } = EncounterGBLanguage.Japanese;

View file

@ -3,6 +3,10 @@ using System.Linq;
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Generation 3 Static Encounter
/// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public sealed class EncounterStatic3 : EncounterStatic public sealed class EncounterStatic3 : EncounterStatic
{ {
public override int Generation => 3; public override int Generation => 3;

View file

@ -1,5 +1,9 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Generation 4 Static Encounter
/// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public class EncounterStatic4 : EncounterStatic public class EncounterStatic4 : EncounterStatic
{ {
public sealed override int Generation => 4; public sealed override int Generation => 4;

View file

@ -2,6 +2,10 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Generation 5 Static Encounter
/// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public class EncounterStatic5 : EncounterStatic public class EncounterStatic5 : EncounterStatic
{ {
public sealed override int Generation => 5; public sealed override int Generation => 5;

View file

@ -3,6 +3,7 @@
/// <summary> /// <summary>
/// Generation 5 Dream Radar gift encounters /// Generation 5 Dream Radar gift encounters
/// </summary> /// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public sealed class EncounterStatic5DR : EncounterStatic5 public sealed class EncounterStatic5DR : EncounterStatic5
{ {
public EncounterStatic5DR(int species, int form, int abilityIndex = 4) public EncounterStatic5DR(int species, int form, int abilityIndex = 4)

View file

@ -1,5 +1,9 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Generation 5 Static Encounter from N
/// </summary>
/// <inheritdoc cref="EncounterStatic"/>
internal sealed class EncounterStatic5N : EncounterStatic5 internal sealed class EncounterStatic5N : EncounterStatic5
{ {
public readonly uint PID; public readonly uint PID;

View file

@ -2,6 +2,10 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Generation 6 Static Encounter
/// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public sealed class EncounterStatic6 : EncounterStatic, IContestStats public sealed class EncounterStatic6 : EncounterStatic, IContestStats
{ {
public override int Generation => 6; public override int Generation => 6;

View file

@ -3,6 +3,10 @@ using System.Collections.Generic;
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Generation 7 Static Encounter
/// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public sealed class EncounterStatic7 : EncounterStatic, IRelearn public sealed class EncounterStatic7 : EncounterStatic, IRelearn
{ {
public override int Generation => 7; public override int Generation => 7;
@ -20,9 +24,9 @@ namespace PKHeX.Core
if (SkipFormCheck) if (SkipFormCheck)
return true; return true;
if (FormConverter.IsTotemForm(Species, Form, Generation)) if (AltFormInfo.IsTotemForm(Species, Form, Generation))
{ {
var expectForm = pkm.Format == 7 ? Form : FormConverter.GetTotemBaseForm(Species, Form); var expectForm = pkm.Format == 7 ? Form : AltFormInfo.GetTotemBaseForm(Species, Form);
return expectForm == evo.Form; return expectForm == evo.Form;
} }

View file

@ -1,5 +1,9 @@
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Generation 7 Static Encounter (<see cref="GameVersion.GG"/>
/// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public sealed class EncounterStatic7b : EncounterStatic public sealed class EncounterStatic7b : EncounterStatic
{ {
public override int Generation => 7; public override int Generation => 7;

View file

@ -3,6 +3,10 @@ using System.Collections.Generic;
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Generation 8 Static Encounter
/// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public class EncounterStatic8 : EncounterStatic, IDynamaxLevel, IGigantamax, IRelearn public class EncounterStatic8 : EncounterStatic, IDynamaxLevel, IGigantamax, IRelearn
{ {
public sealed override int Generation => 8; public sealed override int Generation => 8;

View file

@ -5,8 +5,9 @@ using static PKHeX.Core.Encounters8Nest;
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary> /// <summary>
/// Generation 8 Nest Encounter (Raid) /// Generation 8 Nest Encounter (Regular Raid Dens)
/// </summary> /// </summary>
/// <inheritdoc cref="EncounterStatic8Nest{T}"/>
public sealed class EncounterStatic8N : EncounterStatic8Nest<EncounterStatic8N> public sealed class EncounterStatic8N : EncounterStatic8Nest<EncounterStatic8N>
{ {
private readonly uint MinRank; private readonly uint MinRank;

View file

@ -5,6 +5,7 @@ namespace PKHeX.Core
/// <summary> /// <summary>
/// Generation 8 Nest Encounter (Distributed Crystal Data) /// Generation 8 Nest Encounter (Distributed Crystal Data)
/// </summary> /// </summary>
/// <inheritdoc cref="EncounterStatic8Nest{T}"/>
public sealed class EncounterStatic8NC : EncounterStatic8Nest<EncounterStatic8NC> public sealed class EncounterStatic8NC : EncounterStatic8Nest<EncounterStatic8NC>
{ {
public override int Location { get => SharedNest; set { } } public override int Location { get => SharedNest; set { } }

View file

@ -5,6 +5,7 @@ namespace PKHeX.Core
/// <summary> /// <summary>
/// Generation 8 Nest Encounter (Distributed Data) /// Generation 8 Nest Encounter (Distributed Data)
/// </summary> /// </summary>
/// <inheritdoc cref="EncounterStatic8Nest{T}"/>
public sealed class EncounterStatic8ND : EncounterStatic8Nest<EncounterStatic8ND> public sealed class EncounterStatic8ND : EncounterStatic8Nest<EncounterStatic8ND>
{ {
public EncounterStatic8ND(byte lvl, byte dyna, byte flawless) public EncounterStatic8ND(byte lvl, byte dyna, byte flawless)

View file

@ -3,9 +3,13 @@ using static PKHeX.Core.Encounters8Nest;
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Generation 8 Nest Encounter (Raid)
/// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public abstract class EncounterStatic8Nest<T> : EncounterStatic, IGigantamax, IDynamaxLevel where T : EncounterStatic8Nest<T> public abstract class EncounterStatic8Nest<T> : EncounterStatic, IGigantamax, IDynamaxLevel where T : EncounterStatic8Nest<T>
{ {
public override int Generation => 8; public sealed override int Generation => 8;
public static Func<PKM, T, bool>? VerifyCorrelation { private get; set; } public static Func<PKM, T, bool>? VerifyCorrelation { private get; set; }
public static Action<PKM, T, EncounterCriteria>? GenerateData { private get; set; } public static Action<PKM, T, EncounterCriteria>? GenerateData { private get; set; }
@ -41,7 +45,7 @@ namespace PKHeX.Core
return base.IsMatch(pkm, evo); return base.IsMatch(pkm, evo);
} }
public override bool IsMatchDeferred(PKM pkm) public sealed override bool IsMatchDeferred(PKM pkm)
{ {
if (base.IsMatchDeferred(pkm)) if (base.IsMatchDeferred(pkm))
return true; return true;
@ -75,7 +79,7 @@ namespace PKHeX.Core
return false; return false;
} }
protected override void SetPINGA(PKM pk, EncounterCriteria criteria) protected sealed override void SetPINGA(PKM pk, EncounterCriteria criteria)
{ {
if (GenerateData != null) if (GenerateData != null)
GenerateData(pk, (T)this, criteria); GenerateData(pk, (T)this, criteria);

View file

@ -7,6 +7,7 @@ namespace PKHeX.Core
/// <summary> /// <summary>
/// <see cref="EncounterStatic8"/> with multiple references (used for multiple met locations) /// <see cref="EncounterStatic8"/> with multiple references (used for multiple met locations)
/// </summary> /// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public sealed class EncounterStatic8S : EncounterStatic8 public sealed class EncounterStatic8S : EncounterStatic8
{ {
public override int Location { get => Locations[0]; set { } } public override int Location { get => Locations[0]; set { } }

View file

@ -5,6 +5,7 @@ namespace PKHeX.Core
/// <summary> /// <summary>
/// Generation 8 Nest Encounter (Max Raid) Underground /// Generation 8 Nest Encounter (Max Raid) Underground
/// </summary> /// </summary>
/// <inheritdoc cref="EncounterStatic8Nest{T}"/>
public sealed class EncounterStatic8U : EncounterStatic8Nest<EncounterStatic8U> public sealed class EncounterStatic8U : EncounterStatic8Nest<EncounterStatic8U>
{ {
public override int Location { get => MaxLair; set { } } public override int Location { get => MaxLair; set { } }

View file

@ -7,6 +7,7 @@ namespace PKHeX.Core
/// <summary> /// <summary>
/// Shadow Pokémon Encounter found in <see cref="GameVersion.CXD"/> /// Shadow Pokémon Encounter found in <see cref="GameVersion.CXD"/>
/// </summary> /// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public sealed class EncounterStaticShadow : EncounterStatic public sealed class EncounterStaticShadow : EncounterStatic
{ {
public override int Generation => 3; public override int Generation => 3;

View file

@ -3,6 +3,10 @@ using System.Linq;
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary>
/// Generation 4 Static Encounter
/// </summary>
/// <inheritdoc cref="EncounterStatic"/>
public sealed class EncounterStaticTyped : EncounterStatic4, IEncounterTypeTile public sealed class EncounterStaticTyped : EncounterStatic4, IEncounterTypeTile
{ {
public bool Roaming { get; set; } public bool Roaming { get; set; }
@ -17,6 +21,7 @@ namespace PKHeX.Core
if (!Roaming) if (!Roaming)
return base.IsMatchLocation(pkm); return base.IsMatchLocation(pkm);
// Met location is lost on transfer
if (!(pkm is G4PKM pk4)) if (!(pkm is G4PKM pk4))
return true; return true;

View file

@ -259,16 +259,16 @@ namespace PKHeX.Core
private bool IsMatchLevel(PKM pkm, DexLevel evo) private bool IsMatchLevel(PKM pkm, DexLevel evo)
{ {
if (!pkm.HasOriginalMetLocation) if (!pkm.HasOriginalMetLocation)
return Level <= evo.Level; return evo.Level >= Level;
var loc = Location != 0 ? Location : GetDefaultMetLocation(Generation); var loc = Location != 0 ? Location : GetDefaultMetLocation(Generation);
if (loc != pkm.Met_Location) if (loc != pkm.Met_Location)
return false; return false;
if (pkm.Format < 5) if (pkm.Format < 5)
return Level <= evo.Level; return evo.Level >= Level;
return Level == pkm.Met_Level; return pkm.Met_Level == Level;
} }
protected virtual bool IsMatchNatureGenderShiny(PKM pkm) protected virtual bool IsMatchNatureGenderShiny(PKM pkm)

View file

@ -60,7 +60,7 @@ namespace PKHeX.Core
{ {
if (form == 0) if (form == 0)
return false; return false;
if (FormConverter.IsTotemForm(species, form, gen)) if (AltFormInfo.IsTotemForm(species, form, gen))
return true; return true;
if (species == (int) Species.Pichu) if (species == (int) Species.Pichu)
return true; // can't get Spiky Ear Pichu eggs return true; // can't get Spiky Ear Pichu eggs

View file

@ -204,5 +204,88 @@ namespace PKHeX.Core
hs.UnionWith(BattlePrimals); hs.UnionWith(BattlePrimals);
return hs; return hs;
} }
/// <summary>
/// Chhecks if the <see cref="form"/> for the <see cref="species"/> is a Totem form.
/// </summary>
/// <param name="species">Entity species</param>
/// <param name="form">Entity form</param>
/// <param name="format">Current generation format</param>
public static bool IsTotemForm(int species, int form, int format)
{
if (format != 7)
return false;
if (form == 0)
return false;
if (!Legal.Totem_USUM.Contains(species))
return false;
if (species == (int)Mimikyu)
return form == 2 || form == 3;
if (Legal.Totem_Alolan.Contains(species))
return form == 2;
return form == 1;
}
/// <summary>
/// Gets the base <see cref="form"/> for the <see cref="species"/> when the Totem form is reverted (on transfer).
/// </summary>
/// <param name="species">Entity species</param>
/// <param name="form">Entity form</param>
public static int GetTotemBaseForm(int species, int form)
{
if (species == (int)Mimikyu)
return form - 2;
return form - 1;
}
/// <summary>
/// Checks if the <see cref="form"/> exists for the <see cref="species"/> without having an associated <see cref="PersonalInfo"/> index.
/// </summary>
/// <param name="species">Entity species</param>
/// <param name="form">Entity form</param>
/// <param name="format">Current generation format</param>
/// <seealso cref="HasFormeValuesNotIndicatedByPersonal"/>
public static bool IsValidOutOfBoundsForme(int species, int form, int format)
{
return (Species) species switch
{
Unown => form < (format == 2 ? 26 : 28), // A-Z : A-Z?!
Mothim => form < 3, // Burmy base form is kept
Scatterbug => form < 18, // Vivillon Pre-evolutions
Spewpa => form < 18, // Vivillon Pre-evolutions
_ => false
};
}
/// <summary>
/// Checks if the <see cref="PKM"/> data should have a drop-down selection visible for the <see cref="PKM.AltForm"/> value.
/// </summary>
/// <param name="pi">Game specific personal info</param>
/// <param name="species"><see cref="Species"/> ID</param>
/// <param name="format"><see cref="PKM.AltForm"/> ID</param>
/// <returns>True if has formes that can be provided by <see cref="FormConverter.GetFormList"/>, otherwise false for none.</returns>
public static bool HasFormSelection(PersonalInfo pi, int species, int format)
{
if (format <= 3 && species != (int)Unown)
return false;
if (HasFormeValuesNotIndicatedByPersonal.Contains(species))
return true;
int count = pi.FormeCount;
return count > 1;
}
/// <summary>
/// <seealso cref="IsValidOutOfBoundsForme"/>
/// </summary>
private static readonly HashSet<int> HasFormeValuesNotIndicatedByPersonal = new HashSet<int>
{
(int)Unown,
(int)Mothim, // (Burmy forme carried over, not cleared)
(int)Scatterbug, (int)Spewpa, // Vivillon pre-evos
};
} }
} }

View file

@ -39,7 +39,7 @@ namespace PKHeX.Core
var EncounterMatch = data.EncounterMatch; var EncounterMatch = data.EncounterMatch;
var Info = data.Info; var Info = data.Info;
if (!PersonalInfo.IsFormeWithinRange(form) && !FormConverter.IsValidOutOfBoundsForme(species, form, Info.Generation)) if (!PersonalInfo.IsFormeWithinRange(form) && !AltFormInfo.IsValidOutOfBoundsForme(species, form, Info.Generation))
return GetInvalid(string.Format(LFormInvalidRange, count - 1, form)); return GetInvalid(string.Format(LFormInvalidRange, count - 1, form));
if (EncounterMatch is EncounterSlot w && w.Area.Type == SlotType.FriendSafari) if (EncounterMatch is EncounterSlot w && w.Area.Type == SlotType.FriendSafari)
@ -48,7 +48,7 @@ namespace PKHeX.Core
} }
else if (EncounterMatch is EncounterEgg) else if (EncounterMatch is EncounterEgg)
{ {
if (FormConverter.IsTotemForm(species, form, data.Info.Generation)) if (AltFormInfo.IsTotemForm(species, form, data.Info.Generation))
return GetInvalid(LFormInvalidGame); return GetInvalid(LFormInvalidGame);
} }

View file

@ -128,11 +128,11 @@ namespace PKHeX.Core
} }
else if (enc.Generation < 8 && pkm.Format >= 8) else if (enc.Generation < 8 && pkm.Format >= 8)
{ {
if (enc is EncounterStatic7 s && FormConverter.IsTotemForm(s.Species, s.Form, 7)) if (enc is EncounterStatic7 s && AltFormInfo.IsTotemForm(s.Species, s.Form, 7))
{ {
if (Legal.Totem_NoTransfer.Contains(s.Species)) if (Legal.Totem_NoTransfer.Contains(s.Species))
data.AddLine(GetInvalid(LTransferBad)); data.AddLine(GetInvalid(LTransferBad));
if (pkm.AltForm != FormConverter.GetTotemBaseForm(s.Species, s.Form)) if (pkm.AltForm != AltFormInfo.GetTotemBaseForm(s.Species, s.Form))
data.AddLine(GetInvalid(LTransferBad)); data.AddLine(GetInvalid(LTransferBad));
} }

View file

@ -1713,9 +1713,4 @@
<EmbeddedResource Include="Resources\text\zh\text_xy_60000_zh.txt" /> <EmbeddedResource Include="Resources\text\zh\text_xy_60000_zh.txt" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
<Folder Include="Saves\Substructures\Mail\" />
</ItemGroup>
</Project> </Project>

View file

@ -633,8 +633,8 @@ namespace PKHeX.Core
}; };
// Wipe Totem Forms // Wipe Totem Forms
if (FormConverter.IsTotemForm(Species, AltForm, 7)) if (AltFormInfo.IsTotemForm(Species, AltForm, 7))
pk8.AltForm = FormConverter.GetTotemBaseForm(Species, AltForm); pk8.AltForm = AltFormInfo.GetTotemBaseForm(Species, AltForm);
// Fix PP and Stats // Fix PP and Stats
pk8.Heal(); pk8.Heal();

View file

@ -5,7 +5,7 @@ using static PKHeX.Core.Species;
namespace PKHeX.Core namespace PKHeX.Core
{ {
/// <summary> /// <summary>
/// Logic for various <see cref="PKM.AltForm"/> related requests. /// Retrieves localized form names for indicating <see cref="PKM.AltForm"/> values.
/// </summary> /// </summary>
public static class FormConverter public static class FormConverter
{ {
@ -47,44 +47,6 @@ namespace PKHeX.Core
// this is a hack; depends on currently loaded SaveFile's Game ID // this is a hack; depends on currently loaded SaveFile's Game ID
private static bool IsGG() => PKMConverter.Game == (int)GameVersion.GP || PKMConverter.Game == (int)GameVersion.GE; private static bool IsGG() => PKMConverter.Game == (int)GameVersion.GP || PKMConverter.Game == (int)GameVersion.GE;
public static bool IsTotemForm(int species, int form, int generation)
{
if (generation != 7)
return false;
if (form == 0)
return false;
if (!Legal.Totem_USUM.Contains(species))
return false;
if (species == (int)Mimikyu)
return form == 2 || form == 3;
if (Legal.Totem_Alolan.Contains(species))
return form == 2;
return form == 1;
}
public static int GetTotemBaseForm(int species, int form)
{
if (species == (int)Mimikyu)
return form - 2;
return form - 1;
}
public static bool IsValidOutOfBoundsForme(int species, int form, int generation)
{
switch ((Species)species)
{
case Unown:
return form < (generation == 2 ? 26 : 28); // A-Z : A-Z?!
case Mothim: // Burmy base form is kept
return form < 3;
case Scatterbug:
case Spewpa: // Vivillon Pre-evolutions
return form < 18;
default:
return false;
}
}
private static readonly string[] EMPTY = { string.Empty }; private static readonly string[] EMPTY = { string.Empty };
private const string Starter = nameof(Starter); private const string Starter = nameof(Starter);
@ -904,32 +866,6 @@ namespace PKHeX.Core
015, 018, 080, 208, 254, 260, 302, 319, 323, 334, 362, 373, 376, 384, 428, 475, 531, 719, 015, 018, 080, 208, 254, 260, 302, 319, 323, 334, 362, 373, 376, 384, 428, 475, 531, 719,
}; };
/// <summary>
/// Checks if the <see cref="PKM"/> data should have a drop-down selection visible for the <see cref="PKM.AltForm"/> value.
/// </summary>
/// <param name="pi">Game specific personal info</param>
/// <param name="species"><see cref="Species"/> ID</param>
/// <param name="format"><see cref="PKM.AltForm"/> ID</param>
/// <returns>True if has formes that can be provided by <see cref="GetFormList"/>, otherwise false for none.</returns>
public static bool HasFormSelection(PersonalInfo pi, int species, int format)
{
if (format <= 3 && species != (int)Unown)
return false;
if (HasFormeValuesNotIndicatedByPersonal.Contains(species))
return true;
int count = pi.FormeCount;
return count > 1;
}
private static readonly HashSet<int> HasFormeValuesNotIndicatedByPersonal = new HashSet<int>
{
(int)Unown,
(int)Mothim, // (Burmy forme carried over, not cleared)
(int)Scatterbug, (int)Spewpa, // Vivillon pre-evos
};
private static string[] GetMegaSingle(IReadOnlyList<string> types, IReadOnlyList<string> forms) private static string[] GetMegaSingle(IReadOnlyList<string> types, IReadOnlyList<string> forms)
{ {
return new[] return new[]
@ -969,7 +905,7 @@ namespace PKHeX.Core
} }
private const int Galarian = 1068; private const int Galarian = 1068;
// private const int Gigantamax = 1069; private const int Gigantamax = 1069;
private const int Gulping = 1070; private const int Gulping = 1070;
private const int Gorging = 1071; private const int Gorging = 1071;
private const int LowKey = 1072; private const int LowKey = 1072;
@ -995,6 +931,8 @@ namespace PKHeX.Core
private const int CalyIce = 1089; // Ice private const int CalyIce = 1089; // Ice
private const int CalyGhost = 1090; // Shadow private const int CalyGhost = 1090; // Shadow
public static string GetGigantamaxName(IReadOnlyList<string> forms) => forms[Gigantamax];
public static string[] GetAlcremieFormList(IReadOnlyList<string> forms) public static string[] GetAlcremieFormList(IReadOnlyList<string> forms)
{ {
var result = new string[63]; var result = new string[63];

View file

@ -95,7 +95,7 @@ namespace PKHeX.Core
else if (sav.MaxSpeciesID < pkm.Species) else if (sav.MaxSpeciesID < pkm.Species)
errata.Add($"{MsgIndexSpeciesGame} {strings.Species[pkm.Species]}"); errata.Add($"{MsgIndexSpeciesGame} {strings.Species[pkm.Species]}");
if (!sav.Personal[pkm.Species].IsFormeWithinRange(pkm.AltForm) && !FormConverter.IsValidOutOfBoundsForme(pkm.Species, pkm.AltForm, pkm.GenNumber)) if (!sav.Personal[pkm.Species].IsFormeWithinRange(pkm.AltForm) && !AltFormInfo.IsValidOutOfBoundsForme(pkm.Species, pkm.AltForm, pkm.GenNumber))
errata.Add(string.Format(LegalityCheckStrings.LFormInvalidRange, Math.Max(0, sav.Personal[pkm.Species].FormeCount - 1), pkm.AltForm)); errata.Add(string.Format(LegalityCheckStrings.LFormInvalidRange, Math.Max(0, sav.Personal[pkm.Species].FormeCount - 1), pkm.AltForm));
if (pkm.Moves.Any(m => m > strings.Move.Count)) if (pkm.Moves.Any(m => m > strings.Move.Count))

View file

@ -84,7 +84,7 @@ namespace PKHeX.Drawing
private Image GetBaseImage(int species, int form, int gender, uint formarg, bool shiny, int generation) private Image GetBaseImage(int species, int form, int gender, uint formarg, bool shiny, int generation)
{ {
var img = FormConverter.IsTotemForm(species, form, generation) var img = AltFormInfo.IsTotemForm(species, form, generation)
? GetBaseImageTotem(species, form, gender, formarg, shiny, generation) ? GetBaseImageTotem(species, form, gender, formarg, shiny, generation)
: GetBaseImageDefault(species, form, gender, formarg, shiny, generation); : GetBaseImageDefault(species, form, gender, formarg, shiny, generation);
return img ?? GetBaseImageFallback(species, form, gender, formarg, shiny, generation); return img ?? GetBaseImageFallback(species, form, gender, formarg, shiny, generation);
@ -92,7 +92,7 @@ namespace PKHeX.Drawing
private Image? GetBaseImageTotem(int species, int form, int gender, uint formarg, bool shiny, int generation) private Image? GetBaseImageTotem(int species, int form, int gender, uint formarg, bool shiny, int generation)
{ {
var baseform = FormConverter.GetTotemBaseForm(species, form); var baseform = AltFormInfo.GetTotemBaseForm(species, form);
var baseImage = GetBaseImageDefault(species, baseform, gender, formarg, shiny, generation); var baseImage = GetBaseImageDefault(species, baseform, gender, formarg, shiny, generation);
if (baseImage == null) if (baseImage == null)
return null; return null;

View file

@ -427,7 +427,7 @@ namespace PKHeX.WinForms.Controls
{ {
int species = Entity.Species; int species = Entity.Species;
var pi = RequestSaveFile.Personal[species]; var pi = RequestSaveFile.Personal[species];
bool hasForms = FormConverter.HasFormSelection(pi, species, Entity.Format); bool hasForms = AltFormInfo.HasFormSelection(pi, species, Entity.Format);
CB_Form.Enabled = CB_Form.Visible = Label_Form.Visible = hasForms; CB_Form.Enabled = CB_Form.Visible = Label_Form.Visible = hasForms;
if (HaX && Entity.Format >= 4) if (HaX && Entity.Format >= 4)

View file

@ -458,7 +458,7 @@ namespace PKHeX.WinForms
private void SetForms() private void SetForms()
{ {
int species = WinFormsUtil.GetIndex(CB_Species); int species = WinFormsUtil.GetIndex(CB_Species);
bool hasForms = FormConverter.HasFormSelection(PersonalTable.AO[species], species, 6); bool hasForms = AltFormInfo.HasFormSelection(PersonalTable.AO[species], species, 6);
CB_Form.Enabled = CB_Form.Visible = hasForms; CB_Form.Enabled = CB_Form.Visible = hasForms;
CB_Form.InitializeBinding(); CB_Form.InitializeBinding();

View file

@ -133,7 +133,7 @@ namespace PKHeX.WinForms
int fspecies = LB_Species.SelectedIndex + 1; int fspecies = LB_Species.SelectedIndex + 1;
var bspecies = Dex.GetBaseSpecies(fspecies); var bspecies = Dex.GetBaseSpecies(fspecies);
bool hasForms = FormConverter.HasFormSelection(SAV.Personal[bspecies], bspecies, 7); bool hasForms = AltFormInfo.HasFormSelection(SAV.Personal[bspecies], bspecies, 7);
LB_Forms.Enabled = hasForms; LB_Forms.Enabled = hasForms;
if (!hasForms) return false; if (!hasForms) return false;
var ds = FormConverter.GetFormList(bspecies, GameInfo.Strings.types, GameInfo.Strings.forms, Main.GenderSymbols, SAV.Generation).ToList(); var ds = FormConverter.GetFormList(bspecies, GameInfo.Strings.types, GameInfo.Strings.forms, Main.GenderSymbols, SAV.Generation).ToList();

View file

@ -120,7 +120,7 @@ namespace PKHeX.WinForms
int fspecies = LB_Species.SelectedIndex + 1; int fspecies = LB_Species.SelectedIndex + 1;
var bspecies = Dex.GetBaseSpecies(fspecies); var bspecies = Dex.GetBaseSpecies(fspecies);
bool hasForms = FormConverter.HasFormSelection(SAV.Personal[bspecies], bspecies, 7); bool hasForms = AltFormInfo.HasFormSelection(SAV.Personal[bspecies], bspecies, 7);
LB_Forms.Enabled = hasForms; LB_Forms.Enabled = hasForms;
if (!hasForms) if (!hasForms)
return false; return false;