#include "global.h" #include "main.h" #include "species.h" #include "pokemon.h" #include "songs.h" #include "task.h" #include "fieldmap.h" #include "string_util.h" #include "rng.h" extern void prev_quest_postbuffer_cursor_backup_reset(void); extern void overworld_poison_timer_set(void); extern void current_map_music_set__default_for_battle(u16); extern void c2_exit_to_overworld_1_continue_scripts_restart_music(void); extern void c2_exit_to_overworld_2_switch(void); extern void npc_set_running_behaviour_etc(struct MapObject *, u8); extern u8 FlagGet(u16); extern u8 FlagSet(u16); extern void FlagReset(u16); extern void c2_whiteout(void); extern void sub_800E7C4(void); extern void sub_8081AA4(void); extern void sub_8081A18(void); extern void sub_8081C8C(void); extern void sub_80C824C(void); extern void sub_8081CEC(void); extern void sub_8080E44(void); extern void sub_80821D8(void); extern void sub_8082228(void); extern void sub_808260C(void); extern void sub_8082CB8(void); extern u8 * sub_80BCCE8(void); extern void ShowFieldMessage(); extern void CB2_ChooseStarter(void); extern void sub_811AABC(u8); extern u8 sub_811AAE8(void); extern u32 GetMonData(struct Pokemon *mon, s32 field); extern u8 GetFieldObjectIdByLocalIdAndMap(u8, u8, u8); extern u32 sub_8082880(void); extern u8 sub_803FC58(u16); extern u16 gScriptResult; struct Trainer { /* 0x00 */ u8 partyFlags; /* 0x01 */ u8 trainerClass; /* 0x02 */ u8 encounterMusic:7; /* 0x02 */ u8 gender:1; /* 0x03 */ u8 trainerPic; /* 0x04 */ u8 trainerName[12]; /* 0x10 */ u16 items[4]; /* 0x18 */ bool8 doubleBattle; /* 0x1C */ u32 aiFlags; /* 0x20 */ u8 partySize; /* 0x24 */ struct TrainerPartyMember *party; }; struct TrainerPartyMember { u16 iv; u8 level; u16 species; }; struct TrainerBattleSpec { void *ptr; u8 ptrType; }; struct TrainerEyeTrainer { u16 trainerNums[5]; u16 mapGroup; u16 mapNum; }; extern u16 MapGridGetMetatileBehaviorAt(s16, s16); extern bool8 MetatileBehavior_IsTallGrass(char); extern bool8 MetatileBehavior_IsLongGrass(char); extern bool8 MetatileBehavior_IsSandOrDeepSand(char); extern bool8 MetatileBehavior_IsSurfableWaterOrUnderwater(char); extern bool8 MetatileBehavior_IsBridge(char); extern bool8 sub_80574C4(char); extern bool8 sub_80574D8(char); extern bool8 sub_8057568(char); extern u8 TestPlayerAvatarFlags(u8); extern u8 sub_8057450(u8); extern u8 GetSav1Weather(void); extern void PlayNewMapMusic(u16); extern u8 ScriptGiveMon(u16, u8, u16, u32, u32, u8); extern void (*gUnknown_0300485C)(void); extern u16 *GetVarPointer(u16); extern struct Pokemon gEnemyParty[]; extern struct Pokemon gPlayerParty[]; extern struct Trainer gTrainers[]; extern u16 gTrainerBattleMode; extern u16 gTrainerBattleOpponent; extern u16 gTrainerMapObjectLocalId; extern u32 gTrainerIntroSpeech; extern u32 gTrainerDefeatSpeech; extern u32 gTrainerVictorySpeech; extern u32 gTrainerCannotBattleSpeech; extern u32 gTrainerBattleScriptReturnAddress; extern u32 gTrainerBattleEndScript; extern u32 gTrainerEyeTrainers[]; extern u32 gOtherText_CancelWithTerminator[]; extern u16 gUnknown_020239F8; extern u16 gUnknown_0202E8DE; extern u8 gUnknown_02024D26; extern u16 gBadgeFlags[]; extern struct MapObject gMapObjects[]; extern u8 gUnknown_0819F818[]; extern u8 gUnknown_0819F840[]; extern u8 gUnknown_0819F878[]; extern u8 gUnknown_0819F887[]; extern u8 gUnknown_0819F8AE[]; extern u8 gUnknown_0819F80B[]; extern u8 gUnknown_081C6C02[]; extern u8 gTrainerBattleSpecs_0[]; extern u8 gTrainerBattleSpecs_1[]; extern u8 gTrainerBattleSpecs_2[]; extern u8 gTrainerBattleSpecs_3[]; extern u8 gTrainerBattleSpecs_4[]; extern u8 gStringVar4[]; extern u8 gBattleTransitionTable_Wild[][2]; extern u8 gBattleTransitionTable_Trainer[][2]; void sub_8082188(void); void task01_battle_start(u8 taskId) { s16 *data = gTasks[taskId].data; switch (data[0]) { case 0: if (!FieldPoisonEffectIsRunning()) // is poison not active? { sub_811AABC(data[1]); ++data[0]; // go to case 1. } break; case 1: if (sub_811AAE8() == 1) { SetMainCallback2(sub_800E7C4); prev_quest_postbuffer_cursor_backup_reset(); overworld_poison_timer_set(); DestroyTask(taskId); } break; } } void task_add_01_battle_start(u8 transition, u16 song) { u8 taskId = CreateTask(task01_battle_start, 1); gTasks[taskId].data[1] = transition; current_map_music_set__default_for_battle(song); } void CheckForSafariZoneAndProceed(void) { if (GetSafariZoneFlag()) sub_8081AA4(); else sub_8081A18(); } void sub_8081A18(void) { u8 transition; ScriptContext2_Enable(); player_bitmagic(); sub_80597F4(); gMain.field_8 = sub_8081C8C; gUnknown_020239F8 = 0; transition = GetHigherOrLowerLevelTransitionForWild(); task_add_01_battle_start(transition, 0); sav12_xor_increment(7); sav12_xor_increment(8); } void sub_8081A5C(void) { u8 transition; ScriptContext2_Enable(); player_bitmagic(); sub_80597F4(); gMain.field_8 = sub_8081C8C; gUnknown_020239F8 = 1024; transition = GetHigherOrLowerLevelTransitionForWild(); task_add_01_battle_start(transition, 0); sav12_xor_increment(7); sav12_xor_increment(8); } void sub_8081AA4(void) { u8 transition; ScriptContext2_Enable(); player_bitmagic(); sub_80597F4(); gMain.field_8 = sub_80C824C; gUnknown_020239F8 = 128; transition = GetHigherOrLowerLevelTransitionForWild(); task_add_01_battle_start(transition, 0); } void task_add_01_battle_start_with_music_and_stats(void) { u8 transition; transition = sub_8082080(); task_add_01_battle_start(transition, 0); sav12_xor_increment(7); sav12_xor_increment(9); } void sub_8081AFC(void) { CreateMaleMon(&gEnemyParty, SPECIES_RALTS, 5); ScriptContext2_Enable(); gMain.field_8 = c2_exit_to_overworld_1_continue_scripts_restart_music; gUnknown_020239F8 = 512; task_add_01_battle_start(8, 0); } void sub_8081B3C(void) { u8 transition; ScriptContext2_Enable(); gMain.field_8 = sub_8081CEC; gUnknown_020239F8 = 0; transition = GetHigherOrLowerLevelTransitionForWild(); task_add_01_battle_start(transition, 0); sav12_xor_increment(7); sav12_xor_increment(8); } void sub_8081B78(void) { u8 transition; ScriptContext2_Enable(); gMain.field_8 = sub_8081CEC; gUnknown_020239F8 = 0x2000; transition = GetHigherOrLowerLevelTransitionForWild(); task_add_01_battle_start(transition, 0); sav12_xor_increment(7); sav12_xor_increment(8); } void sub_8081BB8(void) { ScriptContext2_Enable(); gMain.field_8 = sub_8081CEC; gUnknown_020239F8 = 0x2000; task_add_01_battle_start(0, BGM_BATTLE34); sav12_xor_increment(7); sav12_xor_increment(8); } void sub_8081BF8(void) { ScriptContext2_Enable(); gMain.field_8 = sub_8081CEC; gUnknown_020239F8 = 12288; if (gGameVersion == 2) task_add_01_battle_start(0xB, BGM_BATTLE34); // KYOGRE else task_add_01_battle_start(0x6, BGM_BATTLE34); // GROUDON sav12_xor_increment(7); sav12_xor_increment(8); } void sub_8081C50(void) { ScriptContext2_Enable(); gMain.field_8 = sub_8081CEC; gUnknown_020239F8 = 24576; task_add_01_battle_start(0xA, BGM_BATTLE36); sav12_xor_increment(7); sav12_xor_increment(8); } void sub_8081C8C(void) { CpuFill16(0, 0x5000000, 0x1000200); ResetOamRange(0, 0x80); if (battle_exit_is_player_defeat(gUnknown_02024D26) == 1) { SetMainCallback2(c2_whiteout); } else { SetMainCallback2(c2_exit_to_overworld_2_switch); gUnknown_0300485C = sub_8080E44; } } void sub_8081CEC(void) { CpuFill16(0, 0x5000000, 0x1000200); ResetOamRange(0, 0x80); if (battle_exit_is_player_defeat(gUnknown_02024D26) == 1) SetMainCallback2(c2_whiteout); else SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); } s8 sub_8081D3C(void) { u16 tileBehavior; s16 x, y; PlayerGetDestCoords(&x, &y); tileBehavior = MapGridGetMetatileBehaviorAt(x, y); if (MetatileBehavior_IsTallGrass(tileBehavior)) return 0; if (MetatileBehavior_IsLongGrass(tileBehavior)) return 1; if (MetatileBehavior_IsSandOrDeepSand(tileBehavior)) return 2; switch (gMapHeader.light) { case 1: case 2: case 3: break; case 4: if (sub_80574C4(tileBehavior)) return 8; if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) return 5; return 7; case 8: case 9: return 8; case 5: return 3; case 6: if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) return 4; return 9; } if (sub_8057568(tileBehavior)) return 4; if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) return 5; if (sub_80574D8(tileBehavior)) return 6; if (TestPlayerAvatarFlags(8)) { if (sub_8057450(tileBehavior)) return 5; if (MetatileBehavior_IsBridge(tileBehavior) == 1) return 4; } if (!(gSaveBlock1.location.mapGroup == 0 && gSaveBlock1.location.mapNum == 28) && GetSav1Weather() != 8) return 9; else return 2; } s8 sub_8081E90(void) { u8 flashUsed; u16 tileBehavior; s16 x, y; PlayerGetDestCoords(&x, &y); tileBehavior = MapGridGetMetatileBehaviorAt(x, y); flashUsed = sav1_get_flash_used_on_map(); if(flashUsed) return 2; if(!(MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior))) { switch (gMapHeader.light) { case 4: return 1; case 5: return 3; default: return 0; } } return 3; } u16 GetSumOfPartyMonLevel(u8 fixCount) { u32 monData; u8 returnThis = 0; int loopCounter; for (loopCounter = 0; loopCounter <= 5; loopCounter++) { monData = GetMonData(&gPlayerParty[loopCounter], MON_DATA_SPECIES2); if (monData != 412 && monData) // if the pokemon in question is either NOT Ten question marks or an egg, proceed // note that it actually considers the 26 glitch mons to be "valid". { if (GetMonData(&gPlayerParty[loopCounter], MON_DATA_HP)) { returnThis += GetMonData(&gPlayerParty[loopCounter], MON_DATA_LEVEL); fixCount--; if (!fixCount) // has it reached 0? break; } } } return returnThis; } u8 GetSumOfEnemyPartyLevel(u16 trainerNum, u8 partyCount) { // TODO: Clean this up. u8 i; u8 returnThis; // v4 u32 _partyCount = partyCount; struct TrainerPartyMember *party; if (gTrainers[trainerNum].partySize < _partyCount) // is the actual party size smaller than the specified size? _partyCount = gTrainers[trainerNum].partySize; // if so, set the specified size to the actual size. seems to be error correction? returnThis = 0; switch (gTrainers[trainerNum].partyFlags) { case 0: party = gTrainers[trainerNum].party; for(i = 0; i < _partyCount; i++) returnThis += party[i].level; break; case 1: party = gTrainers[trainerNum].party; for(i = 0; i < _partyCount; i++) returnThis += party[i * 2].level; break; case 2: party = gTrainers[trainerNum].party; for(i = 0; i < _partyCount; i++) returnThis += party[i].level; break; case 3: party = gTrainers[trainerNum].party; for(i = 0; i < _partyCount; i++) returnThis += party[i * 2].level; break; } return returnThis; } u8 GetHigherOrLowerLevelTransitionForWild(void) { u8 flashVar = sub_8081E90(); u8 level = GetMonData(&gEnemyParty, MON_DATA_LEVEL); if (level < (u8)GetSumOfPartyMonLevel(1)) // is wild mon level than the player's mon level? return gBattleTransitionTable_Wild[flashVar][0]; else return gBattleTransitionTable_Wild[flashVar][1]; // use a white fade in instead of normal transition. } u8 sub_8082080(void) { struct Trainer *trainer; u8 trainerClass; u8 partyCount; u8 flashVar; u8 level; if (gTrainerBattleOpponent == 1024) // link battle? return 16; trainer = gTrainers; if (trainer[gTrainerBattleOpponent].trainerClass == 24) // league? { if (gTrainerBattleOpponent == 261) return 12; if (gTrainerBattleOpponent == 262) return 13; if (gTrainerBattleOpponent == 263) return 14; if (gTrainerBattleOpponent == 264) return 15; return 16; } if (trainer[gTrainerBattleOpponent].trainerClass == 32) // team leader? return 16; if (trainer[gTrainerBattleOpponent].doubleBattle == TRUE) partyCount = 2; // double battles always at least have 2 pokemon. else partyCount = 1; flashVar = sub_8081E90(); level = GetSumOfEnemyPartyLevel(gTrainerBattleOpponent, partyCount); if (level < (u8)GetSumOfPartyMonLevel(partyCount)) // is wild mon level than the player's mon level? return gBattleTransitionTable_Trainer[flashVar][0]; else return gBattleTransitionTable_Trainer[flashVar][1]; } s8 sub_8082138(void) { u8 monData = GetMonData(&gEnemyParty, MON_DATA_LEVEL); if (monData < (u8)GetSumOfPartyMonLevel(1)) return 4; else return 3; } void sub_8082168(void) { SetMainCallback2(CB2_ChooseStarter); gMain.field_8 = sub_8082188; } void sub_8082188(void) { u16 starterPoke; *GetVarPointer(0x4023) = gScriptResult; starterPoke = GetStarterPokemon(gScriptResult); ScriptGiveMon(starterPoke, 5, 0, 0, 0, 0); ResetTasks(); sub_80408BC(); SetMainCallback2(sub_80821D8); sub_811AAD8(0); } void sub_80821D8(void) { UpdatePaletteFade(); RunTasks(); if (sub_811AAE8() == 1) { gUnknown_020239F8 = 16; gMain.field_8 = sub_8082228; SetMainCallback2(sub_800E7C4); prev_quest_postbuffer_cursor_backup_reset(); overworld_poison_timer_set(); sav12_xor_increment(7); sav12_xor_increment(8); } } void sub_8082228(void) { sav1_reset_battle_music_maybe(); SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); } u32 TrainerBattleLoadArg32(u8 *ptr) { return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); } u16 TrainerBattleLoadArg16(u8 *ptr) { return ptr[0] | (ptr[1] << 8); } u8 TrainerBattleLoadArg8(u8 *ptr) { return ptr[0]; } u16 trainerflag_opponent(void) { return gTrainerBattleOpponent + 1280; } bool32 battle_exit_is_player_defeat(u32 a1) { a1--; if (a1 > 6) return 0; switch(a1) { case 1: case 2: return 1; case 0: case 3: case 4: case 5: case 6: return 0; } } u32 sub_80822BC(void) { u32 *pointer; gTrainerBattleMode = 0; gTrainerBattleOpponent = 0; gTrainerMapObjectLocalId = 0; gTrainerIntroSpeech = 0; gTrainerDefeatSpeech = 0; gTrainerVictorySpeech = 0; gTrainerCannotBattleSpeech = 0; gTrainerBattleScriptReturnAddress = 0; pointer = &gTrainerBattleEndScript; gTrainerBattleEndScript = 0; return pointer; } void TrainerBattleLoadArgs(struct TrainerBattleSpec *specs, u8 *data) { while (1) { switch (specs->ptrType) { case 0: *(u8 *)specs->ptr = TrainerBattleLoadArg8(data); data++; break; case 1: *(u16 *)specs->ptr = TrainerBattleLoadArg16(data); data += 2; break; case 2: *(u32 *)specs->ptr = TrainerBattleLoadArg32(data); data += 4; break; case 3: *(u8 *)specs->ptr = 0; break; case 4: *(u16 *)specs->ptr = 0; break; case 5: *(u32 *)specs->ptr = 0; break; case 6: *(u8 **)specs->ptr = data; return; } specs++; } } void battle_80801F0(void) { if (gTrainerMapObjectLocalId) { gUnknown_0202E8DE = gTrainerMapObjectLocalId; gSelectedMapObject = GetFieldObjectIdByLocalIdAndMap(gTrainerMapObjectLocalId, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup); } } u8 *TrainerBattleConfigure(u8 *a1) { sub_80822BC(); gTrainerBattleMode = TrainerBattleLoadArg8(a1); switch (gTrainerBattleMode) { case 3: TrainerBattleLoadArgs(gTrainerBattleSpecs_3, a1); return gUnknown_0819F878; case 4: TrainerBattleLoadArgs(gTrainerBattleSpecs_2, a1); battle_80801F0(); return gUnknown_0819F840; case 1: case 2: TrainerBattleLoadArgs(gTrainerBattleSpecs_1, a1); battle_80801F0(); return gUnknown_0819F818; case 6: case 8: TrainerBattleLoadArgs(gTrainerBattleSpecs_4, a1); battle_80801F0(); return gUnknown_0819F840; case 7: TrainerBattleLoadArgs(gTrainerBattleSpecs_2, a1); battle_80801F0(); gTrainerBattleOpponent = sub_8082C4C(gTrainerBattleOpponent); return gUnknown_0819F8AE; case 5: TrainerBattleLoadArgs(gTrainerBattleSpecs_0, a1); battle_80801F0(); gTrainerBattleOpponent = sub_8082C4C(gTrainerBattleOpponent); return gUnknown_0819F887; default: TrainerBattleLoadArgs(gTrainerBattleSpecs_0, a1); battle_80801F0(); return gUnknown_0819F818; } } void TrainerWantsBattle(u8 ptr, int a2) { gSelectedMapObject = ptr; gUnknown_0202E8DE = gMapObjects[ptr].localId; TrainerBattleConfigure(a2 + 1); ScriptContext1_SetupScript(gUnknown_0819F80B); ScriptContext2_Enable(); } u8 GetTrainerFlagFromScriptPointer(int a1) { u32 localFlag; localFlag = TrainerBattleLoadArg16(a1 + 2); return FlagGet(localFlag + 0x500); } void sub_8082524(void) { struct MapObject *mapObject = &gMapObjects[gSelectedMapObject]; npc_set_running_behaviour_etc(mapObject, npc_running_behaviour_by_direction(mapObject->mapobj_unk_18)); } u8 sub_8082558(void) { return gTrainerBattleMode; } u8 sub_8082564(void) { return FlagGet(trainerflag_opponent()); } void sub_808257C(void) { FlagSet(trainerflag_opponent()); } void unref_sub_8082590(void) { FlagSet(trainerflag_opponent()); // duplicate function } u8 trainer_flag_check(u16 flag) { return FlagGet(flag + 0x500); } void trainer_flag_set(u16 flag) { FlagSet(flag + 0x500); } void trainer_flag_clear(u16 flag) { FlagReset(flag + 0x500); } void sub_80825E4(void) { gUnknown_020239F8 = 8; gMain.field_8 = sub_808260C; task_add_01_battle_start_with_music_and_stats(); ScriptContext1_Stop(); } void sub_808260C(void) { if (gTrainerBattleOpponent == 1024) { SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); // link battle? } else if (battle_exit_is_player_defeat(gUnknown_02024D26) == 1) { SetMainCallback2(c2_whiteout); } else { SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); sub_808257C(); } } void do_choose_name_or_words_screen(void) { if (gTrainerBattleOpponent == 1024) { SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); // link battle? } else if (battle_exit_is_player_defeat(gUnknown_02024D26) == 1) { SetMainCallback2(c2_whiteout); } else { SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); sub_808257C(); sub_8082CB8(); } } void sub_80826B0(void) { gUnknown_020239F8 = 8; gMain.field_8 = do_choose_name_or_words_screen; task_add_01_battle_start_with_music_and_stats(); ScriptContext1_Stop(); } void sub_80826D8(void) { sub_808281C(); ShowFieldMessage(); } u32 sub_80826E8(void) { u32 *result = gTrainerBattleScriptReturnAddress; if (!gTrainerBattleScriptReturnAddress) return gUnknown_081C6C02; return result; } u32 sub_8082700(void) { u32 *result = gTrainerBattleEndScript; if (!gTrainerBattleEndScript) return gUnknown_081C6C02; return result; } void sub_8082718() { ShowFieldMessage(sub_8082880()); } void sub_8082728(void) // sets the music to be played after a battle { u16 music; if (gTrainerBattleMode != 1 && gTrainerBattleMode != 8) { switch (sub_803FC58(gTrainerBattleOpponent)) { // TODO: Replace with music constants. case 0: music = 380; break; case 1: music = 407; break; case 2: music = 379; break; case 4: music = 416; break; case 5: music = 417; break; case 6: music = 419; break; case 7: music = 441; break; case 8: music = 385; break; case 9: music = 449; break; case 10: music = 450; break; case 11: music = 451; break; case 12: music = 453; break; case 13: music = 397; break; default: music = 423; } PlayNewMapMusic(music); } } u32 ReturnEmptyStringIfNull(u32 *result) { if (result) return result; else return gOtherText_CancelWithTerminator; } u32 sub_808281C(void) { return ReturnEmptyStringIfNull(gTrainerIntroSpeech); } u8 *sub_8082830(void) { u32 *var; if (gTrainerBattleOpponent == 1024) var = sub_80BCCE8(); else var = gTrainerDefeatSpeech; StringExpandPlaceholders(gStringVar4, ReturnEmptyStringIfNull(var)); return gStringVar4; } u32 unref_sub_808286C(void) { return ReturnEmptyStringIfNull(gTrainerVictorySpeech); } u32 sub_8082880(void) { return ReturnEmptyStringIfNull(gTrainerCannotBattleSpeech); } s32 sub_8082894(u16 *ptr, u16 var) { s32 i; for(i = 0; i <= 55; i++) { if(ptr[i * 8] == var) return i; } return -1; } s32 sub_80828B8(struct TrainerEyeTrainer *a, u16 b) { s32 i; for(i = 0; i < 56; i++) { s32 j; for(j = 0; j < 5 && a[i].trainerNums[j] != 0; j++) { if(a[i].trainerNums[j] == b) return i; } } return -1; } u32 sub_80828FC(struct TrainerEyeTrainer *a, u16 b, u16 c) { s32 i; s32 ret = 0; for (i = 0; i < 56; i++) { if (a[i].mapGroup == b && a[i].mapNum == c) { if (gSaveBlock1.trainerRematches[i] != 0) { ret = 1; continue; } if (trainer_flag_check(a[i].trainerNums[0]) == TRUE && (Random() % 100) <= 30) { ret = 1; while(ret <= 4 && a[i].trainerNums[ret] != 0 && trainer_flag_check(a[i].trainerNums[ret])) ret++; gSaveBlock1.trainerRematches[i] = ret; ret = 1; } } } return ret; } s32 sub_80829A8(struct TrainerEyeTrainer *a1, u16 a2, u16 a3) { s32 i; for (i = 0; i < 56; i++) { if (a1[i].mapGroup == a2 && a1[i].mapNum == a3 && gSaveBlock1.trainerRematches[i]) return 1; } return 0; } s32 sub_80829E8(struct TrainerEyeTrainer *a1, u16 a2, u16 a3) { s32 i; for (i = 0; i < 56; i++) { if (a1[i].mapGroup == a2 && a1[i].mapNum == a3) return 1; } return 0; } bool8 sub_8082A18(u16 *a1, u16 a2) { s32 v2 = sub_8082894(a1, a2); if (v2 != -1 && v2 < 100 && gSaveBlock1.trainerRematches[v2]) return TRUE; else return FALSE; } bool8 sub_8082A54(u16 *a1, u16 a2) { s32 v2 = sub_80828B8(a1, a2); if (v2 != -1 && v2 < 100 && gSaveBlock1.trainerRematches[v2]) return TRUE; else return FALSE; } u16 sub_8082A90(struct TrainerEyeTrainer *trainers, u16 trainerNum) { int i; struct TrainerEyeTrainer *trainer; s32 trainerEyeIndex = sub_8082894(trainers, trainerNum); if (trainerEyeIndex == -1) return 0; trainer = &trainers[trainerEyeIndex]; for (i = 1; i < 5; i++) { if (!trainer->trainerNums[i]) return trainer->trainerNums[i - 1]; if (!trainer_flag_check(trainer->trainerNums[i])) return trainer->trainerNums[i]; } return trainer->trainerNums[4]; } void sub_8082AE4(u16 *a1, u16 a2) { s32 var = sub_80828B8(a1, a2); if (var != -1) gSaveBlock1.trainerRematches[var] = 0; } bool8 sub_8082B10(struct TrainerEyeTrainer *a1, u16 a2) { s32 var = sub_8082894(a1, a2); if (var != -1 && trainer_flag_check(a1[var].trainerNums[1])) return TRUE; else return FALSE; } bool32 sub_8082B44(void) { int badgeCount = 0; u32 i; for(i = 0; i < 8; i++) { if (FlagGet(gBadgeFlags[i]) == TRUE) { badgeCount++; if (badgeCount >= 5) return TRUE; } } return FALSE; } void sub_8082B78(void) { if (sub_8082B44()) { if (gSaveBlock1.trainerRematchStepCounter >= 255) gSaveBlock1.trainerRematchStepCounter = 255; else gSaveBlock1.trainerRematchStepCounter++; } } bool32 sub_8082BA4(void) { if (sub_8082B44() && gSaveBlock1.trainerRematchStepCounter >= 255) return TRUE; else return FALSE; } void sub_8082BD0(u16 a1, u16 a2) { if (sub_8082BA4() && sub_80828FC(gTrainerEyeTrainers, a1, a2) == 1) gSaveBlock1.trainerRematchStepCounter = 0; } s32 sub_8082C0C(u16 a1, u16 a2) { return sub_80829A8(gTrainerEyeTrainers, a1, a2); } s32 unref_sub_8082C2C(u16 a1, u16 a2) { return sub_80829E8(gTrainerEyeTrainers, a1, a2); } u16 sub_8082C4C(u16 a1) { return sub_8082A90(gTrainerEyeTrainers, a1); } s32 sub_8082C68(void) { if (sub_8082A18(gTrainerEyeTrainers, gTrainerBattleOpponent)) return 1; else return sub_8082B10(gTrainerEyeTrainers, gTrainerBattleOpponent); } u8 sub_8082C9C(void) { return sub_8082A54(gTrainerEyeTrainers, gTrainerBattleOpponent); } void sub_8082CB8(void) { sub_8082AE4(gTrainerEyeTrainers, gTrainerBattleOpponent); sub_808257C(); }