More mauville_old_man clean up

This commit is contained in:
GriffinR 2021-10-18 14:40:04 -04:00
parent b31bddddca
commit 24b4e898ad
6 changed files with 184 additions and 155 deletions

View File

@ -1,63 +1,63 @@
@ Only contains a portion of the mauville_man text. The rest is in scripts/mauville_man.inc @ Only contains the text for the Mauville Man named Giddy. The rest is in scripts/mauville_man.inc
gText_SoPretty:: GiddyText_SoPretty::
.string " so pretty!$" .string " so pretty!$"
gText_SoDarling:: GiddyText_SoDarling::
.string " so darling!$" .string " so darling!$"
gText_SoRelaxed:: GiddyText_SoRelaxed::
.string " so relaxed!$" .string " so relaxed!$"
gText_SoSunny:: GiddyText_SoSunny::
.string " so sunny!$" .string " so sunny!$"
gText_SoDesirable:: GiddyText_SoDesirable::
.string " so desirable!$" .string " so desirable!$"
gText_SoExciting:: GiddyText_SoExciting::
.string " so exciting!$" .string " so exciting!$"
gText_SoAmusing:: GiddyText_SoAmusing::
.string " so amusing!$" .string " so amusing!$"
gText_SoMagical:: GiddyText_SoMagical::
.string " so magical!$" .string " so magical!$"
gOtherText_Is:: GiddyText_Is::
.string " is$" .string " is$"
gOtherText_DontYouAgree:: GiddyText_DontYouAgree::
.string "\n" .string "\n"
.string "Don't you agree?$" .string "Don't you agree?$"
gMauvilleManText_ISoWantToGoOnAVacation:: GiddyText_ISoWantToGoOnAVacation::
.string "I so want to go on a vacation.\n" .string "I so want to go on a vacation.\n"
.string "Would you happen to know a nice place?$" .string "Would you happen to know a nice place?$"
gMauvilleManText_IBoughtCrayonsWith120Colors:: GiddyText_IBoughtCrayonsWith120Colors::
.string "I bought crayons with 120 colors!\n" .string "I bought crayons with 120 colors!\n"
.string "Don't you think that's nice?$" .string "Don't you think that's nice?$"
gMauvilleManText_WouldntItBeNiceIfWeCouldFloat:: GiddyText_WouldntItBeNiceIfWeCouldFloat::
.string "Wouldn't it be nice if we could float\n" .string "Wouldn't it be nice if we could float\n"
.string "away on a cloud of bubbles?$" .string "away on a cloud of bubbles?$"
gMauvilleManText_WhenYouWriteOnASandyBeach:: GiddyText_WhenYouWriteOnASandyBeach::
.string "When you write on a sandy beach,\n" .string "When you write on a sandy beach,\n"
.string "they wash away. It makes me sad.$" .string "they wash away. It makes me sad.$"
gMauvilleManText_WhatsTheBottomOfTheSeaLike:: GiddyText_WhatsTheBottomOfTheSeaLike::
.string "What's the bottom of the sea like?\n" .string "What's the bottom of the sea like?\n"
.string "Just once I would so love to go!$" .string "Just once I would so love to go!$"
gMauvilleManText_WhenYouSeeTheSettingSunDoesIt:: GiddyText_WhenYouSeeTheSettingSunDoesIt::
.string "When you see the setting sun, does it\n" .string "When you see the setting sun, does it\n"
.string "make you want to go home?$" .string "make you want to go home?$"
gMauvilleManText_LyingBackInTheGreenGrass:: GiddyText_LyingBackInTheGreenGrass::
.string "Lying back in the green grass…\n" .string "Lying back in the green grass…\n"
.string "Oh, it's so, so nice!$" .string "Oh, it's so, so nice!$"
gMauvilleManText_SecretBasesAreSoWonderful:: GiddyText_SecretBasesAreSoWonderful::
.string "SECRET BASES are so wonderful!\n" .string "SECRET BASES are so wonderful!\n"
.string "Can't you feel the excitement?$" .string "Can't you feel the excitement?$"

View File

@ -52,7 +52,7 @@
#define CHAR_LV 0x34 #define CHAR_LV 0x34
#define CHAR_EQUALS 0x35 #define CHAR_EQUALS 0x35
#define CHAR_SEMICOLON 0x36 #define CHAR_SEMICOLON 0x36
// #define CHAR_BARD_WORD_DELIMIT 0x37 // Empty space to separate words in Bard's song
#define CHAR_INV_QUESTION_MARK 0x51 #define CHAR_INV_QUESTION_MARK 0x51
#define CHAR_INV_EXCL_MARK 0x52 #define CHAR_INV_EXCL_MARK 0x52
#define CHAR_PK 0x53 #define CHAR_PK 0x53

View File

@ -96,6 +96,7 @@
#define NUM_STORYTELLER_TALES 4 #define NUM_STORYTELLER_TALES 4
#define NUM_TRADER_ITEMS 4 #define NUM_TRADER_ITEMS 4
#define GIDDY_MAX_TALES 10 #define GIDDY_MAX_TALES 10
#define GIDDY_MAX_QUESTIONS 8
#define OPTIONS_BUTTON_MODE_NORMAL 0 #define OPTIONS_BUTTON_MODE_NORMAL 0
#define OPTIONS_BUTTON_MODE_LR 1 #define OPTIONS_BUTTON_MODE_LR 1

View File

@ -382,27 +382,27 @@ extern const u8 EventScript_UseRockSmash[];
extern const u8 LittlerootTown_BrendansHouse_2F_EventScript_TurnOffPlayerPC[]; extern const u8 LittlerootTown_BrendansHouse_2F_EventScript_TurnOffPlayerPC[];
extern const u8 LittlerootTown_MaysHouse_2F_EventScript_TurnOffPlayerPC[]; extern const u8 LittlerootTown_MaysHouse_2F_EventScript_TurnOffPlayerPC[];
//mauville_old_man // Mauville Old Man (Giddy)
extern const u8 gOtherText_Is[]; extern const u8 GiddyText_Is[];
extern const u8 gOtherText_DontYouAgree[]; extern const u8 GiddyText_DontYouAgree[];
extern const u8 gText_SoPretty[]; extern const u8 GiddyText_SoPretty[];
extern const u8 gText_SoDarling[]; extern const u8 GiddyText_SoDarling[];
extern const u8 gText_SoRelaxed[]; extern const u8 GiddyText_SoRelaxed[];
extern const u8 gText_SoSunny[]; extern const u8 GiddyText_SoSunny[];
extern const u8 gText_SoDesirable[]; extern const u8 GiddyText_SoDesirable[];
extern const u8 gText_SoExciting[]; extern const u8 GiddyText_SoExciting[];
extern const u8 gText_SoAmusing[]; extern const u8 GiddyText_SoAmusing[];
extern const u8 gText_SoMagical[]; extern const u8 GiddyText_SoMagical[];
extern const u8 gMauvilleManText_ISoWantToGoOnAVacation[]; extern const u8 GiddyText_ISoWantToGoOnAVacation[];
extern const u8 gMauvilleManText_IBoughtCrayonsWith120Colors[]; extern const u8 GiddyText_IBoughtCrayonsWith120Colors[];
extern const u8 gMauvilleManText_WouldntItBeNiceIfWeCouldFloat[]; extern const u8 GiddyText_WouldntItBeNiceIfWeCouldFloat[];
extern const u8 gMauvilleManText_WhenYouWriteOnASandyBeach[]; extern const u8 GiddyText_WhenYouWriteOnASandyBeach[];
extern const u8 gMauvilleManText_WhatsTheBottomOfTheSeaLike[]; extern const u8 GiddyText_WhatsTheBottomOfTheSeaLike[];
extern const u8 gMauvilleManText_WhenYouSeeTheSettingSunDoesIt[]; extern const u8 GiddyText_WhenYouSeeTheSettingSunDoesIt[];
extern const u8 gMauvilleManText_LyingBackInTheGreenGrass[]; extern const u8 GiddyText_LyingBackInTheGreenGrass[];
extern const u8 gMauvilleManText_SecretBasesAreSoWonderful[]; extern const u8 GiddyText_SecretBasesAreSoWonderful[];
// mauville old man storyteller // Mauville Old Man (storyteller)
extern const u8 MauvilleCity_PokemonCenter_1F_Text_SavedGameTitle[]; extern const u8 MauvilleCity_PokemonCenter_1F_Text_SavedGameTitle[];
extern const u8 MauvilleCity_PokemonCenter_1F_Text_SavedGameAction[]; extern const u8 MauvilleCity_PokemonCenter_1F_Text_SavedGameAction[];
extern const u8 MauvilleCity_PokemonCenter_1F_Text_SavedGameStory[]; extern const u8 MauvilleCity_PokemonCenter_1F_Text_SavedGameStory[];

View File

@ -640,7 +640,7 @@ struct MauvilleManGiddy
/*0x01*/ u8 taleCounter; /*0x01*/ u8 taleCounter;
/*0x02*/ u8 questionNum; /*0x02*/ u8 questionNum;
/*0x04*/ u16 randomWords[GIDDY_MAX_TALES]; /*0x04*/ u16 randomWords[GIDDY_MAX_TALES];
/*0x18*/ u8 questionList[8]; /*0x18*/ u8 questionList[GIDDY_MAX_QUESTIONS];
/*0x20*/ u8 language; /*0x20*/ u8 language;
}; /*size = 0x2C*/ }; /*size = 0x2C*/

View File

@ -24,8 +24,6 @@
#include "m4a.h" #include "m4a.h"
#include "constants/mauville_old_man.h" #include "constants/mauville_old_man.h"
#define CHAR_SONG_WORD_SEPARATOR 0x37
static void InitGiddyTaleList(void); static void InitGiddyTaleList(void);
static void StartBardSong(bool8 useTemporaryLyrics); static void StartBardSong(bool8 useTemporaryLyrics);
static void Task_BardSong(u8 taskId); static void Task_BardSong(u8 taskId);
@ -50,25 +48,28 @@ static const u16 sDefaultBardSongLyrics[BARD_SONG_LENGTH] = {
}; };
static const u8 * const sGiddyAdjectives[] = { static const u8 * const sGiddyAdjectives[] = {
gText_SoPretty, GiddyText_SoPretty,
gText_SoDarling, GiddyText_SoDarling,
gText_SoRelaxed, GiddyText_SoRelaxed,
gText_SoSunny, GiddyText_SoSunny,
gText_SoDesirable, GiddyText_SoDesirable,
gText_SoExciting, GiddyText_SoExciting,
gText_SoAmusing, GiddyText_SoAmusing,
gText_SoMagical GiddyText_SoMagical
}; };
static const u8 * const sGiddyQuestions[] = { // Non-random lines Giddy can say. Not all are strictly
gMauvilleManText_ISoWantToGoOnAVacation, // questions, but most are, and the player will receive
gMauvilleManText_IBoughtCrayonsWith120Colors, // a Yes/No prompt afterwards regardless.
gMauvilleManText_WouldntItBeNiceIfWeCouldFloat, static const u8 * const sGiddyQuestions[GIDDY_MAX_QUESTIONS] = {
gMauvilleManText_WhenYouWriteOnASandyBeach, GiddyText_ISoWantToGoOnAVacation,
gMauvilleManText_WhatsTheBottomOfTheSeaLike, GiddyText_IBoughtCrayonsWith120Colors,
gMauvilleManText_WhenYouSeeTheSettingSunDoesIt, GiddyText_WouldntItBeNiceIfWeCouldFloat,
gMauvilleManText_LyingBackInTheGreenGrass, GiddyText_WhenYouWriteOnASandyBeach,
gMauvilleManText_SecretBasesAreSoWonderful GiddyText_WhatsTheBottomOfTheSeaLike,
GiddyText_WhenYouSeeTheSettingSunDoesIt,
GiddyText_LyingBackInTheGreenGrass,
GiddyText_SecretBasesAreSoWonderful
}; };
static void SetupBard(void) static void SetupBard(void)
@ -185,7 +186,7 @@ static void PrepareSongText(void)
while (wordEnd != str) while (wordEnd != str)
{ {
if (*str == CHAR_SPACE) if (*str == CHAR_SPACE)
*str = CHAR_SONG_WORD_SEPARATOR; *str = CHAR_BARD_WORD_DELIMIT;
str++; str++;
} }
@ -196,7 +197,7 @@ static void PrepareSongText(void)
while (wordEnd != str) while (wordEnd != str)
{ {
if (*str == CHAR_SPACE) if (*str == CHAR_SPACE)
*str = CHAR_SONG_WORD_SEPARATOR; *str = CHAR_BARD_WORD_DELIMIT;
str++; str++;
} }
@ -207,7 +208,7 @@ static void PrepareSongText(void)
while (wordEnd != str) while (wordEnd != str)
{ {
if (*str == CHAR_SPACE) if (*str == CHAR_SPACE)
*str = CHAR_SONG_WORD_SEPARATOR; *str = CHAR_BARD_WORD_DELIMIT;
str++; str++;
} }
@ -272,22 +273,26 @@ void GenerateGiddyLine(void)
if (giddy->taleCounter == 0) if (giddy->taleCounter == 0)
InitGiddyTaleList(); InitGiddyTaleList();
// A line from Giddy is either a line following this format:
// "{random word} is so {adjective}! Don't you agree?",
// or one of the texts in sGiddyQuestions.
if (giddy->randomWords[giddy->taleCounter] != EC_EMPTY_WORD) if (giddy->randomWords[giddy->taleCounter] != EC_EMPTY_WORD)
{ {
u8 *stringPtr; u8 *stringPtr;
u32 adjective = Random(); u32 adjective = Random();
adjective %= ARRAY_COUNT(sGiddyAdjectives);
adjective %= 8;
stringPtr = CopyEasyChatWord(gStringVar4, giddy->randomWords[giddy->taleCounter]); stringPtr = CopyEasyChatWord(gStringVar4, giddy->randomWords[giddy->taleCounter]);
stringPtr = StringCopy(stringPtr, gOtherText_Is); stringPtr = StringCopy(stringPtr, GiddyText_Is);
stringPtr = StringCopy(stringPtr, sGiddyAdjectives[adjective]); stringPtr = StringCopy(stringPtr, sGiddyAdjectives[adjective]);
StringCopy(stringPtr, gOtherText_DontYouAgree); StringCopy(stringPtr, GiddyText_DontYouAgree);
} }
else else
{ {
StringCopy(gStringVar4, sGiddyQuestions[giddy->questionList[giddy->questionNum++]]); StringCopy(gStringVar4, sGiddyQuestions[giddy->questionList[giddy->questionNum++]]);
} }
// 10% chance for Giddy to stop telling tales.
if (!(Random() % 10)) if (!(Random() % 10))
giddy->taleCounter = GIDDY_MAX_TALES; giddy->taleCounter = GIDDY_MAX_TALES;
else else
@ -308,45 +313,53 @@ static void InitGiddyTaleList(void)
{EC_GROUP_POKEMON_NATIONAL, 0} {EC_GROUP_POKEMON_NATIONAL, 0}
}; };
u16 i; u16 i;
u16 r10; u16 totalWords;
u16 r7; u16 temp;
u16 r1; u16 var; // re-used
// Shuffle question list // Shuffle question list
for (i = 0; i < 8; i++) for (i = 0; i < GIDDY_MAX_QUESTIONS; i++)
giddy->questionList[i] = i; giddy->questionList[i] = i;
for (i = 0; i < 8; i++) for (i = 0; i < GIDDY_MAX_QUESTIONS; i++)
{ {
r1 = Random() % (i + 1); var = Random() % (i + 1);
SWAP(giddy->questionList[i], giddy->questionList[r1], r7); SWAP(giddy->questionList[i], giddy->questionList[var], temp);
} }
r10 = 0; // Count total number of words in above word groups
for (i = 0; i < 6; i++) totalWords = 0;
for (i = 0; i < ARRAY_COUNT(wordGroupsAndCount); i++)
{ {
wordGroupsAndCount[i][1] = EasyChat_GetNumWordsInGroup(wordGroupsAndCount[i][0]); wordGroupsAndCount[i][1] = EasyChat_GetNumWordsInGroup(wordGroupsAndCount[i][0]);
r10 += wordGroupsAndCount[i][1]; totalWords += wordGroupsAndCount[i][1];
} }
giddy->questionNum = 0; giddy->questionNum = 0;
r7 = 0; temp = 0;
for (i = 0; i < GIDDY_MAX_TALES; i++) for (i = 0; i < GIDDY_MAX_TALES; i++)
{ {
r1 = Random() % 10; var = Random() % 10;
if (r1 < 3 && r7 < 8) if (var < 3 && temp < GIDDY_MAX_QUESTIONS)
{ {
// 30% chance for word to be empty (in which case Giddy
// will say one of his non-random questions), unless
// the limit for questions has been reached already.
giddy->randomWords[i] = EC_EMPTY_WORD; giddy->randomWords[i] = EC_EMPTY_WORD;
r7++; temp++;
} }
else else
{ {
s16 r2 = Random() % r10; // Pick a random word id, then advance through the word
for (r1 = 0; i < 6; r1++) // groups until the group where that id landed.
if ((r2 -= wordGroupsAndCount[r1][1]) <= 0) s16 randWord = Random() % totalWords;
for (var = 0; i < ARRAY_COUNT(wordGroupsAndCount); var++)
if ((randWord -= wordGroupsAndCount[var][1]) <= 0)
break; break;
if (r1 == 6) if (var == ARRAY_COUNT(wordGroupsAndCount))
r1 = 0; var = 0;
giddy->randomWords[i] = GetRandomEasyChatWordFromUnlockedGroup(wordGroupsAndCount[r1][0]);
// Save the randomly selected word
giddy->randomWords[i] = GetRandomEasyChatWordFromUnlockedGroup(wordGroupsAndCount[var][0]);
} }
} }
} }
@ -392,10 +405,23 @@ void ResetMauvilleOldManFlag(void)
SetMauvilleOldManObjEventGfx(); SetMauvilleOldManObjEventGfx();
} }
// States and task data for Task_BardSong.
// The function BardSing receives this task as an
// argument and reads its state as well.
enum {
BARD_STATE_INIT,
BARD_STATE_WAIT_BGM,
BARD_STATE_GET_WORD,
BARD_STATE_HANDLE_WORD,
BARD_STATE_WAIT_WORD,
BARD_STATE_PAUSE,
};
#define tState data[0] #define tState data[0]
#define tCharIndex data[3] #define tWordState data[1]
#define tCurrWord data[4] #define tDelay data[2]
#define tCharIndex data[3]
#define tCurrWord data[4]
#define tUseTemporaryLyrics data[5] #define tUseTemporaryLyrics data[5]
#define MACRO1(a) (((a) & 3) + (((a) / 8) & 1)) #define MACRO1(a) (((a) & 3) + (((a) / 8) & 1))
@ -418,7 +444,7 @@ static void DisableTextPrinters(struct TextPrinterTemplate * printer, u16 a1)
gDisableTextPrinters = TRUE; gDisableTextPrinters = TRUE;
} }
static void sub_8120708(const u8 * str) static void DrawSongTextWindow(const u8 * str)
{ {
DrawDialogueFrame(0, 0); DrawDialogueFrame(0, 0);
AddTextPrinterParameterized(0, 1, str, 0, 1, 1, DisableTextPrinters); AddTextPrinterParameterized(0, 1, str, 0, 1, 1, DisableTextPrinters);
@ -430,7 +456,7 @@ static void BardSing(struct Task *task, struct BardSong *song)
{ {
switch (task->tState) switch (task->tState)
{ {
case 0: // Initialize song case BARD_STATE_INIT:
{ {
struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard; struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
u16 *lyrics; u16 *lyrics;
@ -446,9 +472,9 @@ static void BardSing(struct Task *task, struct BardSong *song)
song->currWord = 0; song->currWord = 0;
} }
break; break;
case 1: // Wait for BGM to end case BARD_STATE_WAIT_BGM:
break; break;
case 2: // Initialize word case BARD_STATE_GET_WORD:
{ {
u16 word = song->lyrics[song->currWord]; u16 word = song->lyrics[song->currWord];
song->sound = GetWordSounds(word); song->sound = GetWordSounds(word);
@ -463,8 +489,8 @@ static void BardSing(struct Task *task, struct BardSong *song)
} }
break; break;
} }
case 3: case BARD_STATE_HANDLE_WORD:
case 4: case BARD_STATE_WAIT_WORD:
{ {
const struct BardSound *sound = &song->sound[song->currPhoneme]; const struct BardSound *sound = &song->sound[song->currPhoneme];
@ -524,7 +550,7 @@ static void BardSing(struct Task *task, struct BardSong *song)
} }
} }
break; break;
case 5: case BARD_STATE_PAUSE:
break; break;
} }
} }
@ -534,28 +560,30 @@ static void Task_BardSong(u8 taskId)
struct Task *task = &gTasks[taskId]; struct Task *task = &gTasks[taskId];
BardSing(task, &gBardSong); BardSing(task, &gBardSong);
switch (task->tState) switch (task->tState)
{ {
case 0: // Initialize song case BARD_STATE_INIT:
PrepareSongText(); PrepareSongText();
sub_8120708(gStringVar4); DrawSongTextWindow(gStringVar4);
task->data[1] = 0; task->tWordState = 0;
task->data[2] = 0; task->tDelay = 0;
task->tCharIndex = 0; task->tCharIndex = 0;
task->tCurrWord = 0; task->tCurrWord = 0;
FadeOutBGMTemporarily(4); FadeOutBGMTemporarily(4);
task->tState = 1; task->tState = BARD_STATE_WAIT_BGM;
break; break;
case 1: // Wait for BGM to end case BARD_STATE_WAIT_BGM:
if (IsBGMPausedOrStopped()) if (IsBGMPausedOrStopped())
task->tState = 2; task->tState = BARD_STATE_GET_WORD;
break; break;
case 2: // Initialize word case BARD_STATE_GET_WORD:
{ {
struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard; struct MauvilleManBard *bard = &gSaveBlock1Ptr->oldMan.bard;
u8 *str = gStringVar4 + task->tCharIndex; u8 *str = &gStringVar4[task->tCharIndex];
u16 wordLen = 0; u16 wordLen = 0;
// Read letters until delimiter
while (*str != CHAR_SPACE while (*str != CHAR_SPACE
&& *str != CHAR_NEWLINE && *str != CHAR_NEWLINE
&& *str != EXT_CTRL_CODE_BEGIN && *str != EXT_CTRL_CODE_BEGIN
@ -564,6 +592,7 @@ static void Task_BardSong(u8 taskId)
str++; str++;
wordLen++; wordLen++;
} }
if (!task->tUseTemporaryLyrics) if (!task->tUseTemporaryLyrics)
sUnknownBardRelated = MACRO2(bard->songLyrics[task->tCurrWord]); sUnknownBardRelated = MACRO2(bard->songLyrics[task->tCurrWord]);
else else
@ -574,27 +603,29 @@ static void Task_BardSong(u8 taskId)
gBardSong.length = 1; gBardSong.length = 1;
task->tCurrWord++; task->tCurrWord++;
if (task->data[2] == 0) if (task->tDelay == 0)
{ {
task->tState = 3; task->tState = BARD_STATE_HANDLE_WORD;
task->data[1] = 0; task->tWordState = 0;
} }
else else
{ {
task->tState = 5; task->tState = BARD_STATE_PAUSE;
task->data[1] = 0; task->tWordState = 0;
} }
} }
break; break;
case 5: case BARD_STATE_PAUSE:
if (task->data[2] == 0) // Wait before singing next word
task->tState = 3; if (task->tDelay == 0)
task->tState = BARD_STATE_HANDLE_WORD;
else else
task->data[2]--; task->tDelay--;
break; break;
case 3: case BARD_STATE_HANDLE_WORD:
if (gStringVar4[task->tCharIndex] == EOS) if (gStringVar4[task->tCharIndex] == EOS)
{ {
// End song
FadeInBGM(6); FadeInBGM(6);
m4aMPlayFadeOutTemporarily(&gMPlayInfo_SE2, 2); m4aMPlayFadeOutTemporarily(&gMPlayInfo_SE2, 2);
EnableBothScriptContexts(); EnableBothScriptContexts();
@ -602,55 +633,61 @@ static void Task_BardSong(u8 taskId)
} }
else if (gStringVar4[task->tCharIndex] == CHAR_SPACE) else if (gStringVar4[task->tCharIndex] == CHAR_SPACE)
{ {
// Handle space
EnableTextPrinters(); EnableTextPrinters();
task->tCharIndex++; task->tCharIndex++;
task->tState = 2; task->tState = BARD_STATE_GET_WORD;
task->data[2] = 0; task->tDelay = 0;
} }
else if (gStringVar4[task->tCharIndex] == CHAR_NEWLINE) else if (gStringVar4[task->tCharIndex] == CHAR_NEWLINE)
{ {
// Handle newline
task->tCharIndex++; task->tCharIndex++;
task->tState = 2; task->tState = BARD_STATE_GET_WORD;
task->data[2] = 0; task->tDelay = 0;
} }
else if (gStringVar4[task->tCharIndex] == EXT_CTRL_CODE_BEGIN) else if (gStringVar4[task->tCharIndex] == EXT_CTRL_CODE_BEGIN)
{ {
// Handle ctrl code
task->tCharIndex += 2; // skip over control codes task->tCharIndex += 2; // skip over control codes
task->tState = 2; task->tState = BARD_STATE_GET_WORD;
task->data[2] = 8; task->tDelay = 8;
} }
else if (gStringVar4[task->tCharIndex] == CHAR_SONG_WORD_SEPARATOR) else if (gStringVar4[task->tCharIndex] == CHAR_BARD_WORD_DELIMIT)
{ {
gStringVar4[task->tCharIndex] = CHAR_SPACE; // restore it back to a space // Handle word boundary
gStringVar4[task->tCharIndex] = CHAR_SPACE; // Replace with a real space
EnableTextPrinters(); EnableTextPrinters();
task->tCharIndex++; task->tCharIndex++;
task->data[2] = 0; task->tDelay = 0;
} }
else else
{ {
switch (task->data[1]) // Handle regular word
switch (task->tWordState)
{ {
case 0: case 0:
EnableTextPrinters(); EnableTextPrinters();
task->data[1]++; task->tWordState++;
break; break;
case 1: case 1:
task->data[1]++; task->tWordState++;
break; break;
case 2: case 2:
task->tCharIndex++; task->tCharIndex++;
task->data[1] = 0; task->tWordState = 0;
task->data[2] = gBardSong.length; task->tDelay = gBardSong.length;
task->tState = 4; task->tState = BARD_STATE_WAIT_WORD;
break; break;
} }
} }
break; break;
case 4: case BARD_STATE_WAIT_WORD:
task->data[2]--; // Wait for word to finish being sung.
if (task->data[2] == 0) // BardSing will continue to play it.
task->tState = 3; task->tDelay--;
if (task->tDelay == 0)
task->tState = BARD_STATE_HANDLE_WORD;
break; break;
} }
RunTextPrintersAndIsPrinter0Active(); RunTextPrintersAndIsPrinter0Active();
@ -1107,6 +1144,9 @@ static const struct Story sStorytellerStories[] = {
} }
}; };
static const s32 sNumStories = ARRAY_COUNT(sStorytellerStories);
static const u32 sUnused = 8;
static void StorytellerSetup(void) static void StorytellerSetup(void)
{ {
s32 i; s32 i;
@ -1140,12 +1180,12 @@ static const struct Story *GetStoryByStat(u32 stat)
{ {
s32 i; s32 i;
for (i = 0; i < (int)ARRAY_COUNT(sStorytellerStories); i++) for (i = 0; i < sNumStories; i++)
{ {
if (sStorytellerStories[i].stat == stat) if (sStorytellerStories[i].stat == stat)
return &sStorytellerStories[i]; return &sStorytellerStories[i];
} }
return &sStorytellerStories[ARRAY_COUNT(sStorytellerStories) - 1]; return &sStorytellerStories[sNumStories - 1];
} }
static const u8 *GetStoryTitleByStat(u32 stat) static const u8 *GetStoryTitleByStat(u32 stat)
@ -1241,28 +1281,16 @@ static void ScrambleStatList(u8 * arr, s32 count)
} }
} }
struct UnknownStruct_0859F288
{
s32 length;
u32 unused2;
};
static const struct UnknownStruct_0859F288 sStorytellerStuff = {
ARRAY_COUNT(sStorytellerStories),
sizeof(sStorytellerStuff)
};
static bool8 StorytellerInitializeRandomStat(void) static bool8 StorytellerInitializeRandomStat(void)
{ {
u8 arr[sStorytellerStuff.length]; u8 storyIds[sNumStories];
s32 i; s32 i, j;
s32 j;
ScrambleStatList(arr, ARRAY_COUNT(sStorytellerStories)); ScrambleStatList(storyIds, sNumStories);
for (i = 0; i < (s32)ARRAY_COUNT(sStorytellerStories); i++) for (i = 0; i < sNumStories; i++)
{ {
u8 stat = sStorytellerStories[arr[i]].stat; u8 stat = sStorytellerStories[storyIds[i]].stat;
u8 minVal = sStorytellerStories[arr[i]].minVal; u8 minVal = sStorytellerStories[storyIds[i]].minVal;
for (j = 0; j < NUM_STORYTELLER_TALES; j++) for (j = 0; j < NUM_STORYTELLER_TALES; j++)
{ {