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)
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
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.
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'
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)
relocate program language enum
test that test case is proper
move getcompatible & gettemplate to core
remove catch rate changing for pk1 (catchrate editor now used instead)
be explicit that the string is empty rather than possibly missing
disallow encrypted export for BK4 (they're not encrypted), removes type
check
simplify replaceall in showdownset (don't call ReplaceAll 4x, just get
valid chars and rebuild)
simplify get ribbon sprite name (precompute ToLower and appended values
Reuse some code in netutil for fetching stream (provide useragent for
all uses)
make sav4ranch use dynamicly read offsets to handle both variants
(quicker) #2248
sav1: assign personal table based on (detected/provided) version
catchrate editor: allow to use savefile personal
remove gb era prompt whenever gb/blank loaded; have it as a setting (can
be overridden for VC now). keep allowgbera as autodetect
personaltable: track format for debugging purposes/info
update translations
showdownset: contains char instead of string
gameinfo: static readonly array instead of redefining new on update
legality: order of operation / value reuse / simplification / comments
pkx: compare char instead of single character string
header/footer: move assignment into method as an out instead of ref
Update handler after friendship update (CurrentHandler needs to update
afterwards)
Fix argument order (gender & nonpresent region data)
#2235 side effect
reducing allocations, increasing clarity by removing some magic numbers
probably can rewrite some of the evo loading/checking for even less, but
good for now.
kinda have to restrict these to 'valid' choices; should be enough of a
selection->result to be adequate for changing version
restart the program after changing the setting; won't take effect until
rebooted.
rearrange pkm version groups for clear break between
twins/siblings/family
clear pokelist for sav7b on non-exportable saves (prevents b1s1 from
showing markings)
rename horohoro (pgo) to non romaji lol, hide daycare/party tabs on
nonexportable save
remove some unnecessary operations
rewrite getallcontrolsoftype to remove ToList() and make generic
remove alloc on gc key advancement; advance keys in place
make g6 sizes an explicit comparison instead of new[].Contains
replace Any/Count with Array.Find calls (removes linq dependency from
savetype detection!)
footer is different for Korean saves; checked JP/EN and they use the
2006 date. Probably the same for everyone-but-KO.
Simplify check further, only check the 0x4.... sav as it's the first
region saved to. No point wasting time checking the other!
a previous commit alluded to general/storage being initialized in
different slots
e8644280a1
, gonna ignore what was stated as I can't find any proof with the few
tests I did today (all init on second, and found no backups from that
time)
footer identifiers work just fine for any legitimately created save
file; I might have had the checksum check code for pokesav blank
savefiles
dropping support for bad-blanks in favor of a non-negligible speedup is
favorable :)
settled on the class name; looks like it'll be roughly readable as a
mystery gift so inherit some properties. maybe can get r/w in the
mystery gift editor :)
Didn't really feel like pulling out the shared structure get/set
operations, only the derived properties & overall fixer methods. Should
be easier to maintain if any handling updates.
Clean up pb7 unused stuff; removes ribbon logic since none are used.
c# 8.0 interface defaults can maybe pull out more logic (ex making
FixRelearn and relearn moves into an interface); multiple inheritance
can be useful as features are added/dropped between generations.
remove lockedslots, store & save all teamslots for sav7
differentiate locked slots from overwrite protected slots by emitting an
enum containing info about the slot
locked = can't be replaced, period.
starter/battleteam = can't be pasted over by bulk-pastes
can eventually show more specific sprite layers to denote party
indexes/team#/starter
Closes#2167
Based off sub_71001D16A0 with shortcut modifications:
* code marks new entries for evolution processing later using the low
bit (hence the << 1); in save files I can't see any bits set, but I
can't see anywhere in the code that DOESNT set this bit. Thus the
assumption of post-processing.
As noted in gameplay, a new capture doesn't set Min and Max; it only
sets it if it is above the usual sizing values.
Megas apparently don't set until seen in battle, so don't worry about
setting the other forme based indexes.
now iterates for all boxes, and restores to the correct offset at the
end
update direct offset pointers to box specific (so that it can work on
gen3 rsefrlg saves if ever used on them).
LGPE uses a list of pkm for boxes, and has pointers indicating where
each party member is at
need some logic for handling the sorting. Had suspected this a while
back so this pre-work came in handy (untested tho)
make eventflags offset ptr virtual, I might end up doing things
differently for event flags
Update comments / xmldoc
Add a savefile storage compressor (ie array[] with empty interstitials
-> list); return true if the compression moved anything (repopulate
views), and the count of occupied slots in the list.
Add saveblock base class; I haven't really liked how SAV6/7 do all the
logic; I'll still expose properties that will then point to a saveblock.
Cuts down clutter.
Add template Dex manipulator, with gen6/7 implementations
Speculate sequential gp/ge gameversion IDs
Check max case for level first, then iterate upwards (eliminates inner
if)
change wc* nature to sbyte (update comparisons, 0xFF too magic-y)
use Rand.Next(x) instead of (0, x)
More languages than Italian have a rule-breaking name. Rework checks a
bit
Flag eggs more accurately
Update force hatch to move Link Trade met location to Egg Location
fix Ho-oh -> Ho-Oh text strings (correctness is key!)
rearrange getmove with respect to tutors; verifycurrentmoves was getting
tutor moves in levelup
extract not-found hint fetch
Expose gen5 block objects (so I can play with saves in linqpad)
can't just re-call base.SetEventFlag with an adjusted flag ID since the
exception checks max.
just override the geteventflag method with a silly adjustment -- we
can't be sure if Block2 is immediately after Block2, so just adjust the
flag r/w to a different offset&flag when appropriate.
fixes r/s badgeflag get/set, oops, meant to modify FRLG's value in the
last commit.
was block2+0x64
8*((0xF80-0xEE0)+0x64) = 0x820
this highlights a critical flaw in event flag reading; it expects the
region to be contiguous in the savedata. it's not. that's super bad, and
event flag r/w for flags >1280 won't work until I work something out
#2128
it's still an imprecise thing, as ingame gifts aren't counted by either
release count isn't tracked, so the number should be roughly >= total
box+party count.
Remove unused sav properties
Add translatable strings for autodetect SAV error suggestion
add speculated gg dex formtable
- no eevee forms
- increments 1 for pikachu since it already exists in table
- stops at mewtwo (no other formed-species available)
im currently setting up skeleton stuff for lgpe since we're <70 days
from release; by doing some pre-work like prior games I can get a good
idea of what needs to be adjusted prior to crunchtime!
Closes#2109
Program boots -> load extra locations rather than constantly fetching.
These files won't change location or presence (not an external drive).
just store the locations instead of constantly fetching, we already call
detect once when loading the form anyway.
V### names weren't enjoyable to work with; use similar verbose style as
the program message strings.
updating the translation files with the remapped variable names shortly
remap list: https://pastebin.com/jybkVDAK
move encountertype datasource providing to core
fix rerolling EC not updating characteristic
remove some repeat logic calls
relocate geolocation name fetch to separate class, add tests to ensure
functionality, add languageID->country/region fetch method
use trainerstat editor control in gen6 editor
fill in some details from the disassembly via setrecord usages
still slightly fuzzy on some:
fureai (based on usum idb name, similar logic)
soaring sky counts
looks like there's some other usages of the fields which were outside
the stat range, throwing an exception when loading to NumericUpDown,
added bypass logic
Thanks Holla!
calling Japanese ? X : Y on every single access is too excessive, just
compute one layout for each type whenever the first sav1 requires it.
could probably reduce the amount of properties by reusing others + shift
value; offsets are different due to string lengths being different
Logic is essentially identical; implement a base class and have the
generation specific structures implment the differences.
Reduce the verbosity a little
utilize unchecked byte overflow
remove unnecessary zeroing -- t's immediately after the checksummed
region. even if it was included, chk += 0 is still 0.
extract GetFormDuration to method, remove unused GetIsCompatible
specialized variant (there's a generalized version in SAVUtil.cs,
IsPKMCompatible -- might do another round of WinForms->Core absorption
original file path is not saved with the two listed properties, add
FileFolder and relcoate existing FilePath functions to that field
move some GetVariantSAV usages to the string method instead of byte[]
bulbapedia is wrong, first 4 bytes are info values:
0x0 = dex order (alphabetical, numerical), unused in frlg
0x1 = mode (unused in frlg), regional vs national
0x2 = national magic rse (always set in frlg)
0x3 = national magic frlg (never set in rse)
refer to disassembly (pokefirered isn't too helpful, less developed.
just compare save files & edit ram!)
the other 2 values being set are the eventflag & event const, could use
the abstraction for those rather than direct ofs writes
tfw they store full egg data there too -- show that in the sidebar
Tested on C & GS (english), assumedly works fine for other languages
(based on the disassembly?)
according to the disassembly it all makes more sense; a small block and
a large block are stored in RAM
util calc helps convert between contiguous section offset to a chunked
offset
eg: emerald daycare starts at large 0x3030, which converts to
chunk4@0x1B0
This commit implements IsDaycareOccupied for generation 1 saves. The
byte which tracks if the daycare is occupied should normally only be
0x01 or 0x00, so I decided that all other values mean that the daycare
is probably corrupted and thus not occupied. SetDaycareOccupied is not
implemented, since I am not sure what other flags the game normally sets
in this scenario and daycare is read-only anyway.
The GUI displays the Pokemon's index to the right for some reason, but I
don't have saves to test this for other generations, so it might be
unrelated to this change.
Rework box fetch in SaveFile to be a little more flexible, can now fetch
a single box
Hold control to... export all boxes :)
I wonder if there's a decorator that showdown skips when importing lines
that can help differentiate the boxes since there's the potential for
hundreds output (ie comments in a showdown set?) doubt it.
clamp species list based on savefile
fix form control index set
remove slot from list (avoid duplicates, there's 530 slots and both
games have more than that available).
Closes#1974
swallow error for invalid filenames in saveutil -- don't bother
detecting those files.
on fail to getmoveset, return the current moves instead of null.
remove todo comment
fix exception when refreshing slot coloring
update box when saveslot index changed, not validated.
update boxviewers when saveslot changes
previous hurdle a year ago was propertyinfo fetching not looking at the
base class's properties; dig deeper for all properties to mimic existing
code for netframework
end result is batch editing now possible without gui
hold control when triggering the sort
sneaky linq to reverse a sort by:
* re-doing the initial sort, then
* reversing the sorted pkm data by using a throwaway increment
* re-doing the final sort
If one wanted to extend ConvertToPKM to other IEncounterables, this
would be the provided obj containing the receiver's info
allows pkm gen without a savefile, which is nice?
party stats set when setting a slot to a save file
simplify set/delete slotchange duplicate logic
suggest better met locations beyond VC transfers
hatching a gen6 egg applies memories automatically