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.
Nothing for the PKM Editor; not sure how I want to handle the reused
FormDuration work value.
For the meantime, just use the Batch Editor for a targeted write.
Closes#2441
Gen3 item paste -> Gen3 item import => take item ID as is
once parsing moves starts, break if any following lines are not move
lines
Closes#2412 , thanks @The-Fireplace !
- Gender specific forms now set the correct flags
- Regular click on Check All doesn't set shiny flags
- Shift click on Check All sets shiny flags too.
Closes#2425 thanks @igniscitrinus !
Introducing Sword/Shield support!
Legality is still a work in progress, and documentation of encounters
and game features with respect to save data is ready for community
effort!
-Kurt
Zukan5/6 was pushing 0 for the formBit, which was an incorrect value. I
probably should have abstracted things since gen5/6 don't behave the
same as gen7
rewrite the SetDisplayedFlag for more clarity, and to early-return
without checking displayed state if the flag is being cleared.
Two birds with one stone:
- sav4 doesn't use Data (instead uses General/Storage), so we need to
use the abstracted method calls instead of trying to do things manually.
- setting a blank pkm at a party slot will decrease the party count!
don't decrease things twice.
* 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
With the approaching games, PKM sprites are a different size from the 3DS era (as already hinted by LGPE, which has 56x68). It'll be a little easier to manage with this portion of the library walled off from the rest of the codebase.
Eventually the net46 target will use fody or something to merge in these extra dependency dll's automatically to not disturb the usual exe/dll experience.
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
I think I left these in so AutoLegality could function, but we already
have a couple breaking changes / build pause notice, so lets keep
cleaning our API 👍
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.
See previous commit for discussion; it's easier to read and maintain
this rather than have the precomputed min/max comparisons.
LevelMin - minDecrease <= min && max <= LevelMax + maxIncrease;
See EncounterArea7b:
Since we know min and minDecrease (0) before doing the linq filter we
can precompute the lowbound, same for highbound; but this isn't
immediately obvious to the reader. The perf cost is pretty much
negligible in the big picture, so leave it in the more readable state.
Thanks @fattard & @ammako !
#2389
The inputs to "IsLevelWithinRange" are the highest value the
lowest-level can be, and the lowest value the highest level can be...
seems confusing (hence the original error).
If a slot is 6-7, with a wild encounter (flute), we can go +/-3 from
6-7, which is 3-10.
With an encounter of level 5, the inputs are: 5+3, and 5-3 (8, 2).
Since 8>lvlmin and 2<lvlhi, we can get a level 5 pkm from the slot
(using a negative flute yielding a -1 adjustment).
I could probably refactor it to be a 3-input signature (lvl, lvlneg,
lvlpos), and have it do LevelMin - lvlneg <= lvl && lvl <= LevelMax +
lvlpos
I should probably refactor these methods to do minLevel & maxLevel (so
baseSpecies.Level to CurrentLevel for pkm that lost their original met
data) but nothing needs the extra logic at this time.
Were using default filter behavior, which needs to be tweaked to account
for the original met location/level not being present (ie skip the
minLevel bounds check).
Hardcode logic for HasOriginalMetLocation for simplicity
Closes#2389 , thanks @Ammako !
Extract Species Name logic to SpeciesName
Extract Language logic to Language
Remove FormConverter wrapper for string[] fetch
Rearrange some logic to more appropriate locations, update access
modifiers / types
Move some pkm array methods to arrayutil, make generic
PKX.GetVCLanguage was a dupe of _K12.GuessedLanguage() so just expose
the method
PKX is now back to pkm data manip only
Now logic is reasonably split, and each format of area has its own way
of yielding slots
Too much junk with checking flute boosts or catch combo applicability;
just let the area dictate how slots match.
dual bounds check -> single check via uint cast
pkx: keep array reference for reuse in next check
format return to second line to stick out more; lines of code are cheap
:)
Generating encounters from an EncounterArea is getting a little stupid
without inheritance; each type can now have its own specific behavior
without checking for each individual type of generation pattern. Will
add the abstract method implementations in a future commit
Move some string[] array fetch (for all languages) to Util
split some methods with optional parameters=null
add more xmldoc
replace some magic numbers -> enum/const references
consolidate common array operations (span soon maybe?)
Increase abstraction for arbitrary slot get/set operations, and fracture
SAV4 behavior for each game type.
Adds: Undo/Redo of party slot changes
Fixes: Fixed Gen5 daycare slot 2 reading, and EXP reading
Fixes: Some slot color glitchiness
Fixed: Box layout editor now hides the flag label if no flags are
present
Fixed: Gen7 box flags are now shown (unknown purpose lol)
Changed: savefile objects are generally smaller (removed a few shared
offset fields)
Closes#2381
Keep Raichu and Marowak at the end for ez referencing. Keep a separate
refence for alolan kanto stuff for futureproofing
Might want to improve the EncounterArea abstraction to do the
slot-finding labor themselves, but whatever, hardcode stuff until swsh
throws new monkey wrenches in. A good idea would be a dictionary with
level forcings [species | form << 10] = X and use the dictionary to
check on slot creation
A little bit cleaner when the logic is separated
Keep an abstraction of BoxEdit to cache the current box contents.
Already fetched to show sprites; any future fetches (for preview text /
hover sprite) can reuse the already fetched pkm data.
Should probably rewrite this stuff completely, but effort better spent
elsewhere
* corrections and styling
* FR/LG: some more story/item related variables
* FR/LG: More HMs and Oak's Aide's items
* FR/LG: League beaten flag fairly confirmed
* FR/LG: variables
* FR/LG/E: Altering Cave variable
* FR/LG: Pokemon Tower related variables
* FR/LG: Pokedex/Oak/Rival (part 1) related variables
* FR/LG: more story related variables
* FR/LG: Event flags for eventually reaching event-only places
(required to enable processing of the appropriate items; officially set by DLC scripts)
* FR/LG: Badge names and Running Shoes
Choosing G/S will initialize as GS
Choosing C will initialize as C
calling via their own code (GSC/GS) will choose the most recent (crystal
if possible).
Closes#2359
Remove some unnecessary properties from SaveFile
Enumerate checksum flag results for GC memcard checking
Remove unnecessary checks on savefile type
Add some documentation
Decapitalize some method parameters
move some pk3->pk4 stuff into object constructor
annotate pk3->pk4 string buffer (trash) quirks
split Heal into Party/PP method uses. Setting suggested stats no longer
refreshes PP
apply current level to Stat Level (wasn't being set previously)
event move only
still haven't bothered finding the table in the exefs that results in
the pkm with an oob move being dummied. hardcoded based on data for now
:)
Was initially implemented as fishy during SM's initial implementation. Any nonzero value in this byte is invalid, don't even bother checking unused/count.
Now that Gen6 (and Gen7) are no longer current gen, any hope for them being released is the same as hoping for Gen4's Azure Flute Arceus. Thus we mark as invalid :)
Closes#2353 by effect of no longer flagging as Fishy. I think that my initial implementation of VC stuff had assumed the Generation==7, but later used 1/2 for factual correctness.
c345688f6d
base(x) -> base(x - y) resulted in incorrect offsets for LGPE. Great.
Just make PokeDexLanguageFlags a shift offset instead of absolute;
update all usages.
Closes#2348
Feels pretty brittle with all the optional parameters; if things get
funky for SW/SH it may warrant a rewrite of this portion
Closes#2345 ty @iiippppk !
Closes#2343 ty @WEERSOQUEER !
#2338 was referenced by
4d08e21126
, that commit was incorrect. Looks like these 2 have OT Gender female.
Instead of marking every trade MALE except for these two, just update
the handling (i'll probably regret this lol)
LGPE will missingno your pokemon if it's not a Kanto/M&M, or one of its
moves is not obtainable. For the user's benefit, filter down these
sources to the non-baddata list.
Item filtering and ball filtering might be something to think about for
the future, but not much benefit vs effort.
Check the OT length for the deferral
other encounters are more permissive than trades, hence why we defer
unless we know for certain. Same OTs are possible, except for the
too-long ones!
Closes#2338 , thanks @WEERSOQUEER !
Needs to be checked prior to the strict Array Index search, as we can't
have an exact string match.
can probably be revised to a StartsWith to only check for the specific
language match, but that's a little less obvious & extra work :)
#2338
remove unnecessary %25 check (only applicable for gen4 encounters),
unneeded for gen5 method.
add a test case to generate a haxorus for all natures, verify shininess
Closes#2336
LangFlags is expected to be less than 0x500 or whatever, zero indexed to
the start of the dex block; NOT an absolute position.
I don't feel like making every usage consistent (gen5, gui editors)
which use the absolute position, so just adjust in the zukan
constructors
GameInfo has been the storage for the current Game Language environment
When using GameInfo, only one environment is tracked at a time, which is
initialized by the PKM editor (items, moves). Rework things to allow
multiple filtered sources to exist, and keep the filtering logic in
PKHeX.Core for reuse in other programs... ;)
Pass them as Legal for wild encounters similar to M1/M2/M4.
Add test cases & test pkm validation
Add pid generator support
I decided against checking these PIDIVs after all others; inlined
methods.
Closes#2328 , thanks @pokecal !
create custom comparer to do the work
reorder some parameters
simplify gb hm set (All and FindIndex is duplicate work)
only usages of linq remaining are for the bulk action Where filtering
(ok)
Shared base classes throw a new snag, where the property may be Declared
in the shared class.
eg:
PKM -> _K12 -> PK2
just filter all public ones that have a setter; works well enough idk
not enough documentation to know what every single flag does; just be
lenient
I assume that flags being present XK3->PK3 will set fateful, so we could
remove that logic...
Exposing bitflags for editing isn't fun for the editor, so just ignore
it behind the fateful bool get/set.
fateful required for all xk3 origin
#2289
transfer level exp and current exp not being different enough, which
limits the amount of natures possible. Could handle the 100&<=2 cases
the same way, but keep the branches for faster cases.
fix bad test cases
Not version specific; I'm assuming the 00020003 PID is a result of
hacking the save file to change OT gender. Legitimate saves haven't
yielded the Hardy PID. Changing gender probably results in a bad
pointer, fetching the wrong value.
Closes#2290
Remove usage of linq for sorting, use array.sort for in-place sorting.
Wasteful creating temp sorted buffers then enumerating them to dump into
the list.
existing logic had been overwriting the inner error messages with the
generic fail message
Remove backwards conversion precondition check; the ConvertPKM method
has no branches that allow conversion so it'll naturally fail -- end
result is the same with less upfront logic.
Fresh day, fresh tests of the new code :)
Fix assert conditions
Add extra considerations
Detected clones should be skipped for PID/EC/TID checks -- should
probably detect this a different way rather than checking a computed
string (bool array of flags for the clone check results)
FileInfo inherits from FileSystemInfo, which initializes a bunch of
strings that we don't need
this isn't a great optimization, just a fun exercise finding a quicker
approach to get these values
EvolutionSet was just an object that hides an array, with no logic
was planning to use the EvolutionSet to do the evolution checks, but
EvolutionTree was required to connect the evolution chains together
Removes empty trashbyte array allocation (less objects)
Change int[] to byte[] (less filesize/mem) (-256*6)
Change int[] to ushort[], precompute reverse table in saved space
removes dictionary lookup for array index fetch (faster, less memory, no
temp obj allocations!)
could make the ushort[] arrays into byte[] by changing them to be value
shifts? Not worth saving filesize for cpu.
reduces loading time (don't have to allocate conversion arrays when
launching a gen7 game), and separates things to easier to manage
locations
reworks gen3 string encode/decode, no longer does 3->4->5 and 5->4->3;
instead goes straight to the end result without an intermediary format.
String sanitization should probably be broken up rather than reused, oh
well.
if conditional checks >=3, and all subsequent checks require Valid; add
this to the continue condition, and remove unnecessary comparisons
update some comments
PK2 doesn't like getting passed null for the byte[] parameter (rightly
so); don't depend on the src code order having the first constructor
being the one with the least arguments
fix it in pk1/2 so that the first constructor has the least args, anyway
remove Identifier param. 99% of the time, identifier is not provided,
resulting in a useless call
end result:
provide 'create new' and 'create from' constructors
For xd, getfinaldata returned a standard 344KB save, but then slapped it together with the inner savedata (0x28000 bytes) rather than using the GCI header. Don't use 'Data'
replace linq for Encrypt/Decrypt pkmdata fetch with faster length check
& optional resize (Span pls!?)
update pk6 comment for why affection is not cleared
use 'u' to denote uint values, so that less IL ops are required
~(21->17) in the case of IVs
no functional change, just a fun exercise looking at generated IL and
finding ways to use less ops
no functional change, just rewrite some logic for better flow
fix subform popup count restriction (OwnedForms requires forms to be
added/removed manually; it doesn't automatically update)
sanitize box names when dumping boxes with separate folders (and bad box
names)