Not sure how many would actually be interested in this but I recently discovered an archived thread by Háčky and their disassembly of some e-Reader cards for Ruby & Sapphire, pokecarde.
The e-Reader functionality was inaccessible in Pokemon Emerald versions outside of Japan but is still within the code and can be enabled to accept eCards.
And with pokeemerald eTrainers can be customised further to have 6 pokemon and use expanded pokemon, moves and items.
The Eon Ticket eCard works as well and also can be customised to create event gifts.
I've been playing around with making custom eCards and thought I'd write a tutorial in case anyone else is interested.
1. Setting Up pokeemerald
I found out how to reactivate the e-Reader from CitrusBolt's Pokemon Heliodor and the translation is from Sierraffinity's CrystalDust, so big thanks to them!
1.1 Activating e-Reader functionality
This will show the Mystery Event option when Mystery Gift is unlocked. And also gives translations for the Japanese text.
Code changes here.
1.2 Removing region lock (Optional)
This is only necessary if you want to use eCards from different regions.
Code changes here.
2. Building eCards
Hatschky's original repository can be used for Ruby, Sapphire and our now modified Emerald, albeit with some differences (eg. Trainer classes won't be correct in Emerald).
But I have also made branches for Emerald, to fix the differences, and also for Rom Hacking Hideout's pokeemerald-expansion to allow for the expanded pokemon, attacks and items.
Pokecarde Disassemblies
For Ruby&Sapphire
For Emerald
For pokeemerald-expansion
Now that's out of the way you can go to the battle-e directory using a command line tool (WSL works best, powershell causes some issues) and build them using
The eCards should then compile into .raw files!
To make the Eon Ticket copy the programs you extracted to pokecarde/battle-e to pokecarde/eonticket (rgbasm, rgblink, nedcmake, nevpk, nedclib.dll) and use the make command.
This builds an English and German version of the card.
How to use eCards
For them to work you need to have unlocked Mystery Gift in your save.
I've been able to get these cards working with VisualBoyAdvance-M v2.1.4. as well as mGBA.
You can also print them off for use with a real e-Reader using CaitSith2's Nintendo eReader DotCode Printer. I haven't got an e-Reader myself so I haven't confirmed that custom eCards work.
3. Custom Cards
3.1 Customising eTrainers
Doing simple customisations of eTrainers is pretty straightforward. The data for each trainer is kept in battle-e/trainers. Just open one up in a text editor and you'll be greeted with this
INCLUDE "trainers/macros.asm"
; The type of eCard
Battle_Trainer
BT_Level MOSSDEEP ; What Battle Tower level the trainer appears in 50=Lv50 100= Lv100, MOSSDEEP=0 (doesn't appear in Battle Tower)
Class POKEFAN_F ; Trainer class
BT_Floor MOSSDEEP ; Battle Tower floor they appear on MOSSDEEP=0 doesn't appear
Text_EN "ALANA"8 ; Trainer Name (limited to 7 characters, the 8th is 0xFF)
OT_ID 00000, 00000
; Easy chat words for the battle intro, winning and losing to the player (limited to 6 words each)
Intro_EN LET_S,START,THIS,_ELIP,BATTLE,_EX
Win_EN OH_,DID,I,_ELIP,WIN,_QU
Loss_EN OH_,DID,I,_ELIP,LOSE,_QU
; The pokemon data structure
Pokemon TORKOAL
Holds QUICK_CLAW
Moves OVERHEAT, BODY_SLAM, FLAIL, YAWN
Level 82
PP_Ups 0,0,0,0
EVs 0,0,0,0,255,255
OT_ID 00000, 00000
IVs 15,15,15,15,31,31, TORKOAL_WHITE_SMOKE ;IVs and the pokemon's ability
PV $000000D9 ; Determines gender, nature and shininess, this torkoal is ♂ Quiet
Text_EN "TORKOAL"11 ; Pokemon name, limited to 10 characters
Friendship 255
Pokemon DUSCLOPS
Holds CHESTO_BERRY
Moves CONFUSE_RAY, WILL_O_WISP, TOXIC, REST
Level 80
PP_Ups 0,0,0,0
EVs 0,0,255,0,0,255
OT_ID 00000, 00000
IVs 15,15,31,15,15,31, DUSCLOPS_PRESSURE
PV $00000016 ; ♀ Sassy
Text_EN "DUSCLOPS"11
Friendship 255
Pokemon CORSOLA
Holds MYSTIC_WATER
Moves SURF, ROCK_TOMB, MIRROR_COAT, RECOVER
Level 85
PP_Ups 0,0,0,0
EVs 0,0,0,0,255,255
OT_ID 00000, 00000
IVs 15,15,15,15,31,31, CORSOLA_NATURAL_CURE
PV $0000001B ; ♀ Brave
Text_EN "CORSOLA"11
Friendship 255
End_Trainer
You're able to change the trainer's name and class and pretty much everything about their pokemon.
In the constants folder there's text documents that list all the variables that are possible for making pokemon.
I've created a natures.asm file there so you don't need to memorise what PID will create what nature, gender or shininess (shininess works only if you leave the Trainer ID and SID as 00000).
In addition, pokemon can only have valid abilities but anything goes for their moves.
As you may have seen each eCard is compiled to a file starting with 08-A and then a number. These codes refer to a specific eCard which can be seen here on bulbapedia.
If you don't want to modify and replace one of the existing cards you'll need to create a new file in battle-e/ that follows this code pattern (eg. 08-A049.asm). Inside this file write something like this:
The class determines what image the eCard will display on the e-Reader. The images can be found in battle-e/sprites/trainers and they all use the palette battle-e/sprites/battletrainer5.pal.
The TRAINER variable should just be the name of your new trainer file that you'll put in battle-e/trainers.
Inside the Makefile you'll need to add the code to SERIES_1_NUMS and the name to SERIES_1_TRAINERS.
3.2 Further Customisation
6 Pokemon
Thanks to pokeemerald we can go even further with our customisation
Normally each eTrainer just has 3 pokemon but we can expand that to 6!
Both pokeemerald and pokecarde need to be edited for this to work.
Adding 3 new pokemon requires 132 more bytes of space in Saveblock2 but this wiki tutorial by hjk321 should give us enough.
Code change here.
Pokecarde needs to have the location of the checksum changed so it doesn't overwrite the new pokemon.
Code change here.
And there you go, you can now create eTrainers with 6 pokemon.
Each trainer must have data for 6 pokemon but If you want to use less, like 4 pokemon, just replace pokemon names with SPECIES_NULL or 0.
Hidden Abilities
If your hack has hidden abilities you can make use of them by changing one thing in pokecarde.
Code change here.
You can then use ABILITY3 or ABILITY_HIDDEN to assign hidden abilities to pokemon.
3.3 Customising Scripting Cards (Eon Ticket)
The Eon Ticket event card can be created in the eonticket folder, and the eonticket.asm file can be modified to send over different items and text. The most important parts to know are
These lines give the map number and object ID to initiate the event script when spoken to, in this case Norman in Petalburg Gym. Pretty much any object can be chosen for this.
this line allows the chosen item to be shared with other players using mix records and states how many times that can happen.
Here is the script Norman will use when spoken to, it deletes itself when it successfully gives the player the eon ticket.
This script does several checks to make sure the player hasn't already received the eon ticket.
As an example I've customised eonticket.asm to give the character the Old Sea Map
INCLUDE "../macros.asm"
INCLUDE "../constants/items_expansion.asm"
INCLUDE "../constants/scriptcommands.asm"
Mystery_Event ; Type of eCard
db CHECKSUM_CRC
dd 0 ; checksum placeholder
GBAPTR DataStart
GBAPTR DataEnd
DataStart:
db IN_GAME_SCRIPT
db 15,3 ; Sootopolis PokeCentre 2F ; Map of object
db 4 ; Delivery Man ; Object ID
GBAPTR EventScriptStart
GBAPTR EventScriptEnd
db MIX_RECORDS_ITEM
db 1 ; ???
IF REGION == REGION_DE
db 5 ; distribution limit from German debug ROM
ELSE
db 30 ; distribution limit from English release
ENDC
dw OLD_SEA_MAP
db PRELOAD_SCRIPT
GBAPTR PreloadScriptStart
db END_OF_CHUNKS
GetYourGift:
Text_DE "Lauf und besuche deinen Vater in der\n"
Text_DE "ARENA von BLÜTENBURG CITY.@"
Text_EN "Pick up your gift at a Pokémon\n" ; This text appears immediately after receiving the gift from the e-Reader
Text_EN "Center.@"
; Start of the script we want the object to use
EventScriptStart:
setvirtualaddress EventScriptStart
; Checks to make sure we haven't already got Old Sea Map
checkitem OLD_SEA_MAP, 1
compare LASTRESULT, 1
virtualgotoif 1, .delete_script
checkpcitem OLD_SEA_MAP, 1
compare LASTRESULT, 1
virtualgotoif 1, .delete_script
checkflag $013C
virtualgotoif 1, .delete_script
lock
virtualmsgbox GoodToSeeYou
waitmsg
waitkeypress
checkitemroom OLD_SEA_MAP, 1
compare LASTRESULT, 0
virtualgotoif 1, NoRoomToGive
copyvarifnotzero $8000, OLD_SEA_MAP ; Item to give
copyvarifnotzero $8001, 1 ; Amount to give
callstd 0 ; This is giveitem
setflag $013C ; set FLAG_RECEIVED_OLD_SEA_MAP
setvar $403F, 0 ; We want the delivery man to disappear after giving us a gift
virtualmsgbox AppearsToBeAFerryTicket
waitmsg
waitkeypress
release
.delete_script
killscript ; deletes the script
NoRoomToGive:
virtualmsgbox KeyItemsPocketIsFull
waitmsg
waitkeypress
release
end
GoodToSeeYou:
Text_EN "Thank you for using the Mystery\n"
Text_EN "Event System.\p"
Text_EN "You must be \v1.\n"
Text_EN "There is a ticket here for you.@"
Text_DE "VATER: \v1! Schön, dich zu sehen!\n"
Text_DE "Hier ist ein Brief für dich, \v1.@"
AppearsToBeAFerryTicket:
Text_EN "It appears to be for use at the\n"
Text_EN "Lilycove City port.\p"
Text_EN "Why not give it a try and see what\n"
Text_EN "it is about?@"
Text_DE "VATER: Ich bin mir nicht sicher, es\n"
Text_DE "könnte ein TICKET für eine Fähre sein.\p"
Text_DE "Du solltest nach SEEGRASULB CITY gehen\n"
Text_DE "und dich dort genauer erkundigen.@"
KeyItemsPocketIsFull:
Text_EN "The Key Items Pocket in your Bag\n"
Text_EN "is full.\p"
Text_EN "Move some key items for safekeeping\n"
Text_EN "in your PC then come see me.@"
Text_DE "VATER: \v1, die BASIS-TASCHE\n"
Text_DE "deines BEUTELS ist voll.\p"
Text_DE "Lagere einige deiner Basis-Items in\n"
Text_DE "deinem PC und komm dann wieder.@"
EventScriptEnd:
PreloadScriptStart:
setvirtualaddress PreloadScriptStart
; Check player doesn't have Old Sea Map before sending it
checkitem OLD_SEA_MAP, 1
compare LASTRESULT, 1
virtualgotoif 1, .ineligible
checkpcitem OLD_SEA_MAP, 1
compare LASTRESULT, 1
virtualgotoif 1, .ineligible
checkflag $013C
virtualgotoif 1, .ineligible
checkitemroom OLD_SEA_MAP, 1
compare LASTRESULT, 0
virtualgotoif 1, .no_room
setvar $403F, 1 ; Make delivery man appear
virtualloadpointer GetYourGift
setbyte 2
end
.ineligible
virtualloadpointer MayBeplayedOnlyOnce
setbyte 3
end
.no_room
virtualloadpointer BagsKeyItemsPocketFull
setbyte 3
end
MayBeplayedOnlyOnce:
Text_EN "This Event may be played only once.@"
Text_DE "Dieses GESCHEHEN kann nur einmal\n"
Text_DE "gespielt werden.@"
BagsKeyItemsPocketFull:
Text_EN "Your Bag's Key Items Pocket is full.@"
Text_DE "Deine BASIS-TASCHE ist voll.@"
DataEnd:
EOF
We make the delivery man on the 2nd floor of the PokeCenter appear by setting var 0x403F to 1 using the eCard and make the one in Sootopolis give you the Old Sea Map, but what if we want all the delivery men to give you it (because they will instead give you the Eon Ticket).
We can't do anything about that in the eCard but we can change some code in pokeemerald to allow for it.
Code changes here.
gotoram goes to the script that the eCard sent over, but it does check first if there's a valid wondercard and since we're not using wondercards we circumvented that check.
3.4 Customising Ribbon Cards
In the ribbons folder you can make eCards that give a ribbon to each of your party members. Once again copy rgbds and CaitSith2's tools to this folder and use make to compile.
There are only 2 lines of note here:
The first line is the ribbon type which can be found in constants/ribbons.asm.
The second is the ribbon description where the values can be found on bulbapedia where 0x01 is the starting description on the list.
Now you too can be world champ.
3.5 Customising Gift Pokemon Cards
In the giftpokemon folder you can create eCards that give a pokemon to the player, providing the party isn't full. Once again copy rgbds and CaitSith2's tools to this folder and use make to compile.
Edit the giftpokemon.asm file to change the pokemon to whatever you'd like.
The pokemon follows the 100-byte structure in the game which you can see on Bulbapedia but hopefully my comments provide enough info for basic customisation.
Make sure to back up your save when testing this one out in case you make a Bad Egg!
3.6 Customising The Regi Decoration Card
There's a Japan specific eCard that gives the player the Regi Dolls to use for decorating.
What's notable about this card is there's actually a menu that let's you select which doll you want.
It's (relatively) easy to change all the region checks to get it to send to English games but the text gets all messed up and doesn't look nice.
So I decided to disassemble it which allows you to change the text to English but also edit everything out, like what items to send over.
I've actually already translated all the text to English for your convenience
The 08-O000.asm files contain the asm instructions for everything on the eReader side of things, so things like the text, graphics, menu that shows up on the eReader.
The decoration.asm files contain the scripts that are sent to and are run on the game, so the script that gives the player the chosen item.
I have provided an edited example (08-O002.asm and decoration-tickets.asm, Emerald only not R/S) that gives you some event tickets.
I recommend editing this version because the original card uses one palette that's shared with all 3 Regi Dolls so I've modified the code to use the correct palette for each item.
Things to note:
The scripts in the decoration.asm file need to be the same length for all three scripts, if you have scripts that are shorter you can pad them out with zero bytes (db $00). Otherwise you're not limited to sending items but should be able to send over pokemon as well or doing things like setting flags.
If editing these there are some manual changes that are needed for the code. You'll need to create the decorations section first using the following instructions
Then open decoration-tickets-EN.bin in a hex editor and find the start of the 3 different scripts (one is always at 0x0000). They start with
Take note of their position and add 0x170 to them. Then in 08-O001.asm near the start there's a section called DataPointers, swap the first and second position bytes and replace what's there. Eg. if a script start at 0x110, add 0x170 to get 0x280 and swap the two bytes to get 0x80 and 0x2. Put them in as db $80,$02.
I've put comments in the files to tag things like text and graphics and what I think a couple of the functions do.
If you've ever made pokeemerald you can use the 4bpp sprites it makes and the gbapal files for this. I recommend not using sprites over 32x32 pixels because they're quite large and you can end up needing to swipe in 6 or more strips to start the eReader program (but you can if you really, really want).
All 3 sprites need to be the same size and if you do change their size 2 bytes need to be modified in 08-O001.asm to define their size.
I've probably forgotten something so ask me for help if you get stuck.
There are more types of eCards but I haven't looked into them yet so that's it for now.
All in all this might not have too much value but I just think it's a neat thing to play around with.
It would be possible to do things like changing the champion of the E4 every so often with a new card and it's a novel way to implement changes and events, especially if you print out the cards and use actual hardware!
Updates
Added the Battle-e Series 2 trainers to all branches
Added the Regi Decoration card
Links
Hatscky's post and pokecarde disassembly
My pokecarde fork with a branch for Emerald and an Emerald expansion branch that has 6 pokemon slots for trainers and set up for RHH's emerald-expansion.
My pokeemerald branch that activates the e-Reader and a separate one that makes all the changes in this tutorial.
RGBDS v0.1.2
CaitSith2's tools
GBATEK
Credit
Háčky/Hatschky for their post and disassembly
CitrusBolt for their e-Reader activation code
Sierraffinity for the e-Reader translations
hjk321 for their save space tutorial
CaitSith2 for their programs nvpktool, nedcmake and nedcprint
Everyone who worked on rgbds
The e-Reader functionality was inaccessible in Pokemon Emerald versions outside of Japan but is still within the code and can be enabled to accept eCards.
And with pokeemerald eTrainers can be customised further to have 6 pokemon and use expanded pokemon, moves and items.
The Eon Ticket eCard works as well and also can be customised to create event gifts.
I've been playing around with making custom eCards and thought I'd write a tutorial in case anyone else is interested.
1. Setting Up pokeemerald
I found out how to reactivate the e-Reader from CitrusBolt's Pokemon Heliodor and the translation is from Sierraffinity's CrystalDust, so big thanks to them!
1.1 Activating e-Reader functionality
This will show the Mystery Event option when Mystery Gift is unlocked. And also gives translations for the Japanese text.
Code changes here.
1.2 Removing region lock (Optional)
This is only necessary if you want to use eCards from different regions.
Code changes here.
2. Building eCards
Hatschky's original repository can be used for Ruby, Sapphire and our now modified Emerald, albeit with some differences (eg. Trainer classes won't be correct in Emerald).
But I have also made branches for Emerald, to fix the differences, and also for Rom Hacking Hideout's pokeemerald-expansion to allow for the expanded pokemon, attacks and items.
Pokecarde Disassemblies
For Ruby&Sapphire
For Emerald
For pokeemerald-expansion
- Download the one you'll require and unzip it somewhere.
- Download rgbds v0.1.2.
- Extract rgbasm.exe and rgblink.exe into the battle-e folder of the eCard disassembly and remove the .exe extension.
- Download NEDC Make and NVPK Tool from CaitSith2's website.
- Extract them both and move them to the battle-e folder as well.
Now that's out of the way you can go to the battle-e directory using a command line tool (WSL works best, powershell causes some issues) and build them using
Code:
make
To make the Eon Ticket copy the programs you extracted to pokecarde/battle-e to pokecarde/eonticket (rgbasm, rgblink, nedcmake, nevpk, nedclib.dll) and use the make command.
This builds an English and German version of the card.
How to use eCards
For them to work you need to have unlocked Mystery Gift in your save.
I've been able to get these cards working with VisualBoyAdvance-M v2.1.4. as well as mGBA.
- Open up two instances of it and link them together by going Options>Link>Start Network Link…
- Set one to being the server and the other the client and click connect.
- Load up Emerald which can now access Mystery Events and load the other with the e-Reader gba file.
- For the e-Reader go to File>e-Reader>Load Dot Code… and select one of the raw files we've just created.
- In Emerald select Mystery Event on the starting screen and follow the prompts.
You can also print them off for use with a real e-Reader using CaitSith2's Nintendo eReader DotCode Printer. I haven't got an e-Reader myself so I haven't confirmed that custom eCards work.
3. Custom Cards
3.1 Customising eTrainers
Doing simple customisations of eTrainers is pretty straightforward. The data for each trainer is kept in battle-e/trainers. Just open one up in a text editor and you'll be greeted with this
Spoiler:
INCLUDE "trainers/macros.asm"
; The type of eCard
Battle_Trainer
BT_Level MOSSDEEP ; What Battle Tower level the trainer appears in 50=Lv50 100= Lv100, MOSSDEEP=0 (doesn't appear in Battle Tower)
Class POKEFAN_F ; Trainer class
BT_Floor MOSSDEEP ; Battle Tower floor they appear on MOSSDEEP=0 doesn't appear
Text_EN "ALANA"8 ; Trainer Name (limited to 7 characters, the 8th is 0xFF)
OT_ID 00000, 00000
; Easy chat words for the battle intro, winning and losing to the player (limited to 6 words each)
Intro_EN LET_S,START,THIS,_ELIP,BATTLE,_EX
Win_EN OH_,DID,I,_ELIP,WIN,_QU
Loss_EN OH_,DID,I,_ELIP,LOSE,_QU
; The pokemon data structure
Pokemon TORKOAL
Holds QUICK_CLAW
Moves OVERHEAT, BODY_SLAM, FLAIL, YAWN
Level 82
PP_Ups 0,0,0,0
EVs 0,0,0,0,255,255
OT_ID 00000, 00000
IVs 15,15,15,15,31,31, TORKOAL_WHITE_SMOKE ;IVs and the pokemon's ability
PV $000000D9 ; Determines gender, nature and shininess, this torkoal is ♂ Quiet
Text_EN "TORKOAL"11 ; Pokemon name, limited to 10 characters
Friendship 255
Pokemon DUSCLOPS
Holds CHESTO_BERRY
Moves CONFUSE_RAY, WILL_O_WISP, TOXIC, REST
Level 80
PP_Ups 0,0,0,0
EVs 0,0,255,0,0,255
OT_ID 00000, 00000
IVs 15,15,31,15,15,31, DUSCLOPS_PRESSURE
PV $00000016 ; ♀ Sassy
Text_EN "DUSCLOPS"11
Friendship 255
Pokemon CORSOLA
Holds MYSTIC_WATER
Moves SURF, ROCK_TOMB, MIRROR_COAT, RECOVER
Level 85
PP_Ups 0,0,0,0
EVs 0,0,0,0,255,255
OT_ID 00000, 00000
IVs 15,15,15,15,31,31, CORSOLA_NATURAL_CURE
PV $0000001B ; ♀ Brave
Text_EN "CORSOLA"11
Friendship 255
End_Trainer
You're able to change the trainer's name and class and pretty much everything about their pokemon.
In the constants folder there's text documents that list all the variables that are possible for making pokemon.
I've created a natures.asm file there so you don't need to memorise what PID will create what nature, gender or shininess (shininess works only if you leave the Trainer ID and SID as 00000).
In addition, pokemon can only have valid abilities but anything goes for their moves.
As you may have seen each eCard is compiled to a file starting with 08-A and then a number. These codes refer to a specific eCard which can be seen here on bulbapedia.
If you don't want to modify and replace one of the existing cards you'll need to create a new file in battle-e/ that follows this code pattern (eg. 08-A049.asm). Inside this file write something like this:
Code:
INCLUDE "../macros.asm"
CLASS EQUS "beauty"
TRAINER EQUS "cynthia"
INCLUDE "battletrainer-{REGION_NAME}.tx"
The TRAINER variable should just be the name of your new trainer file that you'll put in battle-e/trainers.
Inside the Makefile you'll need to add the code to SERIES_1_NUMS and the name to SERIES_1_TRAINERS.
3.2 Further Customisation
6 Pokemon
Thanks to pokeemerald we can go even further with our customisation
Normally each eTrainer just has 3 pokemon but we can expand that to 6!
Both pokeemerald and pokecarde need to be edited for this to work.
Adding 3 new pokemon requires 132 more bytes of space in Saveblock2 but this wiki tutorial by hjk321 should give us enough.
Code change here.
Pokecarde needs to have the location of the checksum changed so it doesn't overwrite the new pokemon.
Code change here.
And there you go, you can now create eTrainers with 6 pokemon.
Each trainer must have data for 6 pokemon but If you want to use less, like 4 pokemon, just replace pokemon names with SPECIES_NULL or 0.
Hidden Abilities
If your hack has hidden abilities you can make use of them by changing one thing in pokecarde.
Code change here.
You can then use ABILITY3 or ABILITY_HIDDEN to assign hidden abilities to pokemon.
3.3 Customising Scripting Cards (Eon Ticket)
The Eon Ticket event card can be created in the eonticket folder, and the eonticket.asm file can be modified to send over different items and text. The most important parts to know are
Code:
db 8,1 ; Petalburg Gym
db 1 ; Norman
Code:
db 30 ; distribution limit from English release
Code:
NormanScriptStart:
Code:
PreloadScriptStart:
As an example I've customised eonticket.asm to give the character the Old Sea Map
Spoiler:
INCLUDE "../macros.asm"
INCLUDE "../constants/items_expansion.asm"
INCLUDE "../constants/scriptcommands.asm"
Mystery_Event ; Type of eCard
db CHECKSUM_CRC
dd 0 ; checksum placeholder
GBAPTR DataStart
GBAPTR DataEnd
DataStart:
db IN_GAME_SCRIPT
db 15,3 ; Sootopolis PokeCentre 2F ; Map of object
db 4 ; Delivery Man ; Object ID
GBAPTR EventScriptStart
GBAPTR EventScriptEnd
db MIX_RECORDS_ITEM
db 1 ; ???
IF REGION == REGION_DE
db 5 ; distribution limit from German debug ROM
ELSE
db 30 ; distribution limit from English release
ENDC
dw OLD_SEA_MAP
db PRELOAD_SCRIPT
GBAPTR PreloadScriptStart
db END_OF_CHUNKS
GetYourGift:
Text_DE "Lauf und besuche deinen Vater in der\n"
Text_DE "ARENA von BLÜTENBURG CITY.@"
Text_EN "Pick up your gift at a Pokémon\n" ; This text appears immediately after receiving the gift from the e-Reader
Text_EN "Center.@"
; Start of the script we want the object to use
EventScriptStart:
setvirtualaddress EventScriptStart
; Checks to make sure we haven't already got Old Sea Map
checkitem OLD_SEA_MAP, 1
compare LASTRESULT, 1
virtualgotoif 1, .delete_script
checkpcitem OLD_SEA_MAP, 1
compare LASTRESULT, 1
virtualgotoif 1, .delete_script
checkflag $013C
virtualgotoif 1, .delete_script
lock
virtualmsgbox GoodToSeeYou
waitmsg
waitkeypress
checkitemroom OLD_SEA_MAP, 1
compare LASTRESULT, 0
virtualgotoif 1, NoRoomToGive
copyvarifnotzero $8000, OLD_SEA_MAP ; Item to give
copyvarifnotzero $8001, 1 ; Amount to give
callstd 0 ; This is giveitem
setflag $013C ; set FLAG_RECEIVED_OLD_SEA_MAP
setvar $403F, 0 ; We want the delivery man to disappear after giving us a gift
virtualmsgbox AppearsToBeAFerryTicket
waitmsg
waitkeypress
release
.delete_script
killscript ; deletes the script
NoRoomToGive:
virtualmsgbox KeyItemsPocketIsFull
waitmsg
waitkeypress
release
end
GoodToSeeYou:
Text_EN "Thank you for using the Mystery\n"
Text_EN "Event System.\p"
Text_EN "You must be \v1.\n"
Text_EN "There is a ticket here for you.@"
Text_DE "VATER: \v1! Schön, dich zu sehen!\n"
Text_DE "Hier ist ein Brief für dich, \v1.@"
AppearsToBeAFerryTicket:
Text_EN "It appears to be for use at the\n"
Text_EN "Lilycove City port.\p"
Text_EN "Why not give it a try and see what\n"
Text_EN "it is about?@"
Text_DE "VATER: Ich bin mir nicht sicher, es\n"
Text_DE "könnte ein TICKET für eine Fähre sein.\p"
Text_DE "Du solltest nach SEEGRASULB CITY gehen\n"
Text_DE "und dich dort genauer erkundigen.@"
KeyItemsPocketIsFull:
Text_EN "The Key Items Pocket in your Bag\n"
Text_EN "is full.\p"
Text_EN "Move some key items for safekeeping\n"
Text_EN "in your PC then come see me.@"
Text_DE "VATER: \v1, die BASIS-TASCHE\n"
Text_DE "deines BEUTELS ist voll.\p"
Text_DE "Lagere einige deiner Basis-Items in\n"
Text_DE "deinem PC und komm dann wieder.@"
EventScriptEnd:
PreloadScriptStart:
setvirtualaddress PreloadScriptStart
; Check player doesn't have Old Sea Map before sending it
checkitem OLD_SEA_MAP, 1
compare LASTRESULT, 1
virtualgotoif 1, .ineligible
checkpcitem OLD_SEA_MAP, 1
compare LASTRESULT, 1
virtualgotoif 1, .ineligible
checkflag $013C
virtualgotoif 1, .ineligible
checkitemroom OLD_SEA_MAP, 1
compare LASTRESULT, 0
virtualgotoif 1, .no_room
setvar $403F, 1 ; Make delivery man appear
virtualloadpointer GetYourGift
setbyte 2
end
.ineligible
virtualloadpointer MayBeplayedOnlyOnce
setbyte 3
end
.no_room
virtualloadpointer BagsKeyItemsPocketFull
setbyte 3
end
MayBeplayedOnlyOnce:
Text_EN "This Event may be played only once.@"
Text_DE "Dieses GESCHEHEN kann nur einmal\n"
Text_DE "gespielt werden.@"
BagsKeyItemsPocketFull:
Text_EN "Your Bag's Key Items Pocket is full.@"
Text_DE "Deine BASIS-TASCHE ist voll.@"
DataEnd:
EOF
We make the delivery man on the 2nd floor of the PokeCenter appear by setting var 0x403F to 1 using the eCard and make the one in Sootopolis give you the Old Sea Map, but what if we want all the delivery men to give you it (because they will instead give you the Eon Ticket).
We can't do anything about that in the eCard but we can change some code in pokeemerald to allow for it.
Code changes here.
gotoram goes to the script that the eCard sent over, but it does check first if there's a valid wondercard and since we're not using wondercards we circumvented that check.
3.4 Customising Ribbon Cards
In the ribbons folder you can make eCards that give a ribbon to each of your party members. Once again copy rgbds and CaitSith2's tools to this folder and use make to compile.
There are only 2 lines of note here:
Code:
db MARINE_RIBBON ; Marine Ribbon
db $01 ; description $01=2003 REGIONAL TOURNEY CHAMPION RIBBON
The second is the ribbon description where the values can be found on bulbapedia where 0x01 is the starting description on the list.
Now you too can be world champ.
3.5 Customising Gift Pokemon Cards
In the giftpokemon folder you can create eCards that give a pokemon to the player, providing the party isn't full. Once again copy rgbds and CaitSith2's tools to this folder and use make to compile.
Edit the giftpokemon.asm file to change the pokemon to whatever you'd like.
The pokemon follows the 100-byte structure in the game which you can see on Bulbapedia but hopefully my comments provide enough info for basic customisation.
Make sure to back up your save when testing this one out in case you make a Bad Egg!
3.6 Customising The Regi Decoration Card
There's a Japan specific eCard that gives the player the Regi Dolls to use for decorating.
What's notable about this card is there's actually a menu that let's you select which doll you want.
It's (relatively) easy to change all the region checks to get it to send to English games but the text gets all messed up and doesn't look nice.
So I decided to disassemble it which allows you to change the text to English but also edit everything out, like what items to send over.
I've actually already translated all the text to English for your convenience
The 08-O000.asm files contain the asm instructions for everything on the eReader side of things, so things like the text, graphics, menu that shows up on the eReader.
The decoration.asm files contain the scripts that are sent to and are run on the game, so the script that gives the player the chosen item.
I have provided an edited example (08-O002.asm and decoration-tickets.asm, Emerald only not R/S) that gives you some event tickets.
I recommend editing this version because the original card uses one palette that's shared with all 3 Regi Dolls so I've modified the code to use the correct palette for each item.
Things to note:
The scripts in the decoration.asm file need to be the same length for all three scripts, if you have scripts that are shorter you can pad them out with zero bytes (db $00). Otherwise you're not limited to sending items but should be able to send over pokemon as well or doing things like setting flags.
If editing these there are some manual changes that are needed for the code. You'll need to create the decorations section first using the following instructions
Spoiler:
python ../scripts/regionalize.py decoration-tickets.asm decoration-tickets-EN.tx EN EN
./rgbasm -o decoration-tickets-EN.o decoration-tickets-EN.tx
./rgblink -o decoration-tickets-EN.gbc decoration-tickets-EN.o
python ../scripts/stripgbc.py decoration-tickets-EN.gbc decoration-tickets-EN.bin
python ../scripts/checksum_regi.py decoration-tickets-EN.bin decoration-tickets-EN.mev
./rgbasm -o decoration-tickets-EN.o decoration-tickets-EN.tx
./rgblink -o decoration-tickets-EN.gbc decoration-tickets-EN.o
python ../scripts/stripgbc.py decoration-tickets-EN.gbc decoration-tickets-EN.bin
python ../scripts/checksum_regi.py decoration-tickets-EN.bin decoration-tickets-EN.mev
Then open decoration-tickets-EN.bin in a hex editor and find the start of the 3 different scripts (one is always at 0x0000). They start with
Code:
01 00 00 00 02 02
I've put comments in the files to tag things like text and graphics and what I think a couple of the functions do.
If you've ever made pokeemerald you can use the 4bpp sprites it makes and the gbapal files for this. I recommend not using sprites over 32x32 pixels because they're quite large and you can end up needing to swipe in 6 or more strips to start the eReader program (but you can if you really, really want).
All 3 sprites need to be the same size and if you do change their size 2 bytes need to be modified in 08-O001.asm to define their size.
I've probably forgotten something so ask me for help if you get stuck.
There are more types of eCards but I haven't looked into them yet so that's it for now.
All in all this might not have too much value but I just think it's a neat thing to play around with.
It would be possible to do things like changing the champion of the E4 every so often with a new card and it's a novel way to implement changes and events, especially if you print out the cards and use actual hardware!
Updates
Added the Battle-e Series 2 trainers to all branches
Added the Regi Decoration card
Links
Hatscky's post and pokecarde disassembly
My pokecarde fork with a branch for Emerald and an Emerald expansion branch that has 6 pokemon slots for trainers and set up for RHH's emerald-expansion.
My pokeemerald branch that activates the e-Reader and a separate one that makes all the changes in this tutorial.
RGBDS v0.1.2
CaitSith2's tools
GBATEK
Credit
Háčky/Hatschky for their post and disassembly
CitrusBolt for their e-Reader activation code
Sierraffinity for the e-Reader translations
hjk321 for their save space tutorial
CaitSith2 for their programs nvpktool, nedcmake and nedcprint
Everyone who worked on rgbds
Last edited: