MeroMero Posted September 16, 2014 Author Posted September 16, 2014 (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. Step 2 Click the NDS icon (or alternatively click Ctrl+N). Expand the window if necessary. Step 3 Right-click on overlay_0012.bin and click Extract (not Export !), this will actually decompress the overlay. 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 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 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. 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. 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 into this . 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 April 9, 2015 by MeroMero Fixed the type chart : again
Alpha Posted September 16, 2014 Posted September 16, 2014 Hey Meromero, Thanks for making this! I have used this before and it is really important in some cases. I'm planning on adding it to PPRE soon enough.
MeroMero Posted September 17, 2014 Author Posted September 17, 2014 (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 April 2, 2015 by MeroMero Dragon and Dark types relationship as defender against a Ghost type move were inverted.
walnut3072 Posted January 27, 2016 Posted January 27, 2016 Thanks for sharing this awesome tutorial. Still waiting for the fascinating unposted discoveries you mentioned.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now