On Pickup in Gen3-Kanto and Ruby/Sapphire
I decided to check the info for the first game introducing Pickup - of at least of the first games: Sapphire (english). I strongly guess that Ruby and other languages are the same.
The responsible RNG was found rather quickly at 08040EA4 (just search for the multiplicative component of the generator and you don't get many hits in the game code).
It returns to 080005B9 - far too often. It also returns to 0800FD03 - far too often.
The return to 0802AFE5 has a familiar R1=0A and branch to somewhere. This time, the modulo-division is in 081E0EB0.
Again, there is an 0A21 in 0802AFE8 which can be changed to 0121 for experimentation. From there on every pickup try will be successful (something modulo 1 always is zero).
RNG is called again and returns to 0802AFF9. Again, we have a modulo-division by 0x64, resulting in a number between 0 and 99.
- 00->1D Super Potion (0016)
- 1E->27 Full Heal (0017)
- 28->31 Ultra Ball (0002)
- 32->3B Rare Candy (0044)
- 3C->45 Full Restore (0013)
- 46->4F Revive
- 50->59 Nugget
- 5A->5E Protein
- 5F->62 PP Up
- 63 King's Rock
I tried to find 1600170002004400 a number of ways (and alternations) in the image but couldn't find it. It turns out, the table is stored a bit different here:
Starting at 001FAD06 (in image, not in memory), there is a 10-row table consisting of the item number first and a compare value, second. The rnd-mod-100 has to be higherOrEqual all of the previous compare values but lower than the current compare value to get the current row's item.
Example: You should find
in the image - which is to be read as
* if the rndMod10 is lower than 1E (00->1D), give item 0016 (Super Potion)
* if >=1E but < 28, give item 0017 (Full Heal)
* if >=28, continue table
The last entry is strange as it seems to be "if <0x100" instead of "if <0x64" but this seems to be a "catch-all" for the case of modulo not working (or some hackers interfering).
Regarding the compare values: 1E,28,32,3C,46,50,5A,5F,63 translates to
30,40,50,60,70,80,90,95,99, resulting in probabilities 30,10,10,10,10,10,10,5,4,1 - so the widely-spread tables are correct, this time.
For Leafgreen (german version), I decided to go a slightly different path.
I found some "too-often" return addresses (801167F and 800079D) as before and filtering them out, I quickly found 0802CE55 for the pickup check and 0802CE72 for the item-choosing. This time, 0802CE58 has the 0A21 which can be manipulated for 0121 for easier pickup experiments.
But instead of trying out all the possible numbers (or relevant and interesting ones), I just saw that the item-choosing fetches from 08250748 - which translates to 0250748 in the image - and read the information from the table there. If you want to check the table in other languages, try searching for 8B000F0085001900.
- 8B000F00: If <0F, Oran Berry
- 85001900: if <19, Cheri Berry
- 86002300: if <23, Chesto Berry
- 87002D00: if <2D, Pecha Berry
- 88003700: if <37, Rawst Berry
- 89004100: if <41: Aspear Berry
- 8C004B00: if <4B: Persim Berry
- 2A015000: if <50, TM10 (012A)
- 45005500: if <55, PP Plus
- 44005A00: if <5A: Rare Candy
- 6E005F00: if <5F: Nugget
- A3006000: if <60: Spelon Berry
- A4006100: if <61: Pamtre Berry
- A5006200: if <62: Watmel Berry
- A6006300: if <63: Durin Berry
- A7000100: if <256: Belue Berry
This gives the compare values 15,25,35,45,55,65,75,80,85,90,95,96,97,98,99 resulating in percentages
So, like in Sapphire, I can relax and gladly sign the well-spread-table.
Next plans: checking Emerald with low-level-pickups, try to find percentages for the Battle Pyramid (those are missing on bulbapedia).