mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-26 14:00:21 +00:00
Minor tweaks, add Gigantamax info class
This commit is contained in:
parent
5ce9619690
commit
3df5478d11
9 changed files with 108 additions and 133 deletions
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue