First 5 blocks are reserved for file accessing info, but we should include them when checking length
Closes#3468
Capture the bool indicating Japanese for the save file, so box names are now read correctly (if changed from game's default).
net6 was 4x faster than 461 with the old implementation; now it is faster for both but not as disparate.
New implementation performance is always at least 30% better than the old implementation; even better for smaller chunks of data (40% less time).
Pretty much mimics bare metal value writes
Seal ComboItem
Reorder methods for easier reading
Fix BulkGenerator living dex setting CurrentLevel -- needs to be after species,form as EXPGrowth can vary for forms.
Was originally expected that gen8 was going to be a pair+revision generation, but with BDSP and PLA being totally different games, there's no need to have inheritance complicating a single SWSH class.
Fixes#3455 by adding bool for insular sea, and adjusting overall progress values as listed.
Closes#3456 (supersedes)
Updates SCBlockAccessor to eliminate bounds check (integer overflow, which isn't possible with our array size), adds some overloads, and xmldoc.
Co-Authored-By: Jonathan Herbert <3344332+foohyfooh@users.noreply.github.com>
Closes#3454
Use ahtb sourced (hash,string) correlation from pkNX to dynamically generate block keys.
Co-Authored-By: Jonathan Herbert <3344332+foohyfooh@users.noreply.github.com>
Xor no longer allocates
Encrypt no longer allocates byte[0x60]
temp now allocated on stack instead of heap
Pre-size memorystream (prevents 0xF0 allocation)
Adds structures to read/write saved spawner data such as seeds, counts.
Adds generator and validator to emulate the FixInitSpec builder used by the game logic
Similar to SW/SH raids, validating these in-process is not feasible due to the number crunching required.
This does not handle the encounter slot call or the follow-up level range call. Just the inner FixInitSpec ctor & fill.
level is calc'd:
randFloat(sum) -> slot float
rand.Next() -> gen_seed (for all the details)
rand.NextInt(delta) +min -> level
Co-Authored-By: Lusamine <30205550+Lusamine@users.noreply.github.com>
Was writing kor string, then writing en after (all terminators).
Make method signature match other SetString, with write buffer as first arg
Closes#3440
Stop allocating an entire shadow copy of the save file whenever we create a new savefile object from file.
Prior commits added the clear SaveFileMetadata class to cleanly track the file path. Backups are copied from the original path.
Introduces an option to disable reading .bak / "backup" files; trickle the changes up to all surface users so that SAV_FolderList can correctly load all .bak saves into its Backup tab.
The "ignore backups" was added in the latest feature push to ignore "backup" from being detected as the latest save.
Update 22.02.04
Individual commits from this PR are not cherry-pickable in a vacuum; these were manually re-committed from a staging repo in order to group together changes for general public viewing. There were over 250 commits on the private development repo for this update.
XD shadow monitor stores the Gen3-mainline-SpeciesID instead of nationaldex ID.
Remap the values on the fly.
Pass the data via span to save a 8KB allocation for sav ctor
Closes#3365
Existing `get`/`set` logic is flawed in that it doesn't work on Big Endian operating systems, and it allocates heap objects when it doesn't need to.
`System.Buffers.Binary.BinaryPrimitives` in the `System.Memory` NuGet package provides both Little Endian and Big Endian methods to read and write data; all the `get`/`set` operations have been reworked to use this new API. This removes the need for PKHeX's manual `BigEndian` class, as all functions are already covered by the BinaryPrimitives API.
The `StringConverter` has now been rewritten to accept a Span to read from & write to, no longer requiring a temporary StringBuilder.
Other Fixes included:
- The Super Training UI for Gen6 has been reworked according to the latest block structure additions.
- Cloning a Stadium2 Save File now works correctly (opening from the Folder browser list).
- Checksum & Sanity properties removed from parent PKM class, and is now implemented via interface.
Closes#3318
Gen8: if held item, only give if can be legally held; if dmax crystal, only give if available.
Gen8b: if held item, only give if can be legally held
Others: unimplemented; pull requests accepted.
Still does the same silly ARNG as gen4:
seed = 0x6C078965 * seed + 1;
to advance on each day
Do note that it sets event flag 1711 to true, and sets the absolute value of the "Random" to Work[436]. FLAG_DAILY_RANDOM, WK_DAILY_RANDOM, assumedly for easy use with scripts.
The RAM is pretty dirty for unallocated poffins; slots that have never been filled will have junk with whatever the unallocated pointer was looking at.
An empty poffin slot is just marked as FF, ignores the stats for that slot. Not sure on the naming, but Matt had a single Level 60 poffin -> must be Mild? Thus, all the names are -1 from the textfile array...
Closes#3305
I think it was actually crashing due to the bad GameClear date record, not this extra record data, but we'll still update the head record
Fix note of ENC_SV_DATA start offset now that we know the real size of Record8b
Add actual maximums for all record entries
Big thanks to @SciresM @sora10pls @Lusamine @architdate @ReignOfComputer for testing and contributing code / test cases. Can't add co-authors from the PR menu :(
Builds will fail because azure pipelines not yet updated with net6.
Static encounters (stationary and Max Lair), gift encounters, and some general purpose flags. Can filter most of these out in PKHeX settings by ignoring `KCaptured` and `KReceived`.
* Add metadata flagging for values
Allows users to set a minimum importance for the list displayed.
Could probably make this checkboxes within the flags UI.
* Add setting to filter out gen8 block names
Allows users to filter out unwanted low-value property names.
Co-authored-by: Kurt <kaphotics@gmail.com>
* Providing pkm/sav files via command line (dragging files onto exe / associated file launched) will more intelligently source a partner sav/pkm object if not provided.
* Gen1/2 mainline save files now indicate if they are VC era or GB era (legality implications) in the program title bar.
* Fixes loading VC era save backups not being recognized as VC era (`.bak` extension hides `.dat`)
* Export BAK moved to the SAV tab, which allows Export main to be deleted and Export SAV to be used as the single-click for exporting saves. `CTRL-E` is still the hotkey.
Slap on interface for EntreeSlot
De-magic some 💯 numbers to indicate what they're doing
Improve perf of move-match-relearn check
Add an "else" as valid is never both values (history verifier)
Closes#3231
Symptoms observed:
- Tiles were too dark (not high enough RBG value due to >>3; keep 8bit color here.
- Red/Blue channel inverted, swap R & B. Works? Hope this isn't something related to png storing rgb vs bgr and we'd need to check input pixel format?
- Tiles were misplaced slightly, off by 1. Fix order of operations so that the tile choice value is correct.
EncounterArea now stores a more specific type'd array for encounter slots. Better iteration and less casting, as the nonspecific `Slots` fetch is rarely referenced.
EncounterType renamed to GroundTile to reflect how it actually works in Gen4. Was previously an ambiguous field that was clarified a little; we can describe it a little better now. Keep the GUI the same to not scare the end users.
Change Trash Byte properties to get/set a Span. Trash Byte legality checking easier on the garbage collector?
* Track a PKM's Box,Slot,StorageFlags,Identifier metadata separately
Don't store within the object, track the slot origin data separately.
Batch editing now pre-filters if using Box/Slot/Identifier logic; split up mods/filters as they're starting to get pretty hefty.
- Requesting a Box Data report now shows all slots in the save file (party, misc)
- Can now exclude backup saves from database search via toggle (separate from settings preventing load entirely)
- Replace some linq usages with direct code
* Remove WasLink virtual in PKM
Inline any logic, since we now have encounter objects to indicate matching, rather than the proto-legality logic checking properties of a PKM.
* Use Fateful to directly check gen5 mysterygift origins
No other encounter types in gen5 apply Fateful
* Simplify double ball comparison
Used to be separate for deferral cases, now no longer needed to be separate.
* Grab move/relearn reference and update locally
Fix relearn move identifier
* Inline defog HM transfer preference check
HasMove is faster than getting moves & checking contains. Skips allocation by setting values directly.
* Extract more met location metadata checks: WasBredEgg
* Replace Console.Write* with Debug.Write*
There's no console output UI, so don't include them in release builds.
* Inline WasGiftEgg, WasEvent, and WasEventEgg logic
Adios legality tags that aren't entirely correct for the specific format. Just put the computations in EncounterFinder.
Closes#3177
Format sizes are now accurate to game structure sizes. Added a few more editable fields, rid of label/textbox/etc for general base editing -- use a PropertyGrid instead.
Feels nice having a bank of saves to reference + idb to discover the struct layout.
Removes 1.5MB of allocation; we don't need to preserve the encrypted state.
Revise savefile clone operation to use its own constructor, as we need to call the base constructor first (backup file clone...) prior to decrypting.
Expose CryptStaticXorpadBytes as GetDecryptedRawData no longer exists.
More in line with modernizing the codebase with latest c# syntax
improve web-qr decode speed slightly (no linq skiptake)
get money/coin mask without a temporary string (lol performance)
- Settings now stored as json next to exe
- Settings now exposes all legality checking setttings that can be changed
- Slot hovering now can play cries in MGDB/PKMDB/etc, not just the main boxes.
- Enhanced hover text for mystery gifts and encounters that have movesets
- Show recently loaded save files in ctrl-f browser
- Toggle auto-load savefile setting to be none/detect-latest/last-loaded
- Custom extensions & extra backup paths can now be configured directly in the json settings
- Settings editor now uses propertygrid & tabs.
* 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
Remove hardcoded chunk lengths array
Remove cached chunk index array
Handle new-game files correctly (all blocks present check).
Consistently call things sector instead of chunk or block.
Somehow there was a bug with my FRLG save file's box data, which now loads completely?? Neat
Extract RSBOX checksum logic to checksum class
Allocate half as much for gen3 save detect
Simplify some expressions for GC save loading (x - size + offset, when x==size)
plugin adds a reader -> reader checks if it is a non-PKHeX.Core save type (they'd implement their own savefile/etc type) -> returns a matching save object if so
basically bypasses the base PKHeX logic
path.getfilename will never return null unless you pass null, which we don't do
setchecksums' base method does the AllBlocks.SetChecksums. move the battle team set to right before the usage of SetChecksums
Disassociate pk4/pk6 backing byte[] when converting to pk5|pk7, as we no longer make a copy of the byte[] in the pkm's constructor.
Change UpdatePKM to include isParty, as we want it optional to update FormArgument too.
Change FormArgument saving to be handled by FormConverter; kinda not really good to have it there, but nothing else is handling FormArgument values.
Expand IFormArgument to have all FormArgument values exposed. "Maximum" is furfrou only.
PK6: Max is in the "FormArgument" u32, and the remain/elapsed is in party stats (hence the reverting when boxed)
PK7: u8 remain, u8 elapsed, u8 max, u8 unused.
PK8: assumedly the same as PK7, given the disassembly hints that it's the same as past games (even though Furfrou and Hoopa are not in SWSH).
## 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).
Retain a stringbuilder to mutate the string rather than finalizing temporary strings
yields some speed improvements (less gen0 string objects allocated)
Closes#2954 ; can set directly from propertygrid already, but might as well clean things up a little bit to match the disassembly logic.
Open the simple editor center parent rather than next-form-position
don't use FIPS compliant hashing methods explicitly, no real reason to. hash.Create() will select managed vs csp depending on the framework/core and reg flags.
add >net46 incremental hash logic for swsh
remove static sha256 instance (single threaded overkill)
Further improvements can be made if there's a way to have a union struct (4 u16s, lumped u64) that has a simple 4bit diagonal mirror operation on it. Can be at least twice as fast.
Benchmarking with optimizations shows about 80-90% of the prior time taken, so at least a 10% speed optimization
Rarely used, was fun to try and optimize a little more.
Eliminate bounds checks by accessing/setting the highest element, and only index twice instead of 6x.
Eliminate u16 casts by leaving as int type (same result)
Eliminate temp value caching and instead directly write to storage. (no more _0123).
End result looks neat too, since the >> 0's removed looks like a diagonal, like the nibble rotation :D
Add xmldoc
Remove linq from memecrypto code (speed lmao)
Hide some methods that shouldn't be called directly
Name variables better for accessor const's
GCI, DSV, DUC are already supported, so I've written the abstraction for those and seed the Handler list on startup.
Can add a new class with recognition via SaveUtil.Handlers.Add(myHandler);
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.