replace global usage of gActiveBattler in controller files

This commit is contained in:
DizzyEggg 2023-08-07 12:51:58 +02:00
parent b8ba6139cb
commit ce18df46e6
16 changed files with 1902 additions and 1939 deletions

View File

@ -0,0 +1,3 @@
gBattlerControllerFuncs
gBattleControllerData
gBattlerControllerEndFuncs

View File

@ -2,8 +2,6 @@ gPreBattleCallback1
gBattleMainFunc gBattleMainFunc
gBattleResults gBattleResults
gLeveledUpInBattle gLeveledUpInBattle
gBattlerControllerFuncs
gHealthboxSpriteIds gHealthboxSpriteIds
gMultiUsePlayerCursor gMultiUsePlayerCursor
gNumberOfMovesToChoose gNumberOfMovesToChoose
gBattleControllerData

View File

@ -1002,11 +1002,9 @@ extern void (*gPreBattleCallback1)(void);
extern void (*gBattleMainFunc)(void); extern void (*gBattleMainFunc)(void);
extern struct BattleResults gBattleResults; extern struct BattleResults gBattleResults;
extern u8 gLeveledUpInBattle; extern u8 gLeveledUpInBattle;
extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void);
extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT];
extern u8 gMultiUsePlayerCursor; extern u8 gMultiUsePlayerCursor;
extern u8 gNumberOfMovesToChoose; extern u8 gNumberOfMovesToChoose;
extern u8 gBattleControllerData[MAX_BATTLERS_COUNT];
extern bool8 gHasFetchedBall; extern bool8 gHasFetchedBall;
extern u8 gLastUsedBall; extern u8 gLastUsedBall;
extern u16 gLastThrownBall; extern u16 gLastThrownBall;

View File

@ -197,7 +197,9 @@ enum
}; };
extern struct UnusedControllerStruct gUnusedControllerStruct; extern struct UnusedControllerStruct gUnusedControllerStruct;
extern void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(void); extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(u32 battler);
extern void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(u32 battler);
extern u8 gBattleControllerData[MAX_BATTLERS_COUNT];
// general functions // general functions
void HandleLinkBattleSetup(void); void HandleLinkBattleSetup(void);
@ -253,87 +255,87 @@ void BtlController_EmitEndLinkBattle(u8 bufferId, u8 battleOutcome);
void BtlController_EmitDebugMenu(u8 bufferId); void BtlController_EmitDebugMenu(u8 bufferId);
void BattleControllerComplete(u32 battler); // Can be used for all the controllers. void BattleControllerComplete(u32 battler); // Can be used for all the controllers.
void BtlController_Empty(void); // Empty command, does nothing, only completes the execution. void BtlController_Empty(u32 battler); // Empty command, does nothing, only completes the execution.
void BtlController_TerminatorNop(void); // Dummy function at the end of the table. void BtlController_TerminatorNop(u32 battler); // Dummy function at the end of the table.
void BattleControllerDummy(u32 battler);
void StartSendOutAnim(u32 battler, bool32 dontClearSubstituteBit); void StartSendOutAnim(u32 battler, bool32 dontClearSubstituteBit);
void Controller_WaitForString(void); void Controller_WaitForString(u32 battler);
void Controller_WaitForHealthBar(void); void Controller_WaitForHealthBar(u32 battler);
// handlers // handlers
void BtlController_HandleGetMonData(void); void BtlController_HandleGetMonData(u32 battler);
void BtlController_HandleGetRawMonData(void); void BtlController_HandleGetRawMonData(u32 battler);
void BtlController_HandleSetMonData(void); void BtlController_HandleSetMonData(u32 battler);
void BtlController_HandleSetRawMonData(void); void BtlController_HandleSetRawMonData(u32 battler);
void BtlController_HandleLoadMonSprite(u32 battler, struct Pokemon *party, void (*controllerCallback)(void)); void BtlController_HandleLoadMonSprite(u32 battler, struct Pokemon *party, void (*controllerCallback)(u32 battler));
void BtlController_HandleSwitchInAnim(u32 battler, bool32 isPlayerSide, void (*controllerCallback)(void)); void BtlController_HandleSwitchInAnim(u32 battler, bool32 isPlayerSide, void (*controllerCallback)(u32 battler));
void BtlController_HandleReturnMonToBall(void); void BtlController_HandleReturnMonToBall(u32 battler);
void BtlController_HandleDrawTrainerPic(u32 battlerId, u32 trainerPicId, bool32 isFrontPic, s16 xPos, s16 yPos, s32 subpriority); void BtlController_HandleDrawTrainerPic(u32 battlerId, u32 trainerPicId, bool32 isFrontPic, s16 xPos, s16 yPos, s32 subpriority);
void BtlController_HandleTrainerSlide(u32 battler, u32 trainerPicId); void BtlController_HandleTrainerSlide(u32 battler, u32 trainerPicId);
void BtlController_HandleTrainerSlideBack(u32 battlerId, s16 data0, bool32 startAnim); void BtlController_HandleTrainerSlideBack(u32 battlerId, s16 data0, bool32 startAnim);
void BtlController_HandleFaintAnimation(void); void BtlController_HandleFaintAnimation(u32 battler);
void BtlController_HandleSuccessBallThrowAnim(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture); void BtlController_HandleSuccessBallThrowAnim(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture);
void BtlController_HandleBallThrowAnim(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture); void BtlController_HandleBallThrowAnim(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture);
void BtlController_HandleMoveAnimation(u32 battler, bool32 updateTvData); void BtlController_HandleMoveAnimation(u32 battler, bool32 updateTvData);
void BtlController_HandlePrintString(u32 battler, bool32 updateTvData, bool32 arenaPtsDeduct); void BtlController_HandlePrintString(u32 battler, bool32 updateTvData, bool32 arenaPtsDeduct);
void BtlController_HandleHealthBarUpdate(u32 battler, bool32 updateHpText); void BtlController_HandleHealthBarUpdate(u32 battler, bool32 updateHpText);
void DoStatusIconUpdate(u32 battler); void DoStatusIconUpdate(u32 battler);
void BtlController_HandleStatusIconUpdate(void); void BtlController_HandleStatusIconUpdate(u32 battler);
void BtlController_HandleStatusAnimation(void); void BtlController_HandleStatusAnimation(u32 battler);
void BtlController_HandleClearUnkVar(void); void BtlController_HandleClearUnkVar(u32 battler);
void BtlController_HandleSetUnkVar(void); void BtlController_HandleSetUnkVar(u32 battler);
void BtlController_HandleClearUnkFlag(void); void BtlController_HandleClearUnkFlag(u32 battler);
void BtlController_HandleToggleUnkFlag(void); void BtlController_HandleToggleUnkFlag(u32 battler);
void BtlController_HandleHitAnimation(void); void BtlController_HandleHitAnimation(u32 battler);
void BtlController_HandlePlaySE(void); void BtlController_HandlePlaySE(u32 battler);
void BtlController_HandlePlayFanfareOrBGM(void); void BtlController_HandlePlayFanfareOrBGM(u32 battler);
void BtlController_HandleFaintingCry(void); void BtlController_HandleFaintingCry(u32 battler);
void BtlController_HandleIntroSlide(void); void BtlController_HandleIntroSlide(u32 battler);
void BtlController_HandleSpriteInvisibility(void); void BtlController_HandleSpriteInvisibility(u32 battler);
bool32 TwoPlayerIntroMons(u32 battlerId); // Double battle with both player pokemon active. bool32 TwoPlayerIntroMons(u32 battlerId); // Double battle with both player pokemon active.
bool32 TwoOpponentIntroMons(u32 battlerId); // Double battle with both opponent pokemon active. bool32 TwoOpponentIntroMons(u32 battlerId); // Double battle with both opponent pokemon active.
void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, const u32 *trainerPal, s16 framesToWait, void (*controllerCallback)(void)); void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, const u32 *trainerPal, s16 framesToWait, void (*controllerCallback)(u32 battler));
void BtlController_HandleDrawPartyStatusSummary(u32 battler, u32 side, bool32 considerDelay); void BtlController_HandleDrawPartyStatusSummary(u32 battler, u32 side, bool32 considerDelay);
void BtlController_HandleHidePartyStatusSummary(void); void BtlController_HandleHidePartyStatusSummary(u32 battler);
void BtlController_HandleBattleAnimation(u32 battler, bool32 ignoreSE, bool32 updateTvData); void BtlController_HandleBattleAnimation(u32 battler, bool32 ignoreSE, bool32 updateTvData);
// player controller // player controller
void SetControllerToPlayer(void); void SetControllerToPlayer(u32 battler);
void BattleControllerDummy(void); void SetBattleEndCallbacks(u32 battler);
void SetBattleEndCallbacks(void); void PlayerHandleExpUpdate(u32 battler);
void PlayerHandleExpUpdate(void);
u32 LinkPlayerGetTrainerPicId(u32 multiplayerId); u32 LinkPlayerGetTrainerPicId(u32 multiplayerId);
void CB2_SetUpReshowBattleScreenAfterMenu(void); void CB2_SetUpReshowBattleScreenAfterMenu(void);
void CB2_SetUpReshowBattleScreenAfterMenu2(void); void CB2_SetUpReshowBattleScreenAfterMenu2(void);
void Task_PlayerController_RestoreBgmAfterCry(u8 taskId); void Task_PlayerController_RestoreBgmAfterCry(u8 taskId);
void ActionSelectionCreateCursorAt(u8 cursorPos, u8 unused); void ActionSelectionCreateCursorAt(u8 cursorPos, u8 unused);
void ActionSelectionDestroyCursorAt(u8 cursorPos); void ActionSelectionDestroyCursorAt(u8 cursorPos);
void InitMoveSelectionsVarsAndStrings(void); void InitMoveSelectionsVarsAndStrings(u32 battler);
void MoveSelectionCreateCursorAt(u8 cursorPos, u8 arg1); void MoveSelectionCreateCursorAt(u8 cursorPos, u8 arg1);
void MoveSelectionDestroyCursorAt(u8 cursorPosition); void MoveSelectionDestroyCursorAt(u8 cursorPosition);
// recorded player controller // recorded player controller
void SetControllerToRecordedPlayer(void); void SetControllerToRecordedPlayer(u32 battler);
// opponent controller // opponent controller
void SetControllerToOpponent(void); void SetControllerToOpponent(u32 battler);
// player partner controller // player partner controller
void Controller_PlayerPartnerShowIntroHealthbox(void); // Also used by the link partner. void Controller_PlayerPartnerShowIntroHealthbox(u32 battler); // Also used by the link partner.
void SetControllerToPlayerPartner(void); void SetControllerToPlayerPartner(u32 battler);
// safari controller // safari controller
void SetControllerToSafari(void); void SetControllerToSafari(u32 battler);
// wally controller // wally controller
void SetControllerToWally(void); void SetControllerToWally(u32 battler);
// recorded opponent controller // recorded opponent controller
void SetControllerToRecordedOpponent(void); void SetControllerToRecordedOpponent(u32 battler);
// link opponent // link opponent
void SetControllerToLinkOpponent(void); void SetControllerToLinkOpponent(u32 battler);
// link partner // link partner
void SetControllerToLinkPartner(void); void SetControllerToLinkPartner(u32 battler);
#endif // GUARD_BATTLE_CONTROLLERS_H #endif // GUARD_BATTLE_CONTROLLERS_H

View File

@ -29,25 +29,25 @@
#include "constants/trainers.h" #include "constants/trainers.h"
#include "recorded_battle.h" #include "recorded_battle.h"
static void LinkOpponentHandleLoadMonSprite(void); static void LinkOpponentHandleLoadMonSprite(u32 battler);
static void LinkOpponentHandleSwitchInAnim(void); static void LinkOpponentHandleSwitchInAnim(u32 battler);
static void LinkOpponentHandleDrawTrainerPic(void); static void LinkOpponentHandleDrawTrainerPic(u32 battler);
static void LinkOpponentHandleTrainerSlide(void); static void LinkOpponentHandleTrainerSlide(u32 battler);
static void LinkOpponentHandleTrainerSlideBack(void); static void LinkOpponentHandleTrainerSlideBack(u32 battler);
static void LinkOpponentHandleMoveAnimation(void); static void LinkOpponentHandleMoveAnimation(u32 battler);
static void LinkOpponentHandlePrintString(void); static void LinkOpponentHandlePrintString(u32 battler);
static void LinkOpponentHandleHealthBarUpdate(void); static void LinkOpponentHandleHealthBarUpdate(u32 battler);
static void LinkOpponentHandleIntroTrainerBallThrow(void); static void LinkOpponentHandleIntroTrainerBallThrow(u32 battler);
static void LinkOpponentHandleDrawPartyStatusSummary(void); static void LinkOpponentHandleDrawPartyStatusSummary(u32 battler);
static void LinkOpponentHandleBattleAnimation(void); static void LinkOpponentHandleBattleAnimation(u32 battler);
static void LinkOpponentHandleLinkStandbyMsg(void); static void LinkOpponentHandleLinkStandbyMsg(u32 battler);
static void LinkOpponentHandleEndLinkBattle(void); static void LinkOpponentHandleEndLinkBattle(u32 battler);
static void LinkOpponentBufferRunCommand(void); static void LinkOpponentBufferRunCommand(u32 battler);
static void LinkOpponentBufferExecCompleted(void); static void LinkOpponentBufferExecCompleted(u32 battler);
static void SwitchIn_HandleSoundAndEnd(void); static void SwitchIn_HandleSoundAndEnd(u32 battler);
static void (*const sLinkOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(void) = static void (*const sLinkOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{ {
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty, [CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -109,46 +109,46 @@ static void (*const sLinkOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
}; };
void SetControllerToLinkOpponent(void) void SetControllerToLinkOpponent(u32 battler)
{ {
gBattlerControllerEndFuncs[gActiveBattler] = LinkOpponentBufferExecCompleted; gBattlerControllerEndFuncs[battler] = LinkOpponentBufferExecCompleted;
gBattlerControllerFuncs[gActiveBattler] = LinkOpponentBufferRunCommand; gBattlerControllerFuncs[battler] = LinkOpponentBufferRunCommand;
} }
static void LinkOpponentBufferRunCommand(void) static void LinkOpponentBufferRunCommand(u32 battler)
{ {
if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) if (gBattleControllerExecFlags & gBitTable[battler])
{ {
if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sLinkOpponentBufferCommands)) if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sLinkOpponentBufferCommands))
sLinkOpponentBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); sLinkOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler);
else else
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted(battler);
} }
} }
static void Intro_DelayAndEnd(void) static void Intro_DelayAndEnd(u32 battler)
{ {
if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == (u8)-1) if (--gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay == (u8)-1)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0;
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted(battler);
} }
} }
static void Intro_WaitForShinyAnimAndHealthbox(void) static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
{ {
bool32 healthboxAnimDone = FALSE; bool32 healthboxAnimDone = FALSE;
bool32 twoMons = FALSE; bool32 twoMons = FALSE;
if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)))
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
healthboxAnimDone = TRUE; healthboxAnimDone = TRUE;
} }
else else
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy
&& gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy)
{ {
healthboxAnimDone = TRUE; healthboxAnimDone = TRUE;
} }
@ -157,87 +157,87 @@ static void Intro_WaitForShinyAnimAndHealthbox(void)
if (healthboxAnimDone) if (healthboxAnimDone)
{ {
if (twoMons || !IsBattlerSpriteVisible(BATTLE_PARTNER(gActiveBattler))) if (twoMons || !IsBattlerSpriteVisible(BATTLE_PARTNER(battler)))
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) if (!gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
return; return;
if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim)
return; return;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
} }
else else
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) if (!gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
return; return;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
if (GetBattlerPosition(gActiveBattler) == B_POSITION_OPPONENT_RIGHT) if (GetBattlerPosition(battler) == B_POSITION_OPPONENT_RIGHT)
{ {
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
} }
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3;
gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; gBattlerControllerFuncs[battler] = Intro_DelayAndEnd;
} }
} }
static void Intro_TryShinyAnimShowHealthbox(void) static void Intro_TryShinyAnimShowHealthbox(u32 battler)
{ {
bool32 bgmRestored = FALSE; bool32 bgmRestored = FALSE;
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim && !gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) && !gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
{ {
TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]);
} }
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim)
{ {
TryShinyAnimation(BATTLE_PARTNER(gActiveBattler), &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]]); TryShinyAnimation(BATTLE_PARTNER(battler), &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]]);
} }
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive) if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted) if (!gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted)
{ {
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
{ {
UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL);
StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); StartHealthboxSlideIn(BATTLE_PARTNER(battler));
SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]);
} }
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gEnemyParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = TRUE; gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = TRUE;
} }
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].waitForCry if (!gBattleSpritesDataPtr->healthBoxesData[battler].waitForCry
&& gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted && gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].waitForCry && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].waitForCry
&& !IsCryPlayingOrClearCrySongs()) && !IsCryPlayingOrClearCrySongs())
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored) if (!gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored)
{ {
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK) if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK)
{ {
if (GetBattlerPosition(gActiveBattler) == B_POSITION_OPPONENT_LEFT) if (GetBattlerPosition(battler) == B_POSITION_OPPONENT_LEFT)
m4aMPlayContinue(&gMPlayInfo_BGM); m4aMPlayContinue(&gMPlayInfo_BGM);
} }
else else
@ -246,189 +246,189 @@ static void Intro_TryShinyAnimShowHealthbox(void)
} }
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = TRUE; gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = TRUE;
bgmRestored = TRUE; bgmRestored = TRUE;
} }
if (bgmRestored) if (bgmRestored)
{ {
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && GetBattlerPosition(gActiveBattler) == B_POSITION_OPPONENT_RIGHT) if (gBattleTypeFlags & BATTLE_TYPE_MULTI && GetBattlerPosition(battler) == B_POSITION_OPPONENT_RIGHT)
{ {
if (++gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == 1) if (++gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay == 1)
return; return;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0;
} }
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
{ {
DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]]);
SetBattlerShadowSpriteCallback(BATTLE_PARTNER(gActiveBattler), GetMonData(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], MON_DATA_SPECIES)); SetBattlerShadowSpriteCallback(BATTLE_PARTNER(battler), GetMonData(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], MON_DATA_SPECIES));
} }
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[battler]]);
SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES));
gBattleSpritesDataPtr->animationData->introAnimActive = FALSE; gBattleSpritesDataPtr->animationData->introAnimActive = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = FALSE;
gBattlerControllerFuncs[gActiveBattler] = Intro_WaitForShinyAnimAndHealthbox; gBattlerControllerFuncs[battler] = Intro_WaitForShinyAnimAndHealthbox;
} }
} }
} }
static void TryShinyAnimAfterMonAnim(void) static void TryShinyAnimAfterMonAnim(u32 battler)
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].x2 == 0) && gSprites[gBattlerSpriteIds[battler]].x2 == 0)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim) if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim)
{ {
TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]);
} }
else if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) else if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted(battler);
} }
} }
} }
static void SwitchIn_ShowSubstitute(void) static void SwitchIn_ShowSubstitute(u32 battler)
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_HandleSoundAndEnd; gBattlerControllerFuncs[battler] = SwitchIn_HandleSoundAndEnd;
} }
} }
static void SwitchIn_HandleSoundAndEnd(void) static void SwitchIn_HandleSoundAndEnd(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive && !IsCryPlayingOrClearCrySongs()) if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive && !IsCryPlayingOrClearCrySongs())
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy
|| gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy_2) || gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy_2)
{ {
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100); m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted(battler);
} }
} }
} }
static void SwitchIn_ShowHealthbox(void) static void SwitchIn_ShowHealthbox(u32 battler)
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
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[battler]], 0);
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gEnemyParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
CopyBattleSpriteInvisibility(gActiveBattler); CopyBattleSpriteInvisibility(battler);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowSubstitute; gBattlerControllerFuncs[battler] = SwitchIn_ShowSubstitute;
} }
} }
static void SwitchIn_TryShinyAnim(void) static void SwitchIn_TryShinyAnim(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim) && !gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim)
{ {
TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]);
} }
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
{ {
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[battler]]);
SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES));
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowHealthbox; gBattlerControllerFuncs[battler] = SwitchIn_ShowHealthbox;
} }
} }
static void LinkOpponentBufferExecCompleted(void) static void LinkOpponentBufferExecCompleted(u32 battler)
{ {
gBattlerControllerFuncs[gActiveBattler] = LinkOpponentBufferRunCommand; gBattlerControllerFuncs[battler] = LinkOpponentBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK) if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{ {
u8 playerId = GetMultiplayerId(); u8 playerId = GetMultiplayerId();
PrepareBufferDataTransferLink(2, 4, &playerId); PrepareBufferDataTransferLink(2, 4, &playerId);
gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP;
} }
else else
{ {
gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; gBattleControllerExecFlags &= ~gBitTable[battler];
} }
} }
static void LinkOpponentHandleLoadMonSprite(void) static void LinkOpponentHandleLoadMonSprite(u32 battler)
{ {
BtlController_HandleLoadMonSprite(gActiveBattler, gEnemyParty, TryShinyAnimAfterMonAnim); BtlController_HandleLoadMonSprite(battler, gEnemyParty, TryShinyAnimAfterMonAnim);
} }
static void LinkOpponentHandleSwitchInAnim(void) static void LinkOpponentHandleSwitchInAnim(u32 battler)
{ {
BtlController_HandleSwitchInAnim(gActiveBattler, FALSE, SwitchIn_TryShinyAnim); BtlController_HandleSwitchInAnim(battler, FALSE, SwitchIn_TryShinyAnim);
} }
static void LinkOpponentHandleDrawTrainerPic(void) static void LinkOpponentHandleDrawTrainerPic(u32 battler)
{ {
s16 xPos; s16 xPos;
u32 trainerPicId; u32 trainerPicId;
if (gBattleTypeFlags & BATTLE_TYPE_MULTI) if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{ {
if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != 0) // second mon if ((GetBattlerPosition(battler) & BIT_FLANK) != 0) // second mon
xPos = 152; xPos = 152;
else // first mon else // first mon
xPos = 200; xPos = 200;
if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
{ {
if (gActiveBattler == B_POSITION_OPPONENT_LEFT) if (battler == B_POSITION_OPPONENT_LEFT)
trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A);
else else
trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B); trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B);
} }
else else
{ {
if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_FIRE_RED if ((gLinkPlayers[GetBattlerMultiplayerId(battler)].version & 0xFF) == VERSION_FIRE_RED
|| (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_LEAF_GREEN) || (gLinkPlayers[GetBattlerMultiplayerId(battler)].version & 0xFF) == VERSION_LEAF_GREEN)
{ {
if (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender != MALE) if (gLinkPlayers[GetBattlerMultiplayerId(battler)].gender != MALE)
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_LEAF]; trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_LEAF];
else else
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_RED]; trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_RED];
} }
else if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_RUBY else if ((gLinkPlayers[GetBattlerMultiplayerId(battler)].version & 0xFF) == VERSION_RUBY
|| (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_SAPPHIRE) || (gLinkPlayers[GetBattlerMultiplayerId(battler)].version & 0xFF) == VERSION_SAPPHIRE)
{ {
if (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender != MALE) if (gLinkPlayers[GetBattlerMultiplayerId(battler)].gender != MALE)
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_RS_MAY]; trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_RS_MAY];
else else
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_RS_BRENDAN]; trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_RS_BRENDAN];
} }
else else
{ {
trainerPicId = PlayerGenderToFrontTrainerPicId(gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender); trainerPicId = PlayerGenderToFrontTrainerPicId(gLinkPlayers[GetBattlerMultiplayerId(battler)].gender);
} }
} }
} }
@ -461,77 +461,77 @@ static void LinkOpponentHandleDrawTrainerPic(void)
} }
} }
BtlController_HandleDrawTrainerPic(gActiveBattler, trainerPicId, TRUE, BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE,
xPos, 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicId].size), xPos, 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicId].size),
-1); -1);
} }
static void LinkOpponentHandleTrainerSlide(void) static void LinkOpponentHandleTrainerSlide(u32 battler)
{ {
u32 trainerPicId; u32 trainerPicId;
if (gActiveBattler == 1) if (battler == B_POSITION_OPPONENT_LEFT)
trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A);
else else
trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B); trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B);
BtlController_HandleTrainerSlide(gActiveBattler, trainerPicId); BtlController_HandleTrainerSlide(battler, trainerPicId);
LinkOpponentBufferExecCompleted(); // Possibly a bug, because execution should be completed after the slide in finishes. See Controller_WaitForTrainerPic. LinkOpponentBufferExecCompleted(battler); // Possibly a bug, because execution should be completed after the slide in finishes. See Controller_WaitForTrainerPic.
} }
static void LinkOpponentHandleTrainerSlideBack(void) static void LinkOpponentHandleTrainerSlideBack(u32 battler)
{ {
BtlController_HandleTrainerSlideBack(gActiveBattler, 35, FALSE); BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
} }
static void LinkOpponentHandleMoveAnimation(void) static void LinkOpponentHandleMoveAnimation(u32 battler)
{ {
BtlController_HandleMoveAnimation(gActiveBattler, TRUE); BtlController_HandleMoveAnimation(battler, TRUE);
} }
static void LinkOpponentHandlePrintString(void) static void LinkOpponentHandlePrintString(u32 battler)
{ {
BtlController_HandlePrintString(gActiveBattler, TRUE, FALSE); BtlController_HandlePrintString(battler, TRUE, FALSE);
} }
static void LinkOpponentHandleHealthBarUpdate(void) static void LinkOpponentHandleHealthBarUpdate(u32 battler)
{ {
BtlController_HandleHealthBarUpdate(gActiveBattler, FALSE); BtlController_HandleHealthBarUpdate(battler, FALSE);
} }
static void LinkOpponentHandleIntroTrainerBallThrow(void) static void LinkOpponentHandleIntroTrainerBallThrow(u32 battler)
{ {
BtlController_HandleIntroTrainerBallThrow(gActiveBattler, 0, NULL, 0, Intro_TryShinyAnimShowHealthbox); BtlController_HandleIntroTrainerBallThrow(battler, 0, NULL, 0, Intro_TryShinyAnimShowHealthbox);
} }
static void LinkOpponentHandleDrawPartyStatusSummary(void) static void LinkOpponentHandleDrawPartyStatusSummary(u32 battler)
{ {
BtlController_HandleDrawPartyStatusSummary(gActiveBattler, B_SIDE_OPPONENT, TRUE); BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_OPPONENT, TRUE);
} }
static void LinkOpponentHandleBattleAnimation(void) static void LinkOpponentHandleBattleAnimation(u32 battler)
{ {
BtlController_HandleBattleAnimation(gActiveBattler, FALSE, TRUE); BtlController_HandleBattleAnimation(battler, FALSE, TRUE);
} }
static void LinkOpponentHandleLinkStandbyMsg(void) static void LinkOpponentHandleLinkStandbyMsg(u32 battler)
{ {
RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[gActiveBattler][2]); RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][2]);
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted(battler);
} }
static void LinkOpponentHandleEndLinkBattle(void) static void LinkOpponentHandleEndLinkBattle(u32 battler)
{ {
RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[gActiveBattler][4]); RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]);
if (gBattleResources->bufferA[gActiveBattler][1] == B_OUTCOME_DREW) if (gBattleResources->bufferA[battler][1] == B_OUTCOME_DREW)
gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; gBattleOutcome = gBattleResources->bufferA[battler][1];
else else
gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1] ^ B_OUTCOME_DREW; gBattleOutcome = gBattleResources->bufferA[battler][1] ^ B_OUTCOME_DREW;
gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[gActiveBattler][2]; gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2];
FadeOutMapMusic(5); FadeOutMapMusic(5);
BeginFastPaletteFade(3); BeginFastPaletteFade(3);
LinkOpponentBufferExecCompleted(); LinkOpponentBufferExecCompleted(battler);
gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; gBattlerControllerFuncs[battler] = SetBattleEndCallbacks;
} }

View File

@ -29,24 +29,24 @@
#include "constants/trainers.h" #include "constants/trainers.h"
#include "recorded_battle.h" #include "recorded_battle.h"
static void LinkPartnerHandleLoadMonSprite(void); static void LinkPartnerHandleLoadMonSprite(u32 battler);
static void LinkPartnerHandleSwitchInAnim(void); static void LinkPartnerHandleSwitchInAnim(u32 battler);
static void LinkPartnerHandleDrawTrainerPic(void); static void LinkPartnerHandleDrawTrainerPic(u32 battler);
static void LinkPartnerHandleTrainerSlideBack(void); static void LinkPartnerHandleTrainerSlideBack(u32 battler);
static void LinkPartnerHandleMoveAnimation(void); static void LinkPartnerHandleMoveAnimation(u32 battler);
static void LinkPartnerHandlePrintString(void); static void LinkPartnerHandlePrintString(u32 battler);
static void LinkPartnerHandleHealthBarUpdate(void); static void LinkPartnerHandleHealthBarUpdate(u32 battler);
static void LinkPartnerHandleIntroTrainerBallThrow(void); static void LinkPartnerHandleIntroTrainerBallThrow(u32 battler);
static void LinkPartnerHandleDrawPartyStatusSummary(void); static void LinkPartnerHandleDrawPartyStatusSummary(u32 battler);
static void LinkPartnerHandleBattleAnimation(void); static void LinkPartnerHandleBattleAnimation(u32 battler);
static void LinkPartnerHandleLinkStandbyMsg(void); static void LinkPartnerHandleLinkStandbyMsg(u32 battler);
static void LinkPartnerHandleEndLinkBattle(void); static void LinkPartnerHandleEndLinkBattle(u32 battler);
static void LinkPartnerBufferRunCommand(void); static void LinkPartnerBufferRunCommand(u32 battler);
static void LinkPartnerBufferExecCompleted(void); static void LinkPartnerBufferExecCompleted(u32 battler);
static void SwitchIn_WaitAndEnd(void); static void SwitchIn_WaitAndEnd(u32 battler);
static void (*const sLinkPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(void) = static void (*const sLinkPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{ {
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty, [CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -108,121 +108,121 @@ static void (*const sLinkPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
}; };
void SetControllerToLinkPartner(void) void SetControllerToLinkPartner(u32 battler)
{ {
gBattlerControllerEndFuncs[gActiveBattler] = LinkPartnerBufferExecCompleted; gBattlerControllerEndFuncs[battler] = LinkPartnerBufferExecCompleted;
gBattlerControllerFuncs[gActiveBattler] = LinkPartnerBufferRunCommand; gBattlerControllerFuncs[battler] = LinkPartnerBufferRunCommand;
} }
static void LinkPartnerBufferRunCommand(void) static void LinkPartnerBufferRunCommand(u32 battler)
{ {
if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) if (gBattleControllerExecFlags & gBitTable[battler])
{ {
if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sLinkPartnerBufferCommands)) if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sLinkPartnerBufferCommands))
sLinkPartnerBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); sLinkPartnerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
else else
LinkPartnerBufferExecCompleted(); LinkPartnerBufferExecCompleted(battler);
} }
} }
static void WaitForMonAnimAfterLoad(void) static void WaitForMonAnimAfterLoad(u32 battler)
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].animEnded && gSprites[gBattlerSpriteIds[gActiveBattler]].x2 == 0) if (gSprites[gBattlerSpriteIds[battler]].animEnded && gSprites[gBattlerSpriteIds[battler]].x2 == 0)
LinkPartnerBufferExecCompleted(); LinkPartnerBufferExecCompleted(battler);
} }
static void SwitchIn_ShowSubstitute(void) static void SwitchIn_ShowSubstitute(u32 battler)
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
CopyBattleSpriteInvisibility(gActiveBattler); CopyBattleSpriteInvisibility(battler);
if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_WaitAndEnd; gBattlerControllerFuncs[battler] = SwitchIn_WaitAndEnd;
} }
} }
static void SwitchIn_WaitAndEnd(void) static void SwitchIn_WaitAndEnd(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
LinkPartnerBufferExecCompleted(); LinkPartnerBufferExecCompleted(battler);
} }
} }
static void SwitchIn_ShowHealthbox(void) static void SwitchIn_ShowHealthbox(u32 battler)
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
CreateTask(Task_PlayerController_RestoreBgmAfterCry, 10); CreateTask(Task_PlayerController_RestoreBgmAfterCry, 10);
HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler);
StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 0);
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowSubstitute; gBattlerControllerFuncs[battler] = SwitchIn_ShowSubstitute;
} }
} }
static void SwitchIn_TryShinyAnim(void) static void SwitchIn_TryShinyAnim(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
{ {
TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]);
} }
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
{ {
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[battler]]);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowHealthbox; gBattlerControllerFuncs[battler] = SwitchIn_ShowHealthbox;
} }
} }
static void LinkPartnerBufferExecCompleted(void) static void LinkPartnerBufferExecCompleted(u32 battler)
{ {
gBattlerControllerFuncs[gActiveBattler] = LinkPartnerBufferRunCommand; gBattlerControllerFuncs[battler] = LinkPartnerBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK) if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{ {
u8 playerId = GetMultiplayerId(); u8 playerId = GetMultiplayerId();
PrepareBufferDataTransferLink(2, 4, &playerId); PrepareBufferDataTransferLink(2, 4, &playerId);
gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP;
} }
else else
{ {
gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; gBattleControllerExecFlags &= ~gBitTable[battler];
} }
} }
static void LinkPartnerHandleLoadMonSprite(void) static void LinkPartnerHandleLoadMonSprite(u32 battler)
{ {
BtlController_HandleLoadMonSprite(gActiveBattler, gPlayerParty, WaitForMonAnimAfterLoad); BtlController_HandleLoadMonSprite(battler, gPlayerParty, WaitForMonAnimAfterLoad);
} }
static void LinkPartnerHandleSwitchInAnim(void) static void LinkPartnerHandleSwitchInAnim(u32 battler)
{ {
BtlController_HandleSwitchInAnim(gActiveBattler, TRUE, SwitchIn_TryShinyAnim); BtlController_HandleSwitchInAnim(battler, TRUE, SwitchIn_TryShinyAnim);
} }
static void LinkPartnerHandleDrawTrainerPic(void) static void LinkPartnerHandleDrawTrainerPic(u32 battler)
{ {
s16 xPos; s16 xPos;
u32 trainerPicId; u32 trainerPicId;
if (gBattleTypeFlags & BATTLE_TYPE_MULTI) if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{ {
if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != 0) // second mon if ((GetBattlerPosition(battler) & BIT_FLANK) != 0) // second mon
xPos = 90; xPos = 90;
else // first mon else // first mon
xPos = 32; xPos = 32;
@ -232,76 +232,63 @@ static void LinkPartnerHandleDrawTrainerPic(void)
xPos = 80; xPos = 80;
} }
trainerPicId = LinkPlayerGetTrainerPicId(GetBattlerMultiplayerId(gActiveBattler)); trainerPicId = LinkPlayerGetTrainerPicId(GetBattlerMultiplayerId(battler));
BtlController_HandleDrawTrainerPic(gActiveBattler, trainerPicId, FALSE, BtlController_HandleDrawTrainerPic(battler, trainerPicId, FALSE,
xPos, 80 + 4 * (8 - gTrainerBackPicCoords[trainerPicId].size), xPos, 80 + 4 * (8 - gTrainerBackPicCoords[trainerPicId].size),
-1); -1);
} }
static void LinkPartnerHandleTrainerSlideBack(void) static void LinkPartnerHandleTrainerSlideBack(u32 battler)
{ {
BtlController_HandleTrainerSlideBack(gActiveBattler, 35, FALSE); BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
} }
static void LinkPartnerHandleMoveAnimation(void) static void LinkPartnerHandleMoveAnimation(u32 battler)
{ {
BtlController_HandleMoveAnimation(gActiveBattler, TRUE); BtlController_HandleMoveAnimation(battler, TRUE);
} }
static void LinkPartnerHandlePrintString(void) static void LinkPartnerHandlePrintString(u32 battler)
{ {
BtlController_HandlePrintString(gActiveBattler, TRUE, FALSE); BtlController_HandlePrintString(battler, TRUE, FALSE);
} }
static void LinkPartnerHandleHealthBarUpdate(void) static void LinkPartnerHandleHealthBarUpdate(u32 battler)
{ {
BtlController_HandleHealthBarUpdate(gActiveBattler, FALSE); BtlController_HandleHealthBarUpdate(battler, FALSE);
} }
static void LinkPartnerHandleIntroTrainerBallThrow(void) static void LinkPartnerHandleIntroTrainerBallThrow(u32 battler)
{ {
u32 trainerPicId; u32 trainerPicId = LinkPlayerGetTrainerPicId(GetBattlerMultiplayerId(battler));
u8 gameVersion, playerGender; const u32 *trainerPal = gTrainerBackPicPaletteTable[trainerPicId].data;
const u32 *trainerPal;
gameVersion = gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF;
playerGender = gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender;
if (gameVersion == VERSION_FIRE_RED || gameVersion == VERSION_LEAF_GREEN)
trainerPicId = playerGender + TRAINER_BACK_PIC_RED;
else if (gameVersion == VERSION_RUBY || gameVersion == VERSION_SAPPHIRE)
trainerPicId = playerGender + TRAINER_BACK_PIC_RUBY_SAPPHIRE_BRENDAN;
else
trainerPicId = playerGender + TRAINER_BACK_PIC_BRENDAN;
trainerPal = gTrainerBackPicPaletteTable[trainerPicId].data;
// Link partner uses the same intro sequence as the player partner. // Link partner uses the same intro sequence as the player partner.
BtlController_HandleIntroTrainerBallThrow(gActiveBattler, 0xD6F9, trainerPal, 24, Controller_PlayerPartnerShowIntroHealthbox); BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F9, trainerPal, 24, Controller_PlayerPartnerShowIntroHealthbox);
} }
static void LinkPartnerHandleDrawPartyStatusSummary(void) static void LinkPartnerHandleDrawPartyStatusSummary(u32 battler)
{ {
BtlController_HandleDrawPartyStatusSummary(gActiveBattler, B_SIDE_PLAYER, TRUE); BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, TRUE);
} }
static void LinkPartnerHandleBattleAnimation(void) static void LinkPartnerHandleBattleAnimation(u32 battler)
{ {
BtlController_HandleBattleAnimation(gActiveBattler, FALSE, TRUE); BtlController_HandleBattleAnimation(battler, FALSE, TRUE);
} }
static void LinkPartnerHandleLinkStandbyMsg(void) static void LinkPartnerHandleLinkStandbyMsg(u32 battler)
{ {
RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[gActiveBattler][2]); RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][2]);
LinkPartnerBufferExecCompleted(); LinkPartnerBufferExecCompleted(battler);
} }
static void LinkPartnerHandleEndLinkBattle(void) static void LinkPartnerHandleEndLinkBattle(u32 battler)
{ {
RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[gActiveBattler][4]); RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]);
gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; gBattleOutcome = gBattleResources->bufferA[battler][1];
gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[gActiveBattler][2]; gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2];
FadeOutMapMusic(5); FadeOutMapMusic(5);
BeginFastPaletteFade(3); BeginFastPaletteFade(3);
LinkPartnerBufferExecCompleted(); LinkPartnerBufferExecCompleted(battler);
gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; gBattlerControllerFuncs[battler] = SetBattleEndCallbacks;
} }

View File

@ -39,29 +39,29 @@
#include "constants/trainers.h" #include "constants/trainers.h"
#include "trainer_hill.h" #include "trainer_hill.h"
static void OpponentHandleLoadMonSprite(void); static void OpponentHandleLoadMonSprite(u32 battler);
static void OpponentHandleSwitchInAnim(void); static void OpponentHandleSwitchInAnim(u32 battler);
static void OpponentHandleDrawTrainerPic(void); static void OpponentHandleDrawTrainerPic(u32 battler);
static void OpponentHandleTrainerSlide(void); static void OpponentHandleTrainerSlide(u32 battler);
static void OpponentHandleTrainerSlideBack(void); static void OpponentHandleTrainerSlideBack(u32 battler);
static void OpponentHandleMoveAnimation(void); static void OpponentHandleMoveAnimation(u32 battler);
static void OpponentHandlePrintString(void); static void OpponentHandlePrintString(u32 battler);
static void OpponentHandleChooseAction(void); static void OpponentHandleChooseAction(u32 battler);
static void OpponentHandleChooseMove(void); static void OpponentHandleChooseMove(u32 battler);
static void OpponentHandleChooseItem(void); static void OpponentHandleChooseItem(u32 battler);
static void OpponentHandleChoosePokemon(void); static void OpponentHandleChoosePokemon(u32 battler);
static void OpponentHandleHealthBarUpdate(void); static void OpponentHandleHealthBarUpdate(u32 battler);
static void OpponentHandleIntroTrainerBallThrow(void); static void OpponentHandleIntroTrainerBallThrow(u32 battler);
static void OpponentHandleDrawPartyStatusSummary(void); static void OpponentHandleDrawPartyStatusSummary(u32 battler);
static void OpponentHandleBattleAnimation(void); static void OpponentHandleBattleAnimation(u32 battler);
static void OpponentHandleEndLinkBattle(void); static void OpponentHandleEndLinkBattle(u32 battler);
static u8 CountAIAliveNonEggMonsExcept(u8 slotToIgnore); static u8 CountAIAliveNonEggMonsExcept(u8 slotToIgnore);
static void OpponentBufferRunCommand(void); static void OpponentBufferRunCommand(u32 battler);
static void OpponentBufferExecCompleted(void); static void OpponentBufferExecCompleted(u32 battler);
static void SwitchIn_HandleSoundAndEnd(void); static void SwitchIn_HandleSoundAndEnd(u32 battler);
static void (*const sOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(void) = static void (*const sOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{ {
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_HandleGetRawMonData, [CONTROLLER_GETRAWMONDATA] = BtlController_HandleGetRawMonData,
@ -123,78 +123,78 @@ static void (*const sOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
}; };
void SetControllerToOpponent(void) void SetControllerToOpponent(u32 battler)
{ {
gBattlerControllerEndFuncs[gActiveBattler] = OpponentBufferExecCompleted; gBattlerControllerEndFuncs[battler] = OpponentBufferExecCompleted;
gBattlerControllerFuncs[gActiveBattler] = OpponentBufferRunCommand; gBattlerControllerFuncs[battler] = OpponentBufferRunCommand;
} }
static void OpponentBufferRunCommand(void) static void OpponentBufferRunCommand(u32 battler)
{ {
if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) if (gBattleControllerExecFlags & gBitTable[battler])
{ {
if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sOpponentBufferCommands)) if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sOpponentBufferCommands))
sOpponentBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); sOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler);
else else
OpponentBufferExecCompleted(); OpponentBufferExecCompleted(battler);
} }
} }
static void Intro_DelayAndEnd(void) static void Intro_DelayAndEnd(u32 battler)
{ {
if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == (u8)-1) if (--gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay == (u8)-1)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0;
OpponentBufferExecCompleted(); OpponentBufferExecCompleted(battler);
} }
} }
static void Intro_WaitForShinyAnimAndHealthbox(void) static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
{ {
bool8 healthboxAnimDone = FALSE; bool8 healthboxAnimDone = FALSE;
bool8 twoMons; bool8 twoMons;
twoMons = TwoOpponentIntroMons(gActiveBattler); twoMons = TwoOpponentIntroMons(battler);
if (!twoMons || ((twoMons && (gBattleTypeFlags & BATTLE_TYPE_MULTI) && !BATTLE_TWO_VS_ONE_OPPONENT) || (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS))) if (!twoMons || ((twoMons && (gBattleTypeFlags & BATTLE_TYPE_MULTI) && !BATTLE_TWO_VS_ONE_OPPONENT) || (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)))
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
healthboxAnimDone = TRUE; healthboxAnimDone = TRUE;
twoMons = FALSE; twoMons = FALSE;
} }
else else
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy
&& gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy)
healthboxAnimDone = TRUE; healthboxAnimDone = TRUE;
twoMons = TRUE; twoMons = TRUE;
} }
gBattleControllerOpponentHealthboxData = &gBattleSpritesDataPtr->healthBoxesData[gActiveBattler]; gBattleControllerOpponentHealthboxData = &gBattleSpritesDataPtr->healthBoxesData[battler];
gBattleControllerOpponentFlankHealthboxData = &gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)]; gBattleControllerOpponentFlankHealthboxData = &gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)];
if (healthboxAnimDone) if (healthboxAnimDone)
{ {
if (twoMons == TRUE) if (twoMons == TRUE)
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim
&& gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) && gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
} }
else else
return; return;
} }
else if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) else if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
{ {
if (GetBattlerPosition(gActiveBattler) == 3) if (GetBattlerPosition(battler) == 3)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim)
{ {
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
@ -202,87 +202,87 @@ static void Intro_WaitForShinyAnimAndHealthbox(void)
else else
return; return;
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
} }
else else
return; return;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3;
gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; gBattlerControllerFuncs[battler] = Intro_DelayAndEnd;
} }
} }
static void Intro_TryShinyAnimShowHealthbox(void) static void Intro_TryShinyAnimShowHealthbox(u32 battler)
{ {
bool32 bgmRestored = FALSE; bool32 bgmRestored = FALSE;
bool32 battlerAnimsDone = FALSE; bool32 battlerAnimsDone = FALSE;
bool32 twoMons; bool32 twoMons;
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) && !gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]);
twoMons = TwoOpponentIntroMons(gActiveBattler); twoMons = TwoOpponentIntroMons(battler);
if (!(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) if (!(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
&& (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT) && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT)
&& twoMons && twoMons
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim)
TryShinyAnimation(BATTLE_PARTNER(gActiveBattler), &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]]); TryShinyAnimation(BATTLE_PARTNER(battler), &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]]);
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive) if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted) if (!gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted)
{ {
if (twoMons && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT)) if (twoMons && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT))
{ {
UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL);
StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); StartHealthboxSlideIn(BATTLE_PARTNER(battler));
SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]);
} }
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gEnemyParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = TRUE; gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = TRUE;
} }
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].waitForCry if (!gBattleSpritesDataPtr->healthBoxesData[battler].waitForCry
&& gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted && gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].waitForCry && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].waitForCry
&& !IsCryPlayingOrClearCrySongs()) && !IsCryPlayingOrClearCrySongs())
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored) if (!gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored)
{ {
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK) if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK)
{ {
if (GetBattlerPosition(gActiveBattler) == 1) if (GetBattlerPosition(battler) == 1)
m4aMPlayContinue(&gMPlayInfo_BGM); m4aMPlayContinue(&gMPlayInfo_BGM);
} }
else else
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100); m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = TRUE; gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = TRUE;
bgmRestored = TRUE; bgmRestored = TRUE;
} }
if (!twoMons || (twoMons && gBattleTypeFlags & BATTLE_TYPE_MULTI && !BATTLE_TWO_VS_ONE_OPPONENT)) if (!twoMons || (twoMons && gBattleTypeFlags & BATTLE_TYPE_MULTI && !BATTLE_TWO_VS_ONE_OPPONENT))
{ {
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
battlerAnimsDone = TRUE; battlerAnimsDone = TRUE;
} }
} }
else else
{ {
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy && gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy)
{ {
battlerAnimsDone = TRUE; battlerAnimsDone = TRUE;
} }
@ -292,119 +292,119 @@ static void Intro_TryShinyAnimShowHealthbox(void)
{ {
if (twoMons && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT)) if (twoMons && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT))
{ {
DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]]);
SetBattlerShadowSpriteCallback(BATTLE_PARTNER(gActiveBattler), GetMonData(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], MON_DATA_SPECIES)); SetBattlerShadowSpriteCallback(BATTLE_PARTNER(battler), GetMonData(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], MON_DATA_SPECIES));
} }
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[battler]]);
SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES));
gBattleSpritesDataPtr->animationData->introAnimActive = FALSE; gBattleSpritesDataPtr->animationData->introAnimActive = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = FALSE;
gBattlerControllerFuncs[gActiveBattler] = Intro_WaitForShinyAnimAndHealthbox; gBattlerControllerFuncs[battler] = Intro_WaitForShinyAnimAndHealthbox;
} }
} }
static void TryShinyAnimAfterMonAnim(void) static void TryShinyAnimAfterMonAnim(u32 battler)
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].x2 == 0 if (gSprites[gBattlerSpriteIds[battler]].x2 == 0
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim && !gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) && !gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]);
if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy
&& gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) && gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
OpponentBufferExecCompleted(); OpponentBufferExecCompleted(battler);
} }
} }
static void SwitchIn_ShowSubstitute(void) static void SwitchIn_ShowSubstitute(u32 battler)
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_HandleSoundAndEnd; gBattlerControllerFuncs[battler] = SwitchIn_HandleSoundAndEnd;
} }
} }
static void SwitchIn_HandleSoundAndEnd(void) static void SwitchIn_HandleSoundAndEnd(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive && !IsCryPlayingOrClearCrySongs()) if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive && !IsCryPlayingOrClearCrySongs())
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy
|| gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy_2) || gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy_2)
{ {
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100); m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
OpponentBufferExecCompleted(); OpponentBufferExecCompleted(battler);
} }
} }
} }
static void SwitchIn_ShowHealthbox(void) static void SwitchIn_ShowHealthbox(u32 battler)
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
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[battler]], 0);
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gEnemyParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
CopyBattleSpriteInvisibility(gActiveBattler); CopyBattleSpriteInvisibility(battler);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowSubstitute; gBattlerControllerFuncs[battler] = SwitchIn_ShowSubstitute;
} }
} }
static void SwitchIn_TryShinyAnim(void) static void SwitchIn_TryShinyAnim(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]);
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
{ {
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[battler]]);
SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES));
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowHealthbox; gBattlerControllerFuncs[battler] = SwitchIn_ShowHealthbox;
} }
} }
static void OpponentBufferExecCompleted(void) static void OpponentBufferExecCompleted(u32 battler)
{ {
gBattlerControllerFuncs[gActiveBattler] = OpponentBufferRunCommand; gBattlerControllerFuncs[battler] = OpponentBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK) if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{ {
u8 playerId = GetMultiplayerId(); u8 playerId = GetMultiplayerId();
PrepareBufferDataTransferLink(2, 4, &playerId); PrepareBufferDataTransferLink(2, 4, &playerId);
gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP;
} }
else else
{ {
gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; gBattleControllerExecFlags &= ~gBitTable[battler];
} }
} }
static void OpponentHandleLoadMonSprite(void) static void OpponentHandleLoadMonSprite(u32 battler)
{ {
BtlController_HandleLoadMonSprite(gActiveBattler, gEnemyParty, TryShinyAnimAfterMonAnim); BtlController_HandleLoadMonSprite(battler, gEnemyParty, TryShinyAnimAfterMonAnim);
} }
static void OpponentHandleSwitchInAnim(void) static void OpponentHandleSwitchInAnim(u32 battler)
{ {
gBattleStruct->monToSwitchIntoId[gActiveBattler] = PARTY_SIZE; gBattleStruct->monToSwitchIntoId[battler] = PARTY_SIZE;
BtlController_HandleSwitchInAnim(gActiveBattler, FALSE, SwitchIn_TryShinyAnim); BtlController_HandleSwitchInAnim(battler, FALSE, SwitchIn_TryShinyAnim);
} }
static u32 OpponentGetTrainerPicId(u32 battlerId) static u32 OpponentGetTrainerPicId(u32 battlerId)
@ -466,14 +466,14 @@ static u32 OpponentGetTrainerPicId(u32 battlerId)
return trainerPicId; return trainerPicId;
} }
static void OpponentHandleDrawTrainerPic(void) static void OpponentHandleDrawTrainerPic(u32 battler)
{ {
s16 xPos; s16 xPos;
u32 trainerPicId = OpponentGetTrainerPicId(gActiveBattler); u32 trainerPicId = OpponentGetTrainerPicId(battler);
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS) && !BATTLE_TWO_VS_ONE_OPPONENT) if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS) && !BATTLE_TWO_VS_ONE_OPPONENT)
{ {
if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != 0) // second mon if ((GetBattlerPosition(battler) & BIT_FLANK) != 0) // second mon
xPos = 152; xPos = 152;
else // first mon else // first mon
xPos = 200; xPos = 200;
@ -483,42 +483,42 @@ static void OpponentHandleDrawTrainerPic(void)
xPos = 176; xPos = 176;
} }
BtlController_HandleDrawTrainerPic(gActiveBattler, trainerPicId, TRUE, BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE,
xPos, 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicId].size), xPos, 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicId].size),
-1); -1);
} }
static void OpponentHandleTrainerSlide(void) static void OpponentHandleTrainerSlide(u32 battler)
{ {
u32 trainerPicId = OpponentGetTrainerPicId(gActiveBattler); u32 trainerPicId = OpponentGetTrainerPicId(battler);
BtlController_HandleTrainerSlide(gActiveBattler, trainerPicId); BtlController_HandleTrainerSlide(battler, trainerPicId);
} }
static void OpponentHandleTrainerSlideBack(void) static void OpponentHandleTrainerSlideBack(u32 battler)
{ {
BtlController_HandleTrainerSlideBack(gActiveBattler, 35, FALSE); BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
} }
static void OpponentHandleMoveAnimation(void) static void OpponentHandleMoveAnimation(u32 battler)
{ {
BtlController_HandleMoveAnimation(gActiveBattler, FALSE); BtlController_HandleMoveAnimation(battler, FALSE);
} }
static void OpponentHandlePrintString(void) static void OpponentHandlePrintString(u32 battler)
{ {
BtlController_HandlePrintString(gActiveBattler, FALSE, TRUE); BtlController_HandlePrintString(battler, FALSE, TRUE);
} }
static void OpponentHandleChooseAction(void) static void OpponentHandleChooseAction(u32 battler)
{ {
AI_TrySwitchOrUseItem(); AI_TrySwitchOrUseItem();
OpponentBufferExecCompleted(); OpponentBufferExecCompleted(battler);
} }
static void OpponentHandleChooseMove(void) static void OpponentHandleChooseMove(u32 battler)
{ {
u8 chosenMoveId; u8 chosenMoveId;
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]);
if (gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER) if (gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER)
|| IsWildMonSmart()) || IsWildMonSmart())
@ -529,8 +529,8 @@ static void OpponentHandleChooseMove(void)
} }
else else
{ {
chosenMoveId = gBattleStruct->aiMoveOrAction[gActiveBattler]; chosenMoveId = gBattleStruct->aiMoveOrAction[battler];
gBattlerTarget = gBattleStruct->aiChosenTarget[gActiveBattler]; gBattlerTarget = gBattleStruct->aiChosenTarget[battler];
switch (chosenMoveId) switch (chosenMoveId)
{ {
case AI_CHOICE_WATCH: case AI_CHOICE_WATCH:
@ -549,17 +549,17 @@ static void OpponentHandleChooseMove(void)
{ {
u16 chosenMove = moveInfo->moves[chosenMoveId]; u16 chosenMove = moveInfo->moves[chosenMoveId];
if (GetBattlerMoveTargetType(gActiveBattler, chosenMove) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER)) if (GetBattlerMoveTargetType(battler, chosenMove) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
gBattlerTarget = gActiveBattler; gBattlerTarget = battler;
if (GetBattlerMoveTargetType(gActiveBattler, chosenMove) & MOVE_TARGET_BOTH) if (GetBattlerMoveTargetType(battler, chosenMove) & MOVE_TARGET_BOTH)
{ {
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) if (gAbsentBattlerFlags & gBitTable[gBattlerTarget])
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
} }
if (ShouldUseZMove(gActiveBattler, gBattlerTarget, chosenMove)) if (ShouldUseZMove(battler, gBattlerTarget, chosenMove))
QueueZMove(gActiveBattler, chosenMove); QueueZMove(battler, chosenMove);
if (CanMegaEvolve(gActiveBattler)) // If opponent can mega evolve, do it. if (CanMegaEvolve(battler)) // If opponent can mega evolve, do it.
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8));
else else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gBattlerTarget << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gBattlerTarget << 8));
@ -567,7 +567,7 @@ static void OpponentHandleChooseMove(void)
break; break;
} }
} }
OpponentBufferExecCompleted(); OpponentBufferExecCompleted(battler);
} }
else // Wild pokemon - use random move else // Wild pokemon - use random move
{ {
@ -579,13 +579,13 @@ static void OpponentHandleChooseMove(void)
move = moveInfo->moves[chosenMoveId]; move = moveInfo->moves[chosenMoveId];
} while (move == MOVE_NONE); } while (move == MOVE_NONE);
if (GetBattlerMoveTargetType(gActiveBattler, move) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER)) if (GetBattlerMoveTargetType(battler, move) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER))
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gActiveBattler << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (battler << 8));
else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{ {
do { do {
target = GetBattlerAtPosition(Random() & 2); target = GetBattlerAtPosition(Random() & 2);
} while (!CanTargetBattler(gActiveBattler, target, move)); } while (!CanTargetBattler(battler, target, move));
#if B_WILD_NATURAL_ENEMIES == TRUE #if B_WILD_NATURAL_ENEMIES == TRUE
// Don't bother to loop through table if the move can't attack ally // Don't bother to loop through table if the move can't attack ally
@ -602,8 +602,8 @@ static void OpponentHandleChooseMove(void)
{SPECIES_SABLEYE, SPECIES_CARBINK}, {SPECIES_SABLEYE, SPECIES_CARBINK},
{SPECIES_MAREANIE, SPECIES_CORSOLA}, {SPECIES_MAREANIE, SPECIES_CORSOLA},
}; };
speciesAttacker = gBattleMons[gActiveBattler].species; speciesAttacker = gBattleMons[battler].species;
speciesTarget = gBattleMons[GetBattlerAtPosition(BATTLE_PARTNER(gActiveBattler))].species; speciesTarget = gBattleMons[GetBattlerAtPosition(BATTLE_PARTNER(battler))].species;
for (i = 0; i < ARRAY_COUNT(naturalEnemies); i++) for (i = 0; i < ARRAY_COUNT(naturalEnemies); i++)
{ {
@ -613,8 +613,8 @@ static void OpponentHandleChooseMove(void)
break; break;
} }
} }
if (isPartnerEnemy && CanTargetBattler(gActiveBattler, target, move)) if (isPartnerEnemy && CanTargetBattler(battler, target, move))
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(BATTLE_PARTNER(gActiveBattler)) << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(BATTLE_PARTNER(battler)) << 8));
else else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (target << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (target << 8));
} }
@ -625,28 +625,28 @@ static void OpponentHandleChooseMove(void)
else else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) << 8));
OpponentBufferExecCompleted(); OpponentBufferExecCompleted(battler);
} }
} }
static void OpponentHandleChooseItem(void) static void OpponentHandleChooseItem(u32 battler)
{ {
BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[gActiveBattler]); BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[battler]);
OpponentBufferExecCompleted(); OpponentBufferExecCompleted(battler);
} }
static void OpponentHandleChoosePokemon(void) static void OpponentHandleChoosePokemon(u32 battler)
{ {
s32 chosenMonId; s32 chosenMonId;
s32 pokemonInBattle = 1; s32 pokemonInBattle = 1;
// Choosing Revival Blessing target // Choosing Revival Blessing target
if ((gBattleResources->bufferA[gActiveBattler][1] & 0xF) == PARTY_ACTION_CHOOSE_FAINTED_MON) if ((gBattleResources->bufferA[battler][1] & 0xF) == PARTY_ACTION_CHOOSE_FAINTED_MON)
{ {
chosenMonId = gSelectedMonPartyId = GetFirstFaintedPartyIndex(gActiveBattler); chosenMonId = gSelectedMonPartyId = GetFirstFaintedPartyIndex(battler);
} }
// Switching out // Switching out
else if (*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) == PARTY_SIZE) else if (*(gBattleStruct->AI_monToSwitchIntoId + battler) == PARTY_SIZE)
{ {
chosenMonId = GetMostSuitableMonToSwitchInto(); chosenMonId = GetMostSuitableMonToSwitchInto();
@ -666,7 +666,7 @@ static void OpponentHandleChoosePokemon(void)
} }
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId); GetAIPartyIndexes(battler, &firstId, &lastId);
for (chosenMonId = (lastId-1); chosenMonId >= firstId; chosenMonId--) for (chosenMonId = (lastId-1); chosenMonId >= firstId; chosenMonId--)
{ {
@ -681,16 +681,16 @@ static void OpponentHandleChoosePokemon(void)
} }
} }
} }
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = chosenMonId; *(gBattleStruct->monToSwitchIntoId + battler) = chosenMonId;
} }
else else
{ {
chosenMonId = *(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler); chosenMonId = *(gBattleStruct->AI_monToSwitchIntoId + battler);
*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = PARTY_SIZE; *(gBattleStruct->AI_monToSwitchIntoId + battler) = PARTY_SIZE;
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = chosenMonId; *(gBattleStruct->monToSwitchIntoId + battler) = chosenMonId;
} }
BtlController_EmitChosenMonReturnValue(BUFFER_B, chosenMonId, NULL); BtlController_EmitChosenMonReturnValue(BUFFER_B, chosenMonId, NULL);
OpponentBufferExecCompleted(); OpponentBufferExecCompleted(battler);
} }
@ -701,9 +701,7 @@ static u8 CountAIAliveNonEggMonsExcept(u8 slotToIgnore)
for (i = 0, count = 0; i < PARTY_SIZE; i++) for (i = 0, count = 0; i < PARTY_SIZE; i++)
{ {
if (i != slotToIgnore if (i != slotToIgnore
&& GetMonData(&gEnemyParty[i], MON_DATA_SPECIES) != SPECIES_NONE && IsValidForBattle(&gEnemyParty[i]))
&& !GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG)
&& GetMonData(&gEnemyParty[i], MON_DATA_HP) != 0)
{ {
count++; count++;
} }
@ -712,27 +710,27 @@ static u8 CountAIAliveNonEggMonsExcept(u8 slotToIgnore)
return count; return count;
} }
static void OpponentHandleHealthBarUpdate(void) static void OpponentHandleHealthBarUpdate(u32 battler)
{ {
BtlController_HandleHealthBarUpdate(gActiveBattler, FALSE); BtlController_HandleHealthBarUpdate(battler, FALSE);
} }
static void OpponentHandleIntroTrainerBallThrow(void) static void OpponentHandleIntroTrainerBallThrow(u32 battler)
{ {
BtlController_HandleIntroTrainerBallThrow(gActiveBattler, 0, NULL, 0, Intro_TryShinyAnimShowHealthbox); BtlController_HandleIntroTrainerBallThrow(battler, 0, NULL, 0, Intro_TryShinyAnimShowHealthbox);
} }
static void OpponentHandleDrawPartyStatusSummary(void) static void OpponentHandleDrawPartyStatusSummary(u32 battler)
{ {
BtlController_HandleDrawPartyStatusSummary(gActiveBattler, B_SIDE_OPPONENT, TRUE); BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_OPPONENT, TRUE);
} }
static void OpponentHandleBattleAnimation(void) static void OpponentHandleBattleAnimation(u32 battler)
{ {
BtlController_HandleBattleAnimation(gActiveBattler, FALSE, FALSE); BtlController_HandleBattleAnimation(battler, FALSE, FALSE);
} }
static void OpponentHandleEndLinkBattle(void) static void OpponentHandleEndLinkBattle(u32 battler)
{ {
if (gBattleTypeFlags & BATTLE_TYPE_LINK && !(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)) if (gBattleTypeFlags & BATTLE_TYPE_LINK && !(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER))
{ {
@ -740,5 +738,5 @@ static void OpponentHandleEndLinkBattle(void)
gMain.callback1 = gPreBattleCallback1; gMain.callback1 = gPreBattleCallback1;
SetMainCallback2(gMain.savedCallback); SetMainCallback2(gMain.savedCallback);
} }
OpponentBufferExecCompleted(); OpponentBufferExecCompleted(battler);
} }

File diff suppressed because it is too large Load Diff

View File

@ -31,31 +31,26 @@
#include "constants/party_menu.h" #include "constants/party_menu.h"
#include "constants/trainers.h" #include "constants/trainers.h"
static void PlayerPartnerHandleLoadMonSprite(void); static void PlayerPartnerHandleLoadMonSprite(u32 battler);
static void PlayerPartnerHandleSwitchInAnim(void); static void PlayerPartnerHandleSwitchInAnim(u32 battler);
static void PlayerPartnerHandleDrawTrainerPic(void); static void PlayerPartnerHandleDrawTrainerPic(u32 battler);
static void PlayerPartnerHandleTrainerSlideBack(void); static void PlayerPartnerHandleTrainerSlideBack(u32 battler);
static void PlayerPartnerHandleMoveAnimation(void); static void PlayerPartnerHandleMoveAnimation(u32 battler);
static void PlayerPartnerHandlePrintString(void); static void PlayerPartnerHandlePrintString(u32 battler);
static void PlayerPartnerHandleChooseAction(void); static void PlayerPartnerHandleChooseAction(u32 battler);
static void PlayerPartnerHandleChooseMove(void); static void PlayerPartnerHandleChooseMove(u32 battler);
static void PlayerPartnerHandleChoosePokemon(void); static void PlayerPartnerHandleChoosePokemon(u32 battler);
static void PlayerPartnerHandleHealthBarUpdate(void); static void PlayerPartnerHandleHealthBarUpdate(u32 battler);
static void PlayerPartnerHandleIntroTrainerBallThrow(void); static void PlayerPartnerHandleIntroTrainerBallThrow(u32 battler);
static void PlayerPartnerHandleDrawPartyStatusSummary(void); static void PlayerPartnerHandleDrawPartyStatusSummary(u32 battler);
static void PlayerPartnerHandleBattleAnimation(void); static void PlayerPartnerHandleBattleAnimation(u32 battler);
static void PlayerPartnerHandleEndLinkBattle(void); static void PlayerPartnerHandleEndLinkBattle(u32 battler);
static void PlayerPartnerBufferRunCommand(void); static void PlayerPartnerBufferRunCommand(u32 battler);
static void PlayerPartnerBufferExecCompleted(void); static void PlayerPartnerBufferExecCompleted(u32 battler);
static void Task_LaunchLvlUpAnim(u8 taskId); static void SwitchIn_WaitAndEnd(u32 battler);
static void DestroyExpTaskAndCompleteOnInactiveTextPrinter(u8 taskId);
static void Task_PrepareToGiveExpWithExpBar(u8 taskId);
static void Task_GiveExpWithExpBar(u8 taskId);
static void Task_UpdateLvlInHealthbox(u8 taskId);
static void SwitchIn_WaitAndEnd(void);
static void (*const sPlayerPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(void) = static void (*const sPlayerPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{ {
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty, [CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -117,45 +112,45 @@ static void (*const sPlayerPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
}; };
void SetControllerToPlayerPartner(void) void SetControllerToPlayerPartner(u32 battler)
{ {
gBattlerControllerEndFuncs[gActiveBattler] = PlayerPartnerBufferExecCompleted; gBattlerControllerEndFuncs[battler] = PlayerPartnerBufferExecCompleted;
gBattlerControllerFuncs[gActiveBattler] = PlayerPartnerBufferRunCommand; gBattlerControllerFuncs[battler] = PlayerPartnerBufferRunCommand;
} }
static void PlayerPartnerBufferRunCommand(void) static void PlayerPartnerBufferRunCommand(u32 battler)
{ {
if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) if (gBattleControllerExecFlags & gBitTable[battler])
{ {
if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sPlayerPartnerBufferCommands)) if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sPlayerPartnerBufferCommands))
sPlayerPartnerBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); sPlayerPartnerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
else else
PlayerPartnerBufferExecCompleted(); PlayerPartnerBufferExecCompleted(battler);
} }
} }
static void Intro_DelayAndEnd(void) static void Intro_DelayAndEnd(u32 battler)
{ {
if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == (u8)-1) if (--gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay == (u8)-1)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0;
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
} }
static void Intro_WaitForHealthbox(void) static void Intro_WaitForHealthbox(u32 battler)
{ {
bool32 finished = FALSE; bool32 finished = FALSE;
if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)))
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
finished = TRUE; finished = TRUE;
} }
else else
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy
&& gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy)
{ {
finished = TRUE; finished = TRUE;
} }
@ -166,135 +161,135 @@ static void Intro_WaitForHealthbox(void)
if (finished) if (finished)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3;
gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; gBattlerControllerFuncs[battler] = Intro_DelayAndEnd;
} }
} }
// Also used by the link partner. // Also used by the link partner.
void Controller_PlayerPartnerShowIntroHealthbox(void) void Controller_PlayerPartnerShowIntroHealthbox(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive
&& gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy && gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy
&& ++gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay != 1) && ++gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay != 1)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0;
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
{ {
DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]]);
UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL);
StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); StartHealthboxSlideIn(BATTLE_PARTNER(battler));
SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]);
} }
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[battler]]);
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
gBattleSpritesDataPtr->animationData->introAnimActive = FALSE; gBattleSpritesDataPtr->animationData->introAnimActive = FALSE;
gBattlerControllerFuncs[gActiveBattler] = Intro_WaitForHealthbox; gBattlerControllerFuncs[battler] = Intro_WaitForHealthbox;
} }
} }
static void WaitForMonAnimAfterLoad(void) static void WaitForMonAnimAfterLoad(u32 battler)
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].animEnded && gSprites[gBattlerSpriteIds[gActiveBattler]].x2 == 0) if (gSprites[gBattlerSpriteIds[battler]].animEnded && gSprites[gBattlerSpriteIds[battler]].x2 == 0)
PlayerPartnerBufferExecCompleted(); PlayerPartnerBufferExecCompleted(battler);
} }
static void SwitchIn_ShowSubstitute(void) static void SwitchIn_ShowSubstitute(u32 battler)
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
CopyBattleSpriteInvisibility(gActiveBattler); CopyBattleSpriteInvisibility(battler);
if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_WaitAndEnd; gBattlerControllerFuncs[battler] = SwitchIn_WaitAndEnd;
} }
} }
static void SwitchIn_WaitAndEnd(void) static void SwitchIn_WaitAndEnd(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
PlayerPartnerBufferExecCompleted(); PlayerPartnerBufferExecCompleted(battler);
} }
} }
static void SwitchIn_ShowHealthbox(void) static void SwitchIn_ShowHealthbox(u32 battler)
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
CreateTask(Task_PlayerController_RestoreBgmAfterCry, 10); CreateTask(Task_PlayerController_RestoreBgmAfterCry, 10);
HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler);
StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 0);
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowSubstitute; gBattlerControllerFuncs[battler] = SwitchIn_ShowSubstitute;
} }
} }
static void SwitchIn_TryShinyAnim(void) static void SwitchIn_TryShinyAnim(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
{ {
TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]);
} }
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
{ {
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[battler]]);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowHealthbox; gBattlerControllerFuncs[battler] = SwitchIn_ShowHealthbox;
} }
} }
static void PlayerPartnerBufferExecCompleted(void) static void PlayerPartnerBufferExecCompleted(u32 battler)
{ {
gBattlerControllerFuncs[gActiveBattler] = PlayerPartnerBufferRunCommand; gBattlerControllerFuncs[battler] = PlayerPartnerBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK) if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{ {
u8 playerId = GetMultiplayerId(); u8 playerId = GetMultiplayerId();
PrepareBufferDataTransferLink(2, 4, &playerId); PrepareBufferDataTransferLink(2, 4, &playerId);
gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP;
} }
else else
{ {
gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; gBattleControllerExecFlags &= ~gBitTable[battler];
} }
} }
static void PlayerPartnerHandleLoadMonSprite(void) static void PlayerPartnerHandleLoadMonSprite(u32 battler)
{ {
BtlController_HandleLoadMonSprite(gActiveBattler, gPlayerParty, WaitForMonAnimAfterLoad); BtlController_HandleLoadMonSprite(battler, gPlayerParty, WaitForMonAnimAfterLoad);
} }
static void PlayerPartnerHandleSwitchInAnim(void) static void PlayerPartnerHandleSwitchInAnim(u32 battler)
{ {
BtlController_HandleSwitchInAnim(gActiveBattler, TRUE, SwitchIn_TryShinyAnim); BtlController_HandleSwitchInAnim(battler, TRUE, SwitchIn_TryShinyAnim);
} }
// some explanation here // some explanation here
// in emerald it's possible to have a tag battle in the battle frontier facilities with AI // in emerald it's possible to have a tag battle in the battle frontier facilities with AI
// which use the front sprite for both the player and the partner as opposed to any other battles (including the one with Steven) that use the back pic as well as animate it // which use the front sprite for both the player and the partner as opposed to any other battles (including the one with Steven) that use the back pic as well as animate it
static void PlayerPartnerHandleDrawTrainerPic(void) static void PlayerPartnerHandleDrawTrainerPic(u32 battler)
{ {
bool32 isFrontPic; bool32 isFrontPic;
s16 xPos, yPos; s16 xPos, yPos;
@ -325,40 +320,40 @@ static void PlayerPartnerHandleDrawTrainerPic(void)
else else
isFrontPic = TRUE; isFrontPic = TRUE;
BtlController_HandleDrawTrainerPic(gActiveBattler, trainerPicId, isFrontPic, xPos, yPos, -1); BtlController_HandleDrawTrainerPic(battler, trainerPicId, isFrontPic, xPos, yPos, -1);
} }
static void PlayerPartnerHandleTrainerSlideBack(void) static void PlayerPartnerHandleTrainerSlideBack(u32 battler)
{ {
BtlController_HandleTrainerSlideBack(gActiveBattler, 35, FALSE); BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
} }
static void PlayerPartnerHandleMoveAnimation(void) static void PlayerPartnerHandleMoveAnimation(u32 battler)
{ {
BtlController_HandleMoveAnimation(gActiveBattler, FALSE); BtlController_HandleMoveAnimation(battler, FALSE);
} }
static void PlayerPartnerHandlePrintString(void) static void PlayerPartnerHandlePrintString(u32 battler)
{ {
BtlController_HandlePrintString(gActiveBattler, FALSE, FALSE); BtlController_HandlePrintString(battler, FALSE, FALSE);
} }
static void PlayerPartnerHandleChooseAction(void) static void PlayerPartnerHandleChooseAction(u32 battler)
{ {
AI_TrySwitchOrUseItem(); AI_TrySwitchOrUseItem();
PlayerPartnerBufferExecCompleted(); PlayerPartnerBufferExecCompleted(battler);
} }
static void PlayerPartnerHandleChooseMove(void) static void PlayerPartnerHandleChooseMove(u32 battler)
{ {
u8 chosenMoveId; u8 chosenMoveId;
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]);
chosenMoveId = gBattleStruct->aiMoveOrAction[gActiveBattler]; chosenMoveId = gBattleStruct->aiMoveOrAction[battler];
gBattlerTarget = gBattleStruct->aiChosenTarget[gActiveBattler]; gBattlerTarget = gBattleStruct->aiChosenTarget[battler];
if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED)) if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
gBattlerTarget = gActiveBattler; gBattlerTarget = battler;
if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & MOVE_TARGET_BOTH) if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & MOVE_TARGET_BOTH)
{ {
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
@ -366,25 +361,25 @@ static void PlayerPartnerHandleChooseMove(void)
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
} }
if (ShouldUseZMove(gActiveBattler, gBattlerTarget, moveInfo->moves[chosenMoveId])) if (ShouldUseZMove(battler, gBattlerTarget, moveInfo->moves[chosenMoveId]))
QueueZMove(gActiveBattler, moveInfo->moves[chosenMoveId]); QueueZMove(battler, moveInfo->moves[chosenMoveId]);
// If partner can mega evolve, do it. // If partner can mega evolve, do it.
if (CanMegaEvolve(gActiveBattler)) if (CanMegaEvolve(battler))
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8));
else else
BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gBattlerTarget << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gBattlerTarget << 8));
PlayerPartnerBufferExecCompleted(); PlayerPartnerBufferExecCompleted(battler);
} }
static void PlayerPartnerHandleChoosePokemon(void) static void PlayerPartnerHandleChoosePokemon(u32 battler)
{ {
s32 chosenMonId; s32 chosenMonId;
// Choosing Revival Blessing target // Choosing Revival Blessing target
if ((gBattleResources->bufferA[gActiveBattler][1] & 0xF) == PARTY_ACTION_CHOOSE_FAINTED_MON) if ((gBattleResources->bufferA[battler][1] & 0xF) == PARTY_ACTION_CHOOSE_FAINTED_MON)
{ {
chosenMonId = gSelectedMonPartyId = GetFirstFaintedPartyIndex(gActiveBattler); chosenMonId = gSelectedMonPartyId = GetFirstFaintedPartyIndex(battler);
} }
// Switching out // Switching out
else else
@ -405,18 +400,18 @@ static void PlayerPartnerHandleChoosePokemon(void)
} }
} }
} }
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = chosenMonId; *(gBattleStruct->monToSwitchIntoId + battler) = chosenMonId;
} }
BtlController_EmitChosenMonReturnValue(BUFFER_B, chosenMonId, NULL); BtlController_EmitChosenMonReturnValue(BUFFER_B, chosenMonId, NULL);
PlayerPartnerBufferExecCompleted(); PlayerPartnerBufferExecCompleted(battler);
} }
static void PlayerPartnerHandleHealthBarUpdate(void) static void PlayerPartnerHandleHealthBarUpdate(u32 battler)
{ {
BtlController_HandleHealthBarUpdate(gActiveBattler, FALSE); BtlController_HandleHealthBarUpdate(battler, FALSE);
} }
static void PlayerPartnerHandleIntroTrainerBallThrow(void) static void PlayerPartnerHandleIntroTrainerBallThrow(u32 battler)
{ {
const u32 *trainerPal; const u32 *trainerPal;
@ -427,24 +422,24 @@ static void PlayerPartnerHandleIntroTrainerBallThrow(void)
else else
trainerPal = gTrainerFrontPicPaletteTable[GetFrontierTrainerFrontSpriteId(gPartnerTrainerId)].data; // 2 vs 2 multi battle in Battle Frontier, load front sprite and pal. trainerPal = gTrainerFrontPicPaletteTable[GetFrontierTrainerFrontSpriteId(gPartnerTrainerId)].data; // 2 vs 2 multi battle in Battle Frontier, load front sprite and pal.
BtlController_HandleIntroTrainerBallThrow(gActiveBattler, 0xD6F9, trainerPal, 24, Controller_PlayerPartnerShowIntroHealthbox); BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F9, trainerPal, 24, Controller_PlayerPartnerShowIntroHealthbox);
} }
static void PlayerPartnerHandleDrawPartyStatusSummary(void) static void PlayerPartnerHandleDrawPartyStatusSummary(u32 battler)
{ {
BtlController_HandleDrawPartyStatusSummary(gActiveBattler, B_SIDE_PLAYER, TRUE); BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, TRUE);
} }
static void PlayerPartnerHandleBattleAnimation(void) static void PlayerPartnerHandleBattleAnimation(u32 battler)
{ {
BtlController_HandleBattleAnimation(gActiveBattler, FALSE, FALSE); BtlController_HandleBattleAnimation(battler, FALSE, FALSE);
} }
static void PlayerPartnerHandleEndLinkBattle(void) static void PlayerPartnerHandleEndLinkBattle(u32 battler)
{ {
gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; gBattleOutcome = gBattleResources->bufferA[battler][1];
FadeOutMapMusic(5); FadeOutMapMusic(5);
BeginFastPaletteFade(3); BeginFastPaletteFade(3);
PlayerPartnerBufferExecCompleted(); PlayerPartnerBufferExecCompleted(battler);
gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; gBattlerControllerFuncs[battler] = SetBattleEndCallbacks;
} }

View File

@ -32,29 +32,29 @@
#include "constants/songs.h" #include "constants/songs.h"
#include "constants/trainers.h" #include "constants/trainers.h"
static void RecordedOpponentHandleLoadMonSprite(void); static void RecordedOpponentHandleLoadMonSprite(u32 battler);
static void RecordedOpponentHandleSwitchInAnim(void); static void RecordedOpponentHandleSwitchInAnim(u32 battler);
static void RecordedOpponentHandleDrawTrainerPic(void); static void RecordedOpponentHandleDrawTrainerPic(u32 battler);
static void RecordedOpponentHandleTrainerSlideBack(void); static void RecordedOpponentHandleTrainerSlideBack(u32 battler);
static void RecordedOpponentHandleMoveAnimation(void); static void RecordedOpponentHandleMoveAnimation(u32 battler);
static void RecordedOpponentHandlePrintString(void); static void RecordedOpponentHandlePrintString(u32 battler);
static void RecordedOpponentHandleChooseAction(void); static void RecordedOpponentHandleChooseAction(u32 battler);
static void RecordedOpponentHandleChooseMove(void); static void RecordedOpponentHandleChooseMove(u32 battler);
static void RecordedOpponentHandleChooseItem(void); static void RecordedOpponentHandleChooseItem(u32 battler);
static void RecordedOpponentHandleChoosePokemon(void); static void RecordedOpponentHandleChoosePokemon(u32 battler);
static void RecordedOpponentHandleHealthBarUpdate(void); static void RecordedOpponentHandleHealthBarUpdate(u32 battler);
static void RecordedOpponentHandleStatusIconUpdate(void); static void RecordedOpponentHandleStatusIconUpdate(u32 battler);
static void RecordedOpponentHandleStatusAnimation(void); static void RecordedOpponentHandleStatusAnimation(u32 battler);
static void RecordedOpponentHandleIntroTrainerBallThrow(void); static void RecordedOpponentHandleIntroTrainerBallThrow(u32 battler);
static void RecordedOpponentHandleDrawPartyStatusSummary(void); static void RecordedOpponentHandleDrawPartyStatusSummary(u32 battler);
static void RecordedOpponentHandleBattleAnimation(void); static void RecordedOpponentHandleBattleAnimation(u32 battler);
static void RecordedOpponentHandleEndLinkBattle(void); static void RecordedOpponentHandleEndLinkBattle(u32 battler);
static void RecordedOpponentBufferRunCommand(void); static void RecordedOpponentBufferRunCommand(u32 battler);
static void RecordedOpponentBufferExecCompleted(void); static void RecordedOpponentBufferExecCompleted(u32 battler);
static void SwitchIn_HandleSoundAndEnd(void); static void SwitchIn_HandleSoundAndEnd(u32 battler);
static void (*const sRecordedOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(void) = static void (*const sRecordedOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{ {
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty, [CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -116,120 +116,130 @@ static void (*const sRecordedOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(void
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
}; };
void SetControllerToRecordedOpponent(void) void SetControllerToRecordedOpponent(u32 battler)
{ {
gBattlerControllerEndFuncs[gActiveBattler] = RecordedOpponentBufferExecCompleted; gBattlerControllerEndFuncs[battler] = RecordedOpponentBufferExecCompleted;
gBattlerControllerFuncs[gActiveBattler] = RecordedOpponentBufferRunCommand; gBattlerControllerFuncs[battler] = RecordedOpponentBufferRunCommand;
} }
static void RecordedOpponentBufferRunCommand(void) static void RecordedOpponentBufferRunCommand(u32 battler)
{ {
if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) if (gBattleControllerExecFlags & gBitTable[battler])
{ {
if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sRecordedOpponentBufferCommands)) if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sRecordedOpponentBufferCommands))
sRecordedOpponentBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); sRecordedOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler);
else else
RecordedOpponentBufferExecCompleted(); RecordedOpponentBufferExecCompleted(battler);
} }
} }
static void CompleteOnBankSpriteCallbackDummy2(void) static void RecordedOpponentBufferExecCompleted(u32 battler)
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) gBattlerControllerFuncs[battler] = RecordedOpponentBufferRunCommand;
RecordedOpponentBufferExecCompleted(); if (gBattleTypeFlags & BATTLE_TYPE_LINK)
} {
u8 playerId = GetMultiplayerId();
static void Intro_DelayAndEnd(void) PrepareBufferDataTransferLink(2, 4, &playerId);
gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP;
}
else
{ {
if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == (u8)-1) gBattleControllerExecFlags &= ~gBitTable[battler];
{
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0;
RecordedOpponentBufferExecCompleted();
} }
} }
static void Intro_WaitForShinyAnimAndHealthbox(void) static void Intro_DelayAndEnd(u32 battler)
{
if (--gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay == (u8)-1)
{
gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0;
RecordedOpponentBufferExecCompleted(battler);
}
}
static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
{ {
bool8 healthboxAnimDone = FALSE; bool8 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[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].animEnded) && gSprites[gBattlerSpriteIds[battler]].animEnded)
healthboxAnimDone = TRUE; healthboxAnimDone = TRUE;
} }
else else
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy
&& gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].animEnded && gSprites[gBattlerSpriteIds[battler]].animEnded
&& gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gActiveBattler)]].animEnded) && gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler)]].animEnded)
healthboxAnimDone = TRUE; healthboxAnimDone = TRUE;
} }
if (healthboxAnimDone) if (healthboxAnimDone)
{ {
if (GetBattlerPosition(gActiveBattler) == B_POSITION_OPPONENT_LEFT) if (GetBattlerPosition(battler) == B_POSITION_OPPONENT_LEFT)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) if (!gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
return; return;
if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim)
return; return;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3;
gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; gBattlerControllerFuncs[battler] = Intro_DelayAndEnd;
} }
} }
static void Intro_TryShinyAnimShowHealthbox(void) static void Intro_TryShinyAnimShowHealthbox(u32 battler)
{ {
bool32 bgmRestored = FALSE; bool32 bgmRestored = FALSE;
bool32 battlerAnimsDone = FALSE; bool32 battlerAnimsDone = FALSE;
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]);
if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive)
TryShinyAnimation(BATTLE_PARTNER(gActiveBattler), &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]]); TryShinyAnimation(BATTLE_PARTNER(battler), &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]]);
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive) if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted) if (!gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted)
{ {
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
{ {
UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL);
StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); StartHealthboxSlideIn(BATTLE_PARTNER(battler));
SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]);
} }
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gEnemyParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = TRUE; gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = TRUE;
} }
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].waitForCry if (!gBattleSpritesDataPtr->healthBoxesData[battler].waitForCry
&& gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted && gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].waitForCry && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].waitForCry
&& !IsCryPlayingOrClearCrySongs()) && !IsCryPlayingOrClearCrySongs())
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored) if (!gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored)
{ {
if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK) if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK)
{ {
if (GetBattlerPosition(gActiveBattler) == B_POSITION_OPPONENT_LEFT) if (GetBattlerPosition(battler) == B_POSITION_OPPONENT_LEFT)
m4aMPlayContinue(&gMPlayInfo_BGM); m4aMPlayContinue(&gMPlayInfo_BGM);
} }
else else
@ -237,24 +247,24 @@ static void Intro_TryShinyAnimShowHealthbox(void)
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100); m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
} }
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = TRUE; gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = TRUE;
bgmRestored = TRUE; bgmRestored = TRUE;
} }
if (!IsDoubleBattle()) if (!IsDoubleBattle())
{ {
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
battlerAnimsDone = TRUE; battlerAnimsDone = TRUE;
} }
} }
else else
{ {
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy && gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy)
{ {
battlerAnimsDone = TRUE; battlerAnimsDone = TRUE;
} }
@ -264,146 +274,130 @@ static void Intro_TryShinyAnimShowHealthbox(void)
{ {
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
{ {
DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]]);
SetBattlerShadowSpriteCallback(BATTLE_PARTNER(gActiveBattler), GetMonData(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], MON_DATA_SPECIES)); SetBattlerShadowSpriteCallback(BATTLE_PARTNER(battler), GetMonData(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], MON_DATA_SPECIES));
} }
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[battler]]);
SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES));
gBattleSpritesDataPtr->animationData->introAnimActive = FALSE; gBattleSpritesDataPtr->animationData->introAnimActive = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = FALSE;
gBattlerControllerFuncs[gActiveBattler] = Intro_WaitForShinyAnimAndHealthbox; gBattlerControllerFuncs[battler] = Intro_WaitForShinyAnimAndHealthbox;
} }
} }
static void TryShinyAnimAfterMonAnim(void) static void TryShinyAnimAfterMonAnim(u32 battler)
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].x2 == 0) && gSprites[gBattlerSpriteIds[battler]].x2 == 0)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim) if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim)
{ {
TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]);
} }
else else
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
RecordedOpponentBufferExecCompleted(); RecordedOpponentBufferExecCompleted(battler);
} }
} }
} }
} }
static void SwitchIn_ShowSubstitute(void) static void SwitchIn_ShowSubstitute(u32 battler)
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_HandleSoundAndEnd; gBattlerControllerFuncs[battler] = SwitchIn_HandleSoundAndEnd;
} }
} }
static void SwitchIn_HandleSoundAndEnd(void) static void SwitchIn_HandleSoundAndEnd(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive
&& !IsCryPlayingOrClearCrySongs()) && !IsCryPlayingOrClearCrySongs())
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy
|| gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy_2) || gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy_2)
{ {
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100); m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
RecordedOpponentBufferExecCompleted(); RecordedOpponentBufferExecCompleted(battler);
} }
} }
} }
static void SwitchIn_ShowHealthbox(void) static void SwitchIn_ShowHealthbox(u32 battler)
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
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[battler]], 0);
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gEnemyParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
CopyBattleSpriteInvisibility(gActiveBattler); CopyBattleSpriteInvisibility(battler);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowSubstitute; gBattlerControllerFuncs[battler] = SwitchIn_ShowSubstitute;
} }
} }
static void SwitchIn_TryShinyAnim(void) static void SwitchIn_TryShinyAnim(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim) && !gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim)
TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]);
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
{ {
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[battler]]);
SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES));
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowHealthbox; gBattlerControllerFuncs[battler] = SwitchIn_ShowHealthbox;
} }
} }
static void RecordedOpponentBufferExecCompleted(void) static void RecordedOpponentHandleLoadMonSprite(u32 battler)
{ {
gBattlerControllerFuncs[gActiveBattler] = RecordedOpponentBufferRunCommand; BtlController_HandleLoadMonSprite(battler, gEnemyParty, TryShinyAnimAfterMonAnim);
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{
u8 playerId = GetMultiplayerId();
PrepareBufferDataTransferLink(2, 4, &playerId);
gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP;
}
else
{
gBattleControllerExecFlags &= ~gBitTable[gActiveBattler];
}
} }
static void RecordedOpponentHandleLoadMonSprite(void) static void RecordedOpponentHandleSwitchInAnim(u32 battler)
{ {
BtlController_HandleLoadMonSprite(gActiveBattler, gEnemyParty, TryShinyAnimAfterMonAnim); BtlController_HandleSwitchInAnim(battler, FALSE, SwitchIn_TryShinyAnim);
} }
static void RecordedOpponentHandleSwitchInAnim(void) static void RecordedOpponentHandleDrawTrainerPic(u32 battler)
{
BtlController_HandleSwitchInAnim(gActiveBattler, FALSE, SwitchIn_TryShinyAnim);
}
static void RecordedOpponentHandleDrawTrainerPic(void)
{ {
s16 xPos; s16 xPos;
u32 trainerPicId; u32 trainerPicId;
if (gBattleTypeFlags & BATTLE_TYPE_MULTI) if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{ {
if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != 0) // second mon if ((GetBattlerPosition(battler) & BIT_FLANK) != 0) // second mon
xPos = 152; xPos = 152;
else // first mon else // first mon
xPos = 200; xPos = 200;
if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
{ {
if (gActiveBattler == 1) if (battler == B_POSITION_OPPONENT_LEFT)
trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A);
else else
trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B); trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B);
@ -426,28 +420,28 @@ static void RecordedOpponentHandleDrawTrainerPic(void)
} }
} }
BtlController_HandleDrawTrainerPic(gActiveBattler, trainerPicId, TRUE, BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE,
xPos, 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicId].size), xPos, 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicId].size),
-1); -1);
} }
static void RecordedOpponentHandleTrainerSlideBack(void) static void RecordedOpponentHandleTrainerSlideBack(u32 battler)
{ {
BtlController_HandleTrainerSlideBack(gActiveBattler, 35, FALSE); BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
} }
static void RecordedOpponentHandleMoveAnimation(void) static void RecordedOpponentHandleMoveAnimation(u32 battler)
{ {
BtlController_HandleMoveAnimation(gActiveBattler, FALSE); BtlController_HandleMoveAnimation(battler, FALSE);
} }
static void RecordedOpponentHandlePrintString(void) static void RecordedOpponentHandlePrintString(u32 battler)
{ {
u16 *stringId; u16 *stringId;
gBattle_BG0_X = 0; gBattle_BG0_X = 0;
gBattle_BG0_Y = 0; gBattle_BG0_Y = 0;
stringId = (u16 *)(&gBattleResources->bufferA[gActiveBattler][2]); stringId = (u16 *)(&gBattleResources->bufferA[battler][2]);
BufferStringBattle(*stringId); BufferStringBattle(*stringId);
if (gTestRunnerEnabled) if (gTestRunnerEnabled)
@ -455,22 +449,22 @@ static void RecordedOpponentHandlePrintString(void)
TestRunner_Battle_RecordMessage(gDisplayedStringBattle); TestRunner_Battle_RecordMessage(gDisplayedStringBattle);
if (gTestRunnerHeadless) if (gTestRunnerHeadless)
{ {
RecordedOpponentBufferExecCompleted(); RecordedOpponentBufferExecCompleted(battler);
return; return;
} }
} }
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG);
gBattlerControllerFuncs[gActiveBattler] = Controller_WaitForString; gBattlerControllerFuncs[battler] = Controller_WaitForString;
} }
static void RecordedOpponentHandleChooseAction(void) static void RecordedOpponentHandleChooseAction(u32 battler)
{ {
BtlController_EmitTwoReturnValues(BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_ACTION_TYPE, gActiveBattler), 0); BtlController_EmitTwoReturnValues(BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_ACTION_TYPE, battler), 0);
RecordedOpponentBufferExecCompleted(); RecordedOpponentBufferExecCompleted(battler);
} }
static void RecordedOpponentHandleChooseMove(void) static void RecordedOpponentHandleChooseMove(u32 battler)
{ {
if (gBattleTypeFlags & BATTLE_TYPE_PALACE) if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{ {
@ -478,97 +472,97 @@ static void RecordedOpponentHandleChooseMove(void)
} }
else else
{ {
u8 moveId = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, gActiveBattler); u8 moveId = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, battler);
u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, gActiveBattler); u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, battler);
BtlController_EmitTwoReturnValues(BUFFER_B, 10, moveId | (target << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, moveId | (target << 8));
} }
RecordedOpponentBufferExecCompleted(); RecordedOpponentBufferExecCompleted(battler);
} }
static void RecordedOpponentHandleChooseItem(void) static void RecordedOpponentHandleChooseItem(u32 battler)
{ {
u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler); u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, battler);
u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler); u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, battler);
gBattleStruct->chosenItem[gActiveBattler] = (byte1 << 8) | byte2; gBattleStruct->chosenItem[battler] = (byte1 << 8) | byte2;
gBattleStruct->itemPartyIndex[gActiveBattler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_TARGET, gActiveBattler); gBattleStruct->itemPartyIndex[battler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_TARGET, battler);
gBattleStruct->itemMoveIndex[gActiveBattler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_MOVE, gActiveBattler); gBattleStruct->itemMoveIndex[battler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_MOVE, battler);
BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[gActiveBattler]); BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[battler]);
RecordedOpponentBufferExecCompleted(); RecordedOpponentBufferExecCompleted(battler);
} }
static void RecordedOpponentHandleChoosePokemon(void) static void RecordedOpponentHandleChoosePokemon(u32 battler)
{ {
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, gActiveBattler); *(gBattleStruct->monToSwitchIntoId + battler) = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, battler);
gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[gActiveBattler]; // Revival Blessing gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[battler]; // Revival Blessing
BtlController_EmitChosenMonReturnValue(BUFFER_B, *(gBattleStruct->monToSwitchIntoId + gActiveBattler), NULL); BtlController_EmitChosenMonReturnValue(BUFFER_B, *(gBattleStruct->monToSwitchIntoId + battler), NULL);
RecordedOpponentBufferExecCompleted(); RecordedOpponentBufferExecCompleted(battler);
} }
static void RecordedOpponentHandleHealthBarUpdate(void) static void RecordedOpponentHandleHealthBarUpdate(u32 battler)
{ {
s16 hpVal; s16 hpVal;
s32 maxHP, curHP; s32 maxHP, curHP;
LoadBattleBarGfx(0); LoadBattleBarGfx(0);
hpVal = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); hpVal = gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8);
maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP);
curHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); curHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_HP);
if (hpVal != INSTANT_HP_BAR_DROP) if (hpVal != INSTANT_HP_BAR_DROP)
{ {
SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, curHP, hpVal); SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, curHP, hpVal);
TestRunner_Battle_RecordHP(gActiveBattler, curHP, min(maxHP, max(0, curHP - hpVal))); TestRunner_Battle_RecordHP(battler, curHP, min(maxHP, max(0, curHP - hpVal)));
} }
else else
{ {
SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, 0, hpVal);
TestRunner_Battle_RecordHP(gActiveBattler, curHP, 0); TestRunner_Battle_RecordHP(battler, curHP, 0);
} }
gBattlerControllerFuncs[gActiveBattler] = Controller_WaitForHealthBar; gBattlerControllerFuncs[battler] = Controller_WaitForHealthBar;
} }
static void RecordedOpponentHandleStatusIconUpdate(void) static void RecordedOpponentHandleStatusIconUpdate(u32 battler)
{ {
if (!IsBattleSEPlaying(gActiveBattler)) if (!IsBattleSEPlaying(battler))
{ {
DoStatusIconUpdate(gActiveBattler); DoStatusIconUpdate(battler);
if (gTestRunnerEnabled) if (gTestRunnerEnabled)
TestRunner_Battle_RecordStatus1(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_STATUS)); TestRunner_Battle_RecordStatus1(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_STATUS));
} }
} }
static void RecordedOpponentHandleStatusAnimation(void) static void RecordedOpponentHandleStatusAnimation(u32 battler)
{ {
BtlController_HandleStatusAnimation(); BtlController_HandleStatusAnimation(battler);
} }
static void RecordedOpponentHandleIntroTrainerBallThrow(void) static void RecordedOpponentHandleIntroTrainerBallThrow(u32 battler)
{ {
BtlController_HandleIntroTrainerBallThrow(gActiveBattler, 0, NULL, 0, Intro_TryShinyAnimShowHealthbox); BtlController_HandleIntroTrainerBallThrow(battler, 0, NULL, 0, Intro_TryShinyAnimShowHealthbox);
} }
static void RecordedOpponentHandleDrawPartyStatusSummary(void) static void RecordedOpponentHandleDrawPartyStatusSummary(u32 battler)
{ {
BtlController_HandleDrawPartyStatusSummary(gActiveBattler, B_SIDE_OPPONENT, TRUE); BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_OPPONENT, TRUE);
} }
static void RecordedOpponentHandleBattleAnimation(void) static void RecordedOpponentHandleBattleAnimation(u32 battler)
{ {
BtlController_HandleBattleAnimation(gActiveBattler, FALSE, FALSE); BtlController_HandleBattleAnimation(battler, FALSE, FALSE);
} }
static void RecordedOpponentHandleEndLinkBattle(void) static void RecordedOpponentHandleEndLinkBattle(u32 battler)
{ {
if (gBattleResources->bufferA[gActiveBattler][1] == B_OUTCOME_DREW) if (gBattleResources->bufferA[battler][1] == B_OUTCOME_DREW)
gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; gBattleOutcome = gBattleResources->bufferA[battler][1];
else else
gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1] ^ B_OUTCOME_DREW; gBattleOutcome = gBattleResources->bufferA[battler][1] ^ B_OUTCOME_DREW;
FadeOutMapMusic(5); FadeOutMapMusic(5);
BeginFastPaletteFade(3); BeginFastPaletteFade(3);
RecordedOpponentBufferExecCompleted(); RecordedOpponentBufferExecCompleted(battler);
gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; gBattlerControllerFuncs[battler] = SetBattleEndCallbacks;
} }

View File

@ -29,29 +29,29 @@
#include "constants/songs.h" #include "constants/songs.h"
#include "constants/trainers.h" #include "constants/trainers.h"
static void RecordedPlayerHandleLoadMonSprite(void); static void RecordedPlayerHandleLoadMonSprite(u32 battler);
static void RecordedPlayerHandleSwitchInAnim(void); static void RecordedPlayerHandleSwitchInAnim(u32 battler);
static void RecordedPlayerHandleDrawTrainerPic(void); static void RecordedPlayerHandleDrawTrainerPic(u32 battler);
static void RecordedPlayerHandleTrainerSlideBack(void); static void RecordedPlayerHandleTrainerSlideBack(u32 battler);
static void RecordedPlayerHandleMoveAnimation(void); static void RecordedPlayerHandleMoveAnimation(u32 battler);
static void RecordedPlayerHandlePrintString(void); static void RecordedPlayerHandlePrintString(u32 battler);
static void RecordedPlayerHandleChooseAction(void); static void RecordedPlayerHandleChooseAction(u32 battler);
static void RecordedPlayerHandleChooseMove(void); static void RecordedPlayerHandleChooseMove(u32 battler);
static void RecordedPlayerHandleChooseItem(void); static void RecordedPlayerHandleChooseItem(u32 battler);
static void RecordedPlayerHandleChoosePokemon(void); static void RecordedPlayerHandleChoosePokemon(u32 battler);
static void RecordedPlayerHandleHealthBarUpdate(void); static void RecordedPlayerHandleHealthBarUpdate(u32 battler);
static void RecordedPlayerHandleStatusIconUpdate(void); static void RecordedPlayerHandleStatusIconUpdate(u32 battler);
static void RecordedPlayerHandleStatusAnimation(void); static void RecordedPlayerHandleStatusAnimation(u32 battler);
static void RecordedPlayerHandleIntroTrainerBallThrow(void); static void RecordedPlayerHandleIntroTrainerBallThrow(u32 battler);
static void RecordedPlayerHandleDrawPartyStatusSummary(void); static void RecordedPlayerHandleDrawPartyStatusSummary(u32 battler);
static void RecordedPlayerHandleBattleAnimation(void); static void RecordedPlayerHandleBattleAnimation(u32 battler);
static void RecordedPlayerHandleEndLinkBattle(void); static void RecordedPlayerHandleEndLinkBattle(u32 battler);
static void RecordedPlayerBufferRunCommand(void); static void RecordedPlayerBufferRunCommand(u32 battler);
static void RecordedPlayerBufferExecCompleted(void); static void RecordedPlayerBufferExecCompleted(u32 battler);
static void SwitchIn_WaitAndEnd(void); static void SwitchIn_WaitAndEnd(u32 battler);
static void (*const sRecordedPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(void) = static void (*const sRecordedPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{ {
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty, [CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -113,83 +113,83 @@ static void (*const sRecordedPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(void)
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
}; };
void SetControllerToRecordedPlayer(void) void SetControllerToRecordedPlayer(u32 battler)
{ {
gBattlerControllerEndFuncs[gActiveBattler] = RecordedPlayerBufferExecCompleted; gBattlerControllerEndFuncs[battler] = RecordedPlayerBufferExecCompleted;
gBattlerControllerFuncs[gActiveBattler] = RecordedPlayerBufferRunCommand; gBattlerControllerFuncs[battler] = RecordedPlayerBufferRunCommand;
} }
static void RecordedPlayerBufferRunCommand(void) static void RecordedPlayerBufferRunCommand(u32 battler)
{ {
if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) if (gBattleControllerExecFlags & gBitTable[battler])
{ {
if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sRecordedPlayerBufferCommands)) if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sRecordedPlayerBufferCommands))
sRecordedPlayerBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); sRecordedPlayerBufferCommands[gBattleResources->bufferA[battler][0]](battler);
else else
RecordedPlayerBufferExecCompleted(); RecordedPlayerBufferExecCompleted(battler);
} }
} }
static void Intro_DelayAndEnd(void) static void Intro_DelayAndEnd(u32 battler)
{ {
if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == (u8)-1) if (--gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay == (u8)-1)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0;
RecordedPlayerBufferExecCompleted(); RecordedPlayerBufferExecCompleted(battler);
} }
} }
static void Intro_WaitForShinyAnimAndHealthbox(void) static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
{ {
bool32 healthboxAnimDone = FALSE; bool32 healthboxAnimDone = FALSE;
if (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_LEFT) if (GetBattlerPosition(battler) == B_POSITION_PLAYER_LEFT)
{ {
if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)))
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
healthboxAnimDone = TRUE; healthboxAnimDone = TRUE;
} }
else else
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy
&& gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy)
{ {
healthboxAnimDone = TRUE; healthboxAnimDone = TRUE;
} }
} }
if (healthboxAnimDone && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim if (healthboxAnimDone && gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim
&& gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) && gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler);
if (IsDoubleBattle()) if (IsDoubleBattle())
HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], BATTLE_PARTNER(gActiveBattler)); HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], BATTLE_PARTNER(battler));
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3;
gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; gBattlerControllerFuncs[battler] = Intro_DelayAndEnd;
} }
} }
else else
{ {
if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)))
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
healthboxAnimDone = TRUE; healthboxAnimDone = TRUE;
} }
else else
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy
&& gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy)
{ {
healthboxAnimDone = TRUE; healthboxAnimDone = TRUE;
} }
@ -200,55 +200,55 @@ static void Intro_WaitForShinyAnimAndHealthbox(void)
if (healthboxAnimDone) if (healthboxAnimDone)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3;
gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; gBattlerControllerFuncs[battler] = Intro_DelayAndEnd;
} }
} }
} }
static void Intro_TryShinyAnimShowHealthbox(void) static void Intro_TryShinyAnimShowHealthbox(u32 battler)
{ {
bool32 bgmRestored = FALSE; bool32 bgmRestored = FALSE;
if (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_LEFT) if (GetBattlerPosition(battler) == B_POSITION_PLAYER_LEFT)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]);
if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive)
TryShinyAnimation(BATTLE_PARTNER(gActiveBattler), &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]]); TryShinyAnimation(BATTLE_PARTNER(battler), &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]]);
} }
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted) if (!gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted)
{ {
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
{ {
UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL);
StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); StartHealthboxSlideIn(BATTLE_PARTNER(battler));
SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]);
} }
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = TRUE; gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = TRUE;
} }
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted if (gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].waitForCry && !gBattleSpritesDataPtr->healthBoxesData[battler].waitForCry
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].waitForCry && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].waitForCry
&& !IsCryPlayingOrClearCrySongs()) && !IsCryPlayingOrClearCrySongs())
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored) if (!gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored)
{ {
if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && (gBattleTypeFlags & BATTLE_TYPE_MULTI)) if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && (gBattleTypeFlags & BATTLE_TYPE_MULTI))
{ {
if (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_LEFT) if (GetBattlerPosition(battler) == B_POSITION_PLAYER_LEFT)
m4aMPlayContinue(&gMPlayInfo_BGM); m4aMPlayContinue(&gMPlayInfo_BGM);
} }
else else
@ -257,115 +257,115 @@ static void Intro_TryShinyAnimShowHealthbox(void)
} }
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = TRUE; gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = TRUE;
bgmRestored = TRUE; bgmRestored = TRUE;
} }
if (bgmRestored && gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (bgmRestored && gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]]);
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[battler]]);
gBattleSpritesDataPtr->animationData->introAnimActive = FALSE; gBattleSpritesDataPtr->animationData->introAnimActive = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = FALSE;
gBattlerControllerFuncs[gActiveBattler] = Intro_WaitForShinyAnimAndHealthbox; gBattlerControllerFuncs[battler] = Intro_WaitForShinyAnimAndHealthbox;
} }
} }
static void WaitForMonAnimAfterLoad(void) static void WaitForMonAnimAfterLoad(u32 battler)
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].animEnded && gSprites[gBattlerSpriteIds[gActiveBattler]].x2 == 0) if (gSprites[gBattlerSpriteIds[battler]].animEnded && gSprites[gBattlerSpriteIds[battler]].x2 == 0)
RecordedPlayerBufferExecCompleted(); RecordedPlayerBufferExecCompleted(battler);
} }
static void SwitchIn_ShowSubstitute(void) static void SwitchIn_ShowSubstitute(u32 battler)
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
CopyBattleSpriteInvisibility(gActiveBattler); CopyBattleSpriteInvisibility(battler);
if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_WaitAndEnd; gBattlerControllerFuncs[battler] = SwitchIn_WaitAndEnd;
} }
} }
static void SwitchIn_WaitAndEnd(void) static void SwitchIn_WaitAndEnd(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
RecordedPlayerBufferExecCompleted(); RecordedPlayerBufferExecCompleted(battler);
} }
} }
static void SwitchIn_ShowHealthbox(void) static void SwitchIn_ShowHealthbox(u32 battler)
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
CreateTask(Task_PlayerController_RestoreBgmAfterCry, 10); CreateTask(Task_PlayerController_RestoreBgmAfterCry, 10);
HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler);
StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 0);
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowSubstitute; gBattlerControllerFuncs[battler] = SwitchIn_ShowSubstitute;
} }
} }
static void SwitchIn_TryShinyAnim(void) static void SwitchIn_TryShinyAnim(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
{ {
TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]);
} }
if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
{ {
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[battler]]);
gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowHealthbox; gBattlerControllerFuncs[battler] = SwitchIn_ShowHealthbox;
} }
} }
static void RecordedPlayerBufferExecCompleted(void) static void RecordedPlayerBufferExecCompleted(u32 battler)
{ {
gBattlerControllerFuncs[gActiveBattler] = RecordedPlayerBufferRunCommand; gBattlerControllerFuncs[battler] = RecordedPlayerBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK) if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{ {
u8 playerId = GetMultiplayerId(); u8 playerId = GetMultiplayerId();
PrepareBufferDataTransferLink(2, 4, &playerId); PrepareBufferDataTransferLink(2, 4, &playerId);
gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP;
} }
else else
{ {
gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; gBattleControllerExecFlags &= ~gBitTable[battler];
} }
} }
static void RecordedPlayerHandleLoadMonSprite(void) static void RecordedPlayerHandleLoadMonSprite(u32 battler)
{ {
BtlController_HandleLoadMonSprite(gActiveBattler, gPlayerParty, WaitForMonAnimAfterLoad); BtlController_HandleLoadMonSprite(battler, gPlayerParty, WaitForMonAnimAfterLoad);
} }
static void RecordedPlayerHandleSwitchInAnim(void) static void RecordedPlayerHandleSwitchInAnim(u32 battler)
{ {
BtlController_HandleSwitchInAnim(gActiveBattler, TRUE, SwitchIn_TryShinyAnim); BtlController_HandleSwitchInAnim(battler, TRUE, SwitchIn_TryShinyAnim);
} }
static void RecordedPlayerHandleDrawTrainerPic(void) static void RecordedPlayerHandleDrawTrainerPic(u32 battler)
{ {
bool32 isFrontPic; bool32 isFrontPic;
s16 xPos, yPos; s16 xPos, yPos;
@ -385,7 +385,7 @@ static void RecordedPlayerHandleDrawTrainerPic(void)
if (gBattleTypeFlags & BATTLE_TYPE_MULTI) if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{ {
if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != 0) // second mon if ((GetBattlerPosition(battler) & BIT_FLANK) != 0) // second mon
xPos = 90; xPos = 90;
else // first mon else // first mon
xPos = 32; xPos = 32;
@ -412,26 +412,26 @@ static void RecordedPlayerHandleDrawTrainerPic(void)
else else
isFrontPic = FALSE; isFrontPic = FALSE;
BtlController_HandleDrawTrainerPic(gActiveBattler, trainerPicId, isFrontPic, xPos, yPos, -1); BtlController_HandleDrawTrainerPic(battler, trainerPicId, isFrontPic, xPos, yPos, -1);
} }
static void RecordedPlayerHandleTrainerSlideBack(void) static void RecordedPlayerHandleTrainerSlideBack(u32 battler)
{ {
BtlController_HandleTrainerSlideBack(gActiveBattler, 35, FALSE); BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
} }
static void RecordedPlayerHandleMoveAnimation(void) static void RecordedPlayerHandleMoveAnimation(u32 battler)
{ {
BtlController_HandleMoveAnimation(gActiveBattler, FALSE); BtlController_HandleMoveAnimation(battler, FALSE);
} }
static void RecordedPlayerHandlePrintString(void) static void RecordedPlayerHandlePrintString(u32 battler)
{ {
u16 *stringId; u16 *stringId;
gBattle_BG0_X = 0; gBattle_BG0_X = 0;
gBattle_BG0_Y = 0; gBattle_BG0_Y = 0;
stringId = (u16 *)(&gBattleResources->bufferA[gActiveBattler][2]); stringId = (u16 *)(&gBattleResources->bufferA[battler][2]);
BufferStringBattle(*stringId); BufferStringBattle(*stringId);
if (gTestRunnerEnabled) if (gTestRunnerEnabled)
@ -439,38 +439,38 @@ static void RecordedPlayerHandlePrintString(void)
TestRunner_Battle_RecordMessage(gDisplayedStringBattle); TestRunner_Battle_RecordMessage(gDisplayedStringBattle);
if (gTestRunnerHeadless) if (gTestRunnerHeadless)
{ {
RecordedPlayerBufferExecCompleted(); RecordedPlayerBufferExecCompleted(battler);
return; return;
} }
} }
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG);
gBattlerControllerFuncs[gActiveBattler] = Controller_WaitForString; gBattlerControllerFuncs[battler] = Controller_WaitForString;
} }
static void ChooseActionInBattlePalace(void) static void ChooseActionInBattlePalace(u32 battler)
{ {
if (gBattleCommunication[4] >= gBattlersCount / 2) if (gBattleCommunication[4] >= gBattlersCount / 2)
{ {
BtlController_EmitTwoReturnValues(BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_BATTLE_PALACE_ACTION, gActiveBattler), 0); BtlController_EmitTwoReturnValues(BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_BATTLE_PALACE_ACTION, battler), 0);
RecordedPlayerBufferExecCompleted(); RecordedPlayerBufferExecCompleted(battler);
} }
} }
static void RecordedPlayerHandleChooseAction(void) static void RecordedPlayerHandleChooseAction(u32 battler)
{ {
if (gBattleTypeFlags & BATTLE_TYPE_PALACE) if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{ {
gBattlerControllerFuncs[gActiveBattler] = ChooseActionInBattlePalace; gBattlerControllerFuncs[battler] = ChooseActionInBattlePalace;
} }
else else
{ {
BtlController_EmitTwoReturnValues(BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_ACTION_TYPE, gActiveBattler), 0); BtlController_EmitTwoReturnValues(BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_ACTION_TYPE, battler), 0);
RecordedPlayerBufferExecCompleted(); RecordedPlayerBufferExecCompleted(battler);
} }
} }
static void RecordedPlayerHandleChooseMove(void) static void RecordedPlayerHandleChooseMove(u32 battler)
{ {
if (gBattleTypeFlags & BATTLE_TYPE_PALACE) if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{ {
@ -478,103 +478,103 @@ static void RecordedPlayerHandleChooseMove(void)
} }
else else
{ {
u8 moveId = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, gActiveBattler); u8 moveId = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, battler);
u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, gActiveBattler); u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, battler);
BtlController_EmitTwoReturnValues(BUFFER_B, 10, moveId | (target << 8)); BtlController_EmitTwoReturnValues(BUFFER_B, 10, moveId | (target << 8));
} }
RecordedPlayerBufferExecCompleted(); RecordedPlayerBufferExecCompleted(battler);
} }
static void RecordedPlayerHandleChooseItem(void) static void RecordedPlayerHandleChooseItem(u32 battler)
{ {
u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler); u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, battler);
u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler); u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, battler);
gBattleStruct->chosenItem[gActiveBattler] = (byte1 << 8) | byte2; gBattleStruct->chosenItem[battler] = (byte1 << 8) | byte2;
gBattleStruct->itemPartyIndex[gActiveBattler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_TARGET, gActiveBattler); gBattleStruct->itemPartyIndex[battler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_TARGET, battler);
gBattleStruct->itemMoveIndex[gActiveBattler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_MOVE, gActiveBattler); gBattleStruct->itemMoveIndex[battler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_MOVE, battler);
BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[gActiveBattler]); BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[battler]);
RecordedPlayerBufferExecCompleted(); RecordedPlayerBufferExecCompleted(battler);
} }
static void RecordedPlayerHandleChoosePokemon(void) static void RecordedPlayerHandleChoosePokemon(u32 battler)
{ {
*(gBattleStruct->monToSwitchIntoId + gActiveBattler) = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, gActiveBattler); *(gBattleStruct->monToSwitchIntoId + battler) = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, battler);
gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[gActiveBattler]; // Revival Blessing gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[battler]; // Revival Blessing
BtlController_EmitChosenMonReturnValue(BUFFER_B, *(gBattleStruct->monToSwitchIntoId + gActiveBattler), NULL); BtlController_EmitChosenMonReturnValue(BUFFER_B, *(gBattleStruct->monToSwitchIntoId + battler), NULL);
RecordedPlayerBufferExecCompleted(); RecordedPlayerBufferExecCompleted(battler);
} }
static void RecordedPlayerHandleHealthBarUpdate(void) static void RecordedPlayerHandleHealthBarUpdate(u32 battler)
{ {
s16 hpVal; s16 hpVal;
s32 maxHP, curHP; s32 maxHP, curHP;
LoadBattleBarGfx(0); LoadBattleBarGfx(0);
hpVal = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); hpVal = gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8);
maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP);
curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_HP);
if (hpVal != INSTANT_HP_BAR_DROP) if (hpVal != INSTANT_HP_BAR_DROP)
{ {
SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, curHP, hpVal); SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, curHP, hpVal);
TestRunner_Battle_RecordHP(gActiveBattler, curHP, min(maxHP, max(0, curHP - hpVal))); TestRunner_Battle_RecordHP(battler, curHP, min(maxHP, max(0, curHP - hpVal)));
} }
else else
{ {
SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, 0, hpVal);
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, 0, maxHP); UpdateHpTextInHealthbox(gHealthboxSpriteIds[battler], HP_CURRENT, 0, maxHP);
TestRunner_Battle_RecordHP(gActiveBattler, curHP, 0); TestRunner_Battle_RecordHP(battler, curHP, 0);
} }
gBattlerControllerFuncs[gActiveBattler] = Controller_WaitForHealthBar; gBattlerControllerFuncs[battler] = Controller_WaitForHealthBar;
} }
static void RecordedPlayerHandleStatusIconUpdate(void) static void RecordedPlayerHandleStatusIconUpdate(u32 battler)
{ {
if (!IsBattleSEPlaying(gActiveBattler)) if (!IsBattleSEPlaying(battler))
{ {
DoStatusIconUpdate(gActiveBattler); DoStatusIconUpdate(battler);
if (gTestRunnerEnabled) if (gTestRunnerEnabled)
TestRunner_Battle_RecordStatus1(gActiveBattler, GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_STATUS)); TestRunner_Battle_RecordStatus1(battler, GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_STATUS));
} }
} }
static void RecordedPlayerHandleStatusAnimation(void) static void RecordedPlayerHandleStatusAnimation(u32 battler)
{ {
BtlController_HandleStatusAnimation(); BtlController_HandleStatusAnimation(battler);
} }
static void RecordedPlayerHandleIntroTrainerBallThrow(void) static void RecordedPlayerHandleIntroTrainerBallThrow(u32 battler)
{ {
u32 trainerPicId; u32 trainerPicId;
const u32 *trainerPal; const u32 *trainerPal;
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK) if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK)
trainerPicId = gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender + TRAINER_BACK_PIC_BRENDAN; trainerPicId = gLinkPlayers[GetBattlerMultiplayerId(battler)].gender + TRAINER_BACK_PIC_BRENDAN;
else else
trainerPicId = gSaveBlock2Ptr->playerGender + TRAINER_BACK_PIC_BRENDAN; trainerPicId = gSaveBlock2Ptr->playerGender + TRAINER_BACK_PIC_BRENDAN;
trainerPal = gTrainerFrontPicPaletteTable[trainerPicId].data; trainerPal = gTrainerFrontPicPaletteTable[trainerPicId].data;
BtlController_HandleIntroTrainerBallThrow(gActiveBattler, 0xD6F9, trainerPal, 24, Intro_TryShinyAnimShowHealthbox); BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F9, trainerPal, 24, Intro_TryShinyAnimShowHealthbox);
} }
static void RecordedPlayerHandleDrawPartyStatusSummary(void) static void RecordedPlayerHandleDrawPartyStatusSummary(u32 battler)
{ {
BtlController_HandleDrawPartyStatusSummary(gActiveBattler, B_SIDE_PLAYER, TRUE); BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, TRUE);
} }
static void RecordedPlayerHandleBattleAnimation(void) static void RecordedPlayerHandleBattleAnimation(u32 battler)
{ {
BtlController_HandleBattleAnimation(gActiveBattler, FALSE, FALSE); BtlController_HandleBattleAnimation(battler, FALSE, FALSE);
} }
static void RecordedPlayerHandleEndLinkBattle(void) static void RecordedPlayerHandleEndLinkBattle(u32 battler)
{ {
gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; gBattleOutcome = gBattleResources->bufferA[battler][1];
FadeOutMapMusic(5); FadeOutMapMusic(5);
BeginFastPaletteFade(3); BeginFastPaletteFade(3);
RecordedPlayerBufferExecCompleted(); RecordedPlayerBufferExecCompleted(battler);
gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; gBattlerControllerFuncs[battler] = SetBattleEndCallbacks;
} }

View File

@ -25,24 +25,24 @@
#include "constants/trainers.h" #include "constants/trainers.h"
#include "constants/rgb.h" #include "constants/rgb.h"
static void SafariHandleDrawTrainerPic(void); static void SafariHandleDrawTrainerPic(u32 battler);
static void SafariHandleSuccessBallThrowAnim(void); static void SafariHandleSuccessBallThrowAnim(u32 battler);
static void SafariHandleBallThrowAnim(void); static void SafariHandleBallThrowAnim(u32 battler);
static void SafariHandlePrintString(void); static void SafariHandlePrintString(u32 battler);
static void SafariHandlePrintSelectionString(void); static void SafariHandlePrintSelectionString(u32 battler);
static void SafariHandleChooseAction(void); static void SafariHandleChooseAction(u32 battler);
static void SafariHandleChooseItem(void); static void SafariHandleChooseItem(u32 battler);
static void SafariHandleStatusIconUpdate(void); static void SafariHandleStatusIconUpdate(u32 battler);
static void SafariHandleFaintingCry(void); static void SafariHandleFaintingCry(u32 battler);
static void SafariHandleIntroTrainerBallThrow(void); static void SafariHandleIntroTrainerBallThrow(u32 battler);
static void SafariHandleBattleAnimation(void); static void SafariHandleBattleAnimation(u32 battler);
static void SafariHandleEndLinkBattle(void); static void SafariHandleEndLinkBattle(u32 battler);
static void SafariBufferRunCommand(void); static void SafariBufferRunCommand(u32 battler);
static void SafariBufferExecCompleted(void); static void SafariBufferExecCompleted(u32 battler);
static void CompleteWhenChosePokeblock(void); static void CompleteWhenChosePokeblock(u32 battler);
static void (*const sSafariBufferCommands[CONTROLLER_CMDS_COUNT])(void) = static void (*const sSafariBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{ {
[CONTROLLER_GETMONDATA] = BtlController_Empty, [CONTROLLER_GETMONDATA] = BtlController_Empty,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty, [CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -104,30 +104,30 @@ static void (*const sSafariBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
}; };
void SetControllerToSafari(void) void SetControllerToSafari(u32 battler)
{ {
gBattlerControllerEndFuncs[gActiveBattler] = SafariBufferExecCompleted; gBattlerControllerEndFuncs[battler] = SafariBufferExecCompleted;
gBattlerControllerFuncs[gActiveBattler] = SafariBufferRunCommand; gBattlerControllerFuncs[battler] = SafariBufferRunCommand;
} }
static void SafariBufferRunCommand(void) static void SafariBufferRunCommand(u32 battler)
{ {
if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) if (gBattleControllerExecFlags & gBitTable[battler])
{ {
if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sSafariBufferCommands)) if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sSafariBufferCommands))
sSafariBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); sSafariBufferCommands[gBattleResources->bufferA[battler][0]](battler);
else else
SafariBufferExecCompleted(); SafariBufferExecCompleted(battler);
} }
} }
static void HandleInputChooseAction(void) static void HandleInputChooseAction(u32 battler)
{ {
if (JOY_NEW(A_BUTTON)) if (JOY_NEW(A_BUTTON))
{ {
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
switch (gActionSelectionCursor[gActiveBattler]) switch (gActionSelectionCursor[battler])
{ {
case 0: case 0:
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SAFARI_BALL, 0); BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SAFARI_BALL, 0);
@ -142,57 +142,57 @@ static void HandleInputChooseAction(void)
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SAFARI_RUN, 0); BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SAFARI_RUN, 0);
break; break;
} }
SafariBufferExecCompleted(); SafariBufferExecCompleted(battler);
} }
else if (JOY_NEW(DPAD_LEFT)) else if (JOY_NEW(DPAD_LEFT))
{ {
if (gActionSelectionCursor[gActiveBattler] & 1) if (gActionSelectionCursor[battler] & 1)
{ {
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]); ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]);
gActionSelectionCursor[gActiveBattler] ^= 1; gActionSelectionCursor[battler] ^= 1;
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
} }
} }
else if (JOY_NEW(DPAD_RIGHT)) else if (JOY_NEW(DPAD_RIGHT))
{ {
if (!(gActionSelectionCursor[gActiveBattler] & 1)) if (!(gActionSelectionCursor[battler] & 1))
{ {
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]); ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]);
gActionSelectionCursor[gActiveBattler] ^= 1; gActionSelectionCursor[battler] ^= 1;
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
} }
} }
else if (JOY_NEW(DPAD_UP)) else if (JOY_NEW(DPAD_UP))
{ {
if (gActionSelectionCursor[gActiveBattler] & 2) if (gActionSelectionCursor[battler] & 2)
{ {
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]); ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]);
gActionSelectionCursor[gActiveBattler] ^= 2; gActionSelectionCursor[battler] ^= 2;
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
} }
} }
else if (JOY_NEW(DPAD_DOWN)) else if (JOY_NEW(DPAD_DOWN))
{ {
if (!(gActionSelectionCursor[gActiveBattler] & 2)) if (!(gActionSelectionCursor[battler] & 2))
{ {
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]); ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]);
gActionSelectionCursor[gActiveBattler] ^= 2; gActionSelectionCursor[battler] ^= 2;
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
} }
} }
} }
static void Controller_WaitForHealthbox(void) static void Controller_WaitForHealthbox(u32 battler)
{ {
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
SafariBufferExecCompleted(); SafariBufferExecCompleted(battler);
} }
static void SafariSetBattleEndCallbacks(void) static void SafariSetBattleEndCallbacks(u32 battler)
{ {
if (!gPaletteFade.active) if (!gPaletteFade.active)
{ {
@ -202,140 +202,141 @@ static void SafariSetBattleEndCallbacks(void)
} }
} }
static void SafariOpenPokeblockCase(void) static void SafariOpenPokeblockCase(u32 battler)
{ {
if (!gPaletteFade.active) if (!gPaletteFade.active)
{ {
gBattlerControllerFuncs[gActiveBattler] = CompleteWhenChosePokeblock; gBattlerControllerFuncs[battler] = CompleteWhenChosePokeblock;
FreeAllWindowBuffers(); FreeAllWindowBuffers();
OpenPokeblockCaseInBattle(); OpenPokeblockCaseInBattle();
} }
} }
static void CompleteWhenChosePokeblock(void) static void CompleteWhenChosePokeblock(u32 battler)
{ {
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{ {
BtlController_EmitOneReturnValue(BUFFER_B, gSpecialVar_ItemId); BtlController_EmitOneReturnValue(BUFFER_B, gSpecialVar_ItemId);
SafariBufferExecCompleted(); SafariBufferExecCompleted(battler);
} }
} }
static void SafariBufferExecCompleted(void) static void SafariBufferExecCompleted(u32 battler)
{ {
gBattlerControllerFuncs[gActiveBattler] = SafariBufferRunCommand; gBattlerControllerFuncs[battler] = SafariBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK) if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{ {
u8 playerId = GetMultiplayerId(); u8 playerId = GetMultiplayerId();
PrepareBufferDataTransferLink(2, 4, &playerId); PrepareBufferDataTransferLink(2, 4, &playerId);
gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP;
} }
else else
{ {
gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; gBattleControllerExecFlags &= ~gBitTable[battler];
} }
} }
static void SafariHandleDrawTrainerPic(void) static void SafariHandleDrawTrainerPic(u32 battler)
{ {
u32 trainerPicId = gSaveBlock2Ptr->playerGender + TRAINER_BACK_PIC_BRENDAN; u32 trainerPicId = gSaveBlock2Ptr->playerGender + TRAINER_BACK_PIC_BRENDAN;
BtlController_HandleDrawTrainerPic(gActiveBattler, trainerPicId, FALSE, BtlController_HandleDrawTrainerPic(battler, trainerPicId, FALSE,
80, 80 + 4 * (8 - gTrainerBackPicCoords[trainerPicId].size), 80, 80 + 4 * (8 - gTrainerBackPicCoords[trainerPicId].size),
30); 30);
} }
static void SafariHandleSuccessBallThrowAnim(void) static void SafariHandleSuccessBallThrowAnim(u32 battler)
{ {
BtlController_HandleSuccessBallThrowAnim(gActiveBattler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE); BtlController_HandleSuccessBallThrowAnim(battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE);
} }
static void SafariHandleBallThrowAnim(void) static void SafariHandleBallThrowAnim(u32 battler)
{ {
BtlController_HandleBallThrowAnim(gActiveBattler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE); BtlController_HandleBallThrowAnim(battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE);
} }
static void SafariHandlePrintString(void) static void SafariHandlePrintString(u32 battler)
{ {
BtlController_HandlePrintString(gActiveBattler, FALSE, FALSE); BtlController_HandlePrintString(battler, FALSE, FALSE);
} }
static void SafariHandlePrintSelectionString(void) static void SafariHandlePrintSelectionString(u32 battler)
{ {
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) if (GetBattlerSide(battler) == B_SIDE_PLAYER)
SafariHandlePrintString(); SafariHandlePrintString(battler);
else else
SafariBufferExecCompleted(); SafariBufferExecCompleted(battler);
} }
static void HandleChooseActionAfterDma3(void) static void HandleChooseActionAfterDma3(u32 battler)
{ {
if (!IsDma3ManagerBusyWithBgCopy()) if (!IsDma3ManagerBusyWithBgCopy())
{ {
gBattle_BG0_X = 0; gBattle_BG0_X = 0;
gBattle_BG0_Y = DISPLAY_HEIGHT; gBattle_BG0_Y = DISPLAY_HEIGHT;
gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseAction; gBattlerControllerFuncs[battler] = HandleInputChooseAction;
} }
} }
static void SafariHandleChooseAction(void) static void SafariHandleChooseAction(u32 battler)
{ {
s32 i; s32 i;
gBattlerControllerFuncs[gActiveBattler] = HandleChooseActionAfterDma3; gBattlerControllerFuncs[battler] = HandleChooseActionAfterDma3;
BattlePutTextOnWindow(gText_SafariZoneMenu, B_WIN_ACTION_MENU); BattlePutTextOnWindow(gText_SafariZoneMenu, B_WIN_ACTION_MENU);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
ActionSelectionDestroyCursorAt(i); ActionSelectionDestroyCursorAt(i);
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo2); BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo2);
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT);
} }
static void SafariHandleChooseItem(void) static void SafariHandleChooseItem(u32 battler)
{ {
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK);
gBattlerControllerFuncs[gActiveBattler] = SafariOpenPokeblockCase; gBattlerControllerFuncs[battler] = SafariOpenPokeblockCase;
gBattlerInMenuId = gActiveBattler; gBattlerInMenuId = battler;
} }
static void SafariHandleStatusIconUpdate(void) static void SafariHandleStatusIconUpdate(u32 battler)
{ {
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_SAFARI_BALLS_TEXT); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_SAFARI_BALLS_TEXT);
SafariBufferExecCompleted(); SafariBufferExecCompleted(battler);
} }
// All of the other controllers(except Wally's) use CRY_MODE_FAINT. // All of the other controllers(except Wally's) use CRY_MODE_FAINT.
// Player is not a pokemon, so it can't really faint in the Safari anyway. // Player is not a pokemon, so it can't really faint in the Safari anyway.
static void SafariHandleFaintingCry(void) static void SafariHandleFaintingCry(u32 battler)
{ {
u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES);
PlayCry_Normal(species, 25); PlayCry_Normal(species, 25);
SafariBufferExecCompleted(); SafariBufferExecCompleted(battler);
SafariBufferExecCompleted(battler);
} }
static void SafariHandleIntroTrainerBallThrow(void) static void SafariHandleIntroTrainerBallThrow(u32 battler)
{ {
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_SAFARI_ALL_TEXT); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_SAFARI_ALL_TEXT);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
gBattlerControllerFuncs[gActiveBattler] = Controller_WaitForHealthbox; gBattlerControllerFuncs[battler] = Controller_WaitForHealthbox;
} }
static void SafariHandleBattleAnimation(void) static void SafariHandleBattleAnimation(u32 battler)
{ {
BtlController_HandleBattleAnimation(gActiveBattler, TRUE, FALSE); BtlController_HandleBattleAnimation(battler, TRUE, FALSE);
} }
static void SafariHandleEndLinkBattle(void) static void SafariHandleEndLinkBattle(u32 battler)
{ {
gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; gBattleOutcome = gBattleResources->bufferA[battler][1];
FadeOutMapMusic(5); FadeOutMapMusic(5);
BeginFastPaletteFade(3); BeginFastPaletteFade(3);
SafariBufferExecCompleted(); SafariBufferExecCompleted(battler);
if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && !(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)) if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && !(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER))
gBattlerControllerFuncs[gActiveBattler] = SafariSetBattleEndCallbacks; gBattlerControllerFuncs[battler] = SafariSetBattleEndCallbacks;
} }

View File

@ -32,30 +32,30 @@
#include "constants/trainers.h" #include "constants/trainers.h"
#include "constants/rgb.h" #include "constants/rgb.h"
static void WallyHandleDrawTrainerPic(void); static void WallyHandleDrawTrainerPic(u32 battler);
static void WallyHandleTrainerSlide(void); static void WallyHandleTrainerSlide(u32 battler);
static void WallyHandleSuccessBallThrowAnim(void); static void WallyHandleSuccessBallThrowAnim(u32 battler);
static void WallyHandleBallThrowAnim(void); static void WallyHandleBallThrowAnim(u32 battler);
static void WallyHandleMoveAnimation(void); static void WallyHandleMoveAnimation(u32 battler);
static void WallyHandlePrintString(void); static void WallyHandlePrintString(u32 battler);
static void WallyHandlePrintSelectionString(void); static void WallyHandlePrintSelectionString(u32 battler);
static void WallyHandleChooseAction(void); static void WallyHandleChooseAction(u32 battler);
static void WallyHandleChooseMove(void); static void WallyHandleChooseMove(u32 battler);
static void WallyHandleChooseItem(void); static void WallyHandleChooseItem(u32 battler);
static void WallyHandleHealthBarUpdate(void); static void WallyHandleHealthBarUpdate(u32 battler);
static void WallyHandlePlaySE(void); static void WallyHandlePlaySE(u32 battler);
static void WallyHandleFaintingCry(void); static void WallyHandleFaintingCry(u32 battler);
static void WallyHandleIntroTrainerBallThrow(void); static void WallyHandleIntroTrainerBallThrow(u32 battler);
static void WallyHandleDrawPartyStatusSummary(void); static void WallyHandleDrawPartyStatusSummary(u32 battler);
static void WallyHandleBattleAnimation(void); static void WallyHandleBattleAnimation(u32 battler);
static void WallyHandleEndLinkBattle(void); static void WallyHandleEndLinkBattle(u32 battler);
static void WallyBufferRunCommand(void); static void WallyBufferRunCommand(u32 battler);
static void WallyBufferExecCompleted(void); static void WallyBufferExecCompleted(u32 battler);
static void CompleteOnChosenItem(void); static void CompleteOnChosenItem(u32 battler);
static void Intro_WaitForShinyAnimAndHealthbox(void); static void Intro_WaitForShinyAnimAndHealthbox(u32 battler);
static void (*const sWallyBufferCommands[CONTROLLER_CMDS_COUNT])(void) = static void (*const sWallyBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
{ {
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_HandleGetRawMonData, [CONTROLLER_GETRAWMONDATA] = BtlController_HandleGetRawMonData,
@ -117,28 +117,28 @@ static void (*const sWallyBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
}; };
void SetControllerToWally(void) void SetControllerToWally(u32 battler)
{ {
gBattlerControllerEndFuncs[gActiveBattler] = WallyBufferExecCompleted; gBattlerControllerEndFuncs[battler] = WallyBufferExecCompleted;
gBattlerControllerFuncs[gActiveBattler] = WallyBufferRunCommand; gBattlerControllerFuncs[battler] = WallyBufferRunCommand;
gBattleStruct->wallyBattleState = 0; gBattleStruct->wallyBattleState = 0;
gBattleStruct->wallyMovesState = 0; gBattleStruct->wallyMovesState = 0;
gBattleStruct->wallyWaitFrames = 0; gBattleStruct->wallyWaitFrames = 0;
gBattleStruct->wallyMoveFrames = 0; gBattleStruct->wallyMoveFrames = 0;
} }
static void WallyBufferRunCommand(void) static void WallyBufferRunCommand(u32 battler)
{ {
if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) if (gBattleControllerExecFlags & gBitTable[battler])
{ {
if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sWallyBufferCommands)) if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sWallyBufferCommands))
sWallyBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); sWallyBufferCommands[gBattleResources->bufferA[battler][0]](battler);
else else
WallyBufferExecCompleted(); WallyBufferExecCompleted(battler);
} }
} }
static void WallyHandleActions(void) static void WallyHandleActions(u32 battler)
{ {
switch (gBattleStruct->wallyBattleState) switch (gBattleStruct->wallyBattleState)
{ {
@ -150,7 +150,7 @@ static void WallyHandleActions(void)
{ {
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_USE_MOVE, 0); BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_USE_MOVE, 0);
WallyBufferExecCompleted(); WallyBufferExecCompleted(battler);
gBattleStruct->wallyBattleState++; gBattleStruct->wallyBattleState++;
gBattleStruct->wallyMovesState = 0; gBattleStruct->wallyMovesState = 0;
gBattleStruct->wallyWaitFrames = B_WAIT_TIME_LONG; gBattleStruct->wallyWaitFrames = B_WAIT_TIME_LONG;
@ -161,7 +161,7 @@ static void WallyHandleActions(void)
{ {
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_USE_MOVE, 0); BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_USE_MOVE, 0);
WallyBufferExecCompleted(); WallyBufferExecCompleted(battler);
gBattleStruct->wallyBattleState++; gBattleStruct->wallyBattleState++;
gBattleStruct->wallyMovesState = 0; gBattleStruct->wallyMovesState = 0;
gBattleStruct->wallyWaitFrames = B_WAIT_TIME_LONG; gBattleStruct->wallyWaitFrames = B_WAIT_TIME_LONG;
@ -171,7 +171,7 @@ static void WallyHandleActions(void)
if (--gBattleStruct->wallyWaitFrames == 0) if (--gBattleStruct->wallyWaitFrames == 0)
{ {
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_WALLY_THROW, 0); BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_WALLY_THROW, 0);
WallyBufferExecCompleted(); WallyBufferExecCompleted(battler);
gBattleStruct->wallyBattleState++; gBattleStruct->wallyBattleState++;
gBattleStruct->wallyMovesState = 0; gBattleStruct->wallyMovesState = 0;
gBattleStruct->wallyWaitFrames = B_WAIT_TIME_LONG; gBattleStruct->wallyWaitFrames = B_WAIT_TIME_LONG;
@ -192,187 +192,181 @@ static void WallyHandleActions(void)
{ {
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_USE_ITEM, 0); BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_USE_ITEM, 0);
WallyBufferExecCompleted(); WallyBufferExecCompleted(battler);
} }
break; break;
} }
} }
static void CompleteOnBattlerSpriteCallbackDummy(void) static void OpenBagAfterPaletteFade(u32 battler)
{
if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
WallyBufferExecCompleted();
}
static void OpenBagAfterPaletteFade(void)
{ {
if (!gPaletteFade.active) if (!gPaletteFade.active)
{ {
gBattlerControllerFuncs[gActiveBattler] = CompleteOnChosenItem; gBattlerControllerFuncs[battler] = CompleteOnChosenItem;
ReshowBattleScreenDummy(); ReshowBattleScreenDummy();
FreeAllWindowBuffers(); FreeAllWindowBuffers();
DoWallyTutorialBagMenu(); DoWallyTutorialBagMenu();
} }
} }
static void CompleteOnChosenItem(void) static void CompleteOnChosenItem(u32 battler)
{ {
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{ {
BtlController_EmitOneReturnValue(BUFFER_B, gSpecialVar_ItemId); BtlController_EmitOneReturnValue(BUFFER_B, gSpecialVar_ItemId);
WallyBufferExecCompleted(); WallyBufferExecCompleted(battler);
} }
} }
static void Intro_TryShinyAnimShowHealthbox(void) static void Intro_TryShinyAnimShowHealthbox(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]);
if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive) && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive)
TryShinyAnimation(BATTLE_PARTNER(gActiveBattler), &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]]); TryShinyAnimation(BATTLE_PARTNER(battler), &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]]);
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive
&& gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy && gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy
&& gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
{ {
DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]]);
UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL);
StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); StartHealthboxSlideIn(BATTLE_PARTNER(battler));
SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]);
} }
DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); DestroySprite(&gSprites[gBattleControllerData[battler]]);
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL);
StartHealthboxSlideIn(gActiveBattler); StartHealthboxSlideIn(battler);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
gBattleSpritesDataPtr->animationData->introAnimActive = FALSE; gBattleSpritesDataPtr->animationData->introAnimActive = FALSE;
gBattlerControllerFuncs[gActiveBattler] = Intro_WaitForShinyAnimAndHealthbox; gBattlerControllerFuncs[battler] = Intro_WaitForShinyAnimAndHealthbox;
} }
} }
static void Intro_WaitForShinyAnimAndHealthbox(void) static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
{ {
bool32 healthboxAnimDone = FALSE; bool32 healthboxAnimDone = FALSE;
if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
healthboxAnimDone = TRUE; healthboxAnimDone = TRUE;
if (healthboxAnimDone && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim if (healthboxAnimDone && gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim
&& gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) && gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim = FALSE; gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
CreateTask(Task_PlayerController_RestoreBgmAfterCry, 10); CreateTask(Task_PlayerController_RestoreBgmAfterCry, 10);
HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler);
WallyBufferExecCompleted(); WallyBufferExecCompleted(battler);
} }
} }
static void WallyBufferExecCompleted(void) static void WallyBufferExecCompleted(u32 battler)
{ {
gBattlerControllerFuncs[gActiveBattler] = WallyBufferRunCommand; gBattlerControllerFuncs[battler] = WallyBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK) if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{ {
u8 playerId = GetMultiplayerId(); u8 playerId = GetMultiplayerId();
PrepareBufferDataTransferLink(2, 4, &playerId); PrepareBufferDataTransferLink(2, 4, &playerId);
gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP;
} }
else else
{ {
gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; gBattleControllerExecFlags &= ~gBitTable[battler];
} }
} }
#define sSpeedX data[0] #define sSpeedX data[0]
static void WallyHandleDrawTrainerPic(void) static void WallyHandleDrawTrainerPic(u32 battler)
{ {
BtlController_HandleDrawTrainerPic(gActiveBattler, TRAINER_BACK_PIC_WALLY, FALSE, BtlController_HandleDrawTrainerPic(battler, TRAINER_BACK_PIC_WALLY, FALSE,
80, 80 + 4 * (8 - gTrainerBackPicCoords[TRAINER_BACK_PIC_WALLY].size), 80, 80 + 4 * (8 - gTrainerBackPicCoords[TRAINER_BACK_PIC_WALLY].size),
30); 30);
} }
static void WallyHandleTrainerSlide(void) static void WallyHandleTrainerSlide(u32 battler)
{ {
BtlController_HandleTrainerSlide(gActiveBattler, TRAINER_BACK_PIC_WALLY); BtlController_HandleTrainerSlide(battler, TRAINER_BACK_PIC_WALLY);
} }
#undef sSpeedX #undef sSpeedX
static void WallyHandleSuccessBallThrowAnim(void) static void WallyHandleSuccessBallThrowAnim(u32 battler)
{ {
BtlController_HandleSuccessBallThrowAnim(gActiveBattler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE); BtlController_HandleSuccessBallThrowAnim(battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE);
} }
static void WallyHandleBallThrowAnim(void) static void WallyHandleBallThrowAnim(u32 battler)
{ {
BtlController_HandleBallThrowAnim(gActiveBattler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE); BtlController_HandleBallThrowAnim(battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE);
} }
static void WallyHandleMoveAnimation(void) static void WallyHandleMoveAnimation(u32 battler)
{ {
BtlController_HandleMoveAnimation(gActiveBattler, FALSE); BtlController_HandleMoveAnimation(battler, FALSE);
} }
static void WallyHandlePrintString(void) static void WallyHandlePrintString(u32 battler)
{ {
BtlController_HandlePrintString(gActiveBattler, FALSE, FALSE); BtlController_HandlePrintString(battler, FALSE, FALSE);
} }
static void WallyHandlePrintSelectionString(void) static void WallyHandlePrintSelectionString(u32 battler)
{ {
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) if (GetBattlerSide(battler) == B_SIDE_PLAYER)
WallyHandlePrintString(); WallyHandlePrintString(battler);
else else
WallyBufferExecCompleted(); WallyBufferExecCompleted(battler);
} }
static void HandleChooseActionAfterDma3(void) static void HandleChooseActionAfterDma3(u32 battler)
{ {
if (!IsDma3ManagerBusyWithBgCopy()) if (!IsDma3ManagerBusyWithBgCopy())
{ {
gBattle_BG0_X = 0; gBattle_BG0_X = 0;
gBattle_BG0_Y = DISPLAY_HEIGHT; gBattle_BG0_Y = DISPLAY_HEIGHT;
gBattlerControllerFuncs[gActiveBattler] = WallyHandleActions; gBattlerControllerFuncs[battler] = WallyHandleActions;
} }
} }
static void WallyHandleChooseAction(void) static void WallyHandleChooseAction(u32 battler)
{ {
s32 i; s32 i;
gBattlerControllerFuncs[gActiveBattler] = HandleChooseActionAfterDma3; gBattlerControllerFuncs[battler] = HandleChooseActionAfterDma3;
BattlePutTextOnWindow(gText_BattleMenu, B_WIN_ACTION_MENU); BattlePutTextOnWindow(gText_BattleMenu, B_WIN_ACTION_MENU);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
ActionSelectionDestroyCursorAt(i); ActionSelectionDestroyCursorAt(i);
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillWallyDo); BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillWallyDo);
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT);
} }
static void WallyHandleChooseMove(void) static void WallyHandleChooseMove(u32 battler)
{ {
switch (gBattleStruct->wallyMovesState) switch (gBattleStruct->wallyMovesState)
{ {
case 0: case 0:
InitMoveSelectionsVarsAndStrings(); InitMoveSelectionsVarsAndStrings(battler);
gBattleStruct->wallyMovesState++; gBattleStruct->wallyMovesState++;
gBattleStruct->wallyMoveFrames = 80; gBattleStruct->wallyMoveFrames = 80;
break; break;
@ -389,64 +383,64 @@ static void WallyHandleChooseMove(void)
{ {
PlaySE(SE_SELECT); PlaySE(SE_SELECT);
BtlController_EmitTwoReturnValues(BUFFER_B, 10, 0x100); BtlController_EmitTwoReturnValues(BUFFER_B, 10, 0x100);
WallyBufferExecCompleted(); WallyBufferExecCompleted(battler);
} }
break; break;
} }
} }
static void WallyHandleChooseItem(void) static void WallyHandleChooseItem(u32 battler)
{ {
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK);
gBattlerControllerFuncs[gActiveBattler] = OpenBagAfterPaletteFade; gBattlerControllerFuncs[battler] = OpenBagAfterPaletteFade;
gBattlerInMenuId = gActiveBattler; gBattlerInMenuId = battler;
} }
static void WallyHandleHealthBarUpdate(void) static void WallyHandleHealthBarUpdate(u32 battler)
{ {
BtlController_HandleHealthBarUpdate(gActiveBattler, TRUE); BtlController_HandleHealthBarUpdate(battler, TRUE);
} }
// For some reason Wally's SE don't take side into account and pan is always the same. Possibly a bug // For some reason Wally's SE don't take side into account and pan is always the same. Possibly a bug
static void WallyHandlePlaySE(void) static void WallyHandlePlaySE(u32 battler)
{ {
PlaySE(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); PlaySE(gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8));
WallyBufferExecCompleted(); WallyBufferExecCompleted(battler);
} }
// All of the other controllers use CRY_MODE_FAINT. // All of the other controllers use CRY_MODE_FAINT.
// Wally's Pokémon during the tutorial is never intended to faint, so that's probably why it's different here. // Wally's Pokémon during the tutorial is never intended to faint, so that's probably why it's different here.
static void WallyHandleFaintingCry(void) static void WallyHandleFaintingCry(u32 battler)
{ {
u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES);
PlayCry_Normal(species, 25); PlayCry_Normal(species, 25);
WallyBufferExecCompleted(); WallyBufferExecCompleted(battler);
} }
static void WallyHandleIntroTrainerBallThrow(void) static void WallyHandleIntroTrainerBallThrow(u32 battler)
{ {
const u32 *trainerPal = gTrainerBackPicPaletteTable[TRAINER_BACK_PIC_WALLY].data; const u32 *trainerPal = gTrainerBackPicPaletteTable[TRAINER_BACK_PIC_WALLY].data;
BtlController_HandleIntroTrainerBallThrow(gActiveBattler, 0xD6F8, trainerPal, 31, Intro_TryShinyAnimShowHealthbox); BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F8, trainerPal, 31, Intro_TryShinyAnimShowHealthbox);
} }
static void WallyHandleDrawPartyStatusSummary(void) static void WallyHandleDrawPartyStatusSummary(u32 battler)
{ {
BtlController_HandleDrawPartyStatusSummary(gActiveBattler, B_SIDE_PLAYER, FALSE); BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, FALSE);
} }
static void WallyHandleBattleAnimation(void) static void WallyHandleBattleAnimation(u32 battler)
{ {
BtlController_HandleBattleAnimation(gActiveBattler, TRUE, FALSE); BtlController_HandleBattleAnimation(battler, TRUE, FALSE);
} }
static void WallyHandleEndLinkBattle(void) static void WallyHandleEndLinkBattle(u32 battler)
{ {
gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; gBattleOutcome = gBattleResources->bufferA[battler][1];
FadeOutMapMusic(5); FadeOutMapMusic(5);
BeginFastPaletteFade(3); BeginFastPaletteFade(3);
WallyBufferExecCompleted(); WallyBufferExecCompleted(battler);
if (!(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER) && gBattleTypeFlags & BATTLE_TYPE_LINK) if (!(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER) && gBattleTypeFlags & BATTLE_TYPE_LINK)
gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; gBattlerControllerFuncs[battler] = SetBattleEndCallbacks;
} }

View File

@ -25,10 +25,13 @@
static EWRAM_DATA u8 sLinkSendTaskId = 0; static EWRAM_DATA u8 sLinkSendTaskId = 0;
static EWRAM_DATA u8 sLinkReceiveTaskId = 0; static EWRAM_DATA u8 sLinkReceiveTaskId = 0;
EWRAM_DATA void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(void) = {NULL}; // Controller's buffer complete function for each battler
EWRAM_DATA struct UnusedControllerStruct gUnusedControllerStruct = {}; // Debug? Unused code that writes to it, never read EWRAM_DATA struct UnusedControllerStruct gUnusedControllerStruct = {}; // Debug? Unused code that writes to it, never read
static EWRAM_DATA u8 sBattleBuffersTransferData[0x100] = {}; static EWRAM_DATA u8 sBattleBuffersTransferData[0x100] = {};
void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(u32 battler);
u8 gBattleControllerData[MAX_BATTLERS_COUNT]; // Used by the battle controllers to store misc sprite/task IDs for each battler
void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(u32 battler); // Controller's buffer complete function for each battler
static void CreateTasksForSendRecvLinkBuffers(void); static void CreateTasksForSendRecvLinkBuffers(void);
static void InitLinkBtlControllers(void); static void InitLinkBtlControllers(void);
static void InitSinglePlayerBtlControllers(void); static void InitSinglePlayerBtlControllers(void);
@ -1562,7 +1565,7 @@ void BtlController_EmitDebugMenu(u8 bufferId)
// Can be used for all the controllers. // Can be used for all the controllers.
void BattleControllerComplete(u32 battler) void BattleControllerComplete(u32 battler)
{ {
gBattlerControllerEndFuncs[battler](); gBattlerControllerEndFuncs[battler](battler);
} }
static u32 GetBattlerMonData(u32 battler, struct Pokemon *party, u32 monId, u8 *dst) static u32 GetBattlerMonData(u32 battler, struct Pokemon *party, u32 monId, u8 *dst)
@ -2133,186 +2136,186 @@ static void FreeMonSprite(u32 battler)
SetHealthboxSpriteInvisible(gHealthboxSpriteIds[battler]); SetHealthboxSpriteInvisible(gHealthboxSpriteIds[battler]);
} }
static void Controller_ReturnMonToBall2(void) static void Controller_ReturnMonToBall2(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive)
{ {
FreeMonSprite(gActiveBattler); FreeMonSprite(battler);
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
} }
static void Controller_ReturnMonToBall(void) static void Controller_ReturnMonToBall(u32 battler)
{ {
switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) switch (gBattleSpritesDataPtr->healthBoxesData[battler].animationState)
{ {
case 0: case 0:
if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_SUBSTITUTE_TO_MON);
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 1;
break; break;
case 1: case 1:
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0;
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT) ? B_ANIM_SWITCH_OUT_OPPONENT_MON : B_ANIM_SWITCH_OUT_PLAYER_MON); InitAndLaunchSpecialAnimation(battler, battler, battler, (GetBattlerSide(battler) == B_SIDE_OPPONENT) ? B_ANIM_SWITCH_OUT_OPPONENT_MON : B_ANIM_SWITCH_OUT_PLAYER_MON);
gBattlerControllerFuncs[gActiveBattler] = Controller_ReturnMonToBall2; gBattlerControllerFuncs[battler] = Controller_ReturnMonToBall2;
} }
break; break;
} }
} }
static void Controller_FaintPlayerMon(void) static void Controller_FaintPlayerMon(u32 battler)
{ {
u32 spriteId = gBattlerSpriteIds[gActiveBattler]; u32 spriteId = gBattlerSpriteIds[battler];
if (gSprites[spriteId].y + gSprites[spriteId].y2 > DISPLAY_HEIGHT) if (gSprites[spriteId].y + gSprites[spriteId].y2 > DISPLAY_HEIGHT)
{ {
BattleGfxSfxDummy2(GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); BattleGfxSfxDummy2(GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES));
FreeOamMatrix(gSprites[spriteId].oam.matrixNum); FreeOamMatrix(gSprites[spriteId].oam.matrixNum);
DestroySprite(&gSprites[spriteId]); DestroySprite(&gSprites[spriteId]);
SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteInvisible(gHealthboxSpriteIds[battler]);
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
} }
static void Controller_FaintOpponentMon(void) static void Controller_FaintOpponentMon(u32 battler)
{ {
if (!gSprites[gBattlerSpriteIds[gActiveBattler]].inUse) if (!gSprites[gBattlerSpriteIds[battler]].inUse)
{ {
SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteInvisible(gHealthboxSpriteIds[battler]);
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
} }
static void Controller_DoMoveAnimation(void) static void Controller_DoMoveAnimation(u32 battler)
{ {
u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); u16 move = gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8);
switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) switch (gBattleSpritesDataPtr->healthBoxesData[battler].animationState)
{ {
case 0: case 0:
if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute
&& !gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8) && !gBattleSpritesDataPtr->battlerData[battler].flag_x8)
{ {
gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 1; gBattleSpritesDataPtr->battlerData[battler].flag_x8 = 1;
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_SUBSTITUTE_TO_MON);
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 1;
break; break;
case 1: case 1:
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive)
{ {
SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF); SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF);
DoMoveAnim(move); DoMoveAnim(move);
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 2; gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 2;
} }
break; break;
case 2: case 2:
gAnimScriptCallback(); gAnimScriptCallback();
if (!gAnimScriptActive) if (!gAnimScriptActive)
{ {
u8 multihit = gBattleResources->bufferA[gActiveBattler][11]; u8 multihit = gBattleResources->bufferA[battler][11];
SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL); SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL);
if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute && multihit < 2) if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute && multihit < 2)
{ {
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE);
gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 0; gBattleSpritesDataPtr->battlerData[battler].flag_x8 = 0;
} }
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 3; gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 3;
} }
break; break;
case 3: case 3:
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive)
{ {
CopyAllBattleSpritesInvisibilities(); CopyAllBattleSpritesInvisibilities();
TrySetBehindSubstituteSpriteBit(gActiveBattler, gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); TrySetBehindSubstituteSpriteBit(battler, gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8));
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0;
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
break; break;
} }
} }
static void Controller_HandleTrainerSlideBack(void) static void Controller_HandleTrainerSlideBack(u32 battler)
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
{ {
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT) if (GetBattlerSide(battler) == B_SIDE_OPPONENT)
FreeTrainerFrontPicPalette(gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam); FreeTrainerFrontPicPalette(gSprites[gBattlerSpriteIds[battler]].oam.affineParam);
FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[battler]]);
DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); DestroySprite(&gSprites[gBattlerSpriteIds[battler]]);
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
} }
void Controller_WaitForHealthBar(void) void Controller_WaitForHealthBar(u32 battler)
{ {
s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0); s16 hpValue = MoveBattleBar(battler, gHealthboxSpriteIds[battler], HEALTH_BAR, 0);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]);
if (hpValue != -1) if (hpValue != -1)
{ {
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); UpdateHpTextInHealthbox(gHealthboxSpriteIds[battler], HP_CURRENT, hpValue, gBattleMons[battler].maxHP);
} }
else else
{ {
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) if (GetBattlerSide(battler) == B_SIDE_PLAYER)
HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler);
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
} }
static void Controller_WaitForBallThrow(void) static void Controller_WaitForBallThrow(u32 battler)
{ {
if (!gDoingBattleAnim || !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) if (!gDoingBattleAnim || !gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive)
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
static void Controller_WaitForBattleAnimation(void) static void Controller_WaitForBattleAnimation(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive) if (!gBattleSpritesDataPtr->healthBoxesData[battler].animFromTableActive)
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
static void Controller_WaitForStatusAnimation(void) static void Controller_WaitForStatusAnimation(u32 battler)
{ {
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive) if (!gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive)
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
static void Controller_WaitForTrainerPic(void) static void Controller_WaitForTrainerPic(u32 battler)
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy)
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
void Controller_WaitForString(void) void Controller_WaitForString(u32 battler)
{ {
if (!IsTextPrinterActive(B_WIN_MSG)) if (!IsTextPrinterActive(B_WIN_MSG))
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
static void Controller_WaitForPartyStatusSummary(void) static void Controller_WaitForPartyStatusSummary(u32 battler)
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer++ > 92) if (gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusDelayTimer++ > 92)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusDelayTimer = 0;
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
} }
static void Controller_HitAnimation(void) static void Controller_HitAnimation(u32 battler)
{ {
u32 spriteId = gBattlerSpriteIds[gActiveBattler]; u32 spriteId = gBattlerSpriteIds[battler];
if (gSprites[spriteId].data[1] == 32) if (gSprites[spriteId].data[1] == 32)
{ {
gSprites[spriteId].data[1] = 0; gSprites[spriteId].data[1] = 0;
gSprites[spriteId].invisible = FALSE; gSprites[spriteId].invisible = FALSE;
gDoingBattleAnim = FALSE; gDoingBattleAnim = FALSE;
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
else else
{ {
@ -2323,21 +2326,24 @@ static void Controller_HitAnimation(void)
} }
// Used for all the commands which do nothing. // Used for all the commands which do nothing.
void BtlController_Empty(void) void BtlController_Empty(u32 battler)
{ {
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
// Dummy function at the end of the table. // Dummy function at the end of the table.
void BtlController_TerminatorNop(void) void BtlController_TerminatorNop(u32 battler)
{
}
void BattleControllerDummy(u32 battler)
{ {
} }
// Handlers of the controller commands // Handlers of the controller commands
void BtlController_HandleGetMonData(void) void BtlController_HandleGetMonData(u32 battler)
{ {
u8 monData[sizeof(struct Pokemon) * 2 + 56]; // this allows to get full data of two pokemon, trying to get more will result in overwriting data u8 monData[sizeof(struct Pokemon) * 2 + 56]; // this allows to get full data of two pokemon, trying to get more will result in overwriting data
u32 battler = gActiveBattler;
struct Pokemon *party = GetBattlerParty(battler); struct Pokemon *party = GetBattlerParty(battler);
u32 size = 0; u32 size = 0;
u8 monToCheck; u8 monToCheck;
@ -2361,10 +2367,9 @@ void BtlController_HandleGetMonData(void)
BattleControllerComplete(battler); BattleControllerComplete(battler);
} }
void BtlController_HandleGetRawMonData(void) void BtlController_HandleGetRawMonData(u32 battler)
{ {
struct BattlePokemon battleMon; struct BattlePokemon battleMon;
u32 battler = gActiveBattler;
struct Pokemon *party = GetBattlerParty(battler); struct Pokemon *party = GetBattlerParty(battler);
u8 *src = (u8 *)&party[gBattlerPartyIndexes[battler]] + gBattleResources->bufferA[battler][1]; u8 *src = (u8 *)&party[gBattlerPartyIndexes[battler]] + gBattleResources->bufferA[battler][1];
@ -2378,9 +2383,8 @@ void BtlController_HandleGetRawMonData(void)
BattleControllerComplete(battler); BattleControllerComplete(battler);
} }
void BtlController_HandleSetMonData(void) void BtlController_HandleSetMonData(u32 battler)
{ {
u32 battler = gActiveBattler;
struct Pokemon *party = GetBattlerParty(battler); struct Pokemon *party = GetBattlerParty(battler);
u32 i, monToCheck; u32 i, monToCheck;
@ -2401,10 +2405,9 @@ void BtlController_HandleSetMonData(void)
BattleControllerComplete(battler); BattleControllerComplete(battler);
} }
void BtlController_HandleSetRawMonData(void) void BtlController_HandleSetRawMonData(u32 battler)
{ {
u32 i; u32 i;
u32 battler = gActiveBattler;
struct Pokemon *party = GetBattlerParty(battler); struct Pokemon *party = GetBattlerParty(battler);
u8 *dst = (u8 *)&party[gBattlerPartyIndexes[battler]] + gBattleResources->bufferA[battler][1]; u8 *dst = (u8 *)&party[gBattlerPartyIndexes[battler]] + gBattleResources->bufferA[battler][1];
@ -2414,7 +2417,7 @@ void BtlController_HandleSetRawMonData(void)
BattleControllerComplete(battler); BattleControllerComplete(battler);
} }
void BtlController_HandleLoadMonSprite(u32 battler, struct Pokemon *party, void (*controllerCallback)(void)) void BtlController_HandleLoadMonSprite(u32 battler, struct Pokemon *party, void (*controllerCallback)(u32 battler))
{ {
u16 species = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES); u16 species = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES);
@ -2437,7 +2440,7 @@ void BtlController_HandleLoadMonSprite(u32 battler, struct Pokemon *party, void
gBattlerControllerFuncs[battler] = controllerCallback; gBattlerControllerFuncs[battler] = controllerCallback;
} }
void BtlController_HandleSwitchInAnim(u32 battler, bool32 isPlayerSide, void (*controllerCallback)(void)) void BtlController_HandleSwitchInAnim(u32 battler, bool32 isPlayerSide, void (*controllerCallback)(u32 battler))
{ {
if (isPlayerSide) if (isPlayerSide)
ClearTemporarySpeciesSpriteData(battler, gBattleResources->bufferA[battler][2]); ClearTemporarySpeciesSpriteData(battler, gBattleResources->bufferA[battler][2]);
@ -2448,17 +2451,17 @@ void BtlController_HandleSwitchInAnim(u32 battler, bool32 isPlayerSide, void (*c
gBattlerControllerFuncs[battler] = controllerCallback; gBattlerControllerFuncs[battler] = controllerCallback;
} }
void BtlController_HandleReturnMonToBall(void) void BtlController_HandleReturnMonToBall(u32 battler)
{ {
if (gBattleResources->bufferA[gActiveBattler][1] == 0) if (gBattleResources->bufferA[battler][1] == 0)
{ {
gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0;
gBattlerControllerFuncs[gActiveBattler] = Controller_ReturnMonToBall; gBattlerControllerFuncs[battler] = Controller_ReturnMonToBall;
} }
else else
{ {
FreeMonSprite(gActiveBattler); FreeMonSprite(battler);
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
} }
@ -2578,9 +2581,8 @@ void BtlController_HandleTrainerSlideBack(u32 battlerId, s16 data0, bool32 start
#define sSpeedX data[1] #define sSpeedX data[1]
#define sSpeedY data[2] #define sSpeedY data[2]
void BtlController_HandleFaintAnimation(void) void BtlController_HandleFaintAnimation(u32 battler)
{ {
u32 battler = gActiveBattler;
if (gBattleSpritesDataPtr->healthBoxesData[battler].animationState == 0) if (gBattleSpritesDataPtr->healthBoxesData[battler].animationState == 0)
{ {
if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
@ -2711,92 +2713,92 @@ void DoStatusIconUpdate(u32 battler)
gBattlerControllerFuncs[battler] = Controller_WaitForStatusAnimation; gBattlerControllerFuncs[battler] = Controller_WaitForStatusAnimation;
} }
void BtlController_HandleStatusIconUpdate(void) void BtlController_HandleStatusIconUpdate(u32 battler)
{ {
if (!IsBattleSEPlaying(gActiveBattler)) if (!IsBattleSEPlaying(battler))
{ {
DoStatusIconUpdate(gActiveBattler); DoStatusIconUpdate(battler);
} }
} }
void BtlController_HandleStatusAnimation(void) void BtlController_HandleStatusAnimation(u32 battler)
{ {
if (!IsBattleSEPlaying(gActiveBattler)) if (!IsBattleSEPlaying(battler))
{ {
InitAndLaunchChosenStatusAnimation(gBattleResources->bufferA[gActiveBattler][1], InitAndLaunchChosenStatusAnimation(gBattleResources->bufferA[battler][1],
gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8) | (gBattleResources->bufferA[gActiveBattler][4] << 16) | (gBattleResources->bufferA[gActiveBattler][5] << 24)); gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8) | (gBattleResources->bufferA[battler][4] << 16) | (gBattleResources->bufferA[battler][5] << 24));
gBattlerControllerFuncs[gActiveBattler] = Controller_WaitForStatusAnimation; gBattlerControllerFuncs[battler] = Controller_WaitForStatusAnimation;
} }
} }
void BtlController_HandleClearUnkVar(void) void BtlController_HandleClearUnkVar(u32 battler)
{ {
gUnusedControllerStruct.unk = 0; gUnusedControllerStruct.unk = 0;
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
void BtlController_HandleSetUnkVar(void) void BtlController_HandleSetUnkVar(u32 battler)
{ {
gUnusedControllerStruct.unk = gBattleResources->bufferA[gActiveBattler][1]; gUnusedControllerStruct.unk = gBattleResources->bufferA[battler][1];
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
void BtlController_HandleClearUnkFlag(void) void BtlController_HandleClearUnkFlag(u32 battler)
{ {
gUnusedControllerStruct.flag = 0; gUnusedControllerStruct.flag = 0;
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
void BtlController_HandleToggleUnkFlag(void) void BtlController_HandleToggleUnkFlag(u32 battler)
{ {
gUnusedControllerStruct.flag ^= 1; gUnusedControllerStruct.flag ^= 1;
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
void BtlController_HandleHitAnimation(void) void BtlController_HandleHitAnimation(u32 battler)
{ {
if (gSprites[gBattlerSpriteIds[gActiveBattler]].invisible == TRUE) if (gSprites[gBattlerSpriteIds[battler]].invisible == TRUE)
{ {
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
else else
{ {
gDoingBattleAnim = TRUE; gDoingBattleAnim = TRUE;
gSprites[gBattlerSpriteIds[gActiveBattler]].data[1] = 0; gSprites[gBattlerSpriteIds[battler]].data[1] = 0;
DoHitAnimHealthboxEffect(gActiveBattler); DoHitAnimHealthboxEffect(battler);
gBattlerControllerFuncs[gActiveBattler] = Controller_HitAnimation; gBattlerControllerFuncs[battler] = Controller_HitAnimation;
} }
} }
void BtlController_HandlePlaySE(void) void BtlController_HandlePlaySE(u32 battler)
{ {
s8 pan = (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) ? SOUND_PAN_ATTACKER : SOUND_PAN_TARGET; s8 pan = (GetBattlerSide(battler) == B_SIDE_PLAYER) ? SOUND_PAN_ATTACKER : SOUND_PAN_TARGET;
PlaySE12WithPanning(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8), pan); PlaySE12WithPanning(gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8), pan);
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
void BtlController_HandlePlayFanfareOrBGM(void) void BtlController_HandlePlayFanfareOrBGM(u32 battler)
{ {
if (gBattleResources->bufferA[gActiveBattler][3]) if (gBattleResources->bufferA[battler][3])
{ {
BattleStopLowHpSound(); BattleStopLowHpSound();
PlayBGM(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); PlayBGM(gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8));
} }
else else
{ {
PlayFanfare(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); PlayFanfare(gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8));
} }
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
void BtlController_HandleFaintingCry(void) void BtlController_HandleFaintingCry(u32 battler)
{ {
struct Pokemon *party; struct Pokemon *party;
s8 pan; s8 pan;
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) if (GetBattlerSide(battler) == B_SIDE_PLAYER)
{ {
party = gPlayerParty; party = gPlayerParty;
pan = -25; pan = -25;
@ -2807,25 +2809,25 @@ void BtlController_HandleFaintingCry(void)
pan = 25; pan = 25;
} }
PlayCry_ByMode(GetMonData(&party[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES), pan, CRY_MODE_FAINT); PlayCry_ByMode(GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES), pan, CRY_MODE_FAINT);
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
void BtlController_HandleIntroSlide(void) void BtlController_HandleIntroSlide(u32 battler)
{ {
HandleIntroSlide(gBattleResources->bufferA[gActiveBattler][1]); HandleIntroSlide(gBattleResources->bufferA[battler][1]);
gIntroSlideFlags |= 1; gIntroSlideFlags |= 1;
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
void BtlController_HandleSpriteInvisibility(void) void BtlController_HandleSpriteInvisibility(u32 battler)
{ {
if (IsBattlerSpritePresent(gActiveBattler)) if (IsBattlerSpritePresent(battler))
{ {
gSprites[gBattlerSpriteIds[gActiveBattler]].invisible = gBattleResources->bufferA[gActiveBattler][1]; gSprites[gBattlerSpriteIds[battler]].invisible = gBattleResources->bufferA[battler][1];
CopyBattleSpriteInvisibility(gActiveBattler); CopyBattleSpriteInvisibility(battler);
} }
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
bool32 TwoPlayerIntroMons(u32 battler) // Double battle with both player pokemon active. bool32 TwoPlayerIntroMons(u32 battler) // Double battle with both player pokemon active.
@ -2850,7 +2852,7 @@ bool32 TwoOpponentIntroMons(u32 battler) // Double battle with both opponent pok
// Sprite data for SpriteCB_FreePlayerSpriteLoadMonSprite // Sprite data for SpriteCB_FreePlayerSpriteLoadMonSprite
#define sBattlerId data[5] #define sBattlerId data[5]
void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, const u32 *trainerPal, s16 framesToWait, void (*controllerCallback)(void)) void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, const u32 *trainerPal, s16 framesToWait, void (*controllerCallback)(u32 battler))
{ {
u8 paletteNum, taskId; u8 paletteNum, taskId;
u32 side = GetBattlerSide(battler); u32 side = GetBattlerSide(battler);
@ -2863,8 +2865,8 @@ void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, c
} }
else else
{ {
gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35; gSprites[gBattlerSpriteIds[battler]].data[0] = 35;
gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = 280; gSprites[gBattlerSpriteIds[battler]].data[2] = 280;
} }
gSprites[gBattlerSpriteIds[battler]].data[4] = gSprites[gBattlerSpriteIds[battler]].y; gSprites[gBattlerSpriteIds[battler]].data[4] = gSprites[gBattlerSpriteIds[battler]].y;
@ -3014,11 +3016,11 @@ void BtlController_HandleDrawPartyStatusSummary(u32 battler, u32 side, bool32 co
} }
} }
void BtlController_HandleHidePartyStatusSummary(void) void BtlController_HandleHidePartyStatusSummary(u32 battler)
{ {
if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) if (gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusSummaryShown)
gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; gTasks[gBattlerStatusSummaryTaskId[battler]].func = Task_HidePartyStatusSummary;
BattleControllerComplete(gActiveBattler); BattleControllerComplete(battler);
} }
void BtlController_HandleBattleAnimation(u32 battler, bool32 ignoreSE, bool32 updateTvData) void BtlController_HandleBattleAnimation(u32 battler, bool32 ignoreSE, bool32 updateTvData)

View File

@ -249,11 +249,9 @@ void (*gPreBattleCallback1)(void);
void (*gBattleMainFunc)(void); void (*gBattleMainFunc)(void);
struct BattleResults gBattleResults; struct BattleResults gBattleResults;
u8 gLeveledUpInBattle; u8 gLeveledUpInBattle;
void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void);
u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT];
u8 gMultiUsePlayerCursor; u8 gMultiUsePlayerCursor;
u8 gNumberOfMovesToChoose; u8 gNumberOfMovesToChoose;
u8 gBattleControllerData[MAX_BATTLERS_COUNT]; // Used by the battle controllers to store misc sprite/task IDs for each battler
static const struct ScanlineEffectParams sIntroScanlineParams16Bit = static const struct ScanlineEffectParams sIntroScanlineParams16Bit =
{ {
@ -3076,7 +3074,7 @@ static void BattleMainCB1(void)
gBattleMainFunc(); gBattleMainFunc();
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
gBattlerControllerFuncs[gActiveBattler](); gBattlerControllerFuncs[gActiveBattler](gActiveBattler);
} }
static void BattleStartClearSetData(void) static void BattleStartClearSetData(void)

View File

@ -37,6 +37,7 @@ gReservedSpritePaletteCount:
.include "link_rfu_2.o" .include "link_rfu_2.o"
.include "rtc.o" .include "rtc.o"
.include "battle_main.o" .include "battle_main.o"
.include "battle_controllers.o"
.include "random.o" .include "random.o"
.include "load_save.o" .include "load_save.o"
.include "berry_blender.o" .include "berry_blender.o"