pokeemerald/src/recorded_battle.c

872 lines
29 KiB
C
Raw Normal View History

2017-11-12 22:59:36 +01:00
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
#include "battle_controllers.h"
2017-11-12 22:59:36 +01:00
#include "recorded_battle.h"
#include "main.h"
#include "pokemon.h"
#include "random.h"
2017-11-12 22:59:36 +01:00
#include "event_data.h"
#include "link.h"
#include "string_util.h"
2017-11-13 00:10:34 +01:00
#include "palette.h"
2017-11-13 18:07:23 +01:00
#include "save.h"
#include "malloc.h"
2017-11-13 18:07:23 +01:00
#include "util.h"
#include "task.h"
#include "text.h"
2018-02-08 00:00:25 +01:00
#include "battle_setup.h"
2018-11-01 15:06:50 +01:00
#include "frontier_util.h"
#include "constants/trainers.h"
2019-04-04 23:05:46 +02:00
#include "constants/rgb.h"
2017-11-12 22:59:36 +01:00
2018-02-11 21:05:42 +01:00
#define BATTLER_RECORD_SIZE 664
2017-11-13 18:07:23 +01:00
#define ILLEGAL_BATTLE_TYPES ((BATTLE_TYPE_LINK | BATTLE_TYPE_SAFARI | BATTLE_TYPE_FIRST_BATTLE \
2018-11-01 21:31:10 +01:00
| BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_ROAMER | BATTLE_TYPE_EREADER_TRAINER \
| BATTLE_TYPE_KYOGRE_GROUDON | BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_REGI \
| BATTLE_TYPE_RECORDED | BATTLE_TYPE_TRAINER_HILL | BATTLE_TYPE_SECRET_BASE \
2017-12-16 01:15:19 +01:00
| BATTLE_TYPE_GROUDON | BATTLE_TYPE_KYOGRE | BATTLE_TYPE_RAYQUAZA))
2017-11-12 22:59:36 +01:00
struct PlayerInfo
{
u32 trainerId;
2018-09-01 22:03:21 +02:00
u8 name[PLAYER_NAME_LENGTH + 1];
2017-11-12 22:59:36 +01:00
u8 gender;
2018-02-08 11:17:41 +01:00
u16 battlerId;
2017-11-12 22:59:36 +01:00
u16 language;
};
2017-11-13 18:07:23 +01:00
struct RecordedBattleSave
{
struct Pokemon playerParty[PARTY_SIZE];
struct Pokemon opponentParty[PARTY_SIZE];
2018-09-01 22:03:21 +02:00
u8 playersName[MAX_BATTLERS_COUNT][PLAYER_NAME_LENGTH + 1];
2018-02-06 02:46:59 +01:00
u8 playersGender[MAX_BATTLERS_COUNT];
u32 playersTrainerId[MAX_BATTLERS_COUNT];
u8 playersLanguage[MAX_BATTLERS_COUNT];
2017-11-13 18:07:23 +01:00
u32 rngSeed;
u32 battleFlags;
2018-02-11 21:45:26 +01:00
u8 playersBattlers[MAX_BATTLERS_COUNT];
2017-11-13 18:07:23 +01:00
u16 opponentA;
u16 opponentB;
u16 partnerId;
2021-01-13 21:17:32 +01:00
u16 multiplayerId;
2018-11-01 15:06:50 +01:00
u8 lvlMode;
u8 frontierFacility;
u8 frontierBrainSymbol;
u8 battleScene:1;
2018-07-01 11:15:42 +02:00
u8 textSpeed:3;
2017-11-13 18:07:23 +01:00
u32 AI_scripts;
2018-11-01 15:06:50 +01:00
u8 recordMixFriendName[PLAYER_NAME_LENGTH + 1];
u8 recordMixFriendClass;
u8 apprenticeId;
2021-10-04 16:21:03 +02:00
u16 easyChatSpeech[EASY_CHAT_BATTLE_WORDS_COUNT];
2018-11-01 15:06:50 +01:00
u8 recordMixFriendLanguage;
u8 apprenticeLanguage;
2018-02-11 21:05:42 +01:00
u8 battleRecord[MAX_BATTLERS_COUNT][BATTLER_RECORD_SIZE];
2017-11-13 18:07:23 +01:00
u32 checksum;
};
STATIC_ASSERT(sizeof(struct RecordedBattleSave) <= SECTOR_DATA_SIZE, RecordedBattleSaveFreeSpace);
2017-11-12 22:59:36 +01:00
EWRAM_DATA u32 gRecordedBattleRngSeed = 0;
EWRAM_DATA u32 gBattlePalaceMoveSelectionRngValue = 0;
2018-02-11 21:05:42 +01:00
EWRAM_DATA static u8 sBattleRecords[MAX_BATTLERS_COUNT][BATTLER_RECORD_SIZE] = {0};
2021-01-23 02:03:21 +01:00
EWRAM_DATA static u16 sBattlerRecordSizes[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA static u16 sBattlerPrevRecordSizes[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA static u16 sBattlerSavedRecordSizes[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA static u8 sRecordMode = 0;
2018-11-01 15:06:50 +01:00
EWRAM_DATA static u8 sLvlMode = 0;
2018-07-01 11:15:42 +02:00
EWRAM_DATA static u8 sFrontierFacility = 0;
2018-11-01 15:06:50 +01:00
EWRAM_DATA static u8 sFrontierBrainSymbol = 0;
2017-11-13 19:01:23 +01:00
EWRAM_DATA static MainCallback sCallback2_AfterRecordedBattle = NULL;
2021-01-13 21:17:32 +01:00
EWRAM_DATA u8 gRecordedBattleMultiplayerId = 0;
2021-03-12 22:55:58 +01:00
EWRAM_DATA static u8 sFrontierPassFlag = 0;
2018-11-01 15:06:50 +01:00
EWRAM_DATA static u8 sBattleScene = 0;
2018-07-01 11:15:42 +02:00
EWRAM_DATA static u8 sTextSpeed = 0;
EWRAM_DATA static u32 sBattleFlags = 0;
EWRAM_DATA static u32 sAI_Scripts = 0;
2017-11-13 19:01:23 +01:00
EWRAM_DATA static struct Pokemon sSavedPlayerParty[PARTY_SIZE] = {0};
EWRAM_DATA static struct Pokemon sSavedOpponentParty[PARTY_SIZE] = {0};
EWRAM_DATA static u16 sPlayerMonMoves[MAX_BATTLERS_COUNT / 2][MAX_MON_MOVES] = {0};
2018-07-01 11:15:42 +02:00
EWRAM_DATA static struct PlayerInfo sPlayers[MAX_BATTLERS_COUNT] = {0};
2021-10-04 16:21:03 +02:00
EWRAM_DATA static bool8 sIsPlaybackFinished = 0;
2018-11-01 15:06:50 +01:00
EWRAM_DATA static u8 sRecordMixFriendName[PLAYER_NAME_LENGTH + 1] = {0};
EWRAM_DATA static u8 sRecordMixFriendClass = 0;
EWRAM_DATA static u8 sApprenticeId = 0;
2021-10-04 16:21:03 +02:00
EWRAM_DATA static u16 sEasyChatSpeech[EASY_CHAT_BATTLE_WORDS_COUNT] = {0};
2018-11-01 15:06:50 +01:00
EWRAM_DATA static u8 sBattleOutcome = 0;
2017-11-12 22:59:36 +01:00
static u8 sRecordMixFriendLanguage;
static u8 sApprenticeLanguage;
2018-11-01 21:31:10 +01:00
2021-01-23 02:03:21 +01:00
static u8 GetNextRecordedDataByte(u8 *, u8 *, u8 *);
static bool32 CopyRecordedBattleFromSave(struct RecordedBattleSave *);
2017-11-13 19:01:23 +01:00
static void RecordedBattle_RestoreSavedParties(void);
2017-11-13 18:07:23 +01:00
static void CB2_RecordedBattle(void);
2017-11-13 00:10:34 +01:00
void RecordedBattle_Init(u8 mode)
2017-11-12 22:59:36 +01:00
{
s32 i, j;
sRecordMode = mode;
2021-10-04 16:21:03 +02:00
sIsPlaybackFinished = FALSE;
2017-11-12 22:59:36 +01:00
2018-02-06 02:46:59 +01:00
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
2017-11-12 22:59:36 +01:00
{
2021-01-23 02:03:21 +01:00
sBattlerRecordSizes[i] = 0;
sBattlerPrevRecordSizes[i] = 0;
sBattlerSavedRecordSizes[i] = 0;
2017-11-12 22:59:36 +01:00
if (mode == B_RECORD_MODE_RECORDING)
2017-11-12 22:59:36 +01:00
{
2018-02-11 21:05:42 +01:00
for (j = 0; j < BATTLER_RECORD_SIZE; j++)
2019-01-13 12:12:27 +01:00
sBattleRecords[i][j] = 0xFF;
2018-07-01 11:15:42 +02:00
sBattleFlags = gBattleTypeFlags;
sAI_Scripts = gBattleResources->ai->aiFlags;
2017-11-12 22:59:36 +01:00
}
}
}
2021-10-04 16:21:03 +02:00
void RecordedBattle_SetTrainerInfo(void)
2017-11-12 22:59:36 +01:00
{
s32 i, j;
if (sRecordMode == B_RECORD_MODE_RECORDING)
2017-11-12 22:59:36 +01:00
{
gRecordedBattleRngSeed = gRngValue;
2018-07-01 11:15:42 +02:00
sFrontierFacility = VarGet(VAR_FRONTIER_FACILITY);
2018-11-01 15:06:50 +01:00
sFrontierBrainSymbol = GetFronterBrainSymbol();
2017-11-12 22:59:36 +01:00
}
else if (sRecordMode == B_RECORD_MODE_PLAYBACK)
2017-11-12 22:59:36 +01:00
{
gRngValue = gRecordedBattleRngSeed;
}
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{
2021-10-04 16:21:03 +02:00
// Link recorded battle, record info for all trainers
2017-11-12 22:59:36 +01:00
u8 linkPlayersCount;
u8 text[30];
2021-01-13 21:17:32 +01:00
gRecordedBattleMultiplayerId = GetMultiplayerId();
2017-11-12 22:59:36 +01:00
linkPlayersCount = GetLinkPlayerCount();
2018-02-06 02:46:59 +01:00
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
2017-11-12 22:59:36 +01:00
{
2018-07-01 11:15:42 +02:00
sPlayers[i].trainerId = gLinkPlayers[i].trainerId;
sPlayers[i].gender = gLinkPlayers[i].gender;
2018-07-22 13:14:58 +02:00
sPlayers[i].battlerId = gLinkPlayers[i].id;
2018-07-01 11:15:42 +02:00
sPlayers[i].language = gLinkPlayers[i].language;
2017-11-12 22:59:36 +01:00
2021-10-04 16:21:03 +02:00
// Record names
2017-11-12 22:59:36 +01:00
if (i < linkPlayersCount)
{
StringCopy(text, gLinkPlayers[i].name);
StripExtCtrlCodes(text);
2018-07-01 11:15:42 +02:00
StringCopy(sPlayers[i].name, text);
2017-11-12 22:59:36 +01:00
}
else
{
2018-09-01 22:03:21 +02:00
for (j = 0; j < PLAYER_NAME_LENGTH + 1; j++)
2018-07-01 11:15:42 +02:00
sPlayers[i].name[j] = gLinkPlayers[i].name[j];
2017-11-12 22:59:36 +01:00
}
}
}
else
{
2021-10-04 16:21:03 +02:00
// Local battle, just record own info
2018-07-01 11:15:42 +02:00
sPlayers[0].trainerId = (gSaveBlock2Ptr->playerTrainerId[0])
2021-10-04 16:21:03 +02:00
| (gSaveBlock2Ptr->playerTrainerId[1] << 8)
| (gSaveBlock2Ptr->playerTrainerId[2] << 16)
| (gSaveBlock2Ptr->playerTrainerId[3] << 24);
2017-11-12 22:59:36 +01:00
2018-07-01 11:15:42 +02:00
sPlayers[0].gender = gSaveBlock2Ptr->playerGender;
sPlayers[0].battlerId = 0;
sPlayers[0].language = gGameLanguage;
2017-11-12 22:59:36 +01:00
2018-09-01 22:03:21 +02:00
for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++)
2018-07-01 11:15:42 +02:00
sPlayers[0].name[i] = gSaveBlock2Ptr->playerName[i];
2017-11-12 22:59:36 +01:00
}
}
2017-11-13 00:10:34 +01:00
2018-02-08 11:17:41 +01:00
void RecordedBattle_SetBattlerAction(u8 battlerId, u8 action)
2017-11-13 00:10:34 +01:00
{
2021-01-23 02:03:21 +01:00
if (sBattlerRecordSizes[battlerId] < BATTLER_RECORD_SIZE && sRecordMode != B_RECORD_MODE_PLAYBACK)
sBattleRecords[battlerId][sBattlerRecordSizes[battlerId]++] = action;
2017-11-13 00:10:34 +01:00
}
2018-02-08 11:17:41 +01:00
void RecordedBattle_ClearBattlerAction(u8 battlerId, u8 bytesToClear)
2017-11-13 00:10:34 +01:00
{
s32 i;
for (i = 0; i < bytesToClear; i++)
{
2021-01-23 02:03:21 +01:00
sBattlerRecordSizes[battlerId]--;
sBattleRecords[battlerId][sBattlerRecordSizes[battlerId]] = 0xFF;
if (sBattlerRecordSizes[battlerId] == 0)
2017-11-13 00:10:34 +01:00
break;
}
}
2018-02-08 11:17:41 +01:00
u8 RecordedBattle_GetBattlerAction(u8 battlerId)
2017-11-13 00:10:34 +01:00
{
2018-07-01 11:15:42 +02:00
// Trying to read past array or invalid action byte, battle is over.
2021-01-23 02:03:21 +01:00
if (sBattlerRecordSizes[battlerId] >= BATTLER_RECORD_SIZE || sBattleRecords[battlerId][sBattlerRecordSizes[battlerId]] == 0xFF)
2017-11-13 00:10:34 +01:00
{
2018-01-16 22:12:38 +01:00
gSpecialVar_Result = gBattleOutcome = B_OUTCOME_PLAYER_TELEPORTED; // hah
2017-11-13 00:10:34 +01:00
ResetPaletteFadeControl();
2021-10-04 16:21:03 +02:00
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK);
2017-11-13 00:10:34 +01:00
SetMainCallback2(CB2_QuitRecordedBattle);
return 0xFF;
2017-11-13 00:10:34 +01:00
}
else
{
2021-01-23 02:03:21 +01:00
return sBattleRecords[battlerId][sBattlerRecordSizes[battlerId]++];
2017-11-13 00:10:34 +01:00
}
}
// Unused
static u8 GetRecordedBattleMode(void)
2017-11-13 00:10:34 +01:00
{
return sRecordMode;
2017-11-13 00:10:34 +01:00
}
2021-01-23 02:03:21 +01:00
u8 RecordedBattle_BufferNewBattlerData(u8 *dst)
2017-11-13 00:10:34 +01:00
{
u8 i, j;
u8 idx = 0;
2017-11-13 00:10:34 +01:00
2018-02-06 02:46:59 +01:00
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
2017-11-13 00:10:34 +01:00
{
2021-01-23 02:03:21 +01:00
if (sBattlerRecordSizes[i] != sBattlerPrevRecordSizes[i])
2017-11-13 00:10:34 +01:00
{
dst[idx++] = i;
2021-01-23 02:03:21 +01:00
dst[idx++] = sBattlerRecordSizes[i] - sBattlerPrevRecordSizes[i];
2017-11-13 00:10:34 +01:00
2021-01-23 02:03:21 +01:00
for (j = 0; j < sBattlerRecordSizes[i] - sBattlerPrevRecordSizes[i]; j++)
dst[idx++] = sBattleRecords[i][sBattlerPrevRecordSizes[i] + j];
2017-11-13 00:10:34 +01:00
2021-01-23 02:03:21 +01:00
sBattlerPrevRecordSizes[i] = sBattlerRecordSizes[i];
2017-11-13 00:10:34 +01:00
}
}
return idx;
2017-11-13 00:10:34 +01:00
}
2021-01-23 02:03:21 +01:00
void RecordedBattle_RecordAllBattlerData(u8 *src)
2017-11-13 00:10:34 +01:00
{
s32 i;
2021-01-23 02:03:21 +01:00
u8 idx = 2;
u8 size;
2017-11-13 00:10:34 +01:00
if (!(gBattleTypeFlags & BATTLE_TYPE_LINK))
return;
for (i = 0; i < GetLinkPlayerCount(); i++)
{
if ((gLinkPlayers[i].version & 0xFF) != VERSION_EMERALD)
return;
}
if (!(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER))
2017-11-13 00:10:34 +01:00
{
2021-01-23 02:03:21 +01:00
for (size = *src; size != 0;)
2017-11-13 00:10:34 +01:00
{
2021-01-23 02:03:21 +01:00
u8 battlerId = GetNextRecordedDataByte(src, &idx, &size);
u8 numActions = GetNextRecordedDataByte(src, &idx, &size);
2017-11-13 00:10:34 +01:00
2021-01-23 02:03:21 +01:00
for (i = 0; i < numActions; i++)
sBattleRecords[battlerId][sBattlerSavedRecordSizes[battlerId]++] = GetNextRecordedDataByte(src, &idx, &size);
2017-11-13 00:10:34 +01:00
}
}
}
2021-01-23 02:03:21 +01:00
static u8 GetNextRecordedDataByte(u8 *data, u8 *idx, u8 *size)
2017-11-13 00:10:34 +01:00
{
2021-01-23 02:03:21 +01:00
(*size)--;
return data[(*idx)++];
2017-11-13 00:10:34 +01:00
}
2017-11-13 18:07:23 +01:00
bool32 CanCopyRecordedBattleSaveData(void)
{
struct RecordedBattleSave *dst = AllocZeroed(sizeof(struct RecordedBattleSave));
2018-11-01 15:06:50 +01:00
bool32 ret = CopyRecordedBattleFromSave(dst);
2017-11-13 18:07:23 +01:00
Free(dst);
return ret;
}
2017-11-13 19:01:23 +01:00
static bool32 IsRecordedBattleSaveValid(struct RecordedBattleSave *save)
2017-11-13 18:07:23 +01:00
{
if (save->battleFlags == 0)
return FALSE;
if (save->battleFlags & ILLEGAL_BATTLE_TYPES)
return FALSE;
if (CalcByteArraySum((void*)(save), sizeof(*save) - 4) != save->checksum)
return FALSE;
return TRUE;
}
2021-10-29 04:54:41 +02:00
static bool32 RecordedBattleToSave(struct RecordedBattleSave *battleSave, struct RecordedBattleSave *saveSector)
2017-11-13 18:07:23 +01:00
{
2021-10-29 04:54:41 +02:00
memset(saveSector, 0, SECTOR_SIZE);
memcpy(saveSector, battleSave, sizeof(*battleSave));
2017-11-13 18:07:23 +01:00
2021-10-29 04:54:41 +02:00
saveSector->checksum = CalcByteArraySum((void*)(saveSector), sizeof(*saveSector) - 4);
2017-11-13 18:07:23 +01:00
2021-10-29 04:54:41 +02:00
if (TryWriteSpecialSaveSector(SECTOR_ID_RECORDED_BATTLE, (void*)(saveSector)) != SAVE_STATUS_OK)
2017-11-13 18:07:23 +01:00
return FALSE;
2018-11-01 15:06:50 +01:00
else
return TRUE;
2017-11-13 18:07:23 +01:00
}
2018-11-01 15:06:50 +01:00
bool32 MoveRecordedBattleToSaveData(void)
2017-11-13 18:07:23 +01:00
{
s32 i, j;
2018-11-01 15:06:50 +01:00
bool32 ret;
struct RecordedBattleSave *battleSave, *savSection;
2019-11-24 22:58:40 +01:00
u8 saveAttempts;
2018-11-01 15:06:50 +01:00
2019-11-24 22:58:40 +01:00
saveAttempts = 0;
2018-11-01 15:06:50 +01:00
battleSave = AllocZeroed(sizeof(struct RecordedBattleSave));
2021-10-04 16:21:03 +02:00
savSection = AllocZeroed(SECTOR_SIZE);
2017-11-13 18:07:23 +01:00
for (i = 0; i < PARTY_SIZE; i++)
{
battleSave->playerParty[i] = sSavedPlayerParty[i];
battleSave->opponentParty[i] = sSavedOpponentParty[i];
}
2018-02-06 02:46:59 +01:00
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
2017-11-13 18:07:23 +01:00
{
2018-09-01 22:03:21 +02:00
for (j = 0; j < PLAYER_NAME_LENGTH + 1; j++)
2018-07-01 11:15:42 +02:00
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;
battleSave->playersTrainerId[i] = sPlayers[i].trainerId;
2017-11-13 18:07:23 +01:00
}
battleSave->rngSeed = gRecordedBattleRngSeed;
2018-07-01 11:15:42 +02:00
if (sBattleFlags & BATTLE_TYPE_LINK)
2017-11-13 18:07:23 +01:00
{
2021-01-13 21:17:32 +01:00
battleSave->battleFlags = (sBattleFlags & ~(BATTLE_TYPE_LINK | BATTLE_TYPE_LINK_IN_BATTLE)) | BATTLE_TYPE_RECORDED_LINK;
2017-11-13 18:07:23 +01:00
2021-01-13 21:17:32 +01:00
// BATTLE_TYPE_RECORDED_IS_MASTER set indicates battle will play
// out from player's perspective (i.e. player with back to camera)
// Otherwise player will appear on "opponent" side
if (sBattleFlags & BATTLE_TYPE_IS_MASTER)
2017-11-13 18:07:23 +01:00
{
2021-01-13 21:17:32 +01:00
battleSave->battleFlags |= BATTLE_TYPE_RECORDED_IS_MASTER;
2017-11-13 18:07:23 +01:00
}
2018-07-01 11:15:42 +02:00
else if (sBattleFlags & BATTLE_TYPE_MULTI)
2017-11-13 18:07:23 +01:00
{
2018-07-01 11:15:42 +02:00
switch (sPlayers[0].battlerId)
2017-11-13 18:07:23 +01:00
{
case 0:
case 2:
2021-01-13 21:17:32 +01:00
if (!(sPlayers[gRecordedBattleMultiplayerId].battlerId & 1))
battleSave->battleFlags |= BATTLE_TYPE_RECORDED_IS_MASTER;
2017-11-13 18:07:23 +01:00
break;
case 1:
case 3:
2021-01-13 21:17:32 +01:00
if ((sPlayers[gRecordedBattleMultiplayerId].battlerId & 1))
battleSave->battleFlags |= BATTLE_TYPE_RECORDED_IS_MASTER;
2017-11-13 18:07:23 +01:00
break;
}
}
}
else
{
2018-07-01 11:15:42 +02:00
battleSave->battleFlags = sBattleFlags;
2017-11-13 18:07:23 +01:00
}
battleSave->opponentA = gTrainerBattleOpponent_A;
battleSave->opponentB = gTrainerBattleOpponent_B;
battleSave->partnerId = gPartnerTrainerId;
2021-01-13 21:17:32 +01:00
battleSave->multiplayerId = gRecordedBattleMultiplayerId;
2018-11-01 15:06:50 +01:00
battleSave->lvlMode = gSaveBlock2Ptr->frontier.lvlMode;
battleSave->frontierFacility = sFrontierFacility;
battleSave->frontierBrainSymbol = sFrontierBrainSymbol;
battleSave->battleScene = gSaveBlock2Ptr->optionsBattleSceneOff;
2017-11-13 18:07:23 +01:00
battleSave->textSpeed = gSaveBlock2Ptr->optionsTextSpeed;
2018-07-01 11:15:42 +02:00
battleSave->AI_scripts = sAI_Scripts;
2017-11-13 18:07:23 +01:00
2018-11-01 15:06:50 +01:00
if (gTrainerBattleOpponent_A >= TRAINER_RECORD_MIXING_FRIEND && gTrainerBattleOpponent_A < TRAINER_RECORD_MIXING_APPRENTICE)
2017-11-13 18:07:23 +01:00
{
2018-11-01 15:06:50 +01:00
for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++)
battleSave->recordMixFriendName[i] = gSaveBlock2Ptr->frontier.towerRecords[gTrainerBattleOpponent_A - TRAINER_RECORD_MIXING_FRIEND].name[i];
battleSave->recordMixFriendClass = gSaveBlock2Ptr->frontier.towerRecords[gTrainerBattleOpponent_A - TRAINER_RECORD_MIXING_FRIEND].facilityClass;
2017-11-13 18:07:23 +01:00
2018-11-01 15:06:50 +01:00
if (sBattleOutcome == B_OUTCOME_WON)
2017-11-13 18:07:23 +01:00
{
2019-11-19 17:36:38 +01:00
for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++)
2018-11-01 15:06:50 +01:00
battleSave->easyChatSpeech[i] = gSaveBlock2Ptr->frontier.towerRecords[gTrainerBattleOpponent_A - TRAINER_RECORD_MIXING_FRIEND].speechLost[i];
2017-11-13 18:07:23 +01:00
}
else
{
2019-11-19 17:36:38 +01:00
for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++)
2018-11-01 15:06:50 +01:00
battleSave->easyChatSpeech[i] = gSaveBlock2Ptr->frontier.towerRecords[gTrainerBattleOpponent_A - TRAINER_RECORD_MIXING_FRIEND].speechWon[i];
2017-11-13 18:07:23 +01:00
}
2018-11-01 15:06:50 +01:00
battleSave->recordMixFriendLanguage = gSaveBlock2Ptr->frontier.towerRecords[gTrainerBattleOpponent_A - TRAINER_RECORD_MIXING_FRIEND].language;
2017-11-13 18:07:23 +01:00
}
2018-11-01 15:06:50 +01:00
else if (gTrainerBattleOpponent_B >= TRAINER_RECORD_MIXING_FRIEND && gTrainerBattleOpponent_B < TRAINER_RECORD_MIXING_APPRENTICE)
2017-11-13 18:07:23 +01:00
{
2018-11-01 15:06:50 +01:00
for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++)
battleSave->recordMixFriendName[i] = gSaveBlock2Ptr->frontier.towerRecords[gTrainerBattleOpponent_B - TRAINER_RECORD_MIXING_FRIEND].name[i];
battleSave->recordMixFriendClass = gSaveBlock2Ptr->frontier.towerRecords[gTrainerBattleOpponent_B - TRAINER_RECORD_MIXING_FRIEND].facilityClass;
2017-11-13 18:07:23 +01:00
2018-11-01 15:06:50 +01:00
if (sBattleOutcome == B_OUTCOME_WON)
2017-11-13 18:07:23 +01:00
{
2019-11-19 17:36:38 +01:00
for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++)
2018-11-01 15:06:50 +01:00
battleSave->easyChatSpeech[i] = gSaveBlock2Ptr->frontier.towerRecords[gTrainerBattleOpponent_B - TRAINER_RECORD_MIXING_FRIEND].speechLost[i];
2017-11-13 18:07:23 +01:00
}
else
{
2019-11-19 17:36:38 +01:00
for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++)
2018-11-01 15:06:50 +01:00
battleSave->easyChatSpeech[i] = gSaveBlock2Ptr->frontier.towerRecords[gTrainerBattleOpponent_B - TRAINER_RECORD_MIXING_FRIEND].speechWon[i];
2017-11-13 18:07:23 +01:00
}
2018-11-01 15:06:50 +01:00
battleSave->recordMixFriendLanguage = gSaveBlock2Ptr->frontier.towerRecords[gTrainerBattleOpponent_B - TRAINER_RECORD_MIXING_FRIEND].language;
2017-11-13 18:07:23 +01:00
}
2018-11-01 15:06:50 +01:00
else if (gPartnerTrainerId >= TRAINER_RECORD_MIXING_FRIEND && gPartnerTrainerId < TRAINER_RECORD_MIXING_APPRENTICE)
2017-11-13 18:07:23 +01:00
{
2018-11-01 15:06:50 +01:00
for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++)
battleSave->recordMixFriendName[i] = gSaveBlock2Ptr->frontier.towerRecords[gPartnerTrainerId - TRAINER_RECORD_MIXING_FRIEND].name[i];
battleSave->recordMixFriendClass = gSaveBlock2Ptr->frontier.towerRecords[gPartnerTrainerId - TRAINER_RECORD_MIXING_FRIEND].facilityClass;
2017-11-13 18:07:23 +01:00
2018-11-01 15:06:50 +01:00
battleSave->recordMixFriendLanguage = gSaveBlock2Ptr->frontier.towerRecords[gPartnerTrainerId - TRAINER_RECORD_MIXING_FRIEND].language;
}
if (gTrainerBattleOpponent_A >= TRAINER_RECORD_MIXING_APPRENTICE)
{
battleSave->apprenticeId = gSaveBlock2Ptr->apprentices[gTrainerBattleOpponent_A - TRAINER_RECORD_MIXING_APPRENTICE].id;
2019-11-19 17:36:38 +01:00
for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++)
battleSave->easyChatSpeech[i] = gSaveBlock2Ptr->apprentices[gTrainerBattleOpponent_A - TRAINER_RECORD_MIXING_APPRENTICE].speechWon[i];
2018-11-01 15:06:50 +01:00
battleSave->apprenticeLanguage = gSaveBlock2Ptr->apprentices[gTrainerBattleOpponent_A - TRAINER_RECORD_MIXING_APPRENTICE].language;
}
else if (gTrainerBattleOpponent_B >= TRAINER_RECORD_MIXING_APPRENTICE)
{
battleSave->apprenticeId = gSaveBlock2Ptr->apprentices[gTrainerBattleOpponent_B - TRAINER_RECORD_MIXING_APPRENTICE].id;
2019-11-19 17:36:38 +01:00
for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++)
battleSave->easyChatSpeech[i] = gSaveBlock2Ptr->apprentices[gTrainerBattleOpponent_B - TRAINER_RECORD_MIXING_APPRENTICE].speechWon[i];
2018-11-01 15:06:50 +01:00
battleSave->apprenticeLanguage = gSaveBlock2Ptr->apprentices[gTrainerBattleOpponent_B - TRAINER_RECORD_MIXING_APPRENTICE].language;
}
else if (gPartnerTrainerId >= TRAINER_RECORD_MIXING_APPRENTICE)
{
battleSave->apprenticeId = gSaveBlock2Ptr->apprentices[gPartnerTrainerId - TRAINER_RECORD_MIXING_APPRENTICE].id;
battleSave->apprenticeLanguage = gSaveBlock2Ptr->apprentices[gPartnerTrainerId - TRAINER_RECORD_MIXING_APPRENTICE].language;
}
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
for (j = 0; j < BATTLER_RECORD_SIZE; j++)
battleSave->battleRecord[i][j] = sBattleRecords[i][j];
2017-11-13 18:07:23 +01:00
2018-11-01 15:06:50 +01:00
while (1)
{
ret = RecordedBattleToSave(battleSave, savSection);
if (ret == TRUE)
break;
2019-11-24 22:58:40 +01:00
saveAttempts++;
if (saveAttempts >= 3)
2018-11-01 15:06:50 +01:00
break;
}
2017-11-13 18:07:23 +01:00
2018-11-01 15:06:50 +01:00
free(battleSave);
free(savSection);
return ret;
2017-11-13 18:07:23 +01:00
}
2021-10-29 04:54:41 +02:00
static bool32 TryCopyRecordedBattleSaveData(struct RecordedBattleSave *dst, struct SaveSector *saveBuffer)
2017-11-13 18:07:23 +01:00
{
2021-10-29 04:54:41 +02:00
if (TryReadSpecialSaveSector(SECTOR_ID_RECORDED_BATTLE, (void*)(saveBuffer)) != SAVE_STATUS_OK)
2017-11-13 18:07:23 +01:00
return FALSE;
memcpy(dst, saveBuffer, sizeof(struct RecordedBattleSave));
if (!IsRecordedBattleSaveValid(dst))
return FALSE;
return TRUE;
}
2018-11-01 15:06:50 +01:00
static bool32 CopyRecordedBattleFromSave(struct RecordedBattleSave *dst)
2017-11-13 18:07:23 +01:00
{
2021-10-29 04:54:41 +02:00
struct SaveSector *savBuffer = AllocZeroed(SECTOR_SIZE);
2017-11-13 18:07:23 +01:00
bool32 ret = TryCopyRecordedBattleSaveData(dst, savBuffer);
Free(savBuffer);
return ret;
}
static void CB2_RecordedBattleEnd(void)
{
2018-11-01 15:06:50 +01:00
gSaveBlock2Ptr->frontier.lvlMode = sLvlMode;
2017-11-13 18:07:23 +01:00
gBattleOutcome = 0;
gBattleTypeFlags = 0;
gTrainerBattleOpponent_A = 0;
gTrainerBattleOpponent_B = 0;
gPartnerTrainerId = 0;
RecordedBattle_RestoreSavedParties();
SetMainCallback2(sCallback2_AfterRecordedBattle);
}
#define tFramesToWait data[0]
static void Task_StartAfterCountdown(u8 taskId)
{
if (--gTasks[taskId].tFramesToWait == 0)
{
gMain.savedCallback = CB2_RecordedBattleEnd;
SetMainCallback2(CB2_InitBattle);
DestroyTask(taskId);
}
}
2018-11-01 15:06:50 +01:00
static void SetVariablesForRecordedBattle(struct RecordedBattleSave *src)
2017-11-13 18:07:23 +01:00
{
bool8 var;
s32 i, j;
ZeroPlayerPartyMons();
ZeroEnemyPartyMons();
for (i = 0; i < PARTY_SIZE; i++)
{
gPlayerParty[i] = src->playerParty[i];
gEnemyParty[i] = src->opponentParty[i];
}
2018-02-06 02:46:59 +01:00
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
2017-11-13 18:07:23 +01:00
{
2018-09-01 22:03:21 +02:00
for (var = FALSE, j = 0; j < PLAYER_NAME_LENGTH + 1; j++)
2017-11-13 18:07:23 +01:00
{
gLinkPlayers[i].name[j] = src->playersName[i][j];
if (src->playersName[i][j] == EOS)
var = TRUE;
}
gLinkPlayers[i].gender = src->playersGender[i];
gLinkPlayers[i].language = src->playersLanguage[i];
2018-07-22 12:49:49 +02:00
gLinkPlayers[i].id = src->playersBattlers[i];
2017-11-13 18:07:23 +01:00
gLinkPlayers[i].trainerId = src->playersTrainerId[i];
if (var)
ConvertInternationalString(gLinkPlayers[i].name, gLinkPlayers[i].language);
}
gRecordedBattleRngSeed = src->rngSeed;
gBattleTypeFlags = src->battleFlags | BATTLE_TYPE_RECORDED;
gTrainerBattleOpponent_A = src->opponentA;
gTrainerBattleOpponent_B = src->opponentB;
gPartnerTrainerId = src->partnerId;
2021-01-13 21:17:32 +01:00
gRecordedBattleMultiplayerId = src->multiplayerId;
2018-11-01 15:06:50 +01:00
sLvlMode = gSaveBlock2Ptr->frontier.lvlMode;
sFrontierFacility = src->frontierFacility;
sFrontierBrainSymbol = src->frontierBrainSymbol;
sBattleScene = src->battleScene;
2018-07-01 11:15:42 +02:00
sTextSpeed = src->textSpeed;
sAI_Scripts = src->AI_scripts;
2017-11-13 18:07:23 +01:00
2018-11-01 15:06:50 +01:00
for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++)
sRecordMixFriendName[i] = src->recordMixFriendName[i];
2017-11-13 18:07:23 +01:00
2018-11-01 15:06:50 +01:00
sRecordMixFriendClass = src->recordMixFriendClass;
sApprenticeId = src->apprenticeId;
2018-11-01 21:31:10 +01:00
sRecordMixFriendLanguage = src->recordMixFriendLanguage;
sApprenticeLanguage = src->apprenticeLanguage;
2017-11-13 18:07:23 +01:00
2021-10-04 16:21:03 +02:00
for (i = 0; i < EASY_CHAT_BATTLE_WORDS_COUNT; i++)
2018-11-01 15:06:50 +01:00
sEasyChatSpeech[i] = src->easyChatSpeech[i];
2017-11-13 18:07:23 +01:00
2018-11-01 15:06:50 +01:00
gSaveBlock2Ptr->frontier.lvlMode = src->lvlMode;
2017-11-13 18:07:23 +01:00
2018-02-06 02:46:59 +01:00
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
2018-02-11 21:05:42 +01:00
for (j = 0; j < BATTLER_RECORD_SIZE; j++)
2017-11-13 18:07:23 +01:00
sBattleRecords[i][j] = src->battleRecord[i][j];
}
void PlayRecordedBattle(void (*CB2_After)(void))
{
struct RecordedBattleSave *battleSave = AllocZeroed(sizeof(struct RecordedBattleSave));
2018-11-01 15:06:50 +01:00
if (CopyRecordedBattleFromSave(battleSave) == TRUE)
2017-11-13 18:07:23 +01:00
{
u8 taskId;
RecordedBattle_SaveParties();
2018-11-01 15:06:50 +01:00
SetVariablesForRecordedBattle(battleSave);
2017-11-13 18:07:23 +01:00
taskId = CreateTask(Task_StartAfterCountdown, 1);
gTasks[taskId].tFramesToWait = 128;
sCallback2_AfterRecordedBattle = CB2_After;
PlayMapChosenOrBattleBGM(FALSE);
SetMainCallback2(CB2_RecordedBattle);
}
Free(battleSave);
}
#undef tFramesToWait
static void CB2_RecordedBattle(void)
{
AnimateSprites();
BuildOamBuffer();
RunTasks();
}
u8 GetRecordedBattleFrontierFacility(void)
2017-11-13 18:07:23 +01:00
{
2018-07-01 11:15:42 +02:00
return sFrontierFacility;
2017-11-13 18:07:23 +01:00
}
2018-11-01 15:06:50 +01:00
u8 GetRecordedBattleFronterBrainSymbol(void)
2017-11-13 18:07:23 +01:00
{
2018-11-01 15:06:50 +01:00
return sFrontierBrainSymbol;
2017-11-13 18:07:23 +01:00
}
void RecordedBattle_SaveParties(void)
{
s32 i;
for (i = 0; i < PARTY_SIZE; i++)
{
sSavedPlayerParty[i] = gPlayerParty[i];
sSavedOpponentParty[i] = gEnemyParty[i];
}
}
2017-11-13 19:01:23 +01:00
static void RecordedBattle_RestoreSavedParties(void)
2017-11-13 18:07:23 +01:00
{
s32 i;
for (i = 0; i < PARTY_SIZE; i++)
{
gPlayerParty[i] = sSavedPlayerParty[i];
gEnemyParty[i] = sSavedOpponentParty[i];
}
}
2018-02-08 11:17:41 +01:00
u8 GetActiveBattlerLinkPlayerGender(void)
2017-11-13 18:07:23 +01:00
{
s32 i;
for (i = 0; i < MAX_LINK_PLAYERS; i++)
{
2018-07-22 12:49:49 +02:00
if (gLinkPlayers[i].id == gActiveBattler)
2017-11-13 18:07:23 +01:00
break;
}
if (i != MAX_LINK_PLAYERS)
return gLinkPlayers[i].gender;
return 0;
}
2021-03-12 22:55:58 +01:00
void RecordedBattle_ClearFrontierPassFlag(void)
2017-11-13 18:07:23 +01:00
{
2021-03-12 22:55:58 +01:00
sFrontierPassFlag = 0;
2017-11-13 18:07:23 +01:00
}
2021-03-12 22:55:58 +01:00
// Set sFrontierPassFlag to received state of FLAG_SYS_FRONTIER_PASS
void RecordedBattle_SetFrontierPassFlagFromHword(u16 flags)
2017-11-13 18:07:23 +01:00
{
sFrontierPassFlag |= (flags & (1 << 15)) >> 15;
2017-11-13 18:07:23 +01:00
}
2021-03-12 22:55:58 +01:00
u8 RecordedBattle_GetFrontierPassFlag(void)
2017-11-13 18:07:23 +01:00
{
2021-03-12 22:55:58 +01:00
return sFrontierPassFlag;
2017-11-13 18:07:23 +01:00
}
2018-11-01 15:06:50 +01:00
u8 GetBattleSceneInRecordedBattle(void)
2017-11-13 18:07:23 +01:00
{
2018-11-01 15:06:50 +01:00
return sBattleScene;
2017-11-13 18:07:23 +01:00
}
u8 GetTextSpeedInRecordedBattle(void)
{
2018-07-01 11:15:42 +02:00
return sTextSpeed;
2017-11-13 18:07:23 +01:00
}
2018-02-08 11:17:41 +01:00
void RecordedBattle_CopyBattlerMoves(void)
2017-11-13 18:07:23 +01:00
{
s32 i;
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
2017-11-13 18:07:23 +01:00
return;
2021-01-13 21:17:32 +01:00
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK))
2017-11-13 18:07:23 +01:00
return;
if (sRecordMode == B_RECORD_MODE_PLAYBACK)
2017-11-13 18:07:23 +01:00
return;
for (i = 0; i < MAX_MON_MOVES; i++)
2018-07-01 11:15:42 +02:00
sPlayerMonMoves[gActiveBattler / 2][i] = gBattleMons[gActiveBattler].moves[i];
2017-11-13 18:07:23 +01:00
}
// 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.
2017-11-13 18:07:23 +01:00
#define ACTION_MOVE_CHANGE 6
void RecordedBattle_CheckMovesetChanges(u8 mode)
2017-11-13 18:07:23 +01:00
{
2018-02-08 11:17:41 +01:00
s32 battlerId, j, k;
2017-11-13 18:07:23 +01:00
2021-01-13 21:17:32 +01:00
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK))
2017-11-13 18:07:23 +01:00
return;
2018-02-08 11:17:41 +01:00
for (battlerId = 0; battlerId < gBattlersCount; battlerId++)
2017-11-13 18:07:23 +01:00
{
2021-10-04 16:21:03 +02:00
// Player's side only
if (GetBattlerSide(battlerId) != B_SIDE_OPPONENT)
2017-11-13 18:07:23 +01:00
{
if (mode == B_RECORD_MODE_RECORDING)
2017-11-13 18:07:23 +01:00
{
// Check if any of the battler's moves have changed.
for (j = 0; j < MAX_MON_MOVES; j++)
2017-11-13 18:07:23 +01:00
{
2018-07-01 11:15:42 +02:00
if (gBattleMons[battlerId].moves[j] != sPlayerMonMoves[battlerId / 2][j])
2017-11-13 18:07:23 +01:00
break;
}
2021-10-04 16:21:03 +02:00
if (j != MAX_MON_MOVES)
2017-11-13 18:07:23 +01:00
{
2021-10-04 16:21:03 +02:00
// At least one of the moves has been changed
2018-02-08 11:17:41 +01:00
RecordedBattle_SetBattlerAction(battlerId, ACTION_MOVE_CHANGE);
for (j = 0; j < MAX_MON_MOVES; j++)
2017-11-13 18:07:23 +01:00
{
for (k = 0; k < MAX_MON_MOVES; k++)
2017-11-13 18:07:23 +01:00
{
2018-07-01 11:15:42 +02:00
if (gBattleMons[battlerId].moves[j] == sPlayerMonMoves[battlerId / 2][k])
2017-11-13 18:07:23 +01:00
{
2018-02-08 11:17:41 +01:00
RecordedBattle_SetBattlerAction(battlerId, k);
2017-11-13 18:07:23 +01:00
break;
}
}
}
}
}
else // B_RECORD_MODE_PLAYBACK
2017-11-13 18:07:23 +01:00
{
2021-01-23 02:03:21 +01:00
if (sBattleRecords[battlerId][sBattlerRecordSizes[battlerId]] == ACTION_MOVE_CHANGE)
2017-11-13 18:07:23 +01:00
{
2019-09-08 17:53:48 +02:00
u8 ppBonuses[MAX_MON_MOVES];
u8 moveSlots[MAX_MON_MOVES];
u8 mimickedMoveSlots[MAX_MON_MOVES];
struct ChooseMoveStruct movePp;
u8 ppBonusSet;
2017-11-13 18:07:23 +01:00
// We know the current action is ACTION_MOVE_CHANGE, retrieve
// it without saving it to move on to the next action.
2018-02-08 11:17:41 +01:00
RecordedBattle_GetBattlerAction(battlerId);
for (j = 0; j < MAX_MON_MOVES; j++)
2021-10-04 16:21:03 +02:00
ppBonuses[j] = ((gBattleMons[battlerId].ppBonuses & (3 << (j << 1))) >> (j << 1));
for (j = 0; j < MAX_MON_MOVES; j++)
2017-11-13 18:07:23 +01:00
{
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;
2017-11-13 18:07:23 +01:00
}
for (j = 0; j < MAX_MON_MOVES; j++)
2017-11-13 18:07:23 +01:00
{
2018-02-08 11:17:41 +01:00
gBattleMons[battlerId].moves[j] = movePp.moves[j];
gBattleMons[battlerId].pp[j] = movePp.currentPp[j];
2017-11-13 18:07:23 +01:00
}
2018-02-08 11:17:41 +01:00
gBattleMons[battlerId].ppBonuses = 0;
gDisableStructs[battlerId].mimickedMoves = 0;
for (j = 0; j < MAX_MON_MOVES; j++)
2017-11-13 18:07:23 +01:00
{
gBattleMons[battlerId].ppBonuses |= movePp.maxPp[j] << (j << 1);
gDisableStructs[battlerId].mimickedMoves |= mimickedMoveSlots[j] << j;
2017-11-13 18:07:23 +01:00
}
2018-02-08 11:17:41 +01:00
if (!(gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED))
2017-11-13 18:07:23 +01:00
{
for (j = 0; j < MAX_MON_MOVES; j++)
ppBonuses[j] = (GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP_BONUSES, NULL) & ((3 << (j << 1)))) >> (j << 1);
2021-10-04 16:21:03 +02:00
for (j = 0; j < MAX_MON_MOVES; j++)
2017-11-13 18:07:23 +01:00
{
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]];
2017-11-13 18:07:23 +01:00
}
for (j = 0; j < MAX_MON_MOVES; j++)
2017-11-13 18:07:23 +01:00
{
2018-02-08 11:17:41 +01:00
SetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_MOVE1 + j, &movePp.moves[j]);
SetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP1 + j, &movePp.currentPp[j]);
2017-11-13 18:07:23 +01:00
}
ppBonusSet = 0;
for (j = 0; j < MAX_MON_MOVES; j++)
ppBonusSet |= movePp.maxPp[j] << (j << 1);
2021-10-04 16:21:03 +02:00
SetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PP_BONUSES, &ppBonusSet);
2017-11-13 18:07:23 +01:00
}
2018-02-08 11:17:41 +01:00
gChosenMoveByBattler[battlerId] = gBattleMons[battlerId].moves[*(gBattleStruct->chosenMovePositions + battlerId)];
2017-11-13 18:07:23 +01:00
}
}
}
}
}
2017-11-13 19:01:23 +01:00
u32 GetAiScriptsInRecordedBattle(void)
{
2018-07-01 11:15:42 +02:00
return sAI_Scripts;
2017-11-13 19:01:23 +01:00
}
2021-10-04 16:21:03 +02:00
// Used to determine when the player is allowed to press B to end a recorded battle's playback
void RecordedBattle_SetPlaybackFinished(void)
2017-11-13 19:01:23 +01:00
{
2021-10-04 16:21:03 +02:00
sIsPlaybackFinished = TRUE;
2017-11-13 19:01:23 +01:00
}
2021-10-04 16:21:03 +02:00
bool8 RecordedBattle_CanStopPlayback(void)
2017-11-13 19:01:23 +01:00
{
2021-10-04 16:21:03 +02:00
return (sIsPlaybackFinished == FALSE);
2017-11-13 19:01:23 +01:00
}
2020-12-24 22:18:47 +01:00
void GetRecordedBattleRecordMixFriendName(u8 *dst)
2017-11-13 19:01:23 +01:00
{
s32 i;
2021-10-04 16:21:03 +02:00
for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++)
2018-11-01 15:06:50 +01:00
dst[i] = sRecordMixFriendName[i];
2021-10-04 16:21:03 +02:00
dst[PLAYER_NAME_LENGTH] = EOS;
2018-11-01 21:31:10 +01:00
ConvertInternationalString(dst, sRecordMixFriendLanguage);
2017-11-13 19:01:23 +01:00
}
2018-11-01 15:06:50 +01:00
u8 GetRecordedBattleRecordMixFriendClass(void)
2017-11-13 19:01:23 +01:00
{
2018-11-01 15:06:50 +01:00
return sRecordMixFriendClass;
2017-11-13 19:01:23 +01:00
}
2018-11-01 15:06:50 +01:00
u8 GetRecordedBattleApprenticeId(void)
2017-11-13 19:01:23 +01:00
{
2018-11-01 15:06:50 +01:00
return sApprenticeId;
2017-11-13 19:01:23 +01:00
}
2018-11-01 15:06:50 +01:00
u8 GetRecordedBattleRecordMixFriendLanguage(void)
2017-11-13 19:01:23 +01:00
{
2018-11-01 21:31:10 +01:00
return sRecordMixFriendLanguage;
2017-11-13 19:01:23 +01:00
}
2018-11-01 15:06:50 +01:00
u8 GetRecordedBattleApprenticeLanguage(void)
2017-11-13 19:01:23 +01:00
{
2018-11-01 21:31:10 +01:00
return sApprenticeLanguage;
2017-11-13 19:01:23 +01:00
}
2018-11-01 15:06:50 +01:00
void RecordedBattle_SaveBattleOutcome(void)
2017-11-13 19:01:23 +01:00
{
2018-11-01 15:06:50 +01:00
sBattleOutcome = gBattleOutcome;
2017-11-13 19:01:23 +01:00
}
2018-11-01 15:06:50 +01:00
u16 *GetRecordedBattleEasyChatSpeech(void)
2017-11-13 19:01:23 +01:00
{
2018-11-01 15:06:50 +01:00
return sEasyChatSpeech;
2017-11-13 19:01:23 +01:00
}