Some TV clean-up

This commit is contained in:
GriffinR 2021-11-16 16:13:52 -05:00
parent 5d9c31a610
commit d414787932
7 changed files with 198 additions and 179 deletions

View File

@ -19,6 +19,8 @@
.set LOCALID_GRUNT_11, 33 .set LOCALID_GRUNT_11, 33
.set LOCALID_SCOTT, 35 .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:: SlateportCity_MapScripts::
map_script MAP_SCRIPT_ON_TRANSITION, SlateportCity_OnTransition map_script MAP_SCRIPT_ON_TRANSITION, SlateportCity_OnTransition
map_script MAP_SCRIPT_ON_FRAME_TABLE, SlateportCity_OnFrame map_script MAP_SCRIPT_ON_FRAME_TABLE, SlateportCity_OnFrame

View File

@ -52,11 +52,13 @@ EventScript_PlayersHouseLatiNewsFlash::
releaseall releaseall
end 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:: EventScript_DoTVShow::
special DoTVShow special DoTVShow
waitmessage waitmessage
waitbuttonpress waitbuttonpress
compare VAR_RESULT, 1 compare VAR_RESULT, TRUE
goto_if_ne EventScript_DoTVShow goto_if_ne EventScript_DoTVShow
goto EventScript_TurnOffTV goto EventScript_TurnOffTV
end end

View File

@ -311,5 +311,6 @@
#define LOCALID_MOSSDEEP_MART_CLERK 1 #define LOCALID_MOSSDEEP_MART_CLERK 1
#define LOCALID_SOOTOPOLIS_MART_CLERK 1 #define LOCALID_SOOTOPOLIS_MART_CLERK 1
#define LOCALID_BATTLE_FRONTIER_MART_CLERK 1 #define LOCALID_BATTLE_FRONTIER_MART_CLERK 1
#define LOCALID_SLATEPORT_ENERGY_GURU 25
#endif // GUARD_CONSTANTS_EVENT_OBJECTS_H #endif // GUARD_CONSTANTS_EVENT_OBJECTS_H

View File

@ -8,6 +8,14 @@
#define POKENEWS_BLENDMASTER 4 #define POKENEWS_BLENDMASTER 4
#define NUM_POKENEWS_TYPES 4 // Excludes NONE #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 // TV shows are categorized as being in one of 3 groups
// - TVGROUP_NORMAL, TV shows that can appear without Record Mixing // - TVGROUP_NORMAL, TV shows that can appear without Record Mixing
// - TVGROUP_RECORD_MIX, TV shows that can only appear via Record Mixing // - TVGROUP_RECORD_MIX, TV shows that can only appear via Record Mixing

View File

@ -972,10 +972,10 @@ struct SaveBlock1
/*0x2B92*/ u8 outbreakLocationMapNum; /*0x2B92*/ u8 outbreakLocationMapNum;
/*0x2B93*/ u8 outbreakLocationMapGroup; /*0x2B93*/ u8 outbreakLocationMapGroup;
/*0x2B94*/ u8 outbreakPokemonLevel; /*0x2B94*/ u8 outbreakPokemonLevel;
/*0x2B95*/ u8 outbreakUnk1; /*0x2B95*/ u8 outbreakUnused1;
/*0x2B96*/ u16 outbreakUnk2; /*0x2B96*/ u16 outbreakUnused2;
/*0x2B98*/ u16 outbreakPokemonMoves[MAX_MON_MOVES]; /*0x2B98*/ u16 outbreakPokemonMoves[MAX_MON_MOVES];
/*0x2BA0*/ u8 outbreakUnk4; /*0x2BA0*/ u8 outbreakUnused3;
/*0x2BA1*/ u8 outbreakPokemonProbability; /*0x2BA1*/ u8 outbreakPokemonProbability;
/*0x2BA2*/ u16 outbreakDaysLeft; /*0x2BA2*/ u16 outbreakDaysLeft;
/*0x2BA4*/ struct GabbyAndTyData gabbyAndTyData; /*0x2BA4*/ struct GabbyAndTyData gabbyAndTyData;

View File

@ -61,7 +61,7 @@ typedef union // size = 0x24
/*0x0F*/ u8 filler_0F[1]; /*0x0F*/ u8 filler_0F[1];
/*0x10*/ u8 nickname[PLAYER_NAME_LENGTH + 1]; /*0x10*/ u8 nickname[PLAYER_NAME_LENGTH + 1];
/*0x18*/ u16 words18[2]; /*0x18*/ u16 words18[2];
/*0x1C*/ u16 words[4]; /*0x1C*/ u16 words[2];
} fanclubOpinions; } fanclubOpinions;
// TVSHOW_DUMMY // TVSHOW_DUMMY
@ -334,7 +334,7 @@ typedef union // size = 0x24
/*0x00*/ u8 kind; /*0x00*/ u8 kind;
/*0x01*/ bool8 active; /*0x01*/ bool8 active;
/*0x02*/ u8 avgLevel; /*0x02*/ u8 avgLevel;
/*0x03*/ u8 nDecorations; /*0x03*/ u8 numDecorations;
/*0x04*/ u8 decorations[4]; /*0x04*/ u8 decorations[4];
/*0x08*/ u16 species; /*0x08*/ u16 species;
/*0x0a*/ u16 move; /*0x0a*/ u16 move;
@ -437,8 +437,8 @@ typedef union // size = 0x24
struct { struct {
/*0x00*/ u8 kind; /*0x00*/ u8 kind;
/*0x01*/ bool8 active; /*0x01*/ bool8 active;
/*0x02*/ u8 nMonsCaught; /*0x02*/ u8 monsCaught;
/*0x03*/ u8 nPkblkUsed; /*0x03*/ u8 pokeblocksUsed;
/*0x04*/ u8 language; /*0x04*/ u8 language;
/*0x05*/ u8 filler_05[14]; /*0x05*/ u8 filler_05[14];
/*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1]; /*0x13*/ u8 playerName[PLAYER_NAME_LENGTH + 1];
@ -449,27 +449,27 @@ typedef union // size = 0x24
struct { struct {
/*0x00*/ u8 kind; /*0x00*/ u8 kind;
/*0x01*/ bool8 active; /*0x01*/ bool8 active;
/*0x02*/ u8 var02; /*0x02*/ u8 unused1;
/*0x03*/ u8 var03; /*0x03*/ u8 unused3;
/*0x04*/ u16 moves[MAX_MON_MOVES]; /*0x04*/ u16 moves[MAX_MON_MOVES];
/*0x0C*/ u16 species; /*0x0C*/ u16 species;
/*0x0E*/ u16 var0E; /*0x0E*/ u16 unused2;
/*0x10*/ u8 locationMapNum; /*0x10*/ u8 locationMapNum;
/*0x11*/ u8 locationMapGroup; /*0x11*/ u8 locationMapGroup;
/*0x12*/ u8 var12; /*0x12*/ u8 unused4;
/*0x13*/ u8 probability; /*0x13*/ u8 probability;
/*0x14*/ u8 level; /*0x14*/ u8 level;
/*0x15*/ u8 var15; /*0x15*/ u8 unused5;
/*0x16*/ u16 daysLeft; /*0x16*/ u16 daysLeft;
/*0x18*/ u8 language; /*0x18*/ u8 language;
} massOutbreak; } massOutbreak;
} TVShow; } TVShow;
typedef struct // 2b50 typedef struct
{ {
u8 kind; u8 kind;
u8 state; u8 state;
u16 days; u16 dayCountdown;
} PokeNews; } PokeNews;
struct GabbyAndTyData struct GabbyAndTyData

334
src/tv.c
View File

@ -36,6 +36,7 @@
#include "data.h" #include "data.h"
#include "constants/battle_frontier.h" #include "constants/battle_frontier.h"
#include "constants/contest.h" #include "constants/contest.h"
#include "constants/decorations.h"
#include "constants/event_objects.h" #include "constants/event_objects.h"
#include "constants/items.h" #include "constants/items.h"
#include "constants/layouts.h" #include "constants/layouts.h"
@ -139,7 +140,7 @@ static void TryPutRandomPokeNewsOnAir(void);
static void SortPurchasesByQuantity(void); static void SortPurchasesByQuantity(void);
static void UpdateMassOutbreakTimeLeft(u16); static void UpdateMassOutbreakTimeLeft(u16);
static void TryEndMassOutbreak(u16); static void TryEndMassOutbreak(u16);
static void UpdatePokeNewsTimeLeft(u16); static void UpdatePokeNewsCountdown(u16);
static void ResolveWorldOfMastersShow(u16); static void ResolveWorldOfMastersShow(u16);
static void ResolveNumberOneShow(u16); static void ResolveNumberOneShow(u16);
static void TryPutFishingAdviceOnAir(void); static void TryPutFishingAdviceOnAir(void);
@ -227,24 +228,24 @@ static const struct {
} }
}; };
static const u16 sGoldSymbolFlags[] = { static const u16 sGoldSymbolFlags[NUM_FRONTIER_FACILITIES] = {
FLAG_SYS_TOWER_GOLD, [FRONTIER_FACILITY_TOWER] = FLAG_SYS_TOWER_GOLD,
FLAG_SYS_DOME_GOLD, [FRONTIER_FACILITY_DOME] = FLAG_SYS_DOME_GOLD,
FLAG_SYS_PALACE_GOLD, [FRONTIER_FACILITY_PALACE] = FLAG_SYS_PALACE_GOLD,
FLAG_SYS_ARENA_GOLD, [FRONTIER_FACILITY_ARENA] = FLAG_SYS_ARENA_GOLD,
FLAG_SYS_FACTORY_GOLD, [FRONTIER_FACILITY_FACTORY] = FLAG_SYS_FACTORY_GOLD,
FLAG_SYS_PIKE_GOLD, [FRONTIER_FACILITY_PIKE] = FLAG_SYS_PIKE_GOLD,
FLAG_SYS_PYRAMID_GOLD [FRONTIER_FACILITY_PYRAMID] = FLAG_SYS_PYRAMID_GOLD
}; };
static const u16 sSilverSymbolFlags[] = { static const u16 sSilverSymbolFlags[NUM_FRONTIER_FACILITIES] = {
FLAG_SYS_TOWER_SILVER, [FRONTIER_FACILITY_TOWER] = FLAG_SYS_TOWER_SILVER,
FLAG_SYS_DOME_SILVER, [FRONTIER_FACILITY_DOME] = FLAG_SYS_DOME_SILVER,
FLAG_SYS_PALACE_SILVER, [FRONTIER_FACILITY_PALACE] = FLAG_SYS_PALACE_SILVER,
FLAG_SYS_ARENA_SILVER, [FRONTIER_FACILITY_ARENA] = FLAG_SYS_ARENA_SILVER,
FLAG_SYS_FACTORY_SILVER, [FRONTIER_FACILITY_FACTORY] = FLAG_SYS_FACTORY_SILVER,
FLAG_SYS_PIKE_SILVER, [FRONTIER_FACILITY_PIKE] = FLAG_SYS_PIKE_SILVER,
FLAG_SYS_PYRAMID_SILVER [FRONTIER_FACILITY_PYRAMID] = FLAG_SYS_PYRAMID_SILVER
}; };
static const u16 sNumberOneVarsAndThresholds[][2] = { static const u16 sNumberOneVarsAndThresholds[][2] = {
@ -257,28 +258,28 @@ static const u16 sNumberOneVarsAndThresholds[][2] = {
{VAR_DAILY_BP, 30} {VAR_DAILY_BP, 30}
}; };
static const u8 *const sPokeNewsTextGroup_Upcoming[] = { static const u8 *const sPokeNewsTextGroup_Upcoming[NUM_POKENEWS_TYPES + 1] = {
NULL, [POKENEWS_NONE] = NULL,
gPokeNewsTextSlateport_Upcoming, [POKENEWS_SLATEPORT] = gPokeNewsTextSlateport_Upcoming,
gPokeNewsTextGameCorner_Upcoming, [POKENEWS_GAME_CORNER] = gPokeNewsTextGameCorner_Upcoming,
gPokeNewsTextLilycove_Upcoming, [POKENEWS_LILYCOVE] = gPokeNewsTextLilycove_Upcoming,
gPokeNewsTextBlendMaster_Upcoming [POKENEWS_BLENDMASTER] = gPokeNewsTextBlendMaster_Upcoming
}; };
static const u8 *const sPokeNewsTextGroup_Ongoing[] = { static const u8 *const sPokeNewsTextGroup_Ongoing[NUM_POKENEWS_TYPES + 1] = {
NULL, [POKENEWS_NONE] = NULL,
gPokeNewsTextSlateport_Ongoing, [POKENEWS_SLATEPORT] = gPokeNewsTextSlateport_Ongoing,
gPokeNewsTextGameCorner_Ongoing, [POKENEWS_GAME_CORNER] = gPokeNewsTextGameCorner_Ongoing,
gPokeNewsTextLilycove_Ongoing, [POKENEWS_LILYCOVE] = gPokeNewsTextLilycove_Ongoing,
gPokeNewsTextBlendMaster_Ongoing [POKENEWS_BLENDMASTER] = gPokeNewsTextBlendMaster_Ongoing
}; };
static const u8 *const sPokeNewsTextGroup_Ending[] = { static const u8 *const sPokeNewsTextGroup_Ending[NUM_POKENEWS_TYPES + 1] = {
NULL, [POKENEWS_NONE] = NULL,
gPokeNewsTextSlateport_Ending, [POKENEWS_SLATEPORT] = gPokeNewsTextSlateport_Ending,
gPokeNewsTextGameCorner_Ending, [POKENEWS_GAME_CORNER] = gPokeNewsTextGameCorner_Ending,
gPokeNewsTextLilycove_Ending, [POKENEWS_LILYCOVE] = gPokeNewsTextLilycove_Ending,
gPokeNewsTextBlendMaster_Ending [POKENEWS_BLENDMASTER] = gPokeNewsTextBlendMaster_Ending
}; };
u8 *const gTVStringVarPtrs[] = { u8 *const gTVStringVarPtrs[] = {
@ -1568,13 +1569,13 @@ void StartMassOutbreak(void)
gSaveBlock1Ptr->outbreakLocationMapNum = show->massOutbreak.locationMapNum; gSaveBlock1Ptr->outbreakLocationMapNum = show->massOutbreak.locationMapNum;
gSaveBlock1Ptr->outbreakLocationMapGroup = show->massOutbreak.locationMapGroup; gSaveBlock1Ptr->outbreakLocationMapGroup = show->massOutbreak.locationMapGroup;
gSaveBlock1Ptr->outbreakPokemonLevel = show->massOutbreak.level; gSaveBlock1Ptr->outbreakPokemonLevel = show->massOutbreak.level;
gSaveBlock1Ptr->outbreakUnk1 = show->massOutbreak.var02; gSaveBlock1Ptr->outbreakUnused1 = show->massOutbreak.unused1;
gSaveBlock1Ptr->outbreakUnk2 = show->massOutbreak.var0E; gSaveBlock1Ptr->outbreakUnused2 = show->massOutbreak.unused2;
gSaveBlock1Ptr->outbreakPokemonMoves[0] = show->massOutbreak.moves[0]; gSaveBlock1Ptr->outbreakPokemonMoves[0] = show->massOutbreak.moves[0];
gSaveBlock1Ptr->outbreakPokemonMoves[1] = show->massOutbreak.moves[1]; gSaveBlock1Ptr->outbreakPokemonMoves[1] = show->massOutbreak.moves[1];
gSaveBlock1Ptr->outbreakPokemonMoves[2] = show->massOutbreak.moves[2]; gSaveBlock1Ptr->outbreakPokemonMoves[2] = show->massOutbreak.moves[2];
gSaveBlock1Ptr->outbreakPokemonMoves[3] = show->massOutbreak.moves[3]; gSaveBlock1Ptr->outbreakPokemonMoves[3] = show->massOutbreak.moves[3];
gSaveBlock1Ptr->outbreakUnk4 = show->massOutbreak.var03; gSaveBlock1Ptr->outbreakUnused3 = show->massOutbreak.unused3;
gSaveBlock1Ptr->outbreakPokemonProbability = show->massOutbreak.probability; gSaveBlock1Ptr->outbreakPokemonProbability = show->massOutbreak.probability;
gSaveBlock1Ptr->outbreakDaysLeft = 2; gSaveBlock1Ptr->outbreakDaysLeft = 2;
} }
@ -1667,19 +1668,19 @@ static void TryStartRandomMassOutbreak(void)
show->massOutbreak.kind = TVSHOW_MASS_OUTBREAK; show->massOutbreak.kind = TVSHOW_MASS_OUTBREAK;
show->massOutbreak.active = TRUE; show->massOutbreak.active = TRUE;
show->massOutbreak.level = sPokeOutbreakSpeciesList[outbreakIdx].level; show->massOutbreak.level = sPokeOutbreakSpeciesList[outbreakIdx].level;
show->massOutbreak.var02 = 0; show->massOutbreak.unused1 = 0;
show->massOutbreak.var03 = 0; show->massOutbreak.unused3 = 0;
show->massOutbreak.species = sPokeOutbreakSpeciesList[outbreakIdx].species; 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[0] = sPokeOutbreakSpeciesList[outbreakIdx].moves[0];
show->massOutbreak.moves[1] = sPokeOutbreakSpeciesList[outbreakIdx].moves[1]; show->massOutbreak.moves[1] = sPokeOutbreakSpeciesList[outbreakIdx].moves[1];
show->massOutbreak.moves[2] = sPokeOutbreakSpeciesList[outbreakIdx].moves[2]; show->massOutbreak.moves[2] = sPokeOutbreakSpeciesList[outbreakIdx].moves[2];
show->massOutbreak.moves[3] = sPokeOutbreakSpeciesList[outbreakIdx].moves[3]; show->massOutbreak.moves[3] = sPokeOutbreakSpeciesList[outbreakIdx].moves[3];
show->massOutbreak.locationMapNum = sPokeOutbreakSpeciesList[outbreakIdx].location; show->massOutbreak.locationMapNum = sPokeOutbreakSpeciesList[outbreakIdx].location;
show->massOutbreak.locationMapGroup = 0; show->massOutbreak.locationMapGroup = 0;
show->massOutbreak.var12 = 0; show->massOutbreak.unused4 = 0;
show->massOutbreak.probability = 50; show->massOutbreak.probability = 50;
show->massOutbreak.var15 = 0; show->massOutbreak.unused5 = 0;
show->massOutbreak.daysLeft = 1; show->massOutbreak.daysLeft = 1;
StorePlayerIdInNormalShow(show); StorePlayerIdInNormalShow(show);
show->massOutbreak.language = gGameLanguage; show->massOutbreak.language = gGameLanguage;
@ -1694,13 +1695,13 @@ void EndMassOutbreak(void)
gSaveBlock1Ptr->outbreakLocationMapNum = 0; gSaveBlock1Ptr->outbreakLocationMapNum = 0;
gSaveBlock1Ptr->outbreakLocationMapGroup = 0; gSaveBlock1Ptr->outbreakLocationMapGroup = 0;
gSaveBlock1Ptr->outbreakPokemonLevel = 0; gSaveBlock1Ptr->outbreakPokemonLevel = 0;
gSaveBlock1Ptr->outbreakUnk1 = 0; gSaveBlock1Ptr->outbreakUnused1 = 0;
gSaveBlock1Ptr->outbreakUnk2 = 0; gSaveBlock1Ptr->outbreakUnused2 = 0;
gSaveBlock1Ptr->outbreakPokemonMoves[0] = MOVE_NONE; gSaveBlock1Ptr->outbreakPokemonMoves[0] = MOVE_NONE;
gSaveBlock1Ptr->outbreakPokemonMoves[1] = MOVE_NONE; gSaveBlock1Ptr->outbreakPokemonMoves[1] = MOVE_NONE;
gSaveBlock1Ptr->outbreakPokemonMoves[2] = MOVE_NONE; gSaveBlock1Ptr->outbreakPokemonMoves[2] = MOVE_NONE;
gSaveBlock1Ptr->outbreakPokemonMoves[3] = MOVE_NONE; gSaveBlock1Ptr->outbreakPokemonMoves[3] = MOVE_NONE;
gSaveBlock1Ptr->outbreakUnk4 = 0; gSaveBlock1Ptr->outbreakUnused3 = 0;
gSaveBlock1Ptr->outbreakPokemonProbability = 0; gSaveBlock1Ptr->outbreakPokemonProbability = 0;
gSaveBlock1Ptr->outbreakDaysLeft = 0; gSaveBlock1Ptr->outbreakDaysLeft = 0;
} }
@ -1709,7 +1710,7 @@ void UpdateTVShowsPerDay(u16 days)
{ {
UpdateMassOutbreakTimeLeft(days); UpdateMassOutbreakTimeLeft(days);
TryEndMassOutbreak(days); TryEndMassOutbreak(days);
UpdatePokeNewsTimeLeft(days); UpdatePokeNewsCountdown(days);
ResolveWorldOfMastersShow(days); ResolveWorldOfMastersShow(days);
ResolveNumberOneShow(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. // Either way the temporary version of the show in the last slot is deleted.
static void ResolveWorldOfMastersShow(u16 days) static void ResolveWorldOfMastersShow(u16 days)
{ {
TVShow *show; TVShow *show = &gSaveBlock1Ptr->tvShows[LAST_TVSHOW_IDX];
show = &gSaveBlock1Ptr->tvShows[LAST_TVSHOW_IDX];
if (show->worldOfMasters.kind == TVSHOW_WORLD_OF_MASTERS) if (show->worldOfMasters.kind == TVSHOW_WORLD_OF_MASTERS)
{ {
if (show->worldOfMasters.numPokeCaught >= 20) if (show->worldOfMasters.numPokeCaught >= 20)
@ -1863,7 +1862,7 @@ void TryPutTodaysRivalTrainerOnAir(void)
show->rivalTrainer.mapLayoutId = gMapHeader.mapLayoutId; show->rivalTrainer.mapLayoutId = gMapHeader.mapLayoutId;
show->rivalTrainer.nSilverSymbols = 0; show->rivalTrainer.nSilverSymbols = 0;
show->rivalTrainer.nGoldSymbols = 0; show->rivalTrainer.nGoldSymbols = 0;
for (i = 0; i < 7; i++) for (i = 0; i < NUM_FRONTIER_FACILITIES; i++)
{ {
if (FlagGet(sSilverSymbolFlags[i]) == TRUE) if (FlagGet(sSilverSymbolFlags[i]) == TRUE)
show->rivalTrainer.nSilverSymbols++; show->rivalTrainer.nSilverSymbols++;
@ -1989,33 +1988,39 @@ static void SecretBaseVisit_CalculateDecorationData(TVShow *show)
u8 decoration; u8 decoration;
for (i = 0; i < DECOR_MAX_SECRET_BASE; i++) 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++) for (i = 0, n = 0; i < DECOR_MAX_SECRET_BASE; i++)
{ {
decoration = gSaveBlock1Ptr->secretBases[0].decorations[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++) 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; sTV_DecorationsBuffer[j] = decoration;
n++; n++;
break; break;
} }
// Decoration has already been saved, skip and move on to the next base decoration
if (sTV_DecorationsBuffer[j] == decoration) if (sTV_DecorationsBuffer[j] == decoration)
break; break;
} }
} }
} }
if (n > 4) // Cap the number of unique decorations to the number the TV show will talk about
show->secretBaseVisit.nDecorations = 4; if (n > ARRAY_COUNT(show->secretBaseVisit.decorations))
show->secretBaseVisit.numDecorations = ARRAY_COUNT(show->secretBaseVisit.decorations);
else else
show->secretBaseVisit.nDecorations = n; show->secretBaseVisit.numDecorations = n;
switch (show->secretBaseVisit.nDecorations) switch (show->secretBaseVisit.numDecorations)
{ {
case 0: case 0:
break; break;
@ -2023,16 +2028,16 @@ static void SecretBaseVisit_CalculateDecorationData(TVShow *show)
show->secretBaseVisit.decorations[0] = sTV_DecorationsBuffer[0]; show->secretBaseVisit.decorations[0] = sTV_DecorationsBuffer[0];
break; break;
default: default:
// More than 1 decoration, randomize the full list
for (k = 0; k < n * n; k++) for (k = 0; k < n * n; k++)
{ {
decoration = Random() % n; decoration = Random() % n;
j = Random() % n; j = Random() % n;
i = sTV_DecorationsBuffer[decoration]; SWAP(sTV_DecorationsBuffer[decoration], sTV_DecorationsBuffer[j], i);
sTV_DecorationsBuffer[decoration] = sTV_DecorationsBuffer[j];
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]; show->secretBaseVisit.decorations[i] = sTV_DecorationsBuffer[i];
break; break;
} }
@ -2043,50 +2048,55 @@ static void SecretBaseVisit_CalculatePartyData(TVShow *show)
u8 i; u8 i;
u16 move; u16 move;
u16 j; u16 j;
u8 nMoves; u8 numMoves;
u8 nPokemon; u8 numPokemon;
u16 sum; 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)) 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[numPokemon].level = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL);
sTV_SecretBaseVisitMonsTemp[nPokemon].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES); sTV_SecretBaseVisitMonsTemp[numPokemon].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES);
nMoves = 0;
// Check all the Pokémon's moves, then randomly select one to save
numMoves = 0;
move = GetMonData(&gPlayerParty[i], MON_DATA_MOVE1); move = GetMonData(&gPlayerParty[i], MON_DATA_MOVE1);
if (move != MOVE_NONE) if (move != MOVE_NONE)
{ {
sTV_SecretBaseVisitMovesTemp[nMoves] = move; sTV_SecretBaseVisitMovesTemp[numMoves] = move;
nMoves++; numMoves++;
} }
move = GetMonData(&gPlayerParty[i], MON_DATA_MOVE2); move = GetMonData(&gPlayerParty[i], MON_DATA_MOVE2);
if (move != MOVE_NONE) if (move != MOVE_NONE)
{ {
sTV_SecretBaseVisitMovesTemp[nMoves] = move; sTV_SecretBaseVisitMovesTemp[numMoves] = move;
nMoves++; numMoves++;
} }
move = GetMonData(&gPlayerParty[i], MON_DATA_MOVE3); move = GetMonData(&gPlayerParty[i], MON_DATA_MOVE3);
if (move != MOVE_NONE) if (move != MOVE_NONE)
{ {
sTV_SecretBaseVisitMovesTemp[nMoves] = move; sTV_SecretBaseVisitMovesTemp[numMoves] = move;
nMoves++; numMoves++;
} }
move = GetMonData(&gPlayerParty[i], MON_DATA_MOVE4); move = GetMonData(&gPlayerParty[i], MON_DATA_MOVE4);
if (move != MOVE_NONE) if (move != MOVE_NONE)
{ {
sTV_SecretBaseVisitMovesTemp[nMoves] = move; sTV_SecretBaseVisitMovesTemp[numMoves] = move;
nMoves++; numMoves++;
} }
sTV_SecretBaseVisitMonsTemp[nPokemon].move = sTV_SecretBaseVisitMovesTemp[Random() % nMoves]; sTV_SecretBaseVisitMonsTemp[numPokemon].move = sTV_SecretBaseVisitMovesTemp[Random() % numMoves];
nPokemon++; numPokemon++;
} }
} }
for (i = 0, sum = 0; i < nPokemon; i++)
for (i = 0, sum = 0; i < numPokemon; i++)
sum += sTV_SecretBaseVisitMonsTemp[i].level; sum += sTV_SecretBaseVisitMonsTemp[i].level;
show->secretBaseVisit.avgLevel = sum / nPokemon; // Using the data calculated above, save the data to talk about on the show
j = Random() % nPokemon; // (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.species = sTV_SecretBaseVisitMonsTemp[j].species;
show->secretBaseVisit.move = sTV_SecretBaseVisitMonsTemp[j].move; 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; TVShow *show;
@ -2235,8 +2245,8 @@ void TryPutSafariFanClubOnAir(u8 nMonsCaught, u8 nPkblkUsed)
show->safariFanClub.kind = TVSHOW_SAFARI_FAN_CLUB; show->safariFanClub.kind = TVSHOW_SAFARI_FAN_CLUB;
show->safariFanClub.active = FALSE; // NOTE: Show is not active until passed via Record Mix. show->safariFanClub.active = FALSE; // NOTE: Show is not active until passed via Record Mix.
StringCopy(show->safariFanClub.playerName, gSaveBlock2Ptr->playerName); StringCopy(show->safariFanClub.playerName, gSaveBlock2Ptr->playerName);
show->safariFanClub.nMonsCaught = nMonsCaught; show->safariFanClub.monsCaught = monsCaught;
show->safariFanClub.nPkblkUsed = nPkblkUsed; show->safariFanClub.pokeblocksUsed = pokeblocksUsed;
StorePlayerIdInRecordMixShow(show); StorePlayerIdInRecordMixShow(show);
show->safariFanClub.language = gGameLanguage; show->safariFanClub.language = gGameLanguage;
} }
@ -2536,12 +2546,12 @@ static void TryPutRandomPokeNewsOnAir(void)
sCurTVShowSlot = GetFirstEmptyPokeNewsSlot(gSaveBlock1Ptr->pokeNews); sCurTVShowSlot = GetFirstEmptyPokeNewsSlot(gSaveBlock1Ptr->pokeNews);
if (sCurTVShowSlot != -1 && rbernoulli(1, 100) != TRUE) 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) if (IsAddingPokeNewsDisallowed(newsKind) != TRUE)
{ {
gSaveBlock1Ptr->pokeNews[sCurTVShowSlot].kind = newsKind; gSaveBlock1Ptr->pokeNews[sCurTVShowSlot].kind = newsKind;
gSaveBlock1Ptr->pokeNews[sCurTVShowSlot].days = 4; gSaveBlock1Ptr->pokeNews[sCurTVShowSlot].dayCountdown = POKENEWS_COUNTDOWN;
gSaveBlock1Ptr->pokeNews[sCurTVShowSlot].state = 1; gSaveBlock1Ptr->pokeNews[sCurTVShowSlot].state = POKENEWS_STATE_UPCOMING;
} }
} }
} }
@ -2570,8 +2580,8 @@ static void ClearPokeNews(void)
static void ClearPokeNewsBySlot(u8 i) static void ClearPokeNewsBySlot(u8 i)
{ {
gSaveBlock1Ptr->pokeNews[i].kind = POKENEWS_NONE; gSaveBlock1Ptr->pokeNews[i].kind = POKENEWS_NONE;
gSaveBlock1Ptr->pokeNews[i].state = FALSE; gSaveBlock1Ptr->pokeNews[i].state = POKENEWS_STATE_INACTIVE;
gSaveBlock1Ptr->pokeNews[i].days = 0; gSaveBlock1Ptr->pokeNews[i].dayCountdown = 0;
} }
static void CompactPokeNews(void) static void CompactPokeNews(void)
@ -2603,8 +2613,8 @@ static u8 FindAnyPokeNewsOnTheAir(void)
for (i = 0; i < POKE_NEWS_COUNT; i++) for (i = 0; i < POKE_NEWS_COUNT; i++)
{ {
if (gSaveBlock1Ptr->pokeNews[i].kind != POKENEWS_NONE if (gSaveBlock1Ptr->pokeNews[i].kind != POKENEWS_NONE
&& gSaveBlock1Ptr->pokeNews[i].state == 1 && gSaveBlock1Ptr->pokeNews[i].state == POKENEWS_STATE_UPCOMING
&& gSaveBlock1Ptr->pokeNews[i].days < 3) && gSaveBlock1Ptr->pokeNews[i].dayCountdown < POKENEWS_COUNTDOWN - 1)
return i; return i;
} }
return 0xFF; return 0xFF;
@ -2612,19 +2622,17 @@ static u8 FindAnyPokeNewsOnTheAir(void)
void DoPokeNews(void) void DoPokeNews(void)
{ {
u8 i; u8 i = FindAnyPokeNewsOnTheAir();
u16 n;
i = FindAnyPokeNewsOnTheAir();
if (i == 0xFF) if (i == 0xFF)
{ {
gSpecialVar_Result = FALSE; gSpecialVar_Result = FALSE;
} }
else 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) if (gLocalTime.hours < 20)
ShowFieldMessage(sPokeNewsTextGroup_Ongoing[gSaveBlock1Ptr->pokeNews[i].kind]); ShowFieldMessage(sPokeNewsTextGroup_Ongoing[gSaveBlock1Ptr->pokeNews[i].kind]);
else else
@ -2632,9 +2640,13 @@ void DoPokeNews(void)
} }
else else
{ {
n = gSaveBlock1Ptr->pokeNews[i].days; // News event is upcoming, make comment about countdown to event
ConvertIntToDecimalStringN(gStringVar1, n, STR_CONV_MODE_LEFT_ALIGN, 1); u16 dayCountdown = gSaveBlock1Ptr->pokeNews[i].dayCountdown;
gSaveBlock1Ptr->pokeNews[i].state = 0; 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]); ShowFieldMessage(sPokeNewsTextGroup_Upcoming[gSaveBlock1Ptr->pokeNews[i].kind]);
} }
gSpecialVar_Result = TRUE; gSpecialVar_Result = TRUE;
@ -2652,7 +2664,7 @@ bool8 IsPokeNewsActive(u8 newsKind)
{ {
if (gSaveBlock1Ptr->pokeNews[i].kind == 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 TRUE;
return FALSE; return FALSE;
@ -2662,19 +2674,22 @@ bool8 IsPokeNewsActive(u8 newsKind)
} }
// Returns TRUE if the effects of the given PokeNews should be applied. // Returns TRUE if the effects of the given PokeNews should be applied.
// For POKENEWS_SLATEPORT / POKENEWS_LILYCOVE, only apply the effect (price reduction) // For POKENEWS_SLATEPORT / POKENEWS_LILYCOVE, only apply the effect if
// if the player is talking to the Energy Guru / at the Dept Store Rooftop. // the player is talking to the Energy Guru / at the Dept Store Rooftop.
// For any other type of PokeNews this is always TRUE. // For any other type of PokeNews this is always TRUE.
static bool8 ShouldApplyPokeNewsEffect(u8 newsKind) static bool8 ShouldApplyPokeNewsEffect(u8 newsKind)
{ {
switch (newsKind) switch (newsKind)
{ {
case POKENEWS_SLATEPORT: 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 TRUE;
return FALSE; return FALSE;
case POKENEWS_LILYCOVE: 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 TRUE;
return FALSE; return FALSE;
} }
@ -2696,7 +2711,7 @@ static bool8 IsAddingPokeNewsDisallowed(u8 newsKind)
return FALSE; return FALSE;
} }
static void UpdatePokeNewsTimeLeft(u16 days) static void UpdatePokeNewsCountdown(u16 days)
{ {
u8 i; u8 i;
@ -2704,16 +2719,18 @@ static void UpdatePokeNewsTimeLeft(u16 days)
{ {
if (gSaveBlock1Ptr->pokeNews[i].kind != POKENEWS_NONE) 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); ClearPokeNewsBySlot(i);
} }
else else
{ {
if (gSaveBlock1Ptr->pokeNews[i].state == 0 && FlagGet(FLAG_SYS_GAME_CLEAR) == TRUE) // Progress countdown to news event
gSaveBlock1Ptr->pokeNews[i].state = 1; 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) void SetContestCategoryStringVarForInterview(void)
{ {
TVShow *show; TVShow *show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
show = &gSaveBlock1Ptr->tvShows[gSpecialVar_0x8004];
CopyContestCategoryToStringVar(1, show->bravoTrainer.contestCategory); CopyContestCategoryToStringVar(1, show->bravoTrainer.contestCategory);
} }
@ -2792,9 +2807,7 @@ size_t CountDigits(int value)
static void SmartShopper_BufferPurchaseTotal(u8 varIdx, TVShow *show) static void SmartShopper_BufferPurchaseTotal(u8 varIdx, TVShow *show)
{ {
u8 i; u8 i;
int price; int price = 0;
price = 0;
for (i = 0; i < SMARTSHOPPER_NUM_ITEMS; i++) for (i = 0; i < SMARTSHOPPER_NUM_ITEMS; i++)
{ {
if (show->smartshopperShow.itemIds[i] != ITEM_NONE) if (show->smartshopperShow.itemIds[i] != ITEM_NONE)
@ -2835,21 +2848,19 @@ static bool8 IsRecordMixShowAlreadySpawned(u8 kind, bool8 delete)
static void SortPurchasesByQuantity(void) static void SortPurchasesByQuantity(void)
{ {
u8 i, j; u8 i, j;
u16 tmpId;
u16 tmpQn;
for (i = 0; i < SMARTSHOPPER_NUM_ITEMS - 1; i++) for (i = 0; i < SMARTSHOPPER_NUM_ITEMS - 1; i++)
{ {
for (j = i + 1; j < SMARTSHOPPER_NUM_ITEMS; j++) for (j = i + 1; j < SMARTSHOPPER_NUM_ITEMS; j++)
{ {
if (gMartPurchaseHistory[i].quantity < gMartPurchaseHistory[j].quantity) if (gMartPurchaseHistory[i].quantity < gMartPurchaseHistory[j].quantity)
{ {
tmpId = gMartPurchaseHistory[i].itemId; u16 tempItemId = gMartPurchaseHistory[i].itemId;
tmpQn = gMartPurchaseHistory[i].quantity; u16 tempQuantity = gMartPurchaseHistory[i].quantity;
gMartPurchaseHistory[i].itemId = gMartPurchaseHistory[j].itemId; gMartPurchaseHistory[i].itemId = gMartPurchaseHistory[j].itemId;
gMartPurchaseHistory[i].quantity = gMartPurchaseHistory[j].quantity; gMartPurchaseHistory[i].quantity = gMartPurchaseHistory[j].quantity;
gMartPurchaseHistory[j].itemId = tmpId; gMartPurchaseHistory[j].itemId = tempItemId;
gMartPurchaseHistory[j].quantity = tmpQn; gMartPurchaseHistory[j].quantity = tempQuantity;
} }
} }
} }
@ -2926,7 +2937,8 @@ static void InterviewBefore_FanClubLetter(void)
if (!gSpecialVar_Result) if (!gSpecialVar_Result)
{ {
StringCopy(gStringVar1, gSpeciesNames[GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPECIES, NULL)]); 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); TryReplaceOldTVShowOfKind(TVSHOW_RECENT_HAPPENINGS);
if (!gSpecialVar_Result) 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)]); StringCopy(gStringVar1, gSpeciesNames[GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_SPECIES, NULL)]);
GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_NICKNAME, gStringVar2); GetMonData(&gPlayerParty[GetLeadMonIndex()], MON_DATA_NICKNAME, gStringVar2);
StringGetEnd10(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); TryReplaceOldTVShowOfKind(TVSHOW_BRAVO_TRAINER_POKEMON_PROFILE);
if (!gSpecialVar_Result) 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) static void InterviewBefore_ContestLiveUpdates(void)
@ -2982,14 +2997,16 @@ static void InterviewBefore_BravoTrainerBTProfile(void)
{ {
TryReplaceOldTVShowOfKind(TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE); TryReplaceOldTVShowOfKind(TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE);
if (!gSpecialVar_Result) 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) static void InterviewBefore_FanClubSpecial(void)
{ {
TryReplaceOldTVShowOfKind(TVSHOW_FAN_CLUB_SPECIAL); TryReplaceOldTVShowOfKind(TVSHOW_FAN_CLUB_SPECIAL);
if (!gSpecialVar_Result) 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) 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; u16 species = GetRandomDifferentSpeciesSeenByPlayer(excludedSpecies);
species = GetRandomDifferentSpeciesSeenByPlayer(passedSpecies);
StringCopy(gTVStringVarPtrs[varIdx], gSpeciesNames[species]); StringCopy(gTVStringVarPtrs[varIdx], gSpeciesNames[species]);
return species; return species;
} }
static u16 GetRandomDifferentSpeciesSeenByPlayer(u16 passedSpecies) static u16 GetRandomDifferentSpeciesSeenByPlayer(u16 excludedSpecies)
{ {
u16 species; u16 species = Random() % (NUM_SPECIES - 1) + 1;
u16 initSpecies; u16 initSpecies = species;
species = (Random() % (NUM_SPECIES - 1)) + 1; while (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_SEEN) != TRUE || species == excludedSpecies)
initSpecies = species;
while (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_SEEN) != TRUE || species == passedSpecies)
{ {
if (species == SPECIES_NONE + 1) if (species == SPECIES_NONE + 1)
species = NUM_SPECIES - 1; species = NUM_SPECIES - 1;
@ -3086,7 +3099,8 @@ static u16 GetRandomDifferentSpeciesSeenByPlayer(u16 passedSpecies)
if (species == initSpecies) if (species == initSpecies)
{ {
species = passedSpecies; // Looped back to initial species (only Pokémon seen), must choose excluded species
species = excludedSpecies;
return species; 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) static void DeleteExcessMixedShows(void)
{ {
s8 i; s8 i;
@ -3900,8 +3914,8 @@ static bool8 TryMixPokeNewsShow(PokeNews *dest, PokeNews *src, s8 slot)
return FALSE; return FALSE;
} }
dest[slot].kind = src->kind; dest[slot].kind = src->kind;
dest[slot].state = 1; dest[slot].state = POKENEWS_STATE_UPCOMING;
dest[slot].days = src->days; dest[slot].dayCountdown = src->dayCountdown;
return TRUE; return TRUE;
} }
@ -3932,7 +3946,7 @@ static void ClearPokeNewsIfGameNotComplete(void)
if (FlagGet(FLAG_SYS_GAME_CLEAR) != TRUE) if (FlagGet(FLAG_SYS_GAME_CLEAR) != TRUE)
{ {
for (i = 0; i < POKE_NEWS_COUNT; i++) 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: case 0:
TVShowConvertInternationalString(gStringVar1, show->secretBaseVisit.playerName, show->secretBaseVisit.language); TVShowConvertInternationalString(gStringVar1, show->secretBaseVisit.playerName, show->secretBaseVisit.language);
if (show->secretBaseVisit.nDecorations == 0) if (show->secretBaseVisit.numDecorations == 0)
sTVShowState = 2; sTVShowState = 2;
else else
sTVShowState = 1; sTVShowState = 1;
break; break;
case 1: case 1:
StringCopy(gStringVar2, gDecorations[show->secretBaseVisit.decorations[0]].name); StringCopy(gStringVar2, gDecorations[show->secretBaseVisit.decorations[0]].name);
if (show->secretBaseVisit.nDecorations == 1) if (show->secretBaseVisit.numDecorations == 1)
sTVShowState = 4; sTVShowState = 4;
else else
sTVShowState = 3; sTVShowState = 3;
break; break;
case 3: case 3:
StringCopy(gStringVar2, gDecorations[show->secretBaseVisit.decorations[1]].name); StringCopy(gStringVar2, gDecorations[show->secretBaseVisit.decorations[1]].name);
switch (show->secretBaseVisit.nDecorations) switch (show->secretBaseVisit.numDecorations)
{ {
case 2: case 2:
sTVShowState = 7; sTVShowState = 7;
@ -5988,21 +6002,13 @@ static void DoTVShowPokemonLotteryWinnerFlashReport(void)
state = sTVShowState; state = sTVShowState;
TVShowConvertInternationalString(gStringVar1, show->lottoWinner.playerName, show->lottoWinner.language); TVShowConvertInternationalString(gStringVar1, show->lottoWinner.playerName, show->lottoWinner.language);
if (show->lottoWinner.whichPrize == 0) if (show->lottoWinner.whichPrize == 0)
{
StringCopy(gStringVar2, gText_Jackpot); StringCopy(gStringVar2, gText_Jackpot);
}
else if (show->lottoWinner.whichPrize == 1) else if (show->lottoWinner.whichPrize == 1)
{
StringCopy(gStringVar2, gText_First); StringCopy(gStringVar2, gText_First);
}
else if (show->lottoWinner.whichPrize == 2) else if (show->lottoWinner.whichPrize == 2)
{
StringCopy(gStringVar2, gText_Second); StringCopy(gStringVar2, gText_Second);
}
else else
{
StringCopy(gStringVar2, gText_Third); StringCopy(gStringVar2, gText_Third);
}
StringCopy(gStringVar3, ItemId_GetName(show->lottoWinner.item)); StringCopy(gStringVar3, ItemId_GetName(show->lottoWinner.item));
TVShowDone(); TVShowDone();
ShowFieldMessage(sTVPokemonLotteryWinnerFlashReportTextGroup[state]); ShowFieldMessage(sTVPokemonLotteryWinnerFlashReportTextGroup[state]);
@ -6715,23 +6721,23 @@ static void DoTVShowSafariFanClub(void)
switch (state) switch (state)
{ {
case 0: case 0:
if (show->safariFanClub.nMonsCaught == 0) if (show->safariFanClub.monsCaught == 0)
sTVShowState = 6; sTVShowState = 6;
else if (show->safariFanClub.nMonsCaught < 4) else if (show->safariFanClub.monsCaught < 4)
sTVShowState = 5; sTVShowState = 5;
else else
sTVShowState = 1; sTVShowState = 1;
break; break;
case 1: case 1:
TVShowConvertInternationalString(gStringVar1, show->safariFanClub.playerName, show->safariFanClub.language); TVShowConvertInternationalString(gStringVar1, show->safariFanClub.playerName, show->safariFanClub.language);
ConvertIntToDecimalString(1, show->safariFanClub.nMonsCaught); ConvertIntToDecimalString(1, show->safariFanClub.monsCaught);
if (show->safariFanClub.nPkblkUsed == 0) if (show->safariFanClub.pokeblocksUsed == 0)
sTVShowState = 3; sTVShowState = 3;
else else
sTVShowState = 2; sTVShowState = 2;
break; break;
case 2: case 2:
ConvertIntToDecimalString(1, show->safariFanClub.nPkblkUsed); ConvertIntToDecimalString(1, show->safariFanClub.pokeblocksUsed);
sTVShowState = 4; sTVShowState = 4;
break; break;
case 3: case 3:
@ -6743,21 +6749,21 @@ static void DoTVShowSafariFanClub(void)
break; break;
case 5: case 5:
TVShowConvertInternationalString(gStringVar1, show->safariFanClub.playerName, show->safariFanClub.language); TVShowConvertInternationalString(gStringVar1, show->safariFanClub.playerName, show->safariFanClub.language);
ConvertIntToDecimalString(1, show->safariFanClub.nMonsCaught); ConvertIntToDecimalString(1, show->safariFanClub.monsCaught);
if (show->safariFanClub.nPkblkUsed == 0) if (show->safariFanClub.pokeblocksUsed == 0)
sTVShowState = 8; sTVShowState = 8;
else else
sTVShowState = 7; sTVShowState = 7;
break; break;
case 6: case 6:
TVShowConvertInternationalString(gStringVar1, show->safariFanClub.playerName, show->safariFanClub.language); TVShowConvertInternationalString(gStringVar1, show->safariFanClub.playerName, show->safariFanClub.language);
if (show->safariFanClub.nPkblkUsed == 0) if (show->safariFanClub.pokeblocksUsed == 0)
sTVShowState = 8; sTVShowState = 8;
else else
sTVShowState = 7; sTVShowState = 7;
break; break;
case 7: case 7:
ConvertIntToDecimalString(1, show->safariFanClub.nPkblkUsed); ConvertIntToDecimalString(1, show->safariFanClub.pokeblocksUsed);
sTVShowState = 9; sTVShowState = 9;
break; break;
case 8: case 8: