diff --git a/asm/battle_tower.s b/asm/battle_tower.s index ae01e0b5e7..8eedaf72f2 100644 --- a/asm/battle_tower.s +++ b/asm/battle_tower.s @@ -6,270 +6,6 @@ .text - - - thumb_func_start sub_81621C0 -sub_81621C0: @ 81621C0 - push {r4,r5,lr} - ldr r0, =gTrainerBattleOpponent_A - ldrh r1, [r0] - movs r0, 0xFA - lsls r0, 1 - cmp r1, r0 - bne _081621DA - ldr r0, =gSaveBlock2Ptr - ldr r0, [r0] - ldr r1, =0x00000bec - adds r0, r1 - bl sub_816534C -_081621DA: - ldr r5, =gSaveBlock2Ptr - ldr r0, [r5] - ldr r1, =0x00000d04 - adds r2, r0, r1 - ldrh r1, [r2] - ldr r0, =0x0000270e - cmp r1, r0 - bhi _081621EE - adds r0, r1, 0x1 - strh r0, [r2] -_081621EE: - ldr r1, [r5] - ldr r4, =0x00000cb2 - adds r1, r4 - ldrh r0, [r1] - adds r0, 0x1 - strh r0, [r1] - bl sub_8163E90 - ldr r1, =gSpecialVar_Result - ldr r0, [r5] - adds r0, r4 - ldrh r0, [r0] - strh r0, [r1] - pop {r4,r5} - pop {r0} - bx r0 - .pool - thumb_func_end sub_81621C0 - - thumb_func_start sub_816222C -sub_816222C: @ 816222C - push {r4-r7,lr} - mov r7, r10 - mov r6, r9 - mov r5, r8 - push {r5-r7} - sub sp, 0x3C - movs r0, 0 - str r0, [sp, 0x24] - ldr r4, =gSaveBlock2Ptr - ldr r0, [r4] - ldr r1, =0x00000ca9 - adds r0, r1 - ldrb r0, [r0] - lsls r0, 30 - lsrs r0, 30 - mov r10, r0 - ldr r0, =0x000040ce - bl VarGet - lsls r0, 24 - lsrs r0, 24 - str r0, [sp, 0x2C] - ldr r0, =0x000040cf - bl VarGet - lsls r0, 16 - cmp r0, 0 - beq _08162266 - b _0816239C -_08162266: - mov r0, r10 - ldr r1, [sp, 0x2C] - bl sub_8164FCC - lsls r0, 16 - lsrs r0, 16 - str r0, [sp, 0x28] - movs r7, 0 - mov r2, sp - str r2, [sp, 0x34] -_0816227A: - movs r3, 0xEC - adds r0, r7, 0 - muls r0, r3 - movs r4, 0xE7 - lsls r4, 3 - adds r0, r4 - ldr r5, =gSaveBlock2Ptr - ldr r1, [r5] - movs r2, 0 - mov r8, r2 - mov r9, r2 - movs r5, 0 - adds r3, r7, 0x1 - str r3, [sp, 0x30] - adds r1, r0 -_08162298: - ldm r1!, {r0} - mov r4, r8 - orrs r4, r0 - mov r8, r4 - add r9, r0 - adds r5, 0x1 - cmp r5, 0x39 - bls _08162298 - movs r6, 0 - movs r5, 0 - movs r0, 0xEC - adds r2, r7, 0 - muls r2, r0 -_081622B2: - ldr r3, =gSaveBlock2Ptr - ldr r1, [r3] - movs r0, 0x2C - muls r0, r5 - adds r0, r2 - adds r1, r0 - ldr r4, =0x0000076c - adds r0, r1, r4 - ldrh r0, [r0] - cmp r0, 0 - beq _081622E4 - movs r0, 0xEF - lsls r0, 3 - adds r4, r1, r0 - mov r0, r10 - str r2, [sp, 0x38] - bl GetFrontierEnemyMonLevel - ldrb r1, [r4] - lsls r0, 24 - lsrs r0, 24 - ldr r2, [sp, 0x38] - cmp r1, r0 - bhi _081622E4 - adds r6, 0x1 -_081622E4: - adds r5, 0x1 - cmp r5, 0x3 - ble _081622B2 - ldr r0, =gUnknown_085DF9F6 - ldr r1, [sp, 0x2C] - adds r0, r1, r0 - ldrb r0, [r0] - cmp r6, r0 - blt _0816233E - ldr r3, =gSaveBlock2Ptr - ldr r2, [r3] - movs r4, 0xEC - adds r3, r7, 0 - muls r3, r4 - adds r1, r2, r3 - ldr r5, =0x0000073a - adds r0, r1, r5 - ldrh r0, [r0] - ldr r4, [sp, 0x28] - cmp r0, r4 - bne _0816233E - subs r5, 0x2 - adds r0, r1, r5 - ldrb r0, [r0] - cmp r0, r10 - bne _0816233E - mov r0, r8 - cmp r0, 0 - beq _0816233E - movs r1, 0x82 - lsls r1, 4 - adds r0, r2, r1 - adds r0, r3 - ldr r0, [r0] - cmp r0, r9 - bne _0816233E - movs r2, 0x96 - lsls r2, 1 - adds r0, r7, r2 - ldr r3, [sp, 0x34] - stm r3!, {r0} - str r3, [sp, 0x34] - ldr r4, [sp, 0x24] - adds r4, 0x1 - str r4, [sp, 0x24] -_0816233E: - ldr r7, [sp, 0x30] - cmp r7, 0x4 - ble _0816227A - ldr r5, [sp, 0x2C] - cmp r5, 0 - bne _08162396 - bl sub_8165B20 - movs r7, 0 - ldr r0, =gSaveBlock2Ptr - ldr r0, [r0] - ldr r4, =gUnknown_085DF9EC - adds r2, r0, 0 - adds r2, 0xDC - ldr r1, [sp, 0x24] - lsls r0, r1, 2 - mov r5, sp - adds r3, r0, r5 -_08162362: - ldrb r0, [r2] - lsls r1, r0, 25 - lsrs r0, r1, 30 - cmp r0, 0 - beq _0816238E - ldrb r0, [r2, 0x1] - adds r0, r4 - ldrb r0, [r0] - ldr r5, [sp, 0x28] - cmp r0, r5 - bne _0816238E - lsrs r0, r1, 30 - subs r0, 0x1 - cmp r0, r10 - bne _0816238E - movs r1, 0xC8 - lsls r1, 1 - adds r0, r7, r1 - stm r3!, {r0} - ldr r5, [sp, 0x24] - adds r5, 0x1 - str r5, [sp, 0x24] -_0816238E: - adds r2, 0x44 - adds r7, 0x1 - cmp r7, 0x3 - ble _08162362 -_08162396: - ldr r0, [sp, 0x24] - cmp r0, 0 - bne _081623C0 -_0816239C: - movs r0, 0 - b _081623DA - .pool -_081623C0: - ldr r4, =gTrainerBattleOpponent_A - bl Random - lsls r0, 16 - lsrs r0, 16 - ldr r1, [sp, 0x24] - bl __modsi3 - lsls r0, 2 - add r0, sp - ldr r0, [r0] - strh r0, [r4] - movs r0, 0x1 -_081623DA: - add sp, 0x3C - pop {r3-r5} - mov r8, r3 - mov r9, r4 - mov r10, r5 - pop {r4-r7} - pop {r1} - bx r1 - .pool - thumb_func_end sub_816222C - thumb_func_start sub_81623F0 sub_81623F0: @ 81623F0 push {r4-r7,lr} @@ -329,7 +65,7 @@ _08162414: b _08162530 .pool _08162488: - bl sub_816222C + bl ChooseSpecialBattleTowerTrainer lsls r0, 24 cmp r0, 0 beq _081624B4 @@ -3334,7 +3070,7 @@ sub_8163E90: @ 8163E90 lsrs r4, 24 adds r0, r5, 0 adds r1, r4, 0 - bl sub_8164FCC + bl GetCurrentBattleTowerWinStreak lsls r0, 16 lsrs r2, r0, 16 ldr r0, [r6] @@ -3420,7 +3156,7 @@ _08163F52: bl StringCopy7 adds r0, r6, 0 adds r1, r7, 0 - bl sub_8164FCC + bl GetCurrentBattleTowerWinStreak strh r0, [r5, 0x2] movs r4, 0 movs r2, 0x10 @@ -5289,8 +5025,8 @@ _08164FBE: bx r0 thumb_func_end sub_8164FB8 - thumb_func_start sub_8164FCC -sub_8164FCC: @ 8164FCC + thumb_func_start GetCurrentBattleTowerWinStreak +GetCurrentBattleTowerWinStreak: @ 8164FCC push {lr} lsls r0, 24 lsls r1, 24 @@ -5312,7 +5048,7 @@ _08164FEE: pop {r1} bx r1 .pool - thumb_func_end sub_8164FCC + thumb_func_end GetCurrentBattleTowerWinStreak thumb_func_start sub_8164FFC sub_8164FFC: @ 8164FFC @@ -5378,7 +5114,7 @@ _0816506A: strh r0, [r1] adds r0, r5, 0 adds r1, r4, 0 - bl sub_8164FCC + bl GetCurrentBattleTowerWinStreak lsls r0, 16 lsrs r0, 16 cmp r0, 0x37 diff --git a/include/battle_tower.h b/include/battle_tower.h index 5879a73bb1..6af87210b6 100644 --- a/include/battle_tower.h +++ b/include/battle_tower.h @@ -1,6 +1,10 @@ #ifndef GUARD_BATTLE_TOWER_H #define GUARD_BATTLE_TOWER_H +#define BATTLE_TOWER_EREADER_TRAINER_ID 200 +#define BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID 300 +#define BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID 400 + struct RSBattleTowerRecord { /*0x00*/ u8 battleTowerLevelType; // 0 = level 50, 1 = level 100 @@ -46,7 +50,7 @@ struct FacilityMon extern const struct BattleFrontierTrainer *gFacilityTrainers; extern const struct FacilityMon *gFacilityTrainerMons; -u16 sub_8164FCC(u8, u8); +u16 GetCurrentBattleTowerWinStreak(u8, u8); void sub_81659DC(struct RSBattleTowerRecord *a0, struct RSBattleTowerRecord *a1); bool32 sub_816587C(union BattleTowerRecord *, union BattleTowerRecord *); void CalcEmeraldBattleTowerChecksum(struct EmeraldBattleTowerRecord *); diff --git a/include/global.h b/include/global.h index b92f1097f0..35e34e722d 100644 --- a/include/global.h +++ b/include/global.h @@ -275,26 +275,6 @@ struct BerryCrush u32 unk; }; -struct UnknownSaveBlock2Struct -{ - u8 field_0; - u8 field_1; - u8 field_2[2]; - u8 field_4[8]; - u8 field_C[16]; - u16 field_1C[6]; - u16 field_28[6]; - u8 field_34[176]; - u8 field_E4; - u8 field_E5; - u8 field_E6; - u8 field_E7; - u8 field_E8; - u8 field_E9; - u8 field_EA; - u8 field_EB; -}; // sizeof = 0xEC - struct ApprenticeMon { u16 species; @@ -345,7 +325,7 @@ struct UnknownPokemonStruct struct EmeraldBattleTowerRecord { - /*0x00*/ u8 battleTowerLevelType; // 0 = level 50, 1 = level 100 + /*0x00*/ u8 lvlMode; // 0 = level 50, 1 = level 100 /*0x01*/ u8 trainerClass; /*0x02*/ u16 winStreak; /*0x04*/ u8 name[PLAYER_NAME_LENGTH + 1]; @@ -387,7 +367,7 @@ struct BattleDomeTrainer struct BattleFrontier { /*0x64C*/ struct EmeraldBattleTowerRecord battleTower; - /*0x738*/ struct UnknownSaveBlock2Struct field_738[5]; // No idea here, it's probably wrong, no clue. + /*0x738*/ struct EmeraldBattleTowerRecord records[5]; // No idea here, it's probably wrong, no clue. /*0xBD4*/ u16 field_BD4; /*0xBD6*/ u16 field_BD6; /*0xBD8*/ u8 field_BD8[11]; @@ -415,7 +395,10 @@ struct BattleFrontier /*0xCF0*/ u16 field_CF0[2]; /*0xCF4*/ u16 field_CF4[2]; /*0xCF8*/ u16 field_CF8[2]; - /*0xCFC*/ u16 field_CFC[5]; + /*0xCFC*/ u16 field_CFC[2]; + /*0xD06*/ u16 field_D00; + /*0xD06*/ u16 field_D02; + /*0xD06*/ u16 field_D04; /*0xD06*/ u8 field_D06; /*0xD07*/ u8 field_D07; /*0xD08*/ u8 field_D08_0:1; diff --git a/src/battle_tower.c b/src/battle_tower.c index e70d4af91c..a6983897f6 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; + } +} diff --git a/src/recorded_battle.c b/src/recorded_battle.c index 355ed5e079..0a199f2891 100644 --- a/src/recorded_battle.c +++ b/src/recorded_battle.c @@ -402,73 +402,73 @@ u32 MoveRecordedBattleToSaveData(void) { for (i = 0; i < 8; i++) { - battleSave->field_504[i] = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_A - 300].field_4[i]; + battleSave->field_504[i] = gSaveBlock2Ptr->records[gTrainerBattleOpponent_A - 300].field_4[i]; } - battleSave->field_50C = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_A - 300].field_1; + battleSave->field_50C = gSaveBlock2Ptr->records[gTrainerBattleOpponent_A - 300].field_1; if (sUnknown_0203CCE8 == 1) { for (i = 0; i < 6; i++) { - battleSave->field_50E[i] = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_A - 300].field_28[i]; + battleSave->field_50E[i] = gSaveBlock2Ptr->records[gTrainerBattleOpponent_A - 300].field_28[i]; } } else { for (i = 0; i < 6; i++) { - battleSave->field_50E[i] = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_A - 300].field_1C[i]; + battleSave->field_50E[i] = gSaveBlock2Ptr->records[gTrainerBattleOpponent_A - 300].field_1C[i]; } } - battleSave->field_51A = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_A - 300].field_E4; + battleSave->field_51A = gSaveBlock2Ptr->records[gTrainerBattleOpponent_A - 300].field_E4; } else if (gTrainerBattleOpponent_B >= 300 && gTrainerBattleOpponent_B <= 399) { for (i = 0; i < 8; i++) { - battleSave->field_504[i] = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_B - 300].field_4[i]; + battleSave->field_504[i] = gSaveBlock2Ptr->records[gTrainerBattleOpponent_B - 300].field_4[i]; } - battleSave->field_50C = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_B - 300].field_1; + battleSave->field_50C = gSaveBlock2Ptr->records[gTrainerBattleOpponent_B - 300].field_1; if (sUnknown_0203CCE8 == 1) { for (i = 0; i < 6; i++) { - battleSave->field_50E[i] = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_B - 300].field_28[i]; + battleSave->field_50E[i] = gSaveBlock2Ptr->records[gTrainerBattleOpponent_B - 300].field_28[i]; } } else { for (i = 0; i < 6; i++) { - battleSave->field_50E[i] = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_B - 300].field_1C[i]; + battleSave->field_50E[i] = gSaveBlock2Ptr->records[gTrainerBattleOpponent_B - 300].field_1C[i]; } } - battleSave->field_51A = gSaveBlock2Ptr->field_738[gTrainerBattleOpponent_B - 300].field_E4; + battleSave->field_51A = gSaveBlock2Ptr->records[gTrainerBattleOpponent_B - 300].field_E4; } else if (gPartnerTrainerId >= 300 && gPartnerTrainerId <= 399) { for (i = 0; i < 8; i++) { - battleSave->field_504[i] = gSaveBlock2Ptr->field_738[gPartnerTrainerId - 300].field_4[i]; + battleSave->field_504[i] = gSaveBlock2Ptr->records[gPartnerTrainerId - 300].field_4[i]; } - battleSave->field_50C = gSaveBlock2Ptr->field_738[gPartnerTrainerId - 300].field_1; + battleSave->field_50C = gSaveBlock2Ptr->records[gPartnerTrainerId - 300].field_1; if (sUnknown_0203CCE8 == 1) { for (i = 0; i < 6; i++) { - battleSave->field_50E[i] = gSaveBlock2Ptr->field_738[gPartnerTrainerId - 300].field_28[i]; + battleSave->field_50E[i] = gSaveBlock2Ptr->records[gPartnerTrainerId - 300].field_28[i]; } } else { for (i = 0; i < 6; i++) { - battleSave->field_50E[i] = gSaveBlock2Ptr->field_738[gPartnerTrainerId - 300].field_1C[i]; + battleSave->field_50E[i] = gSaveBlock2Ptr->records[gPartnerTrainerId - 300].field_1C[i]; } } - battleSave->field_51A = gSaveBlock2Ptr->field_738[gPartnerTrainerId - 300].field_E4; + battleSave->field_51A = gSaveBlock2Ptr->records[gPartnerTrainerId - 300].field_E4; } */ diff --git a/src/tv.c b/src/tv.c index fb309f6e3f..3625c6cee1 100644 --- a/src/tv.c +++ b/src/tv.c @@ -1544,7 +1544,7 @@ static void InterviewAfter_BravoTrainerBattleTowerProfile(void) StringCopy(show->bravoTrainerTower.pokemonName, gSaveBlock2Ptr->frontier.field_BD8); show->bravoTrainerTower.species = gSaveBlock2Ptr->frontier.field_BD4; show->bravoTrainerTower.defeatedSpecies = gSaveBlock2Ptr->frontier.field_BD6; - show->bravoTrainerTower.numFights = sub_8164FCC(gSaveBlock2Ptr->frontier.field_D07, 0); + show->bravoTrainerTower.numFights = GetCurrentBattleTowerWinStreak(gSaveBlock2Ptr->frontier.field_D07, 0); show->bravoTrainerTower.wonTheChallenge = gSaveBlock2Ptr->frontier.field_D06; if (gSaveBlock2Ptr->frontier.field_D07 == 0) {