diff --git a/charmap.txt b/charmap.txt index f7591c29d3..01aec1d9aa 100644 --- a/charmap.txt +++ b/charmap.txt @@ -427,6 +427,8 @@ B_PARTNER_NAME_WITH_CLASS = FD 44 B_ATK_TRAINER_NAME_WITH_CLASS = FD 45 B_EFF_TEAM1 = FD 46 B_EFF_TEAM2 = FD 47 +B_PLAYER_MON1_TITLE = FD 48 +B_PLAYER_MON2_TITLE = FD 49 @ indicates the end of a town/city name (before " TOWN" or " CITY") NAME_END = FC 00 diff --git a/include/battle_message.h b/include/battle_message.h index dca6864d45..a110fc5687 100644 --- a/include/battle_message.h +++ b/include/battle_message.h @@ -87,6 +87,9 @@ #define B_TXT_ATK_TRAINER_NAME_WITH_CLASS 0x45 #define B_TXT_EFF_TEAM1 0x46 #define B_TXT_EFF_TEAM2 0x47 +// Assigned Ribbons +#define B_TXT_PLAYER_MON1_TITLE 0x48 +#define B_TXT_PLAYER_MON2_TITLE 0x49 #define B_BUFF_STRING 0 #define B_BUFF_NUMBER 1 diff --git a/include/pokemon.h b/include/pokemon.h index 282796eec5..f7d530ac5d 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -124,6 +124,7 @@ enum MonData { MON_DATA_GIGANTAMAX_FACTOR, MON_DATA_TERA_TYPE, MON_DATA_EVOLUTION_TRACKER, + MON_DATA_ASSIGNED_RIBBON, }; struct PokemonSubstruct0 @@ -131,7 +132,7 @@ struct PokemonSubstruct0 u16 species:11; // 2047 species. enum Type teraType:5; // 30 types. u16 heldItem:10; // 1023 items. - u16 unused_02:6; + u16 assignedRibbon:6; // 31 Ribbons. u32 experience:21; u32 nickname11:8; // 11th character of nickname. u32 unused_04:3; diff --git a/src/battle_message.c b/src/battle_message.c index 912829e01c..6a441640dd 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -106,7 +106,9 @@ static const u8 sText_TwoLinkTrainersSentOutPkmn[] = _("{B_LINK_OPPONENT1_NAME} static const u8 sText_LinkTrainerSentOutPkmn2[] = _("{B_LINK_OPPONENT1_NAME} sent out {B_BUFF1}!"); static const u8 sText_LinkTrainerMultiSentOutPkmn[] = _("{B_LINK_SCR_TRAINER_NAME} sent out {B_BUFF1}!"); static const u8 sText_GoPkmn[] = _("Go! {B_PLAYER_MON1_NAME}!"); +static const u8 sText_GoPkmnTitle[] = _("Go! {B_PLAYER_MON1_NAME} {B_PLAYER_MON1_TITLE}!"); static const u8 sText_GoTwoPkmn[] = _("Go! {B_PLAYER_MON1_NAME} and {B_PLAYER_MON2_NAME}!"); +static const u8 sText_GoTwoPkmnTitle[] = _("Go! {B_PLAYER_MON1_NAME} {B_PLAYER_MON1_TITLE} and {B_PLAYER_MON2_NAME} {B_PLAYER_MON2_TITLE}!"); static const u8 sText_GoPkmn2[] = _("Go! {B_BUFF1}!"); static const u8 sText_DoItPkmn[] = _("You're in charge, {B_BUFF1}!"); static const u8 sText_GoForItPkmn[] = _("Go for it, {B_BUFF1}!"); @@ -1521,6 +1523,21 @@ static const u8 sText_Your2[] = _("your"); static const u8 sText_Opposing2[] = _("the opposing"); static const u8 sText_EmptyStatus[] = _("$$$$$$$"); +// Ribbon Titles +static const u8 sText_ChampionRibbon_Title[] = _("the Champion"); +static const u8 sText_WinningRibbon_Title[] = _("the Veteran"); +static const u8 sText_VictoryRibbon_Title[] = _("the Veteran Victor"); +static const u8 sText_ArtistRibbon_Title[] = _("the Model for Paintings"); +static const u8 sText_EffortRibbon_Title[] = _("the Once Well-Trained"); +static const u8 sText_MarineRibbon_Title[] = _("the Battle Champion"); +static const u8 sText_LandRibbon_Title[] = _("the Regional Champion"); +static const u8 sText_SkyRibbon_Title[] = _("the National Champion"); +static const u8 sText_CountryRibbon_Title[] = _("the Victor"); +static const u8 sText_NationalRibbon_Title[] = _("the Triumphant"); +static const u8 sText_EarthRibbon_Title[] = _("the 100x Victorious"); +static const u8 sText_WorldRibbon_Title[] = _("the World Conqueror"); +static const u8 sText_NoRibbon_Title[] = _(""); + static const struct BattleWindowText sTextOnWindowsInfo_Normal[] = { [B_WIN_MSG] = { @@ -2474,7 +2491,11 @@ void BufferStringBattle(enum StringID stringID, enum BattlerId battler) } else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) { - stringPtr = sText_GoTwoPkmn; + struct Pokemon *mon = GetBattlerMon(battler); + if (GetMonData(mon, MON_DATA_ASSIGNED_RIBBON) > 0) + stringPtr = sText_GoTwoPkmnTitle; + else + stringPtr = sText_GoTwoPkmn; } else if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { @@ -2485,12 +2506,20 @@ void BufferStringBattle(enum StringID stringID, enum BattlerId battler) } else { - stringPtr = sText_GoTwoPkmn; + struct Pokemon *mon = GetBattlerMon(battler); + if (GetMonData(mon, MON_DATA_ASSIGNED_RIBBON) > 0) + stringPtr = sText_GoTwoPkmnTitle; + else + stringPtr = sText_GoTwoPkmn; } } else { - stringPtr = sText_GoPkmn; + struct Pokemon *mon = GetBattlerMon(battler); + if (GetMonData(mon, MON_DATA_ASSIGNED_RIBBON) > 0) + stringPtr = sText_GoPkmnTitle; + else + stringPtr = sText_GoPkmn; } } else @@ -2906,6 +2935,18 @@ static void GetBattlerNick(enum BattlerId battler, u8 *dst) StringGet_Nickname(dst); } +static u32 GetBattlerRibbon(enum BattlerId battler) +{ + struct Pokemon *illusionMon = GetIllusionMonPtr(battler); + struct Pokemon *mon = GetBattlerMon(battler); + u32 assignedRibbon; + + if (illusionMon != NULL) + mon = illusionMon; + assignedRibbon = GetMonData(mon, MON_DATA_ASSIGNED_RIBBON); + return assignedRibbon; +} + #define HANDLE_NICKNAME_STRING_CASE(battler) \ if (!IsOnPlayerSide(battler)) \ { \ @@ -3112,6 +3153,7 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) u8 *textStart = &text[0]; u8 multiplayerId; u8 fontId = FONT_NORMAL; + u32 assignedRibbon; if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK) multiplayerId = gRecordedBattleMultiplayerId; @@ -3675,6 +3717,58 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) case B_TXT_SCR_ACTIVE_NAME_WITH_PREFIX2: HANDLE_NICKNAME_STRING_LOWERCASE(gBattleScripting.battler) break; + // Should probably funciton this out but eh + case B_TXT_PLAYER_MON1_TITLE: + case B_TXT_PLAYER_MON2_TITLE: + if (*src == B_TXT_PLAYER_MON1_TITLE) + assignedRibbon = GetBattlerRibbon(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)); + else + assignedRibbon = GetBattlerRibbon(GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT)); + //assignedRibbon = GetMonData(&GetBattlerParty(gBattleScripting.battler)[gBattleStruct->scriptPartyIdx], MON_DATA_ASSIGNED_RIBBON); + assignedRibbon--; //subtract 1 cause we added 1 due to Champion Ribbon being 0 + switch (assignedRibbon) + { + case CHAMPION_RIBBON: + toCpy = sText_ChampionRibbon_Title; + break; + case WINNING_RIBBON: + toCpy = sText_WinningRibbon_Title; + break; + case VICTORY_RIBBON: + toCpy = sText_VictoryRibbon_Title; + break; + case ARTIST_RIBBON: + toCpy = sText_ArtistRibbon_Title; + break; + case EFFORT_RIBBON: + toCpy = sText_EffortRibbon_Title; + break; + case MARINE_RIBBON: + toCpy = sText_MarineRibbon_Title; + break; + case LAND_RIBBON: + toCpy = sText_LandRibbon_Title; + break; + case SKY_RIBBON: + toCpy = sText_SkyRibbon_Title; + break; + case COUNTRY_RIBBON: + toCpy = sText_CountryRibbon_Title; + break; + case NATIONAL_RIBBON: + toCpy = sText_NationalRibbon_Title; + break; + case EARTH_RIBBON: + toCpy = sText_EarthRibbon_Title; + break; + case WORLD_RIBBON: + toCpy = sText_WorldRibbon_Title; + break; + default: // Failsafe + toCpy = sText_NoRibbon_Title; + break; + } + break; } if (toCpy != NULL) diff --git a/src/pokemon.c b/src/pokemon.c index 8207d62ac4..065018f00f 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -2908,6 +2908,9 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data) }.combinedValue; } break; + case MON_DATA_ASSIGNED_RIBBON: + retVal = GetSubstruct0(boxMon)->assignedRibbon; + break; default: break; } @@ -3340,6 +3343,9 @@ void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg) substruct1->evolutionTracker2 = evoTracker.tracker2; break; } + case MON_DATA_ASSIGNED_RIBBON: + SET8(GetSubstruct0(boxMon)->assignedRibbon); + break; default: break; } diff --git a/src/pokenav_ribbons_summary.c b/src/pokenav_ribbons_summary.c index 142e861c7c..349a13f53a 100644 --- a/src/pokenav_ribbons_summary.c +++ b/src/pokenav_ribbons_summary.c @@ -249,9 +249,23 @@ static u32 RibbonsSummaryHandleInput(struct Pokenav_RibbonsSummaryList *list) return RIBBONS_SUMMARY_FUNC_NONE; } +static u32 GetRibbonId(void) +{ + struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST); + int ribbonPos = list->selectedPos; + if (ribbonPos < FIRST_GIFT_RIBBON) + return list->ribbonIds[ribbonPos]; + else + return list->giftRibbonIds[ribbonPos - GIFT_RIBBON_START_POS]; +} + // Handles input when a ribbon is selected static u32 HandleExpandedRibbonInput(struct Pokenav_RibbonsSummaryList *list) { + u32 ribbonId = GetRibbonId(); + struct PokenavMonList *mons = list->monList; + struct PokenavMonListItem *monInfo = &mons->monData[mons->currIndex]; + // Handle movement while a ribbon is selected if (JOY_REPEAT(DPAD_UP) && TrySelectRibbonUp(list)) return RIBBONS_SUMMARY_FUNC_EXPANDED_CURSOR_MOVE; @@ -262,6 +276,23 @@ static u32 HandleExpandedRibbonInput(struct Pokenav_RibbonsSummaryList *list) if (JOY_REPEAT(DPAD_RIGHT) && TrySelectRibbonRight(list)) return RIBBONS_SUMMARY_FUNC_EXPANDED_CURSOR_MOVE; + // Select a Ribbon to have "assigned" + if (JOY_NEW(A_BUTTON)) + { + // Mon Data + struct Pokemon *mon = &gPlayerParty[monInfo->monId]; + // Deselect the Ribbon if you Press A on the currently selected Ribbon + ribbonId++; // 0 is Champion Ribbon so let's add 1, can subtract later + if (GetMonData(mon, MON_DATA_ASSIGNED_RIBBON) == ribbonId) { + PlaySE(SE_PC_OFF); + ribbonId = 0; + } + else + PlaySE(SE_PC_LOGIN); + + SetMonData(mon, MON_DATA_ASSIGNED_RIBBON, &ribbonId); + } + if (JOY_NEW(B_BUTTON)) { // Exit ribbon selection @@ -504,16 +535,6 @@ static u16 GetSelectedPosition(void) return list->selectedPos; } -static u32 GetRibbonId(void) -{ - struct Pokenav_RibbonsSummaryList *list = GetSubstructPtr(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_LIST); - int ribbonPos = list->selectedPos; - if (ribbonPos < FIRST_GIFT_RIBBON) - return list->ribbonIds[ribbonPos]; - else - return list->giftRibbonIds[ribbonPos - GIFT_RIBBON_START_POS]; -} - bool32 OpenRibbonsSummaryMenu(void) { struct Pokenav_RibbonsSummaryMenu *menu = AllocSubstruct(POKENAV_SUBSTRUCT_RIBBONS_SUMMARY_MENU, sizeof(struct Pokenav_RibbonsSummaryMenu));