summaryrefslogtreecommitdiff
path: root/src/recorded_battle.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/recorded_battle.c')
-rw-r--r--src/recorded_battle.c149
1 files changed, 63 insertions, 86 deletions
diff --git a/src/recorded_battle.c b/src/recorded_battle.c
index e29792766..e6d5b165b 100644
--- a/src/recorded_battle.c
+++ b/src/recorded_battle.c
@@ -1,6 +1,7 @@
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
+#include "battle_controllers.h"
#include "recorded_battle.h"
#include "main.h"
#include "pokemon.h"
@@ -35,12 +36,6 @@ struct PlayerInfo
u16 language;
};
-struct MovePp
-{
- u16 moves[MAX_MON_MOVES];
- u8 pp[MAX_MON_MOVES];
-};
-
struct RecordedBattleSave
{
struct Pokemon playerParty[PARTY_SIZE];
@@ -65,7 +60,7 @@ struct RecordedBattleSave
u8 recordMixFriendName[PLAYER_NAME_LENGTH + 1];
u8 recordMixFriendClass;
u8 apprenticeId;
- u16 easyChatSpeech[6];
+ u16 easyChatSpeech[EASY_CHAT_BATTLE_WORDS_COUNT];
u8 recordMixFriendLanguage;
u8 apprenticeLanguage;
u8 battleRecord[MAX_BATTLERS_COUNT][BATTLER_RECORD_SIZE];
@@ -91,13 +86,13 @@ EWRAM_DATA static u32 sBattleFlags = 0;
EWRAM_DATA static u32 sAI_Scripts = 0;
EWRAM_DATA static struct Pokemon sSavedPlayerParty[PARTY_SIZE] = {0};
EWRAM_DATA static struct Pokemon sSavedOpponentParty[PARTY_SIZE] = {0};
-EWRAM_DATA static u16 sPlayerMonMoves[2][MAX_MON_MOVES] = {0};
+EWRAM_DATA static u16 sPlayerMonMoves[MAX_BATTLERS_COUNT / 2][MAX_MON_MOVES] = {0};
EWRAM_DATA static struct PlayerInfo sPlayers[MAX_BATTLERS_COUNT] = {0};
-EWRAM_DATA static bool8 sUnknown_0203CCD0 = 0;
+EWRAM_DATA static bool8 sIsPlaybackFinished = 0;
EWRAM_DATA static u8 sRecordMixFriendName[PLAYER_NAME_LENGTH + 1] = {0};
EWRAM_DATA static u8 sRecordMixFriendClass = 0;
EWRAM_DATA static u8 sApprenticeId = 0;
-EWRAM_DATA static u16 sEasyChatSpeech[6] = {0};
+EWRAM_DATA static u16 sEasyChatSpeech[EASY_CHAT_BATTLE_WORDS_COUNT] = {0};
EWRAM_DATA static u8 sBattleOutcome = 0;
static u8 sRecordMixFriendLanguage;
@@ -113,7 +108,7 @@ void RecordedBattle_Init(u8 mode)
s32 i, j;
sRecordMode = mode;
- sUnknown_0203CCD0 = FALSE;
+ sIsPlaybackFinished = FALSE;
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
@@ -124,16 +119,14 @@ void RecordedBattle_Init(u8 mode)
if (mode == B_RECORD_MODE_RECORDING)
{
for (j = 0; j < BATTLER_RECORD_SIZE; j++)
- {
sBattleRecords[i][j] = 0xFF;
- }
sBattleFlags = gBattleTypeFlags;
sAI_Scripts = gBattleResources->ai->aiFlags;
}
}
}
-void sub_8184E58(void)
+void RecordedBattle_SetTrainerInfo(void)
{
s32 i, j;
@@ -150,6 +143,7 @@ void sub_8184E58(void)
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{
+ // Link recorded battle, record info for all trainers
u8 linkPlayersCount;
u8 text[30];
@@ -163,6 +157,7 @@ void sub_8184E58(void)
sPlayers[i].battlerId = gLinkPlayers[i].id;
sPlayers[i].language = gLinkPlayers[i].language;
+ // Record names
if (i < linkPlayersCount)
{
StringCopy(text, gLinkPlayers[i].name);
@@ -178,10 +173,11 @@ void sub_8184E58(void)
}
else
{
+ // Local battle, just record own info
sPlayers[0].trainerId = (gSaveBlock2Ptr->playerTrainerId[0])
- | (gSaveBlock2Ptr->playerTrainerId[1] << 8)
- | (gSaveBlock2Ptr->playerTrainerId[2] << 16)
- | (gSaveBlock2Ptr->playerTrainerId[3] << 24);
+ | (gSaveBlock2Ptr->playerTrainerId[1] << 8)
+ | (gSaveBlock2Ptr->playerTrainerId[2] << 16)
+ | (gSaveBlock2Ptr->playerTrainerId[3] << 24);
sPlayers[0].gender = gSaveBlock2Ptr->playerGender;
sPlayers[0].battlerId = 0;
@@ -195,9 +191,7 @@ void sub_8184E58(void)
void RecordedBattle_SetBattlerAction(u8 battlerId, u8 action)
{
if (sBattlerRecordSizes[battlerId] < BATTLER_RECORD_SIZE && sRecordMode != B_RECORD_MODE_PLAYBACK)
- {
sBattleRecords[battlerId][sBattlerRecordSizes[battlerId]++] = action;
- }
}
void RecordedBattle_ClearBattlerAction(u8 battlerId, u8 bytesToClear)
@@ -220,7 +214,7 @@ u8 RecordedBattle_GetBattlerAction(u8 battlerId)
{
gSpecialVar_Result = gBattleOutcome = B_OUTCOME_PLAYER_TELEPORTED; // hah
ResetPaletteFadeControl();
- BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK);
+ BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
SetMainCallback2(CB2_QuitRecordedBattle);
return 0xFF;
}
@@ -249,9 +243,7 @@ u8 RecordedBattle_BufferNewBattlerData(u8 *dst)
dst[idx++] = sBattlerRecordSizes[i] - sBattlerPrevRecordSizes[i];
for (j = 0; j < sBattlerRecordSizes[i] - sBattlerPrevRecordSizes[i]; j++)
- {
dst[idx++] = sBattleRecords[i][sBattlerPrevRecordSizes[i] + j];
- }
sBattlerPrevRecordSizes[i] = sBattlerRecordSizes[i];
}
@@ -283,9 +275,7 @@ void RecordedBattle_RecordAllBattlerData(u8 *src)
u8 numActions = GetNextRecordedDataByte(src, &idx, &size);
for (i = 0; i < numActions; i++)
- {
sBattleRecords[battlerId][sBattlerSavedRecordSizes[battlerId]++] = GetNextRecordedDataByte(src, &idx, &size);
- }
}
}
}
@@ -318,7 +308,7 @@ static bool32 IsRecordedBattleSaveValid(struct RecordedBattleSave *save)
static bool32 RecordedBattleToSave(struct RecordedBattleSave *battleSave, struct RecordedBattleSave *saveSection)
{
- memset(saveSection, 0, 0x1000);
+ memset(saveSection, 0, SECTOR_SIZE);
memcpy(saveSection, battleSave, sizeof(*battleSave));
saveSection->checksum = CalcByteArraySum((void*)(saveSection), sizeof(*saveSection) - 4);
@@ -338,7 +328,7 @@ bool32 MoveRecordedBattleToSaveData(void)
saveAttempts = 0;
battleSave = AllocZeroed(sizeof(struct RecordedBattleSave));
- savSection = AllocZeroed(0x1000);
+ savSection = AllocZeroed(SECTOR_SIZE);
for (i = 0; i < PARTY_SIZE; i++)
{
@@ -349,9 +339,7 @@ bool32 MoveRecordedBattleToSaveData(void)
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
for (j = 0; j < PLAYER_NAME_LENGTH + 1; j++)
- {
battleSave->playersName[i][j] = sPlayers[i].name[j];
- }
battleSave->playersGender[i] = sPlayers[i].gender;
battleSave->playersLanguage[i] = sPlayers[i].language;
battleSave->playersBattlers[i] = sPlayers[i].battlerId;
@@ -471,12 +459,8 @@ bool32 MoveRecordedBattleToSaveData(void)
}
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
- {
for (j = 0; j < BATTLER_RECORD_SIZE; j++)
- {
battleSave->battleRecord[i][j] = sBattleRecords[i][j];
- }
- }
while (1)
{
@@ -585,29 +569,21 @@ static void SetVariablesForRecordedBattle(struct RecordedBattleSave *src)
sAI_Scripts = src->AI_scripts;
for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++)
- {
sRecordMixFriendName[i] = src->recordMixFriendName[i];
- }
sRecordMixFriendClass = src->recordMixFriendClass;
sApprenticeId = src->apprenticeId;
sRecordMixFriendLanguage = src->recordMixFriendLanguage;
sApprenticeLanguage = src->apprenticeLanguage;
- for (i = 0; i < 6; i++)
- {
+ for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++)
sEasyChatSpeech[i] = src->easyChatSpeech[i];
- }
gSaveBlock2Ptr->frontier.lvlMode = src->lvlMode;
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
- {
for (j = 0; j < BATTLER_RECORD_SIZE; j++)
- {
sBattleRecords[i][j] = src->battleRecord[i][j];
- }
- }
}
void PlayRecordedBattle(void (*CB2_After)(void))
@@ -693,9 +669,9 @@ void RecordedBattle_ClearFrontierPassFlag(void)
}
// Set sFrontierPassFlag to received state of FLAG_SYS_FRONTIER_PASS
-void RecordedBattle_SetFrontierPassFlagFromHword(u16 arg0)
+void RecordedBattle_SetFrontierPassFlagFromHword(u16 flags)
{
- sFrontierPassFlag |= (arg0 & 0x8000) >> 15;
+ sFrontierPassFlag |= (flags & (1 << 15)) >> 15;
}
u8 RecordedBattle_GetFrontierPassFlag(void)
@@ -725,14 +701,14 @@ void RecordedBattle_CopyBattlerMoves(void)
return;
for (i = 0; i < MAX_MON_MOVES; i++)
- {
sPlayerMonMoves[gActiveBattler / 2][i] = gBattleMons[gActiveBattler].moves[i];
- }
}
+// This is a special battle action only used by this function
+// It shares a value with B_ACTION_SAFARI_POKEBLOCK, which can never occur in a recorded battle.
#define ACTION_MOVE_CHANGE 6
-void sub_818603C(u8 arg0)
+void RecordedBattle_CheckMovesetChanges(u8 mode)
{
s32 battlerId, j, k;
@@ -741,17 +717,20 @@ void sub_818603C(u8 arg0)
for (battlerId = 0; battlerId < gBattlersCount; battlerId++)
{
- if (GetBattlerSide(battlerId) != B_SIDE_OPPONENT) // player's side only
+ // Player's side only
+ if (GetBattlerSide(battlerId) != B_SIDE_OPPONENT)
{
- if (arg0 == 1)
+ if (mode == B_RECORD_MODE_RECORDING)
{
+ // Check if any of the battler's moves have changed.
for (j = 0; j < MAX_MON_MOVES; j++)
{
if (gBattleMons[battlerId].moves[j] != sPlayerMonMoves[battlerId / 2][j])
break;
}
- if (j != MAX_MON_MOVES) // player's mon's move has been changed
+ if (j != MAX_MON_MOVES)
{
+ // At least one of the moves has been changed
RecordedBattle_SetBattlerAction(battlerId, ACTION_MOVE_CHANGE);
for (j = 0; j < MAX_MON_MOVES; j++)
{
@@ -766,68 +745,66 @@ void sub_818603C(u8 arg0)
}
}
}
- else
+ else // B_RECORD_MODE_PLAYBACK
{
if (sBattleRecords[battlerId][sBattlerRecordSizes[battlerId]] == ACTION_MOVE_CHANGE)
{
u8 ppBonuses[MAX_MON_MOVES];
- u8 array1[MAX_MON_MOVES];
- u8 array2[MAX_MON_MOVES];
- struct MovePp movePp;
- u8 array3[(MAX_MON_MOVES * 2)];
- u8 var;
+ u8 moveSlots[MAX_MON_MOVES];
+ u8 mimickedMoveSlots[MAX_MON_MOVES];
+ struct ChooseMoveStruct movePp;
+ u8 ppBonusSet;
+ // We know the current action is ACTION_MOVE_CHANGE, retrieve
+ // it without saving it to move on to the next action.
RecordedBattle_GetBattlerAction(battlerId);
+
for (j = 0; j < MAX_MON_MOVES; j++)
- {
- ppBonuses[j] = ((gBattleMons[battlerId].ppBonuses & ((3 << (j << 1)))) >> (j << 1));
- }
+ ppBonuses[j] = ((gBattleMons[battlerId].ppBonuses & (3 << (j << 1))) >> (j << 1));
+
for (j = 0; j < MAX_MON_MOVES; j++)
{
- array1[j] = RecordedBattle_GetBattlerAction(battlerId);
- movePp.moves[j] = gBattleMons[battlerId].moves[array1[j]];
- movePp.pp[j] = gBattleMons[battlerId].pp[array1[j]];
- array3[j] = ppBonuses[array1[j]];
- array2[j] = (gDisableStructs[battlerId].mimickedMoves & gBitTable[j]) >> j;
+ moveSlots[j] = RecordedBattle_GetBattlerAction(battlerId);
+ movePp.moves[j] = gBattleMons[battlerId].moves[moveSlots[j]];
+ movePp.currentPp[j] = gBattleMons[battlerId].pp[moveSlots[j]];
+ movePp.maxPp[j] = ppBonuses[moveSlots[j]];
+ mimickedMoveSlots[j] = (gDisableStructs[battlerId].mimickedMoves & gBitTable[j]) >> j;
}
for (j = 0; j < MAX_MON_MOVES; j++)
{
gBattleMons[battlerId].moves[j] = movePp.moves[j];
- gBattleMons[battlerId].pp[j] = movePp.pp[j];
+ gBattleMons[battlerId].pp[j] = movePp.currentPp[j];
}
gBattleMons[battlerId].ppBonuses = 0;
gDisableStructs[battlerId].mimickedMoves = 0;
for (j = 0; j < MAX_MON_MOVES; j++)
{
- gBattleMons[battlerId].ppBonuses |= (array3[j]) << (j << 1);
- gDisableStructs[battlerId].mimickedMoves |= (array2[j]) << (j);
+ gBattleMons[battlerId].ppBonuses |= movePp.maxPp[j] << (j << 1);
+ gDisableStructs[battlerId].mimickedMoves |= mimickedMoveSlots[j] << j;
}
if (!(gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED))
{
for (j = 0; j < MAX_MON_MOVES; j++)
- {
- ppBonuses[j] = ((GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP_BONUSES, NULL) & ((3 << (j << 1)))) >> (j << 1));
- }
+ ppBonuses[j] = (GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP_BONUSES, NULL) & ((3 << (j << 1)))) >> (j << 1);
+
for (j = 0; j < MAX_MON_MOVES; j++)
{
- movePp.moves[j] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_MOVE1 + array1[j], NULL);
- movePp.pp[j] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP1 + array1[j], NULL);
- array3[j] = ppBonuses[array1[j]];
+ movePp.moves[j] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_MOVE1 + moveSlots[j], NULL);
+ movePp.currentPp[j] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP1 + moveSlots[j], NULL);
+ movePp.maxPp[j] = ppBonuses[moveSlots[j]];
}
for (j = 0; j < MAX_MON_MOVES; j++)
{
SetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_MOVE1 + j, &movePp.moves[j]);
- SetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP1 + j, &movePp.pp[j]);
+ SetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP1 + j, &movePp.currentPp[j]);
}
- var = 0;
+ ppBonusSet = 0;
for (j = 0; j < MAX_MON_MOVES; j++)
- {
- var |= (array3[j]) << (j << 1);
- }
- SetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP_BONUSES, &var);
- }
+ ppBonusSet |= movePp.maxPp[j] << (j << 1);
+ SetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP_BONUSES, &ppBonusSet);
+ }
gChosenMoveByBattler[battlerId] = gBattleMons[battlerId].moves[*(gBattleStruct->chosenMovePositions + battlerId)];
}
}
@@ -840,24 +817,24 @@ u32 GetAiScriptsInRecordedBattle(void)
return sAI_Scripts;
}
-void sub_8186444(void)
+// Used to determine when the player is allowed to press B to end a recorded battle's playback
+void RecordedBattle_SetPlaybackFinished(void)
{
- sUnknown_0203CCD0 = TRUE;
+ sIsPlaybackFinished = TRUE;
}
-bool8 sub_8186450(void)
+bool8 RecordedBattle_CanStopPlayback(void)
{
- return (sUnknown_0203CCD0 == FALSE);
+ return (sIsPlaybackFinished == FALSE);
}
void GetRecordedBattleRecordMixFriendName(u8 *dst)
{
s32 i;
- for (i = 0; i < 8; i++)
+ for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++)
dst[i] = sRecordMixFriendName[i];
-
- dst[7] = EOS;
+ dst[PLAYER_NAME_LENGTH] = EOS;
ConvertInternationalString(dst, sRecordMixFriendLanguage);
}