diff options
author | GriffinR <griffin.richards@comcast.net> | 2019-11-20 19:00:08 -0500 |
---|---|---|
committer | GriffinR <griffin.richards@comcast.net> | 2019-11-20 19:00:08 -0500 |
commit | b2eb49888d497b5f04697bf4f6fe14904a3fafe3 (patch) | |
tree | ddd09188d3462261b526558989cce90c18900ec3 /src | |
parent | a05006421b29ac49ce7173bb431d8a0419f5c143 (diff) |
Clean up Apprentice doc
Diffstat (limited to 'src')
-rw-r--r-- | src/apprentice.c | 95 | ||||
-rw-r--r-- | src/record_mixing.c | 90 |
2 files changed, 107 insertions, 78 deletions
diff --git a/src/apprentice.c b/src/apprentice.c index 1cc6996fb..a4c0e0461 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -31,10 +31,37 @@ #include "constants/trainers.h" #include "constants/moves.h" +/* Summary of Apprentice, because (as of writing at least) its not very well documented online + * + * ## 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 + * + * ## 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 + */ + #define PLAYER_APPRENTICE gSaveBlock2Ptr->playerApprentice #define CURRENT_QUESTION_NUM PLAYER_APPRENTICE.questionsAnswered - NUM_WHICH_MON_QUESTIONS -// The below a TODO struct ApprenticePartyMovesData { u8 moveCounter; @@ -373,8 +400,8 @@ static void GetShouldCheckApprenticeGone(void); static void ApprenticeGetQuestion(void); static void GetNumApprenticePartyMonsAssigned(void); static void SetApprenticePartyMon(void); -static void InitApprenticeQuestionData(void); -static void FreeApprenticeQuestionData(void); +static void InitQuestionData(void); +static void FreeQuestionData(void); static void ApprenticeBufferString(void); static void SetApprenticeMonMove(void); static void SetLeadApprenticeMon(void); @@ -1044,32 +1071,32 @@ static const u8 sQuestionPossibilities[] = static void (* const sApprenticeFunctions[])(void) = { - [APPRENTICE_FUNC_GAVE_LVLMODE] = Script_GivenApprenticeLvlMode, - [APPRENTICE_FUNC_SET_LVLMODE] = Script_SetApprenticeLvlMode, - [APPRENTICE_FUNC_SET_ID] = Script_SetApprenticeId, - [APPRENTICE_FUNC_SHUFFLE_SPECIES] = ShuffleApprenticeSpecies, + [APPRENTICE_FUNC_GAVE_LVLMODE] = Script_GivenApprenticeLvlMode, + [APPRENTICE_FUNC_SET_LVLMODE] = Script_SetApprenticeLvlMode, + [APPRENTICE_FUNC_SET_ID] = Script_SetApprenticeId, + [APPRENTICE_FUNC_SHUFFLE_SPECIES] = ShuffleApprenticeSpecies, [APPRENTICE_FUNC_RANDOMIZE_QUESTIONS] = Script_SetRandomQuestionData, - [APPRENTICE_FUNC_ANSWERED_QUESTION] = IncrementQuestionsAnswered, - [APPRENTICE_FUNC_IS_FINAL_QUESTION] = IsFinalQuestion, - [APPRENTICE_FUNC_MENU] = Script_CreateApprenticeMenu, - [APPRENTICE_FUNC_PRINT_MSG] = Script_PrintApprenticeMessage, - [APPRENTICE_FUNC_RESET] = Script_ResetPlayerApprentice, - [APPRENTICE_FUNC_CHECK_GONE] = GetShouldCheckApprenticeGone, - [APPRENTICE_FUNC_GET_QUESTION] = ApprenticeGetQuestion, - [APPRENTICE_FUNC_GET_NUM_PARTY_MONS] = GetNumApprenticePartyMonsAssigned, - [APPRENTICE_FUNC_SET_PARTY_MON] = SetApprenticePartyMon, - [APPRENTICE_FUNC_INIT_QUESTION_DATA] = InitApprenticeQuestionData, - [APPRENTICE_FUNC_FREE_QUESTION_DATA] = FreeApprenticeQuestionData, - [APPRENTICE_FUNC_BUFFER_STRING] = ApprenticeBufferString, - [APPRENTICE_FUNC_SET_MOVE] = SetApprenticeMonMove, - [APPRENTICE_FUNC_SET_LEAD_MON] = SetLeadApprenticeMon, - [APPRENTICE_FUNC_OPEN_BAG] = Script_ApprenticeOpenBagMenu, - [APPRENTICE_FUNC_TRY_SET_HELD_ITEM] = TrySetApprenticeHeldItem, - [APPRENTICE_FUNC_SAVE] = SaveApprentice, - [APPRENTICE_FUNC_SET_GFX_SAVED] = SetSavedApprenticeTrainerGfxId, - [APPRENTICE_FUNC_SET_GFX] = SetPlayerApprenticeTrainerGfxId, - [APPRENTICE_FUNC_SHOULD_LEAVE] = GetShouldApprenticeLeave, - [APPRENTICE_FUNC_SHIFT_SAVED] = ShiftSavedApprentices, + [APPRENTICE_FUNC_ANSWERED_QUESTION] = IncrementQuestionsAnswered, + [APPRENTICE_FUNC_IS_FINAL_QUESTION] = IsFinalQuestion, + [APPRENTICE_FUNC_MENU] = Script_CreateApprenticeMenu, + [APPRENTICE_FUNC_PRINT_MSG] = Script_PrintApprenticeMessage, + [APPRENTICE_FUNC_RESET] = Script_ResetPlayerApprentice, + [APPRENTICE_FUNC_CHECK_GONE] = GetShouldCheckApprenticeGone, + [APPRENTICE_FUNC_GET_QUESTION] = ApprenticeGetQuestion, + [APPRENTICE_FUNC_GET_NUM_PARTY_MONS] = GetNumApprenticePartyMonsAssigned, + [APPRENTICE_FUNC_SET_PARTY_MON] = SetApprenticePartyMon, + [APPRENTICE_FUNC_INIT_QUESTION_DATA] = InitQuestionData, + [APPRENTICE_FUNC_FREE_QUESTION_DATA] = FreeQuestionData, + [APPRENTICE_FUNC_BUFFER_STRING] = ApprenticeBufferString, + [APPRENTICE_FUNC_SET_MOVE] = SetApprenticeMonMove, + [APPRENTICE_FUNC_SET_LEAD_MON] = SetLeadApprenticeMon, + [APPRENTICE_FUNC_OPEN_BAG] = Script_ApprenticeOpenBagMenu, + [APPRENTICE_FUNC_TRY_SET_HELD_ITEM] = TrySetApprenticeHeldItem, + [APPRENTICE_FUNC_SAVE] = SaveApprentice, + [APPRENTICE_FUNC_SET_GFX_SAVED] = SetSavedApprenticeTrainerGfxId, + [APPRENTICE_FUNC_SET_GFX] = SetPlayerApprenticeTrainerGfxId, + [APPRENTICE_FUNC_SHOULD_LEAVE] = GetShouldApprenticeLeave, + [APPRENTICE_FUNC_SHIFT_SAVED] = ShiftSavedApprentices, }; // The first Apprentice can only be one of these @@ -1079,7 +1106,7 @@ static const u8 sInitialApprenticeIds[8] = {0, 1, 2, 3, 6, 7, 8, 9}; void BufferApprenticeChallengeText(u8 saveApprenticeId) { u8 i, num; - const u8 *Intro; + const u8 *challengeText; num = gSaveBlock2Ptr->apprentices[saveApprenticeId].number; for (i = 0; num != 0 && i < APPRENTICE_COUNT; num /= 10, i++) @@ -1088,8 +1115,8 @@ void BufferApprenticeChallengeText(u8 saveApprenticeId) StringCopy7(gStringVar1, gSaveBlock2Ptr->apprentices[saveApprenticeId].playerName); ConvertInternationalString(gStringVar1, gSaveBlock2Ptr->apprentices[saveApprenticeId].language); ConvertIntToDecimalStringN(gStringVar2, gSaveBlock2Ptr->apprentices[saveApprenticeId].number, STR_CONV_MODE_RIGHT_ALIGN, i); - Intro = sApprenticeChallengeTexts[gSaveBlock2Ptr->apprentices[saveApprenticeId].id]; - StringExpandPlaceholders(gStringVar4, Intro); + challengeText = sApprenticeChallengeTexts[gSaveBlock2Ptr->apprentices[saveApprenticeId].id]; + StringExpandPlaceholders(gStringVar4, challengeText); } void Apprentice_EnableBothScriptContexts(void) @@ -1112,7 +1139,7 @@ void ResetAllApprenticeData(void) { u8 i, j; - PLAYER_APPRENTICE.field_B2_1 = 0; + PLAYER_APPRENTICE.saveId = 0; for (i = 0; i < APPRENTICE_COUNT; i++) { for (j = 0; j < ARRAY_COUNT(gSaveBlock2Ptr->apprentices[i].speechWon); j++) @@ -1944,7 +1971,7 @@ static void SetApprenticeMonMove(void) } } -static void InitApprenticeQuestionData(void) +static void InitQuestionData(void) { u8 i; u8 count = 0; @@ -1994,7 +2021,7 @@ static void InitApprenticeQuestionData(void) } } -static void FreeApprenticeQuestionData(void) +static void FreeQuestionData(void) { FREE_AND_SET_NULL(gApprenticeQuestionData); } diff --git a/src/record_mixing.c b/src/record_mixing.c index ac8c8a8a3..0a3b22a28 100644 --- a/src/record_mixing.c +++ b/src/record_mixing.c @@ -69,7 +69,7 @@ struct PlayerRecordsEmerald /* 0x1124 */ struct EmeraldBattleTowerRecord battleTowerRecord; /* 0x1210 */ u16 giftItem; /* 0x1214 */ LilycoveLady lilycoveLady; - /* 0x1254 */ struct Apprentice apprentice[2]; + /* 0x1254 */ struct Apprentice apprentices[2]; /* 0x12dc */ struct PlayerHallRecords hallRecords; /* 0x1434 */ u8 field_1434[0x10]; }; // 0x1444 @@ -120,8 +120,8 @@ static void sub_80E7B2C(const u8 *); static void ReceiveDaycareMailData(struct RecordMixingDayCareMail *, size_t, u8, TVShow *); static void ReceiveGiftItem(u16 *item, u8 which); static void Task_DoRecordMixing(u8 taskId); -static void sub_80E8110(struct Apprentice *arg0, struct Apprentice *arg1); -static void ReceiveApprenticeData(struct Apprentice *arg0, size_t arg1, u32 arg2); +static void GetSavedApprentices(struct Apprentice *dst, struct Apprentice *src); +static void ReceiveApprenticeData(struct Apprentice *mixApprentice, size_t recordSize, u32 multiplayerId); static void ReceiveRankingHallRecords(struct PlayerHallRecords *hallRecords, size_t arg1, u32 arg2); static void sub_80E89F8(struct RecordMixingDayCareMail *dst); static void SanitizeDayCareMailForRuby(struct RecordMixingDayCareMail *src); @@ -252,7 +252,7 @@ static void PrepareExchangePacket(void) if (GetMultiplayerId() == 0) sSentRecord->emerald.giftItem = GetRecordMixingGift(); - sub_80E8110(sSentRecord->emerald.apprentice, sApprenticesSave); + GetSavedApprentices(sSentRecord->emerald.apprentices, sApprenticesSave); GetPlayerHallRecords(&sSentRecord->emerald.hallRecords); } } @@ -285,7 +285,7 @@ static void ReceiveExchangePacket(u32 which) ReceiveBattleTowerData(&sReceivedRecords->emerald.battleTowerRecord, sizeof(struct PlayerRecordsEmerald), which); ReceiveGiftItem(&sReceivedRecords->emerald.giftItem, which); ReceiveLilycoveLadyData(&sReceivedRecords->emerald.lilycoveLady, sizeof(struct PlayerRecordsEmerald), which); - ReceiveApprenticeData(sReceivedRecords->emerald.apprentice, sizeof(struct PlayerRecordsEmerald), (u8) which); + ReceiveApprenticeData(sReceivedRecords->emerald.apprentices, sizeof(struct PlayerRecordsEmerald), (u8) which); ReceiveRankingHallRecords(&sReceivedRecords->emerald.hallRecords, sizeof(struct PlayerRecordsEmerald), (u8) which); } } @@ -651,7 +651,7 @@ static void ReceiveBattleTowerData(void *battleTowerRecord, size_t recordSize, u { struct EmeraldBattleTowerRecord *dest; struct BattleTowerPokemon *btPokemon; - u32 mixIndices[4]; + u32 mixIndices[MAX_LINK_PLAYERS]; s32 i; ShufflePlayerIndices(mixIndices); @@ -682,7 +682,7 @@ static void ReceiveBattleTowerData(void *battleTowerRecord, size_t recordSize, u static void ReceiveLilycoveLadyData(LilycoveLady *lilycoveLady, size_t recordSize, u8 which) { LilycoveLady *dest; - u32 mixIndices[4]; + u32 mixIndices[MAX_LINK_PLAYERS]; ShufflePlayerIndices(mixIndices); memcpy((void *)lilycoveLady + recordSize * which, sLilycoveLadySave, sizeof(LilycoveLady)); @@ -1018,57 +1018,59 @@ static void Task_DoRecordMixing(u8 taskId) // New Emerald functions -static void sub_80E8110(struct Apprentice *dst, struct Apprentice *src) +static void GetSavedApprentices(struct Apprentice *dst, struct Apprentice *src) { s32 i, id; - s32 var_2C, var_28, var_24, r8; + s32 apprenticeSaveId, oldPlayerApprenticeSaveId; + s32 numOldPlayerApprentices, numMixApprentices; dst[0].playerName[0] = EOS; dst[1].playerName[0] = EOS; dst[0] = src[0]; - var_28 = 0; - var_24 = 0; - var_2C = 0; - r8 = 0; + oldPlayerApprenticeSaveId = 0; + numOldPlayerApprentices = 0; + apprenticeSaveId = 0; + numMixApprentices = 0; for (i = 0; i < 2; i++) { - id = ((i + gSaveBlock2Ptr->playerApprentice.field_B2_1) % 3) + 1; + id = ((i + gSaveBlock2Ptr->playerApprentice.saveId) % 3) + 1; if (src[id].playerName[0] != EOS) { if (GetTrainerId(src[id].playerId) != GetTrainerId(gSaveBlock2Ptr->playerTrainerId)) { - r8++; - var_2C = id; + numMixApprentices++; + apprenticeSaveId = id; } if (GetTrainerId(src[id].playerId) == GetTrainerId(gSaveBlock2Ptr->playerTrainerId)) { - var_24++; - var_28 = id; + numOldPlayerApprentices++; + oldPlayerApprenticeSaveId = id; } } } - if (r8 == 0 && var_24 != 0) + // Prefer passing on other mixed Apprentices rather than old player's Apprentices + if (numMixApprentices == 0 && numOldPlayerApprentices != 0) { - r8 = var_24; - var_2C = var_28; + numMixApprentices = numOldPlayerApprentices; + apprenticeSaveId = oldPlayerApprenticeSaveId; } - switch (r8) + switch (numMixApprentices) { case 1: - dst[1] = src[var_2C]; + dst[1] = src[apprenticeSaveId]; break; case 2: if (Random2() > 0x3333) { - dst[1] = src[gSaveBlock2Ptr->playerApprentice.field_B2_1 + 1]; + dst[1] = src[gSaveBlock2Ptr->playerApprentice.saveId + 1]; } else { - dst[1] = src[((gSaveBlock2Ptr->playerApprentice.field_B2_1 + 1) % 3 + 1)]; + dst[1] = src[((gSaveBlock2Ptr->playerApprentice.saveId + 1) % 3 + 1)]; } break; } @@ -1113,7 +1115,7 @@ void GetPlayerHallRecords(struct PlayerHallRecords *dst) } } -static bool32 sub_80E841C(struct Apprentice *mixApprentice, struct Apprentice *apprentices) +static bool32 IsApprenticeAlreadySaved(struct Apprentice *mixApprentice, struct Apprentice *apprentices) { s32 i; @@ -1129,40 +1131,40 @@ static bool32 sub_80E841C(struct Apprentice *mixApprentice, struct Apprentice *a return FALSE; } -static void ReceiveApprenticeData(struct Apprentice *arg0, size_t arg1, u32 arg2) +static void ReceiveApprenticeData(struct Apprentice *mixApprentice, size_t recordSize, u32 multiplayerId) { - s32 i, r7, r8; - struct Apprentice *structPtr; - u32 mixIndices[4]; - u32 structId; + s32 i, numApprentices, apprenticeId; + struct Apprentice *mixApprenticePtr; + u32 mixIndices[MAX_LINK_PLAYERS]; + u32 apprenticeSaveId; ShufflePlayerIndices(mixIndices); - structPtr = (void*)(arg0) + (arg1 * mixIndices[arg2]); - r7 = 0; - r8 = 0; + mixApprenticePtr = (void*)(mixApprentice) + (recordSize * mixIndices[multiplayerId]); + numApprentices = 0; + apprenticeId = 0; for (i = 0; i < 2; i++) { - if (structPtr[i].playerName[0] != EOS && !sub_80E841C(&structPtr[i], &gSaveBlock2Ptr->apprentices[0])) + if (mixApprenticePtr[i].playerName[0] != EOS && !IsApprenticeAlreadySaved(&mixApprenticePtr[i], &gSaveBlock2Ptr->apprentices[0])) { - r7++; - r8 = i; + numApprentices++; + apprenticeId = i; } } - switch (r7) + switch (numApprentices) { case 1: - structId = gSaveBlock2Ptr->playerApprentice.field_B2_1 + 1; - gSaveBlock2Ptr->apprentices[structId] = structPtr[r8]; - gSaveBlock2Ptr->playerApprentice.field_B2_1 = (gSaveBlock2Ptr->playerApprentice.field_B2_1 + 1) % 3; + apprenticeSaveId = gSaveBlock2Ptr->playerApprentice.saveId + 1; + gSaveBlock2Ptr->apprentices[apprenticeSaveId] = mixApprenticePtr[apprenticeId]; + gSaveBlock2Ptr->playerApprentice.saveId = (gSaveBlock2Ptr->playerApprentice.saveId + 1) % 3; break; case 2: for (i = 0; i < 2; i++) { - structId = ((i ^ 1) + gSaveBlock2Ptr->playerApprentice.field_B2_1) % 3 + 1; - gSaveBlock2Ptr->apprentices[structId] = structPtr[i]; + apprenticeSaveId = ((i ^ 1) + gSaveBlock2Ptr->playerApprentice.saveId) % 3 + 1; + gSaveBlock2Ptr->apprentices[apprenticeSaveId] = mixApprenticePtr[i]; } - gSaveBlock2Ptr->playerApprentice.field_B2_1 = (gSaveBlock2Ptr->playerApprentice.field_B2_1 + 2) % 3; + gSaveBlock2Ptr->playerApprentice.saveId = (gSaveBlock2Ptr->playerApprentice.saveId + 2) % 3; break; } } |