diff options
Diffstat (limited to 'src/battle_tower.c')
-rw-r--r-- | src/battle_tower.c | 558 |
1 files changed, 525 insertions, 33 deletions
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]); + } +} |