With the new version of Visual Studio bringing C# 12, we can revise our logic for better readability as well as use new methods/APIs introduced in the .NET 8.0 BCL.
Hoopa cannot know both moves due to form reversion
Kyurem cannot know both moves due to form reversion
Kyurem cannot know Scary Face when fused in past games
Add dexnav for AtAnyTime/HOME lookback when original moveset deleted (no longer in local relearn moves)
BDSP Underground encounters w/ egg moves can be shared by other means
Relocate checksum adders to Checksums class, improve performance by eliminating slice calls
Improve HOME sharing for GO8 and IMoveset encounters: actually sanity check GO8, and skip other non-PK7/PB7 cases.
* Uses LearnSource more throughout the codebase when appropriate, rather than loosely coupled pivot methods.
* Hides Learnset/EggMove data inside the LearnSource classes.
* Extracts functionality from the large Legal class & partial Table*.cs files into better performing helper classes.
* Cleans up some code from prior LearnSource commits.
Updates from net46->net7, dropping support for mono in favor of using the latest runtime (along with the performance/API improvements). Releases will be posted as 64bit only for now.
Refactors a good amount of internal API methods to be more performant and more customizable for future updates & fixes.
Adds functionality for Batch Editor commands to `>`, `<` and <=/>=
TID/SID properties renamed to TID16/SID16 for clarity; other properties exposed for Gen7 / display variants.
Main window has a new layout to account for DPI scaling (8 point grid)
Fixed: Tatsugiri and Paldean Tauros now output Showdown form names as Showdown expects
Changed: Gen9 species now interact based on the confirmed National Dex IDs (closes#3724)
Fixed: Pokedex set all no longer clears species with unavailable non-base forms (closes#3720)
Changed: Hyper Training suggestions now apply for level 50 in SV. (closes#3714)
Fixed: B2/W2 hatched egg met locations exclusive to specific versions are now explicitly checked (closes#3691)
Added: Properties for ribbon/mark count (closes#3659)
Fixed: Traded SV eggs are now checked correctly (closes#3692)
In this pull request I've changed a ton of method signatures to reflect the more-narrow types of Species, Move# and Form; additionally, I've narrowed other large collections that stored lists of species / permitted values, and reworked them to be more performant with the latest API spaghetti that PKHeX provides. Roamer met locations, usually in a range of [max-min]<64, can be quickly checked using a bitflag operation on a UInt64. Other collections (like "Is this from Colosseum or XD") were eliminated -- shadow state is not transferred COLO<->XD, so having a Shadow ID or matching the met location from a gift/wild encounter is a sufficient check for "originated in XD".
Disallow max moves from Sketch
Hide dmax moves from legal dropdown lists
Pass ushort for moves for validating memories
Internal class for move pp (hide empty class from dll users)
`Moveset` struct stores 4 moves, and exposes methods to interact with a moveset.
`IndividualValueSet` stores a 6 IV template (signed).
Performance impact:
* Less allocating on the heap: Moves - (8 bytes member ptr, 20 bytes heap->8 bytes member)
* Less allocating on the heap: IVs - (8 bytes member ptr, 28 bytes heap->8 bytes member)
* No heap pointers, no need to jump to grab data.
* Easy to inline logic for checking if moves are present (no linq usage with temporary collections).
End result is faster ctor times, less memory used, faster program.
Rewrites a good amount of legality APIs pertaining to:
* Legal moves that can be learned
* Evolution chains & cross-generation paths
* Memory validation with forgotten moves
In generation 8, there are 3 separate contexts an entity can exist in: SW/SH, BD/SP, and LA. Not every entity can cross between them, and not every entity from generation 7 can exist in generation 8 (Gogoat, etc). By creating class models representing the restrictions to cross each boundary, we are able to better track and validate data.
The old implementation of validating moves was greedy: it would iterate for all generations and evolutions, and build a full list of every move that can be learned, storing it on the heap. Now, we check one game group at a time to see if the entity can learn a move that hasn't yet been validated. End result is an algorithm that requires 0 allocation, and a smaller/quicker search space.
The old implementation of storing move parses was inefficient; for each move that was parsed, a new object is created and adjusted depending on the parse. Now, move parse results are `struct` and store the move parse contiguously in memory. End result is faster parsing and 0 memory allocation.
* `PersonalTable` objects have been improved with new API methods to check if a species+form can exist in the game.
* `IEncounterTemplate` objects have been improved to indicate the `EntityContext` they originate in (similar to `Generation`).
* Some APIs have been extended to accept `Span<T>` instead of Array/IEnumerable