Like move validation, evolutions are the earliest thing we wish to traverse when determining what encounters may have originated the current Pokémon. To determine the permitted species-form-levels a Pokémon could originate with, we must devolve a Pokémon by traveling down-generation to origin. Once we have an encounter, we can then evolve it to the current species, traversing upwards from origin to the current format.
Adds a basic editor for recorded Geonet/Unity Tower locations for the Gen 4/5 games, building on this [post by Danius88](https://projectpokemon.org/home/forums/topic/62055-bw-b2w2-unity-tower-geonet-and-passerby-research/).
So far, I've implemented buttons that set all locations (including unused ones), set all legal locations, and clear all recorded locations; and checkboxes to toggle whether the whole globe is visible (used in Japanese games) and whether the ferry to Unity Tower is unlocked.
Haven't implemented any UI for editing the status of individual locations, since I'm not sure how to lay it out.
Also haven't implemented anything related to how the data of the other players in Unity Tower is stored.
* Extract/encapsulate inventory legal arrays to interface+class
Hiding them behind methods allows these to be left as ReadOnlySpan<ushort> and thus never allocate on the heap.
Also refactors out some logic for checking if an item is legal.
End result feels more maintainable and is less bloaty (no more passing in a nullable func)
Batch editing
* Add HasType filter
```
=HasType=11
.HeldItem=Meadow Plate
```
slaps a meadow plate on any pkm with grass type
Use `=PersonalType1=11` for only primary grass types; only-secondary-type grass will not match it.
* Add Geonet location to SAV4 and SAV5
* Allow commas to be escaped in subregion names
* Add missing 3DS subregions
* Add Geonet location editing
* Ensure null values are kept as the first option in GetCountryRegionList
* Add Geonet locations in CHS/CHT
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)
Adds support for Scarlet & Violet.
Co-Authored-By: SciresM <8676005+SciresM@users.noreply.github.com>
Co-Authored-By: Matt <17801814+sora10pls@users.noreply.github.com>
Co-Authored-By: Lusamine <30205550+Lusamine@users.noreply.github.com>
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".
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
net6 was 4x faster than 461 with the old implementation; now it is faster for both but not as disparate.
New implementation performance is always at least 30% better than the old implementation; even better for smaller chunks of data (40% less time).
Pretty much mimics bare metal value writes
Existing `get`/`set` logic is flawed in that it doesn't work on Big Endian operating systems, and it allocates heap objects when it doesn't need to.
`System.Buffers.Binary.BinaryPrimitives` in the `System.Memory` NuGet package provides both Little Endian and Big Endian methods to read and write data; all the `get`/`set` operations have been reworked to use this new API. This removes the need for PKHeX's manual `BigEndian` class, as all functions are already covered by the BinaryPrimitives API.
The `StringConverter` has now been rewritten to accept a Span to read from & write to, no longer requiring a temporary StringBuilder.
Other Fixes included:
- The Super Training UI for Gen6 has been reworked according to the latest block structure additions.
- Cloning a Stadium2 Save File now works correctly (opening from the Folder browser list).
- Checksum & Sanity properties removed from parent PKM class, and is now implemented via interface.
Slap on interface for EntreeSlot
De-magic some 💯 numbers to indicate what they're doing
Improve perf of move-match-relearn check
Add an "else" as valid is never both values (history verifier)
Closes#3231
Symptoms observed:
- Tiles were too dark (not high enough RBG value due to >>3; keep 8bit color here.
- Red/Blue channel inverted, swap R & B. Works? Hope this isn't something related to png storing rgb vs bgr and we'd need to check input pixel format?
- Tiles were misplaced slightly, off by 1. Fix order of operations so that the tile choice value is correct.
AltForm & Form & Forme => Form
GenNumber & Generation => Generation
Extract out SpeciesForm interface, and re-add IGeneration
For those using PKHeX as a dependency, this should be a pretty straightforward manual replacement... GenNumber and AltForm should be quick find-replace`s.