• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Gen II - Crystal Making the Time Capsule Actually Consistent with Trading in RBY

Compatible Base ROMs
PKMN Crystal
#1
Before I begin, allow me to give credits to Rangi and pfero from the pret Discord. Without their help, I would not have been able to do this.

Ever used the Time Capsule on a generation 2 game and thought it didn't look right when trying to trade to and from a game from the first generation? Well, look no further as this is the tutorial for you.

What you will need:
- Basic knowledge of the pokecrystal disassembly
- A Notepad program capable of writing and/or editing assembly functions (I use Programmers Notepad myself)
- An Emulator capable of linking Gameboy ROMs

What we are going to do is set a new bit to change the player into Red. Thankfully, bit 3 in wPlayerSpriteSetupFlags seems to be free, see constants/wram_constants.asm - A new "engine flag" (see constants/engine_flags.asm and data/engine_flags.asm) to set that bit through the script.

In constants/wram_constants.asm, you are going to change the following:
PLAYERSPRITESETUP_FACING_MASK EQU %11
PLAYERSPRITESETUP_FEMALE_TO_MALE_F EQU 2
PLAYERSPRITESETUP_CUSTOM_FACING_F EQU 5
PLAYERSPRITESETUP_SKIP_RELOAD_GFX_F EQU 6
PLAYERSPRITESETUP_RESET_ACTION_F EQU 7

To the following:
PLAYERSPRITESETUP_FACING_MASK EQU %11
PLAYERSPRITESETUP_FEMALE_TO_MALE_F EQU 2
PLAYERSPRITESETUP_PLAYER_TO_RED_F EQU 3
PLAYERSPRITESETUP_CUSTOM_FACING_F EQU 5
PLAYERSPRITESETUP_SKIP_RELOAD_GFX_F EQU 6
PLAYERSPRITESETUP_RESET_ACTION_F EQU 7

This sets a new bit that will allow the player's sprite to temporarily become Red's sprite.

In engine/overworld/overworld.asm, you will need to add a piece of code to GetPlayerSprite.

Normally, the start of the code would look like this:
ld hl, ChrisStateSprites
ld a, [wPlayerSpriteSetupFlags]
bit PLAYERSPRITESETUP_FEMALE_TO_MALE_F, a
jr nz, .go
ld a, [wPlayerGender]
bit PLAYERGENDER_FEMALE_F, a
jr z, .go
ld hl, KrisStateSprites

Add the following at the START of the above function:
; Get Red's sprite.
ld a, [wPlayerSpriteSetupFlags]
bit PLAYERSPRITESETUP_PLAYER_TO_RED_F, a
ld a, SPRITE_RED
jr nz, .finish

Next, we are going to open constants/engine_flags.asm. You should see the following:
; wPlayerSpriteSetupFlags
const ENGINE_KRIS_IN_CABLE_CLUB

Below that, we going to add the following:
const ENGINE_PLAYER_IN_TIME_CAPSULE

It should look like this:
; wPlayerSpriteSetupFlags
const ENGINE_KRIS_IN_CABLE_CLUB
const ENGINE_PLAYER_IN_TIME_CAPSULE

We will now need to open data/engine_flags.asm and make some changes there.

This is how it looks normally:
engine_flag wPlayerSpriteSetupFlags, PLAYERSPRITESETUP_FEMALE_TO_MALE_F

Add the following so it looks like this:
engine_flag wPlayerSpriteSetupFlags, PLAYERSPRITESETUP_FEMALE_TO_MALE_F
engine_flag wPlayerSpriteSetupFlags, PLAYERSPRITESETUP_PLAYER_TO_RED_F

Now you can use ENGINE_PLAYER_IN_TIME_CAPSULE in map scripts.

Now comes the actual script editing.

Open maps/Pokecenter2F.asm find a script labelled as Script_LeftTimeCapsule. It should look like this:
special WaitForOtherPlayerToExit
checkflag ENGINE_KRIS_IN_CABLE_CLUB
iftrue .Female
applymovement POKECENTER2F_TIME_CAPSULE_RECEPTIONIST, Pokecenter2FMovementData_ReceptionistStepsLeftLooksRight
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesTwoStepsDown
applymovement POKECENTER2F_TIME_CAPSULE_RECEPTIONIST, Pokecenter2FMovementData_ReceptionistStepsRightLooksDown_2
jump .Done
.Female:
applymovement POKECENTER2F_TIME_CAPSULE_RECEPTIONIST, Pokecenter2FMovementData_ReceptionistStepsLeftLooksRight
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesOneStepDown
clearflag ENGINE_KRIS_IN_CABLE_CLUB
playsound SFX_TINGLE
applymovement PLAYER, Pokecenter2FMovementData_PlayerSpinsClockwiseEndsFacingRight
writebyte (PAL_NPC_BLUE << 4)
special SetPlayerPalette
applymovement PLAYER, Pokecenter2FMovementData_PlayerSpinsClockwiseEndsFacingLeft
special ReplaceKrisSprite
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesOneStepDown
applymovement POKECENTER2F_TIME_CAPSULE_RECEPTIONIST, Pokecenter2FMovementData_ReceptionistStepsRightLooksDown_2
.Done:
setscene SCENE_DEFAULT
setmapscene TIME_CAPSULE, SCENE_DEFAULT
end

What we will change that to is the following:
special WaitForOtherPlayerToExit
applymovement POKECENTER2F_TIME_CAPSULE_RECEPTIONIST, Pokecenter2FMovementData_ReceptionistStepsLeftLooksRight
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesOneStepDown
playsound SFX_TINGLE
applymovement PLAYER, Pokecenter2FMovementData_PlayerSpinsClockwiseEndsFacingRight
checkflag ENGINE_PLAYER_IS_FEMALE
iftrue .Female
writebyte (PAL_NPC_RED << 4)
jump .Done
.Female:
writebyte (PAL_NPC_BLUE << 4)
.Done:
special SetPlayerPalette
applymovement PLAYER, Pokecenter2FMovementData_PlayerSpinsClockwiseEndsFacingLeft
clearflag ENGINE_PLAYER_IN_TIME_CAPSULE
special ReplaceKrisSprite
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesOneStepDown
applymovement POKECENTER2F_TIME_CAPSULE_RECEPTIONIST, Pokecenter2FMovementData_ReceptionistStepsRightLooksDown_2
setscene SCENE_DEFAULT
setmapscene TIME_CAPSULE, SCENE_DEFAULT
end

On that same file, go to TimeCapsuleScript_CheckPlayerGender. It should look like the following:
checkflag ENGINE_PLAYER_IS_FEMALE
iftrue .Female
checkcode VAR_FACING
ifequal LEFT, .MaleFacingLeft
ifequal RIGHT, .MaleFacingRight
applymovement2 Pokecenter2FMovementData_ReceptionistStepsLeftLooksDown
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesTwoStepsUp_2
end

.MaleFacingLeft:
applymovement2 Pokecenter2FMovementData_ReceptionistStepsLeftLooksDown
applymovement PLAYER, Pokecenter2FMovementData_PlayerWalksLeftAndUp
end

.MaleFacingRight:
applymovement2 Pokecenter2FMovementData_ReceptionistStepsRightLooksDown
applymovement PLAYER, Pokecenter2FMovementData_PlayerWalksRightAndUp
end

.Female:
checkcode VAR_FACING
ifequal RIGHT, .FemaleFacingRight
ifequal LEFT, .FemaleFacingLeft
applymovement2 Pokecenter2FMovementData_ReceptionistStepsLeftLooksRight_2
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesOneStepUp_2
jump .FemaleContinue

.FemaleFacingRight:
applymovement2 Pokecenter2FMovementData_ReceptionistStepsRightLooksLeft_2
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesOneStepRight
jump .FemaleContinue

.FemaleFacingLeft:
applymovement2 Pokecenter2FMovementData_ReceptionistStepsLeftLooksRight_2
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesOneStepLeft

.FemaleContinue:
opentext
writetext Text_OhPleaseWait
waitbutton
closetext
checkcode VAR_FACING
ifnotequal UP, .FemaleChangeApperance
turnobject PLAYER, LEFT

.FemaleChangeApperance:
opentext
writetext Text_ChangeTheLook
waitbutton
closetext
playsound SFX_TINGLE
applymovement PLAYER, Pokecenter2FMovementData_PlayerSpinsClockwiseEndsFacingRight
writebyte (PAL_NPC_RED << 4)
special SetPlayerPalette
applymovement PLAYER, Pokecenter2FMovementData_PlayerSpinsClockwiseEndsFacingDown
faceobject PLAYER, POKECENTER2F_TIME_CAPSULE_RECEPTIONIST
setflag ENGINE_KRIS_IN_CABLE_CLUB
special ReplaceKrisSprite
opentext
writetext Text_LikeTheLook
waitbutton
closetext
showemote EMOTE_SHOCK, PLAYER, 15
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesOneStepUp_2
end

We will be changing ALL of that to the following:
checkcode VAR_FACING
ifequal RIGHT, .FemaleFacingRight
ifequal LEFT, .FemaleFacingLeft
applymovement2 Pokecenter2FMovementData_ReceptionistStepsLeftLooksRight_2
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesOneStepUp_2
jump .FemaleContinue

.FemaleFacingRight:
applymovement2 Pokecenter2FMovementData_ReceptionistStepsRightLooksLeft_2
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesOneStepRight
jump .FemaleContinue

.FemaleFacingLeft:
applymovement2 Pokecenter2FMovementData_ReceptionistStepsLeftLooksRight_2
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesOneStepLeft

.FemaleContinue:
opentext
writetext Text_OhPleaseWait
waitbutton
closetext
checkcode VAR_FACING
ifnotequal UP, .FemaleChangeApperance
turnobject PLAYER, LEFT

.FemaleChangeApperance:
opentext
writetext Text_ChangeTheLook
waitbutton
closetext
playsound SFX_TINGLE
applymovement PLAYER, Pokecenter2FMovementData_PlayerSpinsClockwiseEndsFacingRight
writebyte (PAL_NPC_SILVER << 4)
special SetPlayerPalette
applymovement PLAYER, Pokecenter2FMovementData_PlayerSpinsClockwiseEndsFacingDown
faceobject PLAYER, POKECENTER2F_TIME_CAPSULE_RECEPTIONIST
setflag ENGINE_PLAYER_IN_TIME_CAPSULE
special ReplaceKrisSprite
opentext
writetext Text_LikeTheLook
waitbutton
closetext
showemote EMOTE_SHOCK, PLAYER, 15
applymovement PLAYER, Pokecenter2FMovementData_PlayerTakesOneStepUp_2
end

If you've done everything correctly (and if I explained things properly), when you enter the Time Capsule, you'll transform into a Greyscale Red sprite to match the greyscale style of RBY (Mainly Red and Blue)

I will cover inserting the Trade Centre tileset from RBY and editing the other player sprite very soon and I will be adding it to this post.

Wow, this was a pain to write, I just hope I explained things correctly. If anyone has any questions, don't hesitate to message me on here or on Discord.
 
Last edited: