Add a new phone contact - pret/pokecrystal GitHub Wiki

This tutorial is for how to add a new phone contact in the Pokégear. As an example, we'll add the phone number of the rival, Silver.

Contents

  1. Define the phone contact's constant
  2. Giving them a custom name
  3. Define the contact's essential data
  4. Make the number permanent
  5. Create the files for when you call them
  6. Create the files for when they call you
  7. Include the new files in the ROM

1. Define the phone contact's constant

Edit constants/phone_constants.asm:

	const PHONE_BILL
	const PHONE_ELM
+	const PHONE_RIVAL
	const PHONE_SCHOOLBOY_JACK
	const PHONE_POKEFAN_BEVERLY
	const PHONE_SAILOR_HUEY
-	const_skip
	const_skip
	const_skip
	const PHONE_COOLTRAINERM_GAVEN

2. Giving them a custom name

Generic trainers like Youngster Joey or Lass Dana don't need another constant for their name in the phone, since the constant for one of their parties is used instead. It also makes it so that their trainer class also appears below their name. In this case, we'll add a new constant under the trainer class TRAINER_NONE so that no trainer class shows up below the person's name, like how it looks like for MOM or ELM. However, Buena has a title below her called DISC JOCKEY. This is actually not a trainer class, but just part of her name. You can skip this step if want the character's trainer class to appear.

Edit constants/trainer_constants.asm:

CHRIS EQU __trainer_class__
	trainerclass TRAINER_NONE ; 0
	const PHONECONTACT_MOM
	const PHONECONTACT_BIKESHOP
	const PHONECONTACT_BILL
	const PHONECONTACT_ELM
	const PHONECONTACT_BUENA
+	const PHONECONTACT_RIVAL
NUM_NONTRAINER_PHONECONTACTS EQU const_value - 1

Edit data/phone/non_trainer_names.asm:

 NonTrainerCallerNames:
 ; entries correspond to PHONECONTACT_* constants (see constants/trainer_constants.asm)
 	table_width 2, NonTrainerCallerNames
 	dw .none
	dw .mom
	dw .bikeshop
	dw .bill
	dw .elm
	dw .buena
+	dw .rival
	assert_table_length NUM_NONTRAINER_PHONECONTACTS + 1

 .none:     db "----------@"
 .mom:      db "MOM:@"
 .bill:     db "BILL:@"
 .elm:      db "PROF.ELM:@"
 .bikeshop: db "BIKE SHOP:@"
 .buena:    db "BUENA:<LF>   DISC JOCKEY@"
+.rival:    db "<RIVAL>:@"

We put PHONECONTACT_RIVAL below PHONECONTACT_BUENA earlier, so it should be right below dw .buena as well. Otherwise, the wrong name would be shown! To add a custom title, simply add <LF> and three spaces after the name and a semicolon :, then write the title.

3. Define the contact's essential data

Edit data/phone/phone_contacts.asm:

PhoneContacts:
; entries correspond to PHONE_* constants
	table_width PHONE_CONTACT_SIZE, PhoneContacts
	phone TRAINER_NONE, PHONE_00,              N_A,                       0,       UnusedPhoneScript,        0,       UnusedPhoneScript
	phone TRAINER_NONE, PHONECONTACT_MOM,      PLAYERS_HOUSE_1F,          ANYTIME, MomPhoneCalleeScript,     0,       UnusedPhoneScript
	phone TRAINER_NONE, PHONECONTACT_BIKESHOP, OAKS_LAB,                  0,       UnusedPhoneScript,        0,       UnusedPhoneScript
	phone TRAINER_NONE, PHONECONTACT_BILL,     N_A,                       ANYTIME, BillPhoneCalleeScript,    0,       BillPhoneCallerScript
	phone TRAINER_NONE, PHONECONTACT_ELM,      ELMS_LAB,                  ANYTIME, ElmPhoneCalleeScript,     0,       ElmPhoneCallerScript
+	phone TRAINER_NONE, PHONECONTACT_RIVAL,    N_A,                       ANYTIME, RivalPhoneCalleeScript,   ANYTIME, RivalPhoneCallerScript
	phone SCHOOLBOY,    JACK1,                 NATIONAL_PARK,             ANYTIME, JackPhoneCalleeScript,    ANYTIME, JackPhoneCallerScript
	phone POKEFANF,     BEVERLY1,              NATIONAL_PARK,             ANYTIME, BeverlyPhoneCalleeScript, ANYTIME, BeverlyPhoneCallerScript
	phone SAILOR,       HUEY1,                 OLIVINE_LIGHTHOUSE_2F,     ANYTIME, HueyPhoneCalleeScript,    ANYTIME, HueyPhoneCallerScript
-	phone TRAINER_NONE, PHONE_00,              N_A,                       0,       UnusedPhoneScript,        0,       UnusedPhoneScript
	phone TRAINER_NONE, PHONE_00,              N_A,                       0,       UnusedPhoneScript,        0,       UnusedPhoneScript
	phone TRAINER_NONE, PHONE_00,              N_A,                       0,       UnusedPhoneScript,        0,       UnusedPhoneScript
	phone COOLTRAINERM, GAVEN3,                ROUTE_26,                  ANYTIME, GavenPhoneCalleeScript,   ANYTIME, GavenPhoneCallerScript
	phone COOLTRAINERF, BETH1,                 ROUTE_26,                  ANYTIME, BethPhoneCalleeScript,    ANYTIME, BethPhoneCallerScript
	phone BIRD_KEEPER,  JOSE2,                 ROUTE_27,                  ANYTIME, JosePhoneCalleeScript,    ANYTIME, JosePhoneCallerScript

At the comment on top, you can see which of which stand for.

phone: MACRO
; trainer class, trainer id, map, callee time, callee script, caller time, caller script
  • Trainer Class: Since we put the rival's contact in TRAINER_NONE, that's what we enter. Although the rival does indeed have an actual trainer class and constants for his party, his name won't show up in the phone if we use that. Just write the character's trainer class as normal, otherwise.
  • Trainer ID: Under TRAINER_NONE, we added PHONECONTACT_RIVAL earlier, which is what we put in. For a generic trainer, enter the constant for one of their parties instead. This would also be the one that they would use in rematches, as well!
  • Map: This is where the character stays in. Since the rival is always on the move, enter N_A. Otherwise, write the map where they are at, instead.
  • Callee Time: This is the time when you can call them. You can find the constants in constants/wram_constants.asm: which are MORN, DAY, NITE, and DARKNESS.
    • If the player calls them other than at the assigned time, the text "That number is out of the area." will display.
    • Normally, you can't call in DARKNESS since it's used in caves like the Dark Cave or Mt. Silver, where it's out of service anyway.
    • If you don't want the player to be able to call the number at all, simply enter 0.
  • Callee Script: This is the script that the game refers to when you call them. We'll be making an asm file for this later, so let's enter RivalCalleeScript for now.
  • Caller Time: This is the time when they might call you. Silver isn't buddy-buddy with the player after all, so he would probably never call you. However, we can change that! Let's write ANYTIME.
    • Putting in ANYTIME will make them call you at any point from time to time.
    • If you enter 0 instead, the number will never call you randomly.
    • Scripted or special calls like Prof. Elm calling you about the stolen Pokémon, or the Bike Shop regarding the sales are fixed events, so they are also 0.
  • Caller Script: This is the script that the game refers to when they call you. Later, we'll also be making a script for this, so let's enter RivalCallerScript for now.
    • If you noticed earlier, Mom has UnusedPhoneScript set for her. She actually calls you sometimes to tell you that she spent your money in the bank. These are scripted by the game, and are rarer than the NPC trainer calls that occur more commonly.

4. Make the number permanent

This step is optional, but perfect if you'd like to make the player be unable to delete the character's number.

Edit data/phone/permanent_numbers.asm:

PermanentNumbers:
	db PHONECONTACT_MOM
	db PHONECONTACT_ELM
+	db PHONECONTACT_RIVAL
	db -1 ; end

Edit engine/phone/phone.asm:

CheckCanDeletePhoneNumber:
	ld a, c
	call GetCallerTrainerClass
	ld a, c
	; and a
	ret nz
	ld a, b
	cp PHONECONTACT_MOM
	ret z
	cp PHONECONTACT_ELM
	ret z
+	cp PHONECONTACT_RIVAL
+	ret z
	ld c, $1
	ret

This makes it so that the DELETE option when you select the number is absent.

5. Create the files for when you call them

Now, let's make a file for RivalPhoneCalleeScript and the text it uses. You can use another file as a guide, like Buena's (engine/phone/scripts/buena.asm) or Bill's (engine/phone/scripts/bill.asm)!

Create engine/phone/scripts/rival_callee.asm.

+RivalPhoneCalleeScript:
+	checktime MORN
+	iftrue .morngreet
+	checktime DAY
+	iftrue .daygreet
+	farwritetext RivalPhoneNiteGreetingText
+	sjump .main
+
+.morngreet
+	farwritetext RivalPhoneMornGreetingText
+	sjump .main
+
+.daygreet
+	farwritetext RivalPhoneDayGreetingText
+	sjump .main
+
+.main
+	promptbutton
+	farwritetext RivalPhoneGenericText
+	sjump .hangup
+
+.hangup:
+	promptbutton
+	checktime MORN
+	iftrue .mornbye
+	checktime DAY
+	iftrue .daybye
+	farwritetext RivalPhoneHangUpNightText
+	end
+
+.mornbye
+	farwritetext RivalPhoneHangUpMornText
+	end
+
+.daybye
+	farwritetext RivalPhoneHangUpDayText
+	end

Create data/phone/text/rival_callee.asm.

+RivalPhoneMornGreetingText:
+	text "Zzz… Huh?"
+
+	para "What do you want?"
+	done
+
+RivalPhoneDayGreetingText:
+	text "It's you. Why are"
+	line "you calling me?"
+	done
+
+RivalPhoneNiteGreetingText:
+	text "Humph."
+	line "What is it, now?"
+	done
+
+RivalPhoneGenericText:
+	text "Don't you have"
+	line "anything better"
+	cont "to do?"
+
+	para "Other than"
+	line "calling me?"
+	done
+
+RivalPhoneHangUpMornText:
+	text "Finally, I can go"
+	line "back to sleep…"
+	done
+
+RivalPhoneHangUpDayText:
+	text "Humph! Don't waste"
+	line "my time."
+	done
+
+RivalPhoneHangUpNightText:
+	text "Why do you even"
+	line "have my number?"
+	done

You can be creative with how you want the call to play out, depending on the character! You can make them say different text depending on the time of day, or randomized with the use of a table. You could also have them say one time things, with the use of an event flag. You can even incorporate the calls to scenes in the game if you use the event flags!

6. Create the files for when they call you

This time, the rival would say three randomly chosen text whenever he calls you. We'll be using the random command and a table for it. In the post-game after beating the Pokémon League, we learn that Silver becomes more kind to his Pokémon. This is evident in the rematches in Indigo Plateau, in which his Golbat has evolved into Crobat. We can make him say randomly chosen text for this as well, which are now used instead after beating the elite four.

You can choose to just add this to the previous file instead, and rename that file into just rival.asm, but let's put it in another separate file for easy readability.

Create engine/phone/scripts/rival_caller.asm.

+RivalPhoneCallerScript:
+	checkevent EVENT_BEAT_ELITE_FOUR
+	iftrue .PostE4
+	random 3
+	ifequal 0, .zero
+	ifequal 1, .one
+	ifequal 2, .two
+
+.zero
+	farwritetext RivalPhoneCallerRandomText0
+	end
+
+.one
+	farwritetext RivalPhoneCallerRandomText1
+	end
+
+.two
+	farwritetext RivalPhoneCallerRandomText2
+	end
+
+.PostE4
+	random 3
+	ifequal 0, .newzero
+	ifequal 1, .newone
+	ifequal 2, .newtwo
+
+.newzero
+	farwritetext RivalPhoneCallerRandomTextNew0
+	end
+
+.newone
+	farwritetext RivalPhoneCallerRandomTextNew1
+	end
+
+.newtwo
+	farwritetext RivalPhoneCallerRandomTextNew2
+	end

Create data/phone/text/rival_caller.asm.

+RivalPhoneCallerRandomText0:
+	text "I'll become the"
+	line "world's greatest"
+	cont "#MON TRAINER!"
+
+	para "Just wanted to"
+	line "remind you."
+	cont "Bye!"
+	done
+
+RivalPhoneCallerRandomText1:
+	text "Have you seen"
+	line "any signs of"
+
+	para "TEAM ROCKET"
+	line "recently?"
+
+	para "There might be"
+	line "news about them…"
+	done
+
+RivalPhoneCallerRandomText2:
+	text "I'm looking for"
+	line "where to find some"
+	cont "strong #MON."
+
+	para "I thought you"
+	line "might have an"
+	cont "idea."
+	done
+
+RivalPhoneCallerRandomTextNew0:
+	text "<PLAYER>, do you"
+	line "have any tips on"
+
+	para "how you get"
+	line "stronger?"
+
+	para "You seem reliable"
+	line "to ask."
+
+	para "…Humph! Don't"
+	line "get any ideas!"
+	done
+
+RivalPhoneCallerRandomTextNew1:
+	text "I've been training"
+	line "with my #MON"
+	cont "recently."
+
+	para "Once I'm ready,"
+	line "I'll beat you to"
+	cont "a pulp!"
+
+	para "…Well, keep at"
+	line "it, then."
+	done
+
+RivalPhoneCallerRandomTextNew2:
+	text "I was in the"
+	line "middle of training"
+
+	para "but then I thought"
+	line "of you."
+
+	para "…Humph! I just"
+	line "wanted to tell you"
+
+	para "prepare to lose"
+	line "next time!"
+
+	para "You'll see!"
+	done

7. Include the new files in the ROM

Edit main.asm:

 SECTION "Special Phone Text", ROMX

 INCLUDE "data/phone/text/mom.asm"
 INCLUDE "data/phone/text/bill.asm"

...

 INCLUDE "data/phone/text/parry_callee.asm"
 INCLUDE "data/phone/text/erin_callee.asm"
 INCLUDE "data/phone/text/unused.asm"

+SECTION "New Phone Scripts", ROMX
+
+INCLUDE "engine/phone/scripts/rival_callee.asm"
+INCLUDE "engine/phone/scripts/rival_caller.asm"
+
+SECTION "New Phone Text", ROMX
+
+INCLUDE "data/phone/text/rival_callee.asm"
+INCLUDE "data/phone/text/rival_caller.asm"

 SECTION "Miscellaneous Text", ROMX

 INCLUDE "data/items/names.asm"
 INCLUDE "engine/items/print_item_description.asm"
 INCLUDE "data/moves/names.asm"
 INCLUDE "engine/overworld/landmarks.asm"

And that's all! You now have a new, custom phone contact in your game!

Screenshot

Don't forget to add a script in the game that gives the player the new phone number! Here's an example from Elm's Lab (maps/ElmsLab.asm):

ElmDirectionsScript:
...
	addcellnum PHONE_ELM
	opentext
	writetext GotElmsNumberText
	playsound SFX_REGISTER_PHONE_NUMBER
	waitsfx
	waitbutton
	closetext
...

GotElmsNumberText:
	text "<PLAYER> got ELM's"
	line "phone number."
	done

Special/Scripted calls (TODO)

⚠️ **GitHub.com Fallback** ⚠️