On Pickup in Diamond (possibly all Gen4)
Hello,
I just did some research and learn some stuff. Although this may not be very useful, I thought, I'd share it with you.
I wanted to know how the pickup-stuff works in-detail. Originally, I planned to change the function so it would give me items more often (I already patched my Pokeradar and VS Seeker to faster charging methods - using the sun instantly instead of running 50 steps).
Checks for pickup are done at the end of a battle. As the PRNG is cycled like crazy during battle, it seems impossible to precalc or preset the value for those checks.
For the record: I used an english Pokemon Diamond, the simple debugger from free iDeas and four Lv100 Pickup-Slaves.
First, I needed to find the pickup-function. As it needs to call the PRNG I searched for any place in the game that might call 0x0201B9EC (the random function). Those turned out much too many.
So I breakpointed into that function near the end of battle and searched for a savestate in which changes to the seed change the pickup results:
I found a rather small margin: when the screen starts fading to black, it's too late. "wild pokemon fainted" is too early, "own Pokemon gained exp" is too early but not by much. I think it was about 70-80 frames after the exp message that the pickup-results were frozen.
Luckily, I found a state in which I could manipulate the pickup-results by manipulating the seed - so the checks must be done later.
Next, I breakpointed the PRNG and checked where it returns to. It's to be expected that one of them does the pickup-check after it fetches a random number.
I got lots of 222F026. It seems like this is a "do nothing but still cycle like crazy"-function for battle. I also found myself in 2239272 four times and in 2239280 two times. As I got four pickup-slaves with two picking up items (for the seed I savestated), this was a good candidate.
The call to the PRNG from 2239272 is followed by a division by 0xA (ten decimal); the remainder is kept (number between 0 and 9). It is checked against 0, if it is non-zero, the function is done. The interesting thing only happens at zero, which is in (about) ten percent of all cases - the pickup chance stated in literature.
I manipulated the division to always have zero remainder (divide by 1) and all of my pickup-slaves collected stuff.
Naturally, the "which item was found"-part of the function only is called on success. This is the call that returns to 2239280. The random number is divided by 0x64 (100 dec) and again, the remainder is used further - allowing a simple compare to the limits/percentages.
I tried to follow that function any further but got stuck in some strange loop. Instead of iterating just some offsets (like the columns of the pickup-table), it iterated a lot more (does it check on level, too?). I hoped to find a spot where I could force a specific item on the pokemon - maybe even change the pickup-tables - but then gave up.
Instead, I tried to find out which number (remainder of division) resulted in which item:
Code:
0x00 -> 0x1D Revive (30 values, so about 30%)
0x1E -> 0x27 Candy (10 values, so about 10%)
0x28 -> 0x31 Dusk Stone (10 values)
0x32 -> 0x3B Shiny Stone (10 values)
0x3C -> 0x45 Dawn Stone (10 values)
0x46 -> 0x4F Full Restore (10 values)
0x50 -> 0x59 Max Revive (10 values)
0x5A -> 0x5D PP Up (4 values)
0x5E -> 0x61 Max Elixir (4 values)
0x62 TM26
0x63 Leftovers
(I didn't check every number. I just assumed that 0x05 to 0x17 are the same as 0x00 and 0x1D. For each item change, a range was tested. eg. 0x30,0x31,0x32,0x33)
This is strange in two ways:
First of all, PP Up and Max Elixir have the same number of values, thus should have the same percentage. Yet, tables (bulbapedia, smogon) often list one of them with 5% and the other with 3%. Of course, it's possible that the chances are different on other levels but I highly doubt that. Gen5 tables seem to already be corrected to "4%+4%". Is there reason to assume that Gen4 is different?
Also, TM26 is the item that arrives at the Lv91-100 tier, yet has a smaller number. All other items are "shifted in from the right when upgrading pickup level tiers". Of course, this is merely cosmetical.
Regards,
TCC