Skeetendo

’Cause all games were better on the GBC

You are not logged in.

#1 2016-06-01 02:53:51

Montblanc
Member
Registered: 2016-02-23
Post 21/47

Help to fix the OLD MAN glitch

Hello,

I am trying to fix that bug, at first I tried to use the same code from the patch that was used for some UE releases (that makes Tentacool to appear in the shore) but then playing the japanese ROM noticed something: not even Tentacool are there in the japanese game, the wild mon (flag? or whatever is called) for the left and right shore tiles are reversed.

collision.png

The tile marked in blue has no wild pokémon, not even Tentacool, in the japanese game while the one marked in red has water pokémon. In the english ROM on the contrary the blue one has wild (grass) mons while in the red one you never find anything.


Is possible to change any data, block, or tile properties so the tile marked in blue will never contain wild mons (not even the water ones) like the red does?

Offline

#2 2016-06-01 17:01:12

Danny-E 33
Administrator
Registered: 2012-06-09
Post 955/1,023

Re: Help to fix the OLD MAN glitch

This is a very funny bug. Here is why it happens..

Your player sprite takes up a 2x2 tile space, so you are on top of 4 tiles at a time.
The coordinates of these four tiles (where the top-left of the screen is 0, 0) are:
Top-left: 8, 8
Top-right: 9, 8
Bottom-left: 8, 9
Bottom-right: 9, 9

When the game is deciding whether or not a new wild battle needs to start, it uses the tile ids of the tiles you are standing on to make that decision.
Let's look at an asm routine, TryDoWildEncounter, at address 0x13870 in an English Red rom.

; try to initiate a wild pokemon encounter
; returns success in Z
TryDoWildEncounter: ; 13870 (4:7870)

[...]

; determine if wild pokemon can appear in the half-block we're standing in
; is the bottom right tile (9,9) of the half-block we're standing in a grass/water tile?
    coord hl, 9, 9
    ld c, [hl]
    ld a, [wGrassTile]
    cp c
    ld a, [wGrassRate]
    jr z, .CanEncounter
    ld a, $14 ; in all tilesets with a water tile, this is its id
    cp c
    ld a, [wWaterRate]
    jr z, .CanEncounter

What this code does is checks the tile id of the tile at 9, 9 (the bottom-right of the player) and compares it to the current map's grass tile (often 0x52), and also compares it to the water tile id, 0x14.
If the bottom-right tile is either the grass tile or the water tile, a wild battle is possible, but the rng still needs to determine if a battle will actually happen.

If the random number generation determines that a new wild battle will begin, this routine then needs to determine which Pokemon the player will be battling. To do this, the game needs to check, for a second time, if the player is standing on grass or water:

; determine which wild pokemon (grass or water) can appear in the half-block we're standing in
    ld c, [hl]
    ld hl, wGrassMons
    aCoord 8, 9
    cp $14 ; is the bottom left tile (8,9) of the half-block we're standing in a water tile?
    jr nz, .gotWildEncounterType ; else, it's treated as a grass tile by default
    ld hl, wWaterMons
; since the bottom right tile of a "left shore" half-block is $14 but the bottom left tile is not,
; "left shore" half-blocks (such as the one in the east coast of Cinnabar) load grass encounters.

Once it is determined that the player is either standing on water or ground, the wild Pokemon species can be grabbed from the appropriate data table. The bug, however, is that this time the bottom-left tile id is checked.

If the player is standing on an east shore, this routine will determine that a wild battle is possible because the bottom-right tile is water. Then it will grab a Pokemon specie from the currently loaded land wild Pokemon, because the bottom-left tile is not water.
Another problem arises because not every map that has water wild Pokemon defined also has land wild Pokemon defined, hence the glitches on the east shore of Cinnabar Island.


To make it so that east shores and west shores will never produce wild encounters just requires small tweaks to this routine.

If you're not already using the disassembly, you should switch. The disassembly is a great way to make big changes to the game and is a lot easier to work with than hex editing.
This routine specifically came from engine/battle/wild_encounters.asm


Red Hack: Pokémon Prototype

Total number of registered users: 7000+
Total number of active users: ~12

Offline

#3 2016-06-01 23:27:49

Montblanc
Member
Registered: 2016-02-23
Post 22/47

Re: Help to fix the OLD MAN glitch

Thanks for your reply!

I'm already using the dissasembly to find offsets and obtaining clues of how the code works or to save time. I build pokered.gbc and then copy or look how the changes or the code looks in hex. Then I can find the same data in the Jap ROM too.

Looking at the Jap Green ROM (x13DBE and x13DFB) seems that looking at the bottom-left tile for both checks is how the game was originally coded. Changing it to the bottom-right one in the first check is what caused the bug: the game was not meant to check the water tile there to determine if a wild mon can appear, but the shore one instead.

In the english ROM if you change the $5D at x1389F to $5C it restores the original behavior of the game (in pokered that's changing the aCoord of the first check to 8,9). I'm going to leave it that way, as it is how the original Green worked.

Last edited by Montblanc (2016-06-01 23:28:47)

Offline

#4 2016-06-01 23:33:37

Danny-E 33
Administrator
Registered: 2012-06-09
Post 956/1,023

Re: Help to fix the OLD MAN glitch

Glad I could help!


Red Hack: Pokémon Prototype

Total number of registered users: 7000+
Total number of active users: ~12

Offline

Board footer

Powered by FluxBB