Commit graph

94 commits

Author SHA1 Message Date
Kurt
d47bb1d297
Update .NET Runtime to .NET 8.0 (#4082)
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.
2023-12-03 20:13:20 -08:00
Kurt
fd02b97ce1 Misc tweaks
Allow nickname->species with span
add ConstantExpected annotations
Correct Gen8b ability set calling CommonEdits instead of direct setter
Slightly better perf on gen5/gen8+ location fetch
Misc pkm ctor fixes for b2w2 trade & wc3 eggs
wurmple evo now has an enum to be more explicit
no recursion for gen5 generator
fix showdown line length check allowing 86 instead of 80
2023-08-27 23:05:50 -07:00
Kurt
f632aedd15
Encounter Templates: Searching and Creating (#3955)
We implement simple state machine iterators to iterate through every split type encounter array, and more finely control the path we iterate through. And, by using generics, we can have the compiler generate optimized code to avoid virtual calls.

In addition to this, we shift away from the big-5 encounter types and not inherit from an abstract class. This allows for creating a PK* of a specific type and directly writing properties (no virtual calls). Plus we can now fine-tune each encounter type to call specific code, and not have to worry about future game encounter types bothering the generation routines.
2023-08-12 16:01:16 -07:00
Kurt
dcc0e79435
Evotree: Evolution Traversal Enhancements (#3936)
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.
2023-07-05 21:14:09 -07:00
Kurt
5bdc6b9ef8
Privatize some static fields, more robust legal helper classes. (#3865)
* 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.
2023-04-20 21:23:15 -07:00
Kurt
88830e0d00
Update from .NET Framework 4.6 to .NET 7 (#3729)
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)
2023-01-21 20:02:33 -08:00
Kurt
b29d9a65e1 Allow static encounter deerling form change match
Closes #3678
2022-12-07 23:28:47 -08:00
Kurt
7cbde296f8 Make GameVersion a byte enum 2022-09-24 19:23:23 -07:00
Kurt
3c232505e5
Refactoring: Narrow some value types (Species, Move, Form) (#3575)
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".
2022-08-26 23:43:36 -07:00
Kurt
6441bdadd8
Add specialized struct for Moveset and IV specs (#3572)
`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.
2022-08-21 17:34:32 -07:00
Kurt
9166d0eb64
Refactoring: Move Source (Legality) (#3560)
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
2022-08-03 16:15:27 -07:00
Kurt
fc754b346b
File scoped namespaces (#3529)
[Language Reference](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-10.0/file-scoped-namespaces)

Updates all the files, one less level of indentation.

Some small changes were made to API surfaces, renaming `PKM pkm` -> `PKM pk`, and `LegalityAnalysis.pkm` -> `LegalityAnalysis.Entity`
2022-06-18 11:04:24 -07:00
Kurt
436588eb10 Replace é->e for code symbols
Closes #3519
Usages weren't consistent; since `é` isn't accessible on usual english keyboards, just use regular `e` instead of alt-223 entry.

Not sure why VS preferred to save the text files without an encoding prefix; oh well.
2022-06-11 15:32:12 -07:00
Kurt
ccf87242c1 Eliminate boxing on encounter search (criteria)
struct implementing interface is boxed when passed to method that accepts interface (not generic method).
Removes IDexLevel (no other inheritors but EvoCriteria) and uses the primitive the data is stored (array, not IReadOnlyList) for slightly better perf.
2022-05-07 18:29:36 -07:00
Kurt
9deafa851a
Create initial movesets for Alpha entities correctly, verify initial mastery (#3489)
* Draft checks for encounter slot mastery

* Check encounter mastery flags

* Add moves for LA static encounters that don't follow learnset

* Add moves on crossover LA static encounters

* add alpha moveset population method

Now generates and applies moves as the game does
Updates some handling of other methods to use Span

* Show better message for bad mastery init flags

* Insert descending if candidates have same level

Level 78 Yanmega:
- [01] [10] Quick Attack
- [06] [15] Gust
- [11] [20] Silver Wind
- [18] [28] Hypnosis
- [25] [35] Air Slash
- [34] [45] Ancient Power
- [43] [54] Crunch
- [43] [54] Bug Buzz

Yields:
AlphaMove
Crunch*
Bug Buzz*
Ancient Power

* Descending order due to iteration

Co-authored-by: Lusamine <30205550+Lusamine@users.noreply.github.com>
2022-05-06 15:43:23 -07:00
Kurt
ef3cb34387
Refactor EvoCriteria to be a struct, reduce allocation (#3483)
* Make EvolutionCriteria struct

8 bytes per object instead of 26
Unify LevelMin/LevelMax to match EncounterTemplate
bubble up precise array type for better iteration

* Inline queue operations, less allocation

* Inline some logic

* Update EvolutionChain.cs

* Improve clarity on duplicate move check

* Search reverse

For a dual stage chain, finds it first iteration rather than second.
2022-04-23 21:33:17 -07:00
Kurt
d5ae6764aa Stackalloc IVs for template->pkm fill 2022-03-13 19:24:08 -07:00
Kurt
93255efcb8 Disassociate Shiny enum from WC6 PIDType (#3461)
Have `Shiny.Random` be `0`, so we can skip init on this field for EncounterStatic. Plus makes it a little less brittle for future expansion if shiny qualities change.
2022-03-12 17:38:59 -08:00
Kurt
4e1276a954 -8 bytes from each encounter template
saves about ~1MB RAM savings (>=179,142 objects)
2022-03-06 23:25:47 -08:00
Kurt
9cde291595
Enumerate ability permissions in encounter templates, misc updates (#3368) 2022-01-08 22:34:04 -08:00
Kurt
f83a9bf833 Expose shiny potential value
Not really digging it currently as it doesn't cover multi-state like AlwaysStar-Or-Never, but that single edge case can be handled elsewhere
2022-01-07 17:48:12 -08:00
Kurt
51c75dd102 Explicitly implement IFixedAbilityNumber on all templates 2021-12-09 00:46:59 -08:00
Kurt
f55c5bea66 Minor clean
no functional change
2021-12-04 17:56:56 -08:00
Kurt
d4b20b8082 Add nickname checks for WC3, add non-english ageto/colo
Closes #3260

Co-Authored-By: FeralFalcon <33670476+FeralFalcon@users.noreply.github.com>
2021-09-30 19:57:52 -07:00
Kurt
ca35623124 Remove phantom invisible character, fix de mattle ho-oh
#3260 part 1

I searched for more instances of the phantom character, and found the one instance in gen7 zh flags :D

Co-Authored-By: FeralFalcon <33670476+FeralFalcon@users.noreply.github.com>
2021-09-30 19:29:22 -07:00
Kurt
bedc52943e Trailing commas
No functional change
2021-08-20 13:49:20 -07:00
Kurt
138501da2f Minor clean
Condense some expressions
Use less linq
Rename some fields
2021-05-29 15:31:47 -07:00
Kurt
c7b997865c Minor clean 2021-04-09 14:52:49 -07:00
Kurt
6d41d6a17c Fix casting issue for mystry seed fetch
rand32 -> int32 can yield negative, when modulo'd can be negative (bad index)
2021-02-01 10:53:40 -08:00
Kurt
1e86fdcea8
Fracture the encounter matching checks to allow progressive validation (#3137)
## Issue

We want to discard-but-remember any slots that aren't a perfect fit, on the off chance that a better one exists later in the search space. If there's no better match, then we gotta go with what we got.

## Example:
Wurmple exists in area `X`, and also has a more rare slot for Silcoon, with the same level for both slots. 
* We have a Silcoon that we've leveled up a few times.

Was our Silcoon originally a Wurmple, or was it caught as a Silcoon? 
* To be sure, we have to check the EC/PID if the Wurmple wouldn't evolve into Cascoon instead.
* We don't want to wholly reject that Wurmple slot, as maybe the Met Level isn't within Silcoon's slot range.

---

Existing implementation would store "deferred" matches in a list; we only need to keep 1 of these matches around (less allocation!). We also want to differentiate between a "good" deferral and a "bad" deferral; I don't think this is necessary but it's currently used by Mystery Gift matching (implemented for the Eeveelution mystery gifts which matter for evolution moves).

The existing logic didn't use inheritance, and instead had static methods being reused across generations. Quite kludgy. Also, the existing logic was a pain to modify the master encounter yield methods, as one generation's quirks had to not impact all other generations that used the method.

---

The new implementation splits out the encounter yielding methods to be separate for each generation / subset. Now, things don't have to check `WasLink` for Gen7 origin, because Pokémon Link wasn't a thing in Gen7.

---

## Future
Maybe refactoring yielders into "GameCores" that expose yielding behaviors / properties, rather than the static logic. As more generations and side-gamegroups get added (thanks LGPE/GO/GameCube), all this switch stuff gets annoying to maintain instead of just overriding/inheritance.

## Conclusion

This shouldn't impact any legality results negatively; if you notice any regressions, report them! This should reduce false flags where we didn't defer-discard an encounter when we should have (wild area mons being confused with raids).
2021-01-29 17:55:27 -08:00
Kurt
c9f222bf38 Set valid mystry mew seed on creation
Uses a Method specific seed regardless of template.
2021-01-07 21:27:19 -08:00
Kurt
09089da14e Use more expression return style
Reduces indentation & bracketing, a bit more concise
2021-01-01 17:08:49 -08:00
Kurt
afdd2bd57e Mark EncounterSlot/Static types as immutable record types 2020-12-23 20:40:59 -08:00
Kurt
93910df2c6 Use new switch statements 2020-12-23 17:14:38 -08:00
Kurt
98be0f6739 Target type'd new 2020-12-21 17:17:56 -08:00
Kurt
62018cce1a Unify concepts with different names
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.
2020-12-10 20:42:30 -08:00
Kurt
51c872f4e1 Move more logic closer to where it's used 2020-11-02 14:46:26 -08:00
Kurt
d13b893351 Use PKHeX as blanksav language
Closes #3009

Make QRPK7 implement IEncounterable and remove hardcoded PKHeX strings
Let force hatching for WC3 eggs try to hatch from the savefile's language, then revert to english if failed to set an OT.
2020-10-04 08:59:33 -07:00
Kurt
e125424423 Refine zygarde encounter form checking logic
Closes #2984
ty atrius & matt via discord

Co-Authored-By: Atrius97 <39707481+Atrius97@users.noreply.github.com>
Co-Authored-By: Matt <17801814+sora10pls@users.noreply.github.com>
2020-09-13 15:45:15 -07:00
Kurt
a62324a5a1
Refactoring some IEncounterable-type'd object initialization and original-generation evo chain (#2974) 2020-08-21 16:35:49 -07:00
Kurt
8fae396b76 Inject matching dexlevel for form comparison 2020-07-18 13:29:16 -05:00
Kurt
4b881e7021
Update WC3.cs
Handle "RSE" as specified permitted version
2020-07-17 12:56:35 -05:00
Kurt
645db23706 Extract EvoBase and MoveList from Core
These are really old bloated parts of the original legality checking logic; separating for now to rewrite.
2020-06-20 19:44:05 -05:00
Kurt
2cdb5d26db Clean up some method signatures
rename things to be a little more consistent in naming conventions
2020-06-16 21:46:22 -05:00
Kurt
301350d32b Make IEncounterable expose IVersion get 2020-05-19 21:07:30 -07:00
Kurt
c4ce22412a Handle japanese name if egg
Closes #2756

For eggs that we don't know the OT of, they'll still show invalid (empty string).
ty @PrometheusG !
2020-03-13 18:37:51 -07:00
Kurt
bdf6afd2f3 Fix egg trainer name logic for wc3
Closes #2676
2020-02-03 19:22:16 -08:00
Kurt
5be9c6bcc8 Remove unnecessary null handling
objects are no longer null
2020-01-20 23:32:05 -08:00
Kurt
8312c52cc1 Make Move[] readonly list
contract: don't modify the template movesets
mystery gift now exposes IRelearn, remove unnecessary type checks
2020-01-18 16:46:38 -08:00
Kurt
bfd9bf6b53 Simplify formchange calls
Don't use the dex chain for certain checks, it's unnecessary.
2019-12-28 19:00:01 -08:00