split some methods with optional parameters=null
add more xmldoc
replace some magic numbers -> enum/const references
consolidate common array operations (span soon maybe?)
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)
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
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.
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.
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
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
hide setters for LegalInfo outside assembly (shouldn't overwrite the
stored values)
update GenNumber to Gen* if appropriate; GenNumber checks for first Gen*
to match, is a little more explicit and quicker than calling twice when
checking a range
Set default values to prevent any properties from being null
extract ClearNickname logic for hot path & reusable method
extract item conversion and move to appropriate logic class
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
still isn't close enough, but removes the usage of decimals for cp calc.
redd.it/ahac9i
CP calc doesn't flag anything I have that is legal, but the calc is
still off by 2 bits at most... whyyyy? Even the same code run in cpp
results in the same inaccuracy? Maybe this is some arm64 difference?
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
don't continue; instead seek forward
#2235 part 1, need surgery for part 2 (starter/locked prevents writing
data to the slot, but the slot can still be swapped)
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.
All IVs are flagged in LGPE even if they're perfect :(
Might have to revisit this for future games and if LGPE transfer out and
maintain these bad flags (this is bad for inspecting parents before
breeding).
Closes#2229 , thanks @SteelPhase (report) and @sora10pls (verified)!
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 linq for characteristic calc (get max IV) and others
remove some reliance on new[] for iv/ev
pk5 replace bitmagic with property get->set copy for cleanliness
how did this get forgotten so easily lol
added legality check; eggs can't participate in pokestar studio.
not editable from GUI, use ExtraBytes editor.
Re-add 0x86 (array was copied from pk4?) and reorder/comment
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.
Make extrabytes a pkm property (don't mutate array pls)
reconfigure startup loading to only initialize after initial load of sav
& pkm (using blanks if not provided)
there's a value in trainer pokes that gets set to an unused pkm byte
this byte is fetched in the stat/cp calc, but is never used (param
unused)
plans for future? it's right next to friendship in trpoke7b, maybe there
might be another stat amp?
https://www.serebii.net/magikarpjump/trainerrank.shtml
stronger trainer => stronger monz /speculation
2d array -> 1d
skip copy by cloning instead
eliminate %24 (number is 0-31) by duplicating 0-7 as 24-31
dropping a modulo, >1 bounds check, and a half loop unroll should be
less cpu cycles :)
Closes#2160 , use Batch Editor to modify slots; it's not worth GUI
presence as it's only saved for party format mons and is undocumented
for anything besides affliction flags
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.
Starter Pikachu & Eevee have different growth rates than their base
forms (seriously WHY?)
remove old api surface in PKX as a breaking change as adding the
parameter is necessary.
Derived from WC7 with minor alterations (dynamic OT/Nickname which is
stored in the Full data). Since the 0x108 is not stored in the save
file, just keep the full data around.
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!)
0, [9,19] are set (didn't see 15), but there's also a switch case which
references all values 0-19.
these values are used by a 80 sbyte array (4*20) in the Resort.cro
remove usages of "goto case"
Logic is essentially identical; implement a base class and have the
generation specific structures implment the differences.
Reduce the verbosity a little
pk1 boxdata stores current level & current hp, which is only present in
pk2 party data.
if the user drops in pk2(boxdata), the transfer leaves 0 for both
values, which isn't correct.
detect stat_level to determine if values should be regenerated or not.
Thanks HaxAras for finding this :)
Remove unnecessary floor operation, don't fetch stat arrays for each
stat
Current HP is a box stat in pk1 format (offset 0x1), which isn't stored
in box pk2's. If the hp is zero, set it to the current HP.
Thanks HaxAras for the conversion tip!
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
convert all dictionaries to char-byte instead of string (saves 50KB on
compressed dll, lul)
update OT string comparison for pre/post transfer specimens
Showing "TRAINER" for all languages isn't correct, just show a mapped
character
Closes#2049 , thanks @egzonqj & @WEERSOQUEER !
reduce pk3/ck3/xk3 logic, share AbilityBit property within _K3, and when
loading, type check (favored over hardcoding individual load cases)
pull some non-gui code from PKMEditor to core/etc for general data
fetching
Yeah forgot that extremely bad RNG rolls (0,0,0,0,0) leaves 510
remaining, and the last EV can't have that much
rework loop to be simpler & quicker by checking the last IV for validity
only
(don't bother keeping it unrolled
all usages besides fetching a 32bit random value should use rand.next
remove unnecessary do-while loop for calculating random EVs (always
returns 510 in total)
gender: take top 4 bits of gr:
31 = 0x1F = 1
63 = 0x3F = 3
127 = 0x7F = 7
191 = 0xBF = 11
See the pattern? If we change the compares from >= to >, we -1. All
numbers match except for the 25/75 ratio pkm... which unveils the
problem.
Simplify the calc for these using the logic above, which fixes the error
and makes the code easier to read!
Thanks SystemError for assisting :)
easy modification which isn't 'random' resulting in a slightly higher
chance of retaining the current gender if possible. threshold values can
change genders (1f:7m), but is slicker overall
Checks.cs initially started out small, but over the years it has grown
to handle multiple types of checks. With all these checks next to
eachother, it's hard to see the overall groups. Splitting them up
(potentially further?) allows for more focused maintenance &
understanding.
Not sure if I'm happy with the overall bandaids used (checks no longer
done within LegalityAnalysis so variable repointing is excessively
used), but I'm happier the way it is now compared to the huge Checks.cs
Add safari min flawless IVs to reroll (can expand if #2025 is required
for egg group15)
Use EV/IVTotal (faster, not linq array based)
Fix missing pumpkaboo form regression, Closes#2026
Relocate swapbits to appropriate class, unneeded in PKM.cs
continued simplification
core.cs is pretty much the following:
misc one-off junk
moveset fetch
encounter table fetch
evo chain fetch
might eventually move things around a bit further for cleanliness so
that misc meta junk is the only thing that remains in core.
update handling that checked for this case to instead check for
equivalence to ability1 instead of 0
was generating a PGF with ability[1] = 0, which is not correct. Just fix
the binaries to behave and get rid of all the workarounds since future
tables don't have missing values.
stored as wc3's, make "Version" from IVersion rather than int so that
"WasXD" recognizes it.
Update handling for fateful encounter trade-away cases.
#1970
amount of pkm obj classes is pretty high, move the static utility
classes to another folder
breaks usage of pkm.ShowdownText; removes a dependency from PKM.
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
1123c24b0c
had addressed the loading, however, it did not address the saving
update pkx to not create a new array every time IsPKM is called
(possibly a lot)
reference PKHeX.Core, main window loads assemblies & initializes
providing an ISaveProvider and the menustrip control (to insert controls
into)
pretty rough but should allow for inserting external control buttons &
allowing it to edit the UI a little
example: https://github.com/kwsch/PKHeXPluginExample
feedback is appreciated
Closes#1933
if not allowed to be genderless, flag as invalid gender
only permit valid genders after genderless is ruled out
(both done by checking the low bit)
Store 4g giratina held item for enc->pkm legality
revise usages of GetSaneGender
Rearrange some logic
Better handle impossible version encounters (gen4)
gen 1-5 done, stuck on 659 - bunnelby egg...?
Adds IV count sorting
Adds Itemless & Illegal deleting
Adds Max level modding, item clearing. Handle egg cases sensitively.
remove final sortby for reversal case as the incremental integer
prevents further ordering.
Any suggestions? Keep in mind that some modifications can be done by the
Batch Editor scripts; smart deletions & sorts are highest value
additions ;)
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
Nest item choices into separated groups (based on their overall
function).
Adds 3 more deletion options: eggs, untrained, or not-matching-savefile.
Adds 1 more modification option: Max Friendship of current handler
Closes#1912 , genderless ~= fixed gender I guess; shouldn't get these
gender-errors unless it's manually tampered data/ShowdownSet
remove unnecessary code in:
* PKMEditor (>=255 is already covered by == 255 and the fact that gt is
always <= 255)
* VerifyGender (3 <= x <= 5) check is already early-returned via
PIDGender check above
Update IsGenderValid knowing that VC mons have a gennumber <= 2
gen4 and below saves don't provide an accurate Version/Game; ignore the
version check if it is not a valid game ID.
secondary sort to current OT name so that same-named OT (ignoring case)
are immediately after the current save's pkms.
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
WinForms->Core logic absorbing (CommonEdits)
loading ShowdownSet now applies properties to PKM instead of PKMEditor
Contest/IVs for Static/Trades are no longer set by default (less object
allocations), and are now checked by the encounter generator
extract common nature amp logic
generic ienumerable copyto which now returns count of elements copied
(maybe useful later). prior usages never tried to copy an enumerable
larger than the dest array (now length checked).
If the Hidden Power set doesn't match what is required (missing Hyper
Trained IVs), will need to adjust IVs.
Compute the first matching hidden power IV set by permuting flawless IVs
to flawed.
Closes#1821
reflection (now only used for backwards conversion) will use destination
order instead of source order so that the destination can order itself
for quirks
redo method call (probably breaks someone if they update, maybe pk2pk)
standard generation 3 pkm content & interactions
generic inter-converter (more efficient than reflection)
update conversion methods; specific format conversion is now in the
object's src file now.
may be worth doing for gen4 pk4<->bk4
StringLength is the raw buffer size, needs to be offset by 1 as the
string length enforced does not consider the terminator
12char OT name in sav7 loaded to tabs -> load gen1/2 save = exception
(now fixed)
condense repeated logic, reduce overall operations
removes 1 array alloc for pkm encryption (shuffle clones the array, so
don't clone->clone)
removes 1 array alloc for pkm decryption (mutate encrypted array), be
aware that no current use cases input an encrypted region and expect the
reference to stay encrypted (always was a temp array).
remove duplicate bounds checks (early return & for loop)
GetBytes returns an array that is immediately discarded (GC pressure)
reduces overhead when loading large pkm collections from save files
(shaved off a couple seconds from my loading from 200+ bak saves)
could probably go faster with unsafe code to r/w ushort directly
then again im profiling under debug but i'd assume the improvements made
actually do improve speed for release builds
Species and Nicknamed params were never used; foreign always resulted in
true for cases when it actually mattered.
Filter to the non-fullwidth characters, check the char type (latin base
vs jp/zh/ko) in order to determine if the full/half symbols should be
squished
could be faster replacing char instead of string, so change those
add two test cases for half width & full width string
sanitization/unsanitization
fix bk4 ribbon checks (lacked interface inheritance)
change MN -> UM for get blank save (unused in PKHeX solution)
prevent inheriting from derived pkm classes
get language list now doesn't return new objects (or re-enumerate)
update rand usage to be inclusive for top bound, extend shuffle to
collections
remove unnecessary location overrides (already overriden in legal fetch)
Some species have the same unicode name in CHS and in CHT, so it will lose language info after converting from a in-game string to textbox (The game will use different fonts to distinguish them, bad GF)
This change will give CHT encoding a higher priorty if the pkm is in CHT, although it's possible to get CHS encoding default species name with CHT language ID.
Also fixed previous editing error
transporter/bank parsed:
fix 벵벴 swaps (verified ingame)
switch ⋯ for … to match bank
add blank space (u3000) for 0xFF to match bank
note 0xB6C is incorrectly 0xB6D in transporter (=> "."); not an issue as
not a valid char choice ingame.
table data dump: https://pastebin.com/R254mB9p
reproduce via exefs: (kor1-B table followed by english analog
kor_table0)
int ofs0 = 0x1BE3C0;
int ofsK = 0x1BBE48;
int len0 = 0x130;
int lenK = ofs0-ofsK;
A+ parsing: https://pastebin.com/FAxpadxs
pull out transfer locations to const references
add vc2 & crown beast/celebi met location suggesting
add vc2 crystal sensitive detection
add 2 more usum trainer stats (thanks holla!)
fix roamer3 not setting IVs
fix usum z items rightmost pixel getting chopped off
use Gen* instead of GenNumber for specific cases (faster)
add WasGiftEgg location case for Gen7
remove some unnecessary array allocations
add german forme names
truncate some forme names
fix nidoran gender symbols
adds null check for invalid (caught error) pkm
disables accessory giving (needs more research)
more usum prep
don't allocate empty array on every savefile creation (use linq All
comparison)
add percent seen/caught savefile properties for data analysis purposes
closes#1550 , mgdb/pkmdb throw unconverted files which need conversion;
move main file load conversion to a reusable method and have pkmeditor
call it on every load.
add skip argument to ignore the conversion check (ie if the file is
loaded from an undoubtedly same type source).
Closes#1540 , check for german only characters (gen1/2 can trade
between resulting in only OT being checkable). May be worth changing the
german check to return an int instead and check for other language
specific values.
natures (>25) are invalid and causes IndexOutOfRangeException due to
being greater than the length of the array.
sanity check array length and amped stat prior to applying amplification
Closes#1515
fix ranch pkm hacks being treated as valid (wrong severity)
fix xml docs relative to recent changes
move kata/hiragana charmapping to be like the Farfetch'd alias
{"'", 0xE0}, // Alias ' to ’ for Farfetch'd
{"’", 0xE0},
- G1/G2 only have Hiragana letter he -> fixed Houndoom(ヘルガー) /Heracross (ヘラクロス) default name mismatch
- Fixed Stadium2 Farfetch'd move (Thrash -> Slash)
- Added VC Mew TID check
- Update Chinese legality strings
Resolves charmap duplications in the chinese char tables:
多边兽Z (Porygon-Z)
属性:空 (Type Null)
谜拟Q (Mimikyu)
卡璞・鸣鸣 (Tapu-Koko)
Games cannot have a nickname/OT in chinese as of current date... I
assume this will be fixed down the road
extract pkm loading routines to smaller methods
reduce code duplication (rely on empty setters to ignore some calls)
should be much easier to understand the load/save process; the original
setup (pk6) was following the structure from 0x00-end, no point still
doing that as everything is now abstracted.
Both characters map back to character 0x83, but 0x83 previously mapped
back to the lowercase variant which was unlike the others.
(オ and ォ -> オ)
Thanks Afepoke & smileynation!
expose some useful IEnumerable methods (sorting / bin->pkm / copy) to
simplify some common operations
change some explicit arrays to IList for flexibility
remove old memecrypto bool (no longer necessary as XP is not supported)
rename some methods for more clarity
Restriction happens because Korean can not trade with non-Korean GB era games
- There is no Korean release for gen 1 pokemon, included VC
- With no gen1 pokemon means any Korean gen2 is Gen2_NotTradeback, that means no gen1 origin nor moves are Legal
- Crystal was never released in Korean
- Pokemon Stadium 2 was never released in Korean, that means no move reminder for gen 2 korean pokemon
- Generation 4 can not trade between Korean and not Korean games, but Korean games can use the palpark with any language
Chinese language restrictions
There is no Chinese release for gen 1 and 2 pokemon games, VC Chinese games are in Japanese
extracted the GetNonNicknamedBytes method (used in SetNotNicknamed and
GetIsNicknamed)
korean strings are variable byte width so using max string length is
insufficient
* allow gen2 to have evolutions on gen1 when transferred to gen7
(Core.cs)
* handle korean strings on transfer slightly better (pk2.cs)
* auto-set johto location when changing game ID
* auto-detect VC saves (all have extensions with .dat)
Closes#1478 , thanks @NinFanBoyFTW !
regex matching takes a lot more time and is a cosmetic / easily fixable
issue (reset to no nickname / default OT).
Add a prompt to temp turn off those checks to drastically speed up
search (no regexes done).
Fix unsanitize for gen6 (should have been >= 6, aka starting with gen6)
farfetch'd apostrophe mapping disabled for gen5 and prior
Closes#1474
flag gen2 new moves as not obtainable if transferred from RBY (VC1) as
they must be removed before transferring 2->1.
I think egg hatch location checking is wrong for traded eggs (see gen3
vs future games, origin game shouldn't change but could hatch ORAS egg
on XY at XY location?)
species added requires the 'latest personal table' reference to be
USUM's; the other referencs for .SM are fine as there's no possibility
to have a species ID high enough for it to matter.
add docs, move some data fetching to more appropriate class
remove old XP memecrypto support handling, was previously removed due to
net standard/core split
refactor memecrypto to handle multiple save sizes (USUM won't be the
same size save file); placeholder -1 for USUM size
Checks for max language ID on transferred pkm (gen5 pkm on gen7 can't
have CHS/CHT etc)
handles edge case for JPN B/W ingame trades
update pk5->pk6 transfer logic to bump langID 0 to 1.
Thanks HaxAras & Britty for providing samples!
Closes#1451 , was caused by empty party writebacks (was reading from
wrong offset
dex caught/owned offset was listed as 0x28AE in the thread, is at 0x2AAE
instead (-0x20 from seen)
should have correct offsets and handling now :)
Closes#1409, fr entries weren't tab separated
Closes#1408, editor interface was correct (refer to checkbox order
comment in Pokedex4.cs)
Closes#1407, XY species were copypasted to AO's
necessary for reflection property transferral (ie language)
indirectly fixes mixed-bit properties (ie altform/gender) as they are
reversed bits relative to pk4.
fixes 10ANIV pikachu having Thunderbolt twice
un-duplicates CHANNEL event data
adds seed->PIDIV generator template for M1/2/4, CXD, Channel, and BACD
improve pkm converter to update nickname of hatched eggs. isn't perfect
(farfetch'd) but works better than before
Detect channel, only detect Channel PIDIV for RS origin (only really
care about method1/2/4 being used when it shouldn't)
Channel does this weird thing called not setting the met level.
Refactor set suggested met location to a method that can suppress
popups.
Valid species/movepools are already determined via the dexlevel and
prior methods, no need to check again with current species.
edge case: sing froslass from CXD won't check gen3 moves (ie, sing)
Returned messages are slightly misleading since missing/invalid are
mixed together with the static method.
#1250
~322 lines to check ribbons, on top of the interface abstraction... so
much required... kinda understandable as there's over 100 ribbons to
check.
remove legality check's use of reflection which checked individual
properties; add interfaces to interact with the ribbons of each PKM
type. With this, every ribbon attribute is accessible via its
corresponding interface (cast)
will have to add checks for individual interfaces as per #1250
I didn't feel like adding much documentation, is pretty straightforward.
Cast a pkm object to the desired ribbon set; if not null, can access
ribbons regardless of pkm format.