diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/battle_tower.c | 470 | ||||
-rw-r--r-- | src/engine/trainer_card.c | 2 | ||||
-rw-r--r-- | src/field/easy_chat.c | 10 | ||||
-rw-r--r-- | src/field/tv.c | 2 |
4 files changed, 473 insertions, 11 deletions
diff --git a/src/battle_tower.c b/src/battle_tower.c index 519a6f71e..2513322cc 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -6,13 +6,17 @@ #include "data2.h" #include "easy_chat.h" #include "event_data.h" +#include "item.h" #include "items.h" #include "main.h" #include "map_object_constants.h" #include "moves.h" +#include "new_game.h" #include "overworld.h" #include "pokedex.h" #include "rng.h" +#include "save.h" +#include "script_pokemon_80C4.h" #include "species.h" #include "string_util.h" #include "task.h" @@ -217,7 +221,8 @@ const u16 gBattleTowerBanlist[] = { 0xFFFF, }; -const u16 gUnknown_08405EDA[] = { +// Item prizes for battle tower streaks of 5 or fewer sets. +const u16 ShortStreakPrizes[] = { ITEM_HP_UP, ITEM_PROTEIN, ITEM_IRON, @@ -226,7 +231,8 @@ const u16 gUnknown_08405EDA[] = { ITEM_ZINC, }; -const u16 gUnknown_08405EE6[] = { +// Item prizes for battle tower streaks of greater than 5 sets. +const u16 LongStreakPrizes[] = { ITEM_BRIGHT_POWDER, ITEM_WHITE_HERB, ITEM_QUICK_CLAW, @@ -250,12 +256,18 @@ extern u8 gTrainerClassToNameIndex[]; extern u16 gTrainerBattleOpponent; extern u16 gBattleTypeFlags; extern u8 gSelectedOrderFromParty[]; +extern struct Pokemon gUnknown_030042FC[]; +extern u8 gBattleOutcome; +extern struct BattlePokemon gBattleMons[]; -extern void sub_8135C44(void); +extern void ValidateBattleTowerRecordChecksums(void); extern void sub_813601C(void); extern void sub_81349FC(u8); extern void sub_81360AC(struct BattleTowerEReaderTrainer *); extern void sub_8135A3C(void); +extern void sub_8135CFC(void); +static void SetBattleTowerRecordChecksum(struct BattleTowerRecord *); +static void ClearBattleTowerRecord(struct BattleTowerRecord *); #define ewram160FB (ewram[0x160FB]) @@ -306,7 +318,7 @@ void sub_8134548(void) VarSet(VAR_0x4000, 5); } - sub_8135C44(); + ValidateBattleTowerRecordChecksums(); } void sub_813461C(u8 levelType) @@ -2295,3 +2307,453 @@ void sub_8135668(void) break; } } + +void sub_81358A4(void) +{ + u8 battleTowerLevelType = gSaveBlock2.filler_A8.battleTowerLevelType; + + switch (gSpecialVar_0x8004) + { + case 0: + gScriptResult = gSaveBlock2.filler_A8.var_4AE[battleTowerLevelType]; + break; + case 1: + gScriptResult = gSaveBlock2.filler_A8.battleTowerLevelType; + break; + case 2: + gScriptResult = gSaveBlock2.filler_A8.var_4B0[battleTowerLevelType]; + break; + case 3: + gScriptResult = gSaveBlock2.filler_A8.var_4B4[battleTowerLevelType]; + break; + case 4: + gScriptResult = gSaveBlock2.filler_A8.battleTowerTrainerId; + break; + case 5: + case 6: + case 7: + break; + case 8: + gScriptResult = gSaveBlock2.filler_A8.unk_554; + break; + case 9: + gScriptResult = sub_8135D3C(battleTowerLevelType); + break; + case 10: + SetGameStat(GAME_STAT_BATTLE_TOWER_BEST_STREAK, gSaveBlock2.filler_A8.bestBattleTowerWinStreak); + break; + case 11: + sub_813461C(battleTowerLevelType); + break; + case 12: + gSaveBlock2.filler_A8.var_4AE[battleTowerLevelType] = ewram160FB; + break; + case 13: + gSaveBlock2.filler_A8.currentWinStreaks[battleTowerLevelType] = sub_8135D3C(battleTowerLevelType); + break; + case 14: + gSaveBlock2.filler_A8.lastStreakLevelType = gSaveBlock2.filler_A8.battleTowerLevelType; + break; + } +} + +void sub_8135A14(void) +{ + s32 i; + + for (i = 0; i < 3; i++) + { + gSelectedOrderFromParty[i] = gSaveBlock2.filler_A8.var_4BD[i]; + } + + ReducePlayerPartyToThree(); +} + +#ifdef NONMATCHING +void sub_8135A3C(void) +{ + u8 battleTowerLevelType = gSaveBlock2.filler_A8.battleTowerLevelType; + u16 winStreak = sub_8135D3C(battleTowerLevelType); + if (gSaveBlock2.filler_A8.recordWinStreaks[battleTowerLevelType] < winStreak) + { + gSaveBlock2.filler_A8.recordWinStreaks[battleTowerLevelType] = winStreak; + } + + if (gSaveBlock2.filler_A8.recordWinStreaks[0] > gSaveBlock2.filler_A8.recordWinStreaks[1]) + { + SetGameStat(GAME_STAT_BATTLE_TOWER_BEST_STREAK, gSaveBlock2.filler_A8.recordWinStreaks[0]); + if (gSaveBlock2.filler_A8.recordWinStreaks[0] > 9999) + { + gSaveBlock2.filler_A8.bestBattleTowerWinStreak = 9999; + } + else + { + gSaveBlock2.filler_A8.bestBattleTowerWinStreak = gSaveBlock2.filler_A8.recordWinStreaks[0]; + } + } + else + { + SetGameStat(GAME_STAT_BATTLE_TOWER_BEST_STREAK, gSaveBlock2.filler_A8.recordWinStreaks[1]); + if (gSaveBlock2.filler_A8.recordWinStreaks[1] > 9999) + { + gSaveBlock2.filler_A8.bestBattleTowerWinStreak = 9999; + } + else + { + gSaveBlock2.filler_A8.bestBattleTowerWinStreak = gSaveBlock2.filler_A8.recordWinStreaks[1]; + } + } +} +#else +__attribute__((naked)) +void sub_8135A3C(void) +{ + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + ldr r6, _08135A84 @ =gSaveBlock2\n\ + ldr r1, _08135A88 @ =0x00000554\n\ + adds r0, r6, r1\n\ + ldrb r4, [r0]\n\ + lsls r4, 31\n\ + lsrs r4, 31\n\ + adds r0, r4, 0\n\ + bl sub_8135D3C\n\ + lsls r0, 16\n\ + lsrs r5, r0, 16\n\ + lsls r4, 1\n\ + movs r3, 0xAC\n\ + lsls r3, 3\n\ + adds r2, r6, r3\n\ + adds r4, r2\n\ + ldrh r0, [r4]\n\ + cmp r0, r5\n\ + bcs _08135A66\n\ + strh r5, [r4]\n\ +_08135A66:\n\ + ldr r0, _08135A8C @ =0x00000562\n\ + adds r1, r6, r0\n\ + ldrh r0, [r2]\n\ + ldrh r3, [r1]\n\ + cmp r0, r3\n\ + bls _08135A94\n\ + adds r5, r0, 0\n\ + movs r0, 0x20\n\ + adds r1, r5, 0\n\ + bl SetGameStat\n\ + ldr r1, _08135A90 @ =0x0000270f\n\ + cmp r5, r1\n\ + bhi _08135AA4\n\ + b _08135AB4\n\ + .align 2, 0\n\ +_08135A84: .4byte gSaveBlock2\n\ +_08135A88: .4byte 0x00000554\n\ +_08135A8C: .4byte 0x00000562\n\ +_08135A90: .4byte 0x0000270f\n\ +_08135A94:\n\ + ldrh r5, [r1]\n\ + movs r0, 0x20\n\ + adds r1, r5, 0\n\ + bl SetGameStat\n\ + ldr r1, _08135AAC @ =0x0000270f\n\ + cmp r5, r1\n\ + bls _08135AB4\n\ +_08135AA4:\n\ + ldr r2, _08135AB0 @ =0x00000572\n\ + adds r0, r6, r2\n\ + strh r1, [r0]\n\ + b _08135ABA\n\ + .align 2, 0\n\ +_08135AAC: .4byte 0x0000270f\n\ +_08135AB0: .4byte 0x00000572\n\ +_08135AB4:\n\ + ldr r3, _08135AC0 @ =0x00000572\n\ + adds r0, r6, r3\n\ + strh r5, [r0]\n\ +_08135ABA:\n\ + pop {r4-r6}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08135AC0: .4byte 0x00000572\n\ + .syntax divided\n"); +} +#endif // NONMATCHING + +void sub_8135AC4(void) +{ + s32 i; + u8 trainerClass; + struct BattleTowerRecord *playerRecord = &gSaveBlock2.filler_A8.var_A8; + u8 battleTowerLevelType = gSaveBlock2.filler_A8.battleTowerLevelType; + + if (gSaveBlock2.playerGender != 0) + { + trainerClass = gUnknown_08405E7E[(gSaveBlock2.playerTrainerId[0] + gSaveBlock2.playerTrainerId[1] + + gSaveBlock2.playerTrainerId[2] + gSaveBlock2.playerTrainerId[3]) % 20u]; + } + else + { + trainerClass = gUnknown_08405E60[(gSaveBlock2.playerTrainerId[0] + gSaveBlock2.playerTrainerId[1] + + gSaveBlock2.playerTrainerId[2] + gSaveBlock2.playerTrainerId[3]) % 30u]; + } + + playerRecord->var_0 = battleTowerLevelType; + playerRecord->trainerClass = trainerClass; + + copy_word_to_mem(playerRecord->trainerId, gSaveBlock2.playerTrainerId); + StringCopy8(playerRecord->name, gSaveBlock2.playerName); + + playerRecord->var_2 = sub_8135D3C(battleTowerLevelType); + + for (i = 0; i < 6; i++) + { + playerRecord->greeting.easyChat[i] = gSaveBlock1.easyChats.unk2B28[i]; + } + + for (i = 0; i < 3; i++) + { + sub_803AF78(&gUnknown_030042FC[gSaveBlock2.filler_A8.var_4BD[i]], &playerRecord->party[i]); + } + + SetBattleTowerRecordChecksum(&gSaveBlock2.filler_A8.var_A8); + sub_8135A3C(); +} + +void sub_8135BA0(void) +{ + u8 battleTowerLevelType = gSaveBlock2.filler_A8.battleTowerLevelType; + + if (gSpecialVar_0x8004 == 3 || gSpecialVar_0x8004 == 0) + { + if (gSaveBlock2.filler_A8.var_4B4[battleTowerLevelType] > 1 + || gSaveBlock2.filler_A8.var_4B0[battleTowerLevelType] > 1) + { + sub_8135AC4(); + } + } + + sub_8135CFC(); + + gSaveBlock2.filler_A8.var_4AD = gBattleOutcome; + + if (gSpecialVar_0x8004 != 3) + { + gSaveBlock2.filler_A8.var_4AE[battleTowerLevelType] = gSpecialVar_0x8004; + } + + VarSet(VAR_0x4000, 0); + gSaveBlock2.filler_A8.unk_554 = 1; + TrySavingData(EREADER_SAVE); +} + +void sub_8135C38(void) +{ + DoSoftReset(); +} + +void ValidateBattleTowerRecordChecksums(void) +{ + u32 i; + s32 recordIndex; + struct BattleTowerRecord *record; + u32 checksum; + + checksum = 0; + for (i = 0; i < (sizeof(struct BattleTowerRecord) / sizeof(u32)) - 1; i++) + { + checksum += ((u32 *)&gSaveBlock2.filler_A8.var_A8)[i]; + } + + if (gSaveBlock2.filler_A8.var_A8.checksum != checksum) + { + ClearBattleTowerRecord(&gSaveBlock2.filler_A8.var_A8); + } + + for (recordIndex = 0; recordIndex < 5; recordIndex++) + { + record = &gSaveBlock2.filler_A8.var_14C[recordIndex]; + checksum = 0; + for (i = 0; i < (sizeof(struct BattleTowerRecord) / sizeof(u32)) - 1; i++) + { + checksum += ((u32 *)record)[i]; + } + + if (gSaveBlock2.filler_A8.var_14C[recordIndex].checksum != checksum) + { + ClearBattleTowerRecord(&gSaveBlock2.filler_A8.var_14C[recordIndex]); + } + } +} + +void SetBattleTowerRecordChecksum(struct BattleTowerRecord *record) +{ + u32 i; + + record->checksum = 0; + for (i = 0; i < (sizeof(struct BattleTowerRecord) / sizeof(u32)) - 1; i++) + { + record->checksum += ((u32 *)record)[i]; + } +} + +void ClearBattleTowerRecord(struct BattleTowerRecord *record) +{ + u32 i; + + for (i = 0; i < sizeof(struct BattleTowerRecord) / sizeof(u32); i++) + { + ((u32 *)record)[i] = 0; + } +} + +void sub_8135CFC(void) +{ + s32 i; + + get_trainer_name(gSaveBlock2.filler_A8.defeatedByTrainerName); + gSaveBlock2.filler_A8.defeatedBySpecies = gBattleMons[1].species; + gSaveBlock2.filler_A8.firstMonSpecies = gBattleMons[0].species; + + for (i = 0; i < POKEMON_NAME_LENGTH; i++) + { + gSaveBlock2.filler_A8.firstMonNickname[i] = gBattleMons[0].nickname[i]; + } +} + +u16 sub_8135D3C(u8 battleTowerLevelType) +{ + u16 var2 = ((gSaveBlock2.filler_A8.var_4B4[battleTowerLevelType] - 1) * 7 - 1) + gSaveBlock2.filler_A8.var_4B0[battleTowerLevelType]; + + if (var2 > 9999) + { + return 9999; + } + + return var2; +} + +#ifdef NONMATCHING +void sub_8135D84(void) +{ + u16 prizeItem; + struct SaveBlock2 *saveBlock = &gSaveBlock2; + u8 battleTowerLevelType = saveBlock->filler_A8.battleTowerLevelType; + + if (saveBlock->filler_A8.var_4B4[battleTowerLevelType] - 1 > 5) + { + prizeItem = LongStreakPrizes[Random() % 9]; + } + else + { + prizeItem = ShortStreakPrizes[Random() % 6]; + } + + saveBlock->filler_A8.prizeItem = prizeItem; +} +#else +__attribute__((naked)) +void sub_8135D84(void) +{ + asm(".syntax unified\n\ + push {r4,r5,lr}\n\ + ldr r5, _08135DB0 @ =gSaveBlock2\n\ + ldr r1, _08135DB4 @ =0x00000554\n\ + adds r0, r5, r1\n\ + ldrb r0, [r0]\n\ + lsls r0, 31\n\ + lsrs r0, 31\n\ + lsls r0, 1\n\ + ldr r2, _08135DB8 @ =0x0000055c\n\ + adds r1, r5, r2\n\ + adds r0, r1\n\ + ldrh r0, [r0]\n\ + subs r0, 0x1\n\ + cmp r0, 0x5\n\ + ble _08135DC0\n\ + bl Random\n\ + ldr r4, _08135DBC @ =LongStreakPrizes\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0x9\n\ + b _08135DCC\n\ + .align 2, 0\n\ +_08135DB0: .4byte gSaveBlock2\n\ +_08135DB4: .4byte 0x00000554\n\ +_08135DB8: .4byte 0x0000055c\n\ +_08135DBC: .4byte LongStreakPrizes\n\ +_08135DC0:\n\ + bl Random\n\ + ldr r4, _08135DE8 @ =ShortStreakPrizes\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0x6\n\ +_08135DCC:\n\ + bl __umodsi3\n\ + lsls r0, 16\n\ + lsrs r0, 15\n\ + adds r0, r4\n\ + ldrh r1, [r0]\n\ + movs r2, 0xAD\n\ + lsls r2, 3\n\ + adds r0, r5, r2\n\ + strh r1, [r0]\n\ + pop {r4,r5}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08135DE8: .4byte ShortStreakPrizes\n\ + .syntax divided\n"); +} +#endif // NONMATCHING + +void sub_8135DEC(void) +{ + u8 battleTowerLevelType = gSaveBlock2.filler_A8.battleTowerLevelType; + + if (AddBagItem(gSaveBlock2.filler_A8.prizeItem, 1) == TRUE) + { + CopyItemName(gSaveBlock2.filler_A8.prizeItem, gStringVar1); + gScriptResult = 1; + } + else + { + gScriptResult = 0; + gSaveBlock2.filler_A8.var_4AE[battleTowerLevelType] = 6; + } +} + +void sub_8135E50() +{ + s32 i; + u32 partyIndex; + struct Pokemon *pokemon; + u8 ribbonType; + u8 battleTowerLevelType = gSaveBlock2.filler_A8.battleTowerLevelType; + + ribbonType = MON_DATA_WINNING_RIBBON; + if (battleTowerLevelType != 0) + { + ribbonType = MON_DATA_VICTORY_RIBBON; + } + + gScriptResult = 0; + + if (sub_8135D3C(battleTowerLevelType) > 55) + { + for (i = 0; i < 3; i++) + { + partyIndex = gSaveBlock2.filler_A8.var_4BD[i] - 1; + pokemon = &gPlayerParty[partyIndex]; + if (!GetMonData(pokemon, ribbonType)) + { + gScriptResult = 1; + SetMonData(pokemon, ribbonType, (u8 *)&gScriptResult); + } + } + } + + if (gScriptResult != 0) + { + IncrementGameStat(GAME_STAT_RECEIVED_RIBBONS); + } +} diff --git a/src/engine/trainer_card.c b/src/engine/trainer_card.c index c8847b258..11baa65d5 100644 --- a/src/engine/trainer_card.c +++ b/src/engine/trainer_card.c @@ -374,7 +374,7 @@ void sub_8093390(struct TrainerCard *trainerCard) for (i = 0; i < 4; i++) { - trainerCard->var_28[i] = gSaveBlock1.unk2B1C[i]; + trainerCard->var_28[i] = gSaveBlock1.easyChats.unk2B1C[i]; } for (i = 0; i < 8; i++) diff --git a/src/field/easy_chat.c b/src/field/easy_chat.c index 6014b3d14..2668b57dd 100644 --- a/src/field/easy_chat.c +++ b/src/field/easy_chat.c @@ -278,13 +278,13 @@ void sub_80EB7C4(void) switch (gSpecialVar_0x8004) { case 0: - words = gSaveBlock1.unk2B1C; + words = gSaveBlock1.easyChats.unk2B1C; arg1 = 2; arg2 = 2; break; case 1: - words = gSaveBlock1.unk2B28; - if (sub_80EB680(gSaveBlock1.unk2B28, 3, 2, 20)) + words = gSaveBlock1.easyChats.unk2B28; + if (sub_80EB680(gSaveBlock1.easyChats.unk2B28, 3, 2, 20)) { arg1 = 2; arg2 = 3; @@ -296,12 +296,12 @@ void sub_80EB7C4(void) } break; case 2: - words = gSaveBlock1.unk2B34; + words = gSaveBlock1.easyChats.unk2B34; arg1 = 3; arg2 = 2; break; case 3: - words = gSaveBlock1.unk2B40; + words = gSaveBlock1.easyChats.unk2B40; arg1 = 3; arg2 = 2; break; diff --git a/src/field/tv.c b/src/field/tv.c index 89e978d00..1e38e79e0 100644 --- a/src/field/tv.c +++ b/src/field/tv.c @@ -674,7 +674,7 @@ void sub_80BE320(void) bravoTrainerTower->var00 = TVSHOW_BRAVO_TRAINER_BATTLE_TOWER_PROFILE; bravoTrainerTower->var01 = 1; StringCopy(bravoTrainerTower->trainerName, gSaveBlock2.playerName); - StringCopy(bravoTrainerTower->pokemonName, gSaveBlock2.filler_A8.filler_3DC); + StringCopy(bravoTrainerTower->pokemonName, gSaveBlock2.filler_A8.defeatedByTrainerName); bravoTrainerTower->species = gSaveBlock2.filler_A8.firstMonSpecies; bravoTrainerTower->defeatedSpecies = gSaveBlock2.filler_A8.defeatedBySpecies; bravoTrainerTower->var16 = sub_8135D3C(gSaveBlock2.filler_A8.lastStreakLevelType); |