Minor tweaks, add Gigantamax info class

This commit is contained in:
Kurt 2023-11-08 23:32:41 -08:00
parent 5ce9619690
commit 3df5478d11
9 changed files with 108 additions and 133 deletions

View file

@ -23,7 +23,7 @@ public static class BoxManipDefaults
new BoxManipSort(SortFavorite, list => list.OrderByCustom(pk => pk is IFavorite {IsFavorite: true}), s => s.BlankPKM is IFavorite),
new BoxManipSortComplex(SortParty, (list, sav, start) => list.BubbleUp(sav, i => ((SAV7b)sav).Blocks.Storage.IsParty(i), start), s => s is SAV7b),
new BoxManipSort(SortShiny, list => list.OrderByCustom(pk => !pk.IsShiny)),
new BoxManipSort(SortRandom, list => list.OrderByCustom(_ => Util.Rand32())),
new BoxManipSort(SortRandom, list => list.OrderByCustom(_ => Util.Rand.Next())),
};
/// <summary>

View file

@ -211,7 +211,7 @@ public abstract record EncounterStatic8Nest<T>(GameVersion Version)
protected bool IsMatchPartial(PKM pk)
{
if (pk is PK8 and IGigantamax g && g.CanGigantamax != CanGigantamax && !g.CanToggleGigantamax(pk.Species, pk.Form, Species, Form))
if (pk is PK8 and IGigantamax g && g.CanGigantamax != CanGigantamax && !Gigantamax.CanToggle(pk.Species, pk.Form, Species, Form))
return true;
if (Species == (int)Core.Species.Alcremie && pk is IFormArgument { FormArgument: not 0 })
return true;

View file

@ -702,7 +702,7 @@ public sealed class MiscVerifier : Verifier
bool originGMax = enc is IGigantamaxReadOnly {CanGigantamax: true};
if (originGMax != pk8.CanGigantamax)
{
bool ok = !pk8.IsEgg && pk8.CanToggleGigantamax(pk8.Species, pk8.Form, enc.Species, enc.Form);
bool ok = !pk8.IsEgg && Gigantamax.CanToggle(pk8.Species, pk8.Form, enc.Species, enc.Form);
var chk = ok ? GetValid(LStatGigantamaxValid) : GetInvalid(LStatGigantamaxInvalid);
data.AddLine(chk);
}

View file

@ -726,7 +726,7 @@ public sealed class WC8 : DataMysteryGift, ILangNick, INature, IGigantamax, IDyn
if (Nature != -1 && pk.Nature != Nature) return false;
if (Gender != 3 && Gender != pk.Gender) return false;
if (pk is PK8 and IGigantamax g && g.CanGigantamax != CanGigantamax && !g.CanToggleGigantamax(pk.Species, pk.Form, Species, Form))
if (pk is PK8 and IGigantamax g && g.CanGigantamax != CanGigantamax && !Gigantamax.CanToggle(pk.Species, pk.Form, Species, Form))
return false;
if (pk is PK8 pk8 && pk8.DynamaxLevel < DynamaxLevel)

View file

@ -1,4 +1,4 @@
using System.Collections.Generic;
using static PKHeX.Core.Species;
namespace PKHeX.Core;
@ -14,75 +14,78 @@ public interface IGigantamaxReadOnly
}
/// <summary>
/// Extension methods for <see cref="IGigantamaxReadOnly"/>.
/// Permission checks for Gigantamax.
/// </summary>
public static class GigantamaxExtensions
public static class Gigantamax
{
/// <summary>
/// Checks if either of the input Species can consume the Gigantamax soup, toggling the <see cref="IGigantamax.CanGigantamax"/> flag.
/// </summary>
/// <param name="_">Unnecessary, just needed for extension method usage.</param>
/// <param name="currentSpecies">The current species</param>
/// <param name="currentForm">The current form of the species</param>
/// <param name="originSpecies">The original species (what species it was encountered as)</param>
/// <param name="originForm">The original form of the original species</param>
/// <returns>True if either species can toggle Gigantamax potential</returns>
public static bool CanToggleGigantamax(this IGigantamaxReadOnly _, ushort currentSpecies, byte currentForm, ushort originSpecies, byte originForm)
public static bool CanToggle(ushort currentSpecies, byte currentForm, ushort originSpecies, byte originForm)
{
if (currentSpecies is (int)Species.Meowth or (int)Species.Pikachu)
if (currentSpecies is (int)Meowth or (int)Pikachu)
return currentForm == 0;
var soup = CanEatMaxSoup;
return soup.Contains(currentSpecies) || (currentSpecies != originSpecies && soup.Contains(originSpecies));
return CanToggle(currentSpecies) || (currentSpecies != originSpecies && CanToggle(originSpecies));
}
/// <summary>
/// Don't use this method. Use the other overload with multi-species input.
/// Checks if the input Species can consume the Gigantamax soup, toggling the <see cref="IGigantamax.CanGigantamax"/> flag.
/// </summary>
/// <param name="_">Unnecessary, just needed for extension method usage.</param>
/// <param name="currentSpecies">The current species</param>
/// <param name="currentForm">The current form of the species</param>
/// <param name="species">The current species</param>
/// <param name="form">The current form of the species</param>
/// <returns>True if the species can toggle Gigantamax potential</returns>
public static bool CanToggleGigantamax(this IGigantamaxReadOnly _, ushort currentSpecies, byte currentForm)
public static bool CanToggle(ushort species, byte form)
{
if (currentSpecies is (int)Species.Meowth or (int)Species.Pikachu)
return currentForm == 0;
var soup = CanEatMaxSoup;
return soup.Contains(currentSpecies);
if (species is (int)Meowth or (int)Pikachu)
return form == 0;
return CanToggle(species);
}
private static readonly HashSet<ushort> CanEatMaxSoup = new()
/// <summary>
/// Checks if the input Species can consume the Gigantamax soup, toggling the <see cref="IGigantamax.CanGigantamax"/> flag.
/// </summary>
/// <param name="species">The current species</param>
/// <remarks>General case, includes Pikachu and Meowth which require Form == 0.</remarks>
public static bool CanToggle(ushort species) => species switch
{
(int)Species.Venusaur,
(int)Species.Charizard,
(int)Species.Blastoise,
(int)Species.Butterfree,
(int)Species.Pikachu,
(int)Species.Meowth,
(int)Species.Machamp,
(int)Species.Gengar,
(int)Species.Lapras,
(int)Species.Eevee,
(int)Species.Snorlax,
(int)Species.Garbodor,
(int)Species.Rillaboom,
(int)Species.Cinderace,
(int)Species.Inteleon,
(int)Species.Drednaw,
(int)Species.Corviknight,
(int)Species.Toxtricity,
(int)Species.Alcremie,
(int)Species.Duraludon,
(int)Species.Orbeetle,
(int)Species.Coalossal,
(int)Species.Sandaconda,
(int)Species.Grimmsnarl,
(int)Species.Flapple,
(int)Species.Appletun,
(int)Species.Hatterene,
(int)Species.Copperajah,
(int)Species.Kingler,
(int)Species.Centiskorch,
(int)Species.Urshifu,
(ushort)Venusaur => true,
(ushort)Charizard => true,
(ushort)Blastoise => true,
(ushort)Butterfree => true,
(ushort)Pikachu => true,
(ushort)Meowth => true,
(ushort)Machamp => true,
(ushort)Gengar => true,
(ushort)Kingler => true,
(ushort)Lapras => true,
(ushort)Eevee => true,
(ushort)Snorlax => true,
(ushort)Garbodor => true,
(ushort)Rillaboom => true, // DLC 1
(ushort)Cinderace => true, // DLC 1
(ushort)Inteleon => true, // DLC 1
(ushort)Corviknight => true,
(ushort)Orbeetle => true,
(ushort)Drednaw => true,
(ushort)Coalossal => true,
(ushort)Flapple => true,
(ushort)Appletun => true,
(ushort)Sandaconda => true,
(ushort)Toxtricity => true,
(ushort)Centiskorch => true,
(ushort)Hatterene => true,
(ushort)Grimmsnarl => true,
(ushort)Alcremie => true,
(ushort)Copperajah => true,
(ushort)Duraludon => true,
(ushort)Urshifu => true, // DLC 1
_ => false,
};
}

View file

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using static System.Buffers.Binary.BinaryPrimitives;
@ -36,19 +35,12 @@ public sealed class SAV3GCMemoryCard
private const int DENTRY_SIZE = 0x40;
private const int NumEntries_Directory = BLOCK_SIZE / DENTRY_SIZE;
private static readonly HashSet<int> ValidMemoryCardSizes = new()
public static bool IsMemoryCardSize(long size)
{
0x0080000, // 512KB 59 Blocks Memory Card
0x0100000, // 1MB
0x0200000, // 2MB
0x0400000, // 4MB 251 Blocks Memory Card
0x0800000, // 8MB
0x1000000, // 16MB 1019 Blocks Default Dolphin Memory Card
0x2000000, // 64MB
0x4000000, // 128MB
};
public static bool IsMemoryCardSize(long size) => ValidMemoryCardSizes.Contains((int)size);
if ((size & 0x7F8_0000) == 0) // 512KB - 64MB
return false;
return (size & (size - 1)) == 0; // size is a power of 2
}
public static bool IsMemoryCardSize(ReadOnlySpan<byte> Data)
{
@ -77,11 +69,15 @@ public sealed class SAV3GCMemoryCard
// Checksums
private (ushort Checksum, ushort Inverse) GetChecksum(int block, int offset, [ConstantExpected(Min = 0)] int length)
{
ushort csum = 0;
ushort inv_csum = 0;
var ofs = (block * BLOCK_SIZE) + offset;
var span = Data.AsSpan(ofs, length);
return GetChecksum(span);
}
private static (ushort Checksum, ushort Inverse) GetChecksum(ReadOnlySpan<byte> span)
{
ushort csum = 0;
ushort inv_csum = 0;
for (int i = 0; i < span.Length; i += 2)
{
@ -319,11 +315,17 @@ public sealed class SAV3GCMemoryCard
private string GCISaveGameName()
{
int offset = (DirectoryBlock_Used * BLOCK_SIZE) + (EntrySelected * DENTRY_SIZE);
string GameCode = EncodingType.GetString(Data, offset, 4);
string Makercode = EncodingType.GetString(Data, offset + 0x04, 2);
var span = Data.AsSpan(offset, DENTRY_SIZE);
return GetSaveName(EncodingType, span);
}
private static string GetSaveName(Encoding encoding, ReadOnlySpan<byte> data)
{
string GameCode = encoding.GetString(data[..4]);
string Makercode = encoding.GetString(data.Slice(4, 2));
Span<char> FileName = stackalloc char[DENTRY_STRLEN];
EncodingType.GetString(Data.AsSpan(offset + 0x08, DENTRY_STRLEN));
encoding.GetString(data.Slice(0x08, DENTRY_STRLEN));
var zero = FileName.IndexOf('\0');
if (zero >= 0)
FileName = FileName[..zero];

View file

@ -646,7 +646,7 @@ public sealed class Zukan8 : ZukanBase<SAV8SWSH>
SeenAll(species, i, value, pi, shinyToo);
}
if (SpeciesWithGigantamaxData.Contains(species))
if (IsGigantamaxFormStored(species))
{
SeenAll(species, 63, value, pi, shinyToo);
if (species == (int)Species.Urshifu)
@ -687,41 +687,10 @@ public sealed class Zukan8 : ZukanBase<SAV8SWSH>
}
}
private static readonly HashSet<ushort> SpeciesWithGigantamaxData = new()
public static bool IsGigantamaxFormStored(ushort species)
{
(int)Species.Charizard,
(int)Species.Butterfree,
(int)Species.Pikachu,
(int)Species.Meowth,
(int)Species.Machamp,
(int)Species.Gengar,
(int)Species.Kingler,
(int)Species.Lapras,
(int)Species.Eevee,
(int)Species.Snorlax,
(int)Species.Garbodor,
(int)Species.Corviknight,
(int)Species.Orbeetle,
(int)Species.Drednaw,
(int)Species.Coalossal,
(int)Species.Flapple,
(int)Species.Appletun,
(int)Species.Sandaconda,
(int)Species.Toxtricity,
(int)Species.Centiskorch,
(int)Species.Hatterene,
(int)Species.Grimmsnarl,
(int)Species.Alcremie,
(int)Species.Copperajah,
(int)Species.Duraludon,
(int)Species.Eternatus,
// DLC 1
(int)Species.Rillaboom,
(int)Species.Cinderace,
(int)Species.Inteleon,
(int)Species.Urshifu,
};
return Gigantamax.CanToggle(species) || species == (int)Species.Eternatus;
}
#endregion
}

View file

@ -175,12 +175,12 @@ public static partial class Util
return string.Empty;
Span<char> result = stackalloc char[str.Length];
int ctr = GetOnlyHex(str, ref result);
int ctr = GetOnlyHex(str, result);
return new string(result[..ctr]);
}
/// <inheritdoc cref="GetOnlyHex(ReadOnlySpan{char})"/>
public static int GetOnlyHex(ReadOnlySpan<char> str, ref Span<char> result)
public static int GetOnlyHex(ReadOnlySpan<char> str, Span<char> result)
{
int ctr = 0;
foreach (var c in str)

View file

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System;
using System.Text;
using PKHeX.Core;
using static PKHeX.Core.Species;
namespace PKHeX.Drawing.PokeSprite;
@ -33,7 +34,7 @@ public static class SpriteName
{
sb.Append(Separator).Append(form);
if (species == (int) Species.Pikachu)
if (species == (ushort)Pikachu)
{
if (context == EntityContext.Gen6)
{
@ -45,7 +46,7 @@ public static class SpriteName
sb.Append(GGStarter);
}
}
else if (species == (int) Species.Eevee)
else if (species == (ushort)Eevee)
{
if (form == 1)
sb.Append(GGStarter);
@ -56,7 +57,7 @@ public static class SpriteName
sb.Append('f');
}
if (species == (int) Species.Alcremie)
if (species == (ushort)Alcremie)
{
if (form == 0)
sb.Append(Separator).Append(form);
@ -71,32 +72,32 @@ public static class SpriteName
/// <summary>
/// Species that show their default Species sprite regardless of current <see cref="PKM.Form"/>
/// </summary>
private static readonly HashSet<ushort> SpeciesDefaultFormSprite = new()
private static ReadOnlySpan<ushort> SpeciesDefaultFormSprite => new[]
{
(int)Species.Mothim,
(int)Species.Scatterbug,
(int)Species.Spewpa,
(int)Species.Rockruff,
(int)Species.Mimikyu,
(int)Species.Sinistea,
(int)Species.Polteageist,
(int)Species.Urshifu,
(int)Species.Dudunsparce,
(int)Species.Poltchageist,
(int)Species.Sinistcha,
(ushort)Mothim,
(ushort)Scatterbug,
(ushort)Spewpa,
(ushort)Rockruff,
(ushort)Mimikyu,
(ushort)Sinistea,
(ushort)Polteageist,
(ushort)Urshifu,
(ushort)Dudunsparce,
(ushort)Poltchageist,
(ushort)Sinistcha,
};
/// <summary>
/// Species that show a <see cref="PKM.Gender"/> specific Sprite
/// </summary>
private static readonly HashSet<ushort> SpeciesGenderedSprite = new()
private static ReadOnlySpan<ushort> SpeciesGenderedSprite => new[]
{
(int)Species.Pikachu,
(int)Species.Hippopotas,
(int)Species.Hippowdon,
(int)Species.Unfezant,
(int)Species.Frillish,
(int)Species.Jellicent,
(int)Species.Pyroar,
(ushort)Pikachu,
(ushort)Hippopotas,
(ushort)Hippowdon,
(ushort)Unfezant,
(ushort)Frillish,
(ushort)Jellicent,
(ushort)Pyroar,
};
}