In Pokémon Let's Go, Pikachu/Eevee, you can nickname your Pokémon from the party menu. Let's implement that feature into pokeemerald!
The credits for this feature go to the following users: Shinny456, TheXaman, Lunos and Zadien.
extern const u8 gText_Speed[];
extern const u8 gText_Dash[];
extern const u8 gText_Plus[];
+ extern const u8 gText_Nickname[];
//pokedex text
extern const u8 gText_CryOf[];
In src/party_menu.c:
enum
{
MENU_SUMMARY,
+ MENU_NICKNAME,
MENU_SWITCH,
MENU_CANCEL1,
MENU_ITEM,
static void BlitBitmapToPartyWindow_LeftColumn(u8, u8, u8, u8, u8, u8);
static void BlitBitmapToPartyWindow_RightColumn(u8, u8, u8, u8, u8, u8);
static void CursorCb_Summary(u8);
+ static void CursorCb_Nickname(u8);
static void CursorCb_Switch(u8);
static void CursorCb_Cancel1(u8);
static void CursorCb_Item(u8);
sPartyMenuInternal->numActions = 0;
AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_SUMMARY);
+ AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_NICKNAME);
// Add field moves to action list
for (i = 0; i < MAX_MON_MOVES; i++)
Task_ClosePartyMenu(taskId);
}
+void ChangePokemonNickname(void);
+static void CursorCb_Nickname(u8 taskId)
+{
+ PlaySE(SE_SELECT);
+ gSpecialVar_0x8004 = gPartyMenu.slotId;
+ sPartyMenuInternal->exitCallback = ChangePokemonNickname;
+ Task_ClosePartyMenu(taskId);
+}
+
static void CB2_ShowPokemonSummaryScreen(void)
{
if (gPartyMenu.menuType == PARTY_MENU_TYPE_IN_BATTLE)
Around Line 125:
- u8 actions[8];
+ u8 actions[9];
} static const sCursorOptions[] =
{
[MENU_SUMMARY] = {gText_Summary5, CursorCb_Summary},
+ [MENU_NICKNAME] = {gText_Nickname, CursorCb_Nickname},
[MENU_SWITCH] = {gText_Switch2, CursorCb_Switch},
[MENU_CANCEL1] = {gText_Cancel2, CursorCb_Cancel1},
[MENU_ITEM] = {gText_Item, CursorCb_Item},
And finally, in src/strings.c:
const u8 gText_PokeBalls[] = _("POKé BALLS");
const u8 gText_Berry[] = _("BERRY");
const u8 gText_Berries[] = _("BERRIES");
+const u8 gText_Nickname[] = _("NICKNAME");
Optional additions:
Technically, you could stop here. But there are a few changes you can make to this feature that will make it better:
Disable the ability to assign nicknames to Pokémon with a different OT ID
Normally, the Player is not allowed to change the nickname of Pokémon that were originally owned by another trainer and received through a link trade.
In order to do this, and have a more faithful mechanic implemented in our project, we just need to perform a simple change inside the SetPartyMonFieldSelectionActions
function of src/party_menu.c
sPartyMenuInternal->numActions = 0;
AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_SUMMARY);
- AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_NICKNAME);
+ if (!IsTradedMon(&mons[slotId]))
+ AppendToList(sPartyMenuInternal->actions, &sPartyMenuInternal->numActions, MENU_NICKNAME);
if (!InBattlePike())
Return to the party screen after assigning a nickname
This is a pretty simple change, and it improves upon the feature. Who would want to be thrown back into the overworld after giving a nickname to a Pokémon, specially when you're likely to have more business to attend to inside of the party screen, right?
To do this, we'll make the following changes inside src/party_menu.c:
#include "constants/party_menu.h"
#include "constants/rgb.h"
#include "constants/songs.h"
+#include "naming_screen.h"
#define PARTY_PAL_SELECTED (1 << 0)
#define PARTY_PAL_FAINTED (1 << 1)
static void CB2_ShowPokemonSummaryScreen(void);
static void UpdatePartyToBattleOrder(void);
static void CB2_ReturnToPartyMenuFromSummaryScreen(void);
+static void CB2_ReturnToPartyMenuFromNicknameScreen(void);
static void SlidePartyMenuBoxOneStep(u8);
static void Task_SlideSelectedSlotsOffscreen(u8);
Task_ClosePartyMenu(taskId);
}
-void ChangePokemonNickname(void);
+static void ChangePokemonNicknamePartyScreen_CB(void)
+{
+ SetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar2);
+ CB2_ReturnToPartyMenuFromNicknameScreen();
+}
+
+static void ChangePokemonNicknamePartyScreen(void)
+{
+ GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar3);
+ GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_NICKNAME, gStringVar2);
+ DoNamingScreen(NAMING_SCREEN_NICKNAME, gStringVar2, GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_SPECIES, NULL), GetMonGender(&gPlayerParty[gSpecialVar_0x8004]), GetMonData(&gPlayerParty[gSpecialVar_0x8004], MON_DATA_PERSONALITY, NULL), ChangePokemonNicknamePartyScreen_CB);
+}
+
static void CursorCb_Nickname(u8 taskId)
{
PlaySE(SE_SELECT);
gSpecialVar_0x8004 = gPartyMenu.slotId;
- sPartyMenuInternal->exitCallback = ChangePokemonNickname;
+ sPartyMenuInternal->exitCallback = ChangePokemonNicknamePartyScreen;
Task_ClosePartyMenu(taskId);
}
static void CB2_ReturnToPartyMenuFromSummaryScreen(void)
{
gPaletteFade.bufferTransferDisabled = TRUE;
gPartyMenu.slotId = gLastViewedMonIndex;
InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, TRUE, PARTY_MSG_DO_WHAT_WITH_MON, Task_TryCreateSelectionWindow, gPartyMenu.exitCallback);
}
+
+static void CB2_ReturnToPartyMenuFromNicknameScreen(void)
+{
+ gPaletteFade.bufferTransferDisabled = TRUE;
+ InitPartyMenu(gPartyMenu.menuType, KEEP_PARTY_LAYOUT, gPartyMenu.action, TRUE, PARTY_MSG_DO_WHAT_WITH_MON, Task_TryCreateSelectionWindow, gPartyMenu.exitCallback);
+}
Now, when you're returned to the party screen after assigning a nickname to a Pokémon, the highlighted slot is the one for the Pokémon whose nickname was just changed, as expected.
To achieve this, the function CB2_ReturnToPartyMenuFromNicknameScreen
was introduced specifically for handling nickname changes from the party menu. Removing gLastViewedMonIndex
from the summary screen callback would introduce an unintended regression where switching Pokémon in the summary screen and closing it wouldn't highlight the last viewed Pokémon anymore. Therefore, the new CB2_ReturnToPartyMenuFromNicknameScreen
function was added to handle this particular case while keeping the summary screen behavior intact.