Switch expression had an issue with interpreting the object's type (unboxing, yay)
should probably just return a typed object from the parse, but nah, this is a quick fix.
This change revises the logic for an Egg Move's RelearnMoves.
Removes a class that is no longer used
Passes the large value-passing struct byref via in keyword
Revises handling so that early-returned results from the MoveBreed processing are marked with their move source rather than leaving them unvisited.
The moveset processor uses depth search recursion, and returns false if the move that it is processing is not possible for the hatched moveset. If the depth search never reaches the check for base moves, all moves won't be marked for their origins, resulting in the result array not being accurate to use for suggestion purposes.
Yay multi-purpose logic (validation w/early returns & fixing needing fully processed data).
Base method checks wurmple (not available in swsh), removed.
Hidden ability check returns Partial for any species that cannot be patched, and Deferred for any patched; we don't care, because there aren't any wild species that can't be patched in swsh.
* 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
* Exploration: rework ability criteria to ability numbers desired
* Sync remaining changes
* Update EncounterCriteria.cs
* Add xmldoc
* Improve speed of IsDualGender check
* More xmldoc updates
Should be doing this on main but meh, this branch is gonna get merged later
* Fix typo
* Update WC7.cs
* Update PersonalInfo.cs
All slots are now initialized via constructor, property can now be init!
Optimize some value fetching for gen7b, as the input data has features that can be abused
Relocate the SetRandomEC at the tail end of the generator into the specific classes that set EC, so that our correlation generators don't have their EC overwritten at the end.
Update dictionary to use proper format (yyyy-mm-dd), as well as verifier to properly check met year.
Also updated IsValidDateWC8 to clamp latest met date based on UTC, like with GO encounters.
Checks partial matches in the loop rather than outside; it'll only settle on the partial match if there's nothing else to settle on.
Gen1/2 generators can have partial matches bubble up before actual matches (gen1 fighting gen2).
I should probably have slot1/2 and static1/2 and trade1/2 implement GetBlank so that they can flexibly return a japanese/int/(kor) from template rather than default int, but eh
The Encounter dumper project already excluded all headbutt tree areas that can't be accessed. Every slot that is present in this project can be accessed.
Move the tree check to the eslot2 object
Check all gen2 slots regardless of crystal origin, since we now tag all of them with location IDs.
## 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).
Closes#3133
not an ideal solution, but the encounter matching API is kinda limited in deferred-invalid vs deferred-notIdeal.
probably need to unify the match logic and generators so they can cache one secondary-check invalid
See the EncounterSlotDumper with the memoization logic & json tree listing.
Simplifies things a lot, and improves checking speed. Unreachable trees are now treated the same as no-trees maps.
ez 1.5KB reduction in file size :P
Remove gen3 egg location hashset; only paths that reach it are for hatched eggs or current breed-eggs. Check breed eggs with the singular met location.
Simplify some logic flow
This only matches the weather table with the Pokemon and does not fully
account for whether a location can spawn a particular weather.
Additional minor changes:
- Adds ScriptedNoMarks to Regis and Glimwood Tangle static encounters
- Corrects a few version-specific Pokemon such as Ludicolo/Shiftry
- Removes erroneous encounters such as Milotic in East/West Lake Axewell
- Removes an unused Motostoke Stadium encounter
clean:
if (!logical) return;
Existing logic had methods named to return true if fail, now method checks for passing, thus the logic now follows the above pattern.
Simplify some method signatures, reduce checks for MoveEgg.GetEggMoves
ran legality checks for 100,000 pkm, no more exceptions (Internal Error) -- added a "CanGameGenerateEggs" which filters out unused gameIDs
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.
Metagross collision with wild beldum
deferral API is kinda crude, hence these janky workarounds. Was originally intended to hold onto close matches when there's no more possible matches to check.
I think a priority-deferral while only retaining a single encounter bad (instead of a list of retries) may work better than the current setup, but that would require more abstraction
Transporter remaps certain locale specific chars depending on the source ROM's version.
Since VC can trade between languages, there are 2 Spanish in-game trades that have glyphs subject to remapping, if it's transferred from a French game.
If the spanish trade is transferred from a french game, it must match the mutated string.
ty @Lusamine & helpers :D
Slap in friend safari at the end during object construction; saves about 1KB of allocation on startup (lol)
Change internal array types to match object types, similar to other encounter-generation definitions.
I think this was a PKHeX issue that went unnoticed; originally, we didn't include the Á and Í chars in the dictionary.
I checked the transporter code:
The app maintains the international & japanese character tables, and depending on the ROM language, it may change a char to the language-specific entry. Refer to Bulbapedia's notes on the char tables for different languages:
https://bulbapedia.bulbagarden.net/wiki/Character_encoding_in_Generation_II
However, none of these char-changes are able to be reached with a legal char.
Á and Í (only accessible from the Spanish in-game trades) and the german 0xC0 && z <= 0xC6 chars are already in the international table. Every single difference in the VC1/VC2 table is an un-enterable char.
tl;dr -- all possible char codes are transferred fine with the VC2 table without extra language logic. We just keep out any inaccessible char (replaced with space).
Move form-info logic from FormConverter to AltFormInfo; now FormConverter is entirely form=>string[]
Add a bunch of xmldoc
Make pogo no-end-date cmp agaisnt UTCnow rather than local now.
Event Move special encounters are yielded after static encounters by the generator, so this iterator-picker will never behave as originally intended.
Since the encounter generator works fine for these events in its current form, we can just remove it. If we need to prefer GB era events before static, then we'd reinstate the priority and move the GenerateGBEvents before the static yielder.
bla bla bla this is just a cleanup from old preference code where we wanted to recognize the encounter as an event/trade as they're more recognizable. We just want to track the progress of the iterator so that g1/g2 follow a merged yielding order
Adds Nickname checks, thanks @ShadowMario3 for grabbing these into separate text files from Bulbapedia.
I reordered all the encounters to match Bulbapedia; each level is denoted if different if it can be sourced from RBY.
Extract common abstract class for GO transferred encounters
Clamp minlevel instead of met level
Add optional parameter for GO IV randomization
Update go legality binaries with latest
PKHeX.Core now accepts generated pkl binaries from PoGoEncounterTool (PGET).
Refer to pporg's repo. This will be treated like event data; occasionally updated.
took me less than an hour to do these changes, and i can flag bad form movesets no problemo
Expect tightening of restrictions (ball, level, shininess) later
if someone wants to curate met date restrictions, go ahead!
Sure it's nice to cache a valid array, but the amount of logic was small enough that it can be done with 10 lines of code rather than at the end of each verification method.
Reduces parameter passing & removes 1 field from the info object, as relearn suggestions are only done rarely after legality checking.
Allows for a simpler api surface (pkm, encounter) rather than a bigger object reference
Closes#3040
Ty @Atrius97 !
"The Japanese Aurora Ticket was only distributed in Summer 2004, before Emerald (Sept 16th 2004) was released. The software at that time had no support for Emerald games."
Alakazam in the Insular Sea (on the Isle of Armor)
Zapdos at Watchtower Ruins (in a Wild Area)
Zapdos at West Lake Axewell (in a Wild Area)
Moltres in the Soothing Wetlands (on the Isle of Armor)
Moltres on Challenge Beach (on the Isle of Armor)
Moltres in Loop Lagoon (on the Isle of Armor)
Dragapult in the Giant’s Bed (in the Crown Tundra)
Nidorina in Frostpoint Field (in the Crown Tundra)
Glalie on Snowslide Slope (in the Crown Tundra)
Closes#3027
Roamers: Get PID generated externally
NPokemon: Get PID from a fixed value
Forced (Anti)Shiny: Get PID altered
Thanks @LegoFigure11 && Princess Emily (discord 4650) !
The game uses 0x5E if 0x5A+everstone, otherwise it uses 0x58
For determining the seed species-form, we want to use everstone breeds as that resolves to the correct species-form values.
Co-Authored-By: Lusamine <30205550+Lusamine@users.noreply.github.com>
Co-Authored-By: Marty-D <1645989+Marty-D@users.noreply.github.com>
Handle yielding in the moveset generator as well
Future commits will trim down unused values/abstractions; probably can get all the stadium stuff handled innately
Revises the tradeback status to remove any index that could have been sourced from egg moves instead.
really should refactor this TradebackStatus away, but Move validation still remains one of the un-refined parts of the legality checks :P
Introducing a new PKM format: SK2
Split ICaughtData2 off of PK2 so it can be shared with SK2 when type-checks occur
Add conversion for PK2<->SK2
Split the split-buffer handling for GBPKM to GBPKML (what a name), so that I can reuse shared accessor logic for SK2.
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>
EncounterTrade: don't init Location to -1; keep as default 0 and use that as the pivot for default met location. Move Fateful property to the sub-type that uses it (EncounterTrade4, for Ranch).
Move some EncounterStatic->PKM logic that is per-type to the associated type overloaded methods. Rearrange order of properties to be more consistent with interfaces
Gen3: Initialize some classes without using post-constructor setters. The `init` setter functionality coming in c#9 won't be usable as the net46 runtime/netstandard2 doesn't support it on current previews. Do it this way so we can explicity initialize some required properties rather than apply version on a second iteration.
Change Ability array to IReadOnlyList, add method to check ability index in personal data
Suppress some message warnings
Change EvolutionChain short-circuit for VC to jump from gen6 directly down to gen2. There aren't any notradeback 1 situations, so a notradeback1 will always start with g=1, so no need for the other if-continue.
Simplify pk5 conversion
Gen1: all are Trade1 objects, and all get the values set; just set the value in the object initializer
Gen2: all are Trade2 objects, set the same version
Gen2 all static encounters already have a version marked. Only thing remaining is to set the language.
Move logic closer to where it is used rather than in larger static classes
EncounterStatic(7): move VC transfer template creation to class, simplify some sanity checks
EvoChain: g==2 case is never hit as the generation check at the top of the loop already skips
Still some pending stuff like bad mystery gifts
gen2 static encounters on g/s applying met level and not location
gen6 ralts trade (no nickname) being flagged as nicknamed when it shouldn't
gen4 manaphy egg not having a hatch location (worked fine if you transferred it up)
gen3 antishiny gifts not setting their PIDs (jirachi WC3)
gen5 N's pkm gifts setting the wrong nature
gen3 unown not being generated correctly, cosplay pikachu being allowed form0, non-BugCatchingContest no longer require Sport ball, oras dexnav marill now uses the azurill eggmove table
Remove RibbonWishing as property, just calc on the fly since it's a single case
Update type info for vc transfer to indicate it's an es7
Split up dreamworld encounters as intended, fix logic lol
precompute result size
set Gen5 as lumped group for common encounters
remove linq usage (besides Sum call, whatever)
GetEncounters now only filters the in-game static encounters rather than the dreamworld too, as those are already filtered by separate arrays.
Check successive move slots after the current index rather than doing a count eq >= 2.
Flag all empty slots prior to a filled move slot, rather than flagging a full slot as invalid because "empty move".
* Rework gen1 slot loading
Slot templates are precomputed from ROM data and just loaded straight in, with tight coupling to the encounter area (grouped by slot types).
* Revise fuzzy met check for underleveled wild evos
Example: Level 23 poliwhirl in RBY as a level 50 poliwhirl, will assume the chain is 25-50 for poliwhirl (as poliwag evolves at 25). Instead of revising the origin chain, just ignore the evo min level in the comparison.
Previous commit fixed it for gen1.
* Rework gen2-4 slot loading
Gen4 not finished, Type Encounter data and some edge encounters not recognizing yet...
* Add feebas slots for old/good encounters
* Begin moving properties
Great news! Gen5-7 need to be de-dumbed like Gen1-4.
Then I can remove the bang (!) on the Area accessor and ensure that it's never null!
* Split off XD pokespot slot encounter table type
* Set area in constructor
* Deduplicate g3 roaming encounters
* Deduplicate xd encounter locations (rebattle)
Only difference is met location; no need to create 500 extra encounter objects. A simple contains check is ok (rarely in gen3 format).
* Make all slots have a readonly reference to their parent area
* Minor clean
* Remove "Safari" slot type flag
Can be determined via other means (generation-location), allows us to reduce the size of SlotType member to a byte
Output of slot binaries didn't preserve the Safari flag anyway.
* Update SlotType.cs
* Handle type encounters correctly
* Merge safari area into regular xy area
* Merge dexnav accessor logic
* fix some logic so that tests pass again
rearrange g5 dw init to be done outside of static constructor (initializer instead)
PIDGenerator: friend safari slots now generate with required flawless IV count
* Add cianwood tentacool gift encounter
* Remove unnecessary abstractions
Fake area just returned a slot; since Slots have a non-null reference to the area, we can just return the slot and use the API to grab a list of possible slots for the chain.
Increase restrictiveness of location/type get-set operations
* Minor tweaks, pass parameters
DexNav observed state isn't necessary to use, only need to see if it's possible to dexnav. Now that we have metadata for slots, we can.
* Remove unused legality tables