summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/apprentice.c2
-rw-r--r--src/battle_frontier_1.c2
-rw-r--r--src/battle_tent.c2
-rw-r--r--src/battle_tower.c558
-rw-r--r--src/record_mixing.c4
-rw-r--r--src/secret_base.c3
6 files changed, 532 insertions, 39 deletions
diff --git a/src/apprentice.c b/src/apprentice.c
index 2a79652ff..d45cff430 100644
--- a/src/apprentice.c
+++ b/src/apprentice.c
@@ -1970,7 +1970,7 @@ static void sub_81A0FFC(void)
StringCopy(stringDst, gText_OpenLevel);
break;
case APPRENTICE_BUFF_EASY_CHAT:
- ConvertBattleFrontierTrainerSpeechToString(gSaveBlock2Ptr->apprentices[0].easyChatWords);
+ FrontierSpeechToString(gSaveBlock2Ptr->apprentices[0].easyChatWords);
StringCopy(stringDst, gStringVar4);
break;
case APPRENTICE_BUFF_SPECIES4:
diff --git a/src/battle_frontier_1.c b/src/battle_frontier_1.c
index 7c93f4cdc..9ec9f8520 100644
--- a/src/battle_frontier_1.c
+++ b/src/battle_frontier_1.c
@@ -96,7 +96,7 @@ void sub_8195C20(void)
void sub_8195C50(void)
{
if (gTrainerBattleOpponent_A < 300)
- ConvertBattleFrontierTrainerSpeechToString(gFacilityTrainers[gTrainerBattleOpponent_A].speechBefore);
+ FrontierSpeechToString(gFacilityTrainers[gTrainerBattleOpponent_A].speechBefore);
}
/*
diff --git a/src/battle_tent.c b/src/battle_tent.c
index 4edb0b619..4ad045043 100644
--- a/src/battle_tent.c
+++ b/src/battle_tent.c
@@ -126,7 +126,7 @@ static void sub_81B9A60(void)
static void sub_81B9A90(void)
{
if (gTrainerBattleOpponent_A < 300)
- ConvertBattleFrontierTrainerSpeechToString(gFacilityTrainers[gTrainerBattleOpponent_A].speechBefore);
+ FrontierSpeechToString(gFacilityTrainers[gTrainerBattleOpponent_A].speechBefore);
}
static void sub_81B9ABC(void)
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]);
+ }
+}
diff --git a/src/record_mixing.c b/src/record_mixing.c
index 4fb4a256e..c9fe3fd47 100644
--- a/src/record_mixing.c
+++ b/src/record_mixing.c
@@ -197,10 +197,10 @@ static void SetSrcLookupPointers(void)
sOldManSave = &gSaveBlock1Ptr->oldMan;
sEasyChatPairsSave = gSaveBlock1Ptr->easyChatPairs;
gUnknown_03001148 = &gUnknown_02039F9C;
- sBattleTowerSave = &gSaveBlock2Ptr->frontier.battleTower;
+ sBattleTowerSave = &gSaveBlock2Ptr->frontier.towerPlayer;
sLilycoveLadySave = &gSaveBlock1Ptr->lilycoveLady;
gUnknown_03001154 = gSaveBlock2Ptr->apprentices;
- sBattleTowerSave_Duplicate = &gSaveBlock2Ptr->frontier.battleTower;
+ sBattleTowerSave_Duplicate = &gSaveBlock2Ptr->frontier.towerPlayer;
}
static void PrepareUnknownExchangePacket(struct PlayerRecordsRS *dest)
diff --git a/src/secret_base.c b/src/secret_base.c
index a684f3982..87d44fb17 100644
--- a/src/secret_base.c
+++ b/src/secret_base.c
@@ -40,6 +40,7 @@
#include "tv.h"
#include "secret_base.h"
#include "constants/map_types.h"
+#include "constants/trainers.h"
extern void mapldr_default(void);
@@ -1143,7 +1144,7 @@ const u8 *GetSecretBaseTrainerLoseText(void)
void sub_80EA2E4(void)
{
sub_813BADC(TRUE);
- gTrainerBattleOpponent_A = 0x400;
+ gTrainerBattleOpponent_A = TRAINER_SECRET_BASE;
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_SECRET_BASE;
}