Document Dewford Trend

This commit is contained in:
GriffinR 2021-03-31 15:53:01 -04:00
parent c40fb9288c
commit 86856098a3
14 changed files with 295 additions and 223 deletions

View File

@ -10,7 +10,7 @@ DewfordTown_Hall_EventScript_Girl:: @ 81FD4D0
lock lock
faceplayer faceplayer
call Common_EventScript_BufferTrendyPhrase call Common_EventScript_BufferTrendyPhrase
special TrendyPhraseIsOld special IsTrendyPhraseBoring
compare VAR_RESULT, TRUE compare VAR_RESULT, TRUE
goto_if_eq DewfordTown_Hall_EventScript_GirlBoredOfTrend goto_if_eq DewfordTown_Hall_EventScript_GirlBoredOfTrend
msgbox DewfordTown_Hall_Text_CantImagineLifeWithoutTrend, MSGBOX_DEFAULT msgbox DewfordTown_Hall_Text_CantImagineLifeWithoutTrend, MSGBOX_DEFAULT

View File

@ -138,7 +138,7 @@ gSpecials:: @ 81DBA64
def_special BufferMonNickname def_special BufferMonNickname
def_special IsMonOTIDNotPlayers def_special IsMonOTIDNotPlayers
def_special BufferTrendyPhraseString def_special BufferTrendyPhraseString
def_special TrendyPhraseIsOld def_special IsTrendyPhraseBoring
def_special BufferDeepLinkPhrase def_special BufferDeepLinkPhrase
def_special GetDewfordHallPaintingNameIndex def_special GetDewfordHallPaintingNameIndex
def_special SwapRegisteredBike def_special SwapRegisteredBike

View File

@ -1402,7 +1402,7 @@
#define FLAG_SYS_TV_HOME (SYSTEM_FLAGS + 0x30) #define FLAG_SYS_TV_HOME (SYSTEM_FLAGS + 0x30)
#define FLAG_SYS_TV_WATCH (SYSTEM_FLAGS + 0x31) #define FLAG_SYS_TV_WATCH (SYSTEM_FLAGS + 0x31)
#define FLAG_SYS_TV_START (SYSTEM_FLAGS + 0x32) #define FLAG_SYS_TV_START (SYSTEM_FLAGS + 0x32)
#define FLAG_SYS_POPWORD_INPUT (SYSTEM_FLAGS + 0x33) #define FLAG_SYS_CHANGED_DEWFORD_TREND (SYSTEM_FLAGS + 0x33)
#define FLAG_SYS_MIX_RECORD (SYSTEM_FLAGS + 0x34) #define FLAG_SYS_MIX_RECORD (SYSTEM_FLAGS + 0x34)
#define FLAG_SYS_CLOCK_SET (SYSTEM_FLAGS + 0x35) #define FLAG_SYS_CLOCK_SET (SYSTEM_FLAGS + 0x35)
#define FLAG_SYS_NATIONAL_DEX (SYSTEM_FLAGS + 0x36) #define FLAG_SYS_NATIONAL_DEX (SYSTEM_FLAGS + 0x36)

View File

@ -52,6 +52,7 @@
#define NUM_CONTEST_WINNERS 13 #define NUM_CONTEST_WINNERS 13
#define UNION_ROOM_KB_ROW_COUNT 10 #define UNION_ROOM_KB_ROW_COUNT 10
#define GIFT_RIBBONS_COUNT 11 #define GIFT_RIBBONS_COUNT 11
#define SAVED_TRENDS_COUNT 5
#define PYRAMID_BAG_ITEMS_COUNT 10 #define PYRAMID_BAG_ITEMS_COUNT 10
#define HALL_FACILITIES_COUNT 9 // 7 facilities for single mode + tower double mode + tower multi mode. #define HALL_FACILITIES_COUNT 9 // 7 facilities for single mode + tower double mode + tower multi mode.

View File

@ -2,10 +2,9 @@
#define GUARD_DEWFORDTREND_H #define GUARD_DEWFORDTREND_H
void InitDewfordTrend(void); void InitDewfordTrend(void);
void UpdateDewfordTrendPerDay(u16);
void UpdateDewfordTrendPerDay(u16 days); void UpdateDewfordTrendPerDay(u16 days);
bool8 IsPhraseTrendy(u16 *a); bool8 TrySetTrendyPhrase(u16 *phrase);
void ReceiveEasyChatPairsData(struct EasyChatPair *a, size_t b, u8 unused); void ReceiveDewfordTrendData(struct DewfordTrend *linkedTrends, size_t size, u8 unused);
#endif // GUARD_DEWFORDTREND_H #endif // GUARD_DEWFORDTREND_H

View File

@ -587,12 +587,13 @@ struct RamScript
struct RamScriptData data; struct RamScriptData data;
}; };
struct EasyChatPair // See dewford_trend.c
struct DewfordTrend
{ {
u16 unk0_0:7; u16 trendiness:7;
u16 unk0_7:7; u16 maxTrendiness:7;
u16 unk1_6:1; u16 gainingTrendiness:1;
u16 unk2; u16 rand;
u16 words[2]; u16 words[2];
}; /*size = 0x8*/ }; /*size = 0x8*/
@ -1021,7 +1022,7 @@ struct SaveBlock1
/*0x2BE0*/ struct MailStruct mail[MAIL_COUNT]; /*0x2BE0*/ struct MailStruct mail[MAIL_COUNT];
/*0x2E20*/ u8 additionalPhrases[8]; // bitfield for 33 additional phrases in easy chat system /*0x2E20*/ u8 additionalPhrases[8]; // bitfield for 33 additional phrases in easy chat system
/*0x2E28*/ OldMan oldMan; /*0x2E28*/ OldMan oldMan;
/*0x2e64*/ struct EasyChatPair easyChatPairs[5]; //Dewford trend [0] and some other stuff /*0x2e64*/ struct DewfordTrend dewfordTrends[SAVED_TRENDS_COUNT];
/*0x2e90*/ struct ContestWinner contestWinners[NUM_CONTEST_WINNERS]; // see CONTEST_WINNER_* /*0x2e90*/ struct ContestWinner contestWinners[NUM_CONTEST_WINNERS]; // see CONTEST_WINNER_*
/*0x3030*/ struct DayCare daycare; /*0x3030*/ struct DayCare daycare;
/*0x3150*/ struct LinkBattleRecords linkBattleRecords; /*0x3150*/ struct LinkBattleRecords linkBattleRecords;

View File

@ -31,7 +31,7 @@ void AlertTVThatPlayerPlayedRoulette(u16 nCoinsSpent);
void AlertTVOfNewCoinTotal(u16 nCoinsPaidOut); void AlertTVOfNewCoinTotal(u16 nCoinsPaidOut);
void TryPutSecretBaseSecretsOnAir(void); void TryPutSecretBaseSecretsOnAir(void);
void TryPutTodaysRivalTrainerOnAir(void); void TryPutTodaysRivalTrainerOnAir(void);
void sub_80EDC60(const u16 *words); void TryPutTrendWatcherOnAir(const u16 *words);
void sub_80EDA80(void); void sub_80EDA80(void);
void ReceivePokeNewsData(void *src, u32 size, u8 masterIdx); void ReceivePokeNewsData(void *src, u32 size, u8 masterIdx);
void sub_80F0BB8(void); void sub_80F0BB8(void);

View File

@ -10,311 +10,383 @@
#include "string_util.h" #include "string_util.h"
#include "constants/easy_chat.h" #include "constants/easy_chat.h"
// static functions /*
static void sub_8122804(struct EasyChatPair *s, u16 b, u8 c); ## Overview ##
static bool8 sub_8122A58(struct EasyChatPair *a, struct EasyChatPair *b, u8 c); This file handles the "Dewford Trend", a pair of Easy Chat words
static void sub_8122B28(struct EasyChatPair *s); repeated by NPCs around Dewford Hall.
static bool8 SB1ContainsWords(u16 *a);
static bool8 IsEasyChatPairEqual(u16 *words1, u16 *words2); The NPC outside Dewford Hall will ask what the player thinks of the
static s16 GetEqualEasyChatPairIndex(struct EasyChatPair *s, struct EasyChatPair *a, u16 b); current trendy phrase, and the player may submit a new pair of words.
If the NPC thinks the submitted phrase is "trendier" than the
current one (see TrySetTrendyPhrase), it becomes the new phrase.
## struct DewfordTrend ##
Information about a Dewford trend is stored in a struct DewfordTrend.
In addition to the two easy chat words that make up the trend's phrase,
each trend has a few randomly generated values associated with it.
- rand:
This is a 16 bit value generated once when the phrase is created.
It's used in calculations for Feebas tiles, Slot Machines, and Match Call.
It's also used to determine how much "trendiness" is lost over time (see below).
- trendiness / maxTrendiness:
Initialized as a random value between 30-127 inclusive. This is used to
compare how trendy one phrase is vs another. If a submitted phrase is
less trendy than the current one it won't be accepted. If the trend is
"boring" (see below) it will lose trendiness over time until it reaches 0,
at which point it will stop being boring and gain trendiness until it
reaches maxTrendiness (then it becomes boring again and the cycle repeats).
- gainingTrendiness:
This is a flag that determines whether a phrase should be gaining or losing
trendiness. An NPC in Dewford Hall will comment on whether the current phrase
is "boring" or not, and if it is gaining trendiness (or if it is still trendier
than the last phrase) it is not boring. This field will always be TRUE for any
new phrase submitted after the 1st submission.
## Saving trends ##
Each time a new trendy phrase is accepted, the previous Dewford Trend is saved
in gSaveBlock1Ptr->dewfordTrends[]. Up to SAVED_TRENDS_COUNT (5) trends may be
saved at one time. The trends in this array are kept in sorted order from most trendy
to least trendy. The current trendy phrase is always at gSaveBlock1Ptr->dewfordTrends[0].
If the player mixes records with another player, their own trends are replaced with
their mixing partner's, unless the phrase is the same, in which case the version with
a higher trendiness value is used (see ReceiveDewfordTrendData).
*/
enum {
SORT_MODE_NORMAL,
SORT_MODE_MAX_FIRST,
SORT_MODE_FULL,
};
static void SortTrends(struct DewfordTrend *, u16, u8);
static bool8 CompareTrends(struct DewfordTrend *, struct DewfordTrend *, u8);
static void SeedTrendRng(struct DewfordTrend *);
static bool8 IsPhraseInSavedTrends(u16 *);
static bool8 IsEasyChatPairEqual(u16 *, u16 *);
static s16 GetSavedTrendIndex(struct DewfordTrend *, struct DewfordTrend *, u16);
// text
void InitDewfordTrend(void) void InitDewfordTrend(void)
{ {
u16 i; u16 i;
for (i = 0; i < 5; i++) for (i = 0; i < SAVED_TRENDS_COUNT; i++)
{ {
gSaveBlock1Ptr->easyChatPairs[i].words[0] = GetRandomEasyChatWordFromGroup(EC_GROUP_CONDITIONS); gSaveBlock1Ptr->dewfordTrends[i].words[0] = GetRandomEasyChatWordFromGroup(EC_GROUP_CONDITIONS);
if (Random() & 1) if (Random() & 1)
gSaveBlock1Ptr->easyChatPairs[i].words[1] = GetRandomEasyChatWordFromGroup(EC_GROUP_LIFESTYLE); gSaveBlock1Ptr->dewfordTrends[i].words[1] = GetRandomEasyChatWordFromGroup(EC_GROUP_LIFESTYLE);
else else
gSaveBlock1Ptr->easyChatPairs[i].words[1] = GetRandomEasyChatWordFromGroup(EC_GROUP_HOBBIES); gSaveBlock1Ptr->dewfordTrends[i].words[1] = GetRandomEasyChatWordFromGroup(EC_GROUP_HOBBIES);
gSaveBlock1Ptr->easyChatPairs[i].unk1_6 = Random() & 1; gSaveBlock1Ptr->dewfordTrends[i].gainingTrendiness = Random() & 1;
sub_8122B28(&(gSaveBlock1Ptr->easyChatPairs[i])); SeedTrendRng(&(gSaveBlock1Ptr->dewfordTrends[i]));
} }
sub_8122804(gSaveBlock1Ptr->easyChatPairs, 5, 0); SortTrends(gSaveBlock1Ptr->dewfordTrends, SAVED_TRENDS_COUNT, SORT_MODE_NORMAL);
} }
void UpdateDewfordTrendPerDay(u16 a) void UpdateDewfordTrendPerDay(u16 days)
{ {
u16 i; u16 i;
if (a != 0) if (days != 0)
{ {
u32 sp0 = a * 5; u32 clockRand = days * 5;
for (i = 0; i < 5; i++) for (i = 0; i < SAVED_TRENDS_COUNT; i++)
{ {
u32 r4; u32 trendiness;
u32 r2 = sp0; u32 rand = clockRand;
struct EasyChatPair *r5 = &(gSaveBlock1Ptr->easyChatPairs[i]); struct DewfordTrend *trend = &gSaveBlock1Ptr->dewfordTrends[i];
if (r5->unk1_6 == 0) if (!trend->gainingTrendiness)
{ {
if (r5->unk0_0 >= (u16)r2) // This trend is "boring"
// Lose trendiness until it becomes 0
if (trend->trendiness >= (u16)rand)
{ {
r5->unk0_0 -= r2; trend->trendiness -= rand;
if (r5->unk0_0 == 0) if (trend->trendiness == 0)
r5->unk1_6 = 1; trend->gainingTrendiness = TRUE;
continue; continue;
} }
r2 -= r5->unk0_0; rand -= trend->trendiness;
r5->unk0_0 = 0; trend->trendiness = 0;
r5->unk1_6 = 1; trend->gainingTrendiness = TRUE;
} }
r4 = r5->unk0_0 + r2;
if ((u16)r4 > r5->unk0_7)
{
u32 sp4 = r4 % r5->unk0_7;
r4 = r4 / r5->unk0_7;
r5->unk1_6 = r4 ^ 1; trendiness = trend->trendiness + rand;
if (r5->unk1_6) if ((u16)trendiness > trend->maxTrendiness)
r5->unk0_0 = sp4; {
// Reached limit, reset trendiness
u32 newTrendiness = trendiness % trend->maxTrendiness;
trendiness = trendiness / trend->maxTrendiness;
trend->gainingTrendiness = trendiness ^ 1;
if (trend->gainingTrendiness)
trend->trendiness = newTrendiness;
else else
r5->unk0_0 = r5->unk0_7 - sp4; trend->trendiness = trend->maxTrendiness - newTrendiness;
} }
else else
{ {
r5->unk0_0 = r4; // Increase trendiness
trend->trendiness = trendiness;
if (r5->unk0_0 == r5->unk0_7) // Trend has reached its max, becoming "boring" and start losing trendiness
r5->unk1_6 = 0; if (trend->trendiness == trend->maxTrendiness)
trend->gainingTrendiness = FALSE;
} }
} }
sub_8122804(gSaveBlock1Ptr->easyChatPairs, 5, 0); SortTrends(gSaveBlock1Ptr->dewfordTrends, SAVED_TRENDS_COUNT, SORT_MODE_NORMAL);
} }
} }
// Returns TRUE if the current trendy phrase was successfully changed to the given phrase
bool8 IsPhraseTrendy(u16 *a) // Returns FALSE otherwise
bool8 TrySetTrendyPhrase(u16 *phrase)
{ {
struct EasyChatPair s = {0}; struct DewfordTrend trend = {0};
u16 i; u16 i;
if (!SB1ContainsWords(a)) if (!IsPhraseInSavedTrends(phrase))
{ {
if (!FlagGet(FLAG_SYS_POPWORD_INPUT)) if (!FlagGet(FLAG_SYS_CHANGED_DEWFORD_TREND))
{ {
FlagSet(FLAG_SYS_POPWORD_INPUT); FlagSet(FLAG_SYS_CHANGED_DEWFORD_TREND);
// Make sure player couldn't have received this phrase by mixing records
if (!FlagGet(FLAG_SYS_MIX_RECORD)) if (!FlagGet(FLAG_SYS_MIX_RECORD))
{ {
gSaveBlock1Ptr->easyChatPairs[0].words[0] = a[0]; // This is the first time submitting a phrase
gSaveBlock1Ptr->easyChatPairs[0].words[1] = a[1]; // No need to check saved phrases or reset rng, just set the new words
gSaveBlock1Ptr->dewfordTrends[0].words[0] = phrase[0];
gSaveBlock1Ptr->dewfordTrends[0].words[1] = phrase[1];
return TRUE; return TRUE;
} }
} }
s.words[0] = a[0]; // Initialize DewfordTrend using given phrase
s.words[1] = a[1]; trend.words[0] = phrase[0];
s.unk1_6 = 1; trend.words[1] = phrase[1];
sub_8122B28(&s); trend.gainingTrendiness = TRUE;
SeedTrendRng(&trend);
for (i = 0; i < 5; i++) for (i = 0; i < SAVED_TRENDS_COUNT; i++)
{ {
if (sub_8122A58(&s, &(gSaveBlock1Ptr->easyChatPairs[i]), 0)) if (CompareTrends(&trend, &(gSaveBlock1Ptr->dewfordTrends[i]), SORT_MODE_NORMAL))
{ {
u16 r3 = 4; // New trend is "trendier" than dewfordTrend[i]
// Shift other trends back to insert new trend
while (r3 > i) u16 j = SAVED_TRENDS_COUNT - 1;
while (j > i)
{ {
gSaveBlock1Ptr->easyChatPairs[r3] = gSaveBlock1Ptr->easyChatPairs[r3 - 1]; gSaveBlock1Ptr->dewfordTrends[j] = gSaveBlock1Ptr->dewfordTrends[j - 1];
r3--; j--;
} }
gSaveBlock1Ptr->easyChatPairs[i] = s; gSaveBlock1Ptr->dewfordTrends[i] = trend;
if(i == 4)
sub_80EDC60(a); if (i == SAVED_TRENDS_COUNT - 1)
TryPutTrendWatcherOnAir(phrase);
// If i is 0, the given phrase is the new current phrase
return (i == 0); return (i == 0);
} }
} }
gSaveBlock1Ptr->easyChatPairs[4] = s;
sub_80EDC60(a); // New trend is less "trendy" than all other saved trends, put it in last
gSaveBlock1Ptr->dewfordTrends[SAVED_TRENDS_COUNT - 1] = trend;
TryPutTrendWatcherOnAir(phrase);
} }
return FALSE; return FALSE;
} }
static void sub_8122804(struct EasyChatPair *s, u16 b, u8 c) static void SortTrends(struct DewfordTrend *trends, u16 numTrends, u8 mode)
{
u16 h;
for (h = 0; h < b; h++)
{ {
u16 i; u16 i;
for (i = 0; i < numTrends; i++)
for (i = h + 1; i < b; i++)
{ {
if (sub_8122A58(&s[i], &s[h], c)) u16 j;
for (j = i + 1; j < numTrends; j++)
{ {
struct EasyChatPair temp; if (CompareTrends(&trends[j], &trends[i], mode))
{
temp = s[i]; struct DewfordTrend temp;
s[i] = s[h]; SWAP(trends[j], trends[i], temp);
s[h] = temp;
} }
} }
} }
} }
void ReceiveEasyChatPairsData(struct EasyChatPair *a, size_t size, u8 unused) #define SAVED_TRENDS_SIZE (sizeof(struct DewfordTrend) * SAVED_TRENDS_COUNT)
{ #define BUFFER_SIZE (SAVED_TRENDS_SIZE * MAX_LINK_PLAYERS > 0x100 ? SAVED_TRENDS_SIZE * MAX_LINK_PLAYERS : 0x100) // More space was allocated than needed
u16 i, j, r3, players;
struct EasyChatPair *buffer1, *buffer2, *src, *dst, *foo_of_buffer2;
buffer1 = Alloc(0x100); void ReceiveDewfordTrendData(struct DewfordTrend *linkedTrends, size_t size, u8 unused)
if(buffer1 != NULL)
{ {
buffer2 = Alloc(0x100); u16 i, j, numTrends, players;
if(buffer2 == NULL) struct DewfordTrend *linkedTrendsBuffer, *savedTrendsBuffer, *src, *dst, *temp;
// Exit if alloc fails
if (!(linkedTrendsBuffer = Alloc(BUFFER_SIZE)))
return;
// Exit if alloc fails
if (!(savedTrendsBuffer = Alloc(BUFFER_SIZE)))
{ {
Free(buffer1); Free(linkedTrendsBuffer);
return;
} }
else
{ // Buffer the new trends being received via Record Mixing
players = GetLinkPlayerCount(); players = GetLinkPlayerCount();
for (i = 0; i < players; i++) for (i = 0; i < players; i++)
memcpy(&(buffer1[i * 5]), (u8 *)a + i * size, 40); memcpy(&linkedTrendsBuffer[i * SAVED_TRENDS_COUNT], (u8 *)linkedTrends + i * size, SAVED_TRENDS_SIZE);
src = buffer1;
dst = buffer2; // Determine which of the received trends should be saved.
r3 = 0; // savedTrendsBuffer starts empty, and when finished will contain
// which of the linked trends to save in the saveblock.
src = linkedTrendsBuffer;
dst = savedTrendsBuffer;
numTrends = 0;
for (i = 0; i < players; i++) for (i = 0; i < players; i++)
{ {
for (j = 0; j < 5; j++) for (j = 0; j < SAVED_TRENDS_COUNT; j++)
{ {
s16 foo = GetEqualEasyChatPairIndex(buffer2, src, r3); s16 idx = GetSavedTrendIndex(savedTrendsBuffer, src, numTrends);
if (foo < 0) if (idx < 0)
{ {
// This phrase is not a currently saved trend, save it
*(dst++) = *src; *(dst++) = *src;
r3++; numTrends++;
} }
else else
{ {
foo_of_buffer2 = (struct EasyChatPair *)((u32)buffer2 + (foo * 8)); //required to do this to reverse the order of register operands in add ASM statement // This phrase already exists as a saved phrase
if (foo_of_buffer2->unk0_0 < src->unk0_0) // Only overwrrite it if it's "trendier"
temp = &savedTrendsBuffer[idx];
if (temp->trendiness < src->trendiness)
{ {
*foo_of_buffer2 = *src; *temp = *src;
} }
} }
src++; src++;
} }
} }
sub_8122804(buffer2, r3, 2); SortTrends(savedTrendsBuffer, numTrends, SORT_MODE_FULL);
src = buffer2;
dst = gSaveBlock1Ptr->easyChatPairs; // Overwrite current saved trends with new saved trends
for (i = 0; i < 5; i++) src = savedTrendsBuffer;
dst = gSaveBlock1Ptr->dewfordTrends;
for (i = 0; i < SAVED_TRENDS_COUNT; i++)
*(dst++) = *(src++); *(dst++) = *(src++);
Free(buffer1);
Free(buffer2); Free(linkedTrendsBuffer);
} Free(savedTrendsBuffer);
}
} }
void BufferTrendyPhraseString(void) void BufferTrendyPhraseString(void)
{ {
struct EasyChatPair *s = &gSaveBlock1Ptr->easyChatPairs[gSpecialVar_0x8004]; struct DewfordTrend *trend = &gSaveBlock1Ptr->dewfordTrends[gSpecialVar_0x8004];
ConvertEasyChatWordsToString(gStringVar1, trend->words, 2, 1);
ConvertEasyChatWordsToString(gStringVar1, s->words, 2, 1);
} }
void TrendyPhraseIsOld(void) // Returns TRUE if the current trendy phrase is "boring", FALSE otherwise
// This only influences the comment of an NPC inside the Dewford Town Hall
void IsTrendyPhraseBoring(void)
{ {
u16 result = 0; bool16 result = FALSE;
do do
{ {
if (gSaveBlock1Ptr->easyChatPairs[0].unk0_0 - gSaveBlock1Ptr->easyChatPairs[1].unk0_0 > 1) if (gSaveBlock1Ptr->dewfordTrends[0].trendiness - gSaveBlock1Ptr->dewfordTrends[1].trendiness > 1)
break; break;
if (gSaveBlock1Ptr->easyChatPairs[0].unk1_6) if (gSaveBlock1Ptr->dewfordTrends[0].gainingTrendiness)
break; break;
if (!gSaveBlock1Ptr->easyChatPairs[1].unk1_6) if (!gSaveBlock1Ptr->dewfordTrends[1].gainingTrendiness)
break; break;
result = 1; result = TRUE;
} while (0); } while (0);
gSpecialVar_Result = result; gSpecialVar_Result = result;
} }
// A painting hangs on the wall of the Dewford Hall
// When interacted with it says "{trendy phrase}'S {name} is the title"
// {name} is one of 8 pre-set words, depending on the current phrase
// See DewfordTown_Hall_EventScript_Painting
void GetDewfordHallPaintingNameIndex(void) void GetDewfordHallPaintingNameIndex(void)
{ {
gSpecialVar_Result = (gSaveBlock1Ptr->easyChatPairs[0].words[0] + gSaveBlock1Ptr->easyChatPairs[0].words[1]) & 7; gSpecialVar_Result = (gSaveBlock1Ptr->dewfordTrends[0].words[0] + gSaveBlock1Ptr->dewfordTrends[0].words[1]) & 7;
} }
static bool8 sub_8122A58(struct EasyChatPair *a, struct EasyChatPair *b, u8 c) // Returns TRUE if a > b (a is "trendier" than b), FALSE if a < b (b is "trendier" than a)
// How one trend is compared to the other depends on the mode
// In SORT_MODE_FULL if the trends are equal then TRUE is always returned, otherwise TRUE or FALSE is returned randomly
static bool8 CompareTrends(struct DewfordTrend *a, struct DewfordTrend *b, u8 mode)
{ {
switch (c) switch (mode)
{ {
case 0: case SORT_MODE_NORMAL:
if (a->unk0_0 > b->unk0_0) if (a->trendiness > b->trendiness) return TRUE;
return 1; if (a->trendiness < b->trendiness) return FALSE;
if (a->unk0_0 < b->unk0_0)
return 0; if (a->maxTrendiness > b->maxTrendiness) return TRUE;
if (a->unk0_7 > b->unk0_7) if (a->maxTrendiness < b->maxTrendiness) return FALSE;
return 1;
if (a->unk0_7 < b->unk0_7)
return 0;
break; break;
case 1: case SORT_MODE_MAX_FIRST: // Unused
if (a->unk0_7 > b->unk0_7) if (a->maxTrendiness > b->maxTrendiness) return TRUE;
return 1; if (a->maxTrendiness < b->maxTrendiness) return FALSE;
if (a->unk0_7 < b->unk0_7)
return 0; if (a->trendiness > b->trendiness) return TRUE;
if (a->unk0_0 > b->unk0_0) if (a->trendiness < b->trendiness) return FALSE;
return 1;
if (a->unk0_0 < b->unk0_0)
return 0;
break; break;
case 2: case SORT_MODE_FULL:
if (a->unk0_0 > b->unk0_0) if (a->trendiness > b->trendiness) return TRUE;
return 1; if (a->trendiness < b->trendiness) return FALSE;
if (a->unk0_0 < b->unk0_0)
return 0; if (a->maxTrendiness > b->maxTrendiness) return TRUE;
if (a->unk0_7 > b->unk0_7) if (a->maxTrendiness < b->maxTrendiness) return FALSE;
return 1;
if (a->unk0_7 < b->unk0_7) if (a->rand > b->rand) return TRUE;
return 0; if (a->rand < b->rand) return FALSE;
if (a->unk2 > b->unk2)
return 1; if (a->words[0] > b->words[0]) return TRUE;
if (a->unk2 < b->unk2) if (a->words[0] < b->words[0]) return FALSE;
return 0;
if (a->words[0] > b->words[0]) if (a->words[1] > b->words[1]) return TRUE;
return 1; if (a->words[1] < b->words[1]) return FALSE;
if (a->words[0] < b->words[0]) return TRUE;
return 0;
if (a->words[1] > b->words[1])
return 1;
if (a->words[1] < b->words[1])
return 0;
return 1;
} }
// Invalid mode given, or trends are equal in SORT_MODE_NORMAL or SORT_MODE_MAX_FIRST
// Randomly pick one of the phrases
return Random() & 1; return Random() & 1;
} }
static void sub_8122B28(struct EasyChatPair *s) static void SeedTrendRng(struct DewfordTrend *trend)
{ {
u16 r4; u16 rand;
r4 = Random() % 98; rand = Random() % 98;
if (r4 > 50) if (rand > 50)
{ {
r4 = Random() % 98; rand = Random() % 98;
if (r4 > 80) if (rand > 80)
r4 = Random() % 98; rand = Random() % 98;
} }
s->unk0_7 = r4 + 30; trend->maxTrendiness = rand + 30;
s->unk0_0 = (Random() % (r4 + 1)) + 30; trend->trendiness = (Random() % (rand + 1)) + 30;
s->unk2 = Random(); trend->rand = Random();
} }
static bool8 SB1ContainsWords(u16 *a) static bool8 IsPhraseInSavedTrends(u16 *phrase)
{ {
u16 i; u16 i;
for (i = 0; i < 5; i++) for (i = 0; i < SAVED_TRENDS_COUNT; i++)
{ {
if (IsEasyChatPairEqual(a, gSaveBlock1Ptr->easyChatPairs[i].words) != 0) if (IsEasyChatPairEqual(phrase, gSaveBlock1Ptr->dewfordTrends[i].words))
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
@ -332,15 +404,14 @@ static bool8 IsEasyChatPairEqual(u16 *words1, u16 *words2)
return TRUE; return TRUE;
} }
static s16 GetEqualEasyChatPairIndex(struct EasyChatPair*s, struct EasyChatPair *a, u16 b) static s16 GetSavedTrendIndex(struct DewfordTrend *savedTrends, struct DewfordTrend *trend, u16 numSaved)
{ {
s16 i; s16 i;
for (i = 0; i < numSaved; i++)
for (i = 0; i < b; i++)
{ {
if (IsEasyChatPairEqual(a->words, s->words)) if (IsEasyChatPairEqual(trend->words, savedTrends->words))
return i; return i;
s++; savedTrends++;
} }
return -1; return -1;
} }

View File

@ -1477,8 +1477,8 @@ void ShowEasyChatScreen(void)
break; break;
case EASY_CHAT_TYPE_TRENDY_PHRASE: case EASY_CHAT_TYPE_TRENDY_PHRASE:
words = (u16 *)gStringVar3; words = (u16 *)gStringVar3;
words[0] = gSaveBlock1Ptr->easyChatPairs[0].words[0]; words[0] = gSaveBlock1Ptr->dewfordTrends[0].words[0];
words[1] = gSaveBlock1Ptr->easyChatPairs[0].words[1]; words[1] = gSaveBlock1Ptr->dewfordTrends[0].words[1];
break; break;
case EASY_CHAT_TYPE_GABBY_AND_TY: case EASY_CHAT_TYPE_GABBY_AND_TY:
words = gSaveBlock1Ptr->gabbyAndTyData.quote; words = gSaveBlock1Ptr->gabbyAndTyData.quote;
@ -2958,7 +2958,7 @@ static void SetSpecialEasyChatResult(void)
break; break;
case EASY_CHAT_TYPE_TRENDY_PHRASE: case EASY_CHAT_TYPE_TRENDY_PHRASE:
BufferCurrentPhraseToStringVar2(); BufferCurrentPhraseToStringVar2();
gSpecialVar_0x8004 = IsPhraseTrendy(sEasyChatScreen->currentPhrase); gSpecialVar_0x8004 = TrySetTrendyPhrase(sEasyChatScreen->currentPhrase);
break; break;
case EASY_CHAT_TYPE_GOOD_SAYING: case EASY_CHAT_TYPE_GOOD_SAYING:
gSpecialVar_0x8004 = DidPlayerInputABerryMasterWifePhrase(); gSpecialVar_0x8004 = DidPlayerInputABerryMasterWifePhrase();

View File

@ -1336,7 +1336,7 @@ u16 GetSlotMachineId(void)
static const u8 sSlotMachineIds[] = {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5}; static const u8 sSlotMachineIds[] = {0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5};
static const u8 sSlotMachineServiceDayIds[] = {3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5}; static const u8 sSlotMachineServiceDayIds[] = {3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5};
u32 rnd = gSaveBlock1Ptr->easyChatPairs[0].unk0_0 + gSaveBlock1Ptr->easyChatPairs[0].unk2 + sSlotMachineRandomSeeds[gSpecialVar_0x8004]; u32 rnd = gSaveBlock1Ptr->dewfordTrends[0].trendiness + gSaveBlock1Ptr->dewfordTrends[0].rand + sSlotMachineRandomSeeds[gSpecialVar_0x8004];
if (GetPriceReduction(POKENEWS_GAME_CORNER)) if (GetPriceReduction(POKENEWS_GAME_CORNER))
{ {
return sSlotMachineServiceDayIds[rnd % SLOT_MACHINE_COUNT]; return sSlotMachineServiceDayIds[rnd % SLOT_MACHINE_COUNT];

View File

@ -1773,7 +1773,7 @@ static bool32 sub_8196D74(int matchCallId)
{ {
int dayCount; int dayCount;
int otId; int otId;
u16 easyChatWord; u16 rand;
int numRematchTrainersFought; int numRematchTrainersFought;
int var0, var1, var2; int var0, var1, var2;
@ -1783,10 +1783,10 @@ static bool32 sub_8196D74(int matchCallId)
dayCount = RtcGetLocalDayCount(); dayCount = RtcGetLocalDayCount();
otId = GetTrainerId(gSaveBlock2Ptr->playerTrainerId) & 0xFFFF; otId = GetTrainerId(gSaveBlock2Ptr->playerTrainerId) & 0xFFFF;
easyChatWord = gSaveBlock1Ptr->easyChatPairs[0].unk2; rand = gSaveBlock1Ptr->dewfordTrends[0].rand;
numRematchTrainersFought = GetNumRematchTrainersFought(); numRematchTrainersFought = GetNumRematchTrainersFought();
var0 = (numRematchTrainersFought * 13) / 10; var0 = (numRematchTrainersFought * 13) / 10;
var1 = ((dayCount ^ easyChatWord) + (easyChatWord ^ GetGameStat(GAME_STAT_TRAINER_BATTLES))) ^ otId; var1 = ((dayCount ^ rand) + (rand ^ GetGameStat(GAME_STAT_TRAINER_BATTLES))) ^ otId;
var2 = var1 % var0; var2 = var1 % var0;
if (var2 < numRematchTrainersFought) if (var2 < numRematchTrainersFought)
{ {

View File

@ -50,7 +50,7 @@ struct PlayerRecordsRS
TVShow tvShows[TV_SHOWS_COUNT]; TVShow tvShows[TV_SHOWS_COUNT];
PokeNews pokeNews[POKE_NEWS_COUNT]; PokeNews pokeNews[POKE_NEWS_COUNT];
OldMan oldMan; OldMan oldMan;
struct EasyChatPair easyChatPairs[5]; struct DewfordTrend dewfordTrends[SAVED_TRENDS_COUNT];
struct RecordMixingDayCareMail dayCareMail; struct RecordMixingDayCareMail dayCareMail;
struct RSBattleTowerRecord battleTowerRecord; struct RSBattleTowerRecord battleTowerRecord;
u16 giftItem; u16 giftItem;
@ -63,7 +63,7 @@ struct PlayerRecordsEmerald
/* 0x0c80 */ TVShow tvShows[TV_SHOWS_COUNT]; /* 0x0c80 */ TVShow tvShows[TV_SHOWS_COUNT];
/* 0x1004 */ PokeNews pokeNews[POKE_NEWS_COUNT]; /* 0x1004 */ PokeNews pokeNews[POKE_NEWS_COUNT];
/* 0x1044 */ OldMan oldMan; /* 0x1044 */ OldMan oldMan;
/* 0x1084 */ struct EasyChatPair easyChatPairs[5]; /* 0x1084 */ struct DewfordTrend dewfordTrends[SAVED_TRENDS_COUNT];
/* 0x10ac */ struct RecordMixingDayCareMail dayCareMail; /* 0x10ac */ struct RecordMixingDayCareMail dayCareMail;
/* 0x1124 */ struct EmeraldBattleTowerRecord battleTowerRecord; /* 0x1124 */ struct EmeraldBattleTowerRecord battleTowerRecord;
/* 0x1210 */ u16 giftItem; /* 0x1210 */ u16 giftItem;
@ -86,7 +86,7 @@ static struct SecretBase *sSecretBasesSave;
static TVShow *sTvShowsSave; static TVShow *sTvShowsSave;
static PokeNews *sPokeNewsSave; static PokeNews *sPokeNewsSave;
static OldMan *sOldManSave; static OldMan *sOldManSave;
static struct EasyChatPair *sEasyChatPairsSave; static struct DewfordTrend *sDewfordTrendsSave;
static struct RecordMixingDayCareMail *gUnknown_03001148; static struct RecordMixingDayCareMail *gUnknown_03001148;
static void *sBattleTowerSave; static void *sBattleTowerSave;
static LilycoveLady *sLilycoveLadySave; static LilycoveLady *sLilycoveLadySave;
@ -179,7 +179,7 @@ static void SetSrcLookupPointers(void)
sTvShowsSave = gSaveBlock1Ptr->tvShows; sTvShowsSave = gSaveBlock1Ptr->tvShows;
sPokeNewsSave = gSaveBlock1Ptr->pokeNews; sPokeNewsSave = gSaveBlock1Ptr->pokeNews;
sOldManSave = &gSaveBlock1Ptr->oldMan; sOldManSave = &gSaveBlock1Ptr->oldMan;
sEasyChatPairsSave = gSaveBlock1Ptr->easyChatPairs; sDewfordTrendsSave = gSaveBlock1Ptr->dewfordTrends;
gUnknown_03001148 = &gUnknown_02039F9C; gUnknown_03001148 = &gUnknown_02039F9C;
sBattleTowerSave = &gSaveBlock2Ptr->frontier.towerPlayer; sBattleTowerSave = &gSaveBlock2Ptr->frontier.towerPlayer;
sLilycoveLadySave = &gSaveBlock1Ptr->lilycoveLady; sLilycoveLadySave = &gSaveBlock1Ptr->lilycoveLady;
@ -194,7 +194,7 @@ static void PrepareUnknownExchangePacket(struct PlayerRecordsRS *dest)
sub_80F14F8(dest->tvShows); sub_80F14F8(dest->tvShows);
memcpy(dest->pokeNews, sPokeNewsSave, sizeof(dest->pokeNews)); memcpy(dest->pokeNews, sPokeNewsSave, sizeof(dest->pokeNews));
memcpy(&dest->oldMan, sOldManSave, sizeof(dest->oldMan)); memcpy(&dest->oldMan, sOldManSave, sizeof(dest->oldMan));
memcpy(dest->easyChatPairs, sEasyChatPairsSave, sizeof(dest->easyChatPairs)); memcpy(dest->dewfordTrends, sDewfordTrendsSave, sizeof(dest->dewfordTrends));
sub_80E89F8(&dest->dayCareMail); sub_80E89F8(&dest->dayCareMail);
EmeraldBattleTowerRecordToRuby(sBattleTowerSave, &dest->battleTowerRecord); EmeraldBattleTowerRecordToRuby(sBattleTowerSave, &dest->battleTowerRecord);
@ -211,7 +211,7 @@ static void PrepareExchangePacketForRubySapphire(struct PlayerRecordsRS *dest)
memcpy(dest->pokeNews, sPokeNewsSave, sizeof(dest->pokeNews)); memcpy(dest->pokeNews, sPokeNewsSave, sizeof(dest->pokeNews));
memcpy(&dest->oldMan, sOldManSave, sizeof(dest->oldMan)); memcpy(&dest->oldMan, sOldManSave, sizeof(dest->oldMan));
sub_8120B70(&dest->oldMan); sub_8120B70(&dest->oldMan);
memcpy(dest->easyChatPairs, sEasyChatPairsSave, sizeof(dest->easyChatPairs)); memcpy(dest->dewfordTrends, sDewfordTrendsSave, sizeof(dest->dewfordTrends));
sub_80E89F8(&dest->dayCareMail); sub_80E89F8(&dest->dayCareMail);
SanitizeDayCareMailForRuby(&dest->dayCareMail); SanitizeDayCareMailForRuby(&dest->dayCareMail);
EmeraldBattleTowerRecordToRuby(sBattleTowerSave, &dest->battleTowerRecord); EmeraldBattleTowerRecordToRuby(sBattleTowerSave, &dest->battleTowerRecord);
@ -241,7 +241,7 @@ static void PrepareExchangePacket(void)
memcpy(sSentRecord->emerald.pokeNews, sPokeNewsSave, sizeof(sSentRecord->emerald.pokeNews)); memcpy(sSentRecord->emerald.pokeNews, sPokeNewsSave, sizeof(sSentRecord->emerald.pokeNews));
memcpy(&sSentRecord->emerald.oldMan, sOldManSave, sizeof(sSentRecord->emerald.oldMan)); memcpy(&sSentRecord->emerald.oldMan, sOldManSave, sizeof(sSentRecord->emerald.oldMan));
memcpy(&sSentRecord->emerald.lilycoveLady, sLilycoveLadySave, sizeof(sSentRecord->emerald.lilycoveLady)); memcpy(&sSentRecord->emerald.lilycoveLady, sLilycoveLadySave, sizeof(sSentRecord->emerald.lilycoveLady));
memcpy(sSentRecord->emerald.easyChatPairs, sEasyChatPairsSave, sizeof(sSentRecord->emerald.easyChatPairs)); memcpy(sSentRecord->emerald.dewfordTrends, sDewfordTrendsSave, sizeof(sSentRecord->emerald.dewfordTrends));
sub_80E89F8(&sSentRecord->emerald.dayCareMail); sub_80E89F8(&sSentRecord->emerald.dayCareMail);
memcpy(&sSentRecord->emerald.battleTowerRecord, sBattleTowerSave, sizeof(sSentRecord->emerald.battleTowerRecord)); memcpy(&sSentRecord->emerald.battleTowerRecord, sBattleTowerSave, sizeof(sSentRecord->emerald.battleTowerRecord));
SanitizeEmeraldBattleTowerRecord(&sSentRecord->emerald.battleTowerRecord); SanitizeEmeraldBattleTowerRecord(&sSentRecord->emerald.battleTowerRecord);
@ -266,7 +266,7 @@ static void ReceiveExchangePacket(u32 which)
ReceiveTvShowsData(sReceivedRecords->ruby.tvShows, sizeof(struct PlayerRecordsRS), which); ReceiveTvShowsData(sReceivedRecords->ruby.tvShows, sizeof(struct PlayerRecordsRS), which);
ReceivePokeNewsData(sReceivedRecords->ruby.pokeNews, sizeof(struct PlayerRecordsRS), which); ReceivePokeNewsData(sReceivedRecords->ruby.pokeNews, sizeof(struct PlayerRecordsRS), which);
ReceiveOldManData(&sReceivedRecords->ruby.oldMan, sizeof(struct PlayerRecordsRS), which); ReceiveOldManData(&sReceivedRecords->ruby.oldMan, sizeof(struct PlayerRecordsRS), which);
ReceiveEasyChatPairsData(sReceivedRecords->ruby.easyChatPairs, sizeof(struct PlayerRecordsRS), which); ReceiveDewfordTrendData(sReceivedRecords->ruby.dewfordTrends, sizeof(struct PlayerRecordsRS), which);
ReceiveGiftItem(&sReceivedRecords->ruby.giftItem, which); ReceiveGiftItem(&sReceivedRecords->ruby.giftItem, which);
} }
else else
@ -277,7 +277,7 @@ static void ReceiveExchangePacket(u32 which)
ReceiveTvShowsData(sReceivedRecords->emerald.tvShows, sizeof(struct PlayerRecordsEmerald), which); ReceiveTvShowsData(sReceivedRecords->emerald.tvShows, sizeof(struct PlayerRecordsEmerald), which);
ReceivePokeNewsData(sReceivedRecords->emerald.pokeNews, sizeof(struct PlayerRecordsEmerald), which); ReceivePokeNewsData(sReceivedRecords->emerald.pokeNews, sizeof(struct PlayerRecordsEmerald), which);
ReceiveOldManData(&sReceivedRecords->emerald.oldMan, sizeof(struct PlayerRecordsEmerald), which); ReceiveOldManData(&sReceivedRecords->emerald.oldMan, sizeof(struct PlayerRecordsEmerald), which);
ReceiveEasyChatPairsData(sReceivedRecords->emerald.easyChatPairs, sizeof(struct PlayerRecordsEmerald), which); ReceiveDewfordTrendData(sReceivedRecords->emerald.dewfordTrends, sizeof(struct PlayerRecordsEmerald), which);
ReceiveDaycareMailData(&sReceivedRecords->emerald.dayCareMail, sizeof(struct PlayerRecordsEmerald), which, sReceivedRecords->emerald.tvShows); ReceiveDaycareMailData(&sReceivedRecords->emerald.dayCareMail, sizeof(struct PlayerRecordsEmerald), which, sReceivedRecords->emerald.tvShows);
ReceiveBattleTowerData(&sReceivedRecords->emerald.battleTowerRecord, sizeof(struct PlayerRecordsEmerald), which); ReceiveBattleTowerData(&sReceivedRecords->emerald.battleTowerRecord, sizeof(struct PlayerRecordsEmerald), which);
ReceiveGiftItem(&sReceivedRecords->emerald.giftItem, which); ReceiveGiftItem(&sReceivedRecords->emerald.giftItem, which);

View File

@ -1972,7 +1972,7 @@ void TryPutTodaysRivalTrainerOnAir(void)
} }
} }
void sub_80EDC60(const u16 *words) void TryPutTrendWatcherOnAir(const u16 *words)
{ {
TVShow *show; TVShow *show;

View File

@ -108,7 +108,7 @@ static bool8 CheckFeebas(void)
if (Random() % 100 > 49) // 50% chance of encountering Feebas if (Random() % 100 > 49) // 50% chance of encountering Feebas
return FALSE; return FALSE;
FeebasSeedRng(gSaveBlock1Ptr->easyChatPairs[0].unk2); FeebasSeedRng(gSaveBlock1Ptr->dewfordTrends[0].rand);
for (i = 0; i != NUM_FEEBAS_SPOTS;) for (i = 0; i != NUM_FEEBAS_SPOTS;)
{ {
feebasSpots[i] = FeebasRandom() % 447; feebasSpots[i] = FeebasRandom() % 447;