Jump to content

Recommended Posts

Posted (edited)

Greetings everyone.

I'm MeroMero (member on Smogon who responds by the same name)

I joined Project Pokémon just so I could share my findings.

Some notes:

When an offset is followed by an asterisk (*) ,it means that the offset differs between different regions (and sometimes between games of the same region).

Complete type chart

This is the type-chart:

000505
000805
0A0A05
0A0B05
0A0C14
0A0F14
0A0614
0A0505
0A1005
0A0814
0B0A14
0B0B05
0B0C05
0B0414
0B0514
0B1005
0D0B14
0D0D05
0D0C05
0D0400
0D0214
0D1005
0C0A05
0C0B14
0C0C05
0C0305
0C0414
0C0205
0C0605
0C0514
0C1005
0C0805
0F0B05
0F0C14
0F0F05
0F0414
0F0214
0F1014
0F0805
0F0A05
010014
010F14
010305
010205
010E05
010605
010514
011114
010814
030C14
030305
030405
030505
030705
030800
040A14
040D14
040C05
040314
040200
040605
040514
040814
020D05
020C14
020114
020614
020505
020805
0E0114
0E0314
0E0E05
0E1100
0E0805
060A05
060C14
060105
060305
060205
060E14
060705
061114
060805
050A14
050F14
050105
050405
050214
050614
050805
070000
070E14
071105
070805
070714
101014
100805
110105
110E14
110714
111105
110805
080A05
080B05
080D05
080F14
080514
080805
FEFE00
000700
010700
FFFF

Here is its format :

AA DD EE

_AA : attack type

_DD : defender type

_EE : effectiveness

those 3 bytes are repeated consecutively for basically each type, and the table will end at the first occurrence of AA DD equal to FF FF.

AA and DD can take one of the following values :

_0×00 : Normal

_0×01 : Fighting

_0×02 : Flying

_0×03 : Poison

_0×04 : Ground

_0×05 : Rock

_0×06 : Bug

_0×07 : Ghost

_0×08 : Steel

_0×09 : ???

_0×0A : Fire

_0×0B : Water

_0×0C : Grass

_0×0D : Electric

_0×0E : Psychic

_0×0F : Ice

_0×10 : Dragon

_0×11 : Dark

EE can take one of these 4 values :

_0×00 : ineffective

_0×05 : not very effective

_0×0A : normal damage

_0×14 : super effective

As you have guessed, EE is actually a multiplier, but before the effect is applied, EE is divided by 10, thus the origin of the coefficients ×0, ×0.5, ×1 and ×2 !

But there's a first problem, if you try to search for 00 05 05 00 08 05 0A 0A 05, etc. in the ROM, your hex editor of choice will return no results!

This is because the overlay that contains the table (overlay 12 here) is LZ-compressed.

Decompress it with Crystal Tile 2 for example.

Okay now you search through the decompressed overlay 12 with your hex editor, and now you have found the string, great; but there's a second problem!

Look at the table, there's no EE bytes whose value is equal to 0×0A!

That's because 0A is the default multiplier in Gen 4 Pokémon games, which is why ???-typed moves/Pokémon deal/take neutral damage to/from everything. But unlike Gen 2 and Gen 3, thanks to the Physical-Special split, ???-typed moves are actually able to deal damage greater than 1HP (read real damage).

How is it going to affect us?

Well you're going to have a hard time if you want to port the Fairy-type's effectiveness in HGSS (for the sake of an example).

If you try to add (DON'T !) even only one more relationship, once you get into a fight you will break the game since the code will read wrong instructions from everything in the overlay 12 that come after the type table…

How to trick the game then?

First you have to understand how the game works:

Let's say you have 2 main states in Pokémon games, the overworld and the fights.

The game needs to load the following overlays for the overworld: 1, 2, 3 and 27 (Group 1)

And it needs to load these for the fights : 6, 7, 10, 12, and 18 (Group 2)

Actually the overlay 10 is loaded every time you get to choose your action, the overlay 7 when you have chosen said action (and initially at the beginning of the fight too).

Once you press continue on the menu screen, the game will load the group 1, and when you get in a fight, it will load the group 2, once you are finished with your fight the game will load again the group 1, etc.

You can see that with the RAM Viewer around address 0×021D0E00 for those who are curious

It's something like this:

Overworld:

01 00 00 00 01 00 00 00 02 00 00 00 01 00 00 00
03 00 00 00 01 00 00 00 1B 00 00 00 01 00 00 00

Fight:

0C 00 00 00 01 00 00 00 12 00 00 00 01 00 00 00
06 00 00 00 01 00 00 00 0A 00 00 00 01 00 00 00

If you parse through the RAM, you'll see that when the overlays from one group are loaded, the previous overlays who happened to be there will be overwritten.

The trick here is to find a place in the RAM that is not used during the fights and that could be used to fit in the new table.

And such an area exists!

It just so happen that overlay 18 and overlay 1 have the same offset in the RAM, but ovl_1 is much longer than ovl_18! That's exactly what we need.

What does it means? It basically means that the ovl_1 leftovers is basically free space during the fights!

That's something easy to prove, fill the bottom of overlay 18 with FF's until overlay 18 is the same size as overlay 1, reinsert the overlay 18 in the ROM and when you go into a fight, you'll see by yourself that the game doesn't crash!

Modus Operandi

Step 1

Open your Pokémon HeartGold or Pokémon SoulSilver ROM in Crystal Tile 2.

jZ5kopU.png

Step 2

Click the NDS icon (or alternatively click Ctrl+N).

o1dBYjV.png

Expand the window if necessary.

Step 3

Right-click on overlay_0012.bin and click Extract (not Export !), this will actually decompress the overlay.

6KFLMu3.png

Step 4

Do the same for overlay_0018.bin.

Step 5

Open both decompressed files in a hex editor.

Step 6

Add your improved type-chart at the end of overlay_0018.bin

rL0m7mR.png

I advise you to make a full chart with all 324 relationships from the get-go, so that if you want to change something, you won't have to go through all the trouble again.

Or you can take mine, which is up to date with the relationships according to Gen 6 :

00000A00010A00020A00030A00040A00050500060A00080500090A000A0A000B0A000C0A000D0A000E0A000F0A00100A00110A
01001401010A01020501030501040A010514010605010814010905010A0A010B0A010C0A010D0A010E05010F1401100A011114
02000A02011402020A02030A02040A02050502061402070A02080502090A020A0A020B0A020C14020D05020E0A020F0A02100A02110A
03000A03010A03020A03030503040503050503060A030705030800030914030A0A030B0A030C14030D0A030E0A030F0A03100A03110A
04000A04010A04020004031404040A04051404060504070A04081404090A040A14040B0A040C05040D14040E0A040F0A04100A04110A
05000A05010505021405030A05040505050A05061405070A05080505090A050A14050B0A050C0A050D0A050E0A050F1405100A05110A
06000A06010506020506030506040A06050A06060A060705060805060905060A05060B0A060C14060D0A060E14060F0A06100A061114
07000007010A07020A07030A07040A07050A07060A07071407080A07090A070A0A070B0A070C0A070D0A070E14070F0A07100A071105
08000A08010A08020A08030A08040A08051408060A08070A080805080914080A05080B05080C0A080D05080E0A080F1408100A08110A
09000A09011409020A09030509040A09050A09060A09070A09080509090A090A05090B0A090C0A090D0A090E0A090F0A091014091114
0A000A0A010A0A020A0A030A0A040A0A05050A06140A070A0A08140A090A0A0A050A0B050A0C140A0D0A0A0E0A0A0F140A10050A110A
0B000A0B010A0B020A0B030A0B04140B05140B060A0B070A0B080A0B090A0B0A140B0B050B0C050B0D0A0B0E0A0B0F0A0B10050B110A
0C000A0C010A0C02050C03050C04140C05140C06050C070A0C08050C090A0C0A050C0B140C0C050C0D0A0C0E0A0C0F0A0C10050C110A
0D000A0D010A0D02140D030A0D04000D050A0D060A0D070A0D080A0D090A0D0A0A0D0B140D0C050D0D050D0E0A0D0F0A0D10050D110A
0E000A0E01140E020A0E03140E040A0E050A0E060A0E070A0E08050E090A0E0A0A0E0B0A0E0C0A0E0D0A0E0E050E0F0A0E100A0E1100
0F000A0F010A0F02140F030A0F04140F050A0F060A0F070A0F08050F090A0F0A050F0B050F0C140F0D0A0F0E0A0F0F050F10140F110A
10000A10010A10020A10030A10040A10050A10060A10070A100805100900100A0A100B0A100C0A100D0A100E0A100F0A10101410110A
11000A11010511020A11030A11040A11050A11060A11071411080A110905110A0A110B0A110C0A110D0A110E14110F0A11100A111105
FEFE00000700010700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

Step 7

In overlay_0012:

search for 7CCC2602* and change it for 60BE1F02* (4 occurrences)

search for 7DCC2602* and change it for 61BE1F02* (3 occurrences)

search for 7ECC2602* and change it for 62BE1F02* (3 occurrences)

Language     original pointers    updated pointers

Japanese     78C12602             E0B01F02
            79C12602             E1B01F02
            7AC12602             E2B01F02

English      7CCC2602             60BE1F02
            7DCC2602             61BE1F02
            7ECC2602             62BE1F02

French       9CCC2602             A0BA1F02
            9DCC2602             A1BA1F02
            9ECC2602             A2BA1F02

German       5CCC2602             60BA1F02
            5DCC2602             61BA1F02
            5ECC2602             62BA1F02

Italian      1CCC2602             20BA1F02
            1DCC2602             21BA1F02
            1ECC2602             22BA1F02

Spanish HG   9CCC2602             A0BA1F02
            9DCC2602             A1BA1F02
            9ECC2602             A2BA1F02

Spanish SS   BCCC2602             C0BA1F02
            BDCC2602             C1BA1F02
            BECC2602             C2BA1F02

Korean       80D62602             A0C41F02
            81D62602             A1C41F02
            82D62602             A2C41F02

c8wWQnh.png

As you have guessed, the pointers will point to the type table, what you did here is relocating the pointers to the new and (admittedly) more complete table.

Step 8

Save both files and close your hex editor.

Step 9

Back to Crystal Tile, right-click on overlay_0012.bin and click Compression, this will actually import the LZ-compressed of your file back into the ROM.

XwQqTcW.png

Step 10

Do the same for overlay_0018.bin, but be careful now the file is too large to be contained between ovl_17 and ovl_19 even when compressed ! Don't panic, Crystal Tile will take care of that for you.

FykDI0E.png

Just click OK.

Step 11

Close Crystal Tile 2, and now your ROM is ready.

Want to make Poison super-effective against Water ? Sure thing mate.

Want to make Ice resistant to Dragon ? Knock yourself out !

Want to add all the Fairy type relationships ? That's the reason that drove me to think outside the box and find a way to present you this.

Wow ! And I'm still not done, but others discoveries will be for another time, I think those will take enough of your time to swallow.

Other discoveries include:

  • Change this lCtcXPZ.png into this ylomNiS.png.
  • Adding a functional item (why not, the Pixie Plate).
  • Adding sprites for items.
  • Adding an item's effect ID to the list of ×1.2 type-enhancer items.
  • Editing the Incense-babies.
  • Edit the move Judgment so it takes into account the Fairy-Type, yes the case for type 9 is not taken into account in the move's code.
  • Edit the checks for Heal Bell against Soundproof so that Heal Bell acts exactly like Aromatherapy.
  • Restoring the destroyed code to trigger Evolution methods 18, 19 and 1A.
  • Edit Pokémon coordinates and shadow on the battlefield (not by me).

And last but not least, a teaser for what's new to come, and yes you'll see I'm definitely NOT Hollywood tier when it comes to teasers/trailers:

[video=youtube;BHOG8QNhkJY]

Edited by MeroMero
Fixed the type chart : again
Posted (edited)

Oops! Seems like Poetic Justice did another victim, me. In my case it was my clear lack of Foresight.

Jokes aside, I overlooked something; while the string FFFF is important since it marks the end of the type chart, I would have never guessed that the string FEFE00 would be equally important.

Turns out that the code checks for that particular string when it comes to the moves Odor Sleuth and Foresight as well as the ability Scrappy (Miracle Eye has its own check and thus is not affected).

It affects every relation between types after the string FEFE00.

When I found out, my brain went "Uh, oh…"

My apologies, here's the fixed version of the type chart:

00000A00010A00020A00030A00040A00050500060A00080500090A000A0A000B0A000C0A000D0A000E0A000F0A00100A00110A
01001401010A01020501030501040A010514010605010814010905010A0A010B0A010C0A010D0A010E05010F1401100A011114
02000A02011402020A02030A02040A02050502061402070A02080502090A020A0A020B0A020C14020D05020E0A020F0A02100A02110A
03000A03010A03020A03030503040503050503060A030705030800030914030A0A030B0A030C14030D0A030E0A030F0A03100A03110A
04000A04010A04020004031404040A04051404060504070A04081404090A040A14040B0A040C05040D14040E0A040F0A04100A04110A
05000A05010505021405030A05040505050A05061405070A05080505090A050A14050B0A050C0A050D0A050E0A050F1405100A05110A
06000A06010506020506030506040A06050A06060A060705060805060905060A05060B0A060C14060D0A060E14060F0A06100A061114
07000007010A07020A07030A07040A07050A07060A07071407080A07090A070A0A070B0A070C0A070D0A070E14070F0A07100A071105
08000A08010A08020A08030A08040A08051408060A08070A080805080914080A05080B05080C0A080D05080E0A080F1408100A08110A
09000A09011409020A09030509040A09050A09060A09070A09080509090A090A05090B0A090C0A090D0A090E0A090F0A091014091114
0A000A0A010A0A020A0A030A0A040A0A05050A06140A070A0A08140A090A0A0A050A0B050A0C140A0D0A0A0E0A0A0F140A10050A110A
0B000A0B010A0B020A0B030A0B04140B05140B060A0B070A0B080A0B090A0B0A140B0B050B0C050B0D0A0B0E0A0B0F0A0B10050B110A
0C000A0C010A0C02050C03050C04140C05140C06050C070A0C08050C090A0C0A050C0B140C0C050C0D0A0C0E0A0C0F0A0C10050C110A
0D000A0D010A0D02140D030A0D04000D050A0D060A0D070A0D080A0D090A0D0A0A0D0B140D0C050D0D050D0E0A0D0F0A0D10050D110A
0E000A0E01140E020A0E03140E040A0E050A0E060A0E070A0E08050E090A0E0A0A0E0B0A0E0C0A0E0D0A0E0E050E0F0A0E100A0E1100
0F000A0F010A0F02140F030A0F04140F050A0F060A0F070A0F08050F090A0F0A050F0B050F0C140F0D0A0F0E0A0F0F050F10140F110A
10000A10010A10020A10030A10040A10050A10060A10070A100805100900100A0A100B0A100C0A100D0A100E0A100F0A10101410110A
11000A11010511020A11030A11040A11050A11060A11071411080A110905110A0A110B0A110C0A110D0A110E14110F0A11100A111105
FEFE00000700010700FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

Edited by MeroMero
Dragon and Dark types relationship as defender against a Ghost type move were inverted.
  • 1 year later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...