From f4e55999a5282dc1d2b94e0ca14081de6aae93ba Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sat, 20 Oct 2018 00:33:51 +0200 Subject: begin porting and decomping battle tower --- src/battle_tower.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 2 deletions(-) (limited to 'src/battle_tower.c') diff --git a/src/battle_tower.c b/src/battle_tower.c index e70d4af91..a6983897f 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -4,16 +4,24 @@ #include "overworld.h" #include "random.h" #include "battle_tower.h" +#include "battle_frontier_1.h" +#include "constants/battle_frontier.h" extern void sub_81A3ACC(void); +extern u8 GetFrontierEnemyMonLevel(u8); extern const u32 gUnknown_085DF9AC[][2]; extern const u32 gUnknown_085DF9CC[][2]; extern void (* const gUnknown_085DF96C[])(void); +extern const u8 gUnknown_085DF9F6[]; +extern const u8 gUnknown_085DF9EC[]; // This file's functions. void sub_8164ED8(void); -u16 sub_8164FCC(u8, u8); +void sub_8163E90(void); +void sub_8165B20(void); +u16 GetCurrentBattleTowerWinStreak(u8 lvlMode, u8 battleMode); +void sub_816534C(void *); // code void sub_8161F74(void) @@ -49,7 +57,7 @@ void sub_8162054(void) case 0: break; case 1: - gSpecialVar_Result = sub_8164FCC(lvlMode, battleMode); + gSpecialVar_Result = GetCurrentBattleTowerWinStreak(lvlMode, battleMode); break; case 2: gSpecialVar_Result = ((gSaveBlock2Ptr->frontier.field_CDC & gUnknown_085DF9AC[battleMode][lvlMode]) != 0); @@ -83,3 +91,84 @@ void sub_81620F4(void) break; } } + +void sub_81621C0(void) +{ + if (gTrainerBattleOpponent_A == 500) + sub_816534C(&gSaveBlock2Ptr->frontier.filler_BEC); + + if (gSaveBlock2Ptr->frontier.field_D04 < 9999) + gSaveBlock2Ptr->frontier.field_D04++; + + gSaveBlock2Ptr->frontier.field_CB2++; + sub_8163E90(); + gSpecialVar_Result = gSaveBlock2Ptr->frontier.field_CB2; +} + +bool8 ChooseSpecialBattleTowerTrainer(void) +{ + s32 i, j, validMons; + s32 trainerIds[9]; + s32 idsCount = 0; + s32 winStreak = 0; + u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; + u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); + + if (VarGet(VAR_FRONTIER_FACILITY) != FRONTIER_FACILITY_TOWER) + return FALSE; + + winStreak = GetCurrentBattleTowerWinStreak(lvlMode, battleMode); + for (i = 0; i < 5; i++) + { + u32 *record = (u32*)(&gSaveBlock2Ptr->frontier.records[i]); + u32 recordHasData = 0; + u32 checksum = 0; + for (j = 0; j < (sizeof(struct EmeraldBattleTowerRecord) - 4) / 4; j++) // - 4, because of the last field being the checksum itself. + { + recordHasData |= record[j]; + checksum += record[j]; + } + validMons = 0; + for (j = 0; j < 4; j++) + { + if (gSaveBlock2Ptr->frontier.records[i].party[j].species != 0 + && gSaveBlock2Ptr->frontier.records[i].party[j].level <= GetFrontierEnemyMonLevel(lvlMode)) + validMons++; + } + + if (validMons >= gUnknown_085DF9F6[battleMode] + && gSaveBlock2Ptr->frontier.records[i].winStreak == winStreak + && gSaveBlock2Ptr->frontier.records[i].lvlMode == lvlMode + && recordHasData + && gSaveBlock2Ptr->frontier.records[i].checksum == checksum) + { + trainerIds[idsCount] = i + BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID; + idsCount++; + } + } + + if (battleMode == FRONTIER_MODE_SINGLES) + { + sub_8165B20(); + for (i = 0; i < 4; i++) + { + if (gSaveBlock2Ptr->apprentices[i].lvlMode != 0 + && gUnknown_085DF9EC[gSaveBlock2Ptr->apprentices[i].field_1] == winStreak + && gSaveBlock2Ptr->apprentices[i].lvlMode - 1 == lvlMode) + { + trainerIds[idsCount] = i + BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID; + idsCount++; + } + } + } + + if (idsCount != 0) + { + gTrainerBattleOpponent_A = trainerIds[Random() % idsCount]; + return TRUE; + } + else + { + return FALSE; + } +} -- cgit v1.2.3 From 16026fe91d5628f138be434841ae764534946b2c Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sun, 21 Oct 2018 00:06:42 +0200 Subject: More battle tower. --- src/battle_tower.c | 977 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 971 insertions(+), 6 deletions(-) (limited to 'src/battle_tower.c') diff --git a/src/battle_tower.c b/src/battle_tower.c index a6983897f..b9451aecd 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -1,27 +1,55 @@ #include "global.h" +#include "battle_tower.h" +#include "apprentice.h" #include "event_data.h" #include "battle_setup.h" #include "overworld.h" #include "random.h" -#include "battle_tower.h" +#include "text.h" +#include "international_string_util.h" +#include "battle.h" #include "battle_frontier_1.h" +#include "battle_frontier_2.h" +#include "recorded_battle.h" +#include "easy_chat.h" #include "constants/battle_frontier.h" +#include "constants/trainers.h" +#include "constants/event_objects.h" +#include "constants/moves.h" extern void sub_81A3ACC(void); +extern void CreateFrontierBrainPokemon(void); +extern void sub_81A6CD0(void); extern u8 GetFrontierEnemyMonLevel(u8); +extern u8 GetFacilityEnemyMonLevel(void); +extern u16 sub_81A39C4(void); +extern void SetFrontierBrainTrainerGfxId(void); +extern u8 GetFrontierBrainTrainerPicIndex(void); +extern u8 GetFrontierBrainTrainerClass(void); +extern u8 IsFrontierBrainFemale(void); +extern void CopyFrontierBrainTrainerName(u8 *dst); +extern void SetMonMoveAvoidReturn(struct Pokemon *mon, u16 move, u8 moveSlot); extern const u32 gUnknown_085DF9AC[][2]; extern const u32 gUnknown_085DF9CC[][2]; extern void (* const gUnknown_085DF96C[])(void); extern const u8 gUnknown_085DF9F6[]; extern const u8 gUnknown_085DF9EC[]; +extern const u16 gBattleFrontierHeldItems[]; // This file's functions. void sub_8164ED8(void); void sub_8163E90(void); void sub_8165B20(void); +void sub_8165E18(void); u16 GetCurrentBattleTowerWinStreak(u8 lvlMode, u8 battleMode); void sub_816534C(void *); +u16 sub_8162548(u8, u8); +void sub_81630C4(u16 trainerId, u8 firstMonId, u8 monCount); +void sub_8165EA4(u16 trainerId, u8 firstMonId, u8 monCount); +void sub_81635D4(u16 trainerId, u8 firstMonId); +void sub_816379C(u16 trainerId, u8 firstMonId); +u8 GetFrontierTrainerFixedIvs(u16 trainerId); // code void sub_8161F74(void) @@ -35,7 +63,7 @@ void sub_8161F94(void) u32 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); gSaveBlock2Ptr->frontier.field_CA8 = 1; - gSaveBlock2Ptr->frontier.field_CB2 = 0; + gSaveBlock2Ptr->frontier.curChallengeBattleNum = 0; gSaveBlock2Ptr->frontier.field_CA9_a = 0; gSaveBlock2Ptr->frontier.field_CA9_b = 0; sub_81A3ACC(); @@ -94,15 +122,15 @@ void sub_81620F4(void) void sub_81621C0(void) { - if (gTrainerBattleOpponent_A == 500) - sub_816534C(&gSaveBlock2Ptr->frontier.filler_BEC); + if (gTrainerBattleOpponent_A == BATTLE_TOWER_EREADER_TRAINER_ID) + sub_816534C(&gSaveBlock2Ptr->frontier.ereaderTrainer); if (gSaveBlock2Ptr->frontier.field_D04 < 9999) gSaveBlock2Ptr->frontier.field_D04++; - gSaveBlock2Ptr->frontier.field_CB2++; + gSaveBlock2Ptr->frontier.curChallengeBattleNum++; sub_8163E90(); - gSpecialVar_Result = gSaveBlock2Ptr->frontier.field_CB2; + gSpecialVar_Result = gSaveBlock2Ptr->frontier.curChallengeBattleNum; } bool8 ChooseSpecialBattleTowerTrainer(void) @@ -172,3 +200,940 @@ bool8 ChooseSpecialBattleTowerTrainer(void) return FALSE; } } + +void ChooseNextBattleTowerTrainer(void) +{ + u32 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; + if (lvlMode == FRONTIER_LVL_TENT) + { + sub_8165E18(); + } + else + { + u16 id; + u32 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); + u32 r5 = sub_81A39C4() / 7; + GetFacilityEnemyMonLevel(); // Pointless function call. + + if (battleMode == FRONTIER_MODE_MULTIS || battleMode == FRONTIER_MODE_LINK_MULTIS) + { + id = gSaveBlock2Ptr->frontier.curChallengeBattleNum; + gTrainerBattleOpponent_A = gSaveBlock2Ptr->frontier.battledTrainerIds[id * 2]; + gTrainerBattleOpponent_B = gSaveBlock2Ptr->frontier.battledTrainerIds[id * 2 + 1]; + SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_A, 0); + SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_B, 1); + } + else if (ChooseSpecialBattleTowerTrainer()) + { + SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_A, 0); + gSaveBlock2Ptr->frontier.battledTrainerIds[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = gTrainerBattleOpponent_A; + } + else + { + s32 i; + while (1) + { + id = sub_8162548(r5, gSaveBlock2Ptr->frontier.curChallengeBattleNum); + + // Ensure trainer wasn't previously fought in this challenge. + for (i = 0; i < gSaveBlock2Ptr->frontier.curChallengeBattleNum; i++) + { + if (gSaveBlock2Ptr->frontier.battledTrainerIds[i] == id) + break; + } + if (i == gSaveBlock2Ptr->frontier.curChallengeBattleNum) + break; + } + + gTrainerBattleOpponent_A = id; + SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_A, 0); + if (gSaveBlock2Ptr->frontier.curChallengeBattleNum + 1 < 7) + gSaveBlock2Ptr->frontier.battledTrainerIds[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = gTrainerBattleOpponent_A; + } + } +} + +extern const u16 gUnknown_085DFA1A[][2]; +extern const u16 gUnknown_085DF9FA[][2]; + +u16 sub_8162548(u8 challengeNum, u8 battleNum) +{ + u16 trainerId; + + if (challengeNum <= 7) + { + if (battleNum == 6) + { + trainerId = (gUnknown_085DFA1A[challengeNum][1] - gUnknown_085DFA1A[challengeNum][0]) + 1; + trainerId = gUnknown_085DFA1A[challengeNum][0] + (Random() % trainerId); + } + else + { + trainerId = (gUnknown_085DF9FA[challengeNum][1] - gUnknown_085DF9FA[challengeNum][0]) + 1; + trainerId = gUnknown_085DF9FA[challengeNum][0] + (Random() % trainerId); + } + } + else + { + trainerId = (gUnknown_085DF9FA[7][1] - gUnknown_085DF9FA[7][0]) + 1; + trainerId = gUnknown_085DF9FA[7][0] + (Random() % trainerId); + } + + return trainerId; +} + +#ifdef NONMATCHING +u16 sub_81625B4(u8 challengeNum, u8 battleNum, u16 *trainerIdPtr, u8 *arg3) // Unused +{ + register u16 trainerId, count; + + if (challengeNum <= 7) + { + if (battleNum == 6) + { + count = (gUnknown_085DFA1A[challengeNum][1] - gUnknown_085DFA1A[challengeNum][0]) + 1; + trainerId = gUnknown_085DFA1A[challengeNum][0]; + } + else + { + count = (gUnknown_085DF9FA[challengeNum][1] - gUnknown_085DF9FA[challengeNum][0]) + 1; + trainerId = gUnknown_085DF9FA[challengeNum][0]; + } + } + else + { + count = (gUnknown_085DF9FA[7][1] - gUnknown_085DF9FA[7][0]) + 1; + trainerId = gUnknown_085DF9FA[7][0]; + } + + *trainerIdPtr = trainerId; + *arg3 = count; +} +#else +NAKED +u16 sub_81625B4(u8 challengeNum, u8 battleNum, u16 *trainerIdPtr, u8 *arg3) +{ + asm_unified(" push {r4,lr}\n\ + adds r4, r2, 0\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + adds r2, r0, 0\n\ + lsls r1, 24\n\ + lsrs r1, 24\n\ + cmp r0, 0x7\n\ + bhi _081625F4\n\ + cmp r1, 0x6\n\ + bne _081625D4\n\ + ldr r1, =gUnknown_085DFA1A\n\ + lsls r2, r0, 2\n\ + b _081625D8\n\ + .pool\n\ +_081625D4:\n\ + ldr r1, =gUnknown_085DF9FA\n\ + lsls r2, 2\n\ +_081625D8:\n\ + adds r0, r1, 0x2\n\ + adds r0, r2, r0\n\ + adds r2, r1\n\ + ldrh r0, [r0]\n\ + ldrh r1, [r2]\n\ + subs r0, r1\n\ + adds r0, 0x1\n\ + lsls r0, 16\n\ + lsrs r1, r0, 16\n\ + ldrh r0, [r2]\n\ + b _08162604\n\ + .pool\n\ +_081625F4:\n\ + ldr r0, =gUnknown_085DF9FA\n\ + ldrh r1, [r0, 0x1E]\n\ + ldrh r2, [r0, 0x1C]\n\ + subs r1, r2\n\ + adds r1, 0x1\n\ + lsls r1, 16\n\ + lsrs r1, 16\n\ + ldrh r0, [r0, 0x1C]\n\ +_08162604:\n\ + strh r0, [r4]\n\ + strb r1, [r3]\n\ + pop {r4}\n\ + pop {r0}\n\ + bx r0\n\ + .pool"); +} +#endif + +void SetBattleFacilityTrainerGfxId(u16 trainerId, u8 tempVarId) +{ + u32 i; + u8 facilityClass; + u8 trainerObjectGfxId; + + GetFacilityEnemyMonLevel(); // Pointless function call. + if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + { + facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; + } + else if (trainerId == TRAINER_FRONTIER_BRAIN) + { + SetFrontierBrainTrainerGfxId(); + return; + } + else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + facilityClass = gFacilityTrainers[trainerId].facilityClass; + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + facilityClass = gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; + } + else + { + facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id].facilityClass; + } + + // Search male classes. + for (i = 0; i < ARRAY_COUNT(gTowerMaleFacilityClasses); i++) + { + if (gTowerMaleFacilityClasses[i] == facilityClass) + break; + } + if (i != ARRAY_COUNT(gTowerMaleFacilityClasses)) + { + trainerObjectGfxId = gTowerMaleTrainerGfxIds[i]; + switch (tempVarId) + { + case 0: + default: + VarSet(VAR_OBJ_GFX_ID_0, trainerObjectGfxId); + return; + case 1: + VarSet(VAR_OBJ_GFX_ID_1, trainerObjectGfxId); + return; + case 15: + VarSet(VAR_OBJ_GFX_ID_E, trainerObjectGfxId); + return; + } + } + + // Search female classes. + for (i = 0; i < ARRAY_COUNT(gTowerFemaleFacilityClasses); i++) + { + if (gTowerFemaleFacilityClasses[i] == facilityClass) + break; + } + if (i != ARRAY_COUNT(gTowerFemaleFacilityClasses)) + { + trainerObjectGfxId = gTowerFemaleTrainerGfxIds[i]; + switch (tempVarId) + { + case 0: + default: + VarSet(VAR_OBJ_GFX_ID_0, trainerObjectGfxId); + return; + case 1: + VarSet(VAR_OBJ_GFX_ID_1, trainerObjectGfxId); + return; + case 15: + VarSet(VAR_OBJ_GFX_ID_E, trainerObjectGfxId); + return; + } + } + + switch (tempVarId) + { + case 0: + default: + VarSet(VAR_OBJ_GFX_ID_0, EVENT_OBJ_GFX_BOY_1); + return; + case 1: + VarSet(VAR_OBJ_GFX_ID_1, EVENT_OBJ_GFX_BOY_1); + return; + case 15: + VarSet(VAR_OBJ_GFX_ID_E, EVENT_OBJ_GFX_BOY_1); + return; + } +} + +void SetEReaderTrainerGfxId(void) +{ + SetBattleFacilityTrainerGfxId(BATTLE_TOWER_EREADER_TRAINER_ID, 0); +} + +u8 GetBattleFacilityTrainerGfxId(u16 trainerId) +{ + u32 i; + u8 facilityClass; + u8 trainerObjectGfxId; + + GetFacilityEnemyMonLevel(); // Pointless function call. + if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + { + facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; + } + else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + facilityClass = gFacilityTrainers[trainerId].facilityClass; + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + facilityClass = gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; + } + else + { + facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id].facilityClass; + } + + // Search male classes. + for (i = 0; i < ARRAY_COUNT(gTowerMaleFacilityClasses); i++) + { + if (gTowerMaleFacilityClasses[i] == facilityClass) + break; + } + if (i != ARRAY_COUNT(gTowerMaleFacilityClasses)) + { + trainerObjectGfxId = gTowerMaleTrainerGfxIds[i]; + return trainerObjectGfxId; + } + + // Search female classes. + for (i = 0; i < ARRAY_COUNT(gTowerFemaleFacilityClasses); i++) + { + if (gTowerFemaleFacilityClasses[i] == facilityClass) + break; + } + if (i != ARRAY_COUNT(gTowerFemaleFacilityClasses)) + { + trainerObjectGfxId = gTowerFemaleTrainerGfxIds[i]; + return trainerObjectGfxId; + } + else + { + return EVENT_OBJ_GFX_BOY_1; + } +} + +void PutNewBattleTowerRecord(union BattleTowerRecord *newRecord) +{ + u16 slotValues[6]; + u16 slotIds[6]; + s32 i, j, k; + s32 slotsCount = 0; + struct EmeraldBattleTowerRecord *newRecordEm = &newRecord->emerald; + + // Find a record slot of the same player and replace it. + for (i = 0; i < 5; i++) + { + k = 0; + for (j = 0; j < 4; j++) + { + if (gSaveBlock2Ptr->frontier.records[i].trainerId[j] != newRecordEm->trainerId[j]) + break; + } + if (j == 4) + { + for (k = 0; k < PLAYER_NAME_LENGTH; k++) + { + // BUG: Wrong variable used, 'j' instead of 'k'. + if (gSaveBlock2Ptr->frontier.records[i].name[j] != newRecordEm->name[j]) + break; + if (newRecordEm->name[j] == EOS) + { + k = PLAYER_NAME_LENGTH; + break; + } + } + } + + if (k == PLAYER_NAME_LENGTH) + break; + } + if (i < 5) + { + gSaveBlock2Ptr->frontier.records[i] = *newRecordEm; + return; + } + + // Find an empty record slot. + for (i = 0; i < 5; i++) + { + if (gSaveBlock2Ptr->frontier.records[i].winStreak == 0) + break; + } + if (i < 5) + { + gSaveBlock2Ptr->frontier.records[i] = *newRecordEm; + return; + } + + // Find possible slots to replace the record. + slotValues[0] = gSaveBlock2Ptr->frontier.records[0].winStreak; + slotIds[0] = 0; + slotsCount++; + + for (i = 1; i < 5; i++) + { + for (j = 0; j < slotsCount; j++) + { + if (gSaveBlock2Ptr->frontier.records[i].winStreak < slotValues[j]) + { + j = 0; + slotsCount = 1; + slotValues[0] = gSaveBlock2Ptr->frontier.records[i].winStreak; + slotIds[0] = i; + break; + } + else if (gSaveBlock2Ptr->frontier.records[i].winStreak > slotValues[j]) + { + break; + } + } + + if (j == slotsCount) + { + slotValues[slotsCount] = gSaveBlock2Ptr->frontier.records[i].winStreak; + slotIds[slotsCount] = i; + slotsCount++; + } + } + + i = Random() % slotsCount; + gSaveBlock2Ptr->frontier.records[slotIds[i]] = *newRecordEm; +} + +u8 GetFrontierTrainerFrontSpriteId(u16 trainerId) +{ + GetFacilityEnemyMonLevel(); // Pointless function call + + if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + { + return gFacilityClassToPicIndex[gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass]; + } + else if (trainerId == TRAINER_FRONTIER_BRAIN) + { + return GetFrontierBrainTrainerPicIndex(); + } + else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + return gFacilityClassToPicIndex[gFacilityTrainers[trainerId].facilityClass]; + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + return gFacilityClassToPicIndex[sub_818649C()]; + else + return gFacilityClassToPicIndex[gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass]; + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + return gFacilityClassToPicIndex[gApprentices[sub_81864A8()].facilityClass]; + else + return gFacilityClassToPicIndex[gApprentices[gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id].facilityClass]; + } +} + +u8 GetFrontierOpponentClass(u16 trainerId) +{ + u8 trainerClass = 0; + GetFacilityEnemyMonLevel(); // Pointless function call. + + if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + { + trainerClass = gFacilityClassToTrainerClass[gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass]; + } + else if (trainerId == TRAINER_FRONTIER_BRAIN) + { + trainerClass = GetFrontierBrainTrainerClass(); + } + else if (trainerId == TRAINER_STEVEN_PARTNER) + { + trainerClass = gTrainers[TRAINER_STEVEN].trainerClass; + } + else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + trainerClass = gFacilityClassToTrainerClass[gFacilityTrainers[trainerId].facilityClass]; + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + { + trainerClass = gFacilityClassToTrainerClass[sub_818649C()]; + } + else + { + trainerClass = gFacilityClassToTrainerClass[gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass]; + asm(""); + } + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + { + trainerClass = gFacilityClassToTrainerClass[gApprentices[sub_81864A8()].facilityClass]; + } + else + { + trainerClass = gFacilityClassToTrainerClass[gApprentices[gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id].facilityClass]; + asm(""); + } + } + + return trainerClass; +} + +u8 GetFrontierTrainerFacilityClass(u16 trainerId) +{ + u8 facilityClass; + GetFacilityEnemyMonLevel(); // Pointless function call. + + if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + { + facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; + } + else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + facilityClass = gFacilityTrainers[trainerId].facilityClass; + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + facilityClass = sub_818649C(); + else + facilityClass = gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + facilityClass = gApprentices[sub_81864A8()].facilityClass; + else + facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id].facilityClass; + } + + return facilityClass; +} + +void GetFrontierTrainerName(u8 *dst, u16 trainerId) +{ + s32 i = 0; + GetFacilityEnemyMonLevel(); // Pointless function call. + + if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + { + for (i = 0; i < PLAYER_NAME_LENGTH; i++) + dst[i] = gSaveBlock2Ptr->frontier.ereaderTrainer.name[i]; + } + else if (trainerId == TRAINER_FRONTIER_BRAIN) + { + CopyFrontierBrainTrainerName(dst); + return; + } + else if (trainerId == TRAINER_STEVEN_PARTNER) + { + for (i = 0; i < PLAYER_NAME_LENGTH; i++) + dst[i] = gTrainers[TRAINER_STEVEN].trainerName[i]; + } + else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + for (i = 0; i < PLAYER_NAME_LENGTH; i++) + dst[i] = gFacilityTrainers[trainerId].trainerName[i]; + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + { + sub_8186468(dst); + return; + } + else + { + struct EmeraldBattleTowerRecord *record = &gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID]; + TVShowConvertInternationalString(dst, record->name, record->language); + return; + } + } + else + { + u8 id, language; + + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + { + id = sub_81864A8(); + language = sub_81864C0(); + } + else + { + struct Apprentice *apprentice = &gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID]; + id = apprentice->id; + language = apprentice->language; + } + TVShowConvertInternationalString(dst, GetApprenticeNameInLanguage(id, language), language); + return; + } + + dst[i] = EOS; +} + +bool8 IsFrontierTrainerFemale(u16 trainerId) +{ + u32 i; + u8 facilityClass; + + GetFacilityEnemyMonLevel(); // Pointless function call. + if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + { + facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; + } + else if (trainerId == TRAINER_FRONTIER_BRAIN) + { + return IsFrontierBrainFemale(); + } + else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + facilityClass = gFacilityTrainers[trainerId].facilityClass; + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + facilityClass = gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; + } + else + { + facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id].facilityClass; + } + + // Search female classes. + for (i = 0; i < ARRAY_COUNT(gTowerFemaleFacilityClasses); i++) + { + if (gTowerFemaleFacilityClasses[i] == facilityClass) + break; + } + if (i != ARRAY_COUNT(gTowerFemaleFacilityClasses)) + return TRUE; + else + return FALSE; +} + +void sub_8163048(u8 monsCount) +{ + ZeroEnemyPartyMons(); + sub_81630C4(gTrainerBattleOpponent_A, 0, monsCount); +} + +void sub_816306C(u8 monsCount) +{ + ZeroEnemyPartyMons(); + sub_81630C4(gTrainerBattleOpponent_A, 0, monsCount); + sub_81630C4(gTrainerBattleOpponent_B, 3, monsCount); +} + +void sub_81630A0(u8 monsCount) +{ + ZeroEnemyPartyMons(); + sub_8165EA4(gTrainerBattleOpponent_A, 0, monsCount); +} + +void sub_81630C4(u16 trainerId, u8 firstMonId, u8 monCount) +{ + s32 i, j; + u16 chosenMonIndices[4]; + u8 friendship = 0xFF; + u8 level = GetFacilityEnemyMonLevel(); + u8 fixedIV = 0; + u8 bfMonCount; + const u16 *bfMonPool = NULL; + u32 otID = 0; + + if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + // Normal battle frontier trainer. + fixedIV = GetFrontierTrainerFixedIvs(trainerId); + bfMonPool = gFacilityTrainers[gTrainerBattleOpponent_A].bfMonPool; + } + else if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + { + for (i = firstMonId; i < firstMonId + 3; i++) + sub_806819C(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i - firstMonId]); + return; + } + else if (trainerId == TRAINER_FRONTIER_BRAIN) + { + CreateFrontierBrainPokemon(); + return; + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + // Record mixed player. + for (j = 0, i = firstMonId; i < firstMonId + monCount; j++, i++) + { + if (gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[j].species != 0 + && gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[j].level <= level) + { + sub_8068338(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[j], FALSE); + } + } + return; + } + else + { + // Apprentice. + for (i = firstMonId; i < firstMonId + 3; i++) + CreateApprenticeMon(&gEnemyParty[i], &gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID], i - firstMonId); + return; + } + + // Regular battle frontier trainer. + // Attempt to fill the trainer's party with random Pokemon until 3 have been + // successfully chosen. The trainer's party may not have duplicate pokemon species + // or duplicate held items. + for (bfMonCount = 0; bfMonPool[bfMonCount] != 0xFFFF; bfMonCount++) + ; + i = 0; + otID = Random32(); + while (i != monCount) + { + u16 monPoolId = bfMonPool[Random() % bfMonCount]; + if ((level == 50 || level == 20) && monPoolId > 849) + continue; + + // Ensure this pokemon species isn't a duplicate. + for (j = 0; j < i + firstMonId; j++) + { + if (GetMonData(&gEnemyParty[j], MON_DATA_SPECIES, NULL) == gFacilityTrainerMons[monPoolId].species) + break; + } + if (j != i + firstMonId) + continue; + + // Ensure this Pokemon's held item isn't a duplicate. + for (j = 0; j < i + firstMonId; j++) + { + if (GetMonData(&gEnemyParty[j], MON_DATA_HELD_ITEM, NULL) != 0 + && GetMonData(&gEnemyParty[j], MON_DATA_HELD_ITEM, NULL) == gBattleFrontierHeldItems[gFacilityTrainerMons[monPoolId].itemTableId]) + break; + } + if (j != i + firstMonId) + continue; + + // Ensure this exact pokemon index isn't a duplicate. This check doesn't seem necessary + // because the species and held items were already checked directly above. + for (j = 0; j < i; j++) + { + if (chosenMonIndices[j] == monPoolId) + break; + } + if (j != i) + continue; + + chosenMonIndices[i] = monPoolId; + + // Place the chosen pokemon into the trainer's party. + CreateMonWithEVSpreadPersonalityOTID(&gEnemyParty[i + firstMonId], + gFacilityTrainerMons[monPoolId].species, + level, + gFacilityTrainerMons[monPoolId].nature, + fixedIV, + gFacilityTrainerMons[monPoolId].evSpread, + otID); + + friendship = 255; + // Give the chosen pokemon its specified moves. + for (j = 0; j < 4; j++) + { + SetMonMoveSlot(&gEnemyParty[i + firstMonId], gFacilityTrainerMons[monPoolId].moves[j], j); + if (gFacilityTrainerMons[monPoolId].moves[j] == MOVE_FRUSTRATION) + friendship = 0; // Frustration is more powerful the lower the pokemon's friendship is. + } + + SetMonData(&gEnemyParty[i + firstMonId], MON_DATA_FRIENDSHIP, &friendship); + SetMonData(&gEnemyParty[i + firstMonId], MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[monPoolId].itemTableId]); + + // The pokemon was successfully added to the trainer's party, so it's safe to move on to + // the next party slot. + i++; + } +} + +// Probably an early draft before the 'CreateApprenticeMon' was written. +void Unused_CreateApprenticeMons(u16 trainerId, u8 firstMonId) +{ + s32 i, j; + u8 friendship = 0xFF; + u8 level = 0; + u8 fixedIV = 0; + struct Apprentice *apprentice = &gSaveBlock2Ptr->apprentices[0]; + + if (apprentice->field_1 < 5) + fixedIV = 6; + else + fixedIV = 9; + + if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_50) + level = 100; + else + level = 50; + + for (i = 0; i != 3; i++) + { + CreateMonWithEVSpread(&gEnemyParty[firstMonId + i], apprentice->monData[i].species, level, fixedIV, 8); + friendship = 0xFF; + for (j = 0; j < 4; j++) + { + if (apprentice->monData[i].moves[j] == MOVE_FRUSTRATION) + friendship = 0; + } + SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_FRIENDSHIP, &friendship); + SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_HELD_ITEM, &apprentice->monData[i].item); + } +} + +u16 RandomizeFacilityTrainerMonId(u16 trainerId) +{ + u32 monPoolId; + u8 level = GetFacilityEnemyMonLevel(); + const u16 *bfMonPool = gFacilityTrainers[trainerId].bfMonPool; + u8 bfMonCount = 0; + + /* + I had to use ugly C tricks to get this part to match. + A cleaner version would look like this + + for (bfMonCount = 0; bfMonPool[bfMonCount] != 0xFFFF; bfMonCount++) + ; + + */ + + monPoolId = bfMonPool[bfMonCount]; + goto COMPARE; + while (1) + { + bfMonCount++; + monPoolId = bfMonPool[bfMonCount]; + COMPARE: + if (monPoolId == 0xFFFF) + break; + } + + do + { + monPoolId = bfMonPool[Random() % bfMonCount]; + } while((level == 50 || level == 20) && monPoolId > 849); + + return monPoolId; +} + +void sub_8163590(void) +{ + ZeroEnemyPartyMons(); + if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT) + sub_81635D4(gTrainerBattleOpponent_A, 0); + else + sub_816379C(gTrainerBattleOpponent_A, 0); +} + +extern u16 gUnknown_03006298[]; + +void sub_81635D4(u16 trainerId, u8 firstMonId) +{ + u8 i, j; + u8 friendship; + u8 level; + u8 fixedIV; + u32 otID; + + if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; // Unused variable. + u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); + u8 r1 = gSaveBlock2Ptr->frontier.field_CE0[battleMode][0] / 7; + if (gSaveBlock2Ptr->frontier.curChallengeBattleNum < 6) + fixedIV = sub_81A6CA8(r1, 0); + else + fixedIV = sub_81A6CA8(r1, 1); + } + else if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + { + for (i = firstMonId; i < firstMonId + 3; i++) + sub_806819C(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i - firstMonId]); + return; + } + else if (trainerId == TRAINER_FRONTIER_BRAIN) + { + sub_81A6CD0(); + return; + } + else + { + fixedIV = 31; + } + + + level = GetFacilityEnemyMonLevel(); + otID = T1_READ_32(gSaveBlock2Ptr->playerTrainerId); + for (i = 0; i < 3; i++) + { + u16 poolId = gUnknown_03006298[i]; + CreateMonWithEVSpreadPersonalityOTID(&gEnemyParty[firstMonId + i], + gFacilityTrainerMons[poolId].species, + level, + gFacilityTrainerMons[poolId].nature, + fixedIV, + gFacilityTrainerMons[poolId].evSpread, + otID); + + friendship = 0; + for (j = 0; j < 4; j++) + SetMonMoveAvoidReturn(&gEnemyParty[firstMonId + i], gFacilityTrainerMons[poolId].moves[j], j); + + SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_FRIENDSHIP, &friendship); + SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[poolId].itemTableId]); + } +} + +void sub_816379C(u16 trainerId, u8 firstMonId) +{ + u8 i, j; + u8 friendship; + u8 level = 30; + u8 fixedIV = 0; + u32 otID = T1_READ_32(gSaveBlock2Ptr->playerTrainerId); + + for (i = 0; i < 3; i++) + { + u16 poolId = gUnknown_03006298[i]; + CreateMonWithEVSpreadPersonalityOTID(&gEnemyParty[firstMonId + i], + gFacilityTrainerMons[poolId].species, + level, + gFacilityTrainerMons[poolId].nature, + fixedIV, + gFacilityTrainerMons[poolId].evSpread, + otID); + + friendship = 0; + for (j = 0; j < 4; j++) + { + SetMonMoveAvoidReturn(&gEnemyParty[firstMonId + i], gFacilityTrainerMons[poolId].moves[j], j); + if (gFacilityTrainerMons[poolId].moves[j] == MOVE_FRUSTRATION) + friendship = 0; + } + + SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_FRIENDSHIP, &friendship); + SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[poolId].itemTableId]); + } +} + +void ConvertBattleFrontierTrainerSpeechToString(const u16 *words) +{ + ConvertEasyChatWordsToString(gStringVar4, words, 3, 2); + if (GetStringWidth(1, gStringVar4, -1) > 204) + { + s32 i = 0; + + ConvertEasyChatWordsToString(gStringVar4, words, 2, 3); + while (gStringVar4[i++] != CHAR_NEWLINE) + ; + while (gStringVar4[i] != CHAR_NEWLINE) + i++; + + gStringVar4[i] = CHAR_PROMPT_SCROLL; + } +} -- cgit v1.2.3 From 0ab27e44b14a0dc4523b5bac7fef18312ab4fdde Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sun, 21 Oct 2018 20:13:12 +0200 Subject: more tower, fail --- src/battle_tower.c | 558 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 525 insertions(+), 33 deletions(-) (limited to 'src/battle_tower.c') diff --git a/src/battle_tower.c b/src/battle_tower.c index b9451aecd..75253792e 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -6,12 +6,18 @@ #include "overworld.h" #include "random.h" #include "text.h" +#include "main.h" #include "international_string_util.h" #include "battle.h" #include "battle_frontier_1.h" #include "battle_frontier_2.h" #include "recorded_battle.h" #include "easy_chat.h" +#include "gym_leader_rematch.h" +#include "battle_transition.h" +#include "trainer_see.h" +#include "new_game.h" +#include "string_util.h" #include "constants/battle_frontier.h" #include "constants/trainers.h" #include "constants/event_objects.h" @@ -39,9 +45,11 @@ extern const u16 gBattleFrontierHeldItems[]; // This file's functions. void sub_8164ED8(void); -void sub_8163E90(void); +void SaveCurrentWinStreak(void); void sub_8165B20(void); void sub_8165E18(void); +void sub_816537C(void); +void sub_8164FB8(struct EmeraldBattleTowerRecord *record); u16 GetCurrentBattleTowerWinStreak(u8 lvlMode, u8 battleMode); void sub_816534C(void *); u16 sub_8162548(u8, u8); @@ -50,6 +58,7 @@ void sub_8165EA4(u16 trainerId, u8 firstMonId, u8 monCount); void sub_81635D4(u16 trainerId, u8 firstMonId); void sub_816379C(u16 trainerId, u8 firstMonId); u8 GetFrontierTrainerFixedIvs(u16 trainerId); +void sub_8165404(u16 trainerId); // code void sub_8161F74(void) @@ -129,7 +138,7 @@ void sub_81621C0(void) gSaveBlock2Ptr->frontier.field_D04++; gSaveBlock2Ptr->frontier.curChallengeBattleNum++; - sub_8163E90(); + SaveCurrentWinStreak(); gSpecialVar_Result = gSaveBlock2Ptr->frontier.curChallengeBattleNum; } @@ -148,7 +157,7 @@ bool8 ChooseSpecialBattleTowerTrainer(void) winStreak = GetCurrentBattleTowerWinStreak(lvlMode, battleMode); for (i = 0; i < 5; i++) { - u32 *record = (u32*)(&gSaveBlock2Ptr->frontier.records[i]); + u32 *record = (u32*)(&gSaveBlock2Ptr->frontier.towerRecords[i]); u32 recordHasData = 0; u32 checksum = 0; for (j = 0; j < (sizeof(struct EmeraldBattleTowerRecord) - 4) / 4; j++) // - 4, because of the last field being the checksum itself. @@ -159,16 +168,16 @@ bool8 ChooseSpecialBattleTowerTrainer(void) validMons = 0; for (j = 0; j < 4; j++) { - if (gSaveBlock2Ptr->frontier.records[i].party[j].species != 0 - && gSaveBlock2Ptr->frontier.records[i].party[j].level <= GetFrontierEnemyMonLevel(lvlMode)) + if (gSaveBlock2Ptr->frontier.towerRecords[i].party[j].species != 0 + && gSaveBlock2Ptr->frontier.towerRecords[i].party[j].level <= GetFrontierEnemyMonLevel(lvlMode)) validMons++; } if (validMons >= gUnknown_085DF9F6[battleMode] - && gSaveBlock2Ptr->frontier.records[i].winStreak == winStreak - && gSaveBlock2Ptr->frontier.records[i].lvlMode == lvlMode + && gSaveBlock2Ptr->frontier.towerRecords[i].winStreak == winStreak + && gSaveBlock2Ptr->frontier.towerRecords[i].lvlMode == lvlMode && recordHasData - && gSaveBlock2Ptr->frontier.records[i].checksum == checksum) + && gSaveBlock2Ptr->frontier.towerRecords[i].checksum == checksum) { trainerIds[idsCount] = i + BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID; idsCount++; @@ -385,7 +394,7 @@ void SetBattleFacilityTrainerGfxId(u16 trainerId, u8 tempVarId) } else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) { - facilityClass = gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; + facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; } else { @@ -477,7 +486,7 @@ u8 GetBattleFacilityTrainerGfxId(u16 trainerId) } else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) { - facilityClass = gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; + facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; } else { @@ -527,7 +536,7 @@ void PutNewBattleTowerRecord(union BattleTowerRecord *newRecord) k = 0; for (j = 0; j < 4; j++) { - if (gSaveBlock2Ptr->frontier.records[i].trainerId[j] != newRecordEm->trainerId[j]) + if (gSaveBlock2Ptr->frontier.towerRecords[i].trainerId[j] != newRecordEm->trainerId[j]) break; } if (j == 4) @@ -535,7 +544,7 @@ void PutNewBattleTowerRecord(union BattleTowerRecord *newRecord) for (k = 0; k < PLAYER_NAME_LENGTH; k++) { // BUG: Wrong variable used, 'j' instead of 'k'. - if (gSaveBlock2Ptr->frontier.records[i].name[j] != newRecordEm->name[j]) + if (gSaveBlock2Ptr->frontier.towerRecords[i].name[j] != newRecordEm->name[j]) break; if (newRecordEm->name[j] == EOS) { @@ -550,24 +559,24 @@ void PutNewBattleTowerRecord(union BattleTowerRecord *newRecord) } if (i < 5) { - gSaveBlock2Ptr->frontier.records[i] = *newRecordEm; + gSaveBlock2Ptr->frontier.towerRecords[i] = *newRecordEm; return; } // Find an empty record slot. for (i = 0; i < 5; i++) { - if (gSaveBlock2Ptr->frontier.records[i].winStreak == 0) + if (gSaveBlock2Ptr->frontier.towerRecords[i].winStreak == 0) break; } if (i < 5) { - gSaveBlock2Ptr->frontier.records[i] = *newRecordEm; + gSaveBlock2Ptr->frontier.towerRecords[i] = *newRecordEm; return; } // Find possible slots to replace the record. - slotValues[0] = gSaveBlock2Ptr->frontier.records[0].winStreak; + slotValues[0] = gSaveBlock2Ptr->frontier.towerRecords[0].winStreak; slotIds[0] = 0; slotsCount++; @@ -575,15 +584,15 @@ void PutNewBattleTowerRecord(union BattleTowerRecord *newRecord) { for (j = 0; j < slotsCount; j++) { - if (gSaveBlock2Ptr->frontier.records[i].winStreak < slotValues[j]) + if (gSaveBlock2Ptr->frontier.towerRecords[i].winStreak < slotValues[j]) { j = 0; slotsCount = 1; - slotValues[0] = gSaveBlock2Ptr->frontier.records[i].winStreak; + slotValues[0] = gSaveBlock2Ptr->frontier.towerRecords[i].winStreak; slotIds[0] = i; break; } - else if (gSaveBlock2Ptr->frontier.records[i].winStreak > slotValues[j]) + else if (gSaveBlock2Ptr->frontier.towerRecords[i].winStreak > slotValues[j]) { break; } @@ -591,14 +600,14 @@ void PutNewBattleTowerRecord(union BattleTowerRecord *newRecord) if (j == slotsCount) { - slotValues[slotsCount] = gSaveBlock2Ptr->frontier.records[i].winStreak; + slotValues[slotsCount] = gSaveBlock2Ptr->frontier.towerRecords[i].winStreak; slotIds[slotsCount] = i; slotsCount++; } } i = Random() % slotsCount; - gSaveBlock2Ptr->frontier.records[slotIds[i]] = *newRecordEm; + gSaveBlock2Ptr->frontier.towerRecords[slotIds[i]] = *newRecordEm; } u8 GetFrontierTrainerFrontSpriteId(u16 trainerId) @@ -622,7 +631,7 @@ u8 GetFrontierTrainerFrontSpriteId(u16 trainerId) if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) return gFacilityClassToPicIndex[sub_818649C()]; else - return gFacilityClassToPicIndex[gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass]; + return gFacilityClassToPicIndex[gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass]; } else { @@ -662,7 +671,7 @@ u8 GetFrontierOpponentClass(u16 trainerId) } else { - trainerClass = gFacilityClassToTrainerClass[gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass]; + trainerClass = gFacilityClassToTrainerClass[gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass]; asm(""); } } @@ -700,7 +709,7 @@ u8 GetFrontierTrainerFacilityClass(u16 trainerId) if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) facilityClass = sub_818649C(); else - facilityClass = gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; + facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; } else { @@ -747,7 +756,7 @@ void GetFrontierTrainerName(u8 *dst, u16 trainerId) } else { - struct EmeraldBattleTowerRecord *record = &gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID]; + struct EmeraldBattleTowerRecord *record = &gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID]; TVShowConvertInternationalString(dst, record->name, record->language); return; } @@ -794,7 +803,7 @@ bool8 IsFrontierTrainerFemale(u16 trainerId) } else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) { - facilityClass = gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; + facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; } else { @@ -865,10 +874,10 @@ void sub_81630C4(u16 trainerId, u8 firstMonId, u8 monCount) // Record mixed player. for (j = 0, i = firstMonId; i < firstMonId + monCount; j++, i++) { - if (gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[j].species != 0 - && gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[j].level <= level) + if (gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[j].species != 0 + && gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[j].level <= level) { - sub_8068338(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.records[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[j], FALSE); + sub_8068338(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[j], FALSE); } } return; @@ -1044,11 +1053,11 @@ void sub_81635D4(u16 trainerId, u8 firstMonId) { u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; // Unused variable. u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); - u8 r1 = gSaveBlock2Ptr->frontier.field_CE0[battleMode][0] / 7; + u8 challengeNum = gSaveBlock2Ptr->frontier.field_CE0[battleMode][0] / 7; if (gSaveBlock2Ptr->frontier.curChallengeBattleNum < 6) - fixedIV = sub_81A6CA8(r1, 0); + fixedIV = sub_81A6CA8(challengeNum, 0); else - fixedIV = sub_81A6CA8(r1, 1); + fixedIV = sub_81A6CA8(challengeNum, 1); } else if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { @@ -1121,7 +1130,7 @@ void sub_816379C(u16 trainerId, u8 firstMonId) } } -void ConvertBattleFrontierTrainerSpeechToString(const u16 *words) +void FrontierSpeechToString(const u16 *words) { ConvertEasyChatWordsToString(gStringVar4, words, 3, 2); if (GetStringWidth(1, gStringVar4, -1) > 204) @@ -1137,3 +1146,486 @@ void ConvertBattleFrontierTrainerSpeechToString(const u16 *words) gStringVar4[i] = CHAR_PROMPT_SCROLL; } } + +void sub_8163914(void) +{ + u16 trainerId; + GetFacilityEnemyMonLevel(); // Pointless function call. + + if (gSpecialVar_0x8005) + trainerId = gTrainerBattleOpponent_B; + else + trainerId = gTrainerBattleOpponent_A; + + if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + FrontierSpeechToString(gSaveBlock2Ptr->frontier.ereaderTrainer.greeting); + else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + FrontierSpeechToString(gFacilityTrainers[trainerId].speechBefore); + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + FrontierSpeechToString(gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].greeting); + else + CopyFriendsApprenticeChallengeText(trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID); +} + +static void HandleSpecialTrainerBattleEnd(void) +{ + s32 i; + + sub_81864CC(); + switch (gBattleScripting.specialTrainerBattleType) + { + case SPECIAL_BATTLE_TOWER: + case SPECIAL_BATTLE_DOME: + case SPECIAL_BATTLE_PALACE: + case SPECIAL_BATTLE_ARENA: + case SPECIAL_BATTLE_FACTORY: + case SPECIAL_BATTLE_PIKE_SINGLE: + case SPECIAL_BATTLE_PIKE_DOUBLE: + case SPECIAL_BATTLE_PYRAMID: + if (gSaveBlock2Ptr->frontier.battlesCount < 0xFFFFFF) + { + gSaveBlock2Ptr->frontier.battlesCount++; + if (gSaveBlock2Ptr->frontier.battlesCount % 20 == 0) + UpdateGymLeaderRematch(); + } + else + { + gSaveBlock2Ptr->frontier.battlesCount = 0xFFFFFF; + } + break; + case SPECIAL_BATTLE_SECRET_BASE: + for (i = 0; i < PARTY_SIZE; i++) + { + u16 itemBefore = GetMonData(&gSaveBlock1Ptr->playerParty[i], MON_DATA_HELD_ITEM); + SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &itemBefore); + } + break; + case SPECIAL_BATTLE_EREADER: + sub_816537C(); + break; + } + + SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); +} + +static void Task_StartBattleAfterTransition(u8 taskId) +{ + if (IsBattleTransitionDone() == TRUE) + { + gMain.savedCallback = HandleSpecialTrainerBattleEnd; + SetMainCallback2(CB2_InitBattle); + DestroyTask(taskId); + } +} + +extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_224157[]; +extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_224166[]; + +void DoSpecialTrainerBattle(void) +{ + s32 i; + + gBattleScripting.specialTrainerBattleType = gSpecialVar_0x8004; + switch (gSpecialVar_0x8004) + { + case SPECIAL_BATTLE_TOWER: + gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_BATTLE_TOWER; + switch (VarGet(VAR_FRONTIER_BATTLE_MODE)) + { + case FRONTIER_MODE_SINGLES: + sub_8163048(3); + break; + case FRONTIER_MODE_DOUBLES: + sub_8163048(4); + gBattleTypeFlags |= BATTLE_TYPE_DOUBLE; + break; + case FRONTIER_MODE_MULTIS: + sub_816306C(2); + gPartnerTrainerId = gSaveBlock2Ptr->frontier.field_CD6; + sub_8165404(gPartnerTrainerId); + gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS; + break; + case FRONTIER_MODE_LINK_MULTIS: + gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_LINK | BATTLE_TYPE_MULTI | BATTLE_TYPE_x800000; + sub_816306C(2); + break; + } + CreateTask(Task_StartBattleAfterTransition, 1); + PlayMapChosenOrBattleBGM(0); + BattleTransition_StartOnField(sub_80B100C(0)); + break; + case SPECIAL_BATTLE_SECRET_BASE: + for (i = 0; i < PARTY_SIZE; i++) + { + u16 itemBefore = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); + SetMonData(&gSaveBlock1Ptr->playerParty[i], MON_DATA_HELD_ITEM, &itemBefore); + } + CreateTask(Task_StartBattleAfterTransition, 1); + PlayMapChosenOrBattleBGM(0); + BattleTransition_StartOnField(sub_80B100C(12)); + break; + case SPECIAL_BATTLE_EREADER: + ZeroEnemyPartyMons(); + for (i = 0; i < 3; i++) + sub_806819C(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i]); + gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_EREADER_TRAINER; + gTrainerBattleOpponent_A = 0; + CreateTask(Task_StartBattleAfterTransition, 1); + PlayMapChosenOrBattleBGM(0); + BattleTransition_StartOnField(sub_80B100C(13)); + break; + case SPECIAL_BATTLE_DOME: + gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOME; + if (VarGet(VAR_FRONTIER_BATTLE_MODE) == FRONTIER_MODE_DOUBLES) + gBattleTypeFlags |= BATTLE_TYPE_DOUBLE; + if (gTrainerBattleOpponent_A == TRAINER_FRONTIER_BRAIN) + sub_8163048(2); + CreateTask(Task_StartBattleAfterTransition, 1); + sub_806E694(0); + BattleTransition_StartOnField(sub_80B100C(3)); + break; + case SPECIAL_BATTLE_PALACE: + gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_PALACE; + if (VarGet(VAR_FRONTIER_BATTLE_MODE) == FRONTIER_MODE_DOUBLES) + gBattleTypeFlags |= BATTLE_TYPE_DOUBLE; + if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT) + sub_8163048(3); + else + sub_81630A0(3); + CreateTask(Task_StartBattleAfterTransition, 1); + PlayMapChosenOrBattleBGM(0); + BattleTransition_StartOnField(sub_80B100C(4)); + break; + case SPECIAL_BATTLE_ARENA: + gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_ARENA; + if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT) + sub_8163048(3); + else + sub_81630A0(3); + CreateTask(Task_StartBattleAfterTransition, 1); + PlayMapChosenOrBattleBGM(0); + BattleTransition_StartOnField(sub_80B100C(5)); + break; + case SPECIAL_BATTLE_FACTORY: + gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_FACTORY; + if (VarGet(VAR_FRONTIER_BATTLE_MODE) == FRONTIER_MODE_DOUBLES) + gBattleTypeFlags |= BATTLE_TYPE_DOUBLE; + sub_8163590(); + CreateTask(Task_StartBattleAfterTransition, 1); + PlayMapChosenOrBattleBGM(0); + BattleTransition_StartOnField(sub_80B100C(6)); + break; + case SPECIAL_BATTLE_PIKE_SINGLE: + gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_BATTLE_TOWER; + sub_8163048(3); + CreateTask(Task_StartBattleAfterTransition, 1); + PlayMapChosenOrBattleBGM(0); + BattleTransition_StartOnField(sub_80B100C(7)); + break; + case SPECIAL_BATTLE_PYRAMID: + gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_PYRAMID; + sub_8163048(3); + CreateTask(Task_StartBattleAfterTransition, 1); + PlayMapChosenOrBattleBGM(0); + BattleTransition_StartOnField(sub_80B100C(10)); + break; + case SPECIAL_BATTLE_PIKE_DOUBLE: + gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS; + sub_816306C(1); + CreateTask(Task_StartBattleAfterTransition, 1); + PlayMapChosenOrBattleBGM(0); + BattleTransition_StartOnField(sub_80B100C(7)); + break; + case SPECIAL_BATTLE_STEVEN: + gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER; + sub_8165404(TRAINER_STEVEN_PARTNER); + gApproachingTrainerId = 0; + BattleSetup_ConfigureTrainerBattle(MossdeepCity_SpaceCenter_2F_EventScript_224157 + 1); + gApproachingTrainerId = 1; + BattleSetup_ConfigureTrainerBattle(MossdeepCity_SpaceCenter_2F_EventScript_224166 + 1); + gPartnerTrainerId = TRAINER_STEVEN_PARTNER; + CreateTask(Task_StartBattleAfterTransition, 1); + PlayMapChosenOrBattleBGM(0); + BattleTransition_StartOnField(B_TRANSITION_MAGMA); + break; + } +} + +void SaveCurrentWinStreak(void) +{ + u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; + u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); + u16 winStreak = GetCurrentBattleTowerWinStreak(lvlMode, battleMode); + + if (gSaveBlock2Ptr->frontier.field_CE0[battleMode][lvlMode] < winStreak) + gSaveBlock2Ptr->frontier.field_CE0[battleMode][lvlMode] = winStreak; +} + +void sub_8163EE4(void) +{ + s32 i; + u8 lvlMode, battleMode, class; + struct EmeraldBattleTowerRecord *playerRecord = &gSaveBlock2Ptr->frontier.towerPlayer; + + sub_8164FB8(playerRecord); + lvlMode = gSaveBlock2Ptr->frontier.lvlMode; + battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); + if (gSaveBlock2Ptr->playerGender != MALE) + { + class = gTowerFemaleFacilityClasses[(gSaveBlock2Ptr->playerTrainerId[0] + + gSaveBlock2Ptr->playerTrainerId[1] + + gSaveBlock2Ptr->playerTrainerId[2] + + gSaveBlock2Ptr->playerTrainerId[3]) % ARRAY_COUNT(gTowerFemaleFacilityClasses)]; + } + else + { + class = gTowerMaleFacilityClasses[(gSaveBlock2Ptr->playerTrainerId[0] + + gSaveBlock2Ptr->playerTrainerId[1] + + gSaveBlock2Ptr->playerTrainerId[2] + + gSaveBlock2Ptr->playerTrainerId[3]) % ARRAY_COUNT(gTowerMaleFacilityClasses)]; + } + playerRecord->lvlMode = lvlMode; + playerRecord->facilityClass = class; + CopyUnalignedWord(playerRecord->trainerId, gSaveBlock2Ptr->playerTrainerId); + StringCopy7(playerRecord->name, gSaveBlock2Ptr->playerName); + playerRecord->winStreak = GetCurrentBattleTowerWinStreak(lvlMode, battleMode); + + for (i = 0; i < 6; i++) + { + playerRecord->greeting[i] = gSaveBlock1Ptr->unk2BBC[i]; + playerRecord->unk1C[i] = gSaveBlock1Ptr->unk2BC8[i]; + playerRecord->unk28[i] = gSaveBlock1Ptr->unk2BD4[i]; + } + + for (i = 0; i < 4; i++) + { + if (gSaveBlock2Ptr->frontier.field_CAA[i] != 0) + sub_80686FC(&gPlayerParty[gSaveBlock2Ptr->frontier.field_CAA[i] - 1], &playerRecord->party[i]); + } + + playerRecord->language = gGameLanguage; + CalcEmeraldBattleTowerChecksum(&gSaveBlock2Ptr->frontier.towerPlayer); + SaveCurrentWinStreak(); +} + +void SaveBattleTowerProgress(void) +{ + u16 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; + u16 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); + s32 challengeNum = (signed)(gSaveBlock2Ptr->frontier.field_CE0[battleMode][lvlMode] / 7); + + if (gSpecialVar_0x8005 == 0 && (challengeNum > 1 || gSaveBlock2Ptr->frontier.curChallengeBattleNum != 0)) + sub_8163EE4(); + + gSaveBlock2Ptr->frontier.field_CA8 =gSpecialVar_0x8005; + VarSet(VAR_TEMP_0, 0); + gSaveBlock2Ptr->frontier.field_CA9_a = 1; + sub_81A4C30(); +} + +void nullsub_61(void) +{ + +} + +void nullsub_116(void) +{ + +} + +void sub_81640E0(u16 trainerId) +{ + s32 i, count; + u32 validSpecies[3]; + u16 species1 = GetMonData(&gPlayerParty[0], MON_DATA_SPECIES, NULL); + u16 species2 = GetMonData(&gPlayerParty[1], MON_DATA_SPECIES, NULL); + + count = 0; + for (i = 0; i < 3; i++) + { + u16 apprenticeSpecies = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].monData[i].species; + if (apprenticeSpecies != species1 && apprenticeSpecies != species2) + { + validSpecies[count] = i; + count++; + } + } + + gUnknown_03006298[0] = validSpecies[Random() % count]; + do + { + gUnknown_03006298[1] = validSpecies[Random() % count]; + } while (gUnknown_03006298[0] == gUnknown_03006298[1]); +} + +void sub_8164188(u16 trainerId) +{ + s32 i, count; + u32 validSpecies[3]; + u32 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; + u16 species1 = GetMonData(&gPlayerParty[0], MON_DATA_SPECIES, NULL); + u16 species2 = GetMonData(&gPlayerParty[1], MON_DATA_SPECIES, NULL); + + count = 0; + for (i = 0; i < 4; i++) + { + if (gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[i].species != species1 + && gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[i].species != species2 + && gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[i].level <= GetFrontierEnemyMonLevel(lvlMode) + && gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[i].species != 0) + { + validSpecies[count] = i; + count++; + } + } + + gUnknown_03006298[2] = validSpecies[Random() % count]; + do + { + gUnknown_03006298[3] = validSpecies[Random() % count]; + } while (gUnknown_03006298[2] == gUnknown_03006298[3]); +} + +void sub_81642A0(void) +{ + s32 i, j, k; + u32 spArray[5]; + s32 r10; + u16 trainerId; + u16 monPoolId; + u32 lvlMode, battleMode; + s32 challengeNum; + u32 species1, species2; + u32 level; + struct EventObjectTemplate *eventObjTemplates; + + eventObjTemplates = gSaveBlock1Ptr->eventObjectTemplates; + lvlMode = gSaveBlock2Ptr->frontier.lvlMode; + battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); + challengeNum = gSaveBlock2Ptr->frontier.field_CE0[battleMode][lvlMode] / 7; + species1 = GetMonData(&gPlayerParty[0], MON_DATA_SPECIES, NULL); + species2 = GetMonData(&gPlayerParty[1], MON_DATA_SPECIES, NULL); + level = GetFacilityEnemyMonLevel(); + + for (j = 0; j < 6; j++) + { + do + { + trainerId = sub_8162548(challengeNum, 0); + for (i = 0; i < j; i++) + { + if (gSaveBlock2Ptr->frontier.battledTrainerIds[i] == trainerId) + break; + if (gFacilityTrainers[gSaveBlock2Ptr->frontier.battledTrainerIds[i]].facilityClass == gFacilityTrainers[trainerId].facilityClass) + break; + } + } while (i != j); + gSaveBlock2Ptr->frontier.battledTrainerIds[j] = trainerId; + } + + r10 = 8; + for (i = 0; i < 6; i++) + { + trainerId = gSaveBlock2Ptr->frontier.battledTrainerIds[i]; + eventObjTemplates[i + 1].graphicsId = GetBattleFacilityTrainerGfxId(trainerId); + for (j = 0; j < 2; j++) + { + while (1) + { + monPoolId = RandomizeFacilityTrainerMonId(trainerId); + if (j % 2 != 0 && gFacilityTrainerMons[gSaveBlock2Ptr->frontier.battledTrainerIds[r10 - 1]].itemTableId == gFacilityTrainerMons[monPoolId].itemTableId) + continue; + + for (k = 8; k < r10; k++) + { + if (gFacilityTrainerMons[gSaveBlock2Ptr->frontier.battledTrainerIds[k]].species == gFacilityTrainerMons[monPoolId].species) + break; + if (species1 == gFacilityTrainerMons[monPoolId].species) + break; + if (species2 == gFacilityTrainerMons[monPoolId].species) + break; + } + if (k == r10) + break; + } + + gSaveBlock2Ptr->frontier.battledTrainerIds[r10] = monPoolId; + r10++; + } + } + + r10 = 0; + sub_8165B20(); + for (i = 0; i < 4; i++) + { + if (gSaveBlock2Ptr->apprentices[i].lvlMode != 0 + && gUnknown_085DF9EC[gSaveBlock2Ptr->apprentices[i].field_1] / 7 <= challengeNum + && gSaveBlock2Ptr->apprentices[i].lvlMode - 1 == lvlMode) + { + k = 0; + for (j = 0; j < 3; j++) + { + if (species1 != gSaveBlock2Ptr->apprentices[i].monData[j].species + && species2 != gSaveBlock2Ptr->apprentices[i].monData[j].species) + { + k++; + } + } + if (k > 2) + { + spArray[r10] = i + BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID; + r10++; + } + } + } + if (r10 != 0) + { + gSaveBlock2Ptr->frontier.battledTrainerIds[6] = spArray[Random() % r10]; + eventObjTemplates[7].graphicsId = GetBattleFacilityTrainerGfxId(gSaveBlock2Ptr->frontier.battledTrainerIds[6]); + FlagClear(FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_1); + sub_81640E0(gSaveBlock2Ptr->frontier.battledTrainerIds[6]); + } + + r10 = 0; + for (i = 0; i < 5; i++) + { + u32 *record = (u32*)(&gSaveBlock2Ptr->frontier.towerRecords[i]); + u32 recordHasData = 0; + u32 checksum = 0; + for (j = 0; j < (sizeof(struct EmeraldBattleTowerRecord) - 4) / 4; j++) // - 4, because of the last field being the checksum itself. + { + recordHasData |= record[j]; + checksum += record[j]; + } + + if (gSaveBlock2Ptr->frontier.towerRecords[i].winStreak / 7 <= challengeNum + && gSaveBlock2Ptr->frontier.towerRecords[i].lvlMode == lvlMode + && recordHasData + && gSaveBlock2Ptr->frontier.towerRecords[i].checksum == checksum) + { + k = 0; + for (j = 0; j < 4; j++) + { + if (species1 != gSaveBlock2Ptr->frontier.towerRecords[i].party[j].species + && species2 != gSaveBlock2Ptr->frontier.towerRecords[i].party[j].species + && gSaveBlock2Ptr->frontier.towerRecords[i].party[j].level <= GetFrontierEnemyMonLevel(lvlMode) + && gSaveBlock2Ptr->frontier.towerRecords[i].party[j].species != 0) + { + k++; + } + } + if (k > 1) + { + spArray[r10] = i + BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID; + r10++; + } + } + } + if (r10 != 0) + { + gSaveBlock2Ptr->frontier.battledTrainerIds[7] = spArray[Random() % r10]; + eventObjTemplates[8].graphicsId = GetBattleFacilityTrainerGfxId(gSaveBlock2Ptr->frontier.battledTrainerIds[7]); + FlagClear(FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_2); + sub_8164188(gSaveBlock2Ptr->frontier.battledTrainerIds[7]); + } +} -- cgit v1.2.3 From b330bdba51b86959e702e904c4a5d8039e6395c7 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Mon, 22 Oct 2018 19:22:57 +0200 Subject: More and more battle tower --- src/battle_tower.c | 853 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 784 insertions(+), 69 deletions(-) (limited to 'src/battle_tower.c') diff --git a/src/battle_tower.c b/src/battle_tower.c index 75253792e..25a46d073 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -18,6 +18,10 @@ #include "trainer_see.h" #include "new_game.h" #include "string_util.h" +#include "data2.h" +#include "link.h" +#include "field_message_box.h" +#include "tv.h" #include "constants/battle_frontier.h" #include "constants/trainers.h" #include "constants/event_objects.h" @@ -44,21 +48,23 @@ extern const u8 gUnknown_085DF9EC[]; extern const u16 gBattleFrontierHeldItems[]; // This file's functions. -void sub_8164ED8(void); +void ValidateBattleTowerRecordChecksums(void); void SaveCurrentWinStreak(void); void sub_8165B20(void); void sub_8165E18(void); -void sub_816537C(void); -void sub_8164FB8(struct EmeraldBattleTowerRecord *record); +void CopyEReaderTrainerFarewellMessage(void); +void ClearBattleTowerRecord(struct EmeraldBattleTowerRecord *record); u16 GetCurrentBattleTowerWinStreak(u8 lvlMode, u8 battleMode); -void sub_816534C(void *); u16 sub_8162548(u8, u8); -void sub_81630C4(u16 trainerId, u8 firstMonId, u8 monCount); +static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount); void sub_8165EA4(u16 trainerId, u8 firstMonId, u8 monCount); void sub_81635D4(u16 trainerId, u8 firstMonId); void sub_816379C(u16 trainerId, u8 firstMonId); u8 GetFrontierTrainerFixedIvs(u16 trainerId); void sub_8165404(u16 trainerId); +void sub_8165B88(u8 *dst, u16 trainerId); +void SetEReaderTrainerChecksum(struct BattleTowerEReaderTrainer *ereaderTrainer); +void ClearEReaderTrainer(struct BattleTowerEReaderTrainer *ereaderTrainer); // code void sub_8161F74(void) @@ -77,9 +83,9 @@ void sub_8161F94(void) gSaveBlock2Ptr->frontier.field_CA9_b = 0; sub_81A3ACC(); if (!(gSaveBlock2Ptr->frontier.field_CDC & gUnknown_085DF9AC[battleMode][lvlMode])) - gSaveBlock2Ptr->frontier.field_CE0[battleMode][lvlMode] = 0; + gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] = 0; - sub_8164ED8(); + ValidateBattleTowerRecordChecksums(); saved_warp2_set(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1); gTrainerBattleOpponent_A = 0; } @@ -115,7 +121,7 @@ void sub_81620F4(void) case 0: break; case 1: - gSaveBlock2Ptr->frontier.field_CE0[battleMode][lvlMode] = gSpecialVar_0x8006; + gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] = gSpecialVar_0x8006; break; case 2: if (gSpecialVar_0x8006) @@ -132,7 +138,7 @@ void sub_81620F4(void) void sub_81621C0(void) { if (gTrainerBattleOpponent_A == BATTLE_TOWER_EREADER_TRAINER_ID) - sub_816534C(&gSaveBlock2Ptr->frontier.ereaderTrainer); + ClearEReaderTrainer(&gSaveBlock2Ptr->frontier.ereaderTrainer); if (gSaveBlock2Ptr->frontier.field_D04 < 9999) gSaveBlock2Ptr->frontier.field_D04++; @@ -227,15 +233,15 @@ void ChooseNextBattleTowerTrainer(void) if (battleMode == FRONTIER_MODE_MULTIS || battleMode == FRONTIER_MODE_LINK_MULTIS) { id = gSaveBlock2Ptr->frontier.curChallengeBattleNum; - gTrainerBattleOpponent_A = gSaveBlock2Ptr->frontier.battledTrainerIds[id * 2]; - gTrainerBattleOpponent_B = gSaveBlock2Ptr->frontier.battledTrainerIds[id * 2 + 1]; + gTrainerBattleOpponent_A = gSaveBlock2Ptr->frontier.field_CB4[id * 2]; + gTrainerBattleOpponent_B = gSaveBlock2Ptr->frontier.field_CB4[id * 2 + 1]; SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_A, 0); SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_B, 1); } else if (ChooseSpecialBattleTowerTrainer()) { SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_A, 0); - gSaveBlock2Ptr->frontier.battledTrainerIds[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = gTrainerBattleOpponent_A; + gSaveBlock2Ptr->frontier.field_CB4[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = gTrainerBattleOpponent_A; } else { @@ -247,7 +253,7 @@ void ChooseNextBattleTowerTrainer(void) // Ensure trainer wasn't previously fought in this challenge. for (i = 0; i < gSaveBlock2Ptr->frontier.curChallengeBattleNum; i++) { - if (gSaveBlock2Ptr->frontier.battledTrainerIds[i] == id) + if (gSaveBlock2Ptr->frontier.field_CB4[i] == id) break; } if (i == gSaveBlock2Ptr->frontier.curChallengeBattleNum) @@ -257,7 +263,7 @@ void ChooseNextBattleTowerTrainer(void) gTrainerBattleOpponent_A = id; SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_A, 0); if (gSaveBlock2Ptr->frontier.curChallengeBattleNum + 1 < 7) - gSaveBlock2Ptr->frontier.battledTrainerIds[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = gTrainerBattleOpponent_A; + gSaveBlock2Ptr->frontier.field_CB4[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = gTrainerBattleOpponent_A; } } } @@ -522,13 +528,13 @@ u8 GetBattleFacilityTrainerGfxId(u16 trainerId) } } -void PutNewBattleTowerRecord(union BattleTowerRecord *newRecord) +void PutNewBattleTowerRecord(struct EmeraldBattleTowerRecord *newRecordEm) { u16 slotValues[6]; u16 slotIds[6]; s32 i, j, k; s32 slotsCount = 0; - struct EmeraldBattleTowerRecord *newRecordEm = &newRecord->emerald; + struct EmeraldBattleTowerRecord *newRecord = newRecordEm; // Needed to match. // Find a record slot of the same player and replace it. for (i = 0; i < 5; i++) @@ -536,7 +542,7 @@ void PutNewBattleTowerRecord(union BattleTowerRecord *newRecord) k = 0; for (j = 0; j < 4; j++) { - if (gSaveBlock2Ptr->frontier.towerRecords[i].trainerId[j] != newRecordEm->trainerId[j]) + if (gSaveBlock2Ptr->frontier.towerRecords[i].trainerId[j] != newRecord->trainerId[j]) break; } if (j == 4) @@ -544,9 +550,9 @@ void PutNewBattleTowerRecord(union BattleTowerRecord *newRecord) for (k = 0; k < PLAYER_NAME_LENGTH; k++) { // BUG: Wrong variable used, 'j' instead of 'k'. - if (gSaveBlock2Ptr->frontier.towerRecords[i].name[j] != newRecordEm->name[j]) + if (gSaveBlock2Ptr->frontier.towerRecords[i].name[j] != newRecord->name[j]) break; - if (newRecordEm->name[j] == EOS) + if (newRecord->name[j] == EOS) { k = PLAYER_NAME_LENGTH; break; @@ -559,7 +565,7 @@ void PutNewBattleTowerRecord(union BattleTowerRecord *newRecord) } if (i < 5) { - gSaveBlock2Ptr->frontier.towerRecords[i] = *newRecordEm; + gSaveBlock2Ptr->frontier.towerRecords[i] = *newRecord; return; } @@ -571,7 +577,7 @@ void PutNewBattleTowerRecord(union BattleTowerRecord *newRecord) } if (i < 5) { - gSaveBlock2Ptr->frontier.towerRecords[i] = *newRecordEm; + gSaveBlock2Ptr->frontier.towerRecords[i] = *newRecord; return; } @@ -607,7 +613,7 @@ void PutNewBattleTowerRecord(union BattleTowerRecord *newRecord) } i = Random() % slotsCount; - gSaveBlock2Ptr->frontier.towerRecords[slotIds[i]] = *newRecordEm; + gSaveBlock2Ptr->frontier.towerRecords[slotIds[i]] = *newRecord; } u8 GetFrontierTrainerFrontSpriteId(u16 trainerId) @@ -822,17 +828,17 @@ bool8 IsFrontierTrainerFemale(u16 trainerId) return FALSE; } -void sub_8163048(u8 monsCount) +void FillFrontierTrainerParty(u8 monsCount) { ZeroEnemyPartyMons(); - sub_81630C4(gTrainerBattleOpponent_A, 0, monsCount); + FillTrainerParty(gTrainerBattleOpponent_A, 0, monsCount); } -void sub_816306C(u8 monsCount) +void FillFrontierTrainersParties(u8 monsCount) { ZeroEnemyPartyMons(); - sub_81630C4(gTrainerBattleOpponent_A, 0, monsCount); - sub_81630C4(gTrainerBattleOpponent_B, 3, monsCount); + FillTrainerParty(gTrainerBattleOpponent_A, 0, monsCount); + FillTrainerParty(gTrainerBattleOpponent_B, 3, monsCount); } void sub_81630A0(u8 monsCount) @@ -841,7 +847,7 @@ void sub_81630A0(u8 monsCount) sub_8165EA4(gTrainerBattleOpponent_A, 0, monsCount); } -void sub_81630C4(u16 trainerId, u8 firstMonId, u8 monCount) +static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) { s32 i, j; u16 chosenMonIndices[4]; @@ -983,15 +989,15 @@ void Unused_CreateApprenticeMons(u16 trainerId, u8 firstMonId) for (i = 0; i != 3; i++) { - CreateMonWithEVSpread(&gEnemyParty[firstMonId + i], apprentice->monData[i].species, level, fixedIV, 8); + CreateMonWithEVSpread(&gEnemyParty[firstMonId + i], apprentice->party[i].species, level, fixedIV, 8); friendship = 0xFF; for (j = 0; j < 4; j++) { - if (apprentice->monData[i].moves[j] == MOVE_FRUSTRATION) + if (apprentice->party[i].moves[j] == MOVE_FRUSTRATION) friendship = 0; } SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_FRIENDSHIP, &friendship); - SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_HELD_ITEM, &apprentice->monData[i].item); + SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_HELD_ITEM, &apprentice->party[i].item); } } @@ -1053,7 +1059,7 @@ void sub_81635D4(u16 trainerId, u8 firstMonId) { u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; // Unused variable. u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); - u8 challengeNum = gSaveBlock2Ptr->frontier.field_CE0[battleMode][0] / 7; + u8 challengeNum = gSaveBlock2Ptr->frontier.winStreaks[battleMode][0] / 7; if (gSaveBlock2Ptr->frontier.curChallengeBattleNum < 6) fixedIV = sub_81A6CA8(challengeNum, 0); else @@ -1201,7 +1207,7 @@ static void HandleSpecialTrainerBattleEnd(void) } break; case SPECIAL_BATTLE_EREADER: - sub_816537C(); + CopyEReaderTrainerFarewellMessage(); break; } @@ -1233,21 +1239,21 @@ void DoSpecialTrainerBattle(void) switch (VarGet(VAR_FRONTIER_BATTLE_MODE)) { case FRONTIER_MODE_SINGLES: - sub_8163048(3); + FillFrontierTrainerParty(3); break; case FRONTIER_MODE_DOUBLES: - sub_8163048(4); + FillFrontierTrainerParty(4); gBattleTypeFlags |= BATTLE_TYPE_DOUBLE; break; case FRONTIER_MODE_MULTIS: - sub_816306C(2); - gPartnerTrainerId = gSaveBlock2Ptr->frontier.field_CD6; + FillFrontierTrainersParties(2); + gPartnerTrainerId = gSaveBlock2Ptr->frontier.field_CB4[17]; sub_8165404(gPartnerTrainerId); gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS; break; case FRONTIER_MODE_LINK_MULTIS: gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_LINK | BATTLE_TYPE_MULTI | BATTLE_TYPE_x800000; - sub_816306C(2); + FillFrontierTrainersParties(2); break; } CreateTask(Task_StartBattleAfterTransition, 1); @@ -1279,7 +1285,7 @@ void DoSpecialTrainerBattle(void) if (VarGet(VAR_FRONTIER_BATTLE_MODE) == FRONTIER_MODE_DOUBLES) gBattleTypeFlags |= BATTLE_TYPE_DOUBLE; if (gTrainerBattleOpponent_A == TRAINER_FRONTIER_BRAIN) - sub_8163048(2); + FillFrontierTrainerParty(2); CreateTask(Task_StartBattleAfterTransition, 1); sub_806E694(0); BattleTransition_StartOnField(sub_80B100C(3)); @@ -1289,7 +1295,7 @@ void DoSpecialTrainerBattle(void) if (VarGet(VAR_FRONTIER_BATTLE_MODE) == FRONTIER_MODE_DOUBLES) gBattleTypeFlags |= BATTLE_TYPE_DOUBLE; if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT) - sub_8163048(3); + FillFrontierTrainerParty(3); else sub_81630A0(3); CreateTask(Task_StartBattleAfterTransition, 1); @@ -1299,7 +1305,7 @@ void DoSpecialTrainerBattle(void) case SPECIAL_BATTLE_ARENA: gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_ARENA; if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT) - sub_8163048(3); + FillFrontierTrainerParty(3); else sub_81630A0(3); CreateTask(Task_StartBattleAfterTransition, 1); @@ -1317,21 +1323,21 @@ void DoSpecialTrainerBattle(void) break; case SPECIAL_BATTLE_PIKE_SINGLE: gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_BATTLE_TOWER; - sub_8163048(3); + FillFrontierTrainerParty(3); CreateTask(Task_StartBattleAfterTransition, 1); PlayMapChosenOrBattleBGM(0); BattleTransition_StartOnField(sub_80B100C(7)); break; case SPECIAL_BATTLE_PYRAMID: gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_PYRAMID; - sub_8163048(3); + FillFrontierTrainerParty(3); CreateTask(Task_StartBattleAfterTransition, 1); PlayMapChosenOrBattleBGM(0); BattleTransition_StartOnField(sub_80B100C(10)); break; case SPECIAL_BATTLE_PIKE_DOUBLE: gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS; - sub_816306C(1); + FillFrontierTrainersParties(1); CreateTask(Task_StartBattleAfterTransition, 1); PlayMapChosenOrBattleBGM(0); BattleTransition_StartOnField(sub_80B100C(7)); @@ -1357,8 +1363,8 @@ void SaveCurrentWinStreak(void) u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); u16 winStreak = GetCurrentBattleTowerWinStreak(lvlMode, battleMode); - if (gSaveBlock2Ptr->frontier.field_CE0[battleMode][lvlMode] < winStreak) - gSaveBlock2Ptr->frontier.field_CE0[battleMode][lvlMode] = winStreak; + if (gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] < winStreak) + gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] = winStreak; } void sub_8163EE4(void) @@ -1367,7 +1373,7 @@ void sub_8163EE4(void) u8 lvlMode, battleMode, class; struct EmeraldBattleTowerRecord *playerRecord = &gSaveBlock2Ptr->frontier.towerPlayer; - sub_8164FB8(playerRecord); + ClearBattleTowerRecord(playerRecord); lvlMode = gSaveBlock2Ptr->frontier.lvlMode; battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); if (gSaveBlock2Ptr->playerGender != MALE) @@ -1399,8 +1405,8 @@ void sub_8163EE4(void) for (i = 0; i < 4; i++) { - if (gSaveBlock2Ptr->frontier.field_CAA[i] != 0) - sub_80686FC(&gPlayerParty[gSaveBlock2Ptr->frontier.field_CAA[i] - 1], &playerRecord->party[i]); + if (gSaveBlock2Ptr->frontier.selectedPartyMons[i] != 0) + sub_80686FC(&gPlayerParty[gSaveBlock2Ptr->frontier.selectedPartyMons[i] - 1], &playerRecord->party[i]); } playerRecord->language = gGameLanguage; @@ -1412,7 +1418,7 @@ void SaveBattleTowerProgress(void) { u16 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; u16 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); - s32 challengeNum = (signed)(gSaveBlock2Ptr->frontier.field_CE0[battleMode][lvlMode] / 7); + s32 challengeNum = (signed)(gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] / 7); if (gSpecialVar_0x8005 == 0 && (challengeNum > 1 || gSaveBlock2Ptr->frontier.curChallengeBattleNum != 0)) sub_8163EE4(); @@ -1443,7 +1449,7 @@ void sub_81640E0(u16 trainerId) count = 0; for (i = 0; i < 3; i++) { - u16 apprenticeSpecies = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].monData[i].species; + u16 apprenticeSpecies = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].party[i].species; if (apprenticeSpecies != species1 && apprenticeSpecies != species2) { validSpecies[count] = i; @@ -1502,43 +1508,45 @@ void sub_81642A0(void) eventObjTemplates = gSaveBlock1Ptr->eventObjectTemplates; lvlMode = gSaveBlock2Ptr->frontier.lvlMode; battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); - challengeNum = gSaveBlock2Ptr->frontier.field_CE0[battleMode][lvlMode] / 7; + challengeNum = gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] / 7; species1 = GetMonData(&gPlayerParty[0], MON_DATA_SPECIES, NULL); species2 = GetMonData(&gPlayerParty[1], MON_DATA_SPECIES, NULL); level = GetFacilityEnemyMonLevel(); - for (j = 0; j < 6; j++) + j = 0; + do { do { trainerId = sub_8162548(challengeNum, 0); for (i = 0; i < j; i++) { - if (gSaveBlock2Ptr->frontier.battledTrainerIds[i] == trainerId) + if (gSaveBlock2Ptr->frontier.field_CB4[i] == trainerId) break; - if (gFacilityTrainers[gSaveBlock2Ptr->frontier.battledTrainerIds[i]].facilityClass == gFacilityTrainers[trainerId].facilityClass) + if (gFacilityTrainers[gSaveBlock2Ptr->frontier.field_CB4[i]].facilityClass == gFacilityTrainers[trainerId].facilityClass) break; } } while (i != j); - gSaveBlock2Ptr->frontier.battledTrainerIds[j] = trainerId; - } + gSaveBlock2Ptr->frontier.field_CB4[j] = trainerId; + j++; + } while (j < 6); r10 = 8; for (i = 0; i < 6; i++) { - trainerId = gSaveBlock2Ptr->frontier.battledTrainerIds[i]; + trainerId = gSaveBlock2Ptr->frontier.field_CB4[i]; eventObjTemplates[i + 1].graphicsId = GetBattleFacilityTrainerGfxId(trainerId); for (j = 0; j < 2; j++) { while (1) { monPoolId = RandomizeFacilityTrainerMonId(trainerId); - if (j % 2 != 0 && gFacilityTrainerMons[gSaveBlock2Ptr->frontier.battledTrainerIds[r10 - 1]].itemTableId == gFacilityTrainerMons[monPoolId].itemTableId) + if (j % 2 != 0 && gFacilityTrainerMons[gSaveBlock2Ptr->frontier.field_CB4[r10 - 1]].itemTableId == gFacilityTrainerMons[monPoolId].itemTableId) continue; for (k = 8; k < r10; k++) { - if (gFacilityTrainerMons[gSaveBlock2Ptr->frontier.battledTrainerIds[k]].species == gFacilityTrainerMons[monPoolId].species) + if (gFacilityTrainerMons[gSaveBlock2Ptr->frontier.field_CB4[k]].species == gFacilityTrainerMons[monPoolId].species) break; if (species1 == gFacilityTrainerMons[monPoolId].species) break; @@ -1549,7 +1557,7 @@ void sub_81642A0(void) break; } - gSaveBlock2Ptr->frontier.battledTrainerIds[r10] = monPoolId; + gSaveBlock2Ptr->frontier.field_CB4[r10] = monPoolId; r10++; } } @@ -1565,8 +1573,8 @@ void sub_81642A0(void) k = 0; for (j = 0; j < 3; j++) { - if (species1 != gSaveBlock2Ptr->apprentices[i].monData[j].species - && species2 != gSaveBlock2Ptr->apprentices[i].monData[j].species) + if (species1 != gSaveBlock2Ptr->apprentices[i].party[j].species + && species2 != gSaveBlock2Ptr->apprentices[i].party[j].species) { k++; } @@ -1580,10 +1588,10 @@ void sub_81642A0(void) } if (r10 != 0) { - gSaveBlock2Ptr->frontier.battledTrainerIds[6] = spArray[Random() % r10]; - eventObjTemplates[7].graphicsId = GetBattleFacilityTrainerGfxId(gSaveBlock2Ptr->frontier.battledTrainerIds[6]); + gSaveBlock2Ptr->frontier.field_CB4[6] = spArray[Random() % r10]; + eventObjTemplates[7].graphicsId = GetBattleFacilityTrainerGfxId(gSaveBlock2Ptr->frontier.field_CB4[6]); FlagClear(FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_1); - sub_81640E0(gSaveBlock2Ptr->frontier.battledTrainerIds[6]); + sub_81640E0(gSaveBlock2Ptr->frontier.field_CB4[6]); } r10 = 0; @@ -1623,9 +1631,716 @@ void sub_81642A0(void) } if (r10 != 0) { - gSaveBlock2Ptr->frontier.battledTrainerIds[7] = spArray[Random() % r10]; - eventObjTemplates[8].graphicsId = GetBattleFacilityTrainerGfxId(gSaveBlock2Ptr->frontier.battledTrainerIds[7]); + gSaveBlock2Ptr->frontier.field_CB4[7] = spArray[Random() % r10]; + eventObjTemplates[8].graphicsId = GetBattleFacilityTrainerGfxId(gSaveBlock2Ptr->frontier.field_CB4[7]); FlagClear(FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_2); - sub_8164188(gSaveBlock2Ptr->frontier.battledTrainerIds[7]); + sub_8164188(gSaveBlock2Ptr->frontier.field_CB4[7]); + } +} + +void sub_81646BC(u16 trainerId, u16 monPoolId) +{ + u16 move = 0; + u16 species = 0; + GetFacilityEnemyMonLevel(); // Pointless function call. + + if (trainerId != BATTLE_TOWER_EREADER_TRAINER_ID) + { + if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + move = gFacilityTrainerMons[monPoolId].moves[0]; + species = gFacilityTrainerMons[monPoolId].species; + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + move = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[gUnknown_03006298[gSpecialVar_0x8005 + 1]].moves[0]; + species = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[gUnknown_03006298[gSpecialVar_0x8005 + 1]].species; + } + else + { + s32 i; + + move = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].party[gUnknown_03006298[gSpecialVar_0x8005 - 1]].moves[0]; + species = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].party[gUnknown_03006298[gSpecialVar_0x8005 - 1]].species; + for (i = 0; i < PLAYER_NAME_LENGTH; i++) + gStringVar3[i] = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].playerName[i]; + gStringVar3[i] = EOS; + ConvertInternationalString(gStringVar3, gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].language); + } + } + + StringCopy(gStringVar1, gMoveNames[move]); + StringCopy(gStringVar2, gSpeciesNames[species]); +} + +struct +{ + u32 facilityClass; + const u8 *const *strings; +} extern const gUnknown_085DD500[50]; + +extern const u8 *const *const gUnknown_085DD690[]; +extern const u8 gUnknown_085DFA42[4]; + +void sub_8164828(void) +{ + s32 i, j, arrId; + s32 monPoolId; + s32 level = GetFacilityEnemyMonLevel(); // Unused variable. + s32 challengeNum = sub_81A39C4() / 7; + s32 k = gSpecialVar_LastTalked - 2; + s32 trainerId = gSaveBlock2Ptr->frontier.field_CB4[k]; + + for (arrId = 0; arrId < ARRAY_COUNT(gUnknown_085DD500); arrId++) + { + if (gUnknown_085DD500[arrId].facilityClass == GetFrontierTrainerFacilityClass(trainerId)) + break; + } + + switch (gSpecialVar_0x8005) + { + case 0: + if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + return; + if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + GetFrontierTrainerName(gStringVar1, trainerId); + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + GetFrontierTrainerName(gStringVar1, trainerId); + } + else + { + s32 i; + for (i = 0; i < PLAYER_NAME_LENGTH; i++) + gStringVar1[i] = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].playerName[i]; + gStringVar1[i] = EOS; + ConvertInternationalString(gStringVar1, gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].language); + ConvertIntToDecimalStringN(gStringVar2, gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].number, STR_CONV_MODE_LEFT_ALIGN, 3); + GetFrontierTrainerName(gStringVar3, trainerId); + } + break; + case 1: + monPoolId = gSaveBlock2Ptr->frontier.field_CB4[8 + k * 2]; + sub_81646BC(trainerId, monPoolId); + break; + case 2: + monPoolId = gSaveBlock2Ptr->frontier.field_CB4[9 + k * 2]; + sub_81646BC(trainerId, monPoolId); + break; + case 3: + gPartnerTrainerId = trainerId; + if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + gSaveBlock2Ptr->frontier.field_CB4[18] = gSaveBlock2Ptr->frontier.field_CB4[8 + k * 2]; + gSaveBlock2Ptr->frontier.field_CB4[19] = gSaveBlock2Ptr->frontier.field_CB4[9 + k * 2]; + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + gSaveBlock2Ptr->frontier.field_CB4[18] = gUnknown_03006298[2]; + gSaveBlock2Ptr->frontier.field_CB4[19] = gUnknown_03006298[3]; + } + else + { + gSaveBlock2Ptr->frontier.field_CB4[18] = gUnknown_03006298[0]; + gSaveBlock2Ptr->frontier.field_CB4[19] = gUnknown_03006298[1]; + } + for (k = 0; k < 14; k++) + { + while (1) + { + i = sub_8162548(challengeNum, k / 2); + if (gPartnerTrainerId == i) + continue; + + for (j = 0; j < k; j++) + { + if (gSaveBlock2Ptr->frontier.field_CB4[j] == i) + break; + } + if (j == k) + break; + } + gSaveBlock2Ptr->frontier.field_CB4[k] = i; + } + gSaveBlock2Ptr->frontier.field_CB4[17] = trainerId; + break; + case 4: + break; + } + + if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + return; + + if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + ShowFieldMessage(gUnknown_085DD500[arrId].strings[gSpecialVar_0x8005]); + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + ShowFieldMessage(gUnknown_085DD500[arrId].strings[gSpecialVar_0x8005]); + } + else + { + u8 id = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id; + ShowFieldMessage(gUnknown_085DD690[id][gSpecialVar_0x8005]); + } +} + +void sub_8164B74(void) +{ + s32 challengeNum; + s32 i, j; + s32 trainerId = 0; + u32 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; + u32 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); + u32 battleNum = gSaveBlock2Ptr->frontier.curChallengeBattleNum; + GetMultiplayerId(); // Yet another pointless function call. + + switch (gSpecialVar_Result) + { + case 0: + if (battleMode == FRONTIER_MODE_LINK_MULTIS) + { + challengeNum = gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] / 7; + if (sub_800A520()) + { + SendBlock(bitmask_all_link_players_but_self(), &challengeNum, sizeof(challengeNum)); + gSpecialVar_Result = 1; + } + } + else + { + gSpecialVar_Result = 6; + } + break; + case 1: + if ((GetBlockReceivedStatus() & 3) == 3) + { + ResetBlockReceivedFlags(); + if (gBlockRecvBuffer[0][0] > gBlockRecvBuffer[1][0]) + challengeNum = gBlockRecvBuffer[0][0]; + else + challengeNum = gBlockRecvBuffer[1][0]; + for (i = 0; i < 14; i++) + { + do + { + trainerId = sub_8162548(challengeNum, i / 2); + for (j = 0; j < i; j++) + { + if (gSaveBlock2Ptr->frontier.field_CB4[j] == trainerId) + break; + } + } while (i != j); + if (i == j) // This condition is always true, because of the loop above. + gSaveBlock2Ptr->frontier.field_CB4[i] = trainerId; + } + gSpecialVar_Result = 2; + } + break; + case 2: + if (sub_800A520()) + { + SendBlock(bitmask_all_link_players_but_self(), &gSaveBlock2Ptr->frontier.field_CB4, sizeof(gSaveBlock2Ptr->frontier.field_CB4)); + gSpecialVar_Result = 3; + } + break; + case 3: + if ((GetBlockReceivedStatus() & 3) == 3) + { + ResetBlockReceivedFlags(); + memcpy(&gSaveBlock2Ptr->frontier.field_CB4, gBlockRecvBuffer, sizeof(gSaveBlock2Ptr->frontier.field_CB4)); + gTrainerBattleOpponent_A = gSaveBlock2Ptr->frontier.field_CB4[battleNum * 2]; + gTrainerBattleOpponent_B = gSaveBlock2Ptr->frontier.field_CB4[battleNum * 2 + 1]; + SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_A, 0); + SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_B, 1); + if (gReceivedRemoteLinkPlayers != 0 && gWirelessCommType == 0) + gSpecialVar_Result = 4; + else + gSpecialVar_Result = 6; + } + break; + case 4: + sub_800AC34(); + gSpecialVar_Result = 5; + break; + case 5: + if (gReceivedRemoteLinkPlayers == 0) + { + gSpecialVar_Result = 6; + } + break; + case 6: + return; + } +} + +void sub_8164DCC(void) +{ + if (gWirelessCommType != 0) + sub_800AC34(); +} + +void sub_8164DE4(void) +{ + SetBattleFacilityTrainerGfxId(gSaveBlock2Ptr->frontier.field_CB4[17], 0xF); +} + +void sub_8164E04(void) +{ + s32 i; + u8 text[32]; + + if (VarGet(VAR_FRONTIER_BATTLE_MODE) != FRONTIER_MODE_SINGLES) + return; + + GetFrontierTrainerName(text, gTrainerBattleOpponent_A); + StripExtCtrlCodes(text); + StringCopy(gSaveBlock2Ptr->frontier.field_BD8, text); + sub_8165B88(&gSaveBlock2Ptr->frontier.field_BEB, gTrainerBattleOpponent_A); + gSaveBlock2Ptr->frontier.field_BD6 = GetMonData(&gEnemyParty[gBattlerPartyIndexes[1]], MON_DATA_SPECIES, NULL); + gSaveBlock2Ptr->frontier.field_BD4 = GetMonData(&gPlayerParty[gBattlerPartyIndexes[0]], MON_DATA_SPECIES, NULL); + for (i = 0; i < POKEMON_NAME_LENGTH + 1; i++) + gSaveBlock2Ptr->frontier.field_BE0[i] = gBattleMons[0].nickname[i]; + gSaveBlock2Ptr->frontier.field_D06 = gBattleOutcome; +} + +void ValidateBattleTowerRecordChecksums(void) +{ + s32 i, j; + u32 *record = (u32*)(&gSaveBlock2Ptr->frontier.towerPlayer); + u32 checksum = 0; + + for (j = 0; j < (sizeof(struct EmeraldBattleTowerRecord) - 4) / 4; j++) // - 4, because of the last field being the checksum itself. + { + checksum += record[j]; + } + if (gSaveBlock2Ptr->frontier.towerPlayer.checksum != checksum) + ClearBattleTowerRecord(&gSaveBlock2Ptr->frontier.towerPlayer); + + for (i = 0; i < 5; i++) + { + record = (u32*)(&gSaveBlock2Ptr->frontier.towerRecords[i]); + checksum = 0; + for (j = 0; j < (sizeof(struct EmeraldBattleTowerRecord) - 4) / 4; j++) // - 4, because of the last field being the checksum itself. + { + checksum += record[j]; + } + if (gSaveBlock2Ptr->frontier.towerRecords[i].checksum != checksum) + ClearBattleTowerRecord(&gSaveBlock2Ptr->frontier.towerRecords[i]); + } +} + +void CalcEmeraldBattleTowerChecksum(struct EmeraldBattleTowerRecord *record) +{ + u32 i; + + record->checksum = 0; + for (i = 0; i < (sizeof(struct EmeraldBattleTowerRecord) - 4) / 4; i++) // - 4, because of the last field being the checksum itself. + record->checksum += ((u32 *)record)[i]; +} + +void CalcRubyBattleTowerChecksum(struct RSBattleTowerRecord *record) +{ + u32 i; + + record->checksum = 0; + for (i = 0; i < (sizeof(struct RSBattleTowerRecord) - 4) / 4; i++) // - 4, because of the last field being the checksum itself. + record->checksum += ((u32 *)record)[i]; +} + +void ClearBattleTowerRecord(struct EmeraldBattleTowerRecord *record) +{ + u32 i; + + for (i = 0; i < sizeof(struct EmeraldBattleTowerRecord) / 4; i++) + ((u32 *)record)[i] = 0; +} + +u16 GetCurrentBattleTowerWinStreak(u8 lvlMode, u8 battleMode) +{ + u16 winStreak = gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode]; + + if (winStreak > 9999) + return 9999; + else + return winStreak; +} + +u8 GetMonCountForBattleMode(u8 battleMode) +{ + u8 sp[ARRAY_COUNT(gUnknown_085DFA42)]; + memcpy(sp, gUnknown_085DFA42, sizeof(gUnknown_085DFA42)); + + if (battleMode < ARRAY_COUNT(gUnknown_085DFA42)) + return sp[battleMode]; + else + return 3; +} + +struct RibbonCounter +{ + u8 partyIndex; + u8 count; +}; + +void AwardBattleTowerRibbons(void) +{ + s32 i; + u32 partyIndex; + struct RibbonCounter ribbons[3]; // BUG: 4 Pokemon can receive ribbons in a double battle mode. + u8 ribbonType = 0; + u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; + u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); + u8 monCount = GetMonCountForBattleMode(battleMode); + + if (lvlMode != FRONTIER_LVL_50) + ribbonType = MON_DATA_VICTORY_RIBBON; + else + ribbonType = MON_DATA_WINNING_RIBBON; + + gSpecialVar_Result = FALSE; + + if (GetCurrentBattleTowerWinStreak(lvlMode, battleMode) > 55) + { + for (i = 0; i < monCount; i++) + { + partyIndex = gSaveBlock2Ptr->frontier.selectedPartyMons[i] - 1; + ribbons[i].partyIndex = partyIndex; + ribbons[i].count = 0; + if (!GetMonData(&gSaveBlock1Ptr->playerParty[partyIndex], ribbonType)) + { + gSpecialVar_Result = TRUE; + SetMonData(&gSaveBlock1Ptr->playerParty[partyIndex], ribbonType, &gSpecialVar_Result); + ribbons[i].count = GetRibbonCount(&gSaveBlock1Ptr->playerParty[partyIndex]); + } + } + } + + if (gSpecialVar_Result) + { + IncrementGameStat(GAME_STAT_RECEIVED_RIBBONS); + for (i = 1; i < monCount; i++) + { + if (ribbons[i].count > ribbons[0].count) + { + struct RibbonCounter prevBest = ribbons[0]; + ribbons[0] = ribbons[i]; + ribbons[i] = prevBest; + } + } + if (ribbons[0].count > 4) + { + sub_80EE4DC(&gSaveBlock1Ptr->playerParty[ribbons[0].partyIndex], ribbonType); + } + } +} + +// This is a leftover debugging function that is used to populate the E-Reader +// trainer with the player's current data. +void FillEReaderTrainerWithPlayerData(void) +{ + struct BattleTowerEReaderTrainer *ereaderTrainer = &gSaveBlock2Ptr->frontier.ereaderTrainer; + s32 i, j; + + if (gSaveBlock2Ptr->playerGender != MALE) + { + ereaderTrainer->facilityClass = gTowerFemaleFacilityClasses[(gSaveBlock2Ptr->playerTrainerId[0] + gSaveBlock2Ptr->playerTrainerId[1] + + gSaveBlock2Ptr->playerTrainerId[2] + gSaveBlock2Ptr->playerTrainerId[3]) % ARRAY_COUNT(gTowerFemaleFacilityClasses)]; + } + else + { + ereaderTrainer->facilityClass = gTowerMaleFacilityClasses[(gSaveBlock2Ptr->playerTrainerId[0] + gSaveBlock2Ptr->playerTrainerId[1] + + gSaveBlock2Ptr->playerTrainerId[2] + gSaveBlock2Ptr->playerTrainerId[3]) % ARRAY_COUNT(gTowerMaleFacilityClasses)]; + } + + CopyUnalignedWord(ereaderTrainer->trainerId, gSaveBlock2Ptr->playerTrainerId); + StringCopy7(ereaderTrainer->name, gSaveBlock2Ptr->playerName); + + ereaderTrainer->winStreak = 1; + + j = 7; + for (i = 0; i < 6; i++) + { + ereaderTrainer->greeting[i] = gSaveBlock1Ptr->unk2BBC[i]; + ereaderTrainer->farewellPlayerLost[i] = j; + ereaderTrainer->farewellPlayerWon[i] = j + 6; + j++; + } + + for (i = 0; i < 3; i++) + sub_80686FC(&gPlayerParty[i], &ereaderTrainer->party[i]); + + SetEReaderTrainerChecksum(ereaderTrainer); +} + +u8 GetEreaderTrainerFrontSpriteId(void) +{ + return gFacilityClassToPicIndex[gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass]; +} + +u8 GetEreaderTrainerClassId(void) +{ + return gFacilityClassToTrainerClass[gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass]; +} + +void GetEreaderTrainerName(u8 *trainerName) +{ + s32 i; + + for (i = 0; i < 5; i++) + trainerName[i] = gSaveBlock2Ptr->frontier.ereaderTrainer.name[i]; + + trainerName[i] = EOS; +} + +// Checks if the saved E-Reader trainer is valid. +void ValidateEReaderTrainer(void) +{ + u32 i; + u32 checksum; + struct BattleTowerEReaderTrainer *ereaderTrainer; + + gSpecialVar_Result = FALSE; + ereaderTrainer = &gSaveBlock2Ptr->frontier.ereaderTrainer; + + checksum = 0; + for (i = 0; i < (sizeof(struct BattleTowerEReaderTrainer) - 4) / 4; i++) // - 4, because of the last field being the checksum itself. + checksum |= ((u32 *)ereaderTrainer)[i]; + + if (checksum == 0) + { + gSpecialVar_Result = TRUE; + return; + } + + checksum = 0; + for (i = 0; i < (sizeof(struct BattleTowerEReaderTrainer) - 4) / 4; i++) // - 4, because of the last field being the checksum itself. + checksum += ((u32 *)ereaderTrainer)[i]; + + if (gSaveBlock2Ptr->frontier.ereaderTrainer.checksum != checksum) + { + ClearEReaderTrainer(&gSaveBlock2Ptr->frontier.ereaderTrainer); + gSpecialVar_Result = TRUE; + } +} + +void SetEReaderTrainerChecksum(struct BattleTowerEReaderTrainer *ereaderTrainer) +{ + s32 i; + + ereaderTrainer->checksum = 0; + for (i = 0; i < (sizeof(struct BattleTowerEReaderTrainer) - 4) / 4; i++) // - 4, because of the last field being the checksum itself. + ereaderTrainer->checksum += ((u32 *)ereaderTrainer)[i]; +} + +void ClearEReaderTrainer(struct BattleTowerEReaderTrainer *ereaderTrainer) +{ + u32 i; + + for (i = 0; i < (sizeof(struct BattleTowerEReaderTrainer)) / 4; i++) + ((u32 *)ereaderTrainer)[i] = 0; +} + +void CopyEReaderTrainerGreeting(void) +{ + FrontierSpeechToString(gSaveBlock2Ptr->frontier.ereaderTrainer.greeting); +} + +void CopyEReaderTrainerFarewellMessage(void) +{ + if (gBattleOutcome == B_OUTCOME_DREW) + gStringVar4[0] = EOS; + else if (gBattleOutcome == B_OUTCOME_WON) + FrontierSpeechToString(gSaveBlock2Ptr->frontier.ereaderTrainer.farewellPlayerWon); + else + FrontierSpeechToString(gSaveBlock2Ptr->frontier.ereaderTrainer.farewellPlayerLost); +} + +void sub_81653CC(void) +{ + if (gSaveBlock2Ptr->frontier.field_CA8 == 1) + sub_80F01B8(); + if (FlagGet(FLAG_0x077) == TRUE) + { + sub_80F01B8(); + FlagClear(FLAG_0x077); + } +} + +struct StevenMon +{ + u16 species; + u8 fixedIV; + u8 level; + u8 nature; + u8 evs[6]; + u16 moves[4]; +}; + +extern const struct StevenMon sStevenMons[3]; + +#define STEVEN_OTID 61226 + +void sub_8165404(u16 trainerId) +{ + s32 i, j; + u32 ivs, level; + u32 friendship; + u16 monPoolId; + u32 otID; + u8 trainerName[PLAYER_NAME_LENGTH + 1]; + GetFacilityEnemyMonLevel(); // Unused return variable. + + if (trainerId == TRAINER_STEVEN_PARTNER) + { + for (i = 0; i < 3; i++) + { + do + { + j = Random32(); + } while (IsShinyOtIdPersonality(STEVEN_OTID, j) || sStevenMons[i].nature != GetNatureFromPersonality(j)); + CreateMon(&gPlayerParty[3 + i], + sStevenMons[i].species, + sStevenMons[i].level, + sStevenMons[i].fixedIV, + TRUE, i, // BUG: personality was stored in the 'j' variable. As a result, Steven's pokemon do not have the intended natures. + TRUE, STEVEN_OTID); + for (j = 0; j < 6; j++) + SetMonData(&gPlayerParty[3 + i], MON_DATA_HP_EV + j, &sStevenMons[i].evs[j]); + for (j = 0; j < 4; j++) + SetMonMoveSlot(&gPlayerParty[3 + i], sStevenMons[i].moves[j], j); + SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_NAME, gTrainers[TRAINER_STEVEN].trainerName); + j = MALE; + SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_GENDER, &j); + CalculateMonStats(&gPlayerParty[3 + i]); + } + } + else if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + { + // Scrapped, lol. + trainerName[0] = gGameLanguage; + } + else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + level = GetFacilityEnemyMonLevel(); + ivs = GetFrontierTrainerFixedIvs(trainerId); + otID = Random32(); + for (i = 0; i < 2; i++) + { + monPoolId = gSaveBlock2Ptr->frontier.field_CB4[i + 18]; + CreateMonWithEVSpreadPersonalityOTID(&gPlayerParty[3 + i], + gFacilityTrainerMons[monPoolId].species, + level, + gFacilityTrainerMons[monPoolId].nature, + ivs, + gFacilityTrainerMons[monPoolId].evSpread, + otID); + friendship = 0xFF; + for (j = 0; j < 4; j++) + { + SetMonMoveSlot(&gPlayerParty[3 + i], gFacilityTrainerMons[monPoolId].moves[j], j); + if (gFacilityTrainerMons[monPoolId].moves[j] == MOVE_FRUSTRATION) + friendship = 0; + } + SetMonData(&gPlayerParty[3 + i], MON_DATA_FRIENDSHIP, &friendship); + SetMonData(&gPlayerParty[3 + i], MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[monPoolId].itemTableId]); + for (j = 0; j < PLAYER_NAME_LENGTH + 1; j++) + trainerName[j] = gFacilityTrainers[trainerId].trainerName[j]; + SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_NAME, &trainerName); + j = IsFrontierTrainerFemale(trainerId); + SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_GENDER, &j); + } + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + trainerId -= BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID; + for (i = 0; i < 2; i++) + { + struct EmeraldBattleTowerRecord *record = &gSaveBlock2Ptr->frontier.towerRecords[trainerId]; + struct UnknownPokemonStruct monData = record->party[gSaveBlock2Ptr->frontier.field_CB4[18 + i]]; + StringCopy(trainerName, record->name); + if (record->language == LANGUAGE_JAPANESE) + { + if (monData.nickname[0] != EXT_CTRL_CODE_BEGIN || monData.nickname[1] != EXT_CTRL_CODE_JPN) + { + monData.nickname[5] = EOS; + ConvertInternationalString(monData.nickname, LANGUAGE_JAPANESE); + } + } + else + { + if (monData.nickname[0] == EXT_CTRL_CODE_BEGIN && monData.nickname[1] == EXT_CTRL_CODE_JPN) + trainerName[5] = EOS; + } + sub_8068338(&gPlayerParty[3 + i], &monData, TRUE); + SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_NAME, trainerName); + j = IsFrontierTrainerFemale(trainerId + BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID); + SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_GENDER, &j); + } + } + else + { + trainerId -= BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID; + for (i = 0; i < 2; i++) + { + CreateApprenticeMon(&gPlayerParty[3 + i], &gSaveBlock2Ptr->apprentices[trainerId], gSaveBlock2Ptr->frontier.field_CB4[18 + i]); + j = IsFrontierTrainerFemale(trainerId + BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID); + SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_GENDER, &j); + } + } +} + +extern const u8 sRubyFacilityClassToEmerald[82][2]; +extern const u16 gUnknown_085DFA46[]; +extern const u16 gUnknown_085DFA52[]; + +bool32 RubyBattleTowerRecordToEmerald(struct RSBattleTowerRecord *src, struct EmeraldBattleTowerRecord *dst) +{ + s32 i, validMons = 0; + + for (i = 0; i < 3; i++) + { + if (src->party[i].species) + validMons++; + } + + if (validMons != 3) + { + memset(dst, 0, sizeof(*dst)); + return FALSE; + } + else + { + dst->lvlMode = src->lvlMode; + dst->winStreak = src->winStreak; + for (i = 0; i < (signed) ARRAY_COUNT(sRubyFacilityClassToEmerald); i++) + { + if (sRubyFacilityClassToEmerald[i][0] == src->facilityClass) + break; + } + if (i != ARRAY_COUNT(sRubyFacilityClassToEmerald)) + dst->facilityClass = sRubyFacilityClassToEmerald[i][1]; + else + dst->facilityClass = FACILITY_CLASS_YOUNGSTER; + + for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++) + dst->name[i] = src->name[i]; + for (i = 0; i < 4; i++) + dst->trainerId[i] = src->trainerId[i]; + for (i = 0; i < 6; i++) + dst->greeting[i] = src->greeting[i]; + for (i = 0; i < 6; i++) + dst->unk1C[i] = gUnknown_085DFA46[i]; + for (i = 0; i < 6; i++) + dst->unk28[i] = gUnknown_085DFA52[i]; + for (i = 0; i < 3; i++) + dst->party[i] = src->party[i]; + + CpuFill32(0, &dst->party[3], sizeof(dst->party[3])); + CalcEmeraldBattleTowerChecksum(dst); + return TRUE; } } -- cgit v1.2.3 From 549b669f2aa397c9d784de2ff9b91459ab26c060 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 24 Oct 2018 23:14:45 +0200 Subject: battle tower, match sth and dumb loop instead of goto --- src/battle_tower.c | 431 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 385 insertions(+), 46 deletions(-) (limited to 'src/battle_tower.c') diff --git a/src/battle_tower.c b/src/battle_tower.c index 25a46d073..cefb02c8d 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -26,12 +26,13 @@ #include "constants/trainers.h" #include "constants/event_objects.h" #include "constants/moves.h" +#include "constants/species.h" extern void sub_81A3ACC(void); extern void CreateFrontierBrainPokemon(void); extern void sub_81A6CD0(void); extern u8 GetFrontierEnemyMonLevel(u8); -extern u8 GetFacilityEnemyMonLevel(void); +extern u8 SetFacilityPtrsGetLevel(void); extern u16 sub_81A39C4(void); extern void SetFrontierBrainTrainerGfxId(void); extern u8 GetFrontierBrainTrainerPicIndex(void); @@ -50,19 +51,19 @@ extern const u16 gBattleFrontierHeldItems[]; // This file's functions. void ValidateBattleTowerRecordChecksums(void); void SaveCurrentWinStreak(void); -void sub_8165B20(void); +void ValidateApprenticesChecksums(void); void sub_8165E18(void); void CopyEReaderTrainerFarewellMessage(void); void ClearBattleTowerRecord(struct EmeraldBattleTowerRecord *record); u16 GetCurrentBattleTowerWinStreak(u8 lvlMode, u8 battleMode); u16 sub_8162548(u8, u8); static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount); -void sub_8165EA4(u16 trainerId, u8 firstMonId, u8 monCount); +void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount); void sub_81635D4(u16 trainerId, u8 firstMonId); void sub_816379C(u16 trainerId, u8 firstMonId); u8 GetFrontierTrainerFixedIvs(u16 trainerId); -void sub_8165404(u16 trainerId); -void sub_8165B88(u8 *dst, u16 trainerId); +void FillPartnerParty(u16 trainerId); +void GetBattleTowerTrainerLanguage(u8 *dst, u16 trainerId); void SetEReaderTrainerChecksum(struct BattleTowerEReaderTrainer *ereaderTrainer); void ClearEReaderTrainer(struct BattleTowerEReaderTrainer *ereaderTrainer); @@ -192,7 +193,7 @@ bool8 ChooseSpecialBattleTowerTrainer(void) if (battleMode == FRONTIER_MODE_SINGLES) { - sub_8165B20(); + ValidateApprenticesChecksums(); for (i = 0; i < 4; i++) { if (gSaveBlock2Ptr->apprentices[i].lvlMode != 0 @@ -228,7 +229,7 @@ void ChooseNextBattleTowerTrainer(void) u16 id; u32 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); u32 r5 = sub_81A39C4() / 7; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (battleMode == FRONTIER_MODE_MULTIS || battleMode == FRONTIER_MODE_LINK_MULTIS) { @@ -384,7 +385,7 @@ void SetBattleFacilityTrainerGfxId(u16 trainerId, u8 tempVarId) u8 facilityClass; u8 trainerObjectGfxId; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; @@ -481,7 +482,7 @@ u8 GetBattleFacilityTrainerGfxId(u16 trainerId) u8 facilityClass; u8 trainerObjectGfxId; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; @@ -618,7 +619,7 @@ void PutNewBattleTowerRecord(struct EmeraldBattleTowerRecord *newRecordEm) u8 GetFrontierTrainerFrontSpriteId(u16 trainerId) { - GetFacilityEnemyMonLevel(); // Pointless function call + SetFacilityPtrsGetLevel(); // Pointless function call if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { @@ -651,7 +652,7 @@ u8 GetFrontierTrainerFrontSpriteId(u16 trainerId) u8 GetFrontierOpponentClass(u16 trainerId) { u8 trainerClass = 0; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { @@ -700,7 +701,7 @@ u8 GetFrontierOpponentClass(u16 trainerId) u8 GetFrontierTrainerFacilityClass(u16 trainerId) { u8 facilityClass; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { @@ -731,7 +732,7 @@ u8 GetFrontierTrainerFacilityClass(u16 trainerId) void GetFrontierTrainerName(u8 *dst, u16 trainerId) { s32 i = 0; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { @@ -794,7 +795,7 @@ bool8 IsFrontierTrainerFemale(u16 trainerId) u32 i; u8 facilityClass; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; @@ -841,10 +842,10 @@ void FillFrontierTrainersParties(u8 monsCount) FillTrainerParty(gTrainerBattleOpponent_B, 3, monsCount); } -void sub_81630A0(u8 monsCount) +void FillTentTrainerParty(u8 monsCount) { ZeroEnemyPartyMons(); - sub_8165EA4(gTrainerBattleOpponent_A, 0, monsCount); + FillTentTrainerParty_(gTrainerBattleOpponent_A, 0, monsCount); } static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) @@ -852,7 +853,7 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) s32 i, j; u16 chosenMonIndices[4]; u8 friendship = 0xFF; - u8 level = GetFacilityEnemyMonLevel(); + u8 level = SetFacilityPtrsGetLevel(); u8 fixedIV = 0; u8 bfMonCount; const u16 *bfMonPool = NULL; @@ -1003,27 +1004,15 @@ void Unused_CreateApprenticeMons(u16 trainerId, u8 firstMonId) u16 RandomizeFacilityTrainerMonId(u16 trainerId) { - u32 monPoolId; - u8 level = GetFacilityEnemyMonLevel(); + u8 level = SetFacilityPtrsGetLevel(); const u16 *bfMonPool = gFacilityTrainers[trainerId].bfMonPool; u8 bfMonCount = 0; + u32 monPoolId = bfMonPool[bfMonCount]; - /* - I had to use ugly C tricks to get this part to match. - A cleaner version would look like this - - for (bfMonCount = 0; bfMonPool[bfMonCount] != 0xFFFF; bfMonCount++) - ; - - */ - - monPoolId = bfMonPool[bfMonCount]; - goto COMPARE; - while (1) + while (monPoolId != 0xFFFF) { bfMonCount++; monPoolId = bfMonPool[bfMonCount]; - COMPARE: if (monPoolId == 0xFFFF) break; } @@ -1082,7 +1071,7 @@ void sub_81635D4(u16 trainerId, u8 firstMonId) } - level = GetFacilityEnemyMonLevel(); + level = SetFacilityPtrsGetLevel(); otID = T1_READ_32(gSaveBlock2Ptr->playerTrainerId); for (i = 0; i < 3; i++) { @@ -1156,7 +1145,7 @@ void FrontierSpeechToString(const u16 *words) void sub_8163914(void) { u16 trainerId; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (gSpecialVar_0x8005) trainerId = gTrainerBattleOpponent_B; @@ -1248,7 +1237,7 @@ void DoSpecialTrainerBattle(void) case FRONTIER_MODE_MULTIS: FillFrontierTrainersParties(2); gPartnerTrainerId = gSaveBlock2Ptr->frontier.field_CB4[17]; - sub_8165404(gPartnerTrainerId); + FillPartnerParty(gPartnerTrainerId); gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS; break; case FRONTIER_MODE_LINK_MULTIS: @@ -1297,7 +1286,7 @@ void DoSpecialTrainerBattle(void) if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT) FillFrontierTrainerParty(3); else - sub_81630A0(3); + FillTentTrainerParty(3); CreateTask(Task_StartBattleAfterTransition, 1); PlayMapChosenOrBattleBGM(0); BattleTransition_StartOnField(sub_80B100C(4)); @@ -1307,7 +1296,7 @@ void DoSpecialTrainerBattle(void) if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT) FillFrontierTrainerParty(3); else - sub_81630A0(3); + FillTentTrainerParty(3); CreateTask(Task_StartBattleAfterTransition, 1); PlayMapChosenOrBattleBGM(0); BattleTransition_StartOnField(sub_80B100C(5)); @@ -1344,7 +1333,7 @@ void DoSpecialTrainerBattle(void) break; case SPECIAL_BATTLE_STEVEN: gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER; - sub_8165404(TRAINER_STEVEN_PARTNER); + FillPartnerParty(TRAINER_STEVEN_PARTNER); gApproachingTrainerId = 0; BattleSetup_ConfigureTrainerBattle(MossdeepCity_SpaceCenter_2F_EventScript_224157 + 1); gApproachingTrainerId = 1; @@ -1511,7 +1500,7 @@ void sub_81642A0(void) challengeNum = gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] / 7; species1 = GetMonData(&gPlayerParty[0], MON_DATA_SPECIES, NULL); species2 = GetMonData(&gPlayerParty[1], MON_DATA_SPECIES, NULL); - level = GetFacilityEnemyMonLevel(); + level = SetFacilityPtrsGetLevel(); j = 0; do @@ -1563,7 +1552,7 @@ void sub_81642A0(void) } r10 = 0; - sub_8165B20(); + ValidateApprenticesChecksums(); for (i = 0; i < 4; i++) { if (gSaveBlock2Ptr->apprentices[i].lvlMode != 0 @@ -1642,7 +1631,7 @@ void sub_81646BC(u16 trainerId, u16 monPoolId) { u16 move = 0; u16 species = 0; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId != BATTLE_TOWER_EREADER_TRAINER_ID) { @@ -1686,7 +1675,7 @@ void sub_8164828(void) { s32 i, j, arrId; s32 monPoolId; - s32 level = GetFacilityEnemyMonLevel(); // Unused variable. + s32 level = SetFacilityPtrsGetLevel(); s32 challengeNum = sub_81A39C4() / 7; s32 k = gSpecialVar_LastTalked - 2; s32 trainerId = gSaveBlock2Ptr->frontier.field_CB4[k]; @@ -1899,7 +1888,7 @@ void sub_8164E04(void) GetFrontierTrainerName(text, gTrainerBattleOpponent_A); StripExtCtrlCodes(text); StringCopy(gSaveBlock2Ptr->frontier.field_BD8, text); - sub_8165B88(&gSaveBlock2Ptr->frontier.field_BEB, gTrainerBattleOpponent_A); + GetBattleTowerTrainerLanguage(&gSaveBlock2Ptr->frontier.field_BEB, gTrainerBattleOpponent_A); gSaveBlock2Ptr->frontier.field_BD6 = GetMonData(&gEnemyParty[gBattlerPartyIndexes[1]], MON_DATA_SPECIES, NULL); gSaveBlock2Ptr->frontier.field_BD4 = GetMonData(&gPlayerParty[gBattlerPartyIndexes[0]], MON_DATA_SPECIES, NULL); for (i = 0; i < POKEMON_NAME_LENGTH + 1; i++) @@ -2184,7 +2173,7 @@ extern const struct StevenMon sStevenMons[3]; #define STEVEN_OTID 61226 -void sub_8165404(u16 trainerId) +void FillPartnerParty(u16 trainerId) { s32 i, j; u32 ivs, level; @@ -2192,7 +2181,7 @@ void sub_8165404(u16 trainerId) u16 monPoolId; u32 otID; u8 trainerName[PLAYER_NAME_LENGTH + 1]; - GetFacilityEnemyMonLevel(); // Unused return variable. + SetFacilityPtrsGetLevel(); if (trainerId == TRAINER_STEVEN_PARTNER) { @@ -2225,7 +2214,7 @@ void sub_8165404(u16 trainerId) } else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) { - level = GetFacilityEnemyMonLevel(); + level = SetFacilityPtrsGetLevel(); ivs = GetFrontierTrainerFixedIvs(trainerId); otID = Random32(); for (i = 0; i < 2; i++) @@ -2344,3 +2333,353 @@ bool32 RubyBattleTowerRecordToEmerald(struct RSBattleTowerRecord *src, struct Em return TRUE; } } + +bool32 EmeraldBattleTowerRecordToRuby(struct EmeraldBattleTowerRecord *src, struct RSBattleTowerRecord *dst) +{ + s32 i, validMons = 0; + + for (i = 0; i < 3; i++) + { + if (src->party[i].species) + validMons++; + } + + if (validMons != 3) + { + memset(dst, 0, sizeof(*dst)); + return FALSE; + } + else + { + dst->lvlMode = src->lvlMode; + dst->winStreak = src->winStreak; + for (i = 0; i < (signed) ARRAY_COUNT(sRubyFacilityClassToEmerald); i++) + { + if (sRubyFacilityClassToEmerald[i][1] == src->facilityClass) + break; + } + if (i != ARRAY_COUNT(sRubyFacilityClassToEmerald)) + dst->facilityClass = sRubyFacilityClassToEmerald[i][0]; + else + dst->facilityClass = 0x24; // FACILITY_CLASS_YOUNGSTER in Ruby/Sapphire. + + for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++) + dst->name[i] = src->name[i]; + for (i = 0; i < 4; i++) + dst->trainerId[i] = src->trainerId[i]; + for (i = 0; i < 6; i++) + dst->greeting[i] = src->greeting[i]; + for (i = 0; i < 3; i++) + dst->party[i] = src->party[i]; + + CalcRubyBattleTowerChecksum(dst); + return TRUE; + } +} + +void CalcApprenticeChecksum(struct Apprentice *apprentice) +{ + s32 i; + + apprentice->checksum = 0; + for (i = 0; i < (sizeof(struct Apprentice) - 4) / 4; i++) + apprentice->checksum += ((u32 *)apprentice)[i]; +} + +void ClearApprentice(struct Apprentice *apprentice) +{ + s32 i; + + for (i = 0; i < (sizeof(struct Apprentice)) / 4; i++) + ((u32 *)apprentice)[i] = 0; + ResetApprenticeStruct(apprentice); +} + +void ValidateApprenticesChecksums(void) +{ + s32 i, j; + + for (i = 0; i < 4; i++) + { + u32 *data = (u32*) &gSaveBlock2Ptr->apprentices[i]; + u32 checksum = 0; + for (j = 0; j < (sizeof(struct Apprentice) - 4) / 4; j++) + checksum += data[j]; + if (gSaveBlock2Ptr->apprentices[i].checksum != checksum) + ClearApprentice(&gSaveBlock2Ptr->apprentices[i]); + } +} + +void GetBattleTowerTrainerLanguage(u8 *dst, u16 trainerId) +{ + if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + { + *dst = gGameLanguage; + } + else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + *dst = gGameLanguage; + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + *dst = sub_81864B4(); + else + *dst = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].language; + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + *dst = sub_81864C0(); + else + *dst = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].language; + } +} + +extern const struct FacilityMon gBattleFrontierMons[]; +extern const struct FacilityMon gSlateportBattleTentMons[]; +extern const struct FacilityMon gVerdanturfBattleTentMons[]; +extern const struct FacilityMon gFallarborBattleTentMons[]; + +extern const struct BattleFrontierTrainer gBattleFrontierTrainers[]; +extern const struct BattleFrontierTrainer gSlateportBattleTentTrainers[]; +extern const struct BattleFrontierTrainer gVerdanturfBattleTentTrainers[]; +extern const struct BattleFrontierTrainer gFallarborBattleTentTrainers[]; + +u8 SetTentPtrsGetLevel(void); +s32 GetHighestLevelInPlayerParty(void); + +u8 SetFacilityPtrsGetLevel(void) +{ + if (gSaveBlock2Ptr->frontier.lvlMode == FRONTIER_LVL_TENT) + { + return SetTentPtrsGetLevel(); + } + else + { + gFacilityTrainers = gBattleFrontierTrainers; + gFacilityTrainerMons = gBattleFrontierMons; + return GetFrontierEnemyMonLevel(gSaveBlock2Ptr->frontier.lvlMode); + } +} + +u8 GetFrontierEnemyMonLevel(u8 lvlMode) +{ + u8 level; + + switch (lvlMode) + { + default: + case FRONTIER_LVL_50: + level = 50; + break; + case FRONTIER_LVL_OPEN: + level = GetHighestLevelInPlayerParty(); + if (level < 60) + level = 60; + break; + } + + return level; +} + +s32 GetHighestLevelInPlayerParty(void) +{ + s32 highestLevel = 0; + s32 i; + + for (i = 0; i < PARTY_SIZE; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) + && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_EGG) + { + s32 level = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL, NULL); + if (level > highestLevel) + highestLevel = level; + } + } + + return highestLevel; +} + +u8 GetFrontierTrainerFixedIvs(u16 trainerId) +{ + u8 fixedIV = 0; + + if (trainerId < 100) + fixedIV = 3; + else if (trainerId < 120) + fixedIV = 6; + else if (trainerId < 140) + fixedIV = 9; + else if (trainerId < 160) + fixedIV = 12; + else if (trainerId < 180) + fixedIV = 15; + else if (trainerId < 200) + fixedIV = 18; + else if (trainerId < 220) + fixedIV = 21; + else + fixedIV = 31; + + return fixedIV; +} + +u16 sub_8165D40(void) +{ + u32 facility = VarGet(VAR_FRONTIER_FACILITY); + + if (facility == FRONTIER_FACILITY_PALACE) + return Random() % 30; + else if (facility == FRONTIER_FACILITY_ARENA) + return Random() % 30; + else if (facility == FRONTIER_FACILITY_FACTORY) + return Random() % 30; + else if (facility == FRONTIER_FACILITY_TOWER) + return 0; + else + return 0; +} + +u8 SetTentPtrsGetLevel(void) +{ + u8 level = 30; + u32 tentFacility = VarGet(VAR_FRONTIER_FACILITY); + + if (tentFacility == TENT_SLATEPORT) + { + gFacilityTrainers = gSlateportBattleTentTrainers; + gFacilityTrainerMons = gSlateportBattleTentMons; + } + else if (tentFacility == TENT_VERDANTURF) + { + gFacilityTrainers = gVerdanturfBattleTentTrainers; + gFacilityTrainerMons = gVerdanturfBattleTentMons; + } + else if (tentFacility == TENT_FALLARBOR) + { + gFacilityTrainers = gFallarborBattleTentTrainers; + gFacilityTrainerMons = gFallarborBattleTentMons; + } + else + { + gFacilityTrainers = gBattleFrontierTrainers; + gFacilityTrainerMons = gBattleFrontierMons; + } + + level = GetHighestLevelInPlayerParty(); + if (level < 30) + level = 30; + + return level; +} + +void sub_8165E18(void) +{ + s32 i; + u16 trainerId; + + do + { + trainerId = sub_8165D40(); + for (i = 0; i < gSaveBlock2Ptr->frontier.curChallengeBattleNum; i++) + { + if (gSaveBlock2Ptr->frontier.field_CB4[i] == trainerId) + break; + } + } while (i != gSaveBlock2Ptr->frontier.curChallengeBattleNum); + + gTrainerBattleOpponent_A = trainerId; + SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_A, 0); + if (gSaveBlock2Ptr->frontier.curChallengeBattleNum + 1 < 3) + gSaveBlock2Ptr->frontier.field_CB4[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = gTrainerBattleOpponent_A; +} + +void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount) +{ + s32 i, j; + u16 chosenMonIndices[4]; + u8 friendship; + u8 level = SetTentPtrsGetLevel(); + u8 fixedIV = 0; + u8 bfMonCount; + const u16 *bfMonPool = NULL; + u32 otID = 0; + u16 monPoolId; + + bfMonPool = gFacilityTrainers[gTrainerBattleOpponent_A].bfMonPool; + + bfMonCount = 0; + monPoolId = bfMonPool[bfMonCount]; + while (monPoolId != 0xFFFF) + { + bfMonCount++; + monPoolId = bfMonPool[bfMonCount]; + if (monPoolId == 0xFFFF) + break; + } + + i = 0; + otID = Random32(); + while (i != monCount) + { + u16 monPoolId = bfMonPool[Random() % bfMonCount]; + + // Ensure this pokemon species isn't a duplicate. + for (j = 0; j < i + firstMonId; j++) + { + if (GetMonData(&gEnemyParty[j], MON_DATA_SPECIES, NULL) == gFacilityTrainerMons[monPoolId].species) + break; + } + if (j != i + firstMonId) + continue; + + // Ensure this Pokemon's held item isn't a duplicate. + for (j = 0; j < i + firstMonId; j++) + { + if (GetMonData(&gEnemyParty[j], MON_DATA_HELD_ITEM, NULL) != 0 + && GetMonData(&gEnemyParty[j], MON_DATA_HELD_ITEM, NULL) == gBattleFrontierHeldItems[gFacilityTrainerMons[monPoolId].itemTableId]) + break; + } + if (j != i + firstMonId) + continue; + + // Ensure this exact pokemon index isn't a duplicate. This check doesn't seem necessary + // because the species and held items were already checked directly above. + for (j = 0; j < i; j++) + { + if (chosenMonIndices[j] == monPoolId) + break; + } + if (j != i) + continue; + + chosenMonIndices[i] = monPoolId; + + // Place the chosen pokemon into the trainer's party. + CreateMonWithEVSpreadPersonalityOTID(&gEnemyParty[i + firstMonId], + gFacilityTrainerMons[monPoolId].species, + level, + gFacilityTrainerMons[monPoolId].nature, + fixedIV, + gFacilityTrainerMons[monPoolId].evSpread, + otID); + + friendship = 255; + // Give the chosen pokemon its specified moves. + for (j = 0; j < 4; j++) + { + SetMonMoveSlot(&gEnemyParty[i + firstMonId], gFacilityTrainerMons[monPoolId].moves[j], j); + if (gFacilityTrainerMons[monPoolId].moves[j] == MOVE_FRUSTRATION) + friendship = 0; // Frustration is more powerful the lower the pokemon's friendship is. + } + + SetMonData(&gEnemyParty[i + firstMonId], MON_DATA_FRIENDSHIP, &friendship); + SetMonData(&gEnemyParty[i + firstMonId], MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[monPoolId].itemTableId]); + + // The pokemon was successfully added to the trainer's party, so it's safe to move on to + // the next party slot. + i++; + } +} -- cgit v1.2.3 From 1efdaebe2395c8c202b2086d485b7f348dc42783 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 25 Oct 2018 21:27:10 +0200 Subject: finish decompiling battle tower --- src/battle_tower.c | 380 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 274 insertions(+), 106 deletions(-) (limited to 'src/battle_tower.c') diff --git a/src/battle_tower.c b/src/battle_tower.c index cefb02c8d..b03429554 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -28,11 +28,11 @@ #include "constants/moves.h" #include "constants/species.h" +extern u16 gUnknown_03006298[]; + extern void sub_81A3ACC(void); extern void CreateFrontierBrainPokemon(void); extern void sub_81A6CD0(void); -extern u8 GetFrontierEnemyMonLevel(u8); -extern u8 SetFacilityPtrsGetLevel(void); extern u16 sub_81A39C4(void); extern void SetFrontierBrainTrainerGfxId(void); extern u8 GetFrontierBrainTrainerPicIndex(void); @@ -41,31 +41,153 @@ extern u8 IsFrontierBrainFemale(void); extern void CopyFrontierBrainTrainerName(u8 *dst); extern void SetMonMoveAvoidReturn(struct Pokemon *mon, u16 move, u8 moveSlot); -extern const u32 gUnknown_085DF9AC[][2]; -extern const u32 gUnknown_085DF9CC[][2]; -extern void (* const gUnknown_085DF96C[])(void); -extern const u8 gUnknown_085DF9F6[]; -extern const u8 gUnknown_085DF9EC[]; +extern const u8 *const *const gUnknown_085DD690[]; extern const u16 gBattleFrontierHeldItems[]; +extern const u8 sRubyFacilityClassToEmerald[82][2]; +extern const u16 gUnknown_085DFA46[]; +extern const struct FacilityMon gBattleFrontierMons[]; +extern const struct FacilityMon gSlateportBattleTentMons[]; +extern const struct FacilityMon gVerdanturfBattleTentMons[]; +extern const struct FacilityMon gFallarborBattleTentMons[]; +extern const struct BattleFrontierTrainer gBattleFrontierTrainers[]; +extern const struct BattleFrontierTrainer gSlateportBattleTentTrainers[]; +extern const struct BattleFrontierTrainer gVerdanturfBattleTentTrainers[]; +extern const struct BattleFrontierTrainer gFallarborBattleTentTrainers[]; + +struct +{ + u32 facilityClass; + const u8 *const *strings; +} extern const gUnknown_085DD500[50]; + +extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_224157[]; +extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_224166[]; // This file's functions. -void ValidateBattleTowerRecordChecksums(void); -void SaveCurrentWinStreak(void); -void ValidateApprenticesChecksums(void); -void sub_8165E18(void); -void CopyEReaderTrainerFarewellMessage(void); -void ClearBattleTowerRecord(struct EmeraldBattleTowerRecord *record); -u16 GetCurrentBattleTowerWinStreak(u8 lvlMode, u8 battleMode); -u16 sub_8162548(u8, u8); +static void sub_8161F94(void); +static void sub_8162054(void); +static void sub_81620F4(void); +static void ChooseNextBattleTowerTrainer(void); +static void sub_81621C0(void); +static void AwardBattleTowerRibbons(void); +static void SaveBattleTowerProgress(void); +static void sub_8163914(void); +static void nullsub_61(void); +static void nullsub_116(void); +static void sub_81642A0(void); +static void sub_8164828(void); +static void sub_8164B74(void); +static void sub_8164DCC(void); +static void sub_8164DE4(void); +static void sub_8164E04(void); +static void ValidateBattleTowerRecordChecksums(void); +static void SaveCurrentWinStreak(void); +static void ValidateApprenticesChecksums(void); +static void sub_8165E18(void); +static void CopyEReaderTrainerFarewellMessage(void); +static void ClearBattleTowerRecord(struct EmeraldBattleTowerRecord *record); static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount); -void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount); -void sub_81635D4(u16 trainerId, u8 firstMonId); -void sub_816379C(u16 trainerId, u8 firstMonId); -u8 GetFrontierTrainerFixedIvs(u16 trainerId); -void FillPartnerParty(u16 trainerId); -void GetBattleTowerTrainerLanguage(u8 *dst, u16 trainerId); -void SetEReaderTrainerChecksum(struct BattleTowerEReaderTrainer *ereaderTrainer); -void ClearEReaderTrainer(struct BattleTowerEReaderTrainer *ereaderTrainer); +static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount); +static void sub_81635D4(u16 trainerId, u8 firstMonId); +static void sub_816379C(u16 trainerId, u8 firstMonId); +static u8 GetFrontierTrainerFixedIvs(u16 trainerId); +static void FillPartnerParty(u16 trainerId); +static void SetEReaderTrainerChecksum(struct BattleTowerEReaderTrainer *ereaderTrainer); +static u8 SetTentPtrsGetLevel(void); + +// Const rom data. +static void (* const gUnknown_085DF96C[])(void) = +{ + sub_8161F94, + sub_8162054, + sub_81620F4, + ChooseNextBattleTowerTrainer, + sub_81621C0, + AwardBattleTowerRibbons, + SaveBattleTowerProgress, + sub_8163914, + nullsub_61, + nullsub_116, + sub_81642A0, + sub_8164828, + sub_8164B74, + sub_8164DCC, + sub_8164DE4, + sub_8164E04, +}; + +static const u32 gUnknown_085DF9AC[][2] = +{ + {0x00000001, 0x00000002}, + {0x00004000, 0x00008000}, + {0x00010000, 0x00020000}, + {0x00040000, 0x00080000}, +}; + +static const u32 gUnknown_085DF9CC[][2] = +{ + {0xfffffffe, 0xfffffffd}, + {0xffffbfff, 0xffff7fff}, + {0xfffeffff, 0xfffdffff}, + {0xfffbffff, 0xfff7ffff}, +}; + +static const u8 gUnknown_085DF9EC[] = +{ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0a, 0x0b, 0x0c +}; + +static const u8 gUnknown_085DF9F6[] = +{ + [FRONTIER_MODE_SINGLES] = 3, + [FRONTIER_MODE_DOUBLES] = 4, + [FRONTIER_MODE_MULTIS] = 2, + [FRONTIER_MODE_LINK_MULTIS] = 2, +}; + +static const u16 gUnknown_085DF9FA[][2] = +{ + {0x0000, 0x0063}, + {0x0050, 0x0077}, + {0x0064, 0x008b}, + {0x0078, 0x009f}, + {0x008c, 0x00b3}, + {0x00a0, 0x00c7}, + {0x00b4, 0x00db}, + {0x00c8, 0x012b}, +}; + +static const u16 gUnknown_085DFA1A[][2] = +{ + {0x0064, 0x0077}, + {0x0078, 0x008b}, + {0x008c, 0x009f}, + {0x00a0, 0x00b3}, + {0x00b4, 0x00c7}, + {0x00c8, 0x00db}, + {0x00dc, 0x00ef}, + {0x00c8, 0x012b}, + {0x00b3, 0x008d}, + {0x00c8, 0x00b7}, +}; + +static const u8 gUnknown_085DFA42[4] = +{ + [FRONTIER_MODE_SINGLES] = 3, + [FRONTIER_MODE_DOUBLES] = 4, + [FRONTIER_MODE_MULTIS] = 2, + [FRONTIER_MODE_LINK_MULTIS] = 2, +}; + +static const u16 gUnknown_085DFA46[] = +{ + 0x0c3a, 0x0c3a, 0x0c01, 0x0a2a, 0x0607, 0x0c01 +}; + +static const u16 gUnknown_085DFA52[] = +{ + 0x1039, 0x122e, 0x0c04, 0x0a3d, 0x0630, 0x0c04 +}; // code void sub_8161F74(void) @@ -73,7 +195,7 @@ void sub_8161F74(void) gUnknown_085DF96C[gSpecialVar_0x8004](); } -void sub_8161F94(void) +static void sub_8161F94(void) { u32 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; u32 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); @@ -91,7 +213,7 @@ void sub_8161F94(void) gTrainerBattleOpponent_A = 0; } -void sub_8162054(void) +static void sub_8162054(void) { u32 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; u32 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); @@ -112,7 +234,7 @@ void sub_8162054(void) } } -void sub_81620F4(void) +static void sub_81620F4(void) { u32 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; u32 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); @@ -136,7 +258,7 @@ void sub_81620F4(void) } } -void sub_81621C0(void) +static void sub_81621C0(void) { if (gTrainerBattleOpponent_A == BATTLE_TOWER_EREADER_TRAINER_ID) ClearEReaderTrainer(&gSaveBlock2Ptr->frontier.ereaderTrainer); @@ -149,7 +271,7 @@ void sub_81621C0(void) gSpecialVar_Result = gSaveBlock2Ptr->frontier.curChallengeBattleNum; } -bool8 ChooseSpecialBattleTowerTrainer(void) +static bool8 ChooseSpecialBattleTowerTrainer(void) { s32 i, j, validMons; s32 trainerIds[9]; @@ -217,7 +339,7 @@ bool8 ChooseSpecialBattleTowerTrainer(void) } } -void ChooseNextBattleTowerTrainer(void) +static void ChooseNextBattleTowerTrainer(void) { u32 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; if (lvlMode == FRONTIER_LVL_TENT) @@ -269,9 +391,6 @@ void ChooseNextBattleTowerTrainer(void) } } -extern const u16 gUnknown_085DFA1A[][2]; -extern const u16 gUnknown_085DF9FA[][2]; - u16 sub_8162548(u8 challengeNum, u8 battleNum) { u16 trainerId; @@ -299,7 +418,7 @@ u16 sub_8162548(u8 challengeNum, u8 battleNum) } #ifdef NONMATCHING -u16 sub_81625B4(u8 challengeNum, u8 battleNum, u16 *trainerIdPtr, u8 *arg3) // Unused +static u16 sub_81625B4(u8 challengeNum, u8 battleNum, u16 *trainerIdPtr, u8 *arg3) // Unused { register u16 trainerId, count; @@ -327,7 +446,7 @@ u16 sub_81625B4(u8 challengeNum, u8 battleNum, u16 *trainerIdPtr, u8 *arg3) // U } #else NAKED -u16 sub_81625B4(u8 challengeNum, u8 battleNum, u16 *trainerIdPtr, u8 *arg3) +static u16 sub_81625B4(u8 challengeNum, u8 battleNum, u16 *trainerIdPtr, u8 *arg3) { asm_unified(" push {r4,lr}\n\ adds r4, r2, 0\n\ @@ -619,7 +738,7 @@ void PutNewBattleTowerRecord(struct EmeraldBattleTowerRecord *newRecordEm) u8 GetFrontierTrainerFrontSpriteId(u16 trainerId) { - SetFacilityPtrsGetLevel(); // Pointless function call + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { @@ -698,7 +817,7 @@ u8 GetFrontierOpponentClass(u16 trainerId) return trainerClass; } -u8 GetFrontierTrainerFacilityClass(u16 trainerId) +static u8 GetFrontierTrainerFacilityClass(u16 trainerId) { u8 facilityClass; SetFacilityPtrsGetLevel(); @@ -790,7 +909,7 @@ void GetFrontierTrainerName(u8 *dst, u16 trainerId) dst[i] = EOS; } -bool8 IsFrontierTrainerFemale(u16 trainerId) +static bool8 IsFrontierTrainerFemale(u16 trainerId) { u32 i; u8 facilityClass; @@ -842,7 +961,7 @@ void FillFrontierTrainersParties(u8 monsCount) FillTrainerParty(gTrainerBattleOpponent_B, 3, monsCount); } -void FillTentTrainerParty(u8 monsCount) +static void FillTentTrainerParty(u8 monsCount) { ZeroEnemyPartyMons(); FillTentTrainerParty_(gTrainerBattleOpponent_A, 0, monsCount); @@ -970,7 +1089,7 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) } // Probably an early draft before the 'CreateApprenticeMon' was written. -void Unused_CreateApprenticeMons(u16 trainerId, u8 firstMonId) +static void Unused_CreateApprenticeMons(u16 trainerId, u8 firstMonId) { s32 i, j; u8 friendship = 0xFF; @@ -1025,7 +1144,7 @@ u16 RandomizeFacilityTrainerMonId(u16 trainerId) return monPoolId; } -void sub_8163590(void) +static void sub_8163590(void) { ZeroEnemyPartyMons(); if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT) @@ -1034,9 +1153,7 @@ void sub_8163590(void) sub_816379C(gTrainerBattleOpponent_A, 0); } -extern u16 gUnknown_03006298[]; - -void sub_81635D4(u16 trainerId, u8 firstMonId) +static void sub_81635D4(u16 trainerId, u8 firstMonId) { u8 i, j; u8 friendship; @@ -1093,7 +1210,7 @@ void sub_81635D4(u16 trainerId, u8 firstMonId) } } -void sub_816379C(u16 trainerId, u8 firstMonId) +static void sub_816379C(u16 trainerId, u8 firstMonId) { u8 i, j; u8 friendship; @@ -1142,7 +1259,7 @@ void FrontierSpeechToString(const u16 *words) } } -void sub_8163914(void) +static void sub_8163914(void) { u16 trainerId; SetFacilityPtrsGetLevel(); @@ -1213,9 +1330,6 @@ static void Task_StartBattleAfterTransition(u8 taskId) } } -extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_224157[]; -extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_224166[]; - void DoSpecialTrainerBattle(void) { s32 i; @@ -1346,7 +1460,7 @@ void DoSpecialTrainerBattle(void) } } -void SaveCurrentWinStreak(void) +static void SaveCurrentWinStreak(void) { u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); @@ -1356,7 +1470,7 @@ void SaveCurrentWinStreak(void) gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] = winStreak; } -void sub_8163EE4(void) +static void sub_8163EE4(void) { s32 i; u8 lvlMode, battleMode, class; @@ -1403,7 +1517,7 @@ void sub_8163EE4(void) SaveCurrentWinStreak(); } -void SaveBattleTowerProgress(void) +static void SaveBattleTowerProgress(void) { u16 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; u16 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); @@ -1418,17 +1532,17 @@ void SaveBattleTowerProgress(void) sub_81A4C30(); } -void nullsub_61(void) +static void nullsub_61(void) { } -void nullsub_116(void) +static void nullsub_116(void) { } -void sub_81640E0(u16 trainerId) +static void sub_81640E0(u16 trainerId) { s32 i, count; u32 validSpecies[3]; @@ -1453,7 +1567,7 @@ void sub_81640E0(u16 trainerId) } while (gUnknown_03006298[0] == gUnknown_03006298[1]); } -void sub_8164188(u16 trainerId) +static void sub_8164188(u16 trainerId) { s32 i, count; u32 validSpecies[3]; @@ -1481,7 +1595,7 @@ void sub_8164188(u16 trainerId) } while (gUnknown_03006298[2] == gUnknown_03006298[3]); } -void sub_81642A0(void) +static void sub_81642A0(void) { s32 i, j, k; u32 spArray[5]; @@ -1627,7 +1741,7 @@ void sub_81642A0(void) } } -void sub_81646BC(u16 trainerId, u16 monPoolId) +static void sub_81646BC(u16 trainerId, u16 monPoolId) { u16 move = 0; u16 species = 0; @@ -1662,16 +1776,7 @@ void sub_81646BC(u16 trainerId, u16 monPoolId) StringCopy(gStringVar2, gSpeciesNames[species]); } -struct -{ - u32 facilityClass; - const u8 *const *strings; -} extern const gUnknown_085DD500[50]; - -extern const u8 *const *const gUnknown_085DD690[]; -extern const u8 gUnknown_085DFA42[4]; - -void sub_8164828(void) +static void sub_8164828(void) { s32 i, j, arrId; s32 monPoolId; @@ -1777,7 +1882,7 @@ void sub_8164828(void) } } -void sub_8164B74(void) +static void sub_8164B74(void) { s32 challengeNum; s32 i, j; @@ -1866,18 +1971,18 @@ void sub_8164B74(void) } } -void sub_8164DCC(void) +static void sub_8164DCC(void) { if (gWirelessCommType != 0) sub_800AC34(); } -void sub_8164DE4(void) +static void sub_8164DE4(void) { SetBattleFacilityTrainerGfxId(gSaveBlock2Ptr->frontier.field_CB4[17], 0xF); } -void sub_8164E04(void) +static void sub_8164E04(void) { s32 i; u8 text[32]; @@ -1896,7 +2001,7 @@ void sub_8164E04(void) gSaveBlock2Ptr->frontier.field_D06 = gBattleOutcome; } -void ValidateBattleTowerRecordChecksums(void) +static void ValidateBattleTowerRecordChecksums(void) { s32 i, j; u32 *record = (u32*)(&gSaveBlock2Ptr->frontier.towerPlayer); @@ -1940,7 +2045,7 @@ void CalcRubyBattleTowerChecksum(struct RSBattleTowerRecord *record) record->checksum += ((u32 *)record)[i]; } -void ClearBattleTowerRecord(struct EmeraldBattleTowerRecord *record) +static void ClearBattleTowerRecord(struct EmeraldBattleTowerRecord *record) { u32 i; @@ -1958,7 +2063,7 @@ u16 GetCurrentBattleTowerWinStreak(u8 lvlMode, u8 battleMode) return winStreak; } -u8 GetMonCountForBattleMode(u8 battleMode) +static u8 GetMonCountForBattleMode(u8 battleMode) { u8 sp[ARRAY_COUNT(gUnknown_085DFA42)]; memcpy(sp, gUnknown_085DFA42, sizeof(gUnknown_085DFA42)); @@ -1975,7 +2080,7 @@ struct RibbonCounter u8 count; }; -void AwardBattleTowerRibbons(void) +static void AwardBattleTowerRibbons(void) { s32 i; u32 partyIndex; @@ -2029,7 +2134,7 @@ void AwardBattleTowerRibbons(void) // This is a leftover debugging function that is used to populate the E-Reader // trainer with the player's current data. -void FillEReaderTrainerWithPlayerData(void) +static void FillEReaderTrainerWithPlayerData(void) { struct BattleTowerEReaderTrainer *ereaderTrainer = &gSaveBlock2Ptr->frontier.ereaderTrainer; s32 i, j; @@ -2075,14 +2180,14 @@ u8 GetEreaderTrainerClassId(void) return gFacilityClassToTrainerClass[gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass]; } -void GetEreaderTrainerName(u8 *trainerName) +void GetEreaderTrainerName(u8 *dst) { s32 i; for (i = 0; i < 5; i++) - trainerName[i] = gSaveBlock2Ptr->frontier.ereaderTrainer.name[i]; + dst[i] = gSaveBlock2Ptr->frontier.ereaderTrainer.name[i]; - trainerName[i] = EOS; + dst[i] = EOS; } // Checks if the saved E-Reader trainer is valid. @@ -2116,7 +2221,7 @@ void ValidateEReaderTrainer(void) } } -void SetEReaderTrainerChecksum(struct BattleTowerEReaderTrainer *ereaderTrainer) +static void SetEReaderTrainerChecksum(struct BattleTowerEReaderTrainer *ereaderTrainer) { s32 i; @@ -2138,7 +2243,7 @@ void CopyEReaderTrainerGreeting(void) FrontierSpeechToString(gSaveBlock2Ptr->frontier.ereaderTrainer.greeting); } -void CopyEReaderTrainerFarewellMessage(void) +static void CopyEReaderTrainerFarewellMessage(void) { if (gBattleOutcome == B_OUTCOME_DREW) gStringVar4[0] = EOS; @@ -2173,7 +2278,7 @@ extern const struct StevenMon sStevenMons[3]; #define STEVEN_OTID 61226 -void FillPartnerParty(u16 trainerId) +static void FillPartnerParty(u16 trainerId) { s32 i, j; u32 ivs, level; @@ -2282,10 +2387,6 @@ void FillPartnerParty(u16 trainerId) } } -extern const u8 sRubyFacilityClassToEmerald[82][2]; -extern const u16 gUnknown_085DFA46[]; -extern const u16 gUnknown_085DFA52[]; - bool32 RubyBattleTowerRecordToEmerald(struct RSBattleTowerRecord *src, struct EmeraldBattleTowerRecord *dst) { s32 i, validMons = 0; @@ -2386,7 +2487,7 @@ void CalcApprenticeChecksum(struct Apprentice *apprentice) apprentice->checksum += ((u32 *)apprentice)[i]; } -void ClearApprentice(struct Apprentice *apprentice) +static void ClearApprentice(struct Apprentice *apprentice) { s32 i; @@ -2395,7 +2496,7 @@ void ClearApprentice(struct Apprentice *apprentice) ResetApprenticeStruct(apprentice); } -void ValidateApprenticesChecksums(void) +static void ValidateApprenticesChecksums(void) { s32 i, j; @@ -2436,19 +2537,6 @@ void GetBattleTowerTrainerLanguage(u8 *dst, u16 trainerId) } } -extern const struct FacilityMon gBattleFrontierMons[]; -extern const struct FacilityMon gSlateportBattleTentMons[]; -extern const struct FacilityMon gVerdanturfBattleTentMons[]; -extern const struct FacilityMon gFallarborBattleTentMons[]; - -extern const struct BattleFrontierTrainer gBattleFrontierTrainers[]; -extern const struct BattleFrontierTrainer gSlateportBattleTentTrainers[]; -extern const struct BattleFrontierTrainer gVerdanturfBattleTentTrainers[]; -extern const struct BattleFrontierTrainer gFallarborBattleTentTrainers[]; - -u8 SetTentPtrsGetLevel(void); -s32 GetHighestLevelInPlayerParty(void); - u8 SetFacilityPtrsGetLevel(void) { if (gSaveBlock2Ptr->frontier.lvlMode == FRONTIER_LVL_TENT) @@ -2502,7 +2590,7 @@ s32 GetHighestLevelInPlayerParty(void) return highestLevel; } -u8 GetFrontierTrainerFixedIvs(u16 trainerId) +static u8 GetFrontierTrainerFixedIvs(u16 trainerId) { u8 fixedIV = 0; @@ -2526,7 +2614,7 @@ u8 GetFrontierTrainerFixedIvs(u16 trainerId) return fixedIV; } -u16 sub_8165D40(void) +static u16 sub_8165D40(void) { u32 facility = VarGet(VAR_FRONTIER_FACILITY); @@ -2542,7 +2630,7 @@ u16 sub_8165D40(void) return 0; } -u8 SetTentPtrsGetLevel(void) +static u8 SetTentPtrsGetLevel(void) { u8 level = 30; u32 tentFacility = VarGet(VAR_FRONTIER_FACILITY); @@ -2575,7 +2663,7 @@ u8 SetTentPtrsGetLevel(void) return level; } -void sub_8165E18(void) +static void sub_8165E18(void) { s32 i; u16 trainerId; @@ -2596,7 +2684,7 @@ void sub_8165E18(void) gSaveBlock2Ptr->frontier.field_CB4[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = gTrainerBattleOpponent_A; } -void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount) +static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount) { s32 i, j; u16 chosenMonIndices[4]; @@ -2683,3 +2771,83 @@ void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount) i++; } } + +u8 sub_81660B8(u8 facilityClass) +{ + u8 trainerObjectGfxId; + u8 i; + + // Search male classes. + for (i = 0; i < ARRAY_COUNT(gTowerMaleFacilityClasses); i++) + { + if (gTowerMaleFacilityClasses[i] == facilityClass) + break; + } + if (i != ARRAY_COUNT(gTowerMaleFacilityClasses)) + { + trainerObjectGfxId = gTowerMaleTrainerGfxIds[i]; + return trainerObjectGfxId; + } + + // Search female classes. + for (i = 0; i < ARRAY_COUNT(gTowerFemaleFacilityClasses); i++) + { + if (gTowerFemaleFacilityClasses[i] == facilityClass) + break; + } + if (i != ARRAY_COUNT(gTowerFemaleFacilityClasses)) + { + trainerObjectGfxId = gTowerFemaleTrainerGfxIds[i]; + return trainerObjectGfxId; + } + else + { + return EVENT_OBJ_GFX_BOY_1; + } +} + +bool32 ValidateBattleTowerRecord(u8 recordId) // unused +{ + s32 i; + u32 *record = (u32*)(&gSaveBlock2Ptr->frontier.towerRecords[recordId]); + u32 checksum = 0; + u32 hasData = 0; + for (i = 0; i < (sizeof(struct EmeraldBattleTowerRecord) - 4) / 4; i++) // - 4, because of the last fjeld bejng the checksum jtself. + { + checksum += record[i]; + hasData |= record[i]; + } + + if (checksum == 0 && hasData == 0) + { + return FALSE; + } + else if (gSaveBlock2Ptr->frontier.towerRecords[recordId].checksum != checksum) + { + ClearBattleTowerRecord(&gSaveBlock2Ptr->frontier.towerRecords[recordId]); + return FALSE; + } + else + { + return TRUE; + } +} + +void sub_8166188(void) +{ + if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000)) + { + s32 i; + u8 enemyLevel = SetFacilityPtrsGetLevel(); + + for (i = 0; i < PARTY_SIZE; i++) + { + u32 species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES, NULL); + if (species) + { + SetMonData(&gEnemyParty[i], MON_DATA_EXP, &gExperienceTables[gBaseStats[species].growthRate][enemyLevel]); + CalculateMonStats(&gEnemyParty[i]); + } + } + } +} -- cgit v1.2.3 From dc273cc19d842e8831548a1342af857aae2886c9 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Fri, 26 Oct 2018 23:54:41 +0200 Subject: Battle tower - ewram variables --- src/battle_tower.c | 228 +++++++++++++++++++++++++++-------------------------- 1 file changed, 115 insertions(+), 113 deletions(-) (limited to 'src/battle_tower.c') diff --git a/src/battle_tower.c b/src/battle_tower.c index b03429554..4b63c2875 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -60,9 +60,23 @@ struct const u8 *const *strings; } extern const gUnknown_085DD500[50]; +struct +{ + u16 species; + u8 fixedIV; + u8 level; + u8 nature; + u8 evs[6]; + u16 moves[4]; +} extern const sStevenMons[3]; + extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_224157[]; extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_224166[]; +// EWRAM vars. +EWRAM_DATA const struct BattleFrontierTrainer *gFacilityTrainers = NULL; +EWRAM_DATA const struct FacilityMon *gFacilityTrainerMons = NULL; + // This file's functions. static void sub_8161F94(void); static void sub_8162054(void); @@ -88,8 +102,8 @@ static void CopyEReaderTrainerFarewellMessage(void); static void ClearBattleTowerRecord(struct EmeraldBattleTowerRecord *record); static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount); static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount); -static void sub_81635D4(u16 trainerId, u8 firstMonId); -static void sub_816379C(u16 trainerId, u8 firstMonId); +static void FillFactoryFrontierTrainerParty(u16 trainerId, u8 firstMonId); +static void FillFactoryTentTrainerParty(u16 trainerId, u8 firstMonId); static u8 GetFrontierTrainerFixedIvs(u16 trainerId); static void FillPartnerParty(u16 trainerId); static void SetEReaderTrainerChecksum(struct BattleTowerEReaderTrainer *ereaderTrainer); @@ -260,7 +274,7 @@ static void sub_81620F4(void) static void sub_81621C0(void) { - if (gTrainerBattleOpponent_A == BATTLE_TOWER_EREADER_TRAINER_ID) + if (gTrainerBattleOpponent_A == TRAINER_EREADER) ClearEReaderTrainer(&gSaveBlock2Ptr->frontier.ereaderTrainer); if (gSaveBlock2Ptr->frontier.field_D04 < 9999) @@ -308,7 +322,7 @@ static bool8 ChooseSpecialBattleTowerTrainer(void) && recordHasData && gSaveBlock2Ptr->frontier.towerRecords[i].checksum == checksum) { - trainerIds[idsCount] = i + BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID; + trainerIds[idsCount] = i + TRAINER_RECORD_MIXING_FRIEND; idsCount++; } } @@ -322,7 +336,7 @@ static bool8 ChooseSpecialBattleTowerTrainer(void) && gUnknown_085DF9EC[gSaveBlock2Ptr->apprentices[i].field_1] == winStreak && gSaveBlock2Ptr->apprentices[i].lvlMode - 1 == lvlMode) { - trainerIds[idsCount] = i + BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID; + trainerIds[idsCount] = i + TRAINER_RECORD_MIXING_APPRENTICE; idsCount++; } } @@ -505,7 +519,7 @@ void SetBattleFacilityTrainerGfxId(u16 trainerId, u8 tempVarId) u8 trainerObjectGfxId; SetFacilityPtrsGetLevel(); - if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + if (trainerId == TRAINER_EREADER) { facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; } @@ -514,17 +528,17 @@ void SetBattleFacilityTrainerGfxId(u16 trainerId, u8 tempVarId) SetFrontierBrainTrainerGfxId(); return; } - else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { facilityClass = gFacilityTrainers[trainerId].facilityClass; } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { - facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; + facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].facilityClass; } else { - facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id].facilityClass; + facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].id].facilityClass; } // Search male classes. @@ -592,7 +606,7 @@ void SetBattleFacilityTrainerGfxId(u16 trainerId, u8 tempVarId) void SetEReaderTrainerGfxId(void) { - SetBattleFacilityTrainerGfxId(BATTLE_TOWER_EREADER_TRAINER_ID, 0); + SetBattleFacilityTrainerGfxId(TRAINER_EREADER, 0); } u8 GetBattleFacilityTrainerGfxId(u16 trainerId) @@ -602,21 +616,21 @@ u8 GetBattleFacilityTrainerGfxId(u16 trainerId) u8 trainerObjectGfxId; SetFacilityPtrsGetLevel(); - if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + if (trainerId == TRAINER_EREADER) { facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; } - else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { facilityClass = gFacilityTrainers[trainerId].facilityClass; } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { - facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; + facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].facilityClass; } else { - facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id].facilityClass; + facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].id].facilityClass; } // Search male classes. @@ -740,7 +754,7 @@ u8 GetFrontierTrainerFrontSpriteId(u16 trainerId) { SetFacilityPtrsGetLevel(); - if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + if (trainerId == TRAINER_EREADER) { return gFacilityClassToPicIndex[gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass]; } @@ -748,23 +762,23 @@ u8 GetFrontierTrainerFrontSpriteId(u16 trainerId) { return GetFrontierBrainTrainerPicIndex(); } - else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { return gFacilityClassToPicIndex[gFacilityTrainers[trainerId].facilityClass]; } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) return gFacilityClassToPicIndex[sub_818649C()]; else - return gFacilityClassToPicIndex[gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass]; + return gFacilityClassToPicIndex[gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].facilityClass]; } else { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) return gFacilityClassToPicIndex[gApprentices[sub_81864A8()].facilityClass]; else - return gFacilityClassToPicIndex[gApprentices[gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id].facilityClass]; + return gFacilityClassToPicIndex[gApprentices[gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].id].facilityClass]; } } @@ -773,7 +787,7 @@ u8 GetFrontierOpponentClass(u16 trainerId) u8 trainerClass = 0; SetFacilityPtrsGetLevel(); - if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + if (trainerId == TRAINER_EREADER) { trainerClass = gFacilityClassToTrainerClass[gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass]; } @@ -785,11 +799,11 @@ u8 GetFrontierOpponentClass(u16 trainerId) { trainerClass = gTrainers[TRAINER_STEVEN].trainerClass; } - else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { trainerClass = gFacilityClassToTrainerClass[gFacilityTrainers[trainerId].facilityClass]; } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) { @@ -797,7 +811,7 @@ u8 GetFrontierOpponentClass(u16 trainerId) } else { - trainerClass = gFacilityClassToTrainerClass[gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass]; + trainerClass = gFacilityClassToTrainerClass[gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].facilityClass]; asm(""); } } @@ -809,7 +823,7 @@ u8 GetFrontierOpponentClass(u16 trainerId) } else { - trainerClass = gFacilityClassToTrainerClass[gApprentices[gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id].facilityClass]; + trainerClass = gFacilityClassToTrainerClass[gApprentices[gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].id].facilityClass]; asm(""); } } @@ -822,27 +836,27 @@ static u8 GetFrontierTrainerFacilityClass(u16 trainerId) u8 facilityClass; SetFacilityPtrsGetLevel(); - if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + if (trainerId == TRAINER_EREADER) { facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; } - else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { facilityClass = gFacilityTrainers[trainerId].facilityClass; } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) facilityClass = sub_818649C(); else - facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; + facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].facilityClass; } else { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) facilityClass = gApprentices[sub_81864A8()].facilityClass; else - facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id].facilityClass; + facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].id].facilityClass; } return facilityClass; @@ -853,7 +867,7 @@ void GetFrontierTrainerName(u8 *dst, u16 trainerId) s32 i = 0; SetFacilityPtrsGetLevel(); - if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + if (trainerId == TRAINER_EREADER) { for (i = 0; i < PLAYER_NAME_LENGTH; i++) dst[i] = gSaveBlock2Ptr->frontier.ereaderTrainer.name[i]; @@ -868,12 +882,12 @@ void GetFrontierTrainerName(u8 *dst, u16 trainerId) for (i = 0; i < PLAYER_NAME_LENGTH; i++) dst[i] = gTrainers[TRAINER_STEVEN].trainerName[i]; } - else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { for (i = 0; i < PLAYER_NAME_LENGTH; i++) dst[i] = gFacilityTrainers[trainerId].trainerName[i]; } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) { @@ -882,7 +896,7 @@ void GetFrontierTrainerName(u8 *dst, u16 trainerId) } else { - struct EmeraldBattleTowerRecord *record = &gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID]; + struct EmeraldBattleTowerRecord *record = &gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND]; TVShowConvertInternationalString(dst, record->name, record->language); return; } @@ -898,7 +912,7 @@ void GetFrontierTrainerName(u8 *dst, u16 trainerId) } else { - struct Apprentice *apprentice = &gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID]; + struct Apprentice *apprentice = &gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE]; id = apprentice->id; language = apprentice->language; } @@ -915,7 +929,7 @@ static bool8 IsFrontierTrainerFemale(u16 trainerId) u8 facilityClass; SetFacilityPtrsGetLevel(); - if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + if (trainerId == TRAINER_EREADER) { facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; } @@ -923,17 +937,17 @@ static bool8 IsFrontierTrainerFemale(u16 trainerId) { return IsFrontierBrainFemale(); } - else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { facilityClass = gFacilityTrainers[trainerId].facilityClass; } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { - facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].facilityClass; + facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].facilityClass; } else { - facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id].facilityClass; + facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].id].facilityClass; } // Search female classes. @@ -978,13 +992,13 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) const u16 *bfMonPool = NULL; u32 otID = 0; - if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { // Normal battle frontier trainer. fixedIV = GetFrontierTrainerFixedIvs(trainerId); bfMonPool = gFacilityTrainers[gTrainerBattleOpponent_A].bfMonPool; } - else if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + else if (trainerId == TRAINER_EREADER) { for (i = firstMonId; i < firstMonId + 3; i++) sub_806819C(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i - firstMonId]); @@ -995,15 +1009,15 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) CreateFrontierBrainPokemon(); return; } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { // Record mixed player. for (j = 0, i = firstMonId; i < firstMonId + monCount; j++, i++) { - if (gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[j].species != 0 - && gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[j].level <= level) + if (gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[j].species != 0 + && gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[j].level <= level) { - sub_8068338(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[j], FALSE); + sub_8068338(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[j], FALSE); } } return; @@ -1012,7 +1026,7 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) { // Apprentice. for (i = firstMonId; i < firstMonId + 3; i++) - CreateApprenticeMon(&gEnemyParty[i], &gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID], i - firstMonId); + CreateApprenticeMon(&gEnemyParty[i], &gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE], i - firstMonId); return; } @@ -1144,16 +1158,16 @@ u16 RandomizeFacilityTrainerMonId(u16 trainerId) return monPoolId; } -static void sub_8163590(void) +static void FillFactoryTrainerParty(void) { ZeroEnemyPartyMons(); if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT) - sub_81635D4(gTrainerBattleOpponent_A, 0); + FillFactoryFrontierTrainerParty(gTrainerBattleOpponent_A, 0); else - sub_816379C(gTrainerBattleOpponent_A, 0); + FillFactoryTentTrainerParty(gTrainerBattleOpponent_A, 0); } -static void sub_81635D4(u16 trainerId, u8 firstMonId) +static void FillFactoryFrontierTrainerParty(u16 trainerId, u8 firstMonId) { u8 i, j; u8 friendship; @@ -1161,7 +1175,7 @@ static void sub_81635D4(u16 trainerId, u8 firstMonId) u8 fixedIV; u32 otID; - if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; // Unused variable. u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); @@ -1171,7 +1185,7 @@ static void sub_81635D4(u16 trainerId, u8 firstMonId) else fixedIV = sub_81A6CA8(challengeNum, 1); } - else if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + else if (trainerId == TRAINER_EREADER) { for (i = firstMonId; i < firstMonId + 3; i++) sub_806819C(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i - firstMonId]); @@ -1210,7 +1224,7 @@ static void sub_81635D4(u16 trainerId, u8 firstMonId) } } -static void sub_816379C(u16 trainerId, u8 firstMonId) +static void FillFactoryTentTrainerParty(u16 trainerId, u8 firstMonId) { u8 i, j; u8 friendship; @@ -1269,14 +1283,14 @@ static void sub_8163914(void) else trainerId = gTrainerBattleOpponent_A; - if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + if (trainerId == TRAINER_EREADER) FrontierSpeechToString(gSaveBlock2Ptr->frontier.ereaderTrainer.greeting); - else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_FRIEND) FrontierSpeechToString(gFacilityTrainers[trainerId].speechBefore); - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) - FrontierSpeechToString(gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].greeting); + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) + FrontierSpeechToString(gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].greeting); else - CopyFriendsApprenticeChallengeText(trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID); + CopyFriendsApprenticeChallengeText(trainerId - TRAINER_RECORD_MIXING_APPRENTICE); } static void HandleSpecialTrainerBattleEnd(void) @@ -1419,7 +1433,7 @@ void DoSpecialTrainerBattle(void) gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_FACTORY; if (VarGet(VAR_FRONTIER_BATTLE_MODE) == FRONTIER_MODE_DOUBLES) gBattleTypeFlags |= BATTLE_TYPE_DOUBLE; - sub_8163590(); + FillFactoryTrainerParty(); CreateTask(Task_StartBattleAfterTransition, 1); PlayMapChosenOrBattleBGM(0); BattleTransition_StartOnField(sub_80B100C(6)); @@ -1552,7 +1566,7 @@ static void sub_81640E0(u16 trainerId) count = 0; for (i = 0; i < 3; i++) { - u16 apprenticeSpecies = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].party[i].species; + u16 apprenticeSpecies = gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].party[i].species; if (apprenticeSpecies != species1 && apprenticeSpecies != species2) { validSpecies[count] = i; @@ -1578,10 +1592,10 @@ static void sub_8164188(u16 trainerId) count = 0; for (i = 0; i < 4; i++) { - if (gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[i].species != species1 - && gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[i].species != species2 - && gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[i].level <= GetFrontierEnemyMonLevel(lvlMode) - && gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[i].species != 0) + if (gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[i].species != species1 + && gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[i].species != species2 + && gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[i].level <= GetFrontierEnemyMonLevel(lvlMode) + && gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[i].species != 0) { validSpecies[count] = i; count++; @@ -1684,7 +1698,7 @@ static void sub_81642A0(void) } if (k > 2) { - spArray[r10] = i + BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID; + spArray[r10] = i + TRAINER_RECORD_MIXING_APPRENTICE; r10++; } } @@ -1727,7 +1741,7 @@ static void sub_81642A0(void) } if (k > 1) { - spArray[r10] = i + BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID; + spArray[r10] = i + TRAINER_RECORD_MIXING_FRIEND; r10++; } } @@ -1747,28 +1761,28 @@ static void sub_81646BC(u16 trainerId, u16 monPoolId) u16 species = 0; SetFacilityPtrsGetLevel(); - if (trainerId != BATTLE_TOWER_EREADER_TRAINER_ID) + if (trainerId != TRAINER_EREADER) { - if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { move = gFacilityTrainerMons[monPoolId].moves[0]; species = gFacilityTrainerMons[monPoolId].species; } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { - move = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[gUnknown_03006298[gSpecialVar_0x8005 + 1]].moves[0]; - species = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].party[gUnknown_03006298[gSpecialVar_0x8005 + 1]].species; + move = gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[gUnknown_03006298[gSpecialVar_0x8005 + 1]].moves[0]; + species = gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[gUnknown_03006298[gSpecialVar_0x8005 + 1]].species; } else { s32 i; - move = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].party[gUnknown_03006298[gSpecialVar_0x8005 - 1]].moves[0]; - species = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].party[gUnknown_03006298[gSpecialVar_0x8005 - 1]].species; + move = gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].party[gUnknown_03006298[gSpecialVar_0x8005 - 1]].moves[0]; + species = gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].party[gUnknown_03006298[gSpecialVar_0x8005 - 1]].species; for (i = 0; i < PLAYER_NAME_LENGTH; i++) - gStringVar3[i] = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].playerName[i]; + gStringVar3[i] = gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].playerName[i]; gStringVar3[i] = EOS; - ConvertInternationalString(gStringVar3, gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].language); + ConvertInternationalString(gStringVar3, gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].language); } } @@ -1794,13 +1808,13 @@ static void sub_8164828(void) switch (gSpecialVar_0x8005) { case 0: - if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + if (trainerId == TRAINER_EREADER) return; - if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { GetFrontierTrainerName(gStringVar1, trainerId); } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { GetFrontierTrainerName(gStringVar1, trainerId); } @@ -1808,10 +1822,10 @@ static void sub_8164828(void) { s32 i; for (i = 0; i < PLAYER_NAME_LENGTH; i++) - gStringVar1[i] = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].playerName[i]; + gStringVar1[i] = gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].playerName[i]; gStringVar1[i] = EOS; - ConvertInternationalString(gStringVar1, gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].language); - ConvertIntToDecimalStringN(gStringVar2, gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].number, STR_CONV_MODE_LEFT_ALIGN, 3); + ConvertInternationalString(gStringVar1, gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].language); + ConvertIntToDecimalStringN(gStringVar2, gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].number, STR_CONV_MODE_LEFT_ALIGN, 3); GetFrontierTrainerName(gStringVar3, trainerId); } break; @@ -1825,12 +1839,12 @@ static void sub_8164828(void) break; case 3: gPartnerTrainerId = trainerId; - if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { gSaveBlock2Ptr->frontier.field_CB4[18] = gSaveBlock2Ptr->frontier.field_CB4[8 + k * 2]; gSaveBlock2Ptr->frontier.field_CB4[19] = gSaveBlock2Ptr->frontier.field_CB4[9 + k * 2]; } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { gSaveBlock2Ptr->frontier.field_CB4[18] = gUnknown_03006298[2]; gSaveBlock2Ptr->frontier.field_CB4[19] = gUnknown_03006298[3]; @@ -1864,20 +1878,20 @@ static void sub_8164828(void) break; } - if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + if (trainerId == TRAINER_EREADER) return; - if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { ShowFieldMessage(gUnknown_085DD500[arrId].strings[gSpecialVar_0x8005]); } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { ShowFieldMessage(gUnknown_085DD500[arrId].strings[gSpecialVar_0x8005]); } else { - u8 id = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].id; + u8 id = gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].id; ShowFieldMessage(gUnknown_085DD690[id][gSpecialVar_0x8005]); } } @@ -2264,18 +2278,6 @@ void sub_81653CC(void) } } -struct StevenMon -{ - u16 species; - u8 fixedIV; - u8 level; - u8 nature; - u8 evs[6]; - u16 moves[4]; -}; - -extern const struct StevenMon sStevenMons[3]; - #define STEVEN_OTID 61226 static void FillPartnerParty(u16 trainerId) @@ -2312,12 +2314,12 @@ static void FillPartnerParty(u16 trainerId) CalculateMonStats(&gPlayerParty[3 + i]); } } - else if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + else if (trainerId == TRAINER_EREADER) { // Scrapped, lol. trainerName[0] = gGameLanguage; } - else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { level = SetFacilityPtrsGetLevel(); ivs = GetFrontierTrainerFixedIvs(trainerId); @@ -2348,9 +2350,9 @@ static void FillPartnerParty(u16 trainerId) SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_GENDER, &j); } } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { - trainerId -= BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID; + trainerId -= TRAINER_RECORD_MIXING_FRIEND; for (i = 0; i < 2; i++) { struct EmeraldBattleTowerRecord *record = &gSaveBlock2Ptr->frontier.towerRecords[trainerId]; @@ -2371,17 +2373,17 @@ static void FillPartnerParty(u16 trainerId) } sub_8068338(&gPlayerParty[3 + i], &monData, TRUE); SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_NAME, trainerName); - j = IsFrontierTrainerFemale(trainerId + BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID); + j = IsFrontierTrainerFemale(trainerId + TRAINER_RECORD_MIXING_FRIEND); SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_GENDER, &j); } } else { - trainerId -= BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID; + trainerId -= TRAINER_RECORD_MIXING_APPRENTICE; for (i = 0; i < 2; i++) { CreateApprenticeMon(&gPlayerParty[3 + i], &gSaveBlock2Ptr->apprentices[trainerId], gSaveBlock2Ptr->frontier.field_CB4[18 + i]); - j = IsFrontierTrainerFemale(trainerId + BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID); + j = IsFrontierTrainerFemale(trainerId + TRAINER_RECORD_MIXING_APPRENTICE); SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_GENDER, &j); } } @@ -2513,27 +2515,27 @@ static void ValidateApprenticesChecksums(void) void GetBattleTowerTrainerLanguage(u8 *dst, u16 trainerId) { - if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + if (trainerId == TRAINER_EREADER) { *dst = gGameLanguage; } - else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_FRIEND) { *dst = gGameLanguage; } - else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) *dst = sub_81864B4(); else - *dst = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].language; + *dst = gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].language; } else { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) *dst = sub_81864C0(); else - *dst = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].language; + *dst = gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].language; } } -- cgit v1.2.3 From 269d7c251022ccbd68f1e4b93cf4d8f4c3424c6e Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sat, 27 Oct 2018 17:39:05 +0200 Subject: up to factory --- src/battle_tower.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/battle_tower.c') diff --git a/src/battle_tower.c b/src/battle_tower.c index 4b63c2875..4199129b2 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -220,7 +220,7 @@ static void sub_8161F94(void) gSaveBlock2Ptr->frontier.field_CA9_b = 0; sub_81A3ACC(); if (!(gSaveBlock2Ptr->frontier.field_CDC & gUnknown_085DF9AC[battleMode][lvlMode])) - gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] = 0; + gSaveBlock2Ptr->frontier.towerWinStreaks[battleMode][lvlMode] = 0; ValidateBattleTowerRecordChecksums(); saved_warp2_set(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1); @@ -258,7 +258,7 @@ static void sub_81620F4(void) case 0: break; case 1: - gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] = gSpecialVar_0x8006; + gSaveBlock2Ptr->frontier.towerWinStreaks[battleMode][lvlMode] = gSpecialVar_0x8006; break; case 2: if (gSpecialVar_0x8006) @@ -1179,7 +1179,7 @@ static void FillFactoryFrontierTrainerParty(u16 trainerId, u8 firstMonId) { u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; // Unused variable. u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); - u8 challengeNum = gSaveBlock2Ptr->frontier.winStreaks[battleMode][0] / 7; + u8 challengeNum = gSaveBlock2Ptr->frontier.towerWinStreaks[battleMode][0] / 7; if (gSaveBlock2Ptr->frontier.curChallengeBattleNum < 6) fixedIV = sub_81A6CA8(challengeNum, 0); else @@ -1480,8 +1480,8 @@ static void SaveCurrentWinStreak(void) u8 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); u16 winStreak = GetCurrentBattleTowerWinStreak(lvlMode, battleMode); - if (gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] < winStreak) - gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] = winStreak; + if (gSaveBlock2Ptr->frontier.towerWinStreaks[battleMode][lvlMode] < winStreak) + gSaveBlock2Ptr->frontier.towerWinStreaks[battleMode][lvlMode] = winStreak; } static void sub_8163EE4(void) @@ -1535,7 +1535,7 @@ static void SaveBattleTowerProgress(void) { u16 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; u16 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); - s32 challengeNum = (signed)(gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] / 7); + s32 challengeNum = (signed)(gSaveBlock2Ptr->frontier.towerWinStreaks[battleMode][lvlMode] / 7); if (gSpecialVar_0x8005 == 0 && (challengeNum > 1 || gSaveBlock2Ptr->frontier.curChallengeBattleNum != 0)) sub_8163EE4(); @@ -1625,7 +1625,7 @@ static void sub_81642A0(void) eventObjTemplates = gSaveBlock1Ptr->eventObjectTemplates; lvlMode = gSaveBlock2Ptr->frontier.lvlMode; battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); - challengeNum = gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] / 7; + challengeNum = gSaveBlock2Ptr->frontier.towerWinStreaks[battleMode][lvlMode] / 7; species1 = GetMonData(&gPlayerParty[0], MON_DATA_SPECIES, NULL); species2 = GetMonData(&gPlayerParty[1], MON_DATA_SPECIES, NULL); level = SetFacilityPtrsGetLevel(); @@ -1911,7 +1911,7 @@ static void sub_8164B74(void) case 0: if (battleMode == FRONTIER_MODE_LINK_MULTIS) { - challengeNum = gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] / 7; + challengeNum = gSaveBlock2Ptr->frontier.towerWinStreaks[battleMode][lvlMode] / 7; if (sub_800A520()) { SendBlock(bitmask_all_link_players_but_self(), &challengeNum, sizeof(challengeNum)); @@ -2069,7 +2069,7 @@ static void ClearBattleTowerRecord(struct EmeraldBattleTowerRecord *record) u16 GetCurrentBattleTowerWinStreak(u8 lvlMode, u8 battleMode) { - u16 winStreak = gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode]; + u16 winStreak = gSaveBlock2Ptr->frontier.towerWinStreaks[battleMode][lvlMode]; if (winStreak > 9999) return 9999; -- cgit v1.2.3 From e85051712361063b04aa7a35ff5c25aed068cab9 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Sat, 27 Oct 2018 21:01:35 +0200 Subject: more battle frontier 2 --- src/battle_tower.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/battle_tower.c') diff --git a/src/battle_tower.c b/src/battle_tower.c index 4199129b2..0f6e18169 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -33,7 +33,6 @@ extern u16 gUnknown_03006298[]; extern void sub_81A3ACC(void); extern void CreateFrontierBrainPokemon(void); extern void sub_81A6CD0(void); -extern u16 sub_81A39C4(void); extern void SetFrontierBrainTrainerGfxId(void); extern u8 GetFrontierBrainTrainerPicIndex(void); extern u8 GetFrontierBrainTrainerClass(void); @@ -364,7 +363,8 @@ static void ChooseNextBattleTowerTrainer(void) { u16 id; u32 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); - u32 r5 = sub_81A39C4() / 7; + u16 winStreak = GetCurrentFacilityWinStreak(); + u32 challengeNum = winStreak / 7; SetFacilityPtrsGetLevel(); if (battleMode == FRONTIER_MODE_MULTIS || battleMode == FRONTIER_MODE_LINK_MULTIS) @@ -385,7 +385,7 @@ static void ChooseNextBattleTowerTrainer(void) s32 i; while (1) { - id = sub_8162548(r5, gSaveBlock2Ptr->frontier.curChallengeBattleNum); + id = sub_8162548(challengeNum, gSaveBlock2Ptr->frontier.curChallengeBattleNum); // Ensure trainer wasn't previously fought in this challenge. for (i = 0; i < gSaveBlock2Ptr->frontier.curChallengeBattleNum; i++) @@ -1516,8 +1516,8 @@ static void sub_8163EE4(void) for (i = 0; i < 6; i++) { playerRecord->greeting[i] = gSaveBlock1Ptr->unk2BBC[i]; - playerRecord->unk1C[i] = gSaveBlock1Ptr->unk2BC8[i]; - playerRecord->unk28[i] = gSaveBlock1Ptr->unk2BD4[i]; + playerRecord->speechWon[i] = gSaveBlock1Ptr->unk2BC8[i]; + playerRecord->speechLost[i] = gSaveBlock1Ptr->unk2BD4[i]; } for (i = 0; i < 4; i++) @@ -1795,7 +1795,8 @@ static void sub_8164828(void) s32 i, j, arrId; s32 monPoolId; s32 level = SetFacilityPtrsGetLevel(); - s32 challengeNum = sub_81A39C4() / 7; + u16 winStreak = GetCurrentFacilityWinStreak(); + s32 challengeNum = winStreak / 7; s32 k = gSpecialVar_LastTalked - 2; s32 trainerId = gSaveBlock2Ptr->frontier.field_CB4[k]; @@ -2425,9 +2426,9 @@ bool32 RubyBattleTowerRecordToEmerald(struct RSBattleTowerRecord *src, struct Em for (i = 0; i < 6; i++) dst->greeting[i] = src->greeting[i]; for (i = 0; i < 6; i++) - dst->unk1C[i] = gUnknown_085DFA46[i]; + dst->speechWon[i] = gUnknown_085DFA46[i]; for (i = 0; i < 6; i++) - dst->unk28[i] = gUnknown_085DFA52[i]; + dst->speechLost[i] = gUnknown_085DFA52[i]; for (i = 0; i < 3; i++) dst->party[i] = src->party[i]; -- cgit v1.2.3 From 0da7d7e6ae7cb50ca0b52d1ea27d98e3f02e50d2 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Tue, 30 Oct 2018 21:45:26 +0100 Subject: why is this function so hard to match --- src/battle_tower.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/battle_tower.c') diff --git a/src/battle_tower.c b/src/battle_tower.c index 0f6e18169..4518e6ad9 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -10,7 +10,7 @@ #include "international_string_util.h" #include "battle.h" #include "battle_frontier_1.h" -#include "battle_frontier_2.h" +#include "frontier_util.h" #include "recorded_battle.h" #include "easy_chat.h" #include "gym_leader_rematch.h" -- cgit v1.2.3 From 37d742cbd86eab628e0d84d5957a805c407b0948 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 1 Nov 2018 15:06:50 +0100 Subject: Document recorded battle --- src/battle_tower.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/battle_tower.c') diff --git a/src/battle_tower.c b/src/battle_tower.c index 4518e6ad9..f02336ef5 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -769,14 +769,14 @@ u8 GetFrontierTrainerFrontSpriteId(u16 trainerId) else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) - return gFacilityClassToPicIndex[sub_818649C()]; + return gFacilityClassToPicIndex[GetRecordedBattleRecordMixFriendClass()]; else return gFacilityClassToPicIndex[gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].facilityClass]; } else { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) - return gFacilityClassToPicIndex[gApprentices[sub_81864A8()].facilityClass]; + return gFacilityClassToPicIndex[gApprentices[GetRecordedBattleApprenticeId()].facilityClass]; else return gFacilityClassToPicIndex[gApprentices[gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].id].facilityClass]; } @@ -807,7 +807,7 @@ u8 GetFrontierOpponentClass(u16 trainerId) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) { - trainerClass = gFacilityClassToTrainerClass[sub_818649C()]; + trainerClass = gFacilityClassToTrainerClass[GetRecordedBattleRecordMixFriendClass()]; } else { @@ -819,7 +819,7 @@ u8 GetFrontierOpponentClass(u16 trainerId) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) { - trainerClass = gFacilityClassToTrainerClass[gApprentices[sub_81864A8()].facilityClass]; + trainerClass = gFacilityClassToTrainerClass[gApprentices[GetRecordedBattleApprenticeId()].facilityClass]; } else { @@ -847,14 +847,14 @@ static u8 GetFrontierTrainerFacilityClass(u16 trainerId) else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) - facilityClass = sub_818649C(); + facilityClass = GetRecordedBattleRecordMixFriendClass(); else facilityClass = gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].facilityClass; } else { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) - facilityClass = gApprentices[sub_81864A8()].facilityClass; + facilityClass = gApprentices[GetRecordedBattleApprenticeId()].facilityClass; else facilityClass = gApprentices[gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].id].facilityClass; } @@ -907,8 +907,8 @@ void GetFrontierTrainerName(u8 *dst, u16 trainerId) if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) { - id = sub_81864A8(); - language = sub_81864C0(); + id = GetRecordedBattleApprenticeId(); + language = GetRecordedBattleApprenticeLanguage(); } else { @@ -1297,7 +1297,7 @@ static void HandleSpecialTrainerBattleEnd(void) { s32 i; - sub_81864CC(); + RecordedBattle_SaveBattleOutcome(); switch (gBattleScripting.specialTrainerBattleType) { case SPECIAL_BATTLE_TOWER: @@ -2527,14 +2527,14 @@ void GetBattleTowerTrainerLanguage(u8 *dst, u16 trainerId) else if (trainerId < TRAINER_RECORD_MIXING_APPRENTICE) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) - *dst = sub_81864B4(); + *dst = GetRecordedBattleRecordMixFriendLanguage(); else *dst = gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].language; } else { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) - *dst = sub_81864C0(); + *dst = GetRecordedBattleApprenticeLanguage(); else *dst = gSaveBlock2Ptr->apprentices[trainerId - TRAINER_RECORD_MIXING_APPRENTICE].language; } -- cgit v1.2.3 From 0bb51037d7d3e257a84b1488016441aafd34b020 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 1 Nov 2018 21:31:10 +0100 Subject: Finish frontier util --- src/battle_tower.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'src/battle_tower.c') diff --git a/src/battle_tower.c b/src/battle_tower.c index f02336ef5..e95eaf156 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -9,7 +9,6 @@ #include "main.h" #include "international_string_util.h" #include "battle.h" -#include "battle_frontier_1.h" #include "frontier_util.h" #include "recorded_battle.h" #include "easy_chat.h" @@ -30,14 +29,9 @@ extern u16 gUnknown_03006298[]; -extern void sub_81A3ACC(void); -extern void CreateFrontierBrainPokemon(void); extern void sub_81A6CD0(void); -extern void SetFrontierBrainTrainerGfxId(void); -extern u8 GetFrontierBrainTrainerPicIndex(void); -extern u8 GetFrontierBrainTrainerClass(void); -extern u8 IsFrontierBrainFemale(void); -extern void CopyFrontierBrainTrainerName(u8 *dst); +extern void sub_81A4C30(void); +extern u8 sub_81A6CA8(u8, u8); extern void SetMonMoveAvoidReturn(struct Pokemon *mon, u16 move, u8 moveSlot); extern const u8 *const *const gUnknown_085DD690[]; @@ -525,7 +519,7 @@ void SetBattleFacilityTrainerGfxId(u16 trainerId, u8 tempVarId) } else if (trainerId == TRAINER_FRONTIER_BRAIN) { - SetFrontierBrainTrainerGfxId(); + SetFrontierBrainEventObjGfx_2(); return; } else if (trainerId < TRAINER_RECORD_MIXING_FRIEND) @@ -1509,7 +1503,7 @@ static void sub_8163EE4(void) } playerRecord->lvlMode = lvlMode; playerRecord->facilityClass = class; - CopyUnalignedWord(playerRecord->trainerId, gSaveBlock2Ptr->playerTrainerId); + CopyTrainerId(playerRecord->trainerId, gSaveBlock2Ptr->playerTrainerId); StringCopy7(playerRecord->name, gSaveBlock2Ptr->playerName); playerRecord->winStreak = GetCurrentBattleTowerWinStreak(lvlMode, battleMode); @@ -2165,7 +2159,7 @@ static void FillEReaderTrainerWithPlayerData(void) + gSaveBlock2Ptr->playerTrainerId[2] + gSaveBlock2Ptr->playerTrainerId[3]) % ARRAY_COUNT(gTowerMaleFacilityClasses)]; } - CopyUnalignedWord(ereaderTrainer->trainerId, gSaveBlock2Ptr->playerTrainerId); + CopyTrainerId(ereaderTrainer->trainerId, gSaveBlock2Ptr->playerTrainerId); StringCopy7(ereaderTrainer->name, gSaveBlock2Ptr->playerName); ereaderTrainer->winStreak = 1; -- cgit v1.2.3