sync battle_controllers.c

This commit is contained in:
cawtds
2025-01-07 21:52:43 +01:00
parent ea7b00786e
commit c393f5dc07
6 changed files with 279 additions and 46 deletions

View File

@@ -5,6 +5,7 @@ void AllocateBattleSpritesData(void);
void FreeBattleSpritesData(void);
void SpriteCB_WaitForBattlerBallReleaseAnim(struct Sprite *sprite);
void SpriteCB_TrainerSlideIn(struct Sprite *sprite);
void SpriteCB_TrainerSpawn(struct Sprite *sprite);
void InitAndLaunchChosenStatusAnimation(u32 battler, bool8 isStatus2, u32 status);
bool8 TryHandleLaunchBattleTableAnimation(u8 activeBattler, u8 atkBattler, u8 defBattler, u8 tableId, u16 argument);
void InitAndLaunchSpecialAnimation(u8 activeBattler, u8 atkBattler, u8 defBattler, u8 tableId);

View File

@@ -256,7 +256,7 @@ enum
TRAINER_SLIDE_DYNAMAX,
};
void BufferStringBattle(u32 battler, u16 stringID);
void BufferStringBattle(u16 stringID, u32 battler);
u32 BattleStringExpandPlaceholdersToDisplayedString(const u8 *src);
u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize);
void BattleHandleAddTextPrinter(const u8 *text, u8 arg1);

View File

@@ -699,7 +699,7 @@ static void OakOldManHandlePrintString(u32 battler)
}
else
{
BufferStringBattle(battler, *stringId);
BufferStringBattle(*stringId, battler);
if (BattleStringShouldBeColored(*stringId))
BattlePutTextOnWindow(gDisplayedStringBattle, (B_WIN_MSG | B_TEXT_FLAG_NPC_CONTEXT_FONT));
else

View File

@@ -4,6 +4,7 @@
#include "battle_ai_util.h"
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_gfx_sfx_util.h"
#include "battle_interface.h"
#include "battle_message.h"
#include "battle_setup.h"
@@ -13,14 +14,13 @@
#include "link_rfu.h"
#include "palette.h"
#include "party_menu.h"
#include "pokeball.h"
#include "recorded_battle.h"
#include "sound.h"
#include "string_util.h"
#include "sound.h"
#include "task.h"
#include "test_runner.h"
#include "text.h"
#include "util.h"
#include "text.h"
#include "constants/abilities.h"
#include "constants/battle_string_ids.h"
#include "constants/songs.h"
@@ -28,12 +28,11 @@
static EWRAM_DATA u8 sLinkSendTaskId = 0;
static EWRAM_DATA u8 sLinkReceiveTaskId = 0;
static EWRAM_DATA u8 sUnused = 0; // Debug? Never read
EWRAM_DATA struct UnusedControllerStruct gUnusedControllerStruct = {}; // Debug? Unused code that writes to it, never read
void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(u32 battler);
u8 gBattleControllerData[MAX_BATTLERS_COUNT];
void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(u32 battler); // Controller's buffer complete function for each battler
COMMON_DATA void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(u32 battler) = {0};
COMMON_DATA u8 gBattleControllerData[MAX_BATTLERS_COUNT] = {0}; // Used by the battle controllers to store misc sprite/task IDs for each battler
COMMON_DATA void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(u32 battler) = {0}; // Controller's buffer complete function for each battler
static void CreateTasksForSendRecvLinkBuffers(void);
static void InitLinkBtlControllers(void);
@@ -103,6 +102,12 @@ void InitBattleControllers(void)
for (i = 0; i < gBattlersCount; i++)
BufferBattlePartyCurrentOrderBySide(i, 0);
}
// for (i = 0; i < sizeof(gBattleStruct->tvMovePoints); i++)
// *((u8 *)(&gBattleStruct->tvMovePoints) + i) = 0;
// for (i = 0; i < sizeof(gBattleStruct->tv); i++)
// *((u8 *)(&gBattleStruct->tv) + i) = 0;
}
static void InitSinglePlayerBtlControllers(void)
@@ -180,7 +185,7 @@ static void InitSinglePlayerBtlControllers(void)
gBattlerPartyIndexes[3] = 3;
}
}
else if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
else if (!IsDoubleBattle())
{
gBattleMainFunc = BeginBattleIntro;
@@ -422,7 +427,7 @@ static void InitLinkBtlControllers(void)
s32 i;
u8 multiplayerId;
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
if (!IsDoubleBattle())
{
if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)
{
@@ -447,7 +452,7 @@ static void InitLinkBtlControllers(void)
gBattlersCount = 2;
}
}
else if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
else if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && IsDoubleBattle())
{
if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)
{
@@ -484,6 +489,52 @@ static void InitLinkBtlControllers(void)
gBattlersCount = MAX_BATTLERS_COUNT;
}
}
else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
{
if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)
{
gBattleMainFunc = BeginBattleIntro;
gBattlerControllerFuncs[0] = SetControllerToPlayer;
gBattlerPositions[0] = B_POSITION_PLAYER_LEFT;
gBattlerControllerFuncs[1] = SetControllerToOpponent;
gBattlerPositions[1] = B_POSITION_OPPONENT_LEFT;
gBattlerControllerFuncs[2] = SetControllerToLinkPartner;
gBattlerPositions[2] = B_POSITION_PLAYER_RIGHT;
gBattlerControllerFuncs[3] = SetControllerToOpponent;
gBattlerPositions[3] = B_POSITION_OPPONENT_RIGHT;
gBattlersCount = MAX_BATTLERS_COUNT;
}
else
{
gBattlerControllerFuncs[0] = SetControllerToLinkPartner;
gBattlerPositions[0] = B_POSITION_PLAYER_LEFT;
gBattlerControllerFuncs[1] = SetControllerToLinkOpponent;
gBattlerPositions[1] = B_POSITION_OPPONENT_LEFT;
gBattlerControllerFuncs[2] = SetControllerToPlayer;
gBattlerPositions[2] = B_POSITION_PLAYER_RIGHT;
gBattlerControllerFuncs[3] = SetControllerToLinkOpponent;
gBattlerPositions[3] = B_POSITION_OPPONENT_RIGHT;
gBattlersCount = MAX_BATTLERS_COUNT;
}
BufferBattlePartyCurrentOrderBySide(0, 0);
BufferBattlePartyCurrentOrderBySide(1, 0);
BufferBattlePartyCurrentOrderBySide(2, 1);
BufferBattlePartyCurrentOrderBySide(3, 1);
gBattlerPartyIndexes[0] = 0;
gBattlerPartyIndexes[1] = 0;
gBattlerPartyIndexes[2] = 3;
gBattlerPartyIndexes[3] = 3;
}
else
{
multiplayerId = GetMultiplayerId();
@@ -513,7 +564,7 @@ static void InitLinkBtlControllers(void)
case 0:
case 3:
gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = 0;
break;
case 1:
case 2:
@@ -533,12 +584,12 @@ static void InitLinkBtlControllers(void)
case 0:
case 3:
gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = 0;
break;
case 1:
case 2:
gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_PLAYER_RIGHT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_OPPONENT_RIGHT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = 3;
break;
}
}
@@ -550,12 +601,12 @@ static void InitLinkBtlControllers(void)
case 0:
case 3:
gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_OPPONENT_LEFT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_PLAYER_LEFT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = 0;
break;
case 1:
case 2:
gBattlerPositions[gLinkPlayers[i].id] = B_POSITION_OPPONENT_RIGHT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = B_POSITION_OPPONENT_RIGHT;
gBattlerPartyIndexes[gLinkPlayers[i].id] = 3;
break;
}
}
@@ -569,9 +620,10 @@ static void InitLinkBtlControllers(void)
bool32 IsValidForBattle(struct Pokemon *mon)
{
u32 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG);
return (species != SPECIES_NONE && species != SPECIES_EGG
&& GetMonData(mon, MON_DATA_HP) != 0
&& GetMonData(mon, MON_DATA_IS_EGG) == FALSE);
return (species != SPECIES_NONE
&& species != SPECIES_EGG
&& GetMonData(mon, MON_DATA_HP) != 0
&& GetMonData(mon, MON_DATA_IS_EGG) == FALSE);
}
static void SetBattlePartyIds(void)
@@ -674,8 +726,6 @@ static void CreateTasksForSendRecvLinkBuffers(void)
gTasks[sLinkReceiveTaskId].data[13] = 0;
gTasks[sLinkReceiveTaskId].data[14] = 0;
gTasks[sLinkReceiveTaskId].data[15] = 0;
sUnused = 0;
}
enum
@@ -804,7 +854,7 @@ void TryReceiveLinkBattleData(void)
DestroyTask_RfuIdle();
for (i = 0; i < GetLinkPlayerCount(); i++)
{
if (GetBlockReceivedStatus() & gBitTable[i])
if (GetBlockReceivedStatus() & (1 << (i)))
{
ResetBlockReceivedFlag(i);
recvBuffer = (u8 *)gBlockRecvBuffer[i];
@@ -834,7 +884,7 @@ void TryReceiveLinkBattleData(void)
static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId)
{
u16 blockSize;
u8 battlerId;
u8 battler;
u8 var;
if (gTasks[taskId].data[15] != gTasks[taskId].data[14])
@@ -845,17 +895,17 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId)
gTasks[taskId].data[12] = 0;
gTasks[taskId].data[15] = 0;
}
battlerId = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_ACTIVE_BATTLER];
battler = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_ACTIVE_BATTLER];
blockSize = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_LO] | (gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_HI] << 8);
switch (gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 0])
{
case 0:
if (gBattleControllerExecFlags & gBitTable[battlerId])
if (gBattleControllerExecFlags & (1u << battler))
return;
memcpy(gBattleResources->bufferA[battlerId], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize);
MarkBattlerReceivedLinkData(battlerId);
memcpy(gBattleResources->bufferA[battler], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize);
MarkBattlerReceivedLinkData(battler);
if (!(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER))
{
@@ -866,11 +916,11 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId)
}
break;
case 1:
memcpy(gBattleResources->bufferB[battlerId], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize);
memcpy(gBattleResources->bufferB[battler], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize);
break;
case 2:
var = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA];
gBattleControllerExecFlags &= ~(gBitTable[battlerId] << (var * 4));
gBattleControllerExecFlags &= ~(1u << (battler + var * 4));
break;
}
@@ -887,6 +937,15 @@ void BtlController_EmitGetMonData(u32 battler, u32 bufferId, u8 requestId, u8 mo
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
static void UNUSED BtlController_EmitGetRawMonData(u32 battler, u32 bufferId, u8 monId, u8 bytes)
{
gBattleResources->transferBuffer[0] = CONTROLLER_GETRAWMONDATA;
gBattleResources->transferBuffer[1] = monId;
gBattleResources->transferBuffer[2] = bytes;
gBattleResources->transferBuffer[3] = 0;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
void BtlController_EmitSetMonData(u32 battler, u32 bufferId, u8 requestId, u8 monToCheck, u8 bytes, void *data)
{
s32 i;
@@ -899,6 +958,18 @@ void BtlController_EmitSetMonData(u32 battler, u32 bufferId, u8 requestId, u8 mo
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 3 + bytes);
}
static void UNUSED BtlController_EmitSetRawMonData(u32 battler, u32 bufferId, u8 monId, u8 bytes, void *data)
{
s32 i;
gBattleResources->transferBuffer[0] = CONTROLLER_SETRAWMONDATA;
gBattleResources->transferBuffer[1] = monId;
gBattleResources->transferBuffer[2] = bytes;
for (i = 0; i < bytes; i++)
gBattleResources->transferBuffer[3 + i] = *(u8 *)(data++);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, bytes + 3);
}
void BtlController_EmitLoadMonSprite(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_LOADMONSPRITE;
@@ -960,6 +1031,24 @@ void BtlController_EmitFaintAnimation(u32 battler, u32 bufferId)
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
static void UNUSED BtlController_EmitPaletteFade(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_PALETTEFADE;
gBattleResources->transferBuffer[1] = CONTROLLER_PALETTEFADE;
gBattleResources->transferBuffer[2] = CONTROLLER_PALETTEFADE;
gBattleResources->transferBuffer[3] = CONTROLLER_PALETTEFADE;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
static void UNUSED BtlController_EmitSuccessBallThrowAnim(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_SUCCESSBALLTHROWANIM;
gBattleResources->transferBuffer[1] = CONTROLLER_SUCCESSBALLTHROWANIM;
gBattleResources->transferBuffer[2] = CONTROLLER_SUCCESSBALLTHROWANIM;
gBattleResources->transferBuffer[3] = CONTROLLER_SUCCESSBALLTHROWANIM;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
void BtlController_EmitBallThrowAnim(u32 battler, u32 bufferId, u8 caseId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_BALLTHROWANIM;
@@ -967,6 +1056,17 @@ void BtlController_EmitBallThrowAnim(u32 battler, u32 bufferId, u8 caseId)
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 2);
}
static void UNUSED BtlController_EmitPause(u32 battler, u32 bufferId, u8 toWait, void *data)
{
s32 i;
gBattleResources->transferBuffer[0] = CONTROLLER_PAUSE;
gBattleResources->transferBuffer[1] = toWait;
for (i = 0; i < toWait * 3; i++)
gBattleResources->transferBuffer[2 + i] = *(u8 *)(data++);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, toWait * 3 + 2);
}
void BtlController_EmitMoveAnimation(u32 battler, u32 bufferId, u16 move, u8 turnOfMove, u16 movePower, s32 dmg, u8 friendship, struct DisableStruct *disableStructPtr, u8 multihit)
{
gBattleResources->transferBuffer[0] = CONTROLLER_MOVEANIMATION;
@@ -980,7 +1080,7 @@ void BtlController_EmitMoveAnimation(u32 battler, u32 bufferId, u16 move, u8 tur
gBattleResources->transferBuffer[8] = (dmg & 0x00FF0000) >> 16;
gBattleResources->transferBuffer[9] = (dmg & 0xFF000000) >> 24;
gBattleResources->transferBuffer[10] = friendship;
gBattleResources->transferBuffer[11] = multihit; // multihit in pokeem
gBattleResources->transferBuffer[11] = multihit;
if (WEATHER_HAS_EFFECT)
{
gBattleResources->transferBuffer[12] = gBattleWeather;
@@ -1016,7 +1116,7 @@ void BtlController_EmitPrintString(u32 battler, u32 bufferId, u16 stringID)
stringInfo->bakScriptPartyIdx = gBattleStruct->scriptPartyIdx;
stringInfo->hpScale = gBattleStruct->hpScale;
stringInfo->itemEffectBattler = gPotentialItemEffectBattler;
stringInfo->moveType = gMovesInfo[gCurrentMove].type;
stringInfo->moveType = GetMoveType(gCurrentMove);
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
stringInfo->abilities[i] = gBattleMons[i].ability;
@@ -1068,6 +1168,17 @@ void BtlController_EmitChooseAction(u32 battler, u32 bufferId, u8 action, u16 it
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
// Only used by the forfeit prompt in the Battle Frontier
// For other Yes/No boxes in battle, see Cmd_yesnobox
void BtlController_EmitYesNoBox(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_YESNOBOX;
gBattleResources->transferBuffer[1] = CONTROLLER_YESNOBOX;
gBattleResources->transferBuffer[2] = CONTROLLER_YESNOBOX;
gBattleResources->transferBuffer[3] = CONTROLLER_YESNOBOX;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
void BtlController_EmitChooseMove(u32 battler, u32 bufferId, bool8 isDoubleBattle, bool8 NoPpNumber, struct ChooseMoveStruct *movePpData)
{
s32 i;
@@ -1102,9 +1213,19 @@ void BtlController_EmitChoosePokemon(u32 battler, u32 bufferId, u8 caseId, u8 sl
gBattleResources->transferBuffer[7] = (abilityId >> 8) & 0xFF;
for (i = 0; i < 3; i++)
gBattleResources->transferBuffer[4 + i] = data[i];
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 8);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 8); // Only 7 bytes were written.
}
static void UNUSED BtlController_EmitCmd23(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_23;
gBattleResources->transferBuffer[1] = CONTROLLER_23;
gBattleResources->transferBuffer[2] = CONTROLLER_23;
gBattleResources->transferBuffer[3] = CONTROLLER_23;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
// why is the argument u16 if it's being cast to s16 anyway?
void BtlController_EmitHealthBarUpdate(u32 battler, u32 bufferId, u16 hpValue)
{
gBattleResources->transferBuffer[0] = CONTROLLER_HEALTHBARUPDATE;
@@ -1150,6 +1271,13 @@ void BtlController_EmitStatusAnimation(u32 battler, u32 bufferId, bool8 status2,
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 6);
}
static void UNUSED BtlController_EmitStatusXor(u32 battler, u32 bufferId, u8 b)
{
gBattleResources->transferBuffer[0] = CONTROLLER_STATUSXOR;
gBattleResources->transferBuffer[1] = b;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 2);
}
void BtlController_EmitDataTransfer(u32 battler, u32 bufferId, u16 size, void *data)
{
s32 i;
@@ -1163,14 +1291,59 @@ void BtlController_EmitDataTransfer(u32 battler, u32 bufferId, u16 size, void *d
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, size + 4);
}
static void UNUSED BtlController_EmitDMA3Transfer(u32 battler, u32 bufferId, void *dst, u16 size, void *data)
{
s32 i;
gBattleResources->transferBuffer[0] = CONTROLLER_DMA3TRANSFER;
gBattleResources->transferBuffer[1] = (u32)(dst);
gBattleResources->transferBuffer[2] = ((u32)(dst) & 0x0000FF00) >> 8;
gBattleResources->transferBuffer[3] = ((u32)(dst) & 0x00FF0000) >> 16;
gBattleResources->transferBuffer[4] = ((u32)(dst) & 0xFF000000) >> 24;
gBattleResources->transferBuffer[5] = size;
gBattleResources->transferBuffer[6] = (size & 0xFF00) >> 8;
for (i = 0; i < size; i++)
gBattleResources->transferBuffer[7 + i] = *(u8 *)(data++);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, size + 7);
}
static void UNUSED BtlController_EmitPlayBGM(u32 battler, u32 bufferId, u16 songId, void *data)
{
s32 i;
gBattleResources->transferBuffer[0] = CONTROLLER_PLAYBGM;
gBattleResources->transferBuffer[1] = songId;
gBattleResources->transferBuffer[2] = (songId & 0xFF00) >> 8;
// Nonsense loop using songId as a size
// Would go out of bounds for any song id after SE_RG_BAG_POCKET (253)
for (i = 0; i < songId; i++)
gBattleResources->transferBuffer[3 + i] = *(u8 *)(data++);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, songId + 3);
}
static void UNUSED BtlController_EmitCmd32(u32 battler, u32 bufferId, u16 size, void *data)
{
s32 i;
gBattleResources->transferBuffer[0] = CONTROLLER_32;
gBattleResources->transferBuffer[1] = size;
gBattleResources->transferBuffer[2] = (size & 0xFF00) >> 8;
for (i = 0; i < size; i++)
gBattleResources->transferBuffer[3 + i] = *(u8 *)(data++);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, size + 3);
}
//TODO: compare values to pokeemerald?
void BtlController_EmitTwoReturnValues(u32 battler, u32 bufferId, u8 ret8, u32 ret32)
{
gBattleResources->transferBuffer[0] = CONTROLLER_TWORETURNVALUES;
gBattleResources->transferBuffer[1] = ret8;
gBattleResources->transferBuffer[2] = ret32;
gBattleResources->transferBuffer[3] = (ret32 & 0x0000FF00) >> 8;
gBattleResources->transferBuffer[4] = (ret32 & 0x0000FF00) >> 16;
gBattleResources->transferBuffer[5] = (ret32 & 0x0000FF00) >> 24;
gBattleResources->transferBuffer[4] = (ret32 & 0x00FF0000) >> 16;
gBattleResources->transferBuffer[5] = (ret32 & 0xFF000000) >> 24;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 6);
}
@@ -1203,6 +1376,40 @@ void BtlController_EmitOneReturnValue_Duplicate(u32 battler, u32 bufferId, u16 r
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
static void UNUSED BtlController_EmitClearUnkVar(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_CLEARUNKVAR;
gBattleResources->transferBuffer[1] = CONTROLLER_CLEARUNKVAR;
gBattleResources->transferBuffer[2] = CONTROLLER_CLEARUNKVAR;
gBattleResources->transferBuffer[3] = CONTROLLER_CLEARUNKVAR;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
static void UNUSED BtlController_EmitSetUnkVar(u32 battler, u32 bufferId, u8 b)
{
gBattleResources->transferBuffer[0] = CONTROLLER_SETUNKVAR;
gBattleResources->transferBuffer[1] = b;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 2);
}
static void UNUSED BtlController_EmitClearUnkFlag(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_CLEARUNKFLAG;
gBattleResources->transferBuffer[1] = CONTROLLER_CLEARUNKFLAG;
gBattleResources->transferBuffer[2] = CONTROLLER_CLEARUNKFLAG;
gBattleResources->transferBuffer[3] = CONTROLLER_CLEARUNKFLAG;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
static void UNUSED BtlController_EmitToggleUnkFlag(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_TOGGLEUNKFLAG;
gBattleResources->transferBuffer[1] = CONTROLLER_TOGGLEUNKFLAG;
gBattleResources->transferBuffer[2] = CONTROLLER_TOGGLEUNKFLAG;
gBattleResources->transferBuffer[3] = CONTROLLER_TOGGLEUNKFLAG;
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 4);
}
void BtlController_EmitHitAnimation(u32 battler, u32 bufferId)
{
gBattleResources->transferBuffer[0] = CONTROLLER_HITANIMATION;
@@ -1339,6 +1546,9 @@ void BtlController_EmitEndLinkBattle(u32 battler, u32 bufferId, u8 battleOutcome
{
gBattleResources->transferBuffer[0] = CONTROLLER_ENDLINKBATTLE;
gBattleResources->transferBuffer[1] = battleOutcome;
// gBattleResources->transferBuffer[2] = gSaveBlock2Ptr->frontier.disableRecordBattle;
// gBattleResources->transferBuffer[3] = gSaveBlock2Ptr->frontier.disableRecordBattle;
// gBattleResources->transferBuffer[5] = gBattleResources->transferBuffer[4] = RecordedBattle_BufferNewBattlerData(&gBattleResources->transferBuffer[6]);
PrepareBufferDataTransfer(battler, bufferId, gBattleResources->transferBuffer, 2);
}
@@ -1398,12 +1608,22 @@ static u32 GetBattlerMonData(u32 battler, struct Pokemon *party, u32 monId, u8 *
battleMon.abilityNum = GetMonData(&party[monId], MON_DATA_ABILITY_NUM);
battleMon.otId = GetMonData(&party[monId], MON_DATA_OT_ID);
battleMon.metLevel = GetMonData(&party[monId], MON_DATA_MET_LEVEL);
battleMon.isShiny = GetMonData(&party[monId], MON_DATA_IS_SHINY);
GetMonData(&party[monId], MON_DATA_NICKNAME, nickname);
StringCopy_Nickname(battleMon.nickname, nickname);
GetMonData(&party[monId], MON_DATA_OT_NAME, battleMon.otName);
src = (u8 *)&battleMon;
for (size = 0; size < sizeof(battleMon); size++)
dst[size] = src[size];
#if TESTING
if (gTestRunnerEnabled)
{
u32 side = GetBattlerSide(battler);
u32 partyIndex = gBattlerPartyIndexes[battler];
if (TestRunner_Battle_GetForcedAbility(side, partyIndex))
gBattleMons[battler].ability = gDisableStructs[battler].overwrittenAbility = TestRunner_Battle_GetForcedAbility(side, partyIndex);
}
#endif
break;
case REQUEST_SPECIES_BATTLE:
data16 = GetMonData(&party[monId], MON_DATA_SPECIES);
@@ -1890,7 +2110,7 @@ static bool8 ShouldDoSlideInAnim(void)
if (gBattleTypeFlags & (
BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_FRONTIER | BATTLE_TYPE_FIRST_BATTLE |
BATTLE_TYPE_SAFARI | BATTLE_TYPE_OLD_MAN_TUTORIAL | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_TWO_OPPONENTS |
BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_RECORDED | BATTLE_TYPE_POKEDUDE | BATTLE_TYPE_TRAINER_TOWER)
BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_RECORDED | BATTLE_TYPE_TRAINER_HILL | BATTLE_TYPE_POKEDUDE)
)
return FALSE;
return TRUE;
@@ -2348,7 +2568,10 @@ void BtlController_HandleDrawTrainerPic(u32 battler, u32 trainerPicId, bool32 is
gSprites[gBattlerSpriteIds[battler]].x2 = DISPLAY_WIDTH;
gSprites[gBattlerSpriteIds[battler]].sSpeedX = -2;
}
gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn;
if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless)
gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSpawn;
else
gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn;
gBattlerControllerFuncs[battler] = Controller_WaitForTrainerPic;
}
@@ -2486,7 +2709,7 @@ void BtlController_HandlePrintString(u32 battler)
gBattle_BG0_X = 0;
gBattle_BG0_Y = 0;
stringId = (u16 *)(&gBattleResources->bufferA[battler][2]);
BufferStringBattle(battler, *stringId);
BufferStringBattle(*stringId, battler);
if (gTestRunnerEnabled)
{
@@ -2550,7 +2773,7 @@ void DoStatusIconUpdate(u32 battler)
struct Pokemon *party = GetBattlerParty(battler);
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &party[gBattlerPartyIndexes[battler]], HEALTHBOX_STATUS_ICON);
gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = FALSE;
gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = 0;
gBattlerControllerFuncs[battler] = Controller_WaitForStatusAnimation;
}
@@ -2717,7 +2940,7 @@ void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, c
if (side == B_SIDE_PLAYER)
{
StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[battler]], SpriteCB_FreePlayerSpriteLoadMonSprite);
StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 1);
StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], ShouldDoSlideInAnim() ? 2 : 1);
paletteNum = AllocSpritePalette(tagTrainerPal);
LoadCompressedPalette(trainerPal, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP);
@@ -2778,7 +3001,7 @@ static void Task_StartSendOutAnim(u8 taskId)
gBattleResources->bufferA[battler][1] = gBattlerPartyIndexes[battler];
StartSendOutAnim(battler, FALSE, ShouldDoSlideInAnim());
battlerPartner = BATTLE_PARTNER(battler);
battlerPartner = battler ^ BIT_FLANK;
gBattleResources->bufferA[battlerPartner][1] = gBattlerPartyIndexes[battlerPartner];
BattleLoadMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battlerPartner]], battlerPartner);
StartSendOutAnim(battlerPartner, FALSE, ShouldDoSlideInAnim());
@@ -2830,7 +3053,7 @@ void BtlController_HandleDrawPartyStatusSummary(u32 battler, u32 side, bool32 co
}
else
{
gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusSummaryShown = TRUE;
gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusSummaryShown = 1;
if (side == B_SIDE_OPPONENT && gBattleResources->bufferA[battler][2] != 0)
{
@@ -2878,6 +3101,3 @@ void BtlController_HandleBattleAnimation(u32 battler, bool32 ignoreSE)
gBattlerControllerFuncs[battler] = Controller_WaitForBattleAnimation;
}
}

View File

@@ -213,6 +213,18 @@ void SpriteCB_TrainerSlideIn(struct Sprite *sprite)
}
}
void SpriteCB_TrainerSpawn(struct Sprite *sprite)
{
if (!(gIntroSlideFlags & 1))
{
sprite->x2 = 0;
if (sprite->y2 != 0)
sprite->callback = SpriteCB_TrainerSlideVertical;
else
sprite->callback = SpriteCallbackDummy;
}
}
// Slide up to 0 if necessary (used by multi battle intro)
static void SpriteCB_TrainerSlideVertical(struct Sprite *sprite)
{

View File

@@ -2423,7 +2423,7 @@ static const u16 sGrammarMoveUsedTable[] =
static const u8 sRecordedBattleTextSpeeds[] = {8, 4, 1, 0};
void BufferStringBattle(u32 battler, u16 stringId)
void BufferStringBattle(u16 stringId, u32 battler)
{
s32 i;
const u8 *stringPtr = NULL;