diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/apprentice.c | 14 | ||||
-rw-r--r-- | src/battle_dome.c | 24 | ||||
-rw-r--r-- | src/battle_main.c | 6 | ||||
-rw-r--r-- | src/battle_tent.c | 4 | ||||
-rw-r--r-- | src/battle_tower.c | 431 | ||||
-rw-r--r-- | src/field_specials.c | 84 | ||||
-rw-r--r-- | src/pokemon.c | 8 | ||||
-rw-r--r-- | src/record_mixing.c | 4 | ||||
-rw-r--r-- | src/tv.c | 4 |
9 files changed, 427 insertions, 152 deletions
diff --git a/src/apprentice.c b/src/apprentice.c index d45cff430..9e01a072a 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -344,7 +344,7 @@ extern struct Unk030062ECStruct *gUnknown_030062EC; extern struct Unk030062F0Struct *gUnknown_030062F0; extern void (*gUnknown_030062F4)(void); -extern void sub_8165AE8(struct Apprentice *); +extern void CalcApprenticeChecksum(struct Apprentice *); // This file's functions. static u16 sub_819FF98(u8 arg0); @@ -1087,7 +1087,7 @@ void ResetAllApprenticeData(void) for (j = 0; j < 4; j++) gSaveBlock2Ptr->apprentices[i].playerId[j] = 0; gSaveBlock2Ptr->apprentices[i].language = gGameLanguage; - gSaveBlock2Ptr->apprentices[i].unk40 = 0; + gSaveBlock2Ptr->apprentices[i].checksum = 0; } Script_ResetPlayerApprentice(); @@ -1430,16 +1430,16 @@ static void sub_81A0390(u8 arg0) for (i = 0; i < 3; i++) { - gSaveBlock2Ptr->apprentices[0].monData[i].species = 0; - gSaveBlock2Ptr->apprentices[0].monData[i].item = 0; + gSaveBlock2Ptr->apprentices[0].party[i].species = 0; + gSaveBlock2Ptr->apprentices[0].party[i].item = 0; for (j = 0; j < 4; j++) - gSaveBlock2Ptr->apprentices[0].monData[i].moves[j] = 0; + gSaveBlock2Ptr->apprentices[0].party[i].moves[j] = 0; } j = PLAYER_APPRENTICE.field_B1_2; for (i = 0; i < 3; i++) { - apprenticeMons[j] = &gSaveBlock2Ptr->apprentices[0].monData[i]; + apprenticeMons[j] = &gSaveBlock2Ptr->apprentices[0].party[i]; j = (j + 1) % 3; } @@ -2256,7 +2256,7 @@ static void sub_81A1438(void) StringCopy(gSaveBlock2Ptr->apprentices[0].playerName, gSaveBlock2Ptr->playerName); gSaveBlock2Ptr->apprentices[0].language = gGameLanguage; - sub_8165AE8(&gSaveBlock2Ptr->apprentices[0]); + CalcApprenticeChecksum(&gSaveBlock2Ptr->apprentices[0]); } static void sub_81A150C(void) diff --git a/src/battle_dome.c b/src/battle_dome.c index 6401530d7..6b32bf812 100644 --- a/src/battle_dome.c +++ b/src/battle_dome.c @@ -58,7 +58,7 @@ extern void sub_81B8558(void); extern u32 sub_81A39C4(void); extern u16 sub_8162548(u8, u8); extern u16 RandomizeFacilityTrainerMonId(u16); -extern u8 GetFacilityEnemyMonLevel(void); +extern u8 SetFacilityPtrsGetLevel(void); extern u16 sub_81A5060(u8 monId, u8 moveSlotId); extern u8 sub_81A50F0(u8, u8); extern u8 sub_81A50B0(u8); @@ -2595,13 +2595,13 @@ static void InitDomeTrainers(void) for (i = 0; i < 3; i++) { - gSaveBlock2Ptr->frontier.domeMonId[0][i] = GetMonData(&gPlayerParty[gSaveBlock2Ptr->frontier.field_CAA[i] - 1], MON_DATA_SPECIES, NULL); + gSaveBlock2Ptr->frontier.domeMonId[0][i] = GetMonData(&gPlayerParty[gSaveBlock2Ptr->frontier.selectedPartyMons[i] - 1], MON_DATA_SPECIES, NULL); for (j = 0; j < 4; j++) - gSaveBlock2Ptr->frontier.field_EFC[i].moves[j] = GetMonData(&gPlayerParty[gSaveBlock2Ptr->frontier.field_CAA[i] - 1], MON_DATA_MOVE1 + j, NULL); + gSaveBlock2Ptr->frontier.field_EFC[i].moves[j] = GetMonData(&gPlayerParty[gSaveBlock2Ptr->frontier.selectedPartyMons[i] - 1], MON_DATA_MOVE1 + j, NULL); for (j = 0; j < 6; j++) - gSaveBlock2Ptr->frontier.field_EFC[i].evs[j] = GetMonData(&gPlayerParty[gSaveBlock2Ptr->frontier.field_CAA[i] - 1], MON_DATA_HP_EV + j, NULL); + gSaveBlock2Ptr->frontier.field_EFC[i].evs[j] = GetMonData(&gPlayerParty[gSaveBlock2Ptr->frontier.selectedPartyMons[i] - 1], MON_DATA_HP_EV + j, NULL); - gSaveBlock2Ptr->frontier.field_EFC[i].nature = GetNature(&gPlayerParty[gSaveBlock2Ptr->frontier.field_CAA[i] - 1]); + gSaveBlock2Ptr->frontier.field_EFC[i].nature = GetNature(&gPlayerParty[gSaveBlock2Ptr->frontier.selectedPartyMons[i] - 1]); } for (i = 1; i < DOME_TOURNAMENT_TRAINERS_COUNT; i++) @@ -2663,7 +2663,7 @@ static void InitDomeTrainers(void) statSums[0] = 0; for (i = 0; i < 3; i++) { - trainerId = gSaveBlock2Ptr->frontier.field_CAA[i] - 1; // Great variable choice, gamefreak. + trainerId = gSaveBlock2Ptr->frontier.selectedPartyMons[i] - 1; // Great variable choice, gamefreak. statSums[0] += GetMonData(&gPlayerParty[trainerId], MON_DATA_ATK, NULL); statSums[0] += GetMonData(&gPlayerParty[trainerId], MON_DATA_DEF, NULL); statSums[0] += GetMonData(&gPlayerParty[trainerId], MON_DATA_SPATK, NULL); @@ -2681,7 +2681,7 @@ static void InitDomeTrainers(void) monTypesBits >>= 1; } - monLevel = GetFacilityEnemyMonLevel(); + monLevel = SetFacilityPtrsGetLevel(); statSums[0] += (monTypesCount * monLevel) / 20; for (i = 1; i < DOME_TOURNAMENT_TRAINERS_COUNT; i++) @@ -2847,7 +2847,7 @@ static void CreateDomeMon(u8 monPartyId, u16 tournamentTrainerId, u8 tournamentM s32 i; u8 happiness = 0xFF; u8 fixedIv = GetDomeTrainerMonIvs(tournamentTrainerId); // BUG: Should be using trainerId instead of tournamentTrainerId. As a result, all Pokemon have ivs of 3. - u8 level = GetFacilityEnemyMonLevel(); + u8 level = SetFacilityPtrsGetLevel(); CreateMonWithEVSpreadPersonalityOTID(&gEnemyParty[monPartyId], gFacilityTrainerMons[gSaveBlock2Ptr->frontier.domeMonId[tournamentTrainerId][tournamentMonId]].species, level, @@ -5575,7 +5575,7 @@ static u16 GetWinningMove(s32 winnerTournamentId, s32 loserTournamentId, u8 roun u16 bestScore = 0; u16 bestId = 0; s32 movePower = 0; - GetFacilityEnemyMonLevel(); // Unused return variable. + SetFacilityPtrsGetLevel(); // Unused return variable. // Calc move points of all 4 moves for all 3 pokemon hitting all 3 target mons. for (i = 0; i < 3; i++) @@ -6098,7 +6098,7 @@ static void sub_8194D68(void) for (i = 0; i < 2; i++) { - s32 playerMonId = gSaveBlock2Ptr->frontier.field_CAA[gUnknown_0203CEF8[i] - 1] - 1; + s32 playerMonId = gSaveBlock2Ptr->frontier.selectedPartyMons[gUnknown_0203CEF8[i] - 1] - 1; s32 count; for (moveSlot = 0; moveSlot < 4; moveSlot++) @@ -6124,7 +6124,7 @@ static void sub_8194E44(void) for (i = 0; i < 2; i++) { - s32 playerMonId = gSaveBlock2Ptr->frontier.field_CAA[gUnknown_0203CEF8[i] - 1] - 1; + s32 playerMonId = gSaveBlock2Ptr->frontier.selectedPartyMons[gUnknown_0203CEF8[i] - 1] - 1; u16 item = GetMonData(&gSaveBlock1Ptr->playerParty[playerMonId], MON_DATA_HELD_ITEM, NULL); SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &item); } @@ -6439,7 +6439,7 @@ static void DecideRoundWinners(u8 roundId) static void CopyDomeTrainerName(u8 *dst, u16 trainerId) { s32 i = 0; - GetFacilityEnemyMonLevel(); // Unused return value. + SetFacilityPtrsGetLevel(); // Unused return value. if (trainerId == TRAINER_FRONTIER_BRAIN) { diff --git a/src/battle_main.c b/src/battle_main.c index 80ee5c425..b3fcaeeda 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -108,7 +108,7 @@ extern const u8 gText_Love[]; // functions extern void GetFrontierTrainerName(u8* dst, u16 trainerId); // battle tower extern void sub_8166188(void); // battle tower, sets link battle mons level but why? -extern void sub_8165B88(u8* dst, u16 trainerId); // battle tower, gets language +extern void GetBattleTowerTrainerLanguage(u8* dst, u16 trainerId); // battle tower, gets language extern void sub_81B9150(void); extern void sub_80B3AF8(u8 taskId); // cable club extern void sub_81A56B4(void); // battle frontier 2 @@ -1159,9 +1159,9 @@ static void CB2_HandleStartMultiPartnerBattle(void) gLinkPlayers[3].id = 3; GetFrontierTrainerName(gLinkPlayers[2].name, gTrainerBattleOpponent_A); GetFrontierTrainerName(gLinkPlayers[3].name, gTrainerBattleOpponent_B); - sub_8165B88(&language, gTrainerBattleOpponent_A); + GetBattleTowerTrainerLanguage(&language, gTrainerBattleOpponent_A); gLinkPlayers[2].language = language; - sub_8165B88(&language, gTrainerBattleOpponent_B); + GetBattleTowerTrainerLanguage(&language, gTrainerBattleOpponent_B); gLinkPlayers[3].language = language; if (sub_800A520()) diff --git a/src/battle_tent.c b/src/battle_tent.c index 4ad045043..4c4bd7fc3 100644 --- a/src/battle_tent.c +++ b/src/battle_tent.c @@ -553,7 +553,7 @@ static void sub_81BA040(void) trainerId = Random() % 30; for (i = 0; i < gSaveBlock2Ptr->frontier.curChallengeBattleNum; i++) { - if (gSaveBlock2Ptr->frontier.battledTrainerIds[i] == trainerId) + if (gSaveBlock2Ptr->frontier.field_CB4[i] == trainerId) break; } } while (i != gSaveBlock2Ptr->frontier.curChallengeBattleNum); @@ -567,7 +567,7 @@ static void sub_81BA040(void) } if (gSaveBlock2Ptr->frontier.curChallengeBattleNum < 2) - gSaveBlock2Ptr->frontier.battledTrainerIds[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = gTrainerBattleOpponent_A; + gSaveBlock2Ptr->frontier.field_CB4[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = gTrainerBattleOpponent_A; monSetsPool = gFacilityTrainers[gTrainerBattleOpponent_A].bfMonPool; i = 0; diff --git a/src/battle_tower.c b/src/battle_tower.c index 25a46d073..cefb02c8d 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -26,12 +26,13 @@ #include "constants/trainers.h" #include "constants/event_objects.h" #include "constants/moves.h" +#include "constants/species.h" extern void sub_81A3ACC(void); extern void CreateFrontierBrainPokemon(void); extern void sub_81A6CD0(void); extern u8 GetFrontierEnemyMonLevel(u8); -extern u8 GetFacilityEnemyMonLevel(void); +extern u8 SetFacilityPtrsGetLevel(void); extern u16 sub_81A39C4(void); extern void SetFrontierBrainTrainerGfxId(void); extern u8 GetFrontierBrainTrainerPicIndex(void); @@ -50,19 +51,19 @@ extern const u16 gBattleFrontierHeldItems[]; // This file's functions. void ValidateBattleTowerRecordChecksums(void); void SaveCurrentWinStreak(void); -void sub_8165B20(void); +void ValidateApprenticesChecksums(void); void sub_8165E18(void); void CopyEReaderTrainerFarewellMessage(void); void ClearBattleTowerRecord(struct EmeraldBattleTowerRecord *record); u16 GetCurrentBattleTowerWinStreak(u8 lvlMode, u8 battleMode); u16 sub_8162548(u8, u8); static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount); -void sub_8165EA4(u16 trainerId, u8 firstMonId, u8 monCount); +void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount); void sub_81635D4(u16 trainerId, u8 firstMonId); void sub_816379C(u16 trainerId, u8 firstMonId); u8 GetFrontierTrainerFixedIvs(u16 trainerId); -void sub_8165404(u16 trainerId); -void sub_8165B88(u8 *dst, u16 trainerId); +void FillPartnerParty(u16 trainerId); +void GetBattleTowerTrainerLanguage(u8 *dst, u16 trainerId); void SetEReaderTrainerChecksum(struct BattleTowerEReaderTrainer *ereaderTrainer); void ClearEReaderTrainer(struct BattleTowerEReaderTrainer *ereaderTrainer); @@ -192,7 +193,7 @@ bool8 ChooseSpecialBattleTowerTrainer(void) if (battleMode == FRONTIER_MODE_SINGLES) { - sub_8165B20(); + ValidateApprenticesChecksums(); for (i = 0; i < 4; i++) { if (gSaveBlock2Ptr->apprentices[i].lvlMode != 0 @@ -228,7 +229,7 @@ void ChooseNextBattleTowerTrainer(void) u16 id; u32 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); u32 r5 = sub_81A39C4() / 7; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (battleMode == FRONTIER_MODE_MULTIS || battleMode == FRONTIER_MODE_LINK_MULTIS) { @@ -384,7 +385,7 @@ void SetBattleFacilityTrainerGfxId(u16 trainerId, u8 tempVarId) u8 facilityClass; u8 trainerObjectGfxId; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; @@ -481,7 +482,7 @@ u8 GetBattleFacilityTrainerGfxId(u16 trainerId) u8 facilityClass; u8 trainerObjectGfxId; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; @@ -618,7 +619,7 @@ void PutNewBattleTowerRecord(struct EmeraldBattleTowerRecord *newRecordEm) u8 GetFrontierTrainerFrontSpriteId(u16 trainerId) { - GetFacilityEnemyMonLevel(); // Pointless function call + SetFacilityPtrsGetLevel(); // Pointless function call if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { @@ -651,7 +652,7 @@ u8 GetFrontierTrainerFrontSpriteId(u16 trainerId) u8 GetFrontierOpponentClass(u16 trainerId) { u8 trainerClass = 0; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { @@ -700,7 +701,7 @@ u8 GetFrontierOpponentClass(u16 trainerId) u8 GetFrontierTrainerFacilityClass(u16 trainerId) { u8 facilityClass; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { @@ -731,7 +732,7 @@ u8 GetFrontierTrainerFacilityClass(u16 trainerId) void GetFrontierTrainerName(u8 *dst, u16 trainerId) { s32 i = 0; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { @@ -794,7 +795,7 @@ bool8 IsFrontierTrainerFemale(u16 trainerId) u32 i; u8 facilityClass; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) { facilityClass = gSaveBlock2Ptr->frontier.ereaderTrainer.facilityClass; @@ -841,10 +842,10 @@ void FillFrontierTrainersParties(u8 monsCount) FillTrainerParty(gTrainerBattleOpponent_B, 3, monsCount); } -void sub_81630A0(u8 monsCount) +void FillTentTrainerParty(u8 monsCount) { ZeroEnemyPartyMons(); - sub_8165EA4(gTrainerBattleOpponent_A, 0, monsCount); + FillTentTrainerParty_(gTrainerBattleOpponent_A, 0, monsCount); } static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) @@ -852,7 +853,7 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) s32 i, j; u16 chosenMonIndices[4]; u8 friendship = 0xFF; - u8 level = GetFacilityEnemyMonLevel(); + u8 level = SetFacilityPtrsGetLevel(); u8 fixedIV = 0; u8 bfMonCount; const u16 *bfMonPool = NULL; @@ -1003,27 +1004,15 @@ void Unused_CreateApprenticeMons(u16 trainerId, u8 firstMonId) u16 RandomizeFacilityTrainerMonId(u16 trainerId) { - u32 monPoolId; - u8 level = GetFacilityEnemyMonLevel(); + u8 level = SetFacilityPtrsGetLevel(); const u16 *bfMonPool = gFacilityTrainers[trainerId].bfMonPool; u8 bfMonCount = 0; + u32 monPoolId = bfMonPool[bfMonCount]; - /* - I had to use ugly C tricks to get this part to match. - A cleaner version would look like this - - for (bfMonCount = 0; bfMonPool[bfMonCount] != 0xFFFF; bfMonCount++) - ; - - */ - - monPoolId = bfMonPool[bfMonCount]; - goto COMPARE; - while (1) + while (monPoolId != 0xFFFF) { bfMonCount++; monPoolId = bfMonPool[bfMonCount]; - COMPARE: if (monPoolId == 0xFFFF) break; } @@ -1082,7 +1071,7 @@ void sub_81635D4(u16 trainerId, u8 firstMonId) } - level = GetFacilityEnemyMonLevel(); + level = SetFacilityPtrsGetLevel(); otID = T1_READ_32(gSaveBlock2Ptr->playerTrainerId); for (i = 0; i < 3; i++) { @@ -1156,7 +1145,7 @@ void FrontierSpeechToString(const u16 *words) void sub_8163914(void) { u16 trainerId; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (gSpecialVar_0x8005) trainerId = gTrainerBattleOpponent_B; @@ -1248,7 +1237,7 @@ void DoSpecialTrainerBattle(void) case FRONTIER_MODE_MULTIS: FillFrontierTrainersParties(2); gPartnerTrainerId = gSaveBlock2Ptr->frontier.field_CB4[17]; - sub_8165404(gPartnerTrainerId); + FillPartnerParty(gPartnerTrainerId); gBattleTypeFlags |= BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS; break; case FRONTIER_MODE_LINK_MULTIS: @@ -1297,7 +1286,7 @@ void DoSpecialTrainerBattle(void) if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT) FillFrontierTrainerParty(3); else - sub_81630A0(3); + FillTentTrainerParty(3); CreateTask(Task_StartBattleAfterTransition, 1); PlayMapChosenOrBattleBGM(0); BattleTransition_StartOnField(sub_80B100C(4)); @@ -1307,7 +1296,7 @@ void DoSpecialTrainerBattle(void) if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_TENT) FillFrontierTrainerParty(3); else - sub_81630A0(3); + FillTentTrainerParty(3); CreateTask(Task_StartBattleAfterTransition, 1); PlayMapChosenOrBattleBGM(0); BattleTransition_StartOnField(sub_80B100C(5)); @@ -1344,7 +1333,7 @@ void DoSpecialTrainerBattle(void) break; case SPECIAL_BATTLE_STEVEN: gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER; - sub_8165404(TRAINER_STEVEN_PARTNER); + FillPartnerParty(TRAINER_STEVEN_PARTNER); gApproachingTrainerId = 0; BattleSetup_ConfigureTrainerBattle(MossdeepCity_SpaceCenter_2F_EventScript_224157 + 1); gApproachingTrainerId = 1; @@ -1511,7 +1500,7 @@ void sub_81642A0(void) challengeNum = gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode] / 7; species1 = GetMonData(&gPlayerParty[0], MON_DATA_SPECIES, NULL); species2 = GetMonData(&gPlayerParty[1], MON_DATA_SPECIES, NULL); - level = GetFacilityEnemyMonLevel(); + level = SetFacilityPtrsGetLevel(); j = 0; do @@ -1563,7 +1552,7 @@ void sub_81642A0(void) } r10 = 0; - sub_8165B20(); + ValidateApprenticesChecksums(); for (i = 0; i < 4; i++) { if (gSaveBlock2Ptr->apprentices[i].lvlMode != 0 @@ -1642,7 +1631,7 @@ void sub_81646BC(u16 trainerId, u16 monPoolId) { u16 move = 0; u16 species = 0; - GetFacilityEnemyMonLevel(); // Pointless function call. + SetFacilityPtrsGetLevel(); if (trainerId != BATTLE_TOWER_EREADER_TRAINER_ID) { @@ -1686,7 +1675,7 @@ void sub_8164828(void) { s32 i, j, arrId; s32 monPoolId; - s32 level = GetFacilityEnemyMonLevel(); // Unused variable. + s32 level = SetFacilityPtrsGetLevel(); s32 challengeNum = sub_81A39C4() / 7; s32 k = gSpecialVar_LastTalked - 2; s32 trainerId = gSaveBlock2Ptr->frontier.field_CB4[k]; @@ -1899,7 +1888,7 @@ void sub_8164E04(void) GetFrontierTrainerName(text, gTrainerBattleOpponent_A); StripExtCtrlCodes(text); StringCopy(gSaveBlock2Ptr->frontier.field_BD8, text); - sub_8165B88(&gSaveBlock2Ptr->frontier.field_BEB, gTrainerBattleOpponent_A); + GetBattleTowerTrainerLanguage(&gSaveBlock2Ptr->frontier.field_BEB, gTrainerBattleOpponent_A); gSaveBlock2Ptr->frontier.field_BD6 = GetMonData(&gEnemyParty[gBattlerPartyIndexes[1]], MON_DATA_SPECIES, NULL); gSaveBlock2Ptr->frontier.field_BD4 = GetMonData(&gPlayerParty[gBattlerPartyIndexes[0]], MON_DATA_SPECIES, NULL); for (i = 0; i < POKEMON_NAME_LENGTH + 1; i++) @@ -2184,7 +2173,7 @@ extern const struct StevenMon sStevenMons[3]; #define STEVEN_OTID 61226 -void sub_8165404(u16 trainerId) +void FillPartnerParty(u16 trainerId) { s32 i, j; u32 ivs, level; @@ -2192,7 +2181,7 @@ void sub_8165404(u16 trainerId) u16 monPoolId; u32 otID; u8 trainerName[PLAYER_NAME_LENGTH + 1]; - GetFacilityEnemyMonLevel(); // Unused return variable. + SetFacilityPtrsGetLevel(); if (trainerId == TRAINER_STEVEN_PARTNER) { @@ -2225,7 +2214,7 @@ void sub_8165404(u16 trainerId) } else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) { - level = GetFacilityEnemyMonLevel(); + level = SetFacilityPtrsGetLevel(); ivs = GetFrontierTrainerFixedIvs(trainerId); otID = Random32(); for (i = 0; i < 2; i++) @@ -2344,3 +2333,353 @@ bool32 RubyBattleTowerRecordToEmerald(struct RSBattleTowerRecord *src, struct Em return TRUE; } } + +bool32 EmeraldBattleTowerRecordToRuby(struct EmeraldBattleTowerRecord *src, struct RSBattleTowerRecord *dst) +{ + s32 i, validMons = 0; + + for (i = 0; i < 3; i++) + { + if (src->party[i].species) + validMons++; + } + + if (validMons != 3) + { + memset(dst, 0, sizeof(*dst)); + return FALSE; + } + else + { + dst->lvlMode = src->lvlMode; + dst->winStreak = src->winStreak; + for (i = 0; i < (signed) ARRAY_COUNT(sRubyFacilityClassToEmerald); i++) + { + if (sRubyFacilityClassToEmerald[i][1] == src->facilityClass) + break; + } + if (i != ARRAY_COUNT(sRubyFacilityClassToEmerald)) + dst->facilityClass = sRubyFacilityClassToEmerald[i][0]; + else + dst->facilityClass = 0x24; // FACILITY_CLASS_YOUNGSTER in Ruby/Sapphire. + + for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++) + dst->name[i] = src->name[i]; + for (i = 0; i < 4; i++) + dst->trainerId[i] = src->trainerId[i]; + for (i = 0; i < 6; i++) + dst->greeting[i] = src->greeting[i]; + for (i = 0; i < 3; i++) + dst->party[i] = src->party[i]; + + CalcRubyBattleTowerChecksum(dst); + return TRUE; + } +} + +void CalcApprenticeChecksum(struct Apprentice *apprentice) +{ + s32 i; + + apprentice->checksum = 0; + for (i = 0; i < (sizeof(struct Apprentice) - 4) / 4; i++) + apprentice->checksum += ((u32 *)apprentice)[i]; +} + +void ClearApprentice(struct Apprentice *apprentice) +{ + s32 i; + + for (i = 0; i < (sizeof(struct Apprentice)) / 4; i++) + ((u32 *)apprentice)[i] = 0; + ResetApprenticeStruct(apprentice); +} + +void ValidateApprenticesChecksums(void) +{ + s32 i, j; + + for (i = 0; i < 4; i++) + { + u32 *data = (u32*) &gSaveBlock2Ptr->apprentices[i]; + u32 checksum = 0; + for (j = 0; j < (sizeof(struct Apprentice) - 4) / 4; j++) + checksum += data[j]; + if (gSaveBlock2Ptr->apprentices[i].checksum != checksum) + ClearApprentice(&gSaveBlock2Ptr->apprentices[i]); + } +} + +void GetBattleTowerTrainerLanguage(u8 *dst, u16 trainerId) +{ + if (trainerId == BATTLE_TOWER_EREADER_TRAINER_ID) + { + *dst = gGameLanguage; + } + else if (trainerId < BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID) + { + *dst = gGameLanguage; + } + else if (trainerId < BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID) + { + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + *dst = sub_81864B4(); + else + *dst = gSaveBlock2Ptr->frontier.towerRecords[trainerId - BATTLE_TOWER_RECORD_MIXING_TRAINER_BASE_ID].language; + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + *dst = sub_81864C0(); + else + *dst = gSaveBlock2Ptr->apprentices[trainerId - BATTLE_TOWER_RECORD_APPRENTICE_BASE_ID].language; + } +} + +extern const struct FacilityMon gBattleFrontierMons[]; +extern const struct FacilityMon gSlateportBattleTentMons[]; +extern const struct FacilityMon gVerdanturfBattleTentMons[]; +extern const struct FacilityMon gFallarborBattleTentMons[]; + +extern const struct BattleFrontierTrainer gBattleFrontierTrainers[]; +extern const struct BattleFrontierTrainer gSlateportBattleTentTrainers[]; +extern const struct BattleFrontierTrainer gVerdanturfBattleTentTrainers[]; +extern const struct BattleFrontierTrainer gFallarborBattleTentTrainers[]; + +u8 SetTentPtrsGetLevel(void); +s32 GetHighestLevelInPlayerParty(void); + +u8 SetFacilityPtrsGetLevel(void) +{ + if (gSaveBlock2Ptr->frontier.lvlMode == FRONTIER_LVL_TENT) + { + return SetTentPtrsGetLevel(); + } + else + { + gFacilityTrainers = gBattleFrontierTrainers; + gFacilityTrainerMons = gBattleFrontierMons; + return GetFrontierEnemyMonLevel(gSaveBlock2Ptr->frontier.lvlMode); + } +} + +u8 GetFrontierEnemyMonLevel(u8 lvlMode) +{ + u8 level; + + switch (lvlMode) + { + default: + case FRONTIER_LVL_50: + level = 50; + break; + case FRONTIER_LVL_OPEN: + level = GetHighestLevelInPlayerParty(); + if (level < 60) + level = 60; + break; + } + + return level; +} + +s32 GetHighestLevelInPlayerParty(void) +{ + s32 highestLevel = 0; + s32 i; + + for (i = 0; i < PARTY_SIZE; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) + && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_EGG) + { + s32 level = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL, NULL); + if (level > highestLevel) + highestLevel = level; + } + } + + return highestLevel; +} + +u8 GetFrontierTrainerFixedIvs(u16 trainerId) +{ + u8 fixedIV = 0; + + if (trainerId < 100) + fixedIV = 3; + else if (trainerId < 120) + fixedIV = 6; + else if (trainerId < 140) + fixedIV = 9; + else if (trainerId < 160) + fixedIV = 12; + else if (trainerId < 180) + fixedIV = 15; + else if (trainerId < 200) + fixedIV = 18; + else if (trainerId < 220) + fixedIV = 21; + else + fixedIV = 31; + + return fixedIV; +} + +u16 sub_8165D40(void) +{ + u32 facility = VarGet(VAR_FRONTIER_FACILITY); + + if (facility == FRONTIER_FACILITY_PALACE) + return Random() % 30; + else if (facility == FRONTIER_FACILITY_ARENA) + return Random() % 30; + else if (facility == FRONTIER_FACILITY_FACTORY) + return Random() % 30; + else if (facility == FRONTIER_FACILITY_TOWER) + return 0; + else + return 0; +} + +u8 SetTentPtrsGetLevel(void) +{ + u8 level = 30; + u32 tentFacility = VarGet(VAR_FRONTIER_FACILITY); + + if (tentFacility == TENT_SLATEPORT) + { + gFacilityTrainers = gSlateportBattleTentTrainers; + gFacilityTrainerMons = gSlateportBattleTentMons; + } + else if (tentFacility == TENT_VERDANTURF) + { + gFacilityTrainers = gVerdanturfBattleTentTrainers; + gFacilityTrainerMons = gVerdanturfBattleTentMons; + } + else if (tentFacility == TENT_FALLARBOR) + { + gFacilityTrainers = gFallarborBattleTentTrainers; + gFacilityTrainerMons = gFallarborBattleTentMons; + } + else + { + gFacilityTrainers = gBattleFrontierTrainers; + gFacilityTrainerMons = gBattleFrontierMons; + } + + level = GetHighestLevelInPlayerParty(); + if (level < 30) + level = 30; + + return level; +} + +void sub_8165E18(void) +{ + s32 i; + u16 trainerId; + + do + { + trainerId = sub_8165D40(); + for (i = 0; i < gSaveBlock2Ptr->frontier.curChallengeBattleNum; i++) + { + if (gSaveBlock2Ptr->frontier.field_CB4[i] == trainerId) + break; + } + } while (i != gSaveBlock2Ptr->frontier.curChallengeBattleNum); + + gTrainerBattleOpponent_A = trainerId; + SetBattleFacilityTrainerGfxId(gTrainerBattleOpponent_A, 0); + if (gSaveBlock2Ptr->frontier.curChallengeBattleNum + 1 < 3) + gSaveBlock2Ptr->frontier.field_CB4[gSaveBlock2Ptr->frontier.curChallengeBattleNum] = gTrainerBattleOpponent_A; +} + +void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount) +{ + s32 i, j; + u16 chosenMonIndices[4]; + u8 friendship; + u8 level = SetTentPtrsGetLevel(); + u8 fixedIV = 0; + u8 bfMonCount; + const u16 *bfMonPool = NULL; + u32 otID = 0; + u16 monPoolId; + + bfMonPool = gFacilityTrainers[gTrainerBattleOpponent_A].bfMonPool; + + bfMonCount = 0; + monPoolId = bfMonPool[bfMonCount]; + while (monPoolId != 0xFFFF) + { + bfMonCount++; + monPoolId = bfMonPool[bfMonCount]; + if (monPoolId == 0xFFFF) + break; + } + + i = 0; + otID = Random32(); + while (i != monCount) + { + u16 monPoolId = bfMonPool[Random() % bfMonCount]; + + // Ensure this pokemon species isn't a duplicate. + for (j = 0; j < i + firstMonId; j++) + { + if (GetMonData(&gEnemyParty[j], MON_DATA_SPECIES, NULL) == gFacilityTrainerMons[monPoolId].species) + break; + } + if (j != i + firstMonId) + continue; + + // Ensure this Pokemon's held item isn't a duplicate. + for (j = 0; j < i + firstMonId; j++) + { + if (GetMonData(&gEnemyParty[j], MON_DATA_HELD_ITEM, NULL) != 0 + && GetMonData(&gEnemyParty[j], MON_DATA_HELD_ITEM, NULL) == gBattleFrontierHeldItems[gFacilityTrainerMons[monPoolId].itemTableId]) + break; + } + if (j != i + firstMonId) + continue; + + // Ensure this exact pokemon index isn't a duplicate. This check doesn't seem necessary + // because the species and held items were already checked directly above. + for (j = 0; j < i; j++) + { + if (chosenMonIndices[j] == monPoolId) + break; + } + if (j != i) + continue; + + chosenMonIndices[i] = monPoolId; + + // Place the chosen pokemon into the trainer's party. + CreateMonWithEVSpreadPersonalityOTID(&gEnemyParty[i + firstMonId], + gFacilityTrainerMons[monPoolId].species, + level, + gFacilityTrainerMons[monPoolId].nature, + fixedIV, + gFacilityTrainerMons[monPoolId].evSpread, + otID); + + friendship = 255; + // Give the chosen pokemon its specified moves. + for (j = 0; j < 4; j++) + { + SetMonMoveSlot(&gEnemyParty[i + firstMonId], gFacilityTrainerMons[monPoolId].moves[j], j); + if (gFacilityTrainerMons[monPoolId].moves[j] == MOVE_FRUSTRATION) + friendship = 0; // Frustration is more powerful the lower the pokemon's friendship is. + } + + SetMonData(&gEnemyParty[i + firstMonId], MON_DATA_FRIENDSHIP, &friendship); + SetMonData(&gEnemyParty[i + firstMonId], MON_DATA_HELD_ITEM, &gBattleFrontierHeldItems[gFacilityTrainerMons[monPoolId].itemTableId]); + + // The pokemon was successfully added to the trainer's party, so it's safe to move on to + // the next party slot. + i++; + } +} diff --git a/src/field_specials.c b/src/field_specials.c index a74bf40f6..a3308f872 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -2158,13 +2158,13 @@ void sub_8139F20(void) case 1: case 2: case 3: - if (gSaveBlock2Ptr->frontier.field_CE0[var][0] >= gSaveBlock2Ptr->frontier.field_CE0[var][1]) + if (gSaveBlock2Ptr->frontier.winStreaks[var][0] >= gSaveBlock2Ptr->frontier.winStreaks[var][1]) { - unk = gSaveBlock2Ptr->frontier.field_CE0[var][0]; + unk = gSaveBlock2Ptr->frontier.winStreaks[var][0]; } else { - unk = gSaveBlock2Ptr->frontier.field_CE0[var][1]; + unk = gSaveBlock2Ptr->frontier.winStreaks[var][1]; } break; case 4: @@ -2244,7 +2244,7 @@ void sub_813A080(void) u16 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); u8 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; - if (battleMode == 2 && !FlagGet(FLAG_0x152)) + if (battleMode == FRONTIER_MODE_MULTIS && !FlagGet(FLAG_0x152)) { gSpecialVar_0x8005 = 5; gSpecialVar_0x8006 = 4; @@ -2253,7 +2253,7 @@ void sub_813A080(void) for (i = 0; i < 9; i++) { - if (gUnknown_085B2CDC[i] > gSaveBlock2Ptr->frontier.field_CE0[battleMode][lvlMode]) + if (gUnknown_085B2CDC[i] > gSaveBlock2Ptr->frontier.winStreaks[battleMode][lvlMode]) { gSpecialVar_0x8005 = 4; gSpecialVar_0x8006 = i + 5; @@ -2733,8 +2733,6 @@ static void sub_813A46C(s32 itemIndex, bool8 onInit, struct ListMenu *list) } } -// stupid r5<->r6 swap -#ifdef NONMATCHING static void sub_813A4EC(u8 taskId) { struct Task *task = &gTasks[taskId]; @@ -2752,7 +2750,11 @@ static void sub_813A4EC(u8 taskId) default: gSpecialVar_Result = itemId; PlaySE(SE_SELECT); - if (!task->data[6] || itemId == task->data[1] - 1) + if (!task->data[6]) + { + sub_813A570(taskId); + } + else if (itemId == task->data[1] - 1) { sub_813A570(taskId); } @@ -2765,72 +2767,6 @@ static void sub_813A4EC(u8 taskId) break; } } -#else -NAKED -static void sub_813A4EC(u8 taskId) -{ - asm_unified("push {r4-r6,lr}\n\ - lsls r0, 24\n\ - lsrs r5, r0, 24\n\ - lsls r0, r5, 2\n\ - adds r0, r5\n\ - lsls r0, 3\n\ - ldr r1, =gTasks\n\ - adds r6, r0, r1\n\ - ldrh r0, [r6, 0x24]\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - bl ListMenuHandleInputGetItemId\n\ - adds r4, r0, 0\n\ - movs r0, 0x2\n\ - negs r0, r0\n\ - cmp r4, r0\n\ - beq _0813A51C\n\ - adds r0, 0x1\n\ - cmp r4, r0\n\ - bne _0813A530\n\ - b _0813A566\n\ - .pool\n\ -_0813A51C:\n\ - ldr r1, =gSpecialVar_Result\n\ - movs r0, 0x7F\n\ - strh r0, [r1]\n\ - movs r0, 0x5\n\ - bl PlaySE\n\ - b _0813A54C\n\ - .pool\n\ -_0813A530:\n\ - ldr r0, =gSpecialVar_Result\n\ - strh r4, [r0]\n\ - movs r0, 0x5\n\ - bl PlaySE\n\ - movs r1, 0x14\n\ - ldrsh r0, [r6, r1]\n\ - cmp r0, 0\n\ - beq _0813A54C\n\ - movs r1, 0xA\n\ - ldrsh r0, [r6, r1]\n\ - subs r0, 0x1\n\ - cmp r4, r0\n\ - bne _0813A558\n\ -_0813A54C:\n\ - adds r0, r5, 0\n\ - bl sub_813A570\n\ - b _0813A566\n\ - .pool\n\ -_0813A558:\n\ - adds r0, r5, 0\n\ - bl sub_813A738\n\ - ldr r0, =sub_813A600\n\ - str r0, [r6]\n\ - bl EnableBothScriptContexts\n\ -_0813A566:\n\ - pop {r4-r6}\n\ - pop {r0}\n\ - bx r0\n\ - .pool"); -} -#endif // NONMATCHING static void sub_813A570(u8 taskId) { diff --git a/src/pokemon.c b/src/pokemon.c index 7227d28cb..e29aab75b 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -2879,10 +2879,10 @@ void CreateApprenticeMon(struct Pokemon *mon, const struct Apprentice *src, u8 m u8 language; u32 otId = gApprentices[src->id].otId; u32 personality = ((gApprentices[src->id].otId >> 8) | ((gApprentices[src->id].otId & 0xFF) << 8)) - + src->monData[monId].species + src->number; + + src->party[monId].species + src->number; CreateMon(mon, - src->monData[monId].species, + src->party[monId].species, GetFrontierEnemyMonLevel(src->lvlMode - 1), 0x1F, TRUE, @@ -2890,9 +2890,9 @@ void CreateApprenticeMon(struct Pokemon *mon, const struct Apprentice *src, u8 m TRUE, otId); - SetMonData(mon, MON_DATA_HELD_ITEM, &src->monData[monId].item); + SetMonData(mon, MON_DATA_HELD_ITEM, &src->party[monId].item); for (i = 0; i < 4; i++) - SetMonMoveSlot(mon, src->monData[monId].moves[i], i); + SetMonMoveSlot(mon, src->party[monId].moves[i], i); evAmount = MAX_TOTAL_EVS / NUM_STATS; for (i = 0; i < NUM_STATS; i++) diff --git a/src/record_mixing.c b/src/record_mixing.c index 11c3f2fef..4bb97cf1d 100644 --- a/src/record_mixing.c +++ b/src/record_mixing.c @@ -213,7 +213,7 @@ static void PrepareUnknownExchangePacket(struct PlayerRecordsRS *dest) memcpy(&dest->oldMan, sOldManSave, sizeof(dest->oldMan)); memcpy(dest->easyChatPairs, sEasyChatPairsSave, sizeof(dest->easyChatPairs)); sub_80E89F8(&dest->dayCareMail); - sub_81659DC(sBattleTowerSave, &dest->battleTowerRecord); + EmeraldBattleTowerRecordToRuby(sBattleTowerSave, &dest->battleTowerRecord); if (GetMultiplayerId() == 0) dest->giftItem = GetRecordMixingGift(); @@ -231,7 +231,7 @@ static void PrepareExchangePacketForRubySapphire(struct PlayerRecordsRS *dest) memcpy(dest->easyChatPairs, sEasyChatPairsSave, sizeof(dest->easyChatPairs)); sub_80E89F8(&dest->dayCareMail); SanitizeDayCareMailForRuby(&dest->dayCareMail); - sub_81659DC(sBattleTowerSave, &dest->battleTowerRecord); + EmeraldBattleTowerRecordToRuby(sBattleTowerSave, &dest->battleTowerRecord); SanitizeRubyBattleTowerRecord(&dest->battleTowerRecord); if (GetMultiplayerId() == 0) @@ -2540,8 +2540,8 @@ void sub_80EE8C8(u16 winStreak, u8 facility) show->frontier.species2 = GetMonData(&gPlayerParty[1], MON_DATA_SPECIES, NULL); break; case 4: - show->frontier.species1 = GetMonData(&gSaveBlock1Ptr->playerParty[gSaveBlock2Ptr->frontier.field_CAA[0] - 1], MON_DATA_SPECIES, NULL); - show->frontier.species2 = GetMonData(&gSaveBlock1Ptr->playerParty[gSaveBlock2Ptr->frontier.field_CAA[1] - 1], MON_DATA_SPECIES, NULL); + show->frontier.species1 = GetMonData(&gSaveBlock1Ptr->playerParty[gSaveBlock2Ptr->frontier.selectedPartyMons[0] - 1], MON_DATA_SPECIES, NULL); + show->frontier.species2 = GetMonData(&gSaveBlock1Ptr->playerParty[gSaveBlock2Ptr->frontier.selectedPartyMons[1] - 1], MON_DATA_SPECIES, NULL); break; } tv_store_id_3x(show); |