pokeemerald/src/apprentice.c

1311 lines
42 KiB
C
Raw Normal View History

2018-10-13 00:48:26 +02:00
#include "global.h"
#include "apprentice.h"
#include "battle.h"
2018-10-14 16:26:13 +02:00
#include "battle_tower.h"
2019-04-04 23:53:06 +02:00
#include "data.h"
2018-10-14 16:26:13 +02:00
#include "event_data.h"
#include "event_object_movement.h"
#include "field_player_avatar.h"
#include "international_string_util.h"
#include "item.h"
#include "item_menu.h"
2018-10-13 00:48:26 +02:00
#include "main.h"
#include "malloc.h"
#include "menu.h"
2018-10-14 16:26:13 +02:00
#include "new_game.h"
#include "party_menu.h"
2018-10-14 16:26:13 +02:00
#include "random.h"
#include "script.h"
#include "script_menu.h"
2018-10-13 23:23:33 +02:00
#include "sound.h"
2018-10-14 16:26:13 +02:00
#include "string_util.h"
#include "strings.h"
#include "task.h"
#include "text.h"
2019-11-15 00:56:18 +01:00
#include "constants/battle_frontier.h"
#include "constants/items.h"
2018-10-13 23:23:33 +02:00
#include "constants/songs.h"
2019-11-15 00:56:18 +01:00
#include "constants/trainers.h"
2018-10-14 17:00:41 +02:00
#include "constants/moves.h"
2018-10-13 00:48:26 +02:00
/* Summary of Apprentice, because (as of writing at least) it's not very well documented online
2019-11-21 01:00:08 +01:00
*
* ## Basic info
* In the Battle Tower lobby there is an NPC which asks to be taught by the player
* They can be any 1 of 16 NPC trainers, each with their own name, class, and set of possible party species
* They ask the player a series of questions once per day, and eventually depart the lobby to be replaced by a new Apprentice
*
* ## Initial Questions
* The first question they always ask is a request to be taught, which cannot be rejected
* The second question (which follows immediately after) is whether they should participate in Battle Tower Lv 50 or Open Lv
* After these opening questions they always ask the player to choose between 2 mons, which they repeat 3 times
*
* ## Random Questions
* After choosing 3 mons for them, the Apprentice will randomly ask between 1 and 8 questions of 4 different types, as follows
* - Asking which mon to lead with, which they will only ask at most once
* - Asking which move a mon should use, which they will ask at most 5 times
* - Asking what held item to give to a mon, which they will ask at most 3 times (once for each mon)
* - Asking what they should say when they win a battle, which will always be their final question before departing
2019-11-29 21:47:31 +01:00
*
2019-11-21 01:00:08 +01:00
* ## After departing
* After telling them what they should say when they win a battle they will leave the lobby for a final time
* They will then be replaced by a new random Apprentice (they can repeat)
* Up to 4 old Apprentices are saved and can be encountered (or partnered with) during challenges of the mode they were told to battle in
* They can also be record mixed to and from other Emerald games
* Old/record mixed Apprentices are stored in struct Apprentice apprentices of SaveBlock2
* and the current Apprentice is stored in struct PlayersApprentice playerApprentice of SaveBlock2
*/
2018-10-14 16:27:48 +02:00
#define PLAYER_APPRENTICE gSaveBlock2Ptr->playerApprentice
2019-11-20 23:36:52 +01:00
#define CURRENT_QUESTION_NUM PLAYER_APPRENTICE.questionsAnswered - NUM_WHICH_MON_QUESTIONS
2018-10-14 16:27:48 +02:00
2019-11-20 23:36:52 +01:00
struct ApprenticePartyMovesData
2018-10-13 00:48:26 +02:00
{
2019-11-20 23:36:52 +01:00
u8 moveCounter;
u16 moves[MULTI_PARTY_SIZE][NUM_WHICH_MOVE_QUESTIONS];
u8 moveSlots[MULTI_PARTY_SIZE][NUM_WHICH_MOVE_QUESTIONS];
};
2019-11-20 23:36:52 +01:00
struct ApprenticeQuestionData
{
2019-11-20 23:36:52 +01:00
u16 speciesId;
u16 altSpeciesId;
u16 moveId1;
u16 moveId2;
2018-10-13 00:48:26 +02:00
};
// IWRAM common
2019-11-20 23:36:52 +01:00
struct ApprenticePartyMovesData *gApprenticePartyMovesData;
struct ApprenticeQuestionData *gApprenticeQuestionData;
void (*gApprenticeFunc)(void);
2018-10-14 11:37:44 +02:00
2018-10-14 17:00:41 +02:00
// This file's functions.
2019-11-20 23:36:52 +01:00
static u16 GetRandomAlternateMove(u8 monId);
static bool8 TrySetMove(u8 monId, u16 moveId);
2018-10-14 17:00:41 +02:00
static void CreateChooseAnswerTask(bool8 noBButton, u8 itemsCount, u8 windowId);
static u8 CreateAndShowWindow(u8 left, u8 top, u8 width, u8 height);
static void RemoveAndHideWindow(u8 windowId);
static void ExecuteFuncAfterButtonPress(void (*func)(void));
2019-11-15 00:56:18 +01:00
static void Script_GivenApprenticeLvlMode(void);
static void Script_SetApprenticeLvlMode(void);
2019-11-19 17:36:38 +01:00
static void Script_SetApprenticeId(void);
2019-11-20 23:36:52 +01:00
static void ShuffleApprenticeSpecies(void);
static void Script_SetRandomQuestionData(void);
2019-11-19 17:36:38 +01:00
static void IncrementQuestionsAnswered(void);
2019-11-20 23:36:52 +01:00
static void IsFinalQuestion(void);
2018-10-14 17:00:41 +02:00
static void Script_CreateApprenticeMenu(void);
2019-11-15 00:56:18 +01:00
static void Script_PrintApprenticeMessage(void);
2018-10-14 17:00:41 +02:00
static void Script_ResetPlayerApprentice(void);
2019-11-19 17:36:38 +01:00
static void GetShouldCheckApprenticeGone(void);
static void ApprenticeGetQuestion(void);
2019-11-20 23:36:52 +01:00
static void GetNumApprenticePartyMonsAssigned(void);
2019-11-19 17:36:38 +01:00
static void SetApprenticePartyMon(void);
2019-11-21 01:00:08 +01:00
static void InitQuestionData(void);
static void FreeQuestionData(void);
2019-11-15 00:56:18 +01:00
static void ApprenticeBufferString(void);
2019-11-19 17:36:38 +01:00
static void SetApprenticeMonMove(void);
2019-11-20 23:36:52 +01:00
static void SetLeadApprenticeMon(void);
2019-11-19 17:36:38 +01:00
static void Script_ApprenticeOpenBagMenu(void);
2019-11-20 23:36:52 +01:00
static void TrySetApprenticeHeldItem(void);
static void SaveApprentice(void);
2019-11-19 17:36:38 +01:00
static void SetSavedApprenticeTrainerGfxId(void);
static void SetPlayerApprenticeTrainerGfxId(void);
2019-11-15 00:56:18 +01:00
static void GetShouldApprenticeLeave(void);
2019-11-20 23:36:52 +01:00
static void ShiftSavedApprentices(void);
2018-10-14 16:26:13 +02:00
2019-11-21 01:04:25 +01:00
#include "data/battle_frontier/apprentice.h"
2018-10-13 00:48:26 +02:00
2019-11-20 23:36:52 +01:00
void BufferApprenticeChallengeText(u8 saveApprenticeId)
2018-10-13 00:48:26 +02:00
{
2019-11-19 17:36:38 +01:00
u8 i, num;
2019-11-21 01:00:08 +01:00
const u8 *challengeText;
2018-10-13 00:48:26 +02:00
2019-11-20 23:36:52 +01:00
num = gSaveBlock2Ptr->apprentices[saveApprenticeId].number;
2019-11-19 17:36:38 +01:00
for (i = 0; num != 0 && i < APPRENTICE_COUNT; num /= 10, i++)
2018-10-14 14:35:51 +02:00
;
2018-10-13 00:48:26 +02:00
StringCopy_PlayerName(gStringVar1, gSaveBlock2Ptr->apprentices[saveApprenticeId].playerName);
2019-11-20 23:36:52 +01:00
ConvertInternationalString(gStringVar1, gSaveBlock2Ptr->apprentices[saveApprenticeId].language);
ConvertIntToDecimalStringN(gStringVar2, gSaveBlock2Ptr->apprentices[saveApprenticeId].number, STR_CONV_MODE_RIGHT_ALIGN, i);
2019-11-21 01:00:08 +01:00
challengeText = sApprenticeChallengeTexts[gSaveBlock2Ptr->apprentices[saveApprenticeId].id];
StringExpandPlaceholders(gStringVar4, challengeText);
2018-10-13 00:48:26 +02:00
}
void Apprentice_ScriptContext_Enable(void)
2018-10-13 00:48:26 +02:00
{
ScriptContext_Enable();
2018-10-13 00:48:26 +02:00
}
2018-10-14 17:00:41 +02:00
void ResetApprenticeStruct(struct Apprentice *apprentice)
2018-10-13 00:48:26 +02:00
{
u8 i;
2019-11-19 17:36:38 +01:00
for (i = 0; i < ARRAY_COUNT(apprentice->speechWon); i++)
2021-02-22 18:12:35 +01:00
apprentice->speechWon[i] = EC_EMPTY_WORD;
2018-10-13 00:48:26 +02:00
apprentice->playerName[0] = EOS;
2019-11-15 00:56:18 +01:00
apprentice->id = NUM_APPRENTICES;
2018-10-13 00:48:26 +02:00
}
2018-10-14 17:00:41 +02:00
void ResetAllApprenticeData(void)
2018-10-13 00:48:26 +02:00
{
u8 i, j;
2019-11-21 01:00:08 +01:00
PLAYER_APPRENTICE.saveId = 0;
2019-11-15 00:56:18 +01:00
for (i = 0; i < APPRENTICE_COUNT; i++)
2018-10-13 00:48:26 +02:00
{
2019-11-19 17:36:38 +01:00
for (j = 0; j < ARRAY_COUNT(gSaveBlock2Ptr->apprentices[i].speechWon); j++)
2021-02-22 18:12:35 +01:00
gSaveBlock2Ptr->apprentices[i].speechWon[j] = EC_EMPTY_WORD;
2019-11-15 00:56:18 +01:00
gSaveBlock2Ptr->apprentices[i].id = NUM_APPRENTICES;
2018-10-14 14:35:51 +02:00
gSaveBlock2Ptr->apprentices[i].playerName[0] = EOS;
gSaveBlock2Ptr->apprentices[i].lvlMode = 0;
gSaveBlock2Ptr->apprentices[i].number = 0;
2019-11-20 23:36:52 +01:00
gSaveBlock2Ptr->apprentices[i].numQuestions = 0;
2019-09-08 17:53:48 +02:00
for (j = 0; j < TRAINER_ID_LENGTH; j++)
2018-10-14 14:35:51 +02:00
gSaveBlock2Ptr->apprentices[i].playerId[j] = 0;
gSaveBlock2Ptr->apprentices[i].language = gGameLanguage;
gSaveBlock2Ptr->apprentices[i].checksum = 0;
2018-10-13 00:48:26 +02:00
}
2018-10-14 17:00:41 +02:00
Script_ResetPlayerApprentice();
2018-10-13 00:48:26 +02:00
}
2019-11-19 17:36:38 +01:00
static bool8 GivenApprenticeLvlMode(void)
2018-10-13 00:48:26 +02:00
{
2019-11-15 00:56:18 +01:00
return (PLAYER_APPRENTICE.lvlMode != 0);
2018-10-13 00:48:26 +02:00
}
2019-11-19 17:36:38 +01:00
static void SetApprenticeId(void)
2018-10-13 00:48:26 +02:00
{
2018-10-14 14:35:51 +02:00
if (gSaveBlock2Ptr->apprentices[0].number == 0)
2018-10-13 00:48:26 +02:00
{
do
{
2019-11-19 17:36:38 +01:00
PLAYER_APPRENTICE.id = sInitialApprenticeIds[Random() % ARRAY_COUNT(sInitialApprenticeIds)];
2018-10-14 16:27:48 +02:00
} while (PLAYER_APPRENTICE.id == gSaveBlock2Ptr->apprentices[0].id);
2018-10-13 00:48:26 +02:00
}
else
{
do
{
2019-11-15 00:56:18 +01:00
PLAYER_APPRENTICE.id = Random() % (NUM_APPRENTICES);
2018-10-14 16:27:48 +02:00
} while (PLAYER_APPRENTICE.id == gSaveBlock2Ptr->apprentices[0].id);
2018-10-13 00:48:26 +02:00
}
}
2018-10-14 16:27:48 +02:00
static void SetPlayersApprenticeLvlMode(u8 mode)
2018-10-13 00:48:26 +02:00
{
2019-11-15 00:56:18 +01:00
PLAYER_APPRENTICE.lvlMode = mode;
2018-10-13 00:48:26 +02:00
}
2019-11-20 23:36:52 +01:00
static void ShuffleApprenticeSpecies(void)
2018-10-13 00:48:26 +02:00
{
2019-11-20 23:36:52 +01:00
u8 species[APPRENTICE_SPECIES_COUNT];
2018-10-13 00:48:26 +02:00
u8 i;
2019-11-20 23:36:52 +01:00
for (i = 0; i < ARRAY_COUNT(species); i++)
species[i] = i;
2018-10-13 00:48:26 +02:00
2019-11-20 23:36:52 +01:00
// Shuffle the possible species an arbitrary 50 times
2018-10-13 00:48:26 +02:00
for (i = 0; i < 50; i++)
{
u8 temp;
2019-11-20 23:36:52 +01:00
u8 rand1 = Random() % ARRAY_COUNT(species);
u8 rand2 = Random() % ARRAY_COUNT(species);
SWAP(species[rand1], species[rand2], temp);
2018-10-13 00:48:26 +02:00
}
2019-11-15 00:56:18 +01:00
for (i = 0; i < MULTI_PARTY_SIZE; i++)
2019-11-20 23:36:52 +01:00
PLAYER_APPRENTICE.speciesIds[i] = ((species[i * 2] & 0xF) << 4) | ((species[i * 2 + 1]) & 0xF);
2018-10-13 00:48:26 +02:00
}
2019-11-20 23:36:52 +01:00
// Pick one of the Apprentice's mons to ask the question about
// Picking a move chooses a random mon, picking a held item is sequential (so that none are repeated)
static u8 GetMonIdForQuestion(u8 questionId, u8 *party, u8 *partySlot)
2018-10-13 00:48:26 +02:00
{
u8 i, count;
2019-11-15 00:56:18 +01:00
u8 monId = 0;
2018-10-13 00:48:26 +02:00
2019-11-20 23:36:52 +01:00
if (questionId == QUESTION_ID_WHICH_MOVE)
2018-10-13 00:48:26 +02:00
{
do
{
2019-11-19 17:36:38 +01:00
monId = Random() % (MULTI_PARTY_SIZE);
2019-11-20 23:36:52 +01:00
for (count = 0, i = 0; i < NUM_WHICH_MOVE_QUESTIONS; i++)
2018-10-13 00:48:26 +02:00
{
2019-11-20 23:36:52 +01:00
if (gApprenticePartyMovesData->moves[monId][i] != MOVE_NONE)
2018-10-13 00:48:26 +02:00
count++;
}
2019-11-19 17:36:38 +01:00
} while (count > MULTI_PARTY_SIZE);
2018-10-13 00:48:26 +02:00
}
2019-11-20 23:36:52 +01:00
else if (questionId == QUESTION_ID_WHAT_ITEM)
2018-10-13 00:48:26 +02:00
{
2019-11-20 23:36:52 +01:00
monId = party[*partySlot];
(*partySlot)++;
2018-10-13 00:48:26 +02:00
}
2019-11-15 00:56:18 +01:00
return monId;
2018-10-13 00:48:26 +02:00
}
2019-11-20 23:36:52 +01:00
// Sets the random order and data for the remaining questions after the initial "choose mon" questions
static void SetRandomQuestionData(void)
{
2019-11-20 23:36:52 +01:00
u8 questionOrder[APPRENTICE_MAX_QUESTIONS + 1];
u8 partyOrder[MULTI_PARTY_SIZE];
u8 partySlot;
u8 i, j;
u8 rand1, rand2;
u8 id;
2019-11-20 23:36:52 +01:00
for (i = 0; i < ARRAY_COUNT(partyOrder); i++)
partyOrder[i] = i;
// Shuffle the party an arbitrary 10 times
for (i = 0; i < 10; i++)
{
u8 temp;
2019-11-20 23:36:52 +01:00
rand1 = Random() % ARRAY_COUNT(partyOrder);
rand2 = Random() % ARRAY_COUNT(partyOrder);
SWAP(partyOrder[rand1], partyOrder[rand2], temp);
}
2019-11-20 23:36:52 +01:00
for (i = 0; i < ARRAY_COUNT(questionOrder); i++)
questionOrder[i] = sQuestionPossibilities[i];
2019-11-29 21:47:31 +01:00
2019-11-20 23:36:52 +01:00
// Shuffle the questions an arbitrary 50 times
for (i = 0; i < 50; i++)
{
u8 temp;
2019-11-20 23:36:52 +01:00
rand1 = Random() % ARRAY_COUNT(questionOrder);
rand2 = Random() % ARRAY_COUNT(questionOrder);
SWAP(questionOrder[rand1], questionOrder[rand2], temp);
}
2019-11-20 23:36:52 +01:00
gApprenticePartyMovesData = AllocZeroed(sizeof(*gApprenticePartyMovesData));
gApprenticePartyMovesData->moveCounter = 0;
for (i = 0; i < NUM_WHICH_MOVE_QUESTIONS; i++)
{
2019-11-20 23:36:52 +01:00
for (j = 0; j < MULTI_PARTY_SIZE; j++)
gApprenticePartyMovesData->moveSlots[j][i] = MAX_MON_MOVES;
}
2019-11-20 23:36:52 +01:00
partySlot = 0;
for (i = 0; i < APPRENTICE_MAX_QUESTIONS; i++)
{
2019-11-20 23:36:52 +01:00
PLAYER_APPRENTICE.questions[i].questionId = questionOrder[i];
if (questionOrder[i] != QUESTION_ID_WHICH_FIRST)
{
2019-11-20 23:36:52 +01:00
PLAYER_APPRENTICE.questions[i].monId = GetMonIdForQuestion(questionOrder[i], partyOrder, &partySlot);
id = PLAYER_APPRENTICE.questions[i].monId;
if (questionOrder[i] == QUESTION_ID_WHICH_MOVE)
{
do
{
2019-11-20 23:36:52 +01:00
rand1 = Random() % MAX_MON_MOVES;
for (j = 0; j < gApprenticePartyMovesData->moveCounter + 1; j++)
{
2019-11-20 23:36:52 +01:00
if (gApprenticePartyMovesData->moveSlots[id][j] == rand1)
break;
}
2019-11-20 23:36:52 +01:00
} while (j != gApprenticePartyMovesData->moveCounter + 1);
2019-11-20 23:36:52 +01:00
gApprenticePartyMovesData->moveSlots[id][gApprenticePartyMovesData->moveCounter] = rand1;
PLAYER_APPRENTICE.questions[i].moveSlot = rand1;
PLAYER_APPRENTICE.questions[i].data = GetRandomAlternateMove(PLAYER_APPRENTICE.questions[i].monId);
}
}
}
2019-11-20 23:36:52 +01:00
FREE_AND_SET_NULL(gApprenticePartyMovesData);
}
2021-04-22 22:40:46 +02:00
#define APPRENTICE_SPECIES_ID(monId) \
((monId < MULTI_PARTY_SIZE) ? (PLAYER_APPRENTICE.speciesIds[monId] >> (((PLAYER_APPRENTICE.party >> monId) & 1) << 2) & 0xF) : 0)
2021-04-22 23:20:28 +02:00
#define APPRENTICE_SPECIES_ID_NO_COND(monId, count) \
monId = ((PLAYER_APPRENTICE.party >> count) & 1); \
monId = ((PLAYER_APPRENTICE.speciesIds[count]) >> (monId << 2)) & 0xF; \
2019-11-20 23:36:52 +01:00
// Get the second move choice for the "Which move" question
// Unlike the first move choice, this can be either a level up move or a TM/HM move
static u16 GetRandomAlternateMove(u8 monId)
{
u8 i, j;
u8 id;
2019-11-20 23:36:52 +01:00
u8 numLearnsetMoves;
u16 species;
2018-10-14 20:51:34 +02:00
const struct LevelUpMove *learnset;
2019-11-20 23:36:52 +01:00
bool32 needTMs = FALSE;
u16 moveId = MOVE_NONE;
2022-08-29 09:47:11 +02:00
bool32 shouldUseMove;
u8 level;
2021-04-22 22:40:46 +02:00
id = APPRENTICE_SPECIES_ID(monId);
2018-10-14 16:27:48 +02:00
species = gApprentices[PLAYER_APPRENTICE.id].species[id];
learnset = gLevelUpLearnsets[species];
j = 0;
2019-11-20 23:36:52 +01:00
// Despite being open level, level up moves are only read up to level 60
2019-11-15 00:56:18 +01:00
if (PLAYER_APPRENTICE.lvlMode == APPRENTICE_LVL_MODE_50)
level = 50;
2019-11-15 00:56:18 +01:00
else // == APPRENTICE_LVL_MODE_OPEN
level = 60;
2019-11-29 21:47:31 +01:00
for (j = 0; learnset[j].move != LEVEL_UP_END; j++)
{
2018-10-14 20:51:34 +02:00
if (learnset[j].level > level)
break;
}
2019-11-20 23:36:52 +01:00
numLearnsetMoves = j;
i = 0;
2019-11-20 23:36:52 +01:00
// i < 5 here is arbitrary, i isnt used and is only incremented when the selected move isnt in sValidApprenticeMoves
// This while loop contains 3 potential infinite loops, though none of them would occur in the base game
while (i < 5)
{
2019-11-20 23:36:52 +01:00
if (Random() % 2 == 0 || needTMs == TRUE)
{
2019-11-20 23:36:52 +01:00
// Get TM move
// NOTE: Below is an infinite loop if a species that only learns TMs for moves
// that are also in its level up learnset is assigned to an Apprentice
do
{
2019-11-20 23:36:52 +01:00
// NOTE: Below is an infinite loop if a species which cannot learn TMs is assigned to an Apprentice
do
{
id = Random() % (NUM_TECHNICAL_MACHINES + NUM_HIDDEN_MACHINES);
shouldUseMove = CanLearnTeachableMove(species, ItemIdToBattleMoveId(ITEM_TM01 + id));
}
2019-11-20 23:36:52 +01:00
while (!shouldUseMove);
moveId = ItemIdToBattleMoveId(ITEM_TM01 + id);
2019-11-20 23:36:52 +01:00
shouldUseMove = TRUE;
2019-11-20 23:36:52 +01:00
if (numLearnsetMoves <= MAX_MON_MOVES)
j = 0;
else
2019-11-20 23:36:52 +01:00
j = numLearnsetMoves - MAX_MON_MOVES;
2019-11-20 23:36:52 +01:00
for (; j < numLearnsetMoves; j++)
{
2019-11-20 23:36:52 +01:00
// Keep looking for TMs until one not in the level up learnset is found
2018-10-14 20:51:34 +02:00
if ((learnset[j].move) == moveId)
{
2019-11-20 23:36:52 +01:00
shouldUseMove = FALSE;
break;
}
}
2019-11-20 23:36:52 +01:00
} while (shouldUseMove != TRUE);
}
else
{
2019-11-20 23:36:52 +01:00
if (numLearnsetMoves <= MAX_MON_MOVES)
{
2019-11-20 23:36:52 +01:00
needTMs = TRUE;
continue;
}
else
{
2019-11-20 23:36:52 +01:00
// Get level up move
// NOTE: Below is an infinite loop if a mon whose last 4 moves contain
// all the moves in the rest of its learnset is assigned to an Apprentice
do
{
2019-11-20 23:36:52 +01:00
// Get a random move excluding the 4 it would know at max level
u8 learnsetId = Random() % (numLearnsetMoves - MAX_MON_MOVES);
2018-10-14 20:51:34 +02:00
moveId = learnset[learnsetId].move;
2019-11-20 23:36:52 +01:00
shouldUseMove = TRUE;
for (j = numLearnsetMoves - MAX_MON_MOVES; j < numLearnsetMoves; j++)
{
2019-11-20 23:36:52 +01:00
// Keep looking for moves until one not in the last 4 is found
2018-10-14 20:51:34 +02:00
if ((learnset[j].move) == moveId)
{
2019-11-20 23:36:52 +01:00
shouldUseMove = FALSE;
break;
}
}
2019-11-20 23:36:52 +01:00
} while (shouldUseMove != TRUE);
}
}
2019-11-20 23:36:52 +01:00
if (TrySetMove(monId, moveId))
{
2019-11-20 23:36:52 +01:00
if (sValidApprenticeMoves[moveId])
break;
i++;
}
}
2019-11-20 23:36:52 +01:00
gApprenticePartyMovesData->moveCounter++;
return moveId;
}
2019-11-20 23:36:52 +01:00
static bool8 TrySetMove(u8 monId, u16 moveId)
{
u8 i;
2019-11-20 23:36:52 +01:00
for (i = 0; i < NUM_WHICH_MOVE_QUESTIONS; i++)
{
2019-11-20 23:36:52 +01:00
if (gApprenticePartyMovesData->moves[monId][i] == moveId)
return FALSE;
}
2019-11-20 23:36:52 +01:00
gApprenticePartyMovesData->moves[monId][gApprenticePartyMovesData->moveCounter] = moveId;
return TRUE;
}
2018-10-14 17:00:41 +02:00
static void GetLatestLearnedMoves(u16 species, u16 *moves)
{
u8 i, j;
2019-11-20 23:36:52 +01:00
u8 level, numLearnsetMoves;
2018-10-14 20:51:34 +02:00
const struct LevelUpMove *learnset;
2019-11-15 00:56:18 +01:00
if (PLAYER_APPRENTICE.lvlMode == APPRENTICE_LVL_MODE_50)
level = 50;
2019-11-15 00:56:18 +01:00
else // == APPRENTICE_LVL_MODE_OPEN
level = 60;
learnset = gLevelUpLearnsets[species];
2019-11-29 21:47:31 +01:00
for (i = 0; learnset[i].move != LEVEL_UP_END; i++)
{
2019-11-29 21:47:31 +01:00
if (learnset[i].level > level)
break;
}
2019-11-20 23:36:52 +01:00
numLearnsetMoves = i;
if (numLearnsetMoves > MAX_MON_MOVES)
numLearnsetMoves = MAX_MON_MOVES;
2019-11-20 23:36:52 +01:00
for (j = 0; j < numLearnsetMoves; j++)
2018-10-14 20:51:34 +02:00
moves[j] = learnset[(i - 1) - j].move;
}
2019-11-20 23:36:52 +01:00
// Get the level up move or previously suggested move to be the first move choice
// Compare to GetRandomAlternateMove, which gets the move that will be the second choice
static u16 GetDefaultMove(u8 monId, u8 speciesArrayId, u8 moveSlot)
{
2019-09-08 17:53:48 +02:00
u16 moves[MAX_MON_MOVES];
2019-11-20 23:36:52 +01:00
u8 i, numQuestions;
2019-11-20 23:36:52 +01:00
if (PLAYER_APPRENTICE.questionsAnswered < NUM_WHICH_MON_QUESTIONS)
return MOVE_NONE;
2019-11-20 23:36:52 +01:00
numQuestions = 0;
for (i = 0; i < APPRENTICE_MAX_QUESTIONS && PLAYER_APPRENTICE.questions[i].questionId != QUESTION_ID_WIN_SPEECH; i++)
numQuestions++;
2019-11-20 23:36:52 +01:00
GetLatestLearnedMoves(gApprentices[PLAYER_APPRENTICE.id].species[speciesArrayId], moves);
for (i = 0; i < numQuestions && i < CURRENT_QUESTION_NUM; i++)
{
2019-11-20 23:36:52 +01:00
if (PLAYER_APPRENTICE.questions[i].questionId == QUESTION_ID_WHICH_MOVE
&& PLAYER_APPRENTICE.questions[i].monId == monId
&& PLAYER_APPRENTICE.questions[i].suggestedChange)
{
2019-11-20 23:36:52 +01:00
moves[PLAYER_APPRENTICE.questions[i].moveSlot] = PLAYER_APPRENTICE.questions[i].data;
}
}
2019-11-20 23:36:52 +01:00
return moves[moveSlot];
}
2019-11-20 23:36:52 +01:00
static void SaveApprenticeParty(u8 numQuestions)
{
2019-11-15 00:56:18 +01:00
struct ApprenticeMon *apprenticeMons[MULTI_PARTY_SIZE];
u8 i, j;
u32 speciesTableId;
2019-11-15 00:56:18 +01:00
for (i = 0; i < MULTI_PARTY_SIZE; i++)
{
2019-11-20 23:36:52 +01:00
gSaveBlock2Ptr->apprentices[0].party[i].species = SPECIES_NONE;
gSaveBlock2Ptr->apprentices[0].party[i].item = ITEM_NONE;
for (j = 0; j < MAX_MON_MOVES; j++)
2019-11-20 23:36:52 +01:00
gSaveBlock2Ptr->apprentices[0].party[i].moves[j] = MOVE_NONE;
}
2019-11-20 23:36:52 +01:00
// Save party order
j = PLAYER_APPRENTICE.leadMonId;
2019-11-15 00:56:18 +01:00
for (i = 0; i < MULTI_PARTY_SIZE; i++)
{
apprenticeMons[j] = &gSaveBlock2Ptr->apprentices[0].party[i];
2019-11-15 00:56:18 +01:00
j = (j + 1) % (MULTI_PARTY_SIZE);
}
2019-11-20 23:36:52 +01:00
// Save party species
2019-11-15 00:56:18 +01:00
for (i = 0; i < MULTI_PARTY_SIZE; i++)
{
2021-04-22 22:40:46 +02:00
speciesTableId = APPRENTICE_SPECIES_ID(i);
2018-10-14 16:27:48 +02:00
apprenticeMons[i]->species = gApprentices[PLAYER_APPRENTICE.id].species[speciesTableId];
GetLatestLearnedMoves(apprenticeMons[i]->species, apprenticeMons[i]->moves);
}
2019-11-20 23:36:52 +01:00
// Update party based on response to held item / move choice questions
for (i = 0; i < numQuestions; i++)
{
2019-11-20 23:36:52 +01:00
u8 questionId = PLAYER_APPRENTICE.questions[i].questionId;
u8 monId = PLAYER_APPRENTICE.questions[i].monId;
if (questionId == QUESTION_ID_WHAT_ITEM)
{
2019-11-20 23:36:52 +01:00
if (PLAYER_APPRENTICE.questions[i].suggestedChange)
apprenticeMons[monId]->item = PLAYER_APPRENTICE.questions[i].data;
}
2019-11-20 23:36:52 +01:00
else if (questionId == QUESTION_ID_WHICH_MOVE)
{
2019-11-20 23:36:52 +01:00
if (PLAYER_APPRENTICE.questions[i].suggestedChange)
{
2019-11-20 23:36:52 +01:00
u32 moveSlot = PLAYER_APPRENTICE.questions[i].moveSlot;
apprenticeMons[monId]->moves[moveSlot] = PLAYER_APPRENTICE.questions[i].data;
}
}
}
}
2019-11-20 23:36:52 +01:00
static void CreateApprenticeMenu(u8 menu)
{
u8 i;
u8 windowId;
const u8 *strings[3];
u8 count = 2;
2018-10-13 23:23:33 +02:00
u8 width;
u8 left;
u8 top;
s32 pixelWidth;
2019-11-20 23:36:52 +01:00
switch (menu)
{
2018-10-14 11:37:44 +02:00
case APPRENTICE_ASK_WHICH_LEVEL:
2019-11-20 23:36:52 +01:00
left = 18;
2018-10-13 23:23:33 +02:00
top = 8;
strings[0] = gText_Lv50;
strings[1] = gText_OpenLevel;
break;
2018-10-14 11:37:44 +02:00
case APPRENTICE_ASK_3SPECIES:
2019-11-20 23:36:52 +01:00
count = MULTI_PARTY_SIZE;
left = 18;
2018-10-13 23:23:33 +02:00
top = 6;
2019-11-15 00:56:18 +01:00
for (i = 0; i < MULTI_PARTY_SIZE; i++)
{
u16 species;
u32 speciesTableId;
2021-04-22 22:40:46 +02:00
speciesTableId = APPRENTICE_SPECIES_ID(i);
2018-10-14 16:27:48 +02:00
species = gApprentices[PLAYER_APPRENTICE.id].species[speciesTableId];
strings[i] = gSpeciesNames[species];
}
break;
2018-10-14 11:37:44 +02:00
case APPRENTICE_ASK_2SPECIES:
2019-11-20 23:36:52 +01:00
left = 18;
2018-10-13 23:23:33 +02:00
top = 8;
2019-11-20 23:36:52 +01:00
if (PLAYER_APPRENTICE.questionsAnswered >= NUM_WHICH_MON_QUESTIONS)
return;
2019-11-20 23:36:52 +01:00
strings[1] = gSpeciesNames[gApprenticeQuestionData->altSpeciesId];
strings[0] = gSpeciesNames[gApprenticeQuestionData->speciesId];
break;
2018-10-14 11:37:44 +02:00
case APPRENTICE_ASK_MOVES:
2019-11-20 23:36:52 +01:00
left = 17;
2018-10-13 23:23:33 +02:00
top = 8;
2019-11-20 23:36:52 +01:00
strings[0] = gMoveNames[gApprenticeQuestionData->moveId1];
strings[1] = gMoveNames[gApprenticeQuestionData->moveId2];
break;
2018-10-14 11:37:44 +02:00
case APPRENTICE_ASK_GIVE:
2019-11-20 23:36:52 +01:00
left = 18;
2018-10-13 23:23:33 +02:00
top = 8;
strings[0] = gText_Give;
strings[1] = gText_NoNeed;
break;
2018-10-14 11:37:44 +02:00
case APPRENTICE_ASK_YES_NO:
2019-11-20 23:36:52 +01:00
left = 20;
2018-10-13 23:23:33 +02:00
top = 8;
strings[0] = gText_Yes;
strings[1] = gText_No;
break;
default:
2018-10-13 23:23:33 +02:00
left = 0;
top = 0;
break;
}
pixelWidth = 0;
for (i = 0; i < count; i++)
{
2021-10-30 22:47:37 +02:00
s32 width = GetStringWidth(FONT_NORMAL, strings[i], 0);
if (width > pixelWidth)
pixelWidth = width;
}
width = ConvertPixelWidthToTileWidth(pixelWidth);
left = ScriptMenu_AdjustLeftCoordFromWidth(left, width);
2018-10-14 11:37:44 +02:00
windowId = CreateAndShowWindow(left, top, width, count * 2);
2022-07-25 20:59:14 +02:00
SetStandardWindowBorderStyle(windowId, FALSE);
for (i = 0; i < count; i++)
AddTextPrinterParameterized(windowId, FONT_NORMAL, strings[i], 8, (i * 16) + 1, TEXT_SKIP_DRAW, NULL);
2021-11-03 21:06:58 +01:00
InitMenuInUpperLeftCornerNormal(windowId, count, 0);
2018-10-14 11:37:44 +02:00
CreateChooseAnswerTask(TRUE, count, windowId);
2018-10-13 23:23:33 +02:00
}
#define tNoBButton data[4]
#define tWrapAround data[5]
#define tWindowId data[6]
2018-10-14 17:00:41 +02:00
static void Task_ChooseAnswer(u8 taskId)
2018-10-13 23:23:33 +02:00
{
s8 input;
s16 *data = gTasks[taskId].data;
if (!tWrapAround)
2018-11-05 21:45:54 +01:00
input = Menu_ProcessInputNoWrap();
2018-10-13 23:23:33 +02:00
else
2018-11-05 21:45:54 +01:00
input = Menu_ProcessInput();
2018-10-13 23:23:33 +02:00
switch (input)
{
case MENU_NOTHING_CHOSEN:
return;
case MENU_B_PRESSED:
if (tNoBButton)
return;
PlaySE(SE_SELECT);
gSpecialVar_Result = 0x7F;
break;
default:
gSpecialVar_Result = input;
break;
}
2018-10-14 11:37:44 +02:00
RemoveAndHideWindow(tWindowId);
2018-10-13 23:23:33 +02:00
DestroyTask(taskId);
ScriptContext_Enable();
2018-10-13 23:23:33 +02:00
}
2018-10-14 11:37:44 +02:00
static u8 CreateAndShowWindow(u8 left, u8 top, u8 width, u8 height)
2018-10-13 23:23:33 +02:00
{
u8 windowId;
struct WindowTemplate winTemplate = CreateWindowTemplate(0, left + 1, top + 1, width, height, 15, 100);
windowId = AddWindow(&winTemplate);
PutWindowTilemap(windowId);
2021-11-03 20:29:18 +01:00
CopyWindowToVram(windowId, COPYWIN_FULL);
2018-10-13 23:23:33 +02:00
return windowId;
}
2018-10-14 11:37:44 +02:00
static void RemoveAndHideWindow(u8 windowId)
2018-10-13 23:23:33 +02:00
{
ClearStdWindowAndFrameToTransparent(windowId, TRUE);
2018-10-13 23:23:33 +02:00
RemoveWindow(windowId);
}
2019-11-20 23:36:52 +01:00
static void CreateChooseAnswerTask(bool8 noBButton, u8 answers, u8 windowId)
2018-10-13 23:23:33 +02:00
{
2018-10-14 11:37:44 +02:00
u8 taskId = CreateTask(Task_ChooseAnswer, 80);
2018-10-13 23:23:33 +02:00
gTasks[taskId].tNoBButton = noBButton;
2019-11-20 23:36:52 +01:00
if (answers > 3)
2018-10-13 23:23:33 +02:00
gTasks[taskId].tWrapAround = TRUE;
else
gTasks[taskId].tWrapAround = FALSE;
gTasks[taskId].tWindowId = windowId;
}
#undef tNoBButton
#undef tWrapAround
#undef tWindowId
2018-10-14 17:00:41 +02:00
void CallApprenticeFunction(void)
2018-10-13 23:23:33 +02:00
{
2018-10-14 17:00:41 +02:00
sApprenticeFunctions[gSpecialVar_0x8004]();
2018-10-13 23:23:33 +02:00
}
2018-10-14 17:00:41 +02:00
static void Script_ResetPlayerApprentice(void)
2018-10-13 23:23:33 +02:00
{
u8 i;
2019-11-19 17:36:38 +01:00
SetApprenticeId();
2019-11-15 00:56:18 +01:00
PLAYER_APPRENTICE.lvlMode = 0;
2019-11-19 17:36:38 +01:00
PLAYER_APPRENTICE.questionsAnswered = 0;
2019-11-20 23:36:52 +01:00
PLAYER_APPRENTICE.leadMonId = 0;
PLAYER_APPRENTICE.party = 0;
2018-10-13 23:23:33 +02:00
2019-11-15 00:56:18 +01:00
for (i = 0; i < MULTI_PARTY_SIZE; i++)
2019-11-20 23:36:52 +01:00
PLAYER_APPRENTICE.speciesIds[i] = 0;
2018-10-13 23:23:33 +02:00
2019-11-20 23:36:52 +01:00
for (i = 0; i < APPRENTICE_MAX_QUESTIONS; i++)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
PLAYER_APPRENTICE.questions[i].questionId = 0;
PLAYER_APPRENTICE.questions[i].monId = 0;
PLAYER_APPRENTICE.questions[i].moveSlot = 0;
PLAYER_APPRENTICE.questions[i].suggestedChange = 0;
PLAYER_APPRENTICE.questions[i].data = 0;
2018-10-13 23:23:33 +02:00
}
}
2019-11-15 00:56:18 +01:00
static void Script_GivenApprenticeLvlMode(void)
2018-10-13 23:23:33 +02:00
{
2019-11-19 17:36:38 +01:00
if (!GivenApprenticeLvlMode())
2018-10-13 23:23:33 +02:00
gSpecialVar_Result = FALSE;
else
gSpecialVar_Result = TRUE;
}
2019-11-15 00:56:18 +01:00
// VAR_0x8005 is 1 + the selection value from the multichoice APPRENTICE_ASK_WHICH_LEVEL
// i.e. APPRENTICE_LVL_MODE_50 or APPRENTICE_LVL_MODE_OPEN
static void Script_SetApprenticeLvlMode(void)
2018-10-13 23:23:33 +02:00
{
2018-10-14 16:27:48 +02:00
SetPlayersApprenticeLvlMode(gSpecialVar_0x8005);
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
// Never called, APPRENTICE_FUNC_SET_ID is unused
static void Script_SetApprenticeId(void)
2018-10-13 23:23:33 +02:00
{
2019-11-19 17:36:38 +01:00
SetApprenticeId();
2018-10-13 23:23:33 +02:00
}
2019-11-20 23:36:52 +01:00
static void Script_SetRandomQuestionData(void)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
SetRandomQuestionData();
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
static void IncrementQuestionsAnswered(void)
2018-10-13 23:23:33 +02:00
{
2019-11-19 17:36:38 +01:00
PLAYER_APPRENTICE.questionsAnswered++;
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
// The first 3 questions answered after meeting the Apprentice are always selecting party mons
// after which this is never called
2019-11-20 23:36:52 +01:00
static void GetNumApprenticePartyMonsAssigned(void)
2018-10-13 23:23:33 +02:00
{
2019-11-19 17:36:38 +01:00
gSpecialVar_Result = PLAYER_APPRENTICE.questionsAnswered;
2018-10-13 23:23:33 +02:00
}
2019-11-20 23:36:52 +01:00
// Never called, APPRENTICE_FUNC_IS_FINAL_QUESTION is unused
static void IsFinalQuestion(void)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
s32 questionNum = CURRENT_QUESTION_NUM;
2019-11-29 21:47:31 +01:00
2019-11-20 23:36:52 +01:00
if (questionNum < 0)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
// Not finished asking initial questions
2018-10-13 23:23:33 +02:00
gSpecialVar_Result = FALSE;
}
else
{
2019-11-20 23:36:52 +01:00
if (questionNum > APPRENTICE_MAX_QUESTIONS - 1)
2018-10-13 23:23:33 +02:00
gSpecialVar_Result = TRUE;
2019-11-20 23:36:52 +01:00
if (PLAYER_APPRENTICE.questions[questionNum].questionId == QUESTION_ID_WIN_SPEECH)
2018-10-13 23:23:33 +02:00
gSpecialVar_Result = TRUE;
else
gSpecialVar_Result = FALSE;
}
}
2018-10-14 17:00:41 +02:00
static void Script_CreateApprenticeMenu(void)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
CreateApprenticeMenu(gSpecialVar_0x8005);
2018-10-13 23:23:33 +02:00
}
2018-10-14 11:37:44 +02:00
static void Task_WaitForPrintingMessage(u8 taskId)
2018-10-13 23:23:33 +02:00
{
if (!RunTextPrintersAndIsPrinter0Active())
{
DestroyTask(taskId);
if (gSpecialVar_0x8005)
ExecuteFuncAfterButtonPress(ScriptContext_Enable);
2018-10-13 23:23:33 +02:00
else
ScriptContext_Enable();
2018-10-13 23:23:33 +02:00
}
}
2019-11-15 00:56:18 +01:00
static void PrintApprenticeMessage(void)
2018-10-13 23:23:33 +02:00
{
const u8 *string;
2019-11-19 17:36:38 +01:00
if (gSpecialVar_0x8006 == APPRENTICE_MSG_WHICH_MON)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeWhichMonTexts[PLAYER_APPRENTICE.id][0];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_THANKS_MON)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeWhichMonTexts[PLAYER_APPRENTICE.id][1];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_WHICH_MOVE)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeWhichMoveTexts[PLAYER_APPRENTICE.id][0];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_THANKS_MOVE)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeWhichMoveTexts[PLAYER_APPRENTICE.id][1];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_WHICH_MON_FIRST)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeWhichMonFirstTexts[PLAYER_APPRENTICE.id][0];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_THANKS_MON_FIRST)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeWhichMonFirstTexts[PLAYER_APPRENTICE.id][1];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_WHAT_HELD_ITEM)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeHeldItemTexts[PLAYER_APPRENTICE.id][0];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_PICK_WIN_SPEECH)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticePickWinSpeechTexts[PLAYER_APPRENTICE.id][0];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_THANKS_HELD_ITEM)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeHeldItemTexts[PLAYER_APPRENTICE.id][3];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_HOLD_NOTHING)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeHeldItemTexts[PLAYER_APPRENTICE.id][1];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_ITEM_ALREADY_SUGGESTED)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeHeldItemTexts[PLAYER_APPRENTICE.id][4];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_THANKS_NO_HELD_ITEM)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeHeldItemTexts[PLAYER_APPRENTICE.id][2];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_THANKS_WIN_SPEECH)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticePickWinSpeechTexts[PLAYER_APPRENTICE.id][1];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_PLEASE_TEACH)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeFirstMeetingTexts[PLAYER_APPRENTICE.id][0];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_REJECT)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeFirstMeetingTexts[PLAYER_APPRENTICE.id][1];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_WHICH_LVL_MODE)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeFirstMeetingTexts[PLAYER_APPRENTICE.id][2];
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8006 == APPRENTICE_MSG_THANKS_LVL_MODE)
2018-10-13 23:23:33 +02:00
{
2019-11-15 00:56:18 +01:00
string = sApprenticeFirstMeetingTexts[PLAYER_APPRENTICE.id][3];
2018-10-13 23:23:33 +02:00
}
else
{
ScriptContext_Enable();
2018-10-13 23:23:33 +02:00
return;
}
StringExpandPlaceholders(gStringVar4, string);
AddTextPrinterForMessage(TRUE);
2018-10-14 11:37:44 +02:00
CreateTask(Task_WaitForPrintingMessage, 1);
2018-10-13 23:23:33 +02:00
}
2019-11-15 00:56:18 +01:00
static void Script_PrintApprenticeMessage(void)
2018-10-13 23:23:33 +02:00
{
LockPlayerFieldControls();
FreezeObjectEvents();
PlayerFreeze();
2021-10-26 19:27:20 +02:00
StopPlayerAvatar();
2022-07-25 20:59:14 +02:00
DrawDialogueFrame(0, TRUE);
2019-11-15 00:56:18 +01:00
PrintApprenticeMessage();
2018-10-13 23:23:33 +02:00
}
2019-11-19 17:36:38 +01:00
static void ApprenticeGetQuestion(void)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
if (PLAYER_APPRENTICE.questionsAnswered < NUM_WHICH_MON_QUESTIONS)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
gSpecialVar_Result = APPRENTICE_QUESTION_WHICH_MON;
2018-10-13 23:23:33 +02:00
}
2019-11-20 23:36:52 +01:00
else if (PLAYER_APPRENTICE.questionsAnswered > (APPRENTICE_MAX_QUESTIONS + NUM_WHICH_MON_QUESTIONS - 1))
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
gSpecialVar_Result = APPRENTICE_QUESTION_WIN_SPEECH;
2018-10-13 23:23:33 +02:00
}
else
{
2019-11-20 23:36:52 +01:00
s32 id = CURRENT_QUESTION_NUM;
switch (PLAYER_APPRENTICE.questions[id].questionId)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
case QUESTION_ID_WHAT_ITEM:
gSpecialVar_Result = APPRENTICE_QUESTION_WHAT_ITEM;
2018-10-13 23:23:33 +02:00
break;
2019-11-20 23:36:52 +01:00
case QUESTION_ID_WHICH_MOVE:
gSpecialVar_Result = APPRENTICE_QUESTION_WHICH_MOVE;
2018-10-13 23:23:33 +02:00
break;
2019-11-20 23:36:52 +01:00
case QUESTION_ID_WHICH_FIRST:
gSpecialVar_Result = APPRENTICE_QUESTION_WHICH_FIRST;
2018-10-13 23:23:33 +02:00
break;
default:
2019-11-29 21:47:31 +01:00
//case QUESTION_ID_WIN_SPEECH:
2019-11-20 23:36:52 +01:00
gSpecialVar_Result = APPRENTICE_QUESTION_WIN_SPEECH;
2018-10-13 23:23:33 +02:00
break;
}
}
}
2019-11-19 17:36:38 +01:00
// gSpecialVar_0x8005 is 0 or 1 for the mon selection (0 is already on the team)
// gSpecialVar_0x8006 is 0-2 for the number of party mons selected so far
static void SetApprenticePartyMon(void)
2018-10-13 23:23:33 +02:00
{
if (gSpecialVar_0x8005)
{
2019-11-20 23:36:52 +01:00
u8 partySlot = gSpecialVar_0x8006;
PLAYER_APPRENTICE.party |= 1 << partySlot;
2018-10-13 23:23:33 +02:00
}
}
2019-11-20 23:36:52 +01:00
// gSpecialVar_0x8005 is 0 or 1 for the move selection
// Selection 0 is implicitly the default move assigned
2019-11-19 17:36:38 +01:00
static void SetApprenticeMonMove(void)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
if (PLAYER_APPRENTICE.questionsAnswered >= NUM_WHICH_MON_QUESTIONS)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
u8 id = CURRENT_QUESTION_NUM;
2018-10-13 23:23:33 +02:00
if (gSpecialVar_0x8005)
2019-11-20 23:36:52 +01:00
PLAYER_APPRENTICE.questions[id].suggestedChange = TRUE;
2018-10-13 23:23:33 +02:00
else
2019-11-20 23:36:52 +01:00
PLAYER_APPRENTICE.questions[id].suggestedChange = FALSE;
2018-10-13 23:23:33 +02:00
}
}
2019-11-21 01:00:08 +01:00
static void InitQuestionData(void)
2018-10-13 23:23:33 +02:00
{
u8 i;
u8 count = 0;
u8 id1, id2;
2019-11-20 23:36:52 +01:00
for (i = 0; i < APPRENTICE_MAX_QUESTIONS && (PLAYER_APPRENTICE.questions[i].questionId != QUESTION_ID_WIN_SPEECH); count++, i++)
2018-10-13 23:23:33 +02:00
;
2019-11-20 23:36:52 +01:00
gApprenticeQuestionData = AllocZeroed(sizeof(*gApprenticeQuestionData));
2019-11-19 17:36:38 +01:00
if (gSpecialVar_0x8005 == APPRENTICE_QUESTION_WHICH_MON)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
if (PLAYER_APPRENTICE.questionsAnswered < NUM_WHICH_MON_QUESTIONS)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
// For the first MULTI_PARTY_SIZE (3) questions, a mon is asked to be selected for the Apprentice's party
id1 = PLAYER_APPRENTICE.speciesIds[PLAYER_APPRENTICE.questionsAnswered] >> 4;
gApprenticeQuestionData->altSpeciesId = gApprentices[PLAYER_APPRENTICE.id].species[id1];
2018-10-13 23:23:33 +02:00
2019-11-20 23:36:52 +01:00
id2 = PLAYER_APPRENTICE.speciesIds[PLAYER_APPRENTICE.questionsAnswered] & 0xF;
gApprenticeQuestionData->speciesId = gApprentices[PLAYER_APPRENTICE.id].species[id2];
2018-10-13 23:23:33 +02:00
}
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8005 == APPRENTICE_QUESTION_WHICH_MOVE)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
if (PLAYER_APPRENTICE.questionsAnswered >= NUM_WHICH_MON_QUESTIONS
&& PLAYER_APPRENTICE.questionsAnswered < count + NUM_WHICH_MON_QUESTIONS
&& PLAYER_APPRENTICE.questions[CURRENT_QUESTION_NUM].questionId == QUESTION_ID_WHICH_MOVE)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
// count re-used as monId
count = PLAYER_APPRENTICE.questions[CURRENT_QUESTION_NUM].monId;
2021-04-22 23:20:28 +02:00
APPRENTICE_SPECIES_ID_NO_COND(id1, count);
2019-11-20 23:36:52 +01:00
gApprenticeQuestionData->speciesId = gApprentices[PLAYER_APPRENTICE.id].species[id1];
gApprenticeQuestionData->moveId1 = GetDefaultMove(count, id1, PLAYER_APPRENTICE.questions[CURRENT_QUESTION_NUM].moveSlot);
gApprenticeQuestionData->moveId2 = PLAYER_APPRENTICE.questions[CURRENT_QUESTION_NUM].data;
2018-10-13 23:23:33 +02:00
}
}
2019-11-19 17:36:38 +01:00
else if (gSpecialVar_0x8005 == APPRENTICE_QUESTION_WHAT_ITEM)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
if (PLAYER_APPRENTICE.questionsAnswered >= NUM_WHICH_MON_QUESTIONS
&& PLAYER_APPRENTICE.questionsAnswered < count + NUM_WHICH_MON_QUESTIONS
&& PLAYER_APPRENTICE.questions[CURRENT_QUESTION_NUM].questionId == QUESTION_ID_WHAT_ITEM)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
// count re-used as monId
count = PLAYER_APPRENTICE.questions[CURRENT_QUESTION_NUM].monId;
2021-04-22 23:20:28 +02:00
APPRENTICE_SPECIES_ID_NO_COND(id2, count);
2019-11-20 23:36:52 +01:00
gApprenticeQuestionData->speciesId = gApprentices[PLAYER_APPRENTICE.id].species[id2];
2018-10-13 23:23:33 +02:00
}
}
}
2019-11-21 01:00:08 +01:00
static void FreeQuestionData(void)
2018-10-13 23:23:33 +02:00
{
2019-11-20 23:36:52 +01:00
FREE_AND_SET_NULL(gApprenticeQuestionData);
}
2018-10-14 11:37:44 +02:00
2019-11-15 00:56:18 +01:00
static void ApprenticeBufferString(void)
2018-10-14 11:37:44 +02:00
{
u8 *stringDst;
u8 text[16];
u32 speciesArrayId;
switch (gSpecialVar_0x8005)
{
case 0:
stringDst = gStringVar1;
break;
case 1:
stringDst = gStringVar2;
break;
case 2:
stringDst = gStringVar3;
break;
default:
return;
}
switch (gSpecialVar_0x8006)
{
2018-10-14 14:35:51 +02:00
case APPRENTICE_BUFF_SPECIES1:
2019-11-20 23:36:52 +01:00
StringCopy(stringDst, gSpeciesNames[gApprenticeQuestionData->speciesId]);
2018-10-14 11:37:44 +02:00
break;
2018-10-14 14:35:51 +02:00
case APPRENTICE_BUFF_SPECIES2:
2019-11-20 23:36:52 +01:00
StringCopy(stringDst, gSpeciesNames[gApprenticeQuestionData->altSpeciesId]);
2018-10-14 11:37:44 +02:00
break;
2018-10-14 14:35:51 +02:00
case APPRENTICE_BUFF_SPECIES3:
2019-11-20 23:36:52 +01:00
StringCopy(stringDst, gSpeciesNames[gApprenticeQuestionData->speciesId]);
2018-10-14 11:37:44 +02:00
break;
2018-10-14 14:35:51 +02:00
case APPRENTICE_BUFF_MOVE1:
2019-11-20 23:36:52 +01:00
StringCopy(stringDst, gMoveNames[gApprenticeQuestionData->moveId1]);
2018-10-14 11:37:44 +02:00
break;
2018-10-14 14:35:51 +02:00
case APPRENTICE_BUFF_MOVE2:
2019-11-20 23:36:52 +01:00
StringCopy(stringDst, gMoveNames[gApprenticeQuestionData->moveId2]);
2018-10-14 11:37:44 +02:00
break;
2018-10-14 14:35:51 +02:00
case APPRENTICE_BUFF_ITEM:
2019-11-20 23:36:52 +01:00
StringCopy(stringDst, ItemId_GetName(PLAYER_APPRENTICE.questions[CURRENT_QUESTION_NUM].data));
2018-10-14 11:37:44 +02:00
break;
2018-10-14 14:35:51 +02:00
case APPRENTICE_BUFF_NAME:
TVShowConvertInternationalString(text, GetApprenticeNameInLanguage(PLAYER_APPRENTICE.id, GAME_LANGUAGE), GAME_LANGUAGE);
2018-10-14 11:37:44 +02:00
StringCopy(stringDst, text);
break;
2018-10-14 14:35:51 +02:00
case APPRENTICE_BUFF_LEVEL:
2019-11-15 00:56:18 +01:00
if (PLAYER_APPRENTICE.lvlMode == APPRENTICE_LVL_MODE_50)
2018-10-14 11:37:44 +02:00
StringCopy(stringDst, gText_Lv50);
2019-11-15 00:56:18 +01:00
else // == APPRENTICE_LVL_MODE_OPEN
2018-10-14 11:37:44 +02:00
StringCopy(stringDst, gText_OpenLevel);
break;
2019-11-19 17:36:38 +01:00
case APPRENTICE_BUFF_WIN_SPEECH:
FrontierSpeechToString(gSaveBlock2Ptr->apprentices[0].speechWon);
2018-10-14 11:37:44 +02:00
StringCopy(stringDst, gStringVar4);
break;
2019-11-20 23:36:52 +01:00
case APPRENTICE_BUFF_LEAD_MON_SPECIES:
2021-04-22 22:40:46 +02:00
speciesArrayId = APPRENTICE_SPECIES_ID(PLAYER_APPRENTICE.leadMonId);
2018-10-14 16:27:48 +02:00
StringCopy(stringDst, gSpeciesNames[gApprentices[PLAYER_APPRENTICE.id].species[speciesArrayId]]);
2018-10-14 11:37:44 +02:00
break;
}
}
2019-11-20 23:36:52 +01:00
static void SetLeadApprenticeMon(void)
2018-10-14 11:37:44 +02:00
{
2019-11-20 23:36:52 +01:00
PLAYER_APPRENTICE.leadMonId = gSpecialVar_0x8005;
2018-10-14 11:37:44 +02:00
}
2019-11-19 17:36:38 +01:00
static void Script_ApprenticeOpenBagMenu(void)
2018-10-14 11:37:44 +02:00
{
2019-11-19 17:36:38 +01:00
ApprenticeOpenBagMenu();
2018-10-14 11:37:44 +02:00
}
2019-11-20 23:36:52 +01:00
static void TrySetApprenticeHeldItem(void)
2018-10-14 11:37:44 +02:00
{
u8 i, j;
2019-04-16 23:11:59 +02:00
u8 count;
2018-10-14 11:37:44 +02:00
2019-11-20 23:36:52 +01:00
if (PLAYER_APPRENTICE.questionsAnswered < NUM_WHICH_MON_QUESTIONS)
2018-10-14 11:37:44 +02:00
return;
count = 0;
for (j = 0; j < APPRENTICE_MAX_QUESTIONS; j++)
{
if (PLAYER_APPRENTICE.questions[j].questionId == QUESTION_ID_WIN_SPEECH)
break;
count++;
}
2018-10-14 11:37:44 +02:00
// Make sure the item hasn't already been suggested in previous questions
for (i = 0; i < count; i++)
2018-10-14 11:37:44 +02:00
{
if (i >= CURRENT_QUESTION_NUM)
break;
if (PLAYER_APPRENTICE.questions[i].questionId != QUESTION_ID_WHAT_ITEM ||
PLAYER_APPRENTICE.questions[i].suggestedChange == 0)
continue;
if (PLAYER_APPRENTICE.questions[i].data == gSpecialVar_0x8005)
2018-10-14 11:37:44 +02:00
{
2019-11-20 23:36:52 +01:00
PLAYER_APPRENTICE.questions[CURRENT_QUESTION_NUM].suggestedChange = FALSE;
PLAYER_APPRENTICE.questions[CURRENT_QUESTION_NUM].data = gSpecialVar_0x8005;
2019-11-15 00:56:18 +01:00
gSpecialVar_Result = FALSE;
2018-10-14 11:37:44 +02:00
return;
}
}
2019-11-20 23:36:52 +01:00
PLAYER_APPRENTICE.questions[CURRENT_QUESTION_NUM].suggestedChange = TRUE;
PLAYER_APPRENTICE.questions[CURRENT_QUESTION_NUM].data = gSpecialVar_0x8005;
2019-11-15 00:56:18 +01:00
gSpecialVar_Result = TRUE;
2018-10-14 11:37:44 +02:00
}
2019-11-20 23:36:52 +01:00
static void ShiftSavedApprentices(void)
2018-10-14 11:37:44 +02:00
{
s32 i;
2019-11-19 17:36:38 +01:00
s32 apprenticeNum;
s32 apprenticeIdx;
2018-10-14 11:37:44 +02:00
2018-10-14 14:35:51 +02:00
if (gSaveBlock2Ptr->apprentices[0].playerName[0] == EOS)
2018-10-14 11:37:44 +02:00
return;
2019-11-20 23:36:52 +01:00
for (i = 0; i < APPRENTICE_COUNT - 1; i++)
2018-10-14 11:37:44 +02:00
{
2018-10-14 14:35:51 +02:00
if (gSaveBlock2Ptr->apprentices[i + 1].playerName[0] == EOS)
2018-10-14 11:37:44 +02:00
{
2018-10-14 14:35:51 +02:00
gSaveBlock2Ptr->apprentices[i + 1] = gSaveBlock2Ptr->apprentices[0];
2018-10-14 11:37:44 +02:00
return;
}
}
2019-11-19 17:36:38 +01:00
apprenticeNum = 0xFFFF;
apprenticeIdx = -1;
2019-11-20 23:36:52 +01:00
for (i = 1; i < APPRENTICE_COUNT; i++)
2018-10-14 11:37:44 +02:00
{
2018-11-01 21:31:10 +01:00
if (GetTrainerId(gSaveBlock2Ptr->apprentices[i].playerId) == GetTrainerId(gSaveBlock2Ptr->playerTrainerId)
2019-11-19 17:36:38 +01:00
&& gSaveBlock2Ptr->apprentices[i].number < apprenticeNum)
2018-10-14 11:37:44 +02:00
{
2019-11-19 17:36:38 +01:00
apprenticeNum = gSaveBlock2Ptr->apprentices[i].number;
apprenticeIdx = i;
2018-10-14 11:37:44 +02:00
}
}
2019-11-19 17:36:38 +01:00
if (apprenticeIdx > 0)
gSaveBlock2Ptr->apprentices[apprenticeIdx] = gSaveBlock2Ptr->apprentices[0];
2018-10-14 11:37:44 +02:00
}
2019-11-20 23:36:52 +01:00
// Apprentice is always saved in the first slot. Pre-existing Apprentices are moved by ShiftSavedApprentices
static void SaveApprentice(void)
2018-10-14 11:37:44 +02:00
{
u8 i;
2018-10-14 16:27:48 +02:00
gSaveBlock2Ptr->apprentices[0].id = PLAYER_APPRENTICE.id;
2019-11-15 00:56:18 +01:00
gSaveBlock2Ptr->apprentices[0].lvlMode = PLAYER_APPRENTICE.lvlMode;
2018-10-14 11:37:44 +02:00
2019-11-20 23:36:52 +01:00
// Count questions asked until the final (win speech) question was reached
for (i = 0; i < APPRENTICE_MAX_QUESTIONS && (PLAYER_APPRENTICE.questions[i].questionId != QUESTION_ID_WIN_SPEECH); i++)
2018-10-14 11:37:44 +02:00
;
2019-11-20 23:36:52 +01:00
gSaveBlock2Ptr->apprentices[0].numQuestions = i;
2018-10-14 14:35:51 +02:00
if (gSaveBlock2Ptr->apprentices[0].number < 255)
gSaveBlock2Ptr->apprentices[0].number++;
2018-10-14 11:37:44 +02:00
2019-11-20 23:36:52 +01:00
SaveApprenticeParty(gSaveBlock2Ptr->apprentices[0].numQuestions);
2019-09-08 17:53:48 +02:00
for (i = 0; i < TRAINER_ID_LENGTH; i++)
2018-10-14 14:35:51 +02:00
gSaveBlock2Ptr->apprentices[0].playerId[i] = gSaveBlock2Ptr->playerTrainerId[i];
2018-10-14 11:37:44 +02:00
2018-10-14 14:35:51 +02:00
StringCopy(gSaveBlock2Ptr->apprentices[0].playerName, gSaveBlock2Ptr->playerName);
gSaveBlock2Ptr->apprentices[0].language = gGameLanguage;
CalcApprenticeChecksum(&gSaveBlock2Ptr->apprentices[0]);
2018-10-14 11:37:44 +02:00
}
2019-11-19 17:36:38 +01:00
// Never called, APPRENTICE_FUNC_SET_GFX_SAVED is unused
static void SetSavedApprenticeTrainerGfxId(void)
2018-10-14 11:37:44 +02:00
{
u8 i;
2019-11-21 07:40:38 +01:00
u8 objectEventGfxId;
2018-10-14 14:35:51 +02:00
u8 class = gApprentices[gSaveBlock2Ptr->apprentices[0].id].facilityClass;
2018-10-14 11:37:44 +02:00
2018-10-21 00:06:42 +02:00
for (i = 0; i < ARRAY_COUNT(gTowerMaleFacilityClasses) && gTowerMaleFacilityClasses[i] != class; i++)
2018-10-14 11:37:44 +02:00
;
2018-10-21 00:06:42 +02:00
if (i != ARRAY_COUNT(gTowerMaleFacilityClasses))
2018-10-14 11:37:44 +02:00
{
2019-11-21 07:40:38 +01:00
objectEventGfxId = gTowerMaleTrainerGfxIds[i];
VarSet(VAR_OBJ_GFX_ID_0, objectEventGfxId);
2018-10-21 00:06:42 +02:00
return;
2018-10-14 11:37:44 +02:00
}
2018-10-21 00:06:42 +02:00
for (i = 0; i < ARRAY_COUNT(gTowerFemaleFacilityClasses) && gTowerFemaleFacilityClasses[i] != class; i++)
;
if (i != ARRAY_COUNT(gTowerFemaleFacilityClasses))
{
2019-11-21 07:40:38 +01:00
objectEventGfxId = gTowerFemaleTrainerGfxIds[i];
VarSet(VAR_OBJ_GFX_ID_0, objectEventGfxId);
2018-10-14 11:37:44 +02:00
}
}
2019-11-19 17:36:38 +01:00
static void SetPlayerApprenticeTrainerGfxId(void)
2018-10-14 11:37:44 +02:00
{
u8 i;
2019-11-21 07:40:38 +01:00
u8 objectEventGfxId;
2018-10-14 16:27:48 +02:00
u8 class = gApprentices[PLAYER_APPRENTICE.id].facilityClass;
2018-10-14 11:37:44 +02:00
2018-10-21 00:06:42 +02:00
for (i = 0; i < ARRAY_COUNT(gTowerMaleFacilityClasses) && gTowerMaleFacilityClasses[i] != class; i++)
2018-10-14 11:37:44 +02:00
;
2018-10-21 00:06:42 +02:00
if (i != ARRAY_COUNT(gTowerMaleFacilityClasses))
2018-10-14 11:37:44 +02:00
{
2019-11-21 07:40:38 +01:00
objectEventGfxId = gTowerMaleTrainerGfxIds[i];
VarSet(VAR_OBJ_GFX_ID_0, objectEventGfxId);
2018-10-21 00:06:42 +02:00
return;
2018-10-14 11:37:44 +02:00
}
2018-10-21 00:06:42 +02:00
for (i = 0; i < ARRAY_COUNT(gTowerFemaleFacilityClasses) && gTowerFemaleFacilityClasses[i] != class; i++)
;
if (i != ARRAY_COUNT(gTowerFemaleFacilityClasses))
{
2019-11-21 07:40:38 +01:00
objectEventGfxId = gTowerFemaleTrainerGfxIds[i];
VarSet(VAR_OBJ_GFX_ID_0, objectEventGfxId);
2018-10-14 11:37:44 +02:00
}
}
2019-11-19 17:36:38 +01:00
// Both of the below functions may have been dummied / used for debug
2019-11-15 00:56:18 +01:00
// In all cases theres a conditional for VAR_0x8004 right after the call to these functions
2019-11-19 17:36:38 +01:00
static void GetShouldCheckApprenticeGone(void)
2018-10-14 11:37:44 +02:00
{
2019-11-15 00:56:18 +01:00
gSpecialVar_0x8004 = TRUE;
2018-10-14 11:37:44 +02:00
}
2019-11-15 00:56:18 +01:00
static void GetShouldApprenticeLeave(void)
2018-10-14 11:37:44 +02:00
{
2019-11-15 00:56:18 +01:00
gSpecialVar_0x8004 = TRUE;
2018-10-14 11:37:44 +02:00
}
const u8 *GetApprenticeNameInLanguage(u32 apprenticeId, s32 language)
{
const struct ApprenticeTrainer *apprentice = &gApprentices[apprenticeId];
switch (language)
{
case LANGUAGE_JAPANESE:
return apprentice->name[0];
case LANGUAGE_ENGLISH:
return apprentice->name[1];
case LANGUAGE_FRENCH:
return apprentice->name[2];
case LANGUAGE_ITALIAN:
return apprentice->name[3];
case LANGUAGE_GERMAN:
return apprentice->name[4];
case LANGUAGE_SPANISH:
default:
return apprentice->name[5];
}
}
2019-11-19 17:36:38 +01:00
// Functionally unused
static void Task_SwitchToFollowupFuncAfterButtonPress(u8 taskId)
2018-10-14 11:37:44 +02:00
{
2020-09-05 03:11:55 +02:00
if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON))
2018-10-14 11:37:44 +02:00
SwitchTaskToFollowupFunc(taskId);
}
static void Task_ExecuteFuncAfterButtonPress(u8 taskId)
{
2020-09-05 03:11:55 +02:00
if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON))
2018-10-14 11:37:44 +02:00
{
2022-07-29 16:52:35 +02:00
gApprenticeFunc = (void *)(u32)(((u16)gTasks[taskId].data[0] | (gTasks[taskId].data[1] << 16)));
2019-11-20 23:36:52 +01:00
gApprenticeFunc();
2018-10-14 11:37:44 +02:00
DestroyTask(taskId);
}
}
static void ExecuteFuncAfterButtonPress(void (*func)(void))
{
u8 taskId = CreateTask(Task_ExecuteFuncAfterButtonPress, 1);
gTasks[taskId].data[0] = (u32)(func);
gTasks[taskId].data[1] = (u32)(func) >> 16;
}
2019-11-19 17:36:38 +01:00
// Unused
static void ExecuteFollowupFuncAfterButtonPress(TaskFunc task)
2018-10-14 11:37:44 +02:00
{
2019-11-19 17:36:38 +01:00
u8 taskId = CreateTask(Task_SwitchToFollowupFuncAfterButtonPress, 1);
SetTaskFuncWithFollowupFunc(taskId, Task_SwitchToFollowupFuncAfterButtonPress, task);
2018-10-14 11:37:44 +02:00
}