Commit graph

21 commits

Author SHA1 Message Date
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
5bcccc6d92
HOME 2.0.0: Handle conversion behavior & restrictions (#3506)
* Revises legality checks to account for traveling between the three game islands (PLA/BDSP/SWSH)
* Adds conversion mechanisms between the three formats, as well as flexible conversion options to backfill missing data (thanks GameFreak/ILCA for opting for lossy conversion instead of updating the games).
* Adds API abstractions for HOME data storage format (EKH/PKH format 1, aka EH1/PH1).
* Revises some APIs for better usage:
  - `PKM` now exposes a `Context` to indicate the isolation context for legality purposes.
  - Some method signatures have changed to accept `Context` or `GameVersion` instead of a vague `int` for Generation.
  - Evolution History is now tracked in the Legality parse for specific contexts, rather than only per generation.
2022-05-30 21:43:52 -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
e8903505df Min move count: ignore purchased moves 2022-02-05 16:47:19 -08:00
Kurt
0b32cbf132 Update PKHeX.Core abstractions with latest logic
Co-Authored-By: Matt <17801814+sora10pls@users.noreply.github.com>
Co-Authored-By: SciresM <8676005+SciresM@users.noreply.github.com>
Co-Authored-By: Lusamine <30205550+Lusamine@users.noreply.github.com>
2022-02-04 17:35:15 -08:00
Kurt
0626b0c29b
Add Breeding move ordering logic, and use in legality analysis (#3183)
* Initial bred moveset validation logic

Unpeel the inheritance via recursion and permitted moves

* Volt tackle considerations

* Optimize out empty slot skips

* Add tests, fix off-by-one's

* Require all base moves if empty slot in moveset

* Add test to prove failure per Anubis' provided test

* Tweak enum labels for easier debugging

When two enums share the same underlying value, the ToString/name of the value may be either of the two (or the last defined one, in my debugging). Just give it a separate magic value.

* Fix recursion oopsie

Also check for scenario where no-base-moves but not enough moves to push base moves out

* Add Crystal tutor checks

* Add specialized gen2 verification method

Game loops through father's moves and pushes in one iteration, rather than checking by type.

* Add another case with returning base move

* Add push-out requirement for re-added base moves

* Minor tweaks

Condense tests, fix another off-by-one noticed when creating tests

* Disallow inherited parent levelup moves

Disallow volt tackle on Gen2/R/S

* Split MoveBreed into generation specific classes

Gen2 behaves slightly different from Gen3/4, which behaves slightly different from Gen5... and Gen6 behaves differently too.

Add some xmldoc as the api is starting to solidify

* Add method overload that returns the parse

Verify that the parse order is as expected

* Add reordering suggestion logic

Try sorting first, then go nuclear with rebuilding.

* Return base moves if complete fail

* Set base moves when generating eggs, only.

* Use breed logic to check for egg ordering legality

Don't bother helping for split-breed species
2021-04-04 18:30:01 -07:00
Kurt
0c1d13bf4d Minor tweaks
Lift some temporary arrays for more reuse
reuse some temp references
less allocation overall
2021-03-23 23:10:30 -07:00
Kurt
02420d3e93
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases

Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization

* Handle bits more obviously without null

* Make SaveFile.BAK explicitly readonly again

* merge constructor methods to have readonly fields

* Inline some properties

* More nullable handling

* Rearrange box actions

define straightforward classes to not have any null properties

* Make extrabyte reference array immutable

* Move tooltip creation to designer

* Rearrange some logic to reduce nesting

* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum

* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case

* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable

* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator

* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever

* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)

* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-16 18:47:31 -07:00
Kurt
30e36579be Misc updates
add more xmldoc
revise some comments for clarity
redo a little bit of logic for perf
rename some methods for better description
2019-02-24 13:57:10 -08:00
Kurt
f4bfdb8311 Remove unnecessary empty array allocations
yay net 4.6
read more: http://justinvp.com/2015/07/20/array-empty/
2018-08-01 18:30:51 -07:00
Kurt
4b0a2d90b9 Add xmldoc 2018-07-20 20:22:46 -07:00
Kurt
5579c4c80d Tidy up MoveLevelUp
use the Learn objects from prior commits for adding a range of moves
2018-06-13 22:03:58 -07:00
Kurt
39daa6c65d Split GetIsLevelUp to individual versions
static the GameVersion reference as we're excessively using it in the
switch cases, for clearer reading
2018-06-12 22:15:06 -07:00
Kurt
64a64b8ce1 Add special handling for gen1 encounter move fetch
Begin splitting of GetMovesLevelUp per-gen into per-version
2018-06-12 18:35:56 -07:00
Kurt
9b43677bb9 Refactoring
pull out some move data fetching to separate class
add methods to quickly fetch if the move is learnable via that method

eventual plan is this:
replace
'fetch all possible moves then look within' move validation
with:
'peek if learnable, and get info how' move validation

advantages:
- returns game the move was learned in and the level (if appropriate)
- infinitely less object creation (garbage collection)
- only looks for a given move, doesn't have to fetch everything before
checking
- faster than full fetch, can be made even faster by optimizing lookups.

subject to change :)
2018-06-08 20:10:41 -07:00
Kurt
b1cd68e3f3 Convert GetLevelLearnMove to use lazy dictionary
faster move lookup
2018-06-07 19:05:28 -07:00
Kurt
452ffe2369 Refactoring
relocate location of stuff
2018-03-08 21:18:32 -08:00
Kurt
cbf4038a95 Refactoring
relocate gift data storage out of legal.cs
2018-03-05 22:19:56 -08:00
Kurt
21cdf4f642 Reorganization
wonder if it's possible to provide a more lightweight core by pulling
out legality stuff to a separate project?
2018-03-05 20:49:45 -08:00
Renamed from PKHeX.Core/Legality/Structures/Learnset.cs (Browse further)