From d4147879320c563254059a92eb7a07b5cfcc2143 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 16 Nov 2021 16:13:52 -0500 Subject: [PATCH] Some TV clean-up --- data/maps/SlateportCity/scripts.inc | 2 + data/scripts/tv.inc | 4 +- include/constants/event_objects.h | 1 + include/constants/tv.h | 8 + include/global.h | 6 +- include/global.tv.h | 22 +- src/tv.c | 334 ++++++++++++++-------------- 7 files changed, 198 insertions(+), 179 deletions(-) diff --git a/data/maps/SlateportCity/scripts.inc b/data/maps/SlateportCity/scripts.inc index 693a99e49..be2f3f3e5 100644 --- a/data/maps/SlateportCity/scripts.inc +++ b/data/maps/SlateportCity/scripts.inc @@ -19,6 +19,8 @@ .set LOCALID_GRUNT_11, 33 .set LOCALID_SCOTT, 35 +@ Note: LOCALID_SLATEPORT_ENERGY_GURU is a local id for this map used elsewhere. It's defined in event_objects.h + SlateportCity_MapScripts:: map_script MAP_SCRIPT_ON_TRANSITION, SlateportCity_OnTransition map_script MAP_SCRIPT_ON_FRAME_TABLE, SlateportCity_OnFrame diff --git a/data/scripts/tv.inc b/data/scripts/tv.inc index 14f3ade48..f8832a3ab 100644 --- a/data/scripts/tv.inc +++ b/data/scripts/tv.inc @@ -52,11 +52,13 @@ EventScript_PlayersHouseLatiNewsFlash:: releaseall end +@ The following is a loop for the TV show messages +@ VAR_RESULT is set to TRUE when the show has printed its final message EventScript_DoTVShow:: special DoTVShow waitmessage waitbuttonpress - compare VAR_RESULT, 1 + compare VAR_RESULT, TRUE goto_if_ne EventScript_DoTVShow goto EventScript_TurnOffTV end diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index 1958c792e..6b99f19bd 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -311,5 +311,6 @@ #define LOCALID_MOSSDEEP_MART_CLERK 1 #define LOCALID_SOOTOPOLIS_MART_CLERK 1 #define LOCALID_BATTLE_FRONTIER_MART_CLERK 1 +#define LOCALID_SLATEPORT_ENERGY_GURU 25 #endif // GUARD_CONSTANTS_EVENT_OBJECTS_H diff --git a/include/constants/tv.h b/include/constants/tv.h index 3fe6c57b2..4c8dd4fa8 100644 --- a/include/constants/tv.h +++ b/include/constants/tv.h @@ -8,6 +8,14 @@ #define POKENEWS_BLENDMASTER 4 #define NUM_POKENEWS_TYPES 4 // Excludes NONE +#define POKENEWS_STATE_INACTIVE 0 +#define POKENEWS_STATE_UPCOMING 1 +#define POKENEWS_STATE_ACTIVE 2 + +// Number of days to count down until the news event occurs. +// Nothing is aired on TV the first day +#define POKENEWS_COUNTDOWN 4 + // TV shows are categorized as being in one of 3 groups // - TVGROUP_NORMAL, TV shows that can appear without Record Mixing // - TVGROUP_RECORD_MIX, TV shows that can only appear via Record Mixing diff --git a/include/global.h b/include/global.h index 9aac66fda..024280f98 100644 --- a/include/global.h +++ b/include/global.h @@ -972,10 +972,10 @@ struct SaveBlock1 /*0x2B92*/ u8 outbreakLocationMapNum; /*0x2B93*/ u8 outbreakLocationMapGroup; /*0x2B94*/ u8 outbreakPokemonLevel; - /*0x2B95*/ u8 outbreakUnk1; - /*0x2B96*/ u16 outbreakUnk2; + /*0x2B95*/ u8 outbreakUnused1; + /*0x2B96*/ u16 outbreakUnused2; /*0x2B98*/ u16 outbreakPokemonMoves[MAX_MON_MOVES]; - /*0x2BA0*/ u8 outbreakUnk4; + /*0x2BA0*/ u8 outbreakUnused3; /*0x2BA1*/ u8 outbreakPokemonProbability; /*0x2BA2*/ u16 outbreakDaysLeft; /*0x2BA4*/ struct GabbyAndTyData gabbyAndTyData; diff --git a/include/global.tv.h b/include/global.tv.h index 2bc7dda99..e24ead3f2 100644 --- a/include/global.tv.h +++ b/include/global.tv.h @@ -61,7 +61,7 @@ typedef union // size = 0x24 /*0x0F*/ u8 filler_0F[1]; /*0x10*/ u8 nickname[PLAYER_NAME_LENGTH + 1]; /*0x18*/ u16 words18[2]; - /*0x1C*/ u16 words[4]; + /*0x1C*/ u16 words[2]; } fanclubOpinions; // TVSHOW_DUMMY @@ -334,7 +334,7 @@ typedef union // size = 0x24 /*0x00*/ u8 kind; /*0x01*/ bool8 active; /*0x02*/ u8 avgLevel; - /*0x03*/ u8 nDecorations; + /*0x03*/ u8 numDecorations; /*0x04*/ u8 decorations[4]; /*0x08*/ u16 species; /*0x0a*/ u16 move; @@ -437,8 +437,8 @@ typedef union // size = 0x24 struct { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u8 nMonsCaught; - /*0x03*/ u8 nPkblkUsed; + /*0x02*/ u8 monsCaught; + /*0x03*/ u8 pokeblocksUsed; /*0x04*/ u8 language; /*0x05*/ u8 filler_05[14]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; @@ -449,27 +449,27 @@ typedef union // size = 0x24 struct { /*0x00*/ u8 kind; /*0x01*/ bool8 active; - /*0x02*/ u8 var02; - /*0x03*/ u8 var03; + /*0x02*/ u8 unused1; + /*0x03*/ u8 unused3; /*0x04*/ u16 moves[MAX_MON_MOVES]; /*0x0C*/ u16 species; - /*0x0E*/ u16 var0E; + /*0x0E*/ u16 unused2; /*0x10*/ u8 locationMapNum; /*0x11*/ u8 locationMapGroup; - /*0x12*/ u8 var12; + /*0x12*/ u8 unused4; /*0x13*/ u8 probability; /*0x14*/ u8 level; - /*0x15*/ u8 var15; + /*0x15*/ u8 unused5; /*0x16*/ u16 daysLeft; /*0x18*/ u8 language; } massOutbreak; } TVShow; -typedef struct // 2b50 +typedef struct { u8 kind; u8 state; - u16 days; + u16 dayCountdown; } PokeNews; struct GabbyAndTyData diff --git a/src/tv.c b/src/tv.c index 64c3eb783..de1657813 100644 --- a/src/tv.c +++ b/src/tv.c @@ -36,6 +36,7 @@ #include "data.h" #include "constants/battle_frontier.h" #include "constants/contest.h" +#include "constants/decorations.h" #include "constants/event_objects.h" #include "constants/items.h" #include "constants/layouts.h" @@ -139,7 +140,7 @@ static void TryPutRandomPokeNewsOnAir(void); static void SortPurchasesByQuantity(void); static void UpdateMassOutbreakTimeLeft(u16); static void TryEndMassOutbreak(u16); -static void UpdatePokeNewsTimeLeft(u16); +static void UpdatePokeNewsCountdown(u16); static void ResolveWorldOfMastersShow(u16); static void ResolveNumberOneShow(u16); static void TryPutFishingAdviceOnAir(void); @@ -227,24 +228,24 @@ static const struct { } }; -static const u16 sGoldSymbolFlags[] = { - FLAG_SYS_TOWER_GOLD, - FLAG_SYS_DOME_GOLD, - FLAG_SYS_PALACE_GOLD, - FLAG_SYS_ARENA_GOLD, - FLAG_SYS_FACTORY_GOLD, - FLAG_SYS_PIKE_GOLD, - FLAG_SYS_PYRAMID_GOLD +static const u16 sGoldSymbolFlags[NUM_FRONTIER_FACILITIES] = { + [FRONTIER_FACILITY_TOWER] = FLAG_SYS_TOWER_GOLD, + [FRONTIER_FACILITY_DOME] = FLAG_SYS_DOME_GOLD, + [FRONTIER_FACILITY_PALACE] = FLAG_SYS_PALACE_GOLD, + [FRONTIER_FACILITY_ARENA] = FLAG_SYS_ARENA_GOLD, + [FRONTIER_FACILITY_FACTORY] = FLAG_SYS_FACTORY_GOLD, + [FRONTIER_FACILITY_PIKE] = FLAG_SYS_PIKE_GOLD, + [FRONTIER_FACILITY_PYRAMID] = FLAG_SYS_PYRAMID_GOLD }; -static const u16 sSilverSymbolFlags[] = { - FLAG_SYS_TOWER_SILVER, - FLAG_SYS_DOME_SILVER, - FLAG_SYS_PALACE_SILVER, - FLAG_SYS_ARENA_SILVER, - FLAG_SYS_FACTORY_SILVER, - FLAG_SYS_PIKE_SILVER, - FLAG_SYS_PYRAMID_SILVER +static const u16 sSilverSymbolFlags[NUM_FRONTIER_FACILITIES] = { + [FRONTIER_FACILITY_TOWER] = FLAG_SYS_TOWER_SILVER, + [FRONTIER_FACILITY_DOME] = FLAG_SYS_DOME_SILVER, + [FRONTIER_FACILITY_PALACE] = FLAG_SYS_PALACE_SILVER, + [FRONTIER_FACILITY_ARENA] = FLAG_SYS_ARENA_SILVER, + [FRONTIER_FACILITY_FACTORY] = FLAG_SYS_FACTORY_SILVER, + [FRONTIER_FACILITY_PIKE] = FLAG_SYS_PIKE_SILVER, + [FRONTIER_FACILITY_PYRAMID] = FLAG_SYS_PYRAMID_SILVER }; static const u16 sNumberOneVarsAndThresholds[][2] = { @@ -257,28 +258,28 @@ static const u16 sNumberOneVarsAndThresholds[][2] = { {VAR_DAILY_BP, 30} }; -static const u8 *const sPokeNewsTextGroup_Upcoming[] = { - NULL, - gPokeNewsTextSlateport_Upcoming, - gPokeNewsTextGameCorner_Upcoming, - gPokeNewsTextLilycove_Upcoming, - gPokeNewsTextBlendMaster_Upcoming +static const u8 *const sPokeNewsTextGroup_Upcoming[NUM_POKENEWS_TYPES + 1] = { + [POKENEWS_NONE] = NULL, + [POKENEWS_SLATEPORT] = gPokeNewsTextSlateport_Upcoming, + [POKENEWS_GAME_CORNER] = gPokeNewsTextGameCorner_Upcoming, + [POKENEWS_LILYCOVE] = gPokeNewsTextLilycove_Upcoming, + [POKENEWS_BLENDMASTER] = gPokeNewsTextBlendMaster_Upcoming }; -static const u8 *const sPokeNewsTextGroup_Ongoing[] = { - NULL, - gPokeNewsTextSlateport_Ongoing, - gPokeNewsTextGameCorner_Ongoing, - gPokeNewsTextLilycove_Ongoing, - gPokeNewsTextBlendMaster_Ongoing +static const u8 *const sPokeNewsTextGroup_Ongoing[NUM_POKENEWS_TYPES + 1] = { + [POKENEWS_NONE] = NULL, + [POKENEWS_SLATEPORT] = gPokeNewsTextSlateport_Ongoing, + [POKENEWS_GAME_CORNER] = gPokeNewsTextGameCorner_Ongoing, + [POKENEWS_LILYCOVE] = gPokeNewsTextLilycove_Ongoing, + [POKENEWS_BLENDMASTER] = gPokeNewsTextBlendMaster_Ongoing }; -static const u8 *const sPokeNewsTextGroup_Ending[] = { - NULL, - gPokeNewsTextSlateport_Ending, - gPokeNewsTextGameCorner_Ending, - gPokeNewsTextLilycove_Ending, - gPokeNewsTextBlendMaster_Ending +static const u8 *const sPokeNewsTextGroup_Ending[NUM_POKENEWS_TYPES + 1] = { + [POKENEWS_NONE] = NULL, + [POKENEWS_SLATEPORT] = gPokeNewsTextSlateport_Ending, + [POKENEWS_GAME_CORNER] = gPokeNewsTextGameCorner_Ending, + [POKENEWS_LILYCOVE] = gPokeNewsTextLilycove_Ending, + [POKENEWS_BLENDMASTER] = gPokeNewsTextBlendMaster_Ending }; u8 *const gTVStringVarPtrs[] = { @@ -1568,13 +1569,13 @@ void StartMassOutbreak(void) gSaveBlock1Ptr->outbreakLocationMapNum = show->massOutbreak.locationMapNum; gSaveBlock1Ptr->outbreakLocationMapGroup = show->massOutbreak.locationMapGroup; gSaveBlock1Ptr->outbreakPokemonLevel = show->massOutbreak.level; - gSaveBlock1Ptr->outbreakUnk1 = show->massOutbreak.var02; - gSaveBlock1Ptr->outbreakUnk2 = show->massOutbreak.var0E; + gSaveBlock1Ptr->outbreakUnused1 = show->massOutbreak.unused1; + gSaveBlock1Ptr->outbreakUnused2 = show->massOutbreak.unused2; gSaveBlock1Ptr->outbreakPokemonMoves[0] = show->massOutbreak.moves[0]; gSaveBlock1Ptr->outbreakPokemonMoves[1] = show->massOutbreak.moves[1]; gSaveBlock1Ptr->outbreakPokemonMoves[2] = show->massOutbreak.moves[2]; gSaveBlock1Ptr->outbreakPokemonMoves[3] = show->massOutbreak.moves[3]; - gSaveBlock1Ptr->outbreakUnk4 = show->massOutbreak.var03; + gSaveBlock1Ptr->outbreakUnused3 = show->massOutbreak.unused3; gSaveBlock1Ptr->outbreakPokemonProbability = show->massOutbreak.probability; gSaveBlock1Ptr->outbreakDaysLeft = 2; } @@ -1667,19 +1668,19 @@ static void TryStartRandomMassOutbreak(void) show->massOutbreak.kind = TVSHOW_MASS_OUTBREAK; show->massOutbreak.active = TRUE; show->massOutbreak.level = sPokeOutbreakSpeciesList[outbreakIdx].level; - show->massOutbreak.var02 = 0; - show->massOutbreak.var03 = 0; + show->massOutbreak.unused1 = 0; + show->massOutbreak.unused3 = 0; show->massOutbreak.species = sPokeOutbreakSpeciesList[outbreakIdx].species; - show->massOutbreak.var0E = 0; + show->massOutbreak.unused2 = 0; show->massOutbreak.moves[0] = sPokeOutbreakSpeciesList[outbreakIdx].moves[0]; show->massOutbreak.moves[1] = sPokeOutbreakSpeciesList[outbreakIdx].moves[1]; show->massOutbreak.moves[2] = sPokeOutbreakSpeciesList[outbreakIdx].moves[2]; show->massOutbreak.moves[3] = sPokeOutbreakSpeciesList[outbreakIdx].moves[3]; show->massOutbreak.locationMapNum = sPokeOutbreakSpeciesList[outbreakIdx].location; show->massOutbreak.locationMapGroup = 0; - show->massOutbreak.var12 = 0; + show->massOutbreak.unused4 = 0; show->massOutbreak.probability = 50; - show->massOutbreak.var15 = 0; + show->massOutbreak.unused5 = 0; show->massOutbreak.daysLeft = 1; StorePlayerIdInNormalShow(show); show->massOutbreak.language = gGameLanguage; @@ -1694,13 +1695,13 @@ void EndMassOutbreak(void) gSaveBlock1Ptr->outbreakLocationMapNum = 0; gSaveBlock1Ptr->outbreakLocationMapGroup = 0; gSaveBlock1Ptr->outbreakPokemonLevel = 0; - gSaveBlock1Ptr->outbreakUnk1 = 0; - gSaveBlock1Ptr->outbreakUnk2 = 0; + gSaveBlock1Ptr->outbreakUnused1 = 0; + gSaveBlock1Ptr->outbreakUnused2 = 0; gSaveBlock1Ptr->outbreakPokemonMoves[0] = MOVE_NONE; gSaveBlock1Ptr->outbreakPokemonMoves[1] = MOVE_NONE; gSaveBlock1Ptr->outbreakPokemonMoves[2] = MOVE_NONE; gSaveBlock1Ptr->outbreakPokemonMoves[3] = MOVE_NONE; - gSaveBlock1Ptr->outbreakUnk4 = 0; + gSaveBlock1Ptr->outbreakUnused3 = 0; gSaveBlock1Ptr->outbreakPokemonProbability = 0; gSaveBlock1Ptr->outbreakDaysLeft = 0; } @@ -1709,7 +1710,7 @@ void UpdateTVShowsPerDay(u16 days) { UpdateMassOutbreakTimeLeft(days); TryEndMassOutbreak(days); - UpdatePokeNewsTimeLeft(days); + UpdatePokeNewsCountdown(days); ResolveWorldOfMastersShow(days); ResolveNumberOneShow(days); } @@ -1797,9 +1798,7 @@ void SetPokemonAnglerSpecies(u16 species) // Either way the temporary version of the show in the last slot is deleted. static void ResolveWorldOfMastersShow(u16 days) { - TVShow *show; - - show = &gSaveBlock1Ptr->tvShows[LAST_TVSHOW_IDX]; + TVShow *show = &gSaveBlock1Ptr->tvShows[LAST_TVSHOW_IDX]; if (show->worldOfMasters.kind == TVSHOW_WORLD_OF_MASTERS) { if (show->worldOfMasters.numPokeCaught >= 20) @@ -1863,7 +1862,7 @@ void TryPutTodaysRivalTrainerOnAir(void) show->rivalTrainer.mapLayoutId = gMapHeader.mapLayoutId; show->rivalTrainer.nSilverSymbols = 0; show->rivalTrainer.nGoldSymbols = 0; - for (i = 0; i < 7; i++) + for (i = 0; i < NUM_FRONTIER_FACILITIES; i++) { if (FlagGet(sSilverSymbolFlags[i]) == TRUE) show->rivalTrainer.nSilverSymbols++; @@ -1989,33 +1988,39 @@ static void SecretBaseVisit_CalculateDecorationData(TVShow *show) u8 decoration; for (i = 0; i < DECOR_MAX_SECRET_BASE; i++) - sTV_DecorationsBuffer[i] = 0; + sTV_DecorationsBuffer[i] = DECOR_NONE; + // Count (and save) the unique decorations in the base for (i = 0, n = 0; i < DECOR_MAX_SECRET_BASE; i++) { decoration = gSaveBlock1Ptr->secretBases[0].decorations[i]; - if (decoration) + if (decoration != DECOR_NONE) { + // Search for an empty spot to save decoration for (j = 0; j < DECOR_MAX_SECRET_BASE; j++) { - if (sTV_DecorationsBuffer[j] == 0) + if (sTV_DecorationsBuffer[j] == DECOR_NONE) { + // Save and count new unique decoration sTV_DecorationsBuffer[j] = decoration; n++; break; } + + // Decoration has already been saved, skip and move on to the next base decoration if (sTV_DecorationsBuffer[j] == decoration) break; } } } - if (n > 4) - show->secretBaseVisit.nDecorations = 4; + // Cap the number of unique decorations to the number the TV show will talk about + if (n > ARRAY_COUNT(show->secretBaseVisit.decorations)) + show->secretBaseVisit.numDecorations = ARRAY_COUNT(show->secretBaseVisit.decorations); else - show->secretBaseVisit.nDecorations = n; + show->secretBaseVisit.numDecorations = n; - switch (show->secretBaseVisit.nDecorations) + switch (show->secretBaseVisit.numDecorations) { case 0: break; @@ -2023,16 +2028,16 @@ static void SecretBaseVisit_CalculateDecorationData(TVShow *show) show->secretBaseVisit.decorations[0] = sTV_DecorationsBuffer[0]; break; default: + // More than 1 decoration, randomize the full list for (k = 0; k < n * n; k++) { decoration = Random() % n; j = Random() % n; - i = sTV_DecorationsBuffer[decoration]; - sTV_DecorationsBuffer[decoration] = sTV_DecorationsBuffer[j]; - sTV_DecorationsBuffer[j] = i; + SWAP(sTV_DecorationsBuffer[decoration], sTV_DecorationsBuffer[j], i); } - for (i = 0; i < show->secretBaseVisit.nDecorations; i++) + // Pick the first decorations in the randomized list to talk about on the show + for (i = 0; i < show->secretBaseVisit.numDecorations; i++) show->secretBaseVisit.decorations[i] = sTV_DecorationsBuffer[i]; break; } @@ -2043,50 +2048,55 @@ static void SecretBaseVisit_CalculatePartyData(TVShow *show) u8 i; u16 move; u16 j; - u8 nMoves; - u8 nPokemon; + u8 numMoves; + u8 numPokemon; u16 sum; - for (i = 0, nPokemon = 0; i < PARTY_SIZE; i++) + for (i = 0, numPokemon = 0; i < PARTY_SIZE; i++) { if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) != SPECIES_NONE && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)) { - sTV_SecretBaseVisitMonsTemp[nPokemon].level = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); - sTV_SecretBaseVisitMonsTemp[nPokemon].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES); - nMoves = 0; + sTV_SecretBaseVisitMonsTemp[numPokemon].level = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); + sTV_SecretBaseVisitMonsTemp[numPokemon].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES); + + // Check all the Pokémon's moves, then randomly select one to save + numMoves = 0; move = GetMonData(&gPlayerParty[i], MON_DATA_MOVE1); if (move != MOVE_NONE) { - sTV_SecretBaseVisitMovesTemp[nMoves] = move; - nMoves++; + sTV_SecretBaseVisitMovesTemp[numMoves] = move; + numMoves++; } move = GetMonData(&gPlayerParty[i], MON_DATA_MOVE2); if (move != MOVE_NONE) { - sTV_SecretBaseVisitMovesTemp[nMoves] = move; - nMoves++; + sTV_SecretBaseVisitMovesTemp[numMoves] = move; + numMoves++; } move = GetMonData(&gPlayerParty[i], MON_DATA_MOVE3); if (move != MOVE_NONE) { - sTV_SecretBaseVisitMovesTemp[nMoves] = move; - nMoves++; + sTV_SecretBaseVisitMovesTemp[numMoves] = move; + numMoves++; } move = GetMonData(&gPlayerParty[i], MON_DATA_MOVE4); if (move != MOVE_NONE) { - sTV_SecretBaseVisitMovesTemp[nMoves] = move; - nMoves++; + sTV_SecretBaseVisitMovesTemp[numMoves] = move; + numMoves++; } - sTV_SecretBaseVisitMonsTemp[nPokemon].move = sTV_SecretBaseVisitMovesTemp[Random() % nMoves]; - nPokemon++; + sTV_SecretBaseVisitMonsTemp[numPokemon].move = sTV_SecretBaseVisitMovesTemp[Random() % numMoves]; + numPokemon++; } } - for (i = 0, sum = 0; i < nPokemon; i++) + + for (i = 0, sum = 0; i < numPokemon; i++) sum += sTV_SecretBaseVisitMonsTemp[i].level; - show->secretBaseVisit.avgLevel = sum / nPokemon; - j = Random() % nPokemon; + // Using the data calculated above, save the data to talk about on the show + // (average level, and one randomly selected species / move) + show->secretBaseVisit.avgLevel = sum / numPokemon; + j = Random() % numPokemon; show->secretBaseVisit.species = sTV_SecretBaseVisitMonsTemp[j].species; show->secretBaseVisit.move = sTV_SecretBaseVisitMonsTemp[j].move; } @@ -2224,7 +2234,7 @@ void TryPutBattleSeminarOnAir(u16 foeSpecies, u16 species, u8 moveIdx, const u16 } } -void TryPutSafariFanClubOnAir(u8 nMonsCaught, u8 nPkblkUsed) +void TryPutSafariFanClubOnAir(u8 monsCaught, u8 pokeblocksUsed) { TVShow *show; @@ -2235,8 +2245,8 @@ void TryPutSafariFanClubOnAir(u8 nMonsCaught, u8 nPkblkUsed) show->safariFanClub.kind = TVSHOW_SAFARI_FAN_CLUB; show->safariFanClub.active = FALSE; // NOTE: Show is not active until passed via Record Mix. StringCopy(show->safariFanClub.playerName, gSaveBlock2Ptr->playerName); - show->safariFanClub.nMonsCaught = nMonsCaught; - show->safariFanClub.nPkblkUsed = nPkblkUsed; + show->safariFanClub.monsCaught = monsCaught; + show->safariFanClub.pokeblocksUsed = pokeblocksUsed; StorePlayerIdInRecordMixShow(show); show->safariFanClub.language = gGameLanguage; } @@ -2536,12 +2546,12 @@ static void TryPutRandomPokeNewsOnAir(void) sCurTVShowSlot = GetFirstEmptyPokeNewsSlot(gSaveBlock1Ptr->pokeNews); if (sCurTVShowSlot != -1 && rbernoulli(1, 100) != TRUE) { - u8 newsKind = (Random() % NUM_POKENEWS_TYPES) + POKENEWS_SLATEPORT; + u8 newsKind = (Random() % NUM_POKENEWS_TYPES) + 1; // +1 to skip over POKENEWS_NONE if (IsAddingPokeNewsDisallowed(newsKind) != TRUE) { gSaveBlock1Ptr->pokeNews[sCurTVShowSlot].kind = newsKind; - gSaveBlock1Ptr->pokeNews[sCurTVShowSlot].days = 4; - gSaveBlock1Ptr->pokeNews[sCurTVShowSlot].state = 1; + gSaveBlock1Ptr->pokeNews[sCurTVShowSlot].dayCountdown = POKENEWS_COUNTDOWN; + gSaveBlock1Ptr->pokeNews[sCurTVShowSlot].state = POKENEWS_STATE_UPCOMING; } } } @@ -2570,8 +2580,8 @@ static void ClearPokeNews(void) static void ClearPokeNewsBySlot(u8 i) { gSaveBlock1Ptr->pokeNews[i].kind = POKENEWS_NONE; - gSaveBlock1Ptr->pokeNews[i].state = FALSE; - gSaveBlock1Ptr->pokeNews[i].days = 0; + gSaveBlock1Ptr->pokeNews[i].state = POKENEWS_STATE_INACTIVE; + gSaveBlock1Ptr->pokeNews[i].dayCountdown = 0; } static void CompactPokeNews(void) @@ -2603,8 +2613,8 @@ static u8 FindAnyPokeNewsOnTheAir(void) for (i = 0; i < POKE_NEWS_COUNT; i++) { if (gSaveBlock1Ptr->pokeNews[i].kind != POKENEWS_NONE - && gSaveBlock1Ptr->pokeNews[i].state == 1 - && gSaveBlock1Ptr->pokeNews[i].days < 3) + && gSaveBlock1Ptr->pokeNews[i].state == POKENEWS_STATE_UPCOMING + && gSaveBlock1Ptr->pokeNews[i].dayCountdown < POKENEWS_COUNTDOWN - 1) return i; } return 0xFF; @@ -2612,19 +2622,17 @@ static u8 FindAnyPokeNewsOnTheAir(void) void DoPokeNews(void) { - u8 i; - u16 n; - - i = FindAnyPokeNewsOnTheAir(); + u8 i = FindAnyPokeNewsOnTheAir(); if (i == 0xFF) { gSpecialVar_Result = FALSE; } else { - if (gSaveBlock1Ptr->pokeNews[i].days == 0) + if (gSaveBlock1Ptr->pokeNews[i].dayCountdown == 0) { - gSaveBlock1Ptr->pokeNews[i].state = 2; + // News event is occurring, make comment depending on how much time is left + gSaveBlock1Ptr->pokeNews[i].state = POKENEWS_STATE_ACTIVE; if (gLocalTime.hours < 20) ShowFieldMessage(sPokeNewsTextGroup_Ongoing[gSaveBlock1Ptr->pokeNews[i].kind]); else @@ -2632,9 +2640,13 @@ void DoPokeNews(void) } else { - n = gSaveBlock1Ptr->pokeNews[i].days; - ConvertIntToDecimalStringN(gStringVar1, n, STR_CONV_MODE_LEFT_ALIGN, 1); - gSaveBlock1Ptr->pokeNews[i].state = 0; + // News event is upcoming, make comment about countdown to event + u16 dayCountdown = gSaveBlock1Ptr->pokeNews[i].dayCountdown; + ConvertIntToDecimalStringN(gStringVar1, dayCountdown, STR_CONV_MODE_LEFT_ALIGN, 1); + + // Mark as inactive so the countdown TV airing doesn't repeat + // Will be flagged as "upcoming" again by UpdatePokeNewsCountdown + gSaveBlock1Ptr->pokeNews[i].state = POKENEWS_STATE_INACTIVE; ShowFieldMessage(sPokeNewsTextGroup_Upcoming[gSaveBlock1Ptr->pokeNews[i].kind]); } gSpecialVar_Result = TRUE; @@ -2652,7 +2664,7 @@ bool8 IsPokeNewsActive(u8 newsKind) { if (gSaveBlock1Ptr->pokeNews[i].kind == newsKind) { - if (gSaveBlock1Ptr->pokeNews[i].state == 2 && ShouldApplyPokeNewsEffect(newsKind)) + if (gSaveBlock1Ptr->pokeNews[i].state == POKENEWS_STATE_ACTIVE && ShouldApplyPokeNewsEffect(newsKind)) return TRUE; return FALSE; @@ -2662,19 +2674,22 @@ bool8 IsPokeNewsActive(u8 newsKind) } // Returns TRUE if the effects of the given PokeNews should be applied. -// For POKENEWS_SLATEPORT / POKENEWS_LILYCOVE, only apply the effect (price reduction) -// if the player is talking to the Energy Guru / at the Dept Store Rooftop. +// For POKENEWS_SLATEPORT / POKENEWS_LILYCOVE, only apply the effect if +// the player is talking to the Energy Guru / at the Dept Store Rooftop. // For any other type of PokeNews this is always TRUE. static bool8 ShouldApplyPokeNewsEffect(u8 newsKind) { switch (newsKind) { case POKENEWS_SLATEPORT: - if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(SLATEPORT_CITY) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(SLATEPORT_CITY) && gSpecialVar_LastTalked == 25) + if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(SLATEPORT_CITY) + && gSaveBlock1Ptr->location.mapNum == MAP_NUM(SLATEPORT_CITY) + && gSpecialVar_LastTalked == LOCALID_SLATEPORT_ENERGY_GURU) return TRUE; return FALSE; case POKENEWS_LILYCOVE: - if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP)) + if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP) + && gSaveBlock1Ptr->location.mapNum == MAP_NUM(LILYCOVE_CITY_DEPARTMENT_STORE_ROOFTOP)) return TRUE; return FALSE; } @@ -2696,7 +2711,7 @@ static bool8 IsAddingPokeNewsDisallowed(u8 newsKind) return FALSE; } -static void UpdatePokeNewsTimeLeft(u16 days) +static void UpdatePokeNewsCountdown(u16 days) { u8 i; @@ -2704,16 +2719,18 @@ static void UpdatePokeNewsTimeLeft(u16 days) { if (gSaveBlock1Ptr->pokeNews[i].kind != POKENEWS_NONE) { - if (gSaveBlock1Ptr->pokeNews[i].days < days) + if (gSaveBlock1Ptr->pokeNews[i].dayCountdown < days) { + // News event has elapsed, clear it from list ClearPokeNewsBySlot(i); } else { - if (gSaveBlock1Ptr->pokeNews[i].state == 0 && FlagGet(FLAG_SYS_GAME_CLEAR) == TRUE) - gSaveBlock1Ptr->pokeNews[i].state = 1; + // Progress countdown to news event + if (gSaveBlock1Ptr->pokeNews[i].state == POKENEWS_STATE_INACTIVE && FlagGet(FLAG_SYS_GAME_CLEAR) == TRUE) + gSaveBlock1Ptr->pokeNews[i].state = POKENEWS_STATE_UPCOMING; - gSaveBlock1Ptr->pokeNews[i].days -= days; + gSaveBlock1Ptr->pokeNews[i].dayCountdown -= days; } } } @@ -2763,9 +2780,7 @@ void CopyContestCategoryToStringVar(u8 varIdx, u8 category) void SetContestCategoryStringVarForInterview(void) { - TVShow *show; - - show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004]; + TVShow *show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004]; CopyContestCategoryToStringVar(1, show->bravoTrainer.contestCategory); } @@ -2792,9 +2807,7 @@ size_t CountDigits(int value) static void SmartShopper_BufferPurchaseTotal(u8 varIdx, TVShow *show) { u8 i; - int price; - - price = 0; + int price = 0; for (i = 0; i < SMARTSHOPPER_NUM_ITEMS; i++) { if (show->smartshopperShow.itemIds[i] != ITEM_NONE) @@ -2835,21 +2848,19 @@ static bool8 IsRecordMixShowAlreadySpawned(u8 kind, bool8 delete) static void SortPurchasesByQuantity(void) { u8 i, j; - u16 tmpId; - u16 tmpQn; - + for (i = 0; i < SMARTSHOPPER_NUM_ITEMS - 1; i++) { for (j = i + 1; j < SMARTSHOPPER_NUM_ITEMS; j++) { if (gMartPurchaseHistory[i].quantity < gMartPurchaseHistory[j].quantity) { - tmpId = gMartPurchaseHistory[i].itemId; - tmpQn = gMartPurchaseHistory[i].quantity; + u16 tempItemId = gMartPurchaseHistory[i].itemId; + u16 tempQuantity = gMartPurchaseHistory[i].quantity; gMartPurchaseHistory[i].itemId = gMartPurchaseHistory[j].itemId; gMartPurchaseHistory[i].quantity = gMartPurchaseHistory[j].quantity; - gMartPurchaseHistory[j].itemId = tmpId; - gMartPurchaseHistory[j].quantity = tmpQn; + gMartPurchaseHistory[j].itemId = tempItemId; + gMartPurchaseHistory[j].quantity = tempQuantity; } } } @@ -2926,7 +2937,8 @@ static void InterviewBefore_FanClubLetter(void) if (!gSpecialVar_Result) { StringCopy(gStringVar1, gSpeciesNames[GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPECIES, NULL)]); - InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].fanclubLetter.words, 6); + InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].fanclubLetter.words, + ARRAY_COUNT(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].fanclubLetter.words)); } } @@ -2935,7 +2947,8 @@ static void InterviewBefore_RecentHappenings(void) TryReplaceOldTVShowOfKind(TVSHOW_RECENT_HAPPENINGS); if (!gSpecialVar_Result) { - InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].recentHappenings.words, 6); + InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].recentHappenings.words, + ARRAY_COUNT(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].recentHappenings.words)); } } @@ -2947,7 +2960,8 @@ static void InterviewBefore_PkmnFanClubOpinions(void) StringCopy(gStringVar1, gSpeciesNames[GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPECIES, NULL)]); GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_NICKNAME, gStringVar2); StringGetEnd10(gStringVar2); - InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].fanclubOpinions.words, 2); + InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].fanclubOpinions.words, + ARRAY_COUNT(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].fanclubOpinions.words)); } } @@ -2965,7 +2979,8 @@ static void InterviewBefore_BravoTrainerPkmnProfile(void) { TryReplaceOldTVShowOfKind(TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE); if (!gSpecialVar_Result) - InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].bravoTrainer.words, 2); + InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].bravoTrainer.words, + ARRAY_COUNT(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].bravoTrainer.words)); } static void InterviewBefore_ContestLiveUpdates(void) @@ -2982,14 +2997,16 @@ static void InterviewBefore_BravoTrainerBTProfile(void) { TryReplaceOldTVShowOfKind(TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE); if (!gSpecialVar_Result) - InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].bravoTrainerTower.words, 1); + InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].bravoTrainerTower.words, + ARRAY_COUNT(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].bravoTrainerTower.words)); } static void InterviewBefore_FanClubSpecial(void) { TryReplaceOldTVShowOfKind(TVSHOW_FAN_CLUB_SPECIAL); if (!gSpecialVar_Result) - InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].fanClubSpecial.words, 1); + InitializeEasyChatWordArray(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].fanClubSpecial.words, + ARRAY_COUNT(gSaveBlock1Ptr->tvShows[sCurTVShowSlot].fanClubSpecial.words)); } static bool8 IsPartyMonNicknamedOrNotEnglish(u8 monIdx) @@ -3061,23 +3078,19 @@ static void CompactTVShowArray(TVShow *shows) } } -static u16 GetRandomDifferentSpeciesAndNameSeenByPlayer(u8 varIdx, u16 passedSpecies) +static u16 GetRandomDifferentSpeciesAndNameSeenByPlayer(u8 varIdx, u16 excludedSpecies) { - u16 species; - - species = GetRandomDifferentSpeciesSeenByPlayer(passedSpecies); + u16 species = GetRandomDifferentSpeciesSeenByPlayer(excludedSpecies); StringCopy(gTVStringVarPtrs[varIdx], gSpeciesNames[species]); return species; } -static u16 GetRandomDifferentSpeciesSeenByPlayer(u16 passedSpecies) +static u16 GetRandomDifferentSpeciesSeenByPlayer(u16 excludedSpecies) { - u16 species; - u16 initSpecies; + u16 species = Random() % (NUM_SPECIES - 1) + 1; + u16 initSpecies = species; - species = (Random() % (NUM_SPECIES - 1)) + 1; - initSpecies = species; - while (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_SEEN) != TRUE || species == passedSpecies) + while (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_SEEN) != TRUE || species == excludedSpecies) { if (species == SPECIES_NONE + 1) species = NUM_SPECIES - 1; @@ -3086,7 +3099,8 @@ static u16 GetRandomDifferentSpeciesSeenByPlayer(u16 passedSpecies) if (species == initSpecies) { - species = passedSpecies; + // Looped back to initial species (only Pokémon seen), must choose excluded species + species = excludedSpecies; return species; } }; @@ -3801,7 +3815,7 @@ void DeactivateAllNormalTVShows(void) } } -// Ensures a minimum of 5 empty mixed show slots +// Ensures a minimum of 5 empty record mixed show slots static void DeleteExcessMixedShows(void) { s8 i; @@ -3900,8 +3914,8 @@ static bool8 TryMixPokeNewsShow(PokeNews *dest, PokeNews *src, s8 slot) return FALSE; } dest[slot].kind = src->kind; - dest[slot].state = 1; - dest[slot].days = src->days; + dest[slot].state = POKENEWS_STATE_UPCOMING; + dest[slot].dayCountdown = src->dayCountdown; return TRUE; } @@ -3932,7 +3946,7 @@ static void ClearPokeNewsIfGameNotComplete(void) if (FlagGet(FLAG_SYS_GAME_CLEAR) != TRUE) { for (i = 0; i < POKE_NEWS_COUNT; i++) - gSaveBlock1Ptr->pokeNews[i].state = 0; + gSaveBlock1Ptr->pokeNews[i].state = POKENEWS_STATE_INACTIVE; } } @@ -5910,21 +5924,21 @@ static void DoTVShowSecretBaseVisit(void) { case 0: TVShowConvertInternationalString(gStringVar1, show->secretBaseVisit.playerName, show->secretBaseVisit.language); - if (show->secretBaseVisit.nDecorations == 0) + if (show->secretBaseVisit.numDecorations == 0) sTVShowState = 2; else sTVShowState = 1; break; case 1: StringCopy(gStringVar2, gDecorations[show->secretBaseVisit.decorations[0]].name); - if (show->secretBaseVisit.nDecorations == 1) + if (show->secretBaseVisit.numDecorations == 1) sTVShowState = 4; else sTVShowState = 3; break; case 3: StringCopy(gStringVar2, gDecorations[show->secretBaseVisit.decorations[1]].name); - switch (show->secretBaseVisit.nDecorations) + switch (show->secretBaseVisit.numDecorations) { case 2: sTVShowState = 7; @@ -5988,21 +6002,13 @@ static void DoTVShowPokemonLotteryWinnerFlashReport(void) state = sTVShowState; TVShowConvertInternationalString(gStringVar1, show->lottoWinner.playerName, show->lottoWinner.language); if (show->lottoWinner.whichPrize == 0) - { StringCopy(gStringVar2, gText_Jackpot); - } else if (show->lottoWinner.whichPrize == 1) - { StringCopy(gStringVar2, gText_First); - } else if (show->lottoWinner.whichPrize == 2) - { StringCopy(gStringVar2, gText_Second); - } else - { StringCopy(gStringVar2, gText_Third); - } StringCopy(gStringVar3, ItemId_GetName(show->lottoWinner.item)); TVShowDone(); ShowFieldMessage(sTVPokemonLotteryWinnerFlashReportTextGroup[state]); @@ -6715,23 +6721,23 @@ static void DoTVShowSafariFanClub(void) switch (state) { case 0: - if (show->safariFanClub.nMonsCaught == 0) + if (show->safariFanClub.monsCaught == 0) sTVShowState = 6; - else if (show->safariFanClub.nMonsCaught < 4) + else if (show->safariFanClub.monsCaught < 4) sTVShowState = 5; else sTVShowState = 1; break; case 1: TVShowConvertInternationalString(gStringVar1, show->safariFanClub.playerName, show->safariFanClub.language); - ConvertIntToDecimalString(1, show->safariFanClub.nMonsCaught); - if (show->safariFanClub.nPkblkUsed == 0) + ConvertIntToDecimalString(1, show->safariFanClub.monsCaught); + if (show->safariFanClub.pokeblocksUsed == 0) sTVShowState = 3; else sTVShowState = 2; break; case 2: - ConvertIntToDecimalString(1, show->safariFanClub.nPkblkUsed); + ConvertIntToDecimalString(1, show->safariFanClub.pokeblocksUsed); sTVShowState = 4; break; case 3: @@ -6743,21 +6749,21 @@ static void DoTVShowSafariFanClub(void) break; case 5: TVShowConvertInternationalString(gStringVar1, show->safariFanClub.playerName, show->safariFanClub.language); - ConvertIntToDecimalString(1, show->safariFanClub.nMonsCaught); - if (show->safariFanClub.nPkblkUsed == 0) + ConvertIntToDecimalString(1, show->safariFanClub.monsCaught); + if (show->safariFanClub.pokeblocksUsed == 0) sTVShowState = 8; else sTVShowState = 7; break; case 6: TVShowConvertInternationalString(gStringVar1, show->safariFanClub.playerName, show->safariFanClub.language); - if (show->safariFanClub.nPkblkUsed == 0) + if (show->safariFanClub.pokeblocksUsed == 0) sTVShowState = 8; else sTVShowState = 7; break; case 7: - ConvertIntToDecimalString(1, show->safariFanClub.nPkblkUsed); + ConvertIntToDecimalString(1, show->safariFanClub.pokeblocksUsed); sTVShowState = 9; break; case 8: