Move Home8 location to Locations.cs for documentation
Move FestaFacility to correct folder
Remove unnecessary public modifier on interface method
Pass the program's Version to any loaded plugins, if they wanted to check compatibility...?
Closes#2990 ty @Atrius97 !
Remove the `object Content` accessor only used for Mystery Gifts (used to trickle up the PKM object since the two ribbon interfaces weren't implemented on the IEncounterable). Just make PCD/PGT implement the ribbon interfaces and delegate the get/set to PKM directly.
Rewrite the national ribbon check for clarity
Optimize invalid/missing ribbon string replace to operate on the final string rather than do linq and replace each input. With this we make 1 temp string only, rather than 1-per-ribbon.
Replace hardcoded "Ribbon" strings to use a shared const string in a central spot.
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.
Get the variable rather than indexing into the array each time
Simplify some expressions in sav7 for readability
Make SAV_EventFlags use comboitem explicitly by type rather than an anonymous type with same member names
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
Thanks MrPerson0 on discord for notifying us of this mechanic. Stadium 2 can utilize Gen1 learnset data while keeping them in PK2 format, retaining the met data.
Adjust EggItemShift to account for using the big Egg sprite
Add Marowak to non-transferrable Totems (none of the USUM Totems can be transferred to SWSH)
Check egg encounter for state rather than re-deriving some properties on the fly
Only check memories if memories are exposed
Remove debug assert (not always true?)
Only check player ID
Closes#2952
Had originally intended to just recognize the PIDIV and check it in the lock verifier, but this is more straightforward since we don't have to check CPU TSV.
GO Fest 2020 made Alolan Marowak available in wild spawns, and further testing has proved that Raid/Research PKM can be downleveled to 15 after trading to low-level accounts.
This'll probably end up being deprecated in the future when we have GO->HOME transfer checks, in addition to IV checking.
verify relearn: move split check before method call
movelist: don't capture pkm in local method; meowstic ID
pkm: flip argument for easier understanding
Results in a little more code, but each path is less tangled
simplify some expressions
remove RBDragonair content in favor of a strict filter for catch rate
Move gen1 trade trainer names to stringconverter, since pk1/pk2 shouldn't refer to legality classes
Check the memory for RibbonTowerMaster; if the memory is present, permit the lack of ribbon if it was granted via past gen and has the other ribbon.
Simplify !(x || !y) to !x && y
Closes#2926 ty @randomdice101
Some zone names were mislabeled in pkNX -- Staryu are not scripted encounters!
Remove altform specific moves from distro/static Rotom, which would erroneously allow illegal mismatches (e.g. Hydro Pump Rotom-1); thanks Abyzab (Discord)!
no change in species/form from the crownite ore one afaik; common for both games???
fix type of rigel encount so it shows up in block editor, with correct name (ty matt)
vs -> chain (clarity on what it is; an evolution chain, rather than e.v.o.s - vs)
Clamp origin chain for transferred where we can use the max origin level
things shouldn't be this way, but encounterstatic doesn't currently accept a SpeciesForm evolution link in the matching function, so we can't know when the form changed legally.
Encounter Slots do it fine for the most part... might need to refactor the matching API so that it behaves a little smarter
Closes#2912
Can lose gmax flag if its current species is able to eat soup, or its origin species could eat soup
this handles stuff like charmander->charizard, as charmeleon would not pass
hopefully there's never a mid-stage evo that has a gmax form, and its final evo doesn't... (don't get any ideas, gamefreak)
invert ability index favoring so that the first ability index is most favored
ability num:
-1=>0/1/2
0=>0/1,
1=>0
2 =>1
4=>2
Ability Type:
0,1,2=>0,1,2
3=>0/1
4=>0/1/2
Should probably get rid of AbilityNumber definition usage but it's so entwined in the trade/static definitions...
Co-Authored-By: sciresm <sciresm@users.noreply.github.com>
Co-Authored-By: Matt <sora10pls@users.noreply.github.com>
Co-Authored-By: Archit Date <architdate@gmail.com>
(for good? pls)
https://i.redd.it/7g2c4d3kisc41.png
ty anubis
remove GetMinimalLevel override, as it's doing the same thing as LevelMin. When regenerating the pkm, we aren't doing anything downlevel related.
Downleveled shared nest can't go below 20
Downleveled self nest can only happen for 1 or 3 badges and certain star counts, and the result can't be shiny
Encounter Generator stops yielding if anything was yielded (assumes things that are static encounters can't have anything else that would match).
DexNav boosts the wild level (from 25/27) up to the same level 30 of the static encounter.
Thanks @KR1dude !
Co-Authored-By: KR1dude <kr1dude@users.noreply.github.com>
all but egg exposed it; now, just make egg expose it and remove the unnecessary interface
we still need to Set generation for non-eggs/mgift, so have a separate Settable interface for internal purposes.
just need to get all evo chains possible
fetching a GO leafeon, need to reverse leafeon->eevee, but the LGPE evo chains don't know about leafeon
works fine now
Bye bye invalid drilbur, nice meme GF
The first rotom2 in Shield had its moves changed too. Keep that rotom-2 since Discharge can't be learned at that level.
since sw and sh have the same drilbur, it moves from sw -> common.
Strange Souvenir and Room Service would get cut off since they're tall.
Also remove Adventure Guide from resources, and add Discount Coupon to Gen 7 unreleased items.
Add small Female Hippopotas/Hippowdon sprites (Closes#2789)
Add Pt Togepi Gift Egg Event Constant (Closes#2801)
Remove Pokémon Den from Egg Locations (Closes#2804)
Fix Shiny Dhelmise sprite (as per 3774e0dd34)
made an oopsie, Watchtower Ruins also apparently includes 2 extra dens that can spawn encounters that are not 8NC. Den 17 is locked to 8NC encounters only, but location-wise there is no difference between Den 15,16,17
Emerald has the same met locations too, which doesn't clear fateful. So if it was hatched in an RS(E) location, we can't know for sure.
Closes#2790 , but keep in mind the posted file is illegal anyways -- can't get egg move aromatherapy with wish.
Closes#2787
The commit a couple days ago added the missing minimum level restrictions; community documentation was slightly misleading but we should be good now.
The PID check was nonfunctional (compared A==A or A==A*), rather than actually checking the fixed PID.
Co-Authored-By: feralfalcon <feralfalcon@users.noreply.github.com>
XD compares the player TSV against the non-shadow members, which is unnecessary but does result in them being able to cause shiny skips.
Update the VerifyNPC method to remove tsv check, as it's just repeating the logic we've done in the lock generator.
Added a test method that can be stepped through; compare the team results manually since they aren't exposed for interaction.
Closes#2751 , big thanks to @ijuintekka for being so detailed in their investigation/report!
Co-Authored-By: ijuintekka <ijuintekka@users.noreply.github.com>
Mewtwo encounter has been added; awaiting confirmation that it can be captured (assumed yes)
Gen1 starters can be captured in beast ball in gen7 (scan), so nothing changes for ball legality.
Remove non-galar species from gen8 banlist
Add Ban_NoHidden8Apricorn -- all of these aren't even breedable in-game anyways, but futureproof for DLC? ;)
pk7->pk8 doesnt assign height/weight (zero), require zero for legal
p*7->pk8 assigns a tracker value, enforce something is present for legal
copy OT friendship (oops)
Traded eggs in gen4 can have from any game (since version isn't updated on hatch).
Use the hashsets, and remove the incorrect array. The incorrect array allowed stuff like Pokéwalker to be a "valid met location", hah.
held item list now allocates less (concat arrays instead of ienumerables)
item list already prunes out of range items, so simplify data source fetch
simplify item list prune (return as list, so we can call RemoveAll instead of Where.ToList)
gen7 used same as gen6, we just need to restrict gen!=8
add placeholder LGPE origin check; that'll likely throw a wrench into things when HOME happens (next month?).
Add more direct legality analysis constructors
evo count is >= 1
fix invalid test message
disallow gen2 moves if transferred from gen1
use ^1 instead of len-1 for netcore test project
Some routes use the evolutiontree directly instead of this method (with the same name); should probably consolidate but meh
This causes Shedinja to yield the correct evolution chain when called directly (because nothing naturally evolves to shedinja; it's created out of thin air as a clone)
Take the egg short circuit with it to keep things simple
USUM had 20 for both, but XY/AO/SM had only 1 (vivillon had 20); make
them consistent so that our generated evolution paths behave correctly
Add meowstic specific evolution form modifier... so silly
simpler to have it inlined with the sSpecies, for jit optimization
could probably do this with silvally but meh, things work fine now
Closes#2603
PKX.Generation is 8, which returns SWSH evo tree; evo tree doesn't have
non-galar-native species data, so stuff like Ambipom don't get reversed
properly.
use math.max for tree fetch when appropriate:
- egg generator: pre-evolutions like pichu should be allowed if pk1
- don't fetch format twice, just do math.max
Not going to implement this within the base repo as z3 is too large of a
dependency and is platform specific.
If anyone wants to implement as a plugin project, just inject your new
methods via the setters on the static func/action at the top of the 3
classes.
Since z3's searches aren't instant, I'd recommend caching recent results
in a dictionary, as re-parses are common. Something like the Wordfilter
is what you'd be aiming for :)
Closes#2617
The nest is situated right next to the load line, and may be accessed
from either map (across the load line), resulting in a Dusty Bowl
Pumpkaboo-0.
Many thanks to Anubis on Discord for figuring this (very silly) thing
out !
Closes#2573
- self-hosted raids can be downleveled too (see cufant), probably only
by 1 rank
- min-rank check now checks for downleveled cases
- Add extra gyarados/ferrothorn locations
the "Strong" static encounters can be near-matches with wild encounter
slots; example is a evolved Cutiefly->Ribombee with Quiver Dance.
Remove unnecessary IsLink/FriendSafari check for this gen8 method
https://github.com/kwsch/PKHeX/issues/2573#issuecomment-569126371
Closes#2577 thanks @HoppyShnell ! -- this looks like the final met
location ID?!
Not sure if Murkrow (locked) is missing one; moved duplicate-location
Heracross and made it use the same locks.
just read the comments & code, this one is an annoying oversight
untraded pkm /should/ never have HT memory data, but sometimes it do be
like that
Closes#2571
Move EncounterOriginal to Legal info; needed in order to pass the
correct encounter to the EvoChain fetch.
The EncounterOriginal 'hack' might be unnecessary with the current state
of the legality checker... maybe can see if it can be removed later.
Rewrite a bunch of the history verification stuff
Fix a few test cases with incorrect OT Friendship (transferred), and
missing GeoCountry
Need to rewrite memory verification next
(All test cases currently pass)
#2545
GetDestinationForm for gen7+ is fine
gen7 and gen8 use the "form" argument as the destination form; -1 means
don't change
espurr-F just gets forced to 1 in gen7 since it's -1
Closes#2564 ty @iiippppk
only used for Zukan7b, but add in handling so that it works for <=gen6
games, and supports form alterations too!
update style to match GetPreEvolutions
could probably update this to yield tuples (species, form) but LGPE/SWSH
only needs species. If there's the need for tuples later, should be ez
tweak.
espurr-F evolves to form-1 from form0, even tho the form arg is -1 (gen7
consideration)
gen8 has 0/1 for the two evolutions, dictating the destination form
DexLevel was the initial abstraction, which was expanded/reused for
evolution details
I should probably merge the two classes since everything is passed as
EvoCriteria
The encounter generators do some silly form fuzzy match which can now be
more accurately checked since I've moved Form to DexLevel... maybe a
future commit can clean that up.
encounterarea2 was reusing this class, just use a throwaway readonly
struct as our temp value storage
- Use tail recursion and a lookup table (species | form) for reversing
- generate the reversal lookup by extrapolating all species-form
destination values (EvolutionLink)
All tests pass, and no special handling for forms is required. Kinda
suspicious that it works this simply...
Redo evolution banning (no wormhole for non-Alolan evolutions in SM), in
a style that we can ban the Gigantamax event evolutions
(pika/meowth/eevee). Their evolutions can't be resulted from a pre-evo,
because the in-game routine early aborts if the gigantamax flag is set
for those species.
Update gen4 personal tables (formCount was 0, needs to be a minimum of 1
by default)
Closes#2537
format >= 6 is always true (early return in entry)
don't double-flag/check memory presence in OTs from gen5 and below (hist
and OT verifier)
rename method; I'll probably rework the flow of things for gen6
verification and gen8 verification since the rules are slightly
different
Certain Mark values (ribbon) are only obtainable if the encounter was
obtained in some weather (I really hope there's no crossover cases for
this), and non-symbol encounters can't wander to another zone.
I wonder if you can wander from one zone with one exclusive weather, to
another zone, and get an 'unobtainable' mark (with the new zone's
weather) on the crossover mon's weather. yikes lmao
yeah your initial hacks were hacks
It appears there's a bug (in the game) for link trade memories --
applied to the OT memory instead of HT memory?? Fun!
Private report with 3 specimens, 2 undocumented met locations
The other was a Gigantamax which matched another static encounter,
resulting in a partial match being accepted (the real match came after,
but was never iterated to).
Rather than adding deferrals for Enc8, do nest stuff first since it's
the most restrictive
In the past we didn't really have duplicate static encounters with
slightly different permissions.
Thanks @ReignOfComputer & {reporting user}!
#2484
OH BOY REUSED INDEXES
smart to save space, but a small pain for legality
feels pretty bad breaking up abstractions for every minor difference in
verification...
* Static Locations Update
- Removed version lock on Motostoke Stadium Vulpix (may want to investigate Growlithe)
- Wild Area Updates
- Other Static Updates
* Squeeze in 2 more Statics
* Rhydon Static Location
Last one I promise.
Closes#2461 by implementing slightly differently
Dictionary instead of new[] every area
Checks original met location first before attempting the dictionary
lookup (missing in pull request)
Easy path forward if LGPE crossover is needed
Potential issues: Since encounter types aren't marked, shaking trees and
fishing encounters are allowed to cross over. Maybe need to have some
marking for encounter slots or something...
Now recognizes & reverses form-changing evolution chains like Sirfetch'd
basically the whole process is to build the tree but point in the
opposite direction (for de-evolution paths)
Was referencing wild caught mons that are given a single egg move; this
logic handles shared egg moves too via daycare.
Probably need to rework SplitBreed into a dictionary; this might not
catch Mime/etc split breeds if they have different tables.
* 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
New in c# 8
Assert.True(check for null) doesn't give a hint that the obj isnt null
afterwards.
Assert.NotNull does have the compiler hint attribute
could probably use fluentexpression syntax, but resharper doesn't pick
up on the nonnullable hint like vs does.
GeneratorTests: swap FirstOrDefault to First, can keep the fluent style
and resharper gets the hint.
tl;dr : resharper doesn't look at external lib for hints, gotta use
Assert.NotNull or something that doesn't return null
Futureproof with transfer considerations
This is just a guess; gen7 didn't update the medal count and if we
assume pk8 overhauls the structure for a new console, they'll drop old
data.
With c#8 later next week, will move SuperTrainingMedalCount() to a
default interface method ez.