src/battle_controller_link_opponent.c

This commit is contained in:
Eduardo Quezada
2022-08-18 14:17:56 -04:00
parent 9020751fc4
commit 2f03c4a62c
+98 -66
View File
@@ -1,4 +1,9 @@
#include "global.h" #include "global.h"
#include "battle.h"
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_interface.h"
#include "battle_message.h"
#include "gflib.h" #include "gflib.h"
#include "data.h" #include "data.h"
#include "link.h" #include "link.h"
@@ -6,11 +11,6 @@
#include "pokeball.h" #include "pokeball.h"
#include "task.h" #include "task.h"
#include "util.h" #include "util.h"
#include "battle.h"
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_interface.h"
#include "battle_message.h"
#include "constants/battle_anim.h" #include "constants/battle_anim.h"
#include "constants/songs.h" #include "constants/songs.h"
#include "constants/sound.h" #include "constants/sound.h"
@@ -53,12 +53,12 @@ static void LinkOpponentHandleTwoReturnValues(void);
static void LinkOpponentHandleChosenMonReturnValue(void); static void LinkOpponentHandleChosenMonReturnValue(void);
static void LinkOpponentHandleOneReturnValue(void); static void LinkOpponentHandleOneReturnValue(void);
static void LinkOpponentHandleOneReturnValue_Duplicate(void); static void LinkOpponentHandleOneReturnValue_Duplicate(void);
static void LinkOpponentHandleCmd37(void); static void LinkOpponentHandleClearUnkVar(void);
static void LinkOpponentHandleCmd38(void); static void LinkOpponentHandleSetUnkVar(void);
static void LinkOpponentHandleCmd39(void); static void LinkOpponentHandleClearUnkFlag(void);
static void LinkOpponentHandleCmd40(void); static void LinkOpponentHandleToggleUnkFlag(void);
static void LinkOpponentHandleHitAnimation(void); static void LinkOpponentHandleHitAnimation(void);
static void LinkOpponentHandleCmd42(void); static void LinkOpponentHandleCantSwitch(void);
static void LinkOpponentHandlePlaySE(void); static void LinkOpponentHandlePlaySE(void);
static void LinkOpponentHandlePlayFanfare(void); static void LinkOpponentHandlePlayFanfare(void);
static void LinkOpponentHandleFaintingCry(void); static void LinkOpponentHandleFaintingCry(void);
@@ -71,17 +71,17 @@ static void LinkOpponentHandleSpriteInvisibility(void);
static void LinkOpponentHandleBattleAnimation(void); static void LinkOpponentHandleBattleAnimation(void);
static void LinkOpponentHandleLinkStandbyMsg(void); static void LinkOpponentHandleLinkStandbyMsg(void);
static void LinkOpponentHandleResetActionMoveSelection(void); static void LinkOpponentHandleResetActionMoveSelection(void);
static void LinkOpponentHandleCmd55(void); static void LinkOpponentHandleEndLinkBattle(void);
static void LinkOpponentCmdEnd(void); static void LinkOpponentCmdEnd(void);
static void LinkOpponentBufferRunCommand(void); static void LinkOpponentBufferRunCommand(void);
static void LinkOpponentBufferExecCompleted(void); static void LinkOpponentBufferExecCompleted(void);
static void SwitchIn_HandleSoundAndEnd(void);
static u32 CopyLinkOpponentMonData(u8 monId, u8 *dst); static u32 CopyLinkOpponentMonData(u8 monId, u8 *dst);
static void SetLinkOpponentMonData(u8 monId); static void SetLinkOpponentMonData(u8 monId);
static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit);
static void DoSwitchOutAnimation(void); static void DoSwitchOutAnimation(void);
static void LinkOpponentDoMoveAnimation(void); static void LinkOpponentDoMoveAnimation(void);
static void SwitchIn_HandleSoundAndEnd(void);
static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit);
static void Task_StartSendOutAnim(u8 taskId); static void Task_StartSendOutAnim(u8 taskId);
static void SpriteCB_FreeOpponentSprite(struct Sprite *sprite); static void SpriteCB_FreeOpponentSprite(struct Sprite *sprite);
static void EndDrawPartyStatusSummary(void); static void EndDrawPartyStatusSummary(void);
@@ -125,12 +125,12 @@ static void (*const sLinkOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
LinkOpponentHandleChosenMonReturnValue, LinkOpponentHandleChosenMonReturnValue,
LinkOpponentHandleOneReturnValue, LinkOpponentHandleOneReturnValue,
LinkOpponentHandleOneReturnValue_Duplicate, LinkOpponentHandleOneReturnValue_Duplicate,
LinkOpponentHandleCmd37, LinkOpponentHandleClearUnkVar,
LinkOpponentHandleCmd38, LinkOpponentHandleSetUnkVar,
LinkOpponentHandleCmd39, LinkOpponentHandleClearUnkFlag,
LinkOpponentHandleCmd40, LinkOpponentHandleToggleUnkFlag,
LinkOpponentHandleHitAnimation, LinkOpponentHandleHitAnimation,
LinkOpponentHandleCmd42, LinkOpponentHandleCantSwitch,
LinkOpponentHandlePlaySE, LinkOpponentHandlePlaySE,
LinkOpponentHandlePlayFanfare, LinkOpponentHandlePlayFanfare,
LinkOpponentHandleFaintingCry, LinkOpponentHandleFaintingCry,
@@ -143,11 +143,10 @@ static void (*const sLinkOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
LinkOpponentHandleBattleAnimation, LinkOpponentHandleBattleAnimation,
LinkOpponentHandleLinkStandbyMsg, LinkOpponentHandleLinkStandbyMsg,
LinkOpponentHandleResetActionMoveSelection, LinkOpponentHandleResetActionMoveSelection,
LinkOpponentHandleCmd55, LinkOpponentHandleEndLinkBattle,
LinkOpponentCmdEnd LinkOpponentCmdEnd
}; };
static void LinkOpponentDummy(void) static void LinkOpponentDummy(void)
{ {
} }
@@ -161,7 +160,7 @@ static void LinkOpponentBufferRunCommand(void)
{ {
if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) if (gBattleControllerExecFlags & gBitTable[gActiveBattler])
{ {
if (gBattleBufferA[gActiveBattler][0] < NELEMS(sLinkOpponentBufferCommands)) if (gBattleBufferA[gActiveBattler][0] < ARRAY_COUNT(sLinkOpponentBufferCommands))
sLinkOpponentBufferCommands[gBattleBufferA[gActiveBattler][0]](); sLinkOpponentBufferCommands[gBattleBufferA[gActiveBattler][0]]();
else else
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
@@ -197,31 +196,31 @@ static void Intro_DelayAndEnd(void)
static void Intro_WaitForShinyAnimAndHealthbox(void) static void Intro_WaitForShinyAnimAndHealthbox(void)
{ {
bool8 var = FALSE; bool32 healthboxAnimDone = FALSE;
if (!IsDoubleBattle() || ((IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)))) if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)))
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
var = TRUE; healthboxAnimDone = TRUE;
} }
else if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy else if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy
&& gSprites[gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK]].callback == gSprites[gHealthboxSpriteIds[gActiveBattler]].callback) && gSprites[gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK]].callback == gSprites[gHealthboxSpriteIds[gActiveBattler]].callback)
{ {
var = TRUE; healthboxAnimDone = TRUE;
} }
if (IsCryPlayingOrClearCrySongs()) if (IsCryPlayingOrClearCrySongs())
var = FALSE; healthboxAnimDone = FALSE;
if (var) if (healthboxAnimDone)
{ {
if (GetBattlerPosition(gActiveBattler) == B_POSITION_OPPONENT_LEFT) if (GetBattlerPosition(gActiveBattler) == B_POSITION_OPPONENT_LEFT)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim
|| !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].finishedShinyMonAnim) || !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].finishedShinyMonAnim)
return; return;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = 0; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = 0; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].triedShinyMonAnim = 0; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].finishedShinyMonAnim = 0; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
} }
@@ -287,8 +286,8 @@ static void TryShinyAnimAfterMonAnim(void)
} }
else if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) else if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = 0; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = 0; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
@@ -301,10 +300,15 @@ static void CompleteOnHealthbarDone(void)
s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0); s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]);
if (hpValue != -1) if (hpValue != -1)
{
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT); UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT);
}
else else
{
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
}
} }
static void HideHealthboxAfterMonFaint(void) static void HideHealthboxAfterMonFaint(void)
@@ -347,9 +351,9 @@ static void DoHitAnimBlinkSpriteEffect(void)
} }
else else
{ {
if (!(gSprites[spriteId].data[1] % 4)) if ((gSprites[spriteId].data[1] % 4) == 0)
gSprites[spriteId].invisible ^= 1; gSprites[spriteId].invisible ^= 1;
++gSprites[spriteId].data[1]; gSprites[spriteId].data[1]++;
} }
} }
@@ -359,6 +363,7 @@ static void SwitchIn_ShowSubstitute(void)
{ {
if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute)
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_HandleSoundAndEnd; gBattlerControllerFuncs[gActiveBattler] = SwitchIn_HandleSoundAndEnd;
} }
} }
@@ -376,11 +381,14 @@ static void SwitchIn_ShowHealthbox(void)
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = 0; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = 0; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = 0;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0);
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(gActiveBattler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]);
@@ -392,11 +400,13 @@ static void SwitchIn_ShowHealthbox(void)
static void SwitchIn_TryShinyAnim(void) static void SwitchIn_TryShinyAnim(void)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim) && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim)
{
TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]);
}
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive)
{ {
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]);
SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES));
@@ -439,14 +449,14 @@ static void LinkOpponentHandleGetMonData(void)
u8 monToCheck; u8 monToCheck;
s32 i; s32 i;
if (!gBattleBufferA[gActiveBattler][2]) if (gBattleBufferA[gActiveBattler][2] == 0)
{ {
size += CopyLinkOpponentMonData(gBattlerPartyIndexes[gActiveBattler], monData); size += CopyLinkOpponentMonData(gBattlerPartyIndexes[gActiveBattler], monData);
} }
else else
{ {
monToCheck = gBattleBufferA[gActiveBattler][2]; monToCheck = gBattleBufferA[gActiveBattler][2];
for (i = 0; i < PARTY_SIZE; ++i) for (i = 0; i < PARTY_SIZE; i++)
{ {
if (monToCheck & 1) if (monToCheck & 1)
size += CopyLinkOpponentMonData(i, monData + size); size += CopyLinkOpponentMonData(i, monData + size);
@@ -472,7 +482,7 @@ static u32 CopyLinkOpponentMonData(u8 monId, u8 *dst)
case REQUEST_ALL_BATTLE: case REQUEST_ALL_BATTLE:
battleMon.species = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES); battleMon.species = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES);
battleMon.item = GetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM); battleMon.item = GetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM);
for (size = 0; size < MAX_MON_MOVES; ++size) for (size = 0; size < MAX_MON_MOVES; size++)
{ {
battleMon.moves[size] = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + size); battleMon.moves[size] = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + size);
battleMon.pp[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size); battleMon.pp[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size);
@@ -503,7 +513,7 @@ static u32 CopyLinkOpponentMonData(u8 monId, u8 *dst)
StringCopy_Nickname(battleMon.nickname, nickname); StringCopy_Nickname(battleMon.nickname, nickname);
GetMonData(&gEnemyParty[monId], MON_DATA_OT_NAME, battleMon.otName); GetMonData(&gEnemyParty[monId], MON_DATA_OT_NAME, battleMon.otName);
src = (u8 *)&battleMon; src = (u8 *)&battleMon;
for (size = 0; size < sizeof(battleMon); ++size) for (size = 0; size < sizeof(battleMon); size++)
dst[size] = src[size]; dst[size] = src[size];
break; break;
case REQUEST_SPECIES_BATTLE: case REQUEST_SPECIES_BATTLE:
@@ -519,14 +529,14 @@ static u32 CopyLinkOpponentMonData(u8 monId, u8 *dst)
size = 2; size = 2;
break; break;
case REQUEST_MOVES_PP_BATTLE: case REQUEST_MOVES_PP_BATTLE:
for (size = 0; size < MAX_MON_MOVES; ++size) for (size = 0; size < MAX_MON_MOVES; size++)
{ {
moveData.moves[size] = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + size); moveData.moves[size] = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + size);
moveData.pp[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size); moveData.pp[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size);
} }
moveData.ppBonuses = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES); moveData.ppBonuses = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES);
src = (u8 *)(&moveData); src = (u8 *)(&moveData);
for (size = 0; size < sizeof(moveData); ++size) for (size = 0; size < sizeof(moveData); size++)
dst[size] = src[size]; dst[size] = src[size];
break; break;
case REQUEST_MOVE1_BATTLE: case REQUEST_MOVE1_BATTLE:
@@ -539,10 +549,10 @@ static u32 CopyLinkOpponentMonData(u8 monId, u8 *dst)
size = 2; size = 2;
break; break;
case REQUEST_PP_DATA_BATTLE: case REQUEST_PP_DATA_BATTLE:
for (size = 0; size < MAX_MON_MOVES; ++size) for (size = 0; size < MAX_MON_MOVES; size++)
dst[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size); dst[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size);
dst[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES); dst[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES);
++size; size++;
break; break;
case REQUEST_PPMOVE1_BATTLE: case REQUEST_PPMOVE1_BATTLE:
case REQUEST_PPMOVE2_BATTLE: case REQUEST_PPMOVE2_BATTLE:
@@ -803,7 +813,7 @@ static void SetLinkOpponentMonData(u8 monId)
SetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, &battlePokemon->species); SetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, &battlePokemon->species);
SetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM, &battlePokemon->item); SetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM, &battlePokemon->item);
for (i = 0; i < MAX_MON_MOVES; ++i) for (i = 0; i < MAX_MON_MOVES; i++)
{ {
SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]);
SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + i, &battlePokemon->pp[i]); SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + i, &battlePokemon->pp[i]);
@@ -842,7 +852,7 @@ static void SetLinkOpponentMonData(u8 monId)
SetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]); SetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]);
break; break;
case REQUEST_MOVES_PP_BATTLE: case REQUEST_MOVES_PP_BATTLE:
for (i = 0; i < MAX_MON_MOVES; ++i) for (i = 0; i < MAX_MON_MOVES; i++)
{ {
SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + i, &moveData->moves[i]); SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + i, &moveData->moves[i]);
SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + i, &moveData->pp[i]); SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + i, &moveData->pp[i]);
@@ -1055,13 +1065,18 @@ static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit)
GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2), GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2),
GetBattlerSpriteDefault_Y(battlerId), GetBattlerSpriteDefault_Y(battlerId),
GetBattlerSpriteSubpriority(battlerId)); GetBattlerSpriteSubpriority(battlerId));
gSprites[gBattleControllerData[battlerId]].data[1] = gBattlerSpriteIds[battlerId]; gSprites[gBattleControllerData[battlerId]].data[1] = gBattlerSpriteIds[battlerId];
gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId; gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId;
gSprites[gBattlerSpriteIds[battlerId]].data[2] = species; gSprites[gBattlerSpriteIds[battlerId]].data[2] = species;
gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId; gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId;
StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], gBattleMonForms[battlerId]); StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], gBattleMonForms[battlerId]);
gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE; gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE;
gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy; gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy;
gSprites[gBattleControllerData[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_OPPONENT_SENDOUT); gSprites[gBattleControllerData[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_OPPONENT_SENDOUT);
} }
@@ -1103,6 +1118,8 @@ static void DoSwitchOutAnimation(void)
} }
} }
#define sSpeedX data[0]
static void LinkOpponentHandleDrawTrainerPic(void) static void LinkOpponentHandleDrawTrainerPic(void)
{ {
s16 xPos; s16 xPos;
@@ -1110,7 +1127,7 @@ static void LinkOpponentHandleDrawTrainerPic(void)
if (gBattleTypeFlags & BATTLE_TYPE_MULTI) if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{ {
if (GetBattlerPosition(gActiveBattler) & BIT_FLANK) // second mon if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != 0) // second mon
xPos = 152; xPos = 152;
else // first mon else // first mon
xPos = 200; xPos = 200;
@@ -1163,13 +1180,14 @@ static void LinkOpponentHandleDrawTrainerPic(void)
xPos, xPos,
(8 - gTrainerFrontPicCoords[trainerPicId].size) * 4 + 40, (8 - gTrainerFrontPicCoords[trainerPicId].size) * 4 + 40,
GetBattlerSpriteSubpriority(gActiveBattler)); GetBattlerSpriteSubpriority(gActiveBattler));
gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -240; gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -DISPLAY_WIDTH;
gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 2; gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = 2;
gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag);
gSprites[gBattlerSpriteIds[gActiveBattler]].data[5] = gSprites[gBattlerSpriteIds[gActiveBattler]].oam.tileNum; gSprites[gBattlerSpriteIds[gActiveBattler]].data[5] = gSprites[gBattlerSpriteIds[gActiveBattler]].oam.tileNum;
gSprites[gBattlerSpriteIds[gActiveBattler]].oam.tileNum = GetSpriteTileStartByTag(gTrainerFrontPicTable[trainerPicId].tag); gSprites[gBattlerSpriteIds[gActiveBattler]].oam.tileNum = GetSpriteTileStartByTag(gTrainerFrontPicTable[trainerPicId].tag);
gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam = trainerPicId; gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam = trainerPicId;
gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn;
gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy; gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy;
} }
@@ -1178,6 +1196,8 @@ static void LinkOpponentHandleTrainerSlide(void)
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
} }
#undef sSpeedX
static void LinkOpponentHandleTrainerSlideBack(void) static void LinkOpponentHandleTrainerSlideBack(void)
{ {
SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]);
@@ -1195,7 +1215,7 @@ static void LinkOpponentHandleFaintAnimation(void)
{ {
if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute)
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON);
++gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState++;
} }
else else
{ {
@@ -1263,7 +1283,7 @@ static void LinkOpponentDoMoveAnimation(void)
{ {
case 0: case 0:
if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute
&& !gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8) && !gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8)
{ {
gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 1; gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 1;
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON);
@@ -1359,6 +1379,7 @@ static void LinkOpponentHandleHealthBarUpdate(void)
LoadBattleBarGfx(0); LoadBattleBarGfx(0);
hpVal = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); hpVal = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8);
if (hpVal != INSTANT_HP_BAR_DROP) if (hpVal != INSTANT_HP_BAR_DROP)
{ {
u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP);
@@ -1372,6 +1393,7 @@ static void LinkOpponentHandleHealthBarUpdate(void)
SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal);
} }
gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone; gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone;
} }
@@ -1448,25 +1470,25 @@ static void LinkOpponentHandleOneReturnValue_Duplicate(void)
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
} }
static void LinkOpponentHandleCmd37(void) static void LinkOpponentHandleClearUnkVar(void)
{ {
gUnusedControllerStruct.unk = 0; gUnusedControllerStruct.unk = 0;
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
} }
static void LinkOpponentHandleCmd38(void) static void LinkOpponentHandleSetUnkVar(void)
{ {
gUnusedControllerStruct.unk = gBattleBufferA[gActiveBattler][1]; gUnusedControllerStruct.unk = gBattleBufferA[gActiveBattler][1];
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
} }
static void LinkOpponentHandleCmd39(void) static void LinkOpponentHandleClearUnkFlag(void)
{ {
gUnusedControllerStruct.flag = 0; gUnusedControllerStruct.flag = 0;
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
} }
static void LinkOpponentHandleCmd40(void) static void LinkOpponentHandleToggleUnkFlag(void)
{ {
gUnusedControllerStruct.flag ^= 1; gUnusedControllerStruct.flag ^= 1;
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
@@ -1487,7 +1509,7 @@ static void LinkOpponentHandleHitAnimation(void)
} }
} }
static void LinkOpponentHandleCmd42(void) static void LinkOpponentHandleCantSwitch(void)
{ {
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
} }
@@ -1500,6 +1522,7 @@ static void LinkOpponentHandlePlaySE(void)
pan = SOUND_PAN_ATTACKER; pan = SOUND_PAN_ATTACKER;
else else
pan = SOUND_PAN_TARGET; pan = SOUND_PAN_TARGET;
PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan); PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan);
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
} }
@@ -1527,18 +1550,23 @@ static void LinkOpponentHandleIntroSlide(void)
static void LinkOpponentHandleIntroTrainerBallThrow(void) static void LinkOpponentHandleIntroTrainerBallThrow(void)
{ {
u8 paletteNum, taskId; u8 taskId;
SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]);
gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35; gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35;
gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = 280; gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = 280;
gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y;
gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation;
StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCB_FreeOpponentSprite); StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCB_FreeOpponentSprite);
taskId = CreateTask(Task_StartSendOutAnim, 5); taskId = CreateTask(Task_StartSendOutAnim, 5);
gTasks[taskId].data[0] = gActiveBattler; gTasks[taskId].data[0] = gActiveBattler;
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown)
gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary;
gBattleSpritesDataPtr->animationData->introAnimActive = TRUE; gBattleSpritesDataPtr->animationData->introAnimActive = TRUE;
gBattlerControllerFuncs[gActiveBattler] = LinkOpponentDummy; gBattlerControllerFuncs[gActiveBattler] = LinkOpponentDummy;
} }
@@ -1577,7 +1605,7 @@ static void SpriteCB_FreeOpponentSprite(struct Sprite *sprite)
static void LinkOpponentHandleDrawPartyStatusSummary(void) static void LinkOpponentHandleDrawPartyStatusSummary(void)
{ {
if (gBattleBufferA[gActiveBattler][1] && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) if (gBattleBufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
{ {
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
} }
@@ -1585,11 +1613,11 @@ static void LinkOpponentHandleDrawPartyStatusSummary(void)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown = 1; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown = 1;
if (gBattleBufferA[gActiveBattler][2]) if (gBattleBufferA[gActiveBattler][2] != 0)
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay < 2) if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay < 2)
{ {
++gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay++;
return; return;
} }
else else
@@ -1597,17 +1625,20 @@ static void LinkOpponentHandleDrawPartyStatusSummary(void)
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay = 0; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay = 0;
} }
} }
gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]);
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0;
if (gBattleBufferA[gActiveBattler][2])
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0x5D; if (gBattleBufferA[gActiveBattler][2] != 0)
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 93;
gBattlerControllerFuncs[gActiveBattler] = EndDrawPartyStatusSummary; gBattlerControllerFuncs[gActiveBattler] = EndDrawPartyStatusSummary;
} }
} }
static void EndDrawPartyStatusSummary(void) static void EndDrawPartyStatusSummary(void)
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer++ > 0x5C) if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer++ > 92)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0;
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
@@ -1660,12 +1691,13 @@ static void LinkOpponentHandleResetActionMoveSelection(void)
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();
} }
static void LinkOpponentHandleCmd55(void) static void LinkOpponentHandleEndLinkBattle(void)
{ {
if (gBattleBufferA[gActiveBattler][1] == B_OUTCOME_DREW) if (gBattleBufferA[gActiveBattler][1] == B_OUTCOME_DREW)
gBattleOutcome = gBattleBufferA[gActiveBattler][1]; gBattleOutcome = gBattleBufferA[gActiveBattler][1];
else else
gBattleOutcome = gBattleBufferA[gActiveBattler][1] ^ B_OUTCOME_DREW; gBattleOutcome = gBattleBufferA[gActiveBattler][1] ^ B_OUTCOME_DREW;
FadeOutMapMusic(5); FadeOutMapMusic(5);
BeginFastPaletteFade(3); BeginFastPaletteFade(3);
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted();