mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-10 06:34:19 +00:00
Misc fixes
Allow dragon ascent bitfetch for gen6/7 Fix hidden power type parse/trim Remove */ from hidden power type calc allow longer set lines (full EVs specified for Gen2 is 74 chars allow set lines of length 1-2 to fully support trash sets for all languages Tweak pb8->pk8 to be more straightforward
This commit is contained in:
parent
387ab6d546
commit
9ddfe3f629
9 changed files with 60 additions and 28 deletions
|
@ -31,11 +31,22 @@ public static class HiddenPower
|
|||
int hp = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
hp |= (IVs[i] & 1) << i;
|
||||
hp *= 0xF;
|
||||
hp /= 0x3F;
|
||||
return hp;
|
||||
return SixBitType[hp];
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> SixBitType => new byte[]
|
||||
{
|
||||
// (low-bit mash) * 15 / 63
|
||||
00, 00, 00, 00, 00, 01, 01, 01,
|
||||
01, 02, 02, 02, 02, 03, 03, 03,
|
||||
03, 04, 04, 04, 04, 05, 05, 05,
|
||||
05, 05, 06, 06, 06, 06, 07, 07,
|
||||
07, 07, 08, 08, 08, 08, 09, 09,
|
||||
09, 09, 10, 10, 10, 10, 10, 11,
|
||||
11, 11, 11, 12, 12, 12, 12, 13,
|
||||
13, 13, 13, 14, 14, 14, 14, 15,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current Hidden Power Type of the input <see cref="IVs"/> for Generations 1 & 2
|
||||
/// </summary>
|
||||
|
@ -83,6 +94,10 @@ public static class HiddenPower
|
|||
/// <returns>True if the Hidden Power of the <see cref="IVs"/> is obtained, with or without modifications</returns>
|
||||
public static bool SetIVsForType(int hpVal, Span<int> IVs)
|
||||
{
|
||||
int current = GetType(IVs);
|
||||
if (current == hpVal)
|
||||
return true; // no mods necessary
|
||||
|
||||
int flawlessCount = IVs.Count(31);
|
||||
if (flawlessCount == 0)
|
||||
return false;
|
||||
|
@ -93,10 +108,6 @@ public static class HiddenPower
|
|||
return true;
|
||||
}
|
||||
|
||||
int current = GetType(IVs);
|
||||
if (current == hpVal)
|
||||
return true; // no mods necessary
|
||||
|
||||
// Required HP type doesn't match IVs. Make currently-flawless IVs flawed.
|
||||
Span<int> scratch = stackalloc int[IVs.Length];
|
||||
Span<int> result = stackalloc int[IVs.Length];
|
||||
|
|
|
@ -139,6 +139,15 @@ public sealed class ShowdownSet : IBattleTemplate
|
|||
|
||||
private const int MaxMoveCount = 4;
|
||||
|
||||
// Skip lines that are too short or too long.
|
||||
// Longest line is ~74 (Gen2 EVs)
|
||||
// Length permitted: 3-80
|
||||
// The shortest Pokémon name in Japanese is "ニ" (Ni) which is the name for the Pokémon, Nidoran♂ (male Nidoran). It has only one letter.
|
||||
// We will handle this 1-2 letter edge case only if the line is the first line of the set, in the rare chance we are importing for a non-English language?
|
||||
private const int MinLength = 3;
|
||||
private const int MaxLength = 80;
|
||||
private static bool IsLengthOutOfRange(ReadOnlySpan<char> trim) => (uint)(trim.Length - MinLength) > MaxLength + MinLength;
|
||||
|
||||
private void ParseLines(SpanLineEnumerator lines)
|
||||
{
|
||||
int movectr = 0;
|
||||
|
@ -146,8 +155,15 @@ public sealed class ShowdownSet : IBattleTemplate
|
|||
foreach (var line in lines)
|
||||
{
|
||||
ReadOnlySpan<char> trim = line.Trim();
|
||||
if (trim.Length is <= 2 or >= 40)
|
||||
if (IsLengthOutOfRange(trim))
|
||||
{
|
||||
// Try for other languages just in case.
|
||||
if (first && trim.Length != 0)
|
||||
{
|
||||
ParseFirstLine(trim);
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
InvalidLines.Add(line.ToString());
|
||||
continue;
|
||||
}
|
||||
|
@ -170,8 +186,15 @@ public sealed class ShowdownSet : IBattleTemplate
|
|||
foreach (var line in lines)
|
||||
{
|
||||
ReadOnlySpan<char> trim = line.Trim();
|
||||
if (trim.Length is <= 2 or >= 40)
|
||||
if (IsLengthOutOfRange(trim))
|
||||
{
|
||||
// Try for other languages just in case.
|
||||
if (first && trim.Length != 0)
|
||||
{
|
||||
ParseFirstLine(trim);
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
InvalidLines.Add(line);
|
||||
continue;
|
||||
}
|
||||
|
@ -680,7 +703,8 @@ public sealed class ShowdownSet : IBattleTemplate
|
|||
Span<char> type = stackalloc char[moveString.Length - hiddenPowerName.Length];
|
||||
moveString[hiddenPowerName.Length..].CopyTo(type);
|
||||
RemoveAll(ref type, ParenJunk); // Trim out excess data
|
||||
int hpVal = StringUtil.FindIndexIgnoreCase(Strings.types, type) - 1; // Get HP Type
|
||||
type = type.Trim();
|
||||
int hpVal = StringUtil.FindIndexIgnoreCase(Strings.types.AsSpan(1), type); // Get HP Type
|
||||
|
||||
HiddenPowerType = hpVal;
|
||||
if (!Array.TrueForAll(IVs, z => z == 31))
|
||||
|
|
|
@ -127,6 +127,7 @@ public static class Breeding
|
|||
(int)Pikachu or (int)Eevee => false, // can't get these forms as egg
|
||||
(int)Pichu => false, // can't get Spiky Ear Pichu eggs
|
||||
(int)Floette when form == 5 => false, // can't get Eternal Flower from egg
|
||||
(int)Greninja when form == 1 => false, // can't get Battle Bond Greninja from egg
|
||||
(int)Sinistea or (int)Polteageist => false, // can't get Antique eggs
|
||||
_ => true,
|
||||
};
|
||||
|
|
|
@ -208,7 +208,7 @@ public sealed class MiscVerifier : Verifier
|
|||
(int)Species.Sliggoo | (1 << 11), // Sliggoo-1
|
||||
(int)Species.Avalugg | (1 << 11), // Avalugg-1
|
||||
(int)Species.Decidueye | (1 << 11), // Decidueye-1
|
||||
|
||||
|
||||
(int)Species.Wyrdeer,
|
||||
(int)Species.Kleavor,
|
||||
(int)Species.Ursaluna,
|
||||
|
|
|
@ -163,31 +163,27 @@ public sealed class PK8 : G8PKM
|
|||
|
||||
public void SanitizeImport()
|
||||
{
|
||||
// BDSP->SWSH: Set the Met Location to the magic Location, set the Egg Location to 0 if -1, otherwise BDSPEgg (0 is a valid location, but no eggs can be EggMet there -- only hatched.)
|
||||
// PLA->SWSH: Set the Met Location to the magic Location, set the Egg Location to 0 (no eggs in game).
|
||||
var ver = Version;
|
||||
if (ver is (int)GameVersion.SP)
|
||||
{
|
||||
Met_Location = Locations.HOME_SHSP;
|
||||
Version = (int)GameVersion.SH;
|
||||
if (Egg_Location != 0)
|
||||
Egg_Location = Locations.HOME_SHSP;
|
||||
Met_Location = Locations.HOME_SHSP;
|
||||
Egg_Location = Egg_Location == Locations.Default8bNone ? 0 : Locations.HOME_SWSHBDSPEgg;
|
||||
}
|
||||
else if (ver is (int)GameVersion.BD)
|
||||
{
|
||||
Met_Location = Locations.HOME_SWBD;
|
||||
Version = (int)GameVersion.SW;
|
||||
if (Egg_Location != 0)
|
||||
Egg_Location = Locations.HOME_SWBD;
|
||||
Met_Location = Locations.HOME_SWBD;
|
||||
Egg_Location = Egg_Location == Locations.Default8bNone ? 0 : Locations.HOME_SWSHBDSPEgg;
|
||||
}
|
||||
else if (ver is (int)GameVersion.PLA)
|
||||
{
|
||||
Met_Location = Locations.HOME_SWLA;
|
||||
const ushort met = Locations.HOME_SWLA;
|
||||
Version = (int)GameVersion.SW;
|
||||
if (Egg_Location != 0)
|
||||
Egg_Location = Locations.HOME_SWLA;
|
||||
}
|
||||
else if (ver > (int)GameVersion.PLA)
|
||||
{
|
||||
Met_Location = Met_Location <= Locations.HOME_SWLA ? Locations.HOME_SWLA : Locations.HOME_SWSHBDSPEgg;
|
||||
Met_Location = met;
|
||||
Egg_Location = 0; // Everything originating from this game has an Egg Location of 0.
|
||||
}
|
||||
|
||||
if (Ball > (int)Core.Ball.Beast)
|
||||
|
|
|
@ -42,7 +42,7 @@ public class LegalityRejuvenator : IEntityRejuvenator
|
|||
// No egg encounters. Always not-egg.
|
||||
{
|
||||
result.Met_Location = enc.Location;
|
||||
result.Egg_Location = Locations.Default8bNone;
|
||||
result.Egg_Location = 0;
|
||||
}
|
||||
|
||||
// Try again with rectified locations.
|
||||
|
|
|
@ -73,7 +73,7 @@ public sealed class PersonalInfo6AO : PersonalInfo, IPersonalAbility12H, IPerson
|
|||
private const int CountTMHM = CountTM + CountHM;
|
||||
private const int ByteCountTM = (CountTMHM + 7) / 8;
|
||||
private const int TypeTutor = 0x38;
|
||||
private const int TypeTutorCount = 7;
|
||||
private const int TypeTutorCount = 8;
|
||||
|
||||
public bool GetIsLearnTM(int index)
|
||||
{
|
||||
|
|
|
@ -78,7 +78,7 @@ public sealed class PersonalInfo7 : PersonalInfo, IPersonalAbility12H, IPersonal
|
|||
private const int CountTMHM = CountTM + CountHM;
|
||||
private const int ByteCountTM = (CountTMHM + 7) / 8;
|
||||
private const int TypeTutor = 0x38;
|
||||
private const int TypeTutorCount = 7;
|
||||
private const int TypeTutorCount = 8;
|
||||
|
||||
public bool GetIsLearnTM(int index)
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@ public static class StringUtil
|
|||
/// <param name="arr">Array of strings to search in</param>
|
||||
/// <param name="value">Value to search for</param>
|
||||
/// <returns>Index within <see cref="arr"/></returns>
|
||||
public static int FindIndexIgnoreCase(string[] arr, ReadOnlySpan<char> value)
|
||||
public static int FindIndexIgnoreCase(ReadOnlySpan<string> arr, ReadOnlySpan<char> value)
|
||||
{
|
||||
for (int i = 0; i < arr.Length; i++)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue