diff --git a/common_syms/battle_controllers.txt b/common_syms/battle_controllers.txt new file mode 100644 index 000000000..0b3c25266 --- /dev/null +++ b/common_syms/battle_controllers.txt @@ -0,0 +1,3 @@ +gBattlerControllerFuncs +gBattleControllerData +gBattlerControllerEndFuncs diff --git a/common_syms/battle_main.txt b/common_syms/battle_main.txt index f6f02c48d..7a9faa5a1 100644 --- a/common_syms/battle_main.txt +++ b/common_syms/battle_main.txt @@ -2,8 +2,6 @@ gPreBattleCallback1 gBattleMainFunc gBattleResults gLeveledUpInBattle -gBattlerControllerFuncs gHealthboxSpriteIds gMultiUsePlayerCursor gNumberOfMovesToChoose -gBattleControllerData diff --git a/include/battle.h b/include/battle.h index 131f192e9..1fe0ed4ef 100644 --- a/include/battle.h +++ b/include/battle.h @@ -1002,11 +1002,9 @@ extern void (*gPreBattleCallback1)(void); extern void (*gBattleMainFunc)(void); extern struct BattleResults gBattleResults; extern u8 gLeveledUpInBattle; -extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); extern u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; extern u8 gMultiUsePlayerCursor; extern u8 gNumberOfMovesToChoose; -extern u8 gBattleControllerData[MAX_BATTLERS_COUNT]; extern bool8 gHasFetchedBall; extern u8 gLastUsedBall; extern u16 gLastThrownBall; diff --git a/include/battle_controllers.h b/include/battle_controllers.h index e1ab98b0c..ff4a8c6e5 100644 --- a/include/battle_controllers.h +++ b/include/battle_controllers.h @@ -197,6 +197,9 @@ enum }; extern struct UnusedControllerStruct gUnusedControllerStruct; +extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(u32 battler); +extern void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(u32 battler); +extern u8 gBattleControllerData[MAX_BATTLERS_COUNT]; // general functions void HandleLinkBattleSetup(void); @@ -251,43 +254,88 @@ void BtlController_EmitResetActionMoveSelection(u8 bufferId, u8 caseId); void BtlController_EmitEndLinkBattle(u8 bufferId, u8 battleOutcome); void BtlController_EmitDebugMenu(u8 bufferId); +void BattleControllerComplete(u32 battler); // Can be used for all the controllers. +void BtlController_Empty(u32 battler); // Empty command, does nothing, only completes the execution. +void BtlController_TerminatorNop(u32 battler); // Dummy function at the end of the table. +void BattleControllerDummy(u32 battler); +void StartSendOutAnim(u32 battler, bool32 dontClearSubstituteBit); +void Controller_WaitForString(u32 battler); +void Controller_WaitForHealthBar(u32 battler); + +// handlers +void BtlController_HandleGetMonData(u32 battler); +void BtlController_HandleGetRawMonData(u32 battler); +void BtlController_HandleSetMonData(u32 battler); +void BtlController_HandleSetRawMonData(u32 battler); +void BtlController_HandleLoadMonSprite(u32 battler, void (*controllerCallback)(u32 battler)); +void BtlController_HandleSwitchInAnim(u32 battler, bool32 isPlayerSide, void (*controllerCallback)(u32 battler)); +void BtlController_HandleReturnMonToBall(u32 battler); +void BtlController_HandleDrawTrainerPic(u32 battlerId, u32 trainerPicId, bool32 isFrontPic, s16 xPos, s16 yPos, s32 subpriority); +void BtlController_HandleTrainerSlide(u32 battler, u32 trainerPicId); +void BtlController_HandleTrainerSlideBack(u32 battlerId, s16 data0, bool32 startAnim); +void BtlController_HandleFaintAnimation(u32 battler); +void BtlController_HandleSuccessBallThrowAnim(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_HandlePrintString(u32 battler, bool32 updateTvData, bool32 arenaPtsDeduct); +void BtlController_HandleHealthBarUpdate(u32 battler, bool32 updateHpText); +void DoStatusIconUpdate(u32 battler); +void BtlController_HandleStatusIconUpdate(u32 battler); +void BtlController_HandleStatusAnimation(u32 battler); +void BtlController_HandleClearUnkVar(u32 battler); +void BtlController_HandleSetUnkVar(u32 battler); +void BtlController_HandleClearUnkFlag(u32 battler); +void BtlController_HandleToggleUnkFlag(u32 battler); +void BtlController_HandleHitAnimation(u32 battler); +void BtlController_HandlePlaySE(u32 battler); +void BtlController_HandlePlayFanfareOrBGM(u32 battler); +void BtlController_HandleFaintingCry(u32 battler); +void BtlController_HandleIntroSlide(u32 battler); +void BtlController_HandleSpriteInvisibility(u32 battler); +bool32 TwoPlayerIntroMons(u32 battlerId); // Double battle with both player 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)(u32 battler)); +void BtlController_HandleDrawPartyStatusSummary(u32 battler, u32 side, bool32 considerDelay); +void BtlController_HandleHidePartyStatusSummary(u32 battler); +void BtlController_HandleBattleAnimation(u32 battler, bool32 ignoreSE, bool32 updateTvData); + // player controller -void SetControllerToPlayer(void); -void BattleControllerDummy(void); -void PlayerHandleGetRawMonData(void); -void SetBattleEndCallbacks(void); -void SpriteCB_FreePlayerSpriteLoadMonSprite(struct Sprite *sprite); +void SetControllerToPlayer(u32 battler); +void SetBattleEndCallbacks(u32 battler); +void PlayerHandleExpUpdate(u32 battler); +u32 LinkPlayerGetTrainerPicId(u32 multiplayerId); void CB2_SetUpReshowBattleScreenAfterMenu(void); void CB2_SetUpReshowBattleScreenAfterMenu2(void); void Task_PlayerController_RestoreBgmAfterCry(u8 taskId); void ActionSelectionCreateCursorAt(u8 cursorPos, u8 unused); void ActionSelectionDestroyCursorAt(u8 cursorPos); -void InitMoveSelectionsVarsAndStrings(void); +void InitMoveSelectionsVarsAndStrings(u32 battler); void MoveSelectionCreateCursorAt(u8 cursorPos, u8 arg1); void MoveSelectionDestroyCursorAt(u8 cursorPosition); // recorded player controller -void SetControllerToRecordedPlayer(void); +void SetControllerToRecordedPlayer(u32 battler); // opponent controller -void SetControllerToOpponent(void); +void SetControllerToOpponent(u32 battler); // player partner controller -void SetControllerToPlayerPartner(void); +void Controller_PlayerPartnerShowIntroHealthbox(u32 battler); // Also used by the link partner. +void SetControllerToPlayerPartner(u32 battler); // safari controller -void SetControllerToSafari(void); +void SetControllerToSafari(u32 battler); // wally controller -void SetControllerToWally(void); +void SetControllerToWally(u32 battler); // recorded opponent controller -void SetControllerToRecordedOpponent(void); +void SetControllerToRecordedOpponent(u32 battler); // link opponent -void SetControllerToLinkOpponent(void); +void SetControllerToLinkOpponent(u32 battler); // link partner -void SetControllerToLinkPartner(void); +void SetControllerToLinkPartner(u32 battler); #endif // GUARD_BATTLE_CONTROLLERS_H diff --git a/include/battle_dome.h b/include/battle_dome.h index 900508c4b..b7572451c 100644 --- a/include/battle_dome.h +++ b/include/battle_dome.h @@ -1,8 +1,6 @@ #ifndef GUARD_BATTLE_DOME_H #define GUARD_BATTLE_DOME_H -extern u32 gPlayerPartyLostHP; - int GetDomeTrainerSelectedMons(u16 tournamentTrainerId); int TrainerIdToDomeTournamentId(u16 trainerId); diff --git a/include/battle_gfx_sfx_util.h b/include/battle_gfx_sfx_util.h index 0b1bd52fb..794447446 100644 --- a/include/battle_gfx_sfx_util.h +++ b/include/battle_gfx_sfx_util.h @@ -10,12 +10,10 @@ void InitAndLaunchChosenStatusAnimation(bool8 isStatus2, u32 status); bool8 TryHandleLaunchBattleTableAnimation(u8 activeBattlerId, u8 attacker, u8 target, u8 tableId, u16 argument); void InitAndLaunchSpecialAnimation(u8 activeBattlerId, u8 attacker, u8 target, u8 tableId); bool8 IsBattleSEPlaying(u8 battlerId); -void BattleLoadOpponentMonSpriteGfx(struct Pokemon *mon, u8 battlerId); -void BattleLoadPlayerMonSpriteGfx(struct Pokemon *mon, u8 battlerId); +void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId); void BattleGfxSfxDummy2(u16 species); void DecompressTrainerFrontPic(u16 frontPicId, u8 battlerId); void DecompressTrainerBackPic(u16 backPicId, u8 battlerId); -void BattleGfxSfxDummy3(u8 gender); void FreeTrainerFrontPicPalette(u16 frontPicId); bool8 BattleLoadAllHealthBoxesGfx(u8 state); void LoadBattleBarGfx(u8 unused); diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c index 69e2f6bde..4f1c3da97 100644 --- a/src/battle_controller_link_opponent.c +++ b/src/battle_controller_link_opponent.c @@ -29,205 +29,126 @@ #include "constants/trainers.h" #include "recorded_battle.h" -static void LinkOpponentHandleGetMonData(void); -static void LinkOpponentHandleGetRawMonData(void); -static void LinkOpponentHandleSetMonData(void); -static void LinkOpponentHandleSetRawMonData(void); -static void LinkOpponentHandleLoadMonSprite(void); -static void LinkOpponentHandleSwitchInAnim(void); -static void LinkOpponentHandleReturnMonToBall(void); -static void LinkOpponentHandleDrawTrainerPic(void); -static void LinkOpponentHandleTrainerSlide(void); -static void LinkOpponentHandleTrainerSlideBack(void); -static void LinkOpponentHandleFaintAnimation(void); -static void LinkOpponentHandlePaletteFade(void); -static void LinkOpponentHandleSuccessBallThrowAnim(void); -static void LinkOpponentHandleBallThrowAnim(void); -static void LinkOpponentHandlePause(void); -static void LinkOpponentHandleMoveAnimation(void); -static void LinkOpponentHandlePrintString(void); -static void LinkOpponentHandlePrintSelectionString(void); -static void LinkOpponentHandleChooseAction(void); -static void LinkOpponentHandleYesNoBox(void); -static void LinkOpponentHandleChooseMove(void); -static void LinkOpponentHandleChooseItem(void); -static void LinkOpponentHandleChoosePokemon(void); -static void LinkOpponentHandleCmd23(void); -static void LinkOpponentHandleHealthBarUpdate(void); -static void LinkOpponentHandleExpUpdate(void); -static void LinkOpponentHandleStatusIconUpdate(void); -static void LinkOpponentHandleStatusAnimation(void); -static void LinkOpponentHandleStatusXor(void); -static void LinkOpponentHandleDataTransfer(void); -static void LinkOpponentHandleDMA3Transfer(void); -static void LinkOpponentHandlePlayBGM(void); -static void LinkOpponentHandleCmd32(void); -static void LinkOpponentHandleTwoReturnValues(void); -static void LinkOpponentHandleChosenMonReturnValue(void); -static void LinkOpponentHandleOneReturnValue(void); -static void LinkOpponentHandleOneReturnValue_Duplicate(void); -static void LinkOpponentHandleClearUnkVar(void); -static void LinkOpponentHandleSetUnkVar(void); -static void LinkOpponentHandleClearUnkFlag(void); -static void LinkOpponentHandleToggleUnkFlag(void); -static void LinkOpponentHandleHitAnimation(void); -static void LinkOpponentHandleCantSwitch(void); -static void LinkOpponentHandlePlaySE(void); -static void LinkOpponentHandlePlayFanfareOrBGM(void); -static void LinkOpponentHandleFaintingCry(void); -static void LinkOpponentHandleIntroSlide(void); -static void LinkOpponentHandleIntroTrainerBallThrow(void); -static void LinkOpponentHandleDrawPartyStatusSummary(void); -static void LinkOpponentHandleHidePartyStatusSummary(void); -static void LinkOpponentHandleEndBounceEffect(void); -static void LinkOpponentHandleSpriteInvisibility(void); -static void LinkOpponentHandleBattleAnimation(void); -static void LinkOpponentHandleLinkStandbyMsg(void); -static void LinkOpponentHandleResetActionMoveSelection(void); -static void LinkOpponentHandleEndLinkBattle(void); -static void LinkOpponentHandleBattleDebug(void); -static void LinkOpponentCmdEnd(void); +static void LinkOpponentHandleLoadMonSprite(u32 battler); +static void LinkOpponentHandleSwitchInAnim(u32 battler); +static void LinkOpponentHandleDrawTrainerPic(u32 battler); +static void LinkOpponentHandleTrainerSlide(u32 battler); +static void LinkOpponentHandleTrainerSlideBack(u32 battler); +static void LinkOpponentHandleMoveAnimation(u32 battler); +static void LinkOpponentHandlePrintString(u32 battler); +static void LinkOpponentHandleHealthBarUpdate(u32 battler); +static void LinkOpponentHandleIntroTrainerBallThrow(u32 battler); +static void LinkOpponentHandleDrawPartyStatusSummary(u32 battler); +static void LinkOpponentHandleBattleAnimation(u32 battler); +static void LinkOpponentHandleLinkStandbyMsg(u32 battler); +static void LinkOpponentHandleEndLinkBattle(u32 battler); -static void LinkOpponentBufferRunCommand(void); -static void LinkOpponentBufferExecCompleted(void); -static void SwitchIn_HandleSoundAndEnd(void); -static u32 CopyLinkOpponentMonData(u8 monId, u8 *dst); -static void SetLinkOpponentMonData(u8 monId); -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit); -static void DoSwitchOutAnimation(void); -static void LinkOpponentDoMoveAnimation(void); -static void Task_StartSendOutAnim(u8 taskId); -static void SpriteCB_FreeOpponentSprite(struct Sprite *sprite); -static void EndDrawPartyStatusSummary(void); +static void LinkOpponentBufferRunCommand(u32 battler); +static void LinkOpponentBufferExecCompleted(u32 battler); +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] = LinkOpponentHandleGetMonData, - [CONTROLLER_GETRAWMONDATA] = LinkOpponentHandleGetRawMonData, - [CONTROLLER_SETMONDATA] = LinkOpponentHandleSetMonData, - [CONTROLLER_SETRAWMONDATA] = LinkOpponentHandleSetRawMonData, + [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, + [CONTROLLER_GETRAWMONDATA] = BtlController_Empty, + [CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, + [CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData, [CONTROLLER_LOADMONSPRITE] = LinkOpponentHandleLoadMonSprite, [CONTROLLER_SWITCHINANIM] = LinkOpponentHandleSwitchInAnim, - [CONTROLLER_RETURNMONTOBALL] = LinkOpponentHandleReturnMonToBall, + [CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, [CONTROLLER_DRAWTRAINERPIC] = LinkOpponentHandleDrawTrainerPic, [CONTROLLER_TRAINERSLIDE] = LinkOpponentHandleTrainerSlide, [CONTROLLER_TRAINERSLIDEBACK] = LinkOpponentHandleTrainerSlideBack, - [CONTROLLER_FAINTANIMATION] = LinkOpponentHandleFaintAnimation, - [CONTROLLER_PALETTEFADE] = LinkOpponentHandlePaletteFade, - [CONTROLLER_SUCCESSBALLTHROWANIM] = LinkOpponentHandleSuccessBallThrowAnim, - [CONTROLLER_BALLTHROWANIM] = LinkOpponentHandleBallThrowAnim, - [CONTROLLER_PAUSE] = LinkOpponentHandlePause, + [CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, + [CONTROLLER_PALETTEFADE] = BtlController_Empty, + [CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty, + [CONTROLLER_BALLTHROWANIM] = BtlController_Empty, + [CONTROLLER_PAUSE] = BtlController_Empty, [CONTROLLER_MOVEANIMATION] = LinkOpponentHandleMoveAnimation, [CONTROLLER_PRINTSTRING] = LinkOpponentHandlePrintString, - [CONTROLLER_PRINTSTRINGPLAYERONLY] = LinkOpponentHandlePrintSelectionString, - [CONTROLLER_CHOOSEACTION] = LinkOpponentHandleChooseAction, - [CONTROLLER_YESNOBOX] = LinkOpponentHandleYesNoBox, - [CONTROLLER_CHOOSEMOVE] = LinkOpponentHandleChooseMove, - [CONTROLLER_OPENBAG] = LinkOpponentHandleChooseItem, - [CONTROLLER_CHOOSEPOKEMON] = LinkOpponentHandleChoosePokemon, - [CONTROLLER_23] = LinkOpponentHandleCmd23, + [CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty, + [CONTROLLER_CHOOSEACTION] = BtlController_Empty, + [CONTROLLER_YESNOBOX] = BtlController_Empty, + [CONTROLLER_CHOOSEMOVE] = BtlController_Empty, + [CONTROLLER_OPENBAG] = BtlController_Empty, + [CONTROLLER_CHOOSEPOKEMON] = BtlController_Empty, + [CONTROLLER_23] = BtlController_Empty, [CONTROLLER_HEALTHBARUPDATE] = LinkOpponentHandleHealthBarUpdate, - [CONTROLLER_EXPUPDATE] = LinkOpponentHandleExpUpdate, - [CONTROLLER_STATUSICONUPDATE] = LinkOpponentHandleStatusIconUpdate, - [CONTROLLER_STATUSANIMATION] = LinkOpponentHandleStatusAnimation, - [CONTROLLER_STATUSXOR] = LinkOpponentHandleStatusXor, - [CONTROLLER_DATATRANSFER] = LinkOpponentHandleDataTransfer, - [CONTROLLER_DMA3TRANSFER] = LinkOpponentHandleDMA3Transfer, - [CONTROLLER_PLAYBGM] = LinkOpponentHandlePlayBGM, - [CONTROLLER_32] = LinkOpponentHandleCmd32, - [CONTROLLER_TWORETURNVALUES] = LinkOpponentHandleTwoReturnValues, - [CONTROLLER_CHOSENMONRETURNVALUE] = LinkOpponentHandleChosenMonReturnValue, - [CONTROLLER_ONERETURNVALUE] = LinkOpponentHandleOneReturnValue, - [CONTROLLER_ONERETURNVALUE_DUPLICATE] = LinkOpponentHandleOneReturnValue_Duplicate, - [CONTROLLER_CLEARUNKVAR] = LinkOpponentHandleClearUnkVar, - [CONTROLLER_SETUNKVAR] = LinkOpponentHandleSetUnkVar, - [CONTROLLER_CLEARUNKFLAG] = LinkOpponentHandleClearUnkFlag, - [CONTROLLER_TOGGLEUNKFLAG] = LinkOpponentHandleToggleUnkFlag, - [CONTROLLER_HITANIMATION] = LinkOpponentHandleHitAnimation, - [CONTROLLER_CANTSWITCH] = LinkOpponentHandleCantSwitch, - [CONTROLLER_PLAYSE] = LinkOpponentHandlePlaySE, - [CONTROLLER_PLAYFANFAREORBGM] = LinkOpponentHandlePlayFanfareOrBGM, - [CONTROLLER_FAINTINGCRY] = LinkOpponentHandleFaintingCry, - [CONTROLLER_INTROSLIDE] = LinkOpponentHandleIntroSlide, + [CONTROLLER_EXPUPDATE] = BtlController_Empty, + [CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate, + [CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation, + [CONTROLLER_STATUSXOR] = BtlController_Empty, + [CONTROLLER_DATATRANSFER] = BtlController_Empty, + [CONTROLLER_DMA3TRANSFER] = BtlController_Empty, + [CONTROLLER_PLAYBGM] = BtlController_Empty, + [CONTROLLER_32] = BtlController_Empty, + [CONTROLLER_TWORETURNVALUES] = BtlController_Empty, + [CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, + [CONTROLLER_CLEARUNKVAR] = BtlController_HandleClearUnkVar, + [CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar, + [CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag, + [CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag, + [CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, + [CONTROLLER_CANTSWITCH] = BtlController_Empty, + [CONTROLLER_PLAYSE] = BtlController_HandlePlaySE, + [CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, + [CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry, + [CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, [CONTROLLER_INTROTRAINERBALLTHROW] = LinkOpponentHandleIntroTrainerBallThrow, [CONTROLLER_DRAWPARTYSTATUSSUMMARY] = LinkOpponentHandleDrawPartyStatusSummary, - [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = LinkOpponentHandleHidePartyStatusSummary, - [CONTROLLER_ENDBOUNCE] = LinkOpponentHandleEndBounceEffect, - [CONTROLLER_SPRITEINVISIBILITY] = LinkOpponentHandleSpriteInvisibility, + [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary, + [CONTROLLER_ENDBOUNCE] = BtlController_Empty, + [CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility, [CONTROLLER_BATTLEANIMATION] = LinkOpponentHandleBattleAnimation, [CONTROLLER_LINKSTANDBYMSG] = LinkOpponentHandleLinkStandbyMsg, - [CONTROLLER_RESETACTIONMOVESELECTION] = LinkOpponentHandleResetActionMoveSelection, + [CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, [CONTROLLER_ENDLINKBATTLE] = LinkOpponentHandleEndLinkBattle, - [CONTROLLER_DEBUGMENU] = LinkOpponentHandleBattleDebug, - [CONTROLLER_TERMINATOR_NOP] = LinkOpponentCmdEnd + [CONTROLLER_DEBUGMENU] = BtlController_Empty, + [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop }; -static void LinkOpponentDummy(void) +void SetControllerToLinkOpponent(u32 battler) { + gBattlerControllerEndFuncs[battler] = LinkOpponentBufferExecCompleted; + gBattlerControllerFuncs[battler] = LinkOpponentBufferRunCommand; } -void SetControllerToLinkOpponent(void) +static void LinkOpponentBufferRunCommand(u32 battler) { - gBattlerControllerFuncs[gActiveBattler] = LinkOpponentBufferRunCommand; -} - -static void LinkOpponentBufferRunCommand(void) -{ - if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) + if (gBattleControllerExecFlags & gBitTable[battler]) { - if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sLinkOpponentBufferCommands)) - sLinkOpponentBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); + if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sLinkOpponentBufferCommands)) + sLinkOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler); else - LinkOpponentBufferExecCompleted(); + LinkOpponentBufferExecCompleted(battler); } } -static void CompleteOnBattlerSpriteCallbackDummy(void) +static void Intro_DelayAndEnd(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - LinkOpponentBufferExecCompleted(); -} - -static void CompleteOnBankSpriteCallbackDummy2(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - LinkOpponentBufferExecCompleted(); -} - -static void FreeTrainerSpriteAfterSlide(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (--gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay == (u8)-1) { - FreeTrainerFrontPicPalette(gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam); - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - LinkOpponentBufferExecCompleted(); + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0; + LinkOpponentBufferExecCompleted(battler); } } -static void Intro_DelayAndEnd(void) -{ - if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == (u8)-1) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; - LinkOpponentBufferExecCompleted(); - } -} - -static void Intro_WaitForShinyAnimAndHealthbox(void) +static void Intro_WaitForShinyAnimAndHealthbox(u32 battler) { bool32 healthboxAnimDone = FALSE; bool32 twoMons = FALSE; if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) healthboxAnimDone = TRUE; } else { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy) { healthboxAnimDone = TRUE; } @@ -236,88 +157,87 @@ static void Intro_WaitForShinyAnimAndHealthbox(void) 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; - if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) + if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim) return; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); } else { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim) return; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = 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); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); } } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; - gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3; + gBattlerControllerFuncs[battler] = Intro_DelayAndEnd; } } -static void Intro_TryShinyAnimShowHealthbox(void) +static void Intro_TryShinyAnimShowHealthbox(u32 battler) { bool32 bgmRestored = FALSE; - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive + && !gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim) { - TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]); } if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim + && !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)) { - UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); - StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL); + StartHealthboxSlideIn(BATTLE_PARTNER(battler)); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]); } - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gEnemyParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = TRUE; + gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = TRUE; } - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].waitForCry - && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].waitForCry + if (!gBattleSpritesDataPtr->healthBoxesData[battler].waitForCry + && gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].waitForCry && !IsCryPlayingOrClearCrySongs()) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored) { 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); } else @@ -326,937 +246,189 @@ static void Intro_TryShinyAnimShowHealthbox(void) } } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = TRUE; + gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = TRUE; bgmRestored = TRUE; } if (bgmRestored) { - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gBattleControllerData[battler]].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; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0; } if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { - DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); - SetBattlerShadowSpriteCallback(BATTLE_PARTNER(gActiveBattler), GetMonData(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], MON_DATA_SPECIES)); + DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]]); + SetBattlerShadowSpriteCallback(BATTLE_PARTNER(battler), GetMonData(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], MON_DATA_SPECIES)); } - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + DestroySprite(&gSprites[gBattleControllerData[battler]]); + SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES)); gBattleSpritesDataPtr->animationData->introAnimActive = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = 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 - && gSprites[gBattlerSpriteIds[gActiveBattler]].x2 == 0) + if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy + && 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[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); - LinkOpponentBufferExecCompleted(); + LinkOpponentBufferExecCompleted(battler); } } } -static void CompleteOnHealthbarDone(void) +static void SwitchIn_ShowSubstitute(u32 battler) { - s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0); - - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - - if (hpValue != -1) - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); - else - LinkOpponentBufferExecCompleted(); -} - -static void HideHealthboxAfterMonFaint(void) -{ - if (!gSprites[gBattlerSpriteIds[gActiveBattler]].inUse) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) { - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - LinkOpponentBufferExecCompleted(); + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE); + + gBattlerControllerFuncs[battler] = SwitchIn_HandleSoundAndEnd; } } -static void FreeMonSpriteAfterSwitchOutAnim(void) +static void SwitchIn_HandleSoundAndEnd(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive && !IsCryPlayingOrClearCrySongs()) { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - HideBattlerShadowSprite(gActiveBattler); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - LinkOpponentBufferExecCompleted(); - } -} - -static void CompleteOnInactiveTextPrinter(void) -{ - if (!IsTextPrinterActive(B_WIN_MSG)) - LinkOpponentBufferExecCompleted(); -} - -static void DoHitAnimBlinkSpriteEffect(void) -{ - u8 spriteId = gBattlerSpriteIds[gActiveBattler]; - - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = FALSE; - LinkOpponentBufferExecCompleted(); - } - else - { - if ((gSprites[spriteId].data[1] % 4) == 0) - gSprites[spriteId].invisible ^= 1; - gSprites[spriteId].data[1]++; - } -} - -static void SwitchIn_ShowSubstitute(void) -{ - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_HandleSoundAndEnd; - } -} - -static void SwitchIn_HandleSoundAndEnd(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive && !IsCryPlayingOrClearCrySongs()) - { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - || gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy_2) + if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy + || gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy_2) { 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 - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(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); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - CopyBattleSpriteInvisibility(gActiveBattler); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowSubstitute; + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gEnemyParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); + CopyBattleSpriteInvisibility(battler); + gBattlerControllerFuncs[battler] = SwitchIn_ShowSubstitute; } } -static void SwitchIn_TryShinyAnim(void) +static void SwitchIn_TryShinyAnim(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive + && !gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim) { - TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]); } - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) { - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowHealthbox; + DestroySprite(&gSprites[gBattleControllerData[battler]]); + SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES)); + gBattlerControllerFuncs[battler] = SwitchIn_ShowHealthbox; } } -static void CompleteOnFinishedStatusAnimation(void) +static void LinkOpponentBufferExecCompleted(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive) - LinkOpponentBufferExecCompleted(); -} - -static void CompleteOnFinishedBattleAnimation(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive) - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentBufferExecCompleted(void) -{ - gBattlerControllerFuncs[gActiveBattler] = LinkOpponentBufferRunCommand; + gBattlerControllerFuncs[battler] = LinkOpponentBufferRunCommand; if (gBattleTypeFlags & BATTLE_TYPE_LINK) { u8 playerId = GetMultiplayerId(); PrepareBufferDataTransferLink(2, 4, &playerId); - gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; + gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP; } else { - gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; + gBattleControllerExecFlags &= ~gBitTable[battler]; } } -static void LinkOpponentHandleGetMonData(void) +static void LinkOpponentHandleLoadMonSprite(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 - u32 size = 0; - u8 monToCheck; - s32 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - size += CopyLinkOpponentMonData(gBattlerPartyIndexes[gActiveBattler], monData); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - size += CopyLinkOpponentMonData(i, monData + size); - monToCheck >>= 1; - } - } - BtlController_EmitDataTransfer(BUFFER_B, size, monData); - LinkOpponentBufferExecCompleted(); + BtlController_HandleLoadMonSprite(battler, TryShinyAnimAfterMonAnim); } -static u32 CopyLinkOpponentMonData(u8 monId, u8 *dst) +static void LinkOpponentHandleSwitchInAnim(u32 battler) { - struct BattlePokemon battleMon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - battleMon.species = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES); - battleMon.item = GetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM); - for (size = 0; size < MAX_MON_MOVES; size++) - { - battleMon.moves[size] = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + size); - battleMon.pp[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size); - } - battleMon.ppBonuses = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES); - battleMon.friendship = GetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP); - battleMon.experience = GetMonData(&gEnemyParty[monId], MON_DATA_EXP); - battleMon.hpIV = GetMonData(&gEnemyParty[monId], MON_DATA_HP_IV); - battleMon.attackIV = GetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV); - battleMon.defenseIV = GetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV); - battleMon.speedIV = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV); - battleMon.spAttackIV = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV); - battleMon.spDefenseIV = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV); - battleMon.personality = GetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY); - battleMon.status1 = GetMonData(&gEnemyParty[monId], MON_DATA_STATUS); - battleMon.level = GetMonData(&gEnemyParty[monId], MON_DATA_LEVEL); - battleMon.hp = GetMonData(&gEnemyParty[monId], MON_DATA_HP); - battleMon.maxHP = GetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP); - battleMon.attack = GetMonData(&gEnemyParty[monId], MON_DATA_ATK); - battleMon.defense = GetMonData(&gEnemyParty[monId], MON_DATA_DEF); - battleMon.speed = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED); - battleMon.spAttack = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK); - battleMon.spDefense = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF); - battleMon.abilityNum = GetMonData(&gEnemyParty[monId], MON_DATA_ABILITY_NUM); - battleMon.otId = GetMonData(&gEnemyParty[monId], MON_DATA_OT_ID); - battleMon.metLevel = GetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL); - GetMonData(&gEnemyParty[monId], MON_DATA_NICKNAME, nickname); - StringCopy_Nickname(battleMon.nickname, nickname); - GetMonData(&gEnemyParty[monId], MON_DATA_OT_NAME, battleMon.otName); - src = (u8 *)&battleMon; - for (size = 0; size < sizeof(battleMon); size++) - dst[size] = src[size]; - break; - case REQUEST_SPECIES_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_HELDITEM_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MOVES_PP_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - { - moveData.moves[size] = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES); - src = (u8 *)(&moveData); - for (size = 0; size < sizeof(moveData); size++) - dst[size] = src[size]; - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_PP_DATA_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - dst[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size); - dst[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES); - size++; - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE); - size = 1; - break; - case REQUEST_OTID_BATTLE: - data32 = GetMonData(&gEnemyParty[monId], MON_DATA_OT_ID); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_EXP_BATTLE: - data32 = GetMonData(&gEnemyParty[monId], MON_DATA_EXP); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_HP_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_HP_EV); - size = 1; - break; - case REQUEST_ATK_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_ATK_EV); - size = 1; - break; - case REQUEST_DEF_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_DEF_EV); - size = 1; - break; - case REQUEST_SPEED_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED_EV); - size = 1; - break; - case REQUEST_SPATK_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK_EV); - size = 1; - break; - case REQUEST_SPDEF_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_EV); - size = 1; - break; - case REQUEST_FRIENDSHIP_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP); - size = 1; - break; - case REQUEST_POKERUS_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_POKERUS); - size = 1; - break; - case REQUEST_MET_LOCATION_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_MET_LOCATION); - size = 1; - break; - case REQUEST_MET_LEVEL_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL); - size = 1; - break; - case REQUEST_MET_GAME_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_MET_GAME); - size = 1; - break; - case REQUEST_POKEBALL_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_POKEBALL); - size = 1; - break; - case REQUEST_ALL_IVS_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_HP_IV); - dst[1] = GetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV); - dst[2] = GetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV); - dst[3] = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV); - dst[4] = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV); - dst[5] = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV); - size = 6; - break; - case REQUEST_HP_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_HP_IV); - size = 1; - break; - case REQUEST_ATK_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV); - size = 1; - break; - case REQUEST_DEF_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV); - size = 1; - break; - case REQUEST_SPEED_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV); - size = 1; - break; - case REQUEST_SPATK_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV); - size = 1; - break; - case REQUEST_SPDEF_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV); - size = 1; - break; - case REQUEST_PERSONALITY_BATTLE: - data32 = GetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_CHECKSUM_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_CHECKSUM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_STATUS_BATTLE: - data32 = GetMonData(&gEnemyParty[monId], MON_DATA_STATUS); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_LEVEL_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_LEVEL); - size = 1; - break; - case REQUEST_HP_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MAX_HP_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_ATK_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_ATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_DEF_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_DEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPEED_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPATK_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPDEF_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_COOL_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_COOL); - size = 1; - break; - case REQUEST_BEAUTY_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY); - size = 1; - break; - case REQUEST_CUTE_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_CUTE); - size = 1; - break; - case REQUEST_SMART_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SMART); - size = 1; - break; - case REQUEST_TOUGH_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_TOUGH); - size = 1; - break; - case REQUEST_SHEEN_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SHEEN); - size = 1; - break; - case REQUEST_COOL_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_COOL_RIBBON); - size = 1; - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case REQUEST_CUTE_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case REQUEST_SMART_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SMART_RIBBON); - size = 1; - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - - return size; + BtlController_HandleSwitchInAnim(battler, FALSE, SwitchIn_TryShinyAnim); } -static void LinkOpponentHandleGetRawMonData(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleSetMonData(void) -{ - u8 monToCheck; - u8 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - SetLinkOpponentMonData(gBattlerPartyIndexes[gActiveBattler]); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - SetLinkOpponentMonData(i); - monToCheck >>= 1; - } - } - LinkOpponentBufferExecCompleted(); -} - -static void SetLinkOpponentMonData(u8 monId) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleResources->bufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleResources->bufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - { - u8 iv; - - SetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gEnemyParty[monId], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gEnemyParty[monId], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gEnemyParty[monId], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gEnemyParty[monId], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gEnemyParty[monId], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gEnemyParty[monId], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case REQUEST_SPECIES_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HELDITEM_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MOVES_PP_BATTLE: - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PP_DATA_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_PP1, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP2, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP3, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP4, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES, &gBattleResources->bufferA[gActiveBattler][7]); - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_OTID_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_OT_ID, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_EXP_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_EXP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HP_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_ATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_DEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_FRIENDSHIP_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKERUS_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_POKERUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LOCATION_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MET_LOCATION, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LEVEL_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_GAME_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MET_GAME, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKEBALL_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_POKEBALL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ALL_IVS_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][7]); - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][8]); - break; - case REQUEST_HP_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PERSONALITY_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CHECKSUM_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_CHECKSUM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_STATUS_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_STATUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_LEVEL_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MAX_HP_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_ATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_DEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_COOL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_CUTE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SMART, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_TOUGH, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SHEEN_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SHEEN, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_COOL_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_CUTE_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SMART_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_TOUGH_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - } -} - -static void LinkOpponentHandleSetRawMonData(void) -{ - u8 *dst = (u8 *)&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleResources->bufferA[gActiveBattler][1]; - u8 i; - - for (i = 0; i < gBattleResources->bufferA[gActiveBattler][2]; i++) - dst[i] = gBattleResources->bufferA[gActiveBattler][3 + i]; - - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleLoadMonSprite(void) -{ - u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(gActiveBattler)); - - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(gActiveBattler, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(gActiveBattler), - GetBattlerSpriteSubpriority(gActiveBattler)); - - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); - - SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - - gBattlerControllerFuncs[gActiveBattler] = TryShinyAnimAfterMonAnim; -} - -static void LinkOpponentHandleSwitchInAnim(void) -{ - gBattlerPartyIndexes[gActiveBattler] = gBattleResources->bufferA[gActiveBattler][1]; - StartSendOutAnim(gActiveBattler, gBattleResources->bufferA[gActiveBattler][2]); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_TryShinyAnim; -} - -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit) -{ - u16 species; - - ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit); - gBattlerPartyIndexes[battlerId] = gBattleResources->bufferA[battlerId][1]; - species = GetIllusionMonSpecies(battlerId); - if (species == SPECIES_NONE) - species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); - gBattleControllerData[battlerId] = CreateInvisibleSpriteWithCallback(SpriteCB_WaitForBattlerBallReleaseAnim); - BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battlerId)); - - gBattlerSpriteIds[battlerId] = CreateSprite( - &gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(battlerId), - GetBattlerSpriteSubpriority(battlerId)); - - gSprites[gBattleControllerData[battlerId]].data[1] = gBattlerSpriteIds[battlerId]; - gSprites[gBattleControllerData[battlerId]].data[2] = battlerId; - - gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId; - gSprites[gBattlerSpriteIds[battlerId]].data[2] = species; - gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId; - - StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], 0); - - gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE; - gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy; - - gSprites[gBattleControllerData[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_OPPONENT_SENDOUT); -} - -static void LinkOpponentHandleReturnMonToBall(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] == 0) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = DoSwitchOutAnimation; - } - else - { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - HideBattlerShadowSprite(gActiveBattler); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - LinkOpponentBufferExecCompleted(); - } -} - -static void DoSwitchOutAnimation(void) -{ - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SWITCH_OUT_OPPONENT_MON); - gBattlerControllerFuncs[gActiveBattler] = FreeMonSpriteAfterSwitchOutAnim; - } - break; - } -} - -#define sSpeedX data[0] - -static void LinkOpponentHandleDrawTrainerPic(void) +static void LinkOpponentHandleDrawTrainerPic(u32 battler) { s16 xPos; u32 trainerPicId; if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { - if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != 0) // second mon + if ((GetBattlerPosition(battler) & BIT_FLANK) != 0) // second mon xPos = 152; else // first mon xPos = 200; if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) { - if (gActiveBattler == B_POSITION_OPPONENT_LEFT) + if (battler == B_POSITION_OPPONENT_LEFT) trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); else trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B); } else { - if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_FIRE_RED - || (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_LEAF_GREEN) + if ((gLinkPlayers[GetBattlerMultiplayerId(battler)].version & 0xFF) == VERSION_FIRE_RED + || (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]; else trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_RED]; } - else if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_RUBY - || (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_SAPPHIRE) + else if ((gLinkPlayers[GetBattlerMultiplayerId(battler)].version & 0xFF) == VERSION_RUBY + || (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]; else trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_RS_BRENDAN]; } else { - trainerPicId = PlayerGenderToFrontTrainerPicId(gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender); + trainerPicId = PlayerGenderToFrontTrainerPicId(gLinkPlayers[GetBattlerMultiplayerId(battler)].gender); } } } @@ -1289,566 +461,77 @@ static void LinkOpponentHandleDrawTrainerPic(void) } } - DecompressTrainerFrontPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, - xPos, - (8 - gTrainerFrontPicCoords[trainerPicId].size) * 4 + 40, - GetBattlerSpriteSubpriority(gActiveBattler)); - - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = 2; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam = trainerPicId; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy; + BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, + xPos, 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicId].size), + -1); } -static void LinkOpponentHandleTrainerSlide(void) +static void LinkOpponentHandleTrainerSlide(u32 battler) { u32 trainerPicId; - if (gActiveBattler == 1) + if (battler == B_POSITION_OPPONENT_LEFT) trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); else trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B); - DecompressTrainerFrontPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, 176, (8 - gTrainerFrontPicCoords[trainerPicId].size) * 4 + 40, 0x1E); - - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = 96; - gSprites[gBattlerSpriteIds[gActiveBattler]].x += 32; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = -2; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam = trainerPicId; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBankSpriteCallbackDummy2; // this line is redundant, because LinkOpponentBufferExecCompleted changes the battle battlerId function - LinkOpponentBufferExecCompleted(); + BtlController_HandleTrainerSlide(battler, trainerPicId); + LinkOpponentBufferExecCompleted(battler); // Possibly a bug, because execution should be completed after the slide in finishes. See Controller_WaitForTrainerPic. } -#undef sSpeedX - -static void LinkOpponentHandleTrainerSlideBack(void) +static void LinkOpponentHandleTrainerSlideBack(u32 battler) { - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = 280; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCallbackDummy); - gBattlerControllerFuncs[gActiveBattler] = FreeTrainerSpriteAfterSlide; + BtlController_HandleTrainerSlideBack(battler, 35, FALSE); } -static void LinkOpponentHandleFaintAnimation(void) +static void LinkOpponentHandleMoveAnimation(u32 battler) { - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState == 0) - { - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState++; - } + BtlController_HandleMoveAnimation(battler, TRUE); +} + +static void LinkOpponentHandlePrintString(u32 battler) +{ + BtlController_HandlePrintString(battler, TRUE, FALSE); +} + +static void LinkOpponentHandleHealthBarUpdate(u32 battler) +{ + BtlController_HandleHealthBarUpdate(battler, FALSE); +} + +static void LinkOpponentHandleIntroTrainerBallThrow(u32 battler) +{ + BtlController_HandleIntroTrainerBallThrow(battler, 0, NULL, 0, Intro_TryShinyAnimShowHealthbox); +} + +static void LinkOpponentHandleDrawPartyStatusSummary(u32 battler) +{ + BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_OPPONENT, TRUE); +} + +static void LinkOpponentHandleBattleAnimation(u32 battler) +{ + BtlController_HandleBattleAnimation(battler, FALSE, TRUE); +} + +static void LinkOpponentHandleLinkStandbyMsg(u32 battler) +{ + RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][2]); + LinkOpponentBufferExecCompleted(battler); +} + +static void LinkOpponentHandleEndLinkBattle(u32 battler) +{ + RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]); + + if (gBattleResources->bufferA[battler][1] == B_OUTCOME_DREW) + gBattleOutcome = gBattleResources->bufferA[battler][1]; else - { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - PlaySE12WithPanning(SE_FAINT, SOUND_PAN_TARGET); - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_FaintOpponentMon; - gBattlerControllerFuncs[gActiveBattler] = HideHealthboxAfterMonFaint; - } - } -} + gBattleOutcome = gBattleResources->bufferA[battler][1] ^ B_OUTCOME_DREW; -static void LinkOpponentHandlePaletteFade(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleSuccessBallThrowAnim(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleBallThrowAnim(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandlePause(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleMoveAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleResources->bufferA[gActiveBattler][3]; - gAnimMovePower = gBattleResources->bufferA[gActiveBattler][4] | (gBattleResources->bufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleResources->bufferA[gActiveBattler][6] | (gBattleResources->bufferA[gActiveBattler][7] << 8) | (gBattleResources->bufferA[gActiveBattler][8] << 16) | (gBattleResources->bufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleResources->bufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleResources->bufferA[gActiveBattler][12] | (gBattleResources->bufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - gTransformedOtIds[gActiveBattler] = gAnimDisableStructPtr->transformedMonOtId; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = LinkOpponentDoMoveAnimation; - BattleTv_SetDataBasedOnMove(move, gWeatherMoveAnim, gAnimDisableStructPtr); - } -} - -static void LinkOpponentDoMoveAnimation(void) -{ - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - u8 multihit = gBattleResources->bufferA[gActiveBattler][11]; - - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute - && !gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8) - { - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 1; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF); - DoMoveAnim(move); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL); - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute && multihit < 2) - { - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 0; - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 3; - } - break; - case 3: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - CopyAllBattleSpritesInvisibilities(); - TrySetBehindSubstituteSpriteBit(gActiveBattler, gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - LinkOpponentBufferExecCompleted(); - } - break; - } -} - -static void LinkOpponentHandlePrintString(void) -{ - u16 *stringId; - - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - stringId = (u16 *)(&gBattleResources->bufferA[gActiveBattler][2]); - BufferStringBattle(*stringId); - BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter; - BattleTv_SetDataBasedOnString(*stringId); -} - -static void LinkOpponentHandlePrintSelectionString(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleChooseAction(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleYesNoBox(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleChooseMove(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleChooseItem(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleChoosePokemon(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleCmd23(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleHealthBarUpdate(void) -{ - s16 hpVal; - - LoadBattleBarGfx(0); - hpVal = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (hpVal != INSTANT_HP_BAR_DROP) - { - u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - u32 curHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); - - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, curHP, hpVal); - } - else - { - u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); - } - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone; -} - -static void LinkOpponentHandleExpUpdate(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleStatusIconUpdate(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u8 battlerId; - - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON); - battlerId = gActiveBattler; - gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0; - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - } -} - -static void LinkOpponentHandleStatusAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - InitAndLaunchChosenStatusAnimation(gBattleResources->bufferA[gActiveBattler][1], - gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8) | (gBattleResources->bufferA[gActiveBattler][4] << 16) | (gBattleResources->bufferA[gActiveBattler][5] << 24)); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - } -} - -static void LinkOpponentHandleStatusXor(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleDataTransfer(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleDMA3Transfer(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandlePlayBGM(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleCmd32(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleTwoReturnValues(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleChosenMonReturnValue(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleOneReturnValue(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleOneReturnValue_Duplicate(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleClearUnkVar(void) -{ - gUnusedControllerStruct.unk = 0; - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleSetUnkVar(void) -{ - gUnusedControllerStruct.unk = gBattleResources->bufferA[gActiveBattler][1]; - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleClearUnkFlag(void) -{ - gUnusedControllerStruct.flag = 0; - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleToggleUnkFlag(void) -{ - gUnusedControllerStruct.flag ^= 1; - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleHitAnimation(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].invisible == TRUE) - { - LinkOpponentBufferExecCompleted(); - } - else - { - gDoingBattleAnim = TRUE; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[1] = 0; - DoHitAnimHealthboxEffect(gActiveBattler); - gBattlerControllerFuncs[gActiveBattler] = DoHitAnimBlinkSpriteEffect; - } -} - -static void LinkOpponentHandleCantSwitch(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandlePlaySE(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - pan = SOUND_PAN_ATTACKER; - else - pan = SOUND_PAN_TARGET; - - PlaySE12WithPanning(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8), pan); - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandlePlayFanfareOrBGM(void) -{ - if (gBattleResources->bufferA[gActiveBattler][3]) - { - BattleStopLowHpSound(); - PlayBGM(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - else - { - PlayFanfare(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleFaintingCry(void) -{ - u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - PlayCry_ByMode(species, 25, CRY_MODE_FAINT); - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleIntroSlide(void) -{ - HandleIntroSlide(gBattleResources->bufferA[gActiveBattler][1]); - gIntroSlideFlags |= 1; - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleIntroTrainerBallThrow(void) -{ - u8 taskId; - - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = 280; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCB_FreeOpponentSprite); - - taskId = CreateTask(Task_StartSendOutAnim, 5); - gTasks[taskId].data[0] = gActiveBattler; - - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - - gBattleSpritesDataPtr->animationData->introAnimActive = TRUE; - gBattlerControllerFuncs[gActiveBattler] = LinkOpponentDummy; -} - -static void Task_StartSendOutAnim(u8 taskId) -{ - u8 savedActiveBank = gActiveBattler; - - gActiveBattler = gTasks[taskId].data[0]; - if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - } - else - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler = BATTLE_PARTNER(gActiveBattler); - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler = BATTLE_PARTNER(gActiveBattler); - } - gBattlerControllerFuncs[gActiveBattler] = Intro_TryShinyAnimShowHealthbox; - gActiveBattler = savedActiveBank; - DestroyTask(taskId); -} - -static void SpriteCB_FreeOpponentSprite(struct Sprite *sprite) -{ - FreeTrainerFrontPicPalette(sprite->oam.affineParam); - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); -} - -static void LinkOpponentHandleDrawPartyStatusSummary(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - { - LinkOpponentBufferExecCompleted(); - } - else - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown = 1; - - if (gBattleResources->bufferA[gActiveBattler][2] != 0) - { - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay < 2) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay++; - return; - } - else - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay = 0; - } - } - - gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleResources->bufferA[gActiveBattler][4], gBattleResources->bufferA[gActiveBattler][1], gBattleResources->bufferA[gActiveBattler][2]); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - - if (gBattleResources->bufferA[gActiveBattler][2] != 0) - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 93; - - gBattlerControllerFuncs[gActiveBattler] = EndDrawPartyStatusSummary; - } -} - -static void EndDrawPartyStatusSummary(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer++ > 92) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - LinkOpponentBufferExecCompleted(); - } -} - -static void LinkOpponentHandleHidePartyStatusSummary(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleEndBounceEffect(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleSpriteInvisibility(void) -{ - if (IsBattlerSpritePresent(gActiveBattler)) - { - gSprites[gBattlerSpriteIds[gActiveBattler]].invisible = gBattleResources->bufferA[gActiveBattler][1]; - CopyBattleSpriteInvisibility(gActiveBattler); - } - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleBattleAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u8 animationId = gBattleResources->bufferA[gActiveBattler][1]; - u16 argument = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (TryHandleLaunchBattleTableAnimation(gActiveBattler, gActiveBattler, gActiveBattler, animationId, argument)) - LinkOpponentBufferExecCompleted(); - else - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; - - BattleTv_SetDataBasedOnAnimation(animationId); - } -} - -static void LinkOpponentHandleLinkStandbyMsg(void) -{ - RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[gActiveBattler][2]); - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleResetActionMoveSelection(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentHandleEndLinkBattle(void) -{ - RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[gActiveBattler][4]); - - if (gBattleResources->bufferA[gActiveBattler][1] == B_OUTCOME_DREW) - gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; - else - gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1] ^ B_OUTCOME_DREW; - - gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[gActiveBattler][2]; + gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2]; FadeOutMapMusic(5); BeginFastPaletteFade(3); - LinkOpponentBufferExecCompleted(); - gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; -} - -static void LinkOpponentHandleBattleDebug(void) -{ - LinkOpponentBufferExecCompleted(); -} - -static void LinkOpponentCmdEnd(void) -{ + LinkOpponentBufferExecCompleted(battler); + gBattlerControllerFuncs[battler] = SetBattleEndCallbacks; } diff --git a/src/battle_controller_link_partner.c b/src/battle_controller_link_partner.c index 8684ba70e..c4b4e2112 100644 --- a/src/battle_controller_link_partner.c +++ b/src/battle_controller_link_partner.c @@ -29,1093 +29,200 @@ #include "constants/trainers.h" #include "recorded_battle.h" -static void LinkPartnerHandleGetMonData(void); -static void LinkPartnerHandleGetRawMonData(void); -static void LinkPartnerHandleSetMonData(void); -static void LinkPartnerHandleSetRawMonData(void); -static void LinkPartnerHandleLoadMonSprite(void); -static void LinkPartnerHandleSwitchInAnim(void); -static void LinkPartnerHandleReturnMonToBall(void); -static void LinkPartnerHandleDrawTrainerPic(void); -static void LinkPartnerHandleTrainerSlide(void); -static void LinkPartnerHandleTrainerSlideBack(void); -static void LinkPartnerHandleFaintAnimation(void); -static void LinkPartnerHandlePaletteFade(void); -static void LinkPartnerHandleSuccessBallThrowAnim(void); -static void LinkPartnerHandleBallThrowAnim(void); -static void LinkPartnerHandlePause(void); -static void LinkPartnerHandleMoveAnimation(void); -static void LinkPartnerHandlePrintString(void); -static void LinkPartnerHandlePrintSelectionString(void); -static void LinkPartnerHandleChooseAction(void); -static void LinkPartnerHandleYesNoBox(void); -static void LinkPartnerHandleChooseMove(void); -static void LinkPartnerHandleChooseItem(void); -static void LinkPartnerHandleChoosePokemon(void); -static void LinkPartnerHandleCmd23(void); -static void LinkPartnerHandleHealthBarUpdate(void); -static void LinkPartnerHandleExpUpdate(void); -static void LinkPartnerHandleStatusIconUpdate(void); -static void LinkPartnerHandleStatusAnimation(void); -static void LinkPartnerHandleStatusXor(void); -static void LinkPartnerHandleDataTransfer(void); -static void LinkPartnerHandleDMA3Transfer(void); -static void LinkPartnerHandlePlayBGM(void); -static void LinkPartnerHandleCmd32(void); -static void LinkPartnerHandleTwoReturnValues(void); -static void LinkPartnerHandleChosenMonReturnValue(void); -static void LinkPartnerHandleOneReturnValue(void); -static void LinkPartnerHandleOneReturnValue_Duplicate(void); -static void LinkPartnerHandleClearUnkVar(void); -static void LinkPartnerHandleSetUnkVar(void); -static void LinkPartnerHandleClearUnkFlag(void); -static void LinkPartnerHandleToggleUnkFlag(void); -static void LinkPartnerHandleHitAnimation(void); -static void LinkPartnerHandleCantSwitch(void); -static void LinkPartnerHandlePlaySE(void); -static void LinkPartnerHandlePlayFanfareOrBGM(void); -static void LinkPartnerHandleFaintingCry(void); -static void LinkPartnerHandleIntroSlide(void); -static void LinkPartnerHandleIntroTrainerBallThrow(void); -static void LinkPartnerHandleDrawPartyStatusSummary(void); -static void LinkPartnerHandleHidePartyStatusSummary(void); -static void LinkPartnerHandleEndBounceEffect(void); -static void LinkPartnerHandleSpriteInvisibility(void); -static void LinkPartnerHandleBattleAnimation(void); -static void LinkPartnerHandleLinkStandbyMsg(void); -static void LinkPartnerHandleResetActionMoveSelection(void); -static void LinkPartnerHandleEndLinkBattle(void); -static void LinkPartnerHandleBattleDebug(void); -static void LinkPartnerCmdEnd(void); +static void LinkPartnerHandleLoadMonSprite(u32 battler); +static void LinkPartnerHandleSwitchInAnim(u32 battler); +static void LinkPartnerHandleDrawTrainerPic(u32 battler); +static void LinkPartnerHandleTrainerSlideBack(u32 battler); +static void LinkPartnerHandleMoveAnimation(u32 battler); +static void LinkPartnerHandlePrintString(u32 battler); +static void LinkPartnerHandleHealthBarUpdate(u32 battler); +static void LinkPartnerHandleIntroTrainerBallThrow(u32 battler); +static void LinkPartnerHandleDrawPartyStatusSummary(u32 battler); +static void LinkPartnerHandleBattleAnimation(u32 battler); +static void LinkPartnerHandleLinkStandbyMsg(u32 battler); +static void LinkPartnerHandleEndLinkBattle(u32 battler); -static void LinkPartnerBufferRunCommand(void); -static void LinkPartnerBufferExecCompleted(void); -static void SwitchIn_WaitAndEnd(void); -static u32 CopyLinkPartnerMonData(u8 monId, u8 *dst); -static void SetLinkPartnerMonData(u8 monId); -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit); -static void DoSwitchOutAnimation(void); -static void LinkPartnerDoMoveAnimation(void); -static void Task_StartSendOutAnim(u8 taskId); -static void EndDrawPartyStatusSummary(void); +static void LinkPartnerBufferRunCommand(u32 battler); +static void LinkPartnerBufferExecCompleted(u32 battler); +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] = LinkPartnerHandleGetMonData, - [CONTROLLER_GETRAWMONDATA] = LinkPartnerHandleGetRawMonData, - [CONTROLLER_SETMONDATA] = LinkPartnerHandleSetMonData, - [CONTROLLER_SETRAWMONDATA] = LinkPartnerHandleSetRawMonData, + [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, + [CONTROLLER_GETRAWMONDATA] = BtlController_Empty, + [CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, + [CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData, [CONTROLLER_LOADMONSPRITE] = LinkPartnerHandleLoadMonSprite, [CONTROLLER_SWITCHINANIM] = LinkPartnerHandleSwitchInAnim, - [CONTROLLER_RETURNMONTOBALL] = LinkPartnerHandleReturnMonToBall, + [CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, [CONTROLLER_DRAWTRAINERPIC] = LinkPartnerHandleDrawTrainerPic, - [CONTROLLER_TRAINERSLIDE] = LinkPartnerHandleTrainerSlide, + [CONTROLLER_TRAINERSLIDE] = BtlController_Empty, [CONTROLLER_TRAINERSLIDEBACK] = LinkPartnerHandleTrainerSlideBack, - [CONTROLLER_FAINTANIMATION] = LinkPartnerHandleFaintAnimation, - [CONTROLLER_PALETTEFADE] = LinkPartnerHandlePaletteFade, - [CONTROLLER_SUCCESSBALLTHROWANIM] = LinkPartnerHandleSuccessBallThrowAnim, - [CONTROLLER_BALLTHROWANIM] = LinkPartnerHandleBallThrowAnim, - [CONTROLLER_PAUSE] = LinkPartnerHandlePause, + [CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, + [CONTROLLER_PALETTEFADE] = BtlController_Empty, + [CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty, + [CONTROLLER_BALLTHROWANIM] = BtlController_Empty, + [CONTROLLER_PAUSE] = BtlController_Empty, [CONTROLLER_MOVEANIMATION] = LinkPartnerHandleMoveAnimation, [CONTROLLER_PRINTSTRING] = LinkPartnerHandlePrintString, - [CONTROLLER_PRINTSTRINGPLAYERONLY] = LinkPartnerHandlePrintSelectionString, - [CONTROLLER_CHOOSEACTION] = LinkPartnerHandleChooseAction, - [CONTROLLER_YESNOBOX] = LinkPartnerHandleYesNoBox, - [CONTROLLER_CHOOSEMOVE] = LinkPartnerHandleChooseMove, - [CONTROLLER_OPENBAG] = LinkPartnerHandleChooseItem, - [CONTROLLER_CHOOSEPOKEMON] = LinkPartnerHandleChoosePokemon, - [CONTROLLER_23] = LinkPartnerHandleCmd23, + [CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty, + [CONTROLLER_CHOOSEACTION] = BtlController_Empty, + [CONTROLLER_YESNOBOX] = BtlController_Empty, + [CONTROLLER_CHOOSEMOVE] = BtlController_Empty, + [CONTROLLER_OPENBAG] = BtlController_Empty, + [CONTROLLER_CHOOSEPOKEMON] = BtlController_Empty, + [CONTROLLER_23] = BtlController_Empty, [CONTROLLER_HEALTHBARUPDATE] = LinkPartnerHandleHealthBarUpdate, - [CONTROLLER_EXPUPDATE] = LinkPartnerHandleExpUpdate, - [CONTROLLER_STATUSICONUPDATE] = LinkPartnerHandleStatusIconUpdate, - [CONTROLLER_STATUSANIMATION] = LinkPartnerHandleStatusAnimation, - [CONTROLLER_STATUSXOR] = LinkPartnerHandleStatusXor, - [CONTROLLER_DATATRANSFER] = LinkPartnerHandleDataTransfer, - [CONTROLLER_DMA3TRANSFER] = LinkPartnerHandleDMA3Transfer, - [CONTROLLER_PLAYBGM] = LinkPartnerHandlePlayBGM, - [CONTROLLER_32] = LinkPartnerHandleCmd32, - [CONTROLLER_TWORETURNVALUES] = LinkPartnerHandleTwoReturnValues, - [CONTROLLER_CHOSENMONRETURNVALUE] = LinkPartnerHandleChosenMonReturnValue, - [CONTROLLER_ONERETURNVALUE] = LinkPartnerHandleOneReturnValue, - [CONTROLLER_ONERETURNVALUE_DUPLICATE] = LinkPartnerHandleOneReturnValue_Duplicate, - [CONTROLLER_CLEARUNKVAR] = LinkPartnerHandleClearUnkVar, - [CONTROLLER_SETUNKVAR] = LinkPartnerHandleSetUnkVar, - [CONTROLLER_CLEARUNKFLAG] = LinkPartnerHandleClearUnkFlag, - [CONTROLLER_TOGGLEUNKFLAG] = LinkPartnerHandleToggleUnkFlag, - [CONTROLLER_HITANIMATION] = LinkPartnerHandleHitAnimation, - [CONTROLLER_CANTSWITCH] = LinkPartnerHandleCantSwitch, - [CONTROLLER_PLAYSE] = LinkPartnerHandlePlaySE, - [CONTROLLER_PLAYFANFAREORBGM] = LinkPartnerHandlePlayFanfareOrBGM, - [CONTROLLER_FAINTINGCRY] = LinkPartnerHandleFaintingCry, - [CONTROLLER_INTROSLIDE] = LinkPartnerHandleIntroSlide, + [CONTROLLER_EXPUPDATE] = BtlController_Empty, + [CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate, + [CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation, + [CONTROLLER_STATUSXOR] = BtlController_Empty, + [CONTROLLER_DATATRANSFER] = BtlController_Empty, + [CONTROLLER_DMA3TRANSFER] = BtlController_Empty, + [CONTROLLER_PLAYBGM] = BtlController_Empty, + [CONTROLLER_32] = BtlController_Empty, + [CONTROLLER_TWORETURNVALUES] = BtlController_Empty, + [CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, + [CONTROLLER_CLEARUNKVAR] = BtlController_HandleClearUnkVar, + [CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar, + [CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag, + [CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag, + [CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, + [CONTROLLER_CANTSWITCH] = BtlController_Empty, + [CONTROLLER_PLAYSE] = BtlController_HandlePlaySE, + [CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, + [CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry, + [CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, [CONTROLLER_INTROTRAINERBALLTHROW] = LinkPartnerHandleIntroTrainerBallThrow, [CONTROLLER_DRAWPARTYSTATUSSUMMARY] = LinkPartnerHandleDrawPartyStatusSummary, - [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = LinkPartnerHandleHidePartyStatusSummary, - [CONTROLLER_ENDBOUNCE] = LinkPartnerHandleEndBounceEffect, - [CONTROLLER_SPRITEINVISIBILITY] = LinkPartnerHandleSpriteInvisibility, + [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary, + [CONTROLLER_ENDBOUNCE] = BtlController_Empty, + [CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility, [CONTROLLER_BATTLEANIMATION] = LinkPartnerHandleBattleAnimation, [CONTROLLER_LINKSTANDBYMSG] = LinkPartnerHandleLinkStandbyMsg, - [CONTROLLER_RESETACTIONMOVESELECTION] = LinkPartnerHandleResetActionMoveSelection, + [CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, [CONTROLLER_ENDLINKBATTLE] = LinkPartnerHandleEndLinkBattle, - [CONTROLLER_DEBUGMENU] = LinkPartnerHandleBattleDebug, - [CONTROLLER_TERMINATOR_NOP] = LinkPartnerCmdEnd + [CONTROLLER_DEBUGMENU] = BtlController_Empty, + [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop }; -static void SpriteCB_Null2(void) +void SetControllerToLinkPartner(u32 battler) { + gBattlerControllerEndFuncs[battler] = LinkPartnerBufferExecCompleted; + gBattlerControllerFuncs[battler] = LinkPartnerBufferRunCommand; } -void SetControllerToLinkPartner(void) +static void LinkPartnerBufferRunCommand(u32 battler) { - gBattlerControllerFuncs[gActiveBattler] = LinkPartnerBufferRunCommand; -} - -static void LinkPartnerBufferRunCommand(void) -{ - if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) + if (gBattleControllerExecFlags & gBitTable[battler]) { - if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sLinkPartnerBufferCommands)) - sLinkPartnerBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); + if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sLinkPartnerBufferCommands)) + sLinkPartnerBufferCommands[gBattleResources->bufferA[battler][0]](battler); else - LinkPartnerBufferExecCompleted(); + LinkPartnerBufferExecCompleted(battler); } } -static void CompleteOnBattlerSpriteCallbackDummy(void) +static void WaitForMonAnimAfterLoad(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - LinkPartnerBufferExecCompleted(); + if (gSprites[gBattlerSpriteIds[battler]].animEnded && gSprites[gBattlerSpriteIds[battler]].x2 == 0) + LinkPartnerBufferExecCompleted(battler); } -static void FreeTrainerSpriteAfterSlide(void) +static void SwitchIn_ShowSubstitute(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) { - BattleGfxSfxDummy3(MALE); - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - LinkPartnerBufferExecCompleted(); + CopyBattleSpriteInvisibility(battler); + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE); + + gBattlerControllerFuncs[battler] = SwitchIn_WaitAndEnd; } } -static void Intro_DelayAndEnd(void) +static void SwitchIn_WaitAndEnd(u32 battler) { - if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == (u8)-1) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; - LinkPartnerBufferExecCompleted(); + LinkPartnerBufferExecCompleted(battler); } } -static void Intro_WaitForHealthbox(void) +static void SwitchIn_ShowHealthbox(u32 battler) { - bool32 finished = FALSE; - - if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) + if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim) { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - finished = TRUE; - } - else - { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) - { - finished = TRUE; - } - } - - if (IsCryPlayingOrClearCrySongs()) - finished = FALSE; - - if (finished) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; - gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; - } -} - -static void Intro_ShowHealthbox(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive - && gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && ++gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay != 1) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; - - if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); - UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); - StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); - } - - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - - gBattleSpritesDataPtr->animationData->introAnimActive = FALSE; - - gBattlerControllerFuncs[gActiveBattler] = Intro_WaitForHealthbox; - } -} - -static void WaitForMonAnimAfterLoad(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].animEnded && gSprites[gBattlerSpriteIds[gActiveBattler]].x2 == 0) - LinkPartnerBufferExecCompleted(); -} - -static void CompleteOnHealthbarDone(void) -{ - s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0); - - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - - if (hpValue != -1) - { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); - } - else - { - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - LinkPartnerBufferExecCompleted(); - } -} - -static void FreeMonSpriteAfterFaintAnim(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].y + gSprites[gBattlerSpriteIds[gActiveBattler]].y2 > DISPLAY_HEIGHT) - { - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - BattleGfxSfxDummy2(species); - FreeOamMatrix(gSprites[gBattlerSpriteIds[gActiveBattler]].oam.matrixNum); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - LinkPartnerBufferExecCompleted(); - } -} - -static void FreeMonSpriteAfterSwitchOutAnim(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - LinkPartnerBufferExecCompleted(); - } -} - -static void CompleteOnInactiveTextPrinter(void) -{ - if (!IsTextPrinterActive(B_WIN_MSG)) - LinkPartnerBufferExecCompleted(); -} - -static void DoHitAnimBlinkSpriteEffect(void) -{ - u8 spriteId = gBattlerSpriteIds[gActiveBattler]; - - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = FALSE; - LinkPartnerBufferExecCompleted(); - } - else - { - if ((gSprites[spriteId].data[1] % 4) == 0) - gSprites[spriteId].invisible ^= 1; - gSprites[spriteId].data[1]++; - } -} - -static void SwitchIn_ShowSubstitute(void) -{ - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - CopyBattleSpriteInvisibility(gActiveBattler); - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_WaitAndEnd; - } -} - -static void SwitchIn_WaitAndEnd(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - LinkPartnerBufferExecCompleted(); - } -} - -static void SwitchIn_ShowHealthbox(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); CreateTask(Task_PlayerController_RestoreBgmAfterCry, 10); - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); + StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 0); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + 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 - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) { - TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]); } - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) { - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowHealthbox; + DestroySprite(&gSprites[gBattleControllerData[battler]]); + gBattlerControllerFuncs[battler] = SwitchIn_ShowHealthbox; } } -static void LinkPartnerBufferExecCompleted(void) +static void LinkPartnerBufferExecCompleted(u32 battler) { - gBattlerControllerFuncs[gActiveBattler] = LinkPartnerBufferRunCommand; + gBattlerControllerFuncs[battler] = LinkPartnerBufferRunCommand; if (gBattleTypeFlags & BATTLE_TYPE_LINK) { u8 playerId = GetMultiplayerId(); PrepareBufferDataTransferLink(2, 4, &playerId); - gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; + gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP; } else { - gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; + gBattleControllerExecFlags &= ~gBitTable[battler]; } } -static void CompleteOnFinishedStatusAnimation(void) +static void LinkPartnerHandleLoadMonSprite(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive) - LinkPartnerBufferExecCompleted(); + BtlController_HandleLoadMonSprite(battler, WaitForMonAnimAfterLoad); } -static void CompleteOnFinishedBattleAnimation(void) +static void LinkPartnerHandleSwitchInAnim(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive) - LinkPartnerBufferExecCompleted(); + BtlController_HandleSwitchInAnim(battler, TRUE, SwitchIn_TryShinyAnim); } -static void LinkPartnerHandleGetMonData(void) -{ - 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 size = 0; - u8 monToCheck; - s32 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - size += CopyLinkPartnerMonData(gBattlerPartyIndexes[gActiveBattler], monData); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - size += CopyLinkPartnerMonData(i, monData + size); - monToCheck >>= 1; - } - } - BtlController_EmitDataTransfer(BUFFER_B, size, monData); - LinkPartnerBufferExecCompleted(); -} - -static u32 CopyLinkPartnerMonData(u8 monId, u8 *dst) -{ - struct BattlePokemon battleMon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - battleMon.species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); - battleMon.item = GetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM); - for (size = 0; size < MAX_MON_MOVES; size++) - { - battleMon.moves[size] = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + size); - battleMon.pp[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - } - battleMon.ppBonuses = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - battleMon.friendship = GetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP); - battleMon.experience = GetMonData(&gPlayerParty[monId], MON_DATA_EXP); - battleMon.hpIV = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - battleMon.attackIV = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - battleMon.defenseIV = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - battleMon.speedIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - battleMon.spAttackIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - battleMon.spDefenseIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - battleMon.personality = GetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY); - battleMon.status1 = GetMonData(&gPlayerParty[monId], MON_DATA_STATUS); - battleMon.level = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); - battleMon.hp = GetMonData(&gPlayerParty[monId], MON_DATA_HP); - battleMon.maxHP = GetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP); - battleMon.attack = GetMonData(&gPlayerParty[monId], MON_DATA_ATK); - battleMon.defense = GetMonData(&gPlayerParty[monId], MON_DATA_DEF); - battleMon.speed = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED); - battleMon.spAttack = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK); - battleMon.spDefense = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF); - battleMon.abilityNum = GetMonData(&gPlayerParty[monId], MON_DATA_ABILITY_NUM); - battleMon.otId = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID); - battleMon.metLevel = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL); - GetMonData(&gPlayerParty[monId], MON_DATA_NICKNAME, nickname); - StringCopy_Nickname(battleMon.nickname, nickname); - GetMonData(&gPlayerParty[monId], MON_DATA_OT_NAME, battleMon.otName); - src = (u8 *)&battleMon; - for (size = 0; size < sizeof(battleMon); size++) - dst[size] = src[size]; - break; - case REQUEST_SPECIES_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_HELDITEM_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MOVES_PP_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - { - moveData.moves[size] = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - src = (u8 *)(&moveData); - for (size = 0; size < sizeof(moveData); size++) - dst[size] = src[size]; - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_PP_DATA_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - dst[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - dst[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - size++; - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE); - size = 1; - break; - case REQUEST_OTID_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_EXP_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_EXP); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_HP_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_EV); - size = 1; - break; - case REQUEST_ATK_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_EV); - size = 1; - break; - case REQUEST_DEF_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_EV); - size = 1; - break; - case REQUEST_SPEED_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_EV); - size = 1; - break; - case REQUEST_SPATK_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_EV); - size = 1; - break; - case REQUEST_SPDEF_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_EV); - size = 1; - break; - case REQUEST_FRIENDSHIP_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP); - size = 1; - break; - case REQUEST_POKERUS_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_POKERUS); - size = 1; - break; - case REQUEST_MET_LOCATION_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LOCATION); - size = 1; - break; - case REQUEST_MET_LEVEL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL); - size = 1; - break; - case REQUEST_MET_GAME_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_GAME); - size = 1; - break; - case REQUEST_POKEBALL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_POKEBALL); - size = 1; - break; - case REQUEST_ALL_IVS_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - dst[1] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - dst[2] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - dst[3] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - dst[4] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - dst[5] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - size = 6; - break; - case REQUEST_HP_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - size = 1; - break; - case REQUEST_ATK_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - size = 1; - break; - case REQUEST_DEF_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - size = 1; - break; - case REQUEST_SPEED_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - size = 1; - break; - case REQUEST_SPATK_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - size = 1; - break; - case REQUEST_SPDEF_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - size = 1; - break; - case REQUEST_PERSONALITY_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_CHECKSUM_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_CHECKSUM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_STATUS_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_STATUS); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_LEVEL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); - size = 1; - break; - case REQUEST_HP_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MAX_HP_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_ATK_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_ATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_DEF_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_DEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPEED_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPATK_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPDEF_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_COOL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_COOL); - size = 1; - break; - case REQUEST_BEAUTY_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY); - size = 1; - break; - case REQUEST_CUTE_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_CUTE); - size = 1; - break; - case REQUEST_SMART_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SMART); - size = 1; - break; - case REQUEST_TOUGH_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_TOUGH); - size = 1; - break; - case REQUEST_SHEEN_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SHEEN); - size = 1; - break; - case REQUEST_COOL_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_COOL_RIBBON); - size = 1; - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case REQUEST_CUTE_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case REQUEST_SMART_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SMART_RIBBON); - size = 1; - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - - return size; -} - -static void LinkPartnerHandleGetRawMonData(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleSetMonData(void) -{ - u8 monToCheck; - u8 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - SetLinkPartnerMonData(gBattlerPartyIndexes[gActiveBattler]); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - SetLinkPartnerMonData(i); - monToCheck >>= 1; - } - } - LinkPartnerBufferExecCompleted(); -} - -static void SetLinkPartnerMonData(u8 monId) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleResources->bufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleResources->bufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - { - u8 iv; - - SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gPlayerParty[monId], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gPlayerParty[monId], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gPlayerParty[monId], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gPlayerParty[monId], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gPlayerParty[monId], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case REQUEST_SPECIES_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HELDITEM_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MOVES_PP_BATTLE: - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PP_DATA_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PP1, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP2, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP3, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP4, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &gBattleResources->bufferA[gActiveBattler][7]); - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_OTID_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_OT_ID, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_EXP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_FRIENDSHIP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKERUS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_POKERUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LOCATION_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_LOCATION, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LEVEL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_GAME_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_GAME, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKEBALL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_POKEBALL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ALL_IVS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][7]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][8]); - break; - case REQUEST_HP_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PERSONALITY_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CHECKSUM_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CHECKSUM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_STATUS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_STATUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_LEVEL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MAX_HP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_COOL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CUTE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SMART, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_TOUGH, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SHEEN_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SHEEN, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_COOL_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CUTE_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SMART_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_TOUGH_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - } - - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); -} - -static void LinkPartnerHandleSetRawMonData(void) -{ - u8 *dst = (u8 *)&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleResources->bufferA[gActiveBattler][1]; - u8 i; - - for (i = 0; i < gBattleResources->bufferA[gActiveBattler][2]; i++) - dst[i] = gBattleResources->bufferA[gActiveBattler][3 + i]; - - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleLoadMonSprite(void) -{ - u16 species; - - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(gActiveBattler)); - - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(gActiveBattler, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(gActiveBattler), - GetBattlerSpriteSubpriority(gActiveBattler)); - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); - gBattlerControllerFuncs[gActiveBattler] = WaitForMonAnimAfterLoad; -} - -static void LinkPartnerHandleSwitchInAnim(void) -{ - ClearTemporarySpeciesSpriteData(gActiveBattler, gBattleResources->bufferA[gActiveBattler][2]); - gBattlerPartyIndexes[gActiveBattler] = gBattleResources->bufferA[gActiveBattler][1]; - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - StartSendOutAnim(gActiveBattler, gBattleResources->bufferA[gActiveBattler][2]); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_TryShinyAnim; -} - -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit) -{ - u16 species; - - ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit); - gBattlerPartyIndexes[battlerId] = gBattleResources->bufferA[battlerId][1]; - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); - gBattleControllerData[battlerId] = CreateInvisibleSpriteWithCallback(SpriteCB_WaitForBattlerBallReleaseAnim); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battlerId)); - - gBattlerSpriteIds[battlerId] = CreateSprite( - &gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(battlerId), - GetBattlerSpriteSubpriority(battlerId)); - - gSprites[gBattleControllerData[battlerId]].data[1] = gBattlerSpriteIds[battlerId]; - gSprites[gBattleControllerData[battlerId]].data[2] = battlerId; - - gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId; - gSprites[gBattlerSpriteIds[battlerId]].data[2] = species; - gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId; - - StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], 0); - - gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE; - gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy; - - gSprites[gBattleControllerData[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT); -} - -static void LinkPartnerHandleReturnMonToBall(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] == 0) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = DoSwitchOutAnimation; - } - else - { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - LinkPartnerBufferExecCompleted(); - } -} - -static void DoSwitchOutAnimation(void) -{ - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SWITCH_OUT_PLAYER_MON); - gBattlerControllerFuncs[gActiveBattler] = FreeMonSpriteAfterSwitchOutAnim; - } - break; - } -} - -#define sSpeedX data[0] - -static void LinkPartnerHandleDrawTrainerPic(void) +static void LinkPartnerHandleDrawTrainerPic(u32 battler) { s16 xPos; u32 trainerPicId; if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { - if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != 0) // second mon + if ((GetBattlerPosition(battler) & BIT_FLANK) != 0) // second mon xPos = 90; else // first mon xPos = 32; @@ -1125,574 +232,63 @@ static void LinkPartnerHandleDrawTrainerPic(void) xPos = 80; } - if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_FIRE_RED - || (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_LEAF_GREEN) - { - trainerPicId = gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender + TRAINER_BACK_PIC_RED; - } - else if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_RUBY - || (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_SAPPHIRE) - { - trainerPicId = gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender + TRAINER_BACK_PIC_RUBY_SAPPHIRE_BRENDAN; - } - else - { - trainerPicId = gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender; - } - - DecompressTrainerBackPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, xPos, (8 - gTrainerBackPicCoords[trainerPicId].size) * 4 + 80, GetBattlerSpriteSubpriority(gActiveBattler)); - - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = -2; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy; + trainerPicId = LinkPlayerGetTrainerPicId(GetBattlerMultiplayerId(battler)); + BtlController_HandleDrawTrainerPic(battler, trainerPicId, FALSE, + xPos, 80 + 4 * (8 - gTrainerBackPicCoords[trainerPicId].size), + -1); } -#undef sSpeedX - -static void LinkPartnerHandleTrainerSlide(void) +static void LinkPartnerHandleTrainerSlideBack(u32 battler) { - LinkPartnerBufferExecCompleted(); + BtlController_HandleTrainerSlideBack(battler, 35, FALSE); } -static void LinkPartnerHandleTrainerSlideBack(void) +static void LinkPartnerHandleMoveAnimation(u32 battler) { - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCallbackDummy); - gBattlerControllerFuncs[gActiveBattler] = FreeTrainerSpriteAfterSlide; + BtlController_HandleMoveAnimation(battler, TRUE); } -#define sSpeedX data[1] -#define sSpeedY data[2] - -static void LinkPartnerHandleFaintAnimation(void) +static void LinkPartnerHandlePrintString(u32 battler) { - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState == 0) - { - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState++; - } - else - { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - PlaySE12WithPanning(SE_FAINT, SOUND_PAN_ATTACKER); - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = 0; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedY = 5; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_FaintSlideAnim; - gBattlerControllerFuncs[gActiveBattler] = FreeMonSpriteAfterFaintAnim; - } - } + BtlController_HandlePrintString(battler, TRUE, FALSE); } -#undef sSpeedX -#undef sSpeedY - -static void LinkPartnerHandlePaletteFade(void) +static void LinkPartnerHandleHealthBarUpdate(u32 battler) { - LinkPartnerBufferExecCompleted(); + BtlController_HandleHealthBarUpdate(battler, FALSE); } -static void LinkPartnerHandleSuccessBallThrowAnim(void) +static void LinkPartnerHandleIntroTrainerBallThrow(u32 battler) { - LinkPartnerBufferExecCompleted(); + u32 trainerPicId = LinkPlayerGetTrainerPicId(GetBattlerMultiplayerId(battler)); + const u32 *trainerPal = gTrainerBackPicPaletteTable[trainerPicId].data; + // Link partner uses the same intro sequence as the player partner. + BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F9, trainerPal, 24, Controller_PlayerPartnerShowIntroHealthbox); } -static void LinkPartnerHandleBallThrowAnim(void) +static void LinkPartnerHandleDrawPartyStatusSummary(u32 battler) { - LinkPartnerBufferExecCompleted(); + BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, TRUE); } -static void LinkPartnerHandlePause(void) +static void LinkPartnerHandleBattleAnimation(u32 battler) { - LinkPartnerBufferExecCompleted(); + BtlController_HandleBattleAnimation(battler, FALSE, TRUE); } -static void LinkPartnerHandleMoveAnimation(void) +static void LinkPartnerHandleLinkStandbyMsg(u32 battler) { - if (!IsBattleSEPlaying(gActiveBattler)) - { - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleResources->bufferA[gActiveBattler][3]; - gAnimMovePower = gBattleResources->bufferA[gActiveBattler][4] | (gBattleResources->bufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleResources->bufferA[gActiveBattler][6] | (gBattleResources->bufferA[gActiveBattler][7] << 8) | (gBattleResources->bufferA[gActiveBattler][8] << 16) | (gBattleResources->bufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleResources->bufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleResources->bufferA[gActiveBattler][12] | (gBattleResources->bufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - gTransformedOtIds[gActiveBattler] = gAnimDisableStructPtr->transformedMonOtId; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = LinkPartnerDoMoveAnimation; - BattleTv_SetDataBasedOnMove(move, gWeatherMoveAnim, gAnimDisableStructPtr); - } + RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][2]); + LinkPartnerBufferExecCompleted(battler); } -static void LinkPartnerDoMoveAnimation(void) +static void LinkPartnerHandleEndLinkBattle(u32 battler) { - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - u8 multihit = gBattleResources->bufferA[gActiveBattler][11]; - - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute - && !gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8) - { - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 1; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF); - DoMoveAnim(move); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL); - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute && multihit < 2) - { - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 0; - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 3; - } - break; - case 3: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - CopyAllBattleSpritesInvisibilities(); - TrySetBehindSubstituteSpriteBit(gActiveBattler, gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - LinkPartnerBufferExecCompleted(); - } - break; - } -} - -static void LinkPartnerHandlePrintString(void) -{ - u16 *stringId; - - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - stringId = (u16 *)(&gBattleResources->bufferA[gActiveBattler][2]); - BufferStringBattle(*stringId); - BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter; - BattleTv_SetDataBasedOnString(*stringId); -} - -static void LinkPartnerHandlePrintSelectionString(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleChooseAction(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleYesNoBox(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleChooseMove(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleChooseItem(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleChoosePokemon(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleCmd23(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleHealthBarUpdate(void) -{ - s16 hpVal; - - LoadBattleBarGfx(0); - hpVal = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (hpVal != INSTANT_HP_BAR_DROP) - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - u32 curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); - - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, curHP, hpVal); - } - else - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); - } - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone; -} - -static void LinkPartnerHandleExpUpdate(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleStatusIconUpdate(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u8 battlerId; - - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON); - battlerId = gActiveBattler; - gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0; - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - } -} - -static void LinkPartnerHandleStatusAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - InitAndLaunchChosenStatusAnimation(gBattleResources->bufferA[gActiveBattler][1], - gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8) | (gBattleResources->bufferA[gActiveBattler][4] << 16) | (gBattleResources->bufferA[gActiveBattler][5] << 24)); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - } -} - -static void LinkPartnerHandleStatusXor(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleDataTransfer(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleDMA3Transfer(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandlePlayBGM(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleCmd32(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleTwoReturnValues(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleChosenMonReturnValue(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleOneReturnValue(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleOneReturnValue_Duplicate(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleClearUnkVar(void) -{ - gUnusedControllerStruct.unk = 0; - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleSetUnkVar(void) -{ - gUnusedControllerStruct.unk = gBattleResources->bufferA[gActiveBattler][1]; - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleClearUnkFlag(void) -{ - gUnusedControllerStruct.flag = 0; - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleToggleUnkFlag(void) -{ - gUnusedControllerStruct.flag ^= 1; - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleHitAnimation(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].invisible == TRUE) - { - LinkPartnerBufferExecCompleted(); - } - else - { - gDoingBattleAnim = TRUE; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[1] = 0; - DoHitAnimHealthboxEffect(gActiveBattler); - gBattlerControllerFuncs[gActiveBattler] = DoHitAnimBlinkSpriteEffect; - } -} - -static void LinkPartnerHandleCantSwitch(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandlePlaySE(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - pan = SOUND_PAN_ATTACKER; - else - pan = SOUND_PAN_TARGET; - - PlaySE12WithPanning(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8), pan); - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandlePlayFanfareOrBGM(void) -{ - if (gBattleResources->bufferA[gActiveBattler][3]) - { - BattleStopLowHpSound(); - PlayBGM(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - else - { - PlayFanfare(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleFaintingCry(void) -{ - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - PlayCry_ByMode(species, -25, CRY_MODE_FAINT); - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleIntroSlide(void) -{ - HandleIntroSlide(gBattleResources->bufferA[gActiveBattler][1]); - gIntroSlideFlags |= 1; - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleIntroTrainerBallThrow(void) -{ - u8 paletteNum; - u8 taskId; - u32 trainerPicId; - - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 50; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[5] = gActiveBattler; - - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCB_FreePlayerSpriteLoadMonSprite); - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 1); - - paletteNum = AllocSpritePalette(0xD6F9); - - if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_FIRE_RED - || (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_LEAF_GREEN) - { - trainerPicId = gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender + TRAINER_BACK_PIC_RED; - } - else if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_RUBY - || (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_SAPPHIRE) - { - trainerPicId = gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender + TRAINER_BACK_PIC_RUBY_SAPPHIRE_BRENDAN; - } - else - { - trainerPicId = gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender; - } - - LoadCompressedPalette(gTrainerBackPicPaletteTable[trainerPicId].data, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP); - - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = paletteNum; - - taskId = CreateTask(Task_StartSendOutAnim, 5); - gTasks[taskId].data[0] = gActiveBattler; - - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - - gBattleSpritesDataPtr->animationData->introAnimActive = TRUE; - gBattlerControllerFuncs[gActiveBattler] = SpriteCB_Null2; -} - -static void Task_StartSendOutAnim(u8 taskId) -{ - if (gTasks[taskId].data[1] < 24) - { - gTasks[taskId].data[1]++; - } - else - { - u8 savedActiveBank = gActiveBattler; - - gActiveBattler = gTasks[taskId].data[0]; - if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - } - else - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler ^= BIT_FLANK; - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler ^= BIT_FLANK; - } - gBattlerControllerFuncs[gActiveBattler] = Intro_ShowHealthbox; - gActiveBattler = savedActiveBank; - DestroyTask(taskId); - } -} - -static void LinkPartnerHandleDrawPartyStatusSummary(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - { - LinkPartnerBufferExecCompleted(); - } - else - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown = 1; - gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleResources->bufferA[gActiveBattler][4], gBattleResources->bufferA[gActiveBattler][1], gBattleResources->bufferA[gActiveBattler][2]); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - - if (gBattleResources->bufferA[gActiveBattler][2] != 0) - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 93; - - gBattlerControllerFuncs[gActiveBattler] = EndDrawPartyStatusSummary; - } -} - -static void EndDrawPartyStatusSummary(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer++ > 92) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - LinkPartnerBufferExecCompleted(); - } -} - -static void LinkPartnerHandleHidePartyStatusSummary(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleEndBounceEffect(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleSpriteInvisibility(void) -{ - if (IsBattlerSpritePresent(gActiveBattler)) - { - gSprites[gBattlerSpriteIds[gActiveBattler]].invisible = gBattleResources->bufferA[gActiveBattler][1]; - CopyBattleSpriteInvisibility(gActiveBattler); - } - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleBattleAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u8 animationId = gBattleResources->bufferA[gActiveBattler][1]; - u16 argument = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (TryHandleLaunchBattleTableAnimation(gActiveBattler, gActiveBattler, gActiveBattler, animationId, argument)) - LinkPartnerBufferExecCompleted(); - else - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; - - BattleTv_SetDataBasedOnAnimation(animationId); - } -} - -static void LinkPartnerHandleLinkStandbyMsg(void) -{ - RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[gActiveBattler][2]); - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleResetActionMoveSelection(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerHandleEndLinkBattle(void) -{ - RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[gActiveBattler][4]); - gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; - gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[gActiveBattler][2]; + RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]); + gBattleOutcome = gBattleResources->bufferA[battler][1]; + gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2]; FadeOutMapMusic(5); BeginFastPaletteFade(3); - LinkPartnerBufferExecCompleted(); - gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; -} - -static void LinkPartnerHandleBattleDebug(void) -{ - LinkPartnerBufferExecCompleted(); -} - -static void LinkPartnerCmdEnd(void) -{ + LinkPartnerBufferExecCompleted(battler); + gBattlerControllerFuncs[battler] = SetBattleEndCallbacks; } diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index a786dafa6..93e6a2bab 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -39,248 +39,162 @@ #include "constants/trainers.h" #include "trainer_hill.h" -static void OpponentHandleGetMonData(void); -static void OpponentHandleGetRawMonData(void); -static void OpponentHandleSetMonData(void); -static void OpponentHandleSetRawMonData(void); -static void OpponentHandleLoadMonSprite(void); -static void OpponentHandleSwitchInAnim(void); -static void OpponentHandleReturnMonToBall(void); -static void OpponentHandleDrawTrainerPic(void); -static void OpponentHandleTrainerSlide(void); -static void OpponentHandleTrainerSlideBack(void); -static void OpponentHandleFaintAnimation(void); -static void OpponentHandlePaletteFade(void); -static void OpponentHandleSuccessBallThrowAnim(void); -static void OpponentHandleBallThrow(void); -static void OpponentHandlePause(void); -static void OpponentHandleMoveAnimation(void); -static void OpponentHandlePrintString(void); -static void OpponentHandlePrintSelectionString(void); -static void OpponentHandleChooseAction(void); -static void OpponentHandleYesNoBox(void); -static void OpponentHandleChooseMove(void); -static void OpponentHandleChooseItem(void); -static void OpponentHandleChoosePokemon(void); -static void OpponentHandleCmd23(void); -static void OpponentHandleHealthBarUpdate(void); -static void OpponentHandleExpUpdate(void); -static void OpponentHandleStatusIconUpdate(void); -static void OpponentHandleStatusAnimation(void); -static void OpponentHandleStatusXor(void); -static void OpponentHandleDataTransfer(void); -static void OpponentHandleDMA3Transfer(void); -static void OpponentHandlePlayBGM(void); -static void OpponentHandleCmd32(void); -static void OpponentHandleTwoReturnValues(void); -static void OpponentHandleChosenMonReturnValue(void); -static void OpponentHandleOneReturnValue(void); -static void OpponentHandleOneReturnValue_Duplicate(void); -static void OpponentHandleClearUnkVar(void); -static void OpponentHandleSetUnkVar(void); -static void OpponentHandleClearUnkFlag(void); -static void OpponentHandleToggleUnkFlag(void); -static void OpponentHandleHitAnimation(void); -static void OpponentHandleCantSwitch(void); -static void OpponentHandlePlaySE(void); -static void OpponentHandlePlayFanfareOrBGM(void); -static void OpponentHandleFaintingCry(void); -static void OpponentHandleIntroSlide(void); -static void OpponentHandleIntroTrainerBallThrow(void); -static void OpponentHandleDrawPartyStatusSummary(void); -static void OpponentHandleHidePartyStatusSummary(void); -static void OpponentHandleEndBounceEffect(void); -static void OpponentHandleSpriteInvisibility(void); -static void OpponentHandleBattleAnimation(void); -static void OpponentHandleLinkStandbyMsg(void); -static void OpponentHandleResetActionMoveSelection(void); -static void OpponentHandleEndLinkBattle(void); -static void OpponentHandleDebugMenu(void); -static void OpponentCmdEnd(void); +static void OpponentHandleLoadMonSprite(u32 battler); +static void OpponentHandleSwitchInAnim(u32 battler); +static void OpponentHandleDrawTrainerPic(u32 battler); +static void OpponentHandleTrainerSlide(u32 battler); +static void OpponentHandleTrainerSlideBack(u32 battler); +static void OpponentHandleMoveAnimation(u32 battler); +static void OpponentHandlePrintString(u32 battler); +static void OpponentHandleChooseAction(u32 battler); +static void OpponentHandleChooseMove(u32 battler); +static void OpponentHandleChooseItem(u32 battler); +static void OpponentHandleChoosePokemon(u32 battler); +static void OpponentHandleHealthBarUpdate(u32 battler); +static void OpponentHandleIntroTrainerBallThrow(u32 battler); +static void OpponentHandleDrawPartyStatusSummary(u32 battler); +static void OpponentHandleBattleAnimation(u32 battler); +static void OpponentHandleEndLinkBattle(u32 battler); static u8 CountAIAliveNonEggMonsExcept(u8 slotToIgnore); -static void OpponentBufferRunCommand(void); -static void OpponentBufferExecCompleted(void); -static void SwitchIn_HandleSoundAndEnd(void); -static u32 GetOpponentMonData(u8 monId, u8 *dst); -static void SetOpponentMonData(u8 monId); -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit); -static void DoSwitchOutAnimation(void); -static void OpponentDoMoveAnimation(void); -static void SpriteCB_FreeOpponentSprite(struct Sprite *sprite); -static void Task_StartSendOutAnim(u8 taskId); -static void EndDrawPartyStatusSummary(void); +static void OpponentBufferRunCommand(u32 battler); +static void OpponentBufferExecCompleted(u32 battler); +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] = OpponentHandleGetMonData, - [CONTROLLER_GETRAWMONDATA] = OpponentHandleGetRawMonData, - [CONTROLLER_SETMONDATA] = OpponentHandleSetMonData, - [CONTROLLER_SETRAWMONDATA] = OpponentHandleSetRawMonData, + [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, + [CONTROLLER_GETRAWMONDATA] = BtlController_HandleGetRawMonData, + [CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, + [CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData, [CONTROLLER_LOADMONSPRITE] = OpponentHandleLoadMonSprite, [CONTROLLER_SWITCHINANIM] = OpponentHandleSwitchInAnim, - [CONTROLLER_RETURNMONTOBALL] = OpponentHandleReturnMonToBall, + [CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, [CONTROLLER_DRAWTRAINERPIC] = OpponentHandleDrawTrainerPic, [CONTROLLER_TRAINERSLIDE] = OpponentHandleTrainerSlide, [CONTROLLER_TRAINERSLIDEBACK] = OpponentHandleTrainerSlideBack, - [CONTROLLER_FAINTANIMATION] = OpponentHandleFaintAnimation, - [CONTROLLER_PALETTEFADE] = OpponentHandlePaletteFade, - [CONTROLLER_SUCCESSBALLTHROWANIM] = OpponentHandleSuccessBallThrowAnim, - [CONTROLLER_BALLTHROWANIM] = OpponentHandleBallThrow, - [CONTROLLER_PAUSE] = OpponentHandlePause, + [CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, + [CONTROLLER_PALETTEFADE] = BtlController_Empty, + [CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty, + [CONTROLLER_BALLTHROWANIM] = BtlController_Empty, + [CONTROLLER_PAUSE] = BtlController_Empty, [CONTROLLER_MOVEANIMATION] = OpponentHandleMoveAnimation, [CONTROLLER_PRINTSTRING] = OpponentHandlePrintString, - [CONTROLLER_PRINTSTRINGPLAYERONLY] = OpponentHandlePrintSelectionString, + [CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty, [CONTROLLER_CHOOSEACTION] = OpponentHandleChooseAction, - [CONTROLLER_YESNOBOX] = OpponentHandleYesNoBox, + [CONTROLLER_YESNOBOX] = BtlController_Empty, [CONTROLLER_CHOOSEMOVE] = OpponentHandleChooseMove, [CONTROLLER_OPENBAG] = OpponentHandleChooseItem, [CONTROLLER_CHOOSEPOKEMON] = OpponentHandleChoosePokemon, - [CONTROLLER_23] = OpponentHandleCmd23, + [CONTROLLER_23] = BtlController_Empty, [CONTROLLER_HEALTHBARUPDATE] = OpponentHandleHealthBarUpdate, - [CONTROLLER_EXPUPDATE] = OpponentHandleExpUpdate, - [CONTROLLER_STATUSICONUPDATE] = OpponentHandleStatusIconUpdate, - [CONTROLLER_STATUSANIMATION] = OpponentHandleStatusAnimation, - [CONTROLLER_STATUSXOR] = OpponentHandleStatusXor, - [CONTROLLER_DATATRANSFER] = OpponentHandleDataTransfer, - [CONTROLLER_DMA3TRANSFER] = OpponentHandleDMA3Transfer, - [CONTROLLER_PLAYBGM] = OpponentHandlePlayBGM, - [CONTROLLER_32] = OpponentHandleCmd32, - [CONTROLLER_TWORETURNVALUES] = OpponentHandleTwoReturnValues, - [CONTROLLER_CHOSENMONRETURNVALUE] = OpponentHandleChosenMonReturnValue, - [CONTROLLER_ONERETURNVALUE] = OpponentHandleOneReturnValue, - [CONTROLLER_ONERETURNVALUE_DUPLICATE] = OpponentHandleOneReturnValue_Duplicate, - [CONTROLLER_CLEARUNKVAR] = OpponentHandleClearUnkVar, - [CONTROLLER_SETUNKVAR] = OpponentHandleSetUnkVar, - [CONTROLLER_CLEARUNKFLAG] = OpponentHandleClearUnkFlag, - [CONTROLLER_TOGGLEUNKFLAG] = OpponentHandleToggleUnkFlag, - [CONTROLLER_HITANIMATION] = OpponentHandleHitAnimation, - [CONTROLLER_CANTSWITCH] = OpponentHandleCantSwitch, - [CONTROLLER_PLAYSE] = OpponentHandlePlaySE, - [CONTROLLER_PLAYFANFAREORBGM] = OpponentHandlePlayFanfareOrBGM, - [CONTROLLER_FAINTINGCRY] = OpponentHandleFaintingCry, - [CONTROLLER_INTROSLIDE] = OpponentHandleIntroSlide, + [CONTROLLER_EXPUPDATE] = BtlController_Empty, + [CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate, + [CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation, + [CONTROLLER_STATUSXOR] = BtlController_Empty, + [CONTROLLER_DATATRANSFER] = BtlController_Empty, + [CONTROLLER_DMA3TRANSFER] = BtlController_Empty, + [CONTROLLER_PLAYBGM] = BtlController_Empty, + [CONTROLLER_32] = BtlController_Empty, + [CONTROLLER_TWORETURNVALUES] = BtlController_Empty, + [CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, + [CONTROLLER_CLEARUNKVAR] = BtlController_HandleClearUnkVar, + [CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar, + [CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag, + [CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag, + [CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, + [CONTROLLER_CANTSWITCH] = BtlController_Empty, + [CONTROLLER_PLAYSE] = BtlController_HandlePlaySE, + [CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, + [CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry, + [CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, [CONTROLLER_INTROTRAINERBALLTHROW] = OpponentHandleIntroTrainerBallThrow, [CONTROLLER_DRAWPARTYSTATUSSUMMARY] = OpponentHandleDrawPartyStatusSummary, - [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = OpponentHandleHidePartyStatusSummary, - [CONTROLLER_ENDBOUNCE] = OpponentHandleEndBounceEffect, - [CONTROLLER_SPRITEINVISIBILITY] = OpponentHandleSpriteInvisibility, + [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary, + [CONTROLLER_ENDBOUNCE] = BtlController_Empty, + [CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility, [CONTROLLER_BATTLEANIMATION] = OpponentHandleBattleAnimation, - [CONTROLLER_LINKSTANDBYMSG] = OpponentHandleLinkStandbyMsg, - [CONTROLLER_RESETACTIONMOVESELECTION] = OpponentHandleResetActionMoveSelection, + [CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty, + [CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, [CONTROLLER_ENDLINKBATTLE] = OpponentHandleEndLinkBattle, - [CONTROLLER_DEBUGMENU] = OpponentHandleDebugMenu, - [CONTROLLER_TERMINATOR_NOP] = OpponentCmdEnd + [CONTROLLER_DEBUGMENU] = BtlController_Empty, + [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop }; -// unknown unused data -static const u8 sUnused[] = {0xB0, 0xB0, 0xC8, 0x98, 0x28, 0x28, 0x28, 0x20}; - -static void OpponentDummy(void) +void SetControllerToOpponent(u32 battler) { + gBattlerControllerEndFuncs[battler] = OpponentBufferExecCompleted; + gBattlerControllerFuncs[battler] = OpponentBufferRunCommand; } -void SetControllerToOpponent(void) +static void OpponentBufferRunCommand(u32 battler) { - gBattlerControllerFuncs[gActiveBattler] = OpponentBufferRunCommand; -} - -static void OpponentBufferRunCommand(void) -{ - if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) + if (gBattleControllerExecFlags & gBitTable[battler]) { - if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sOpponentBufferCommands)) - sOpponentBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); + if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sOpponentBufferCommands)) + sOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler); else - OpponentBufferExecCompleted(); + OpponentBufferExecCompleted(battler); } } -static void CompleteOnBattlerSpriteCallbackDummy(void) +static void Intro_DelayAndEnd(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - OpponentBufferExecCompleted(); -} - -static void CompleteOnBankSpriteCallbackDummy2(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - OpponentBufferExecCompleted(); -} - -static void FreeTrainerSpriteAfterSlide(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (--gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay == (u8)-1) { - FreeTrainerFrontPicPalette(gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam); - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - OpponentBufferExecCompleted(); + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0; + OpponentBufferExecCompleted(battler); } } -static void Intro_DelayAndEnd(void) -{ - if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == (u8)-1) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; - OpponentBufferExecCompleted(); - } -} - -static bool32 TwoIntroMons(u32 battlerId) // Double battle with both opponent pokemon active. -{ - return (IsDoubleBattle() - && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[battlerId]]) - && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battlerId)]])); -} - -static void Intro_WaitForShinyAnimAndHealthbox(void) +static void Intro_WaitForShinyAnimAndHealthbox(u32 battler) { bool8 healthboxAnimDone = FALSE; bool8 twoMons; - twoMons = TwoIntroMons(gActiveBattler); + twoMons = TwoOpponentIntroMons(battler); 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; twoMons = FALSE; } else { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy) healthboxAnimDone = TRUE; twoMons = TRUE; } - gBattleControllerOpponentHealthboxData = &gBattleSpritesDataPtr->healthBoxesData[gActiveBattler]; - gBattleControllerOpponentFlankHealthboxData = &gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)]; + gBattleControllerOpponentHealthboxData = &gBattleSpritesDataPtr->healthBoxesData[battler]; + gBattleControllerOpponentFlankHealthboxData = &gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)]; if (healthboxAnimDone) { if (twoMons == TRUE) { - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim - && gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) + if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim + && gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim) { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); } else 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 - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) + if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim) { FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); @@ -288,87 +202,87 @@ static void Intro_WaitForShinyAnimAndHealthbox(void) else return; } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; } else return; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; - gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3; + gBattlerControllerFuncs[battler] = Intro_DelayAndEnd; } } -static void Intro_TryShinyAnimShowHealthbox(void) +static void Intro_TryShinyAnimShowHealthbox(u32 battler) { bool32 bgmRestored = FALSE; bool32 battlerAnimsDone = FALSE; bool32 twoMons; - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) - TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive + && !gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim) + TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]); - twoMons = TwoIntroMons(gActiveBattler); + twoMons = TwoOpponentIntroMons(battler); if (!(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT) && twoMons - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) - TryShinyAnimation(BATTLE_PARTNER(gActiveBattler), &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]]); + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim) + 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)) { - UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); - StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL); + StartHealthboxSlideIn(BATTLE_PARTNER(battler)); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]); } - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gEnemyParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = TRUE; + gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = TRUE; } - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].waitForCry - && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].waitForCry + if (!gBattleSpritesDataPtr->healthBoxesData[battler].waitForCry + && gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].waitForCry && !IsCryPlayingOrClearCrySongs()) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored) { if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK) { - if (GetBattlerPosition(gActiveBattler) == 1) + if (GetBattlerPosition(battler) == 1) m4aMPlayContinue(&gMPlayInfo_BGM); } else m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100); } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = TRUE; + gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = TRUE; bgmRestored = TRUE; } if (!twoMons || (twoMons && gBattleTypeFlags & BATTLE_TYPE_MULTI && !BATTLE_TWO_VS_ONE_OPPONENT)) { - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) { battlerAnimsDone = TRUE; } } else { - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy + && gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy) { battlerAnimsDone = TRUE; } @@ -378,881 +292,124 @@ static void Intro_TryShinyAnimShowHealthbox(void) { if (twoMons && (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) || BATTLE_TWO_VS_ONE_OPPONENT)) { - DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); - SetBattlerShadowSpriteCallback(BATTLE_PARTNER(gActiveBattler), GetMonData(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], MON_DATA_SPECIES)); + DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]]); + SetBattlerShadowSpriteCallback(BATTLE_PARTNER(battler), GetMonData(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], MON_DATA_SPECIES)); } - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + DestroySprite(&gSprites[gBattleControllerData[battler]]); + SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES)); gBattleSpritesDataPtr->animationData->introAnimActive = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = 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 - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) - TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + if (gSprites[gBattlerSpriteIds[battler]].x2 == 0 + && !gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim) + TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]); - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) + if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy + && gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim) { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); - OpponentBufferExecCompleted(); + OpponentBufferExecCompleted(battler); } } -static void CompleteOnHealthbarDone(void) +static void SwitchIn_ShowSubstitute(u32 battler) { - s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - if (hpValue != -1) - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); - else - OpponentBufferExecCompleted(); -} - -static void HideHealthboxAfterMonFaint(void) -{ - if (!gSprites[gBattlerSpriteIds[gActiveBattler]].inUse) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) { - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - OpponentBufferExecCompleted(); + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE); + gBattlerControllerFuncs[battler] = SwitchIn_HandleSoundAndEnd; } } -static void FreeMonSpriteAfterSwitchOutAnim(void) +static void SwitchIn_HandleSoundAndEnd(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive && !IsCryPlayingOrClearCrySongs()) { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - HideBattlerShadowSprite(gActiveBattler); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - OpponentBufferExecCompleted(); - } -} - -static void CompleteOnInactiveTextPrinter(void) -{ - if (!IsTextPrinterActive(B_WIN_MSG)) - OpponentBufferExecCompleted(); -} - -static void DoHitAnimBlinkSpriteEffect(void) -{ - u8 spriteId = gBattlerSpriteIds[gActiveBattler]; - - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = FALSE; - OpponentBufferExecCompleted(); - } - else - { - if ((gSprites[spriteId].data[1] % 4) == 0) - gSprites[spriteId].invisible ^= 1; - gSprites[spriteId].data[1]++; - } -} - -static void SwitchIn_ShowSubstitute(void) -{ - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_HandleSoundAndEnd; - } -} - -static void SwitchIn_HandleSoundAndEnd(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive && !IsCryPlayingOrClearCrySongs()) - { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - || gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy_2) + if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy + || gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy_2) { 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 - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - CopyBattleSpriteInvisibility(gActiveBattler); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowSubstitute; + StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 0); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gEnemyParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); + CopyBattleSpriteInvisibility(battler); + gBattlerControllerFuncs[battler] = SwitchIn_ShowSubstitute; } } -static void SwitchIn_TryShinyAnim(void) +static void SwitchIn_TryShinyAnim(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) - TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) + TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]); - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) { - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowHealthbox; + DestroySprite(&gSprites[gBattleControllerData[battler]]); + SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES)); + gBattlerControllerFuncs[battler] = SwitchIn_ShowHealthbox; } } -static void CompleteOnFinishedStatusAnimation(void) +static void OpponentBufferExecCompleted(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive) - OpponentBufferExecCompleted(); -} - -static void CompleteOnFinishedBattleAnimation(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive) - OpponentBufferExecCompleted(); -} - -static void OpponentBufferExecCompleted(void) -{ - gBattlerControllerFuncs[gActiveBattler] = OpponentBufferRunCommand; + gBattlerControllerFuncs[battler] = OpponentBufferRunCommand; if (gBattleTypeFlags & BATTLE_TYPE_LINK) { u8 playerId = GetMultiplayerId(); PrepareBufferDataTransferLink(2, 4, &playerId); - gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; + gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP; } else { - gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; + gBattleControllerExecFlags &= ~gBitTable[battler]; } } -static void OpponentHandleGetMonData(void) +static void OpponentHandleLoadMonSprite(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 - u32 size = 0; - u8 monToCheck; - s32 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - size += GetOpponentMonData(gBattlerPartyIndexes[gActiveBattler], monData); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - size += GetOpponentMonData(i, monData + size); - monToCheck >>= 1; - } - } - BtlController_EmitDataTransfer(BUFFER_B, size, monData); - OpponentBufferExecCompleted(); + BtlController_HandleLoadMonSprite(battler, TryShinyAnimAfterMonAnim); } -static u32 GetOpponentMonData(u8 monId, u8 *dst) +static void OpponentHandleSwitchInAnim(u32 battler) { - struct BattlePokemon battleMon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - battleMon.species = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES); - battleMon.item = GetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM); - for (size = 0; size < MAX_MON_MOVES; size++) - { - battleMon.moves[size] = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + size); - battleMon.pp[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size); - } - battleMon.ppBonuses = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES); - battleMon.friendship = GetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP); - battleMon.experience = GetMonData(&gEnemyParty[monId], MON_DATA_EXP); - battleMon.hpIV = GetMonData(&gEnemyParty[monId], MON_DATA_HP_IV); - battleMon.attackIV = GetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV); - battleMon.defenseIV = GetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV); - battleMon.speedIV = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV); - battleMon.spAttackIV = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV); - battleMon.spDefenseIV = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV); - battleMon.personality = GetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY); - battleMon.status1 = GetMonData(&gEnemyParty[monId], MON_DATA_STATUS); - battleMon.level = GetMonData(&gEnemyParty[monId], MON_DATA_LEVEL); - battleMon.hp = GetMonData(&gEnemyParty[monId], MON_DATA_HP); - battleMon.maxHP = GetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP); - battleMon.attack = GetMonData(&gEnemyParty[monId], MON_DATA_ATK); - battleMon.defense = GetMonData(&gEnemyParty[monId], MON_DATA_DEF); - battleMon.speed = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED); - battleMon.spAttack = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK); - battleMon.spDefense = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF); - battleMon.abilityNum = GetMonData(&gEnemyParty[monId], MON_DATA_ABILITY_NUM); - battleMon.otId = GetMonData(&gEnemyParty[monId], MON_DATA_OT_ID); - battleMon.metLevel = GetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL); - GetMonData(&gEnemyParty[monId], MON_DATA_NICKNAME, nickname); - StringCopy_Nickname(battleMon.nickname, nickname); - GetMonData(&gEnemyParty[monId], MON_DATA_OT_NAME, battleMon.otName); - src = (u8 *)&battleMon; - for (size = 0; size < sizeof(battleMon); size++) - dst[size] = src[size]; - break; - case REQUEST_SPECIES_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_HELDITEM_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MOVES_PP_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - { - moveData.moves[size] = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES); - src = (u8 *)(&moveData); - for (size = 0; size < sizeof(moveData); size++) - dst[size] = src[size]; - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_PP_DATA_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - dst[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size); - dst[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES); - size++; - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE); - size = 1; - break; - case REQUEST_OTID_BATTLE: - data32 = GetMonData(&gEnemyParty[monId], MON_DATA_OT_ID); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_EXP_BATTLE: - data32 = GetMonData(&gEnemyParty[monId], MON_DATA_EXP); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_HP_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_HP_EV); - size = 1; - break; - case REQUEST_ATK_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_ATK_EV); - size = 1; - break; - case REQUEST_DEF_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_DEF_EV); - size = 1; - break; - case REQUEST_SPEED_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED_EV); - size = 1; - break; - case REQUEST_SPATK_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK_EV); - size = 1; - break; - case REQUEST_SPDEF_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_EV); - size = 1; - break; - case REQUEST_FRIENDSHIP_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP); - size = 1; - break; - case REQUEST_POKERUS_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_POKERUS); - size = 1; - break; - case REQUEST_MET_LOCATION_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_MET_LOCATION); - size = 1; - break; - case REQUEST_MET_LEVEL_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL); - size = 1; - break; - case REQUEST_MET_GAME_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_MET_GAME); - size = 1; - break; - case REQUEST_POKEBALL_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_POKEBALL); - size = 1; - break; - case REQUEST_ALL_IVS_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_HP_IV); - dst[1] = GetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV); - dst[2] = GetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV); - dst[3] = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV); - dst[4] = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV); - dst[5] = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV); - size = 6; - break; - case REQUEST_HP_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_HP_IV); - size = 1; - break; - case REQUEST_ATK_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV); - size = 1; - break; - case REQUEST_DEF_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV); - size = 1; - break; - case REQUEST_SPEED_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV); - size = 1; - break; - case REQUEST_SPATK_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV); - size = 1; - break; - case REQUEST_SPDEF_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV); - size = 1; - break; - case REQUEST_PERSONALITY_BATTLE: - data32 = GetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_CHECKSUM_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_CHECKSUM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_STATUS_BATTLE: - data32 = GetMonData(&gEnemyParty[monId], MON_DATA_STATUS); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_LEVEL_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_LEVEL); - size = 1; - break; - case REQUEST_HP_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MAX_HP_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_ATK_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_ATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_DEF_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_DEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPEED_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPATK_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPDEF_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_COOL_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_COOL); - size = 1; - break; - case REQUEST_BEAUTY_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY); - size = 1; - break; - case REQUEST_CUTE_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_CUTE); - size = 1; - break; - case REQUEST_SMART_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SMART); - size = 1; - break; - case REQUEST_TOUGH_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_TOUGH); - size = 1; - break; - case REQUEST_SHEEN_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SHEEN); - size = 1; - break; - case REQUEST_COOL_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_COOL_RIBBON); - size = 1; - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case REQUEST_CUTE_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case REQUEST_SMART_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SMART_RIBBON); - size = 1; - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - - return size; + gBattleStruct->monToSwitchIntoId[battler] = PARTY_SIZE; + BtlController_HandleSwitchInAnim(battler, FALSE, SwitchIn_TryShinyAnim); } -static void OpponentHandleGetRawMonData(void) -{ - struct BattlePokemon battleMon; - u8 *src = (u8 *)&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleResources->bufferA[gActiveBattler][1]; - u8 *dst = (u8 *)&battleMon + gBattleResources->bufferA[gActiveBattler][1]; - u8 i; - - for (i = 0; i < gBattleResources->bufferA[gActiveBattler][2]; i++) - dst[i] = src[i]; - - BtlController_EmitDataTransfer(BUFFER_B, gBattleResources->bufferA[gActiveBattler][2], dst); - OpponentBufferExecCompleted(); -} - -static void OpponentHandleSetMonData(void) -{ - u8 monToCheck; - u8 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - SetOpponentMonData(gBattlerPartyIndexes[gActiveBattler]); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - SetOpponentMonData(i); - monToCheck >>= 1; - } - } - OpponentBufferExecCompleted(); -} - -static void SetOpponentMonData(u8 monId) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleResources->bufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleResources->bufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - { - u8 iv; - - SetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gEnemyParty[monId], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gEnemyParty[monId], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gEnemyParty[monId], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gEnemyParty[monId], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gEnemyParty[monId], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gEnemyParty[monId], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case REQUEST_SPECIES_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HELDITEM_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MOVES_PP_BATTLE: - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PP_DATA_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_PP1, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP2, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP3, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP4, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES, &gBattleResources->bufferA[gActiveBattler][7]); - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_OTID_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_OT_ID, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_EXP_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_EXP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HP_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_ATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_DEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_FRIENDSHIP_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKERUS_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_POKERUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LOCATION_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MET_LOCATION, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LEVEL_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_GAME_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MET_GAME, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKEBALL_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_POKEBALL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ALL_IVS_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][7]); - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][8]); - break; - case REQUEST_HP_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PERSONALITY_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CHECKSUM_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_CHECKSUM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_STATUS_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_STATUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_LEVEL_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MAX_HP_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_ATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_DEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_COOL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_CUTE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SMART, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_TOUGH, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SHEEN_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SHEEN, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_COOL_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_CUTE_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SMART_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_TOUGH_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - } -} - -static void OpponentHandleSetRawMonData(void) -{ - u8 *dst = (u8 *)&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleResources->bufferA[gActiveBattler][1]; - u8 i; - - for (i = 0; i < gBattleResources->bufferA[gActiveBattler][2]; i++) - dst[i] = gBattleResources->bufferA[gActiveBattler][3 + i]; - - OpponentBufferExecCompleted(); -} - -static void OpponentHandleLoadMonSprite(void) -{ - u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(gActiveBattler)); - - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(gActiveBattler, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(gActiveBattler), - GetBattlerSpriteSubpriority(gActiveBattler)); - - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = species; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); - - SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - - gBattlerControllerFuncs[gActiveBattler] = TryShinyAnimAfterMonAnim; -} - -static void OpponentHandleSwitchInAnim(void) -{ - *(gBattleStruct->monToSwitchIntoId + gActiveBattler) = PARTY_SIZE; - gBattlerPartyIndexes[gActiveBattler] = gBattleResources->bufferA[gActiveBattler][1]; - StartSendOutAnim(gActiveBattler, gBattleResources->bufferA[gActiveBattler][2]); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_TryShinyAnim; -} - -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit) -{ - u16 species; - - ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit); - gBattlerPartyIndexes[battlerId] = gBattleResources->bufferA[battlerId][1]; - species = GetIllusionMonSpecies(battlerId); - if (species == SPECIES_NONE) - species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); - gBattleControllerData[battlerId] = CreateInvisibleSpriteWithCallback(SpriteCB_WaitForBattlerBallReleaseAnim); - BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battlerId)); - - gBattlerSpriteIds[battlerId] = CreateSprite(&gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(battlerId), - GetBattlerSpriteSubpriority(battlerId)); - - gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId; - gSprites[gBattlerSpriteIds[battlerId]].data[2] = species; - - gSprites[gBattleControllerData[battlerId]].data[1] = gBattlerSpriteIds[battlerId]; - gSprites[gBattleControllerData[battlerId]].data[2] = battlerId; - - gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId; - - StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], 0); - - gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE; - gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy; - - gSprites[gBattleControllerData[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_OPPONENT_SENDOUT); -} - -static void OpponentHandleReturnMonToBall(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] == 0) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = DoSwitchOutAnimation; - } - else - { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - HideBattlerShadowSprite(gActiveBattler); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - OpponentBufferExecCompleted(); - } -} - -static void DoSwitchOutAnimation(void) -{ - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SWITCH_OUT_OPPONENT_MON); - gBattlerControllerFuncs[gActiveBattler] = FreeMonSpriteAfterSwitchOutAnim; - } - break; - } -} - -#define sSpeedX data[0] - -static void OpponentHandleDrawTrainerPic(void) +static u32 OpponentGetTrainerPicId(u32 battlerId) { u32 trainerPicId; - s16 xPos; if (gBattleTypeFlags & BATTLE_TYPE_SECRET_BASE) { @@ -1266,7 +423,7 @@ static void OpponentHandleDrawTrainerPic(void) { if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) { - if (gActiveBattler == 1) + if (battlerId == 1) trainerPicId = GetTrainerHillTrainerFrontSpriteId(gTrainerBattleOpponent_A); else trainerPicId = GetTrainerHillTrainerFrontSpriteId(gTrainerBattleOpponent_B); @@ -1280,7 +437,7 @@ static void OpponentHandleDrawTrainerPic(void) { if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_TOWER_LINK_MULTI)) { - if (gActiveBattler == 1) + if (battlerId == 1) trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); else trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B); @@ -1296,7 +453,7 @@ static void OpponentHandleDrawTrainerPic(void) } else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) { - if (gActiveBattler != 1) + if (battlerId != 1) trainerPicId = gTrainers[gTrainerBattleOpponent_B].trainerPic; else trainerPicId = gTrainers[gTrainerBattleOpponent_A].trainerPic; @@ -1306,9 +463,17 @@ static void OpponentHandleDrawTrainerPic(void) trainerPicId = gTrainers[gTrainerBattleOpponent_A].trainerPic; } + return trainerPicId; +} + +static void OpponentHandleDrawTrainerPic(u32 battler) +{ + s16 xPos; + u32 trainerPicId = OpponentGetTrainerPicId(battler); + 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; else // first mon xPos = 200; @@ -1318,246 +483,42 @@ static void OpponentHandleDrawTrainerPic(void) xPos = 176; } - DecompressTrainerFrontPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, - xPos, - (8 - gTrainerFrontPicCoords[trainerPicId].size) * 4 + 40, - GetBattlerSpriteSubpriority(gActiveBattler)); - - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = 2; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam = trainerPicId; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy; + BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, + xPos, 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicId].size), + -1); } -static void OpponentHandleTrainerSlide(void) +static void OpponentHandleTrainerSlide(u32 battler) { - u32 trainerPicId; - - if (gBattleTypeFlags & BATTLE_TYPE_SECRET_BASE) - { - trainerPicId = GetSecretBaseTrainerPicIndex(); - } - else if (gTrainerBattleOpponent_A == TRAINER_FRONTIER_BRAIN) - { - trainerPicId = GetFrontierBrainTrainerPicIndex(); - } - else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_HILL) - { - if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) - { - if (gActiveBattler == 1) - trainerPicId = GetTrainerHillTrainerFrontSpriteId(gTrainerBattleOpponent_A); - else - trainerPicId = GetTrainerHillTrainerFrontSpriteId(gTrainerBattleOpponent_B); - } - else - { - trainerPicId = GetTrainerHillTrainerFrontSpriteId(gTrainerBattleOpponent_A); - } - } - else if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER) - { - if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_TOWER_LINK_MULTI)) - { - if (gActiveBattler == 1) - trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); - else - trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B); - } - else - { - trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); - } - } - else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) - { - trainerPicId = GetEreaderTrainerFrontSpriteId(); - } - else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) - { - if (gActiveBattler != 1) - trainerPicId = gTrainers[gTrainerBattleOpponent_B].trainerPic; - else - trainerPicId = gTrainers[gTrainerBattleOpponent_A].trainerPic; - } - else - { - trainerPicId = gTrainers[gTrainerBattleOpponent_A].trainerPic; - } - - DecompressTrainerFrontPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, 176, (8 - gTrainerFrontPicCoords[trainerPicId].size) * 4 + 40, 0x1E); - - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = 96; - gSprites[gBattlerSpriteIds[gActiveBattler]].x += 32; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = -2; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam = trainerPicId; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBankSpriteCallbackDummy2; + u32 trainerPicId = OpponentGetTrainerPicId(battler); + BtlController_HandleTrainerSlide(battler, trainerPicId); } -#undef sSpeedX - -static void OpponentHandleTrainerSlideBack(void) +static void OpponentHandleTrainerSlideBack(u32 battler) { - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = 280; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCallbackDummy); - gBattlerControllerFuncs[gActiveBattler] = FreeTrainerSpriteAfterSlide; + BtlController_HandleTrainerSlideBack(battler, 35, FALSE); } -static void OpponentHandleFaintAnimation(void) +static void OpponentHandleMoveAnimation(u32 battler) { - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState == 0) - { - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState++; - } - else - { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - PlaySE12WithPanning(SE_FAINT, SOUND_PAN_TARGET); - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_FaintOpponentMon; - gBattlerControllerFuncs[gActiveBattler] = HideHealthboxAfterMonFaint; - } - } + BtlController_HandleMoveAnimation(battler, FALSE); } -static void OpponentHandlePaletteFade(void) +static void OpponentHandlePrintString(u32 battler) { - OpponentBufferExecCompleted(); + BtlController_HandlePrintString(battler, FALSE, TRUE); } -static void OpponentHandleSuccessBallThrowAnim(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleBallThrow(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandlePause(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleMoveAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleResources->bufferA[gActiveBattler][3]; - gAnimMovePower = gBattleResources->bufferA[gActiveBattler][4] | (gBattleResources->bufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleResources->bufferA[gActiveBattler][6] | (gBattleResources->bufferA[gActiveBattler][7] << 8) | (gBattleResources->bufferA[gActiveBattler][8] << 16) | (gBattleResources->bufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleResources->bufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleResources->bufferA[gActiveBattler][12] | (gBattleResources->bufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - gTransformedOtIds[gActiveBattler] = gAnimDisableStructPtr->transformedMonOtId; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = OpponentDoMoveAnimation; - } -} - -static void OpponentDoMoveAnimation(void) -{ - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - u8 multihit = gBattleResources->bufferA[gActiveBattler][11]; - - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute - && !gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8) - { - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 1; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF); - DoMoveAnim(move); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL); - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute && multihit < 2) - { - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 0; - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 3; - } - break; - case 3: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - CopyAllBattleSpritesInvisibilities(); - TrySetBehindSubstituteSpriteBit(gActiveBattler, gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - OpponentBufferExecCompleted(); - } - break; - } -} - -static void OpponentHandlePrintString(void) -{ - u16 *stringId; - - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - stringId = (u16 *)(&gBattleResources->bufferA[gActiveBattler][2]); - BufferStringBattle(*stringId); - BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter; - BattleArena_DeductSkillPoints(gActiveBattler, *stringId); -} - -static void OpponentHandlePrintSelectionString(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleChooseAction(void) +static void OpponentHandleChooseAction(u32 battler) { AI_TrySwitchOrUseItem(); - OpponentBufferExecCompleted(); + OpponentBufferExecCompleted(battler); } -static void OpponentHandleYesNoBox(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleChooseMove(void) +static void OpponentHandleChooseMove(u32 battler) { 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) || IsWildMonSmart()) @@ -1568,8 +529,8 @@ static void OpponentHandleChooseMove(void) } else { - chosenMoveId = gBattleStruct->aiMoveOrAction[gActiveBattler]; - gBattlerTarget = gBattleStruct->aiChosenTarget[gActiveBattler]; + chosenMoveId = gBattleStruct->aiMoveOrAction[battler]; + gBattlerTarget = gBattleStruct->aiChosenTarget[battler]; switch (chosenMoveId) { case AI_CHOICE_WATCH: @@ -1588,17 +549,17 @@ static void OpponentHandleChooseMove(void) { u16 chosenMove = moveInfo->moves[chosenMoveId]; - if (GetBattlerMoveTargetType(gActiveBattler, chosenMove) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER)) - gBattlerTarget = gActiveBattler; - if (GetBattlerMoveTargetType(gActiveBattler, chosenMove) & MOVE_TARGET_BOTH) + if (GetBattlerMoveTargetType(battler, chosenMove) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER)) + gBattlerTarget = battler; + if (GetBattlerMoveTargetType(battler, chosenMove) & MOVE_TARGET_BOTH) { gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); } - if (ShouldUseZMove(gActiveBattler, gBattlerTarget, chosenMove)) - QueueZMove(gActiveBattler, chosenMove); - if (CanMegaEvolve(gActiveBattler)) // If opponent can mega evolve, do it. + if (ShouldUseZMove(battler, gBattlerTarget, chosenMove)) + QueueZMove(battler, chosenMove); + if (CanMegaEvolve(battler)) // If opponent can mega evolve, do it. BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8)); else BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gBattlerTarget << 8)); @@ -1606,7 +567,7 @@ static void OpponentHandleChooseMove(void) break; } } - OpponentBufferExecCompleted(); + OpponentBufferExecCompleted(battler); } else // Wild pokemon - use random move { @@ -1618,13 +579,13 @@ static void OpponentHandleChooseMove(void) move = moveInfo->moves[chosenMoveId]; } while (move == MOVE_NONE); - if (GetBattlerMoveTargetType(gActiveBattler, move) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER)) - BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gActiveBattler << 8)); + if (GetBattlerMoveTargetType(battler, move) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER)) + BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (battler << 8)); else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) { do { target = GetBattlerAtPosition(Random() & 2); - } while (!CanTargetBattler(gActiveBattler, target, move)); + } while (!CanTargetBattler(battler, target, move)); #if B_WILD_NATURAL_ENEMIES == TRUE // Don't bother to loop through table if the move can't attack ally @@ -1641,8 +602,8 @@ static void OpponentHandleChooseMove(void) {SPECIES_SABLEYE, SPECIES_CARBINK}, {SPECIES_MAREANIE, SPECIES_CORSOLA}, }; - speciesAttacker = gBattleMons[gActiveBattler].species; - speciesTarget = gBattleMons[GetBattlerAtPosition(BATTLE_PARTNER(gActiveBattler))].species; + speciesAttacker = gBattleMons[battler].species; + speciesTarget = gBattleMons[GetBattlerAtPosition(BATTLE_PARTNER(battler))].species; for (i = 0; i < ARRAY_COUNT(naturalEnemies); i++) { @@ -1652,8 +613,8 @@ static void OpponentHandleChooseMove(void) break; } } - if (isPartnerEnemy && CanTargetBattler(gActiveBattler, target, move)) - BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(BATTLE_PARTNER(gActiveBattler)) << 8)); + if (isPartnerEnemy && CanTargetBattler(battler, target, move)) + BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (GetBattlerAtPosition(BATTLE_PARTNER(battler)) << 8)); else BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (target << 8)); } @@ -1664,28 +625,28 @@ static void OpponentHandleChooseMove(void) else 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]); - OpponentBufferExecCompleted(); + BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[battler]); + OpponentBufferExecCompleted(battler); } -static void OpponentHandleChoosePokemon(void) +static void OpponentHandleChoosePokemon(u32 battler) { s32 chosenMonId; s32 pokemonInBattle = 1; // 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 - else if (*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) == PARTY_SIZE) + else if (*(gBattleStruct->AI_monToSwitchIntoId + battler) == PARTY_SIZE) { chosenMonId = GetMostSuitableMonToSwitchInto(); if (chosenMonId == PARTY_SIZE) @@ -1703,7 +664,7 @@ static void OpponentHandleChoosePokemon(void) pokemonInBattle = 2; } - GetAIPartyIndexes(gActiveBattler, &firstId, &lastId); + GetAIPartyIndexes(battler, &firstId, &lastId); for (chosenMonId = (lastId-1); chosenMonId >= firstId; chosenMonId--) { @@ -1718,16 +679,16 @@ static void OpponentHandleChoosePokemon(void) } } } - *(gBattleStruct->monToSwitchIntoId + gActiveBattler) = chosenMonId; + *(gBattleStruct->monToSwitchIntoId + battler) = chosenMonId; } else { - chosenMonId = *(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler); - *(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) = PARTY_SIZE; - *(gBattleStruct->monToSwitchIntoId + gActiveBattler) = chosenMonId; + chosenMonId = *(gBattleStruct->AI_monToSwitchIntoId + battler); + *(gBattleStruct->AI_monToSwitchIntoId + battler) = PARTY_SIZE; + *(gBattleStruct->monToSwitchIntoId + battler) = chosenMonId; } BtlController_EmitChosenMonReturnValue(BUFFER_B, chosenMonId, NULL); - OpponentBufferExecCompleted(); + OpponentBufferExecCompleted(battler); } @@ -1738,9 +699,7 @@ static u8 CountAIAliveNonEggMonsExcept(u8 slotToIgnore) for (i = 0, count = 0; i < PARTY_SIZE; i++) { if (i != slotToIgnore - && GetMonData(&gEnemyParty[i], MON_DATA_SPECIES) != SPECIES_NONE - && !GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG) - && GetMonData(&gEnemyParty[i], MON_DATA_HP) != 0) + && IsValidForBattle(&gEnemyParty[i])) { count++; } @@ -1749,343 +708,27 @@ static u8 CountAIAliveNonEggMonsExcept(u8 slotToIgnore) return count; } -static void OpponentHandleCmd23(void) +static void OpponentHandleHealthBarUpdate(u32 battler) { - OpponentBufferExecCompleted(); + BtlController_HandleHealthBarUpdate(battler, FALSE); } -static void OpponentHandleHealthBarUpdate(void) +static void OpponentHandleIntroTrainerBallThrow(u32 battler) { - s16 hpVal; - - LoadBattleBarGfx(0); - hpVal = (gBattleResources->bufferA[gActiveBattler][3] << 8) | gBattleResources->bufferA[gActiveBattler][2]; - - if (hpVal != INSTANT_HP_BAR_DROP) - { - u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - u32 curHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); - - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, curHP, hpVal); - } - else - { - u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); - } - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone; + BtlController_HandleIntroTrainerBallThrow(battler, 0, NULL, 0, Intro_TryShinyAnimShowHealthbox); } -static void OpponentHandleExpUpdate(void) +static void OpponentHandleDrawPartyStatusSummary(u32 battler) { - OpponentBufferExecCompleted(); + BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_OPPONENT, TRUE); } -static void OpponentHandleStatusIconUpdate(void) +static void OpponentHandleBattleAnimation(u32 battler) { - if (!IsBattleSEPlaying(gActiveBattler)) - { - u8 battlerId; - - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON); - battlerId = gActiveBattler; - gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0; - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - } + BtlController_HandleBattleAnimation(battler, FALSE, FALSE); } -static void OpponentHandleStatusAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - InitAndLaunchChosenStatusAnimation(gBattleResources->bufferA[gActiveBattler][1], - gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8) | (gBattleResources->bufferA[gActiveBattler][4] << 16) | (gBattleResources->bufferA[gActiveBattler][5] << 24)); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - } -} - -static void OpponentHandleStatusXor(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleDataTransfer(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleDMA3Transfer(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandlePlayBGM(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleCmd32(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleTwoReturnValues(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleChosenMonReturnValue(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleOneReturnValue(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleOneReturnValue_Duplicate(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleClearUnkVar(void) -{ - gUnusedControllerStruct.unk = 0; - OpponentBufferExecCompleted(); -} - -static void OpponentHandleSetUnkVar(void) -{ - gUnusedControllerStruct.unk = gBattleResources->bufferA[gActiveBattler][1]; - OpponentBufferExecCompleted(); -} - -static void OpponentHandleClearUnkFlag(void) -{ - gUnusedControllerStruct.flag = 0; - OpponentBufferExecCompleted(); -} - -static void OpponentHandleToggleUnkFlag(void) -{ - gUnusedControllerStruct.flag ^= 1; - OpponentBufferExecCompleted(); -} - -static void OpponentHandleHitAnimation(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].invisible == TRUE) - { - OpponentBufferExecCompleted(); - } - else - { - gDoingBattleAnim = TRUE; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[1] = 0; - DoHitAnimHealthboxEffect(gActiveBattler); - gBattlerControllerFuncs[gActiveBattler] = DoHitAnimBlinkSpriteEffect; - } -} - -static void OpponentHandleCantSwitch(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandlePlaySE(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - pan = SOUND_PAN_ATTACKER; - else - pan = SOUND_PAN_TARGET; - - PlaySE12WithPanning(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8), pan); - OpponentBufferExecCompleted(); -} - -static void OpponentHandlePlayFanfareOrBGM(void) -{ - if (gBattleResources->bufferA[gActiveBattler][3]) - { - BattleStopLowHpSound(); - PlayBGM(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - else - { - PlayFanfare(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - - OpponentBufferExecCompleted(); -} - -static void OpponentHandleFaintingCry(void) -{ - u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - PlayCry_ByMode(species, 25, CRY_MODE_FAINT); - OpponentBufferExecCompleted(); -} - -static void OpponentHandleIntroSlide(void) -{ - HandleIntroSlide(gBattleResources->bufferA[gActiveBattler][1]); - gIntroSlideFlags |= 1; - OpponentBufferExecCompleted(); -} - -static void OpponentHandleIntroTrainerBallThrow(void) -{ - u8 taskId; - - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = 280; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCB_FreeOpponentSprite); - - taskId = CreateTask(Task_StartSendOutAnim, 5); - gTasks[taskId].data[0] = gActiveBattler; - - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - - gBattleSpritesDataPtr->animationData->introAnimActive = TRUE; - gBattlerControllerFuncs[gActiveBattler] = OpponentDummy; -} - -static void SpriteCB_FreeOpponentSprite(struct Sprite *sprite) -{ - FreeTrainerFrontPicPalette(sprite->oam.affineParam); - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); -} - -static void Task_StartSendOutAnim(u8 taskId) -{ - u8 savedActiveBattler = gActiveBattler; - - gActiveBattler = gTasks[taskId].data[0]; - if ((!TwoIntroMons(gActiveBattler) || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) && !BATTLE_TWO_VS_ONE_OPPONENT) - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - } - else if ((gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) || (BATTLE_TWO_VS_ONE_OPPONENT && !TwoIntroMons(gActiveBattler))) - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - } - else - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler ^= BIT_FLANK; - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler ^= BIT_FLANK; - } - gBattlerControllerFuncs[gActiveBattler] = Intro_TryShinyAnimShowHealthbox; - gActiveBattler = savedActiveBattler; - DestroyTask(taskId); -} - -static void OpponentHandleDrawPartyStatusSummary(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - { - OpponentBufferExecCompleted(); - } - else - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown = 1; - - if (gBattleResources->bufferA[gActiveBattler][2] != 0) - { - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay < 2) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay++; - return; - } - else - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay = 0; - } - } - - gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleResources->bufferA[gActiveBattler][4], gBattleResources->bufferA[gActiveBattler][1], gBattleResources->bufferA[gActiveBattler][2]); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - - if (gBattleResources->bufferA[gActiveBattler][2] != 0) - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 93; - - gBattlerControllerFuncs[gActiveBattler] = EndDrawPartyStatusSummary; - } -} - -static void EndDrawPartyStatusSummary(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer++ > 92) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - OpponentBufferExecCompleted(); - } -} - -static void OpponentHandleHidePartyStatusSummary(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - OpponentBufferExecCompleted(); -} - -static void OpponentHandleEndBounceEffect(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleSpriteInvisibility(void) -{ - if (IsBattlerSpritePresent(gActiveBattler)) - { - gSprites[gBattlerSpriteIds[gActiveBattler]].invisible = gBattleResources->bufferA[gActiveBattler][1]; - CopyBattleSpriteInvisibility(gActiveBattler); - } - OpponentBufferExecCompleted(); -} - -static void OpponentHandleBattleAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u8 animationId = gBattleResources->bufferA[gActiveBattler][1]; - u16 argument = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (TryHandleLaunchBattleTableAnimation(gActiveBattler, gActiveBattler, gActiveBattler, animationId, argument)) - OpponentBufferExecCompleted(); - else - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; - } -} - -static void OpponentHandleLinkStandbyMsg(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleResetActionMoveSelection(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentHandleEndLinkBattle(void) +static void OpponentHandleEndLinkBattle(u32 battler) { if (gBattleTypeFlags & BATTLE_TYPE_LINK && !(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)) { @@ -2093,14 +736,5 @@ static void OpponentHandleEndLinkBattle(void) gMain.callback1 = gPreBattleCallback1; SetMainCallback2(gMain.savedCallback); } - OpponentBufferExecCompleted(); -} - -static void OpponentHandleDebugMenu(void) -{ - OpponentBufferExecCompleted(); -} - -static void OpponentCmdEnd(void) -{ + OpponentBufferExecCompleted(battler); } diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 6950a06b3..b6c47369e 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -37,104 +37,75 @@ #include "constants/trainers.h" #include "constants/rgb.h" -static void PlayerHandleGetMonData(void); -static void PlayerHandleSetMonData(void); -static void PlayerHandleSetRawMonData(void); -static void PlayerHandleLoadMonSprite(void); -static void PlayerHandleSwitchInAnim(void); -static void PlayerHandleReturnMonToBall(void); -static void PlayerHandleDrawTrainerPic(void); -static void PlayerHandleTrainerSlide(void); -static void PlayerHandleTrainerSlideBack(void); -static void PlayerHandleFaintAnimation(void); -static void PlayerHandlePaletteFade(void); -static void PlayerHandleSuccessBallThrowAnim(void); -static void PlayerHandleBallThrowAnim(void); -static void PlayerHandlePause(void); -static void PlayerHandleMoveAnimation(void); -static void PlayerHandlePrintString(void); -static void PlayerHandlePrintSelectionString(void); -static void PlayerHandleChooseAction(void); -static void PlayerHandleYesNoBox(void); -static void PlayerHandleChooseMove(void); -static void PlayerHandleChooseItem(void); -static void PlayerHandleChoosePokemon(void); -static void PlayerHandleCmd23(void); -static void PlayerHandleHealthBarUpdate(void); -static void PlayerHandleExpUpdate(void); -static void PlayerHandleStatusIconUpdate(void); -static void PlayerHandleStatusAnimation(void); -static void PlayerHandleStatusXor(void); -static void PlayerHandleDataTransfer(void); -static void PlayerHandleDMA3Transfer(void); -static void PlayerHandlePlayBGM(void); -static void PlayerHandleCmd32(void); -static void PlayerHandleTwoReturnValues(void); -static void PlayerHandleChosenMonReturnValue(void); -static void PlayerHandleOneReturnValue(void); -static void PlayerHandleOneReturnValue_Duplicate(void); -static void PlayerHandleClearUnkVar(void); -static void PlayerHandleSetUnkVar(void); -static void PlayerHandleClearUnkFlag(void); -static void PlayerHandleToggleUnkFlag(void); -static void PlayerHandleHitAnimation(void); -static void PlayerHandleCantSwitch(void); -static void PlayerHandlePlaySE(void); -static void PlayerHandlePlayFanfareOrBGM(void); -static void PlayerHandleFaintingCry(void); -static void PlayerHandleIntroSlide(void); -static void PlayerHandleIntroTrainerBallThrow(void); -static void PlayerHandleDrawPartyStatusSummary(void); -static void PlayerHandleHidePartyStatusSummary(void); -static void PlayerHandleEndBounceEffect(void); -static void PlayerHandleSpriteInvisibility(void); -static void PlayerHandleBattleAnimation(void); -static void PlayerHandleLinkStandbyMsg(void); -static void PlayerHandleResetActionMoveSelection(void); -static void PlayerHandleEndLinkBattle(void); -static void PlayerHandleBattleDebug(void); -static void PlayerCmdEnd(void); +static void PlayerBufferExecCompleted(u32 battler); +static void PlayerHandleLoadMonSprite(u32 battler); +static void PlayerHandleSwitchInAnim(u32 battler); +static void PlayerHandleDrawTrainerPic(u32 battler); +static void PlayerHandleTrainerSlide(u32 battler); +static void PlayerHandleTrainerSlideBack(u32 battler); +static void PlayerHandlePaletteFade(u32 battler); +static void PlayerHandleSuccessBallThrowAnim(u32 battler); +static void PlayerHandleBallThrowAnim(u32 battler); +static void PlayerHandlePause(u32 battler); +static void PlayerHandleMoveAnimation(u32 battler); +static void PlayerHandlePrintString(u32 battler); +static void PlayerHandlePrintSelectionString(u32 battler); +static void PlayerHandleChooseAction(u32 battler); +static void PlayerHandleYesNoBox(u32 battler); +static void PlayerHandleChooseMove(u32 battler); +static void PlayerHandleChooseItem(u32 battler); +static void PlayerHandleChoosePokemon(u32 battler); +static void PlayerHandleCmd23(u32 battler); +static void PlayerHandleHealthBarUpdate(u32 battler); +static void PlayerHandleStatusXor(u32 battler); +static void PlayerHandleDMA3Transfer(u32 battler); +static void PlayerHandlePlayBGM(u32 battler); +static void PlayerHandleTwoReturnValues(u32 battler); +static void PlayerHandleChosenMonReturnValue(u32 battler); +static void PlayerHandleOneReturnValue(u32 battler); +static void PlayerHandleOneReturnValue_Duplicate(u32 battler); +static void PlayerHandleIntroTrainerBallThrow(u32 battler); +static void PlayerHandleDrawPartyStatusSummary(u32 battler); +static void PlayerHandleEndBounceEffect(u32 battler); +static void PlayerHandleBattleAnimation(u32 battler); +static void PlayerHandleLinkStandbyMsg(u32 battler); +static void PlayerHandleResetActionMoveSelection(u32 battler); +static void PlayerHandleEndLinkBattle(u32 battler); +static void PlayerHandleBattleDebug(u32 battler); -static void PlayerBufferRunCommand(void); -static void HandleInputChooseTarget(void); -static void HandleInputChooseMove(void); -static void MoveSelectionDisplayPpNumber(void); -static void MoveSelectionDisplayPpString(void); -static void MoveSelectionDisplayMoveType(void); -static void MoveSelectionDisplayMoveNames(void); -static void HandleMoveSwitching(void); -static void SwitchIn_HandleSoundAndEnd(void); -static void WaitForMonSelection(void); -static void CompleteWhenChoseItem(void); +static void PlayerBufferRunCommand(u32 battler); +static void HandleInputChooseTarget(u32 battler); +static void HandleInputChooseMove(u32 battler); +static void MoveSelectionDisplayPpNumber(u32 battler); +static void MoveSelectionDisplayPpString(u32 battler); +static void MoveSelectionDisplayMoveType(u32 battler); +static void MoveSelectionDisplayMoveNames(u32 battler); +static void HandleMoveSwitching(u32 battler); +static void SwitchIn_HandleSoundAndEnd(u32 battler); +static void WaitForMonSelection(u32 battler); +static void CompleteWhenChoseItem(u32 battler); static void Task_LaunchLvlUpAnim(u8); static void Task_PrepareToGiveExpWithExpBar(u8); -static void DestroyExpTaskAndCompleteOnInactiveTextPrinter(u8); +static void Task_SetControllerToWaitForString(u8); static void Task_GiveExpWithExpBar(u8); static void Task_UpdateLvlInHealthbox(u8); static void PrintLinkStandbyMsg(void); -static u32 CopyPlayerMonData(u8, u8 *); -static void SetPlayerMonData(u8); -static void StartSendOutAnim(u8, bool8); -static void DoSwitchOutAnimation(void); -static void PlayerDoMoveAnimation(void); -static void Task_StartSendOutAnim(u8); -static void EndDrawPartyStatusSummary(void); -static void ReloadMoveNames(void); +static void ReloadMoveNames(u32 battler); -static void (*const sPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(void) = +static void (*const sPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) = { - [CONTROLLER_GETMONDATA] = PlayerHandleGetMonData, - [CONTROLLER_GETRAWMONDATA] = PlayerHandleGetRawMonData, - [CONTROLLER_SETMONDATA] = PlayerHandleSetMonData, - [CONTROLLER_SETRAWMONDATA] = PlayerHandleSetRawMonData, + [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, + [CONTROLLER_GETRAWMONDATA] = BtlController_HandleGetRawMonData, + [CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, + [CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData, [CONTROLLER_LOADMONSPRITE] = PlayerHandleLoadMonSprite, [CONTROLLER_SWITCHINANIM] = PlayerHandleSwitchInAnim, - [CONTROLLER_RETURNMONTOBALL] = PlayerHandleReturnMonToBall, + [CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, [CONTROLLER_DRAWTRAINERPIC] = PlayerHandleDrawTrainerPic, [CONTROLLER_TRAINERSLIDE] = PlayerHandleTrainerSlide, [CONTROLLER_TRAINERSLIDEBACK] = PlayerHandleTrainerSlideBack, - [CONTROLLER_FAINTANIMATION] = PlayerHandleFaintAnimation, + [CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, [CONTROLLER_PALETTEFADE] = PlayerHandlePaletteFade, [CONTROLLER_SUCCESSBALLTHROWANIM] = PlayerHandleSuccessBallThrowAnim, [CONTROLLER_BALLTHROWANIM] = PlayerHandleBallThrowAnim, @@ -150,88 +121,82 @@ static void (*const sPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(void) = [CONTROLLER_23] = PlayerHandleCmd23, [CONTROLLER_HEALTHBARUPDATE] = PlayerHandleHealthBarUpdate, [CONTROLLER_EXPUPDATE] = PlayerHandleExpUpdate, - [CONTROLLER_STATUSICONUPDATE] = PlayerHandleStatusIconUpdate, - [CONTROLLER_STATUSANIMATION] = PlayerHandleStatusAnimation, + [CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate, + [CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation, [CONTROLLER_STATUSXOR] = PlayerHandleStatusXor, - [CONTROLLER_DATATRANSFER] = PlayerHandleDataTransfer, + [CONTROLLER_DATATRANSFER] = BtlController_Empty, [CONTROLLER_DMA3TRANSFER] = PlayerHandleDMA3Transfer, [CONTROLLER_PLAYBGM] = PlayerHandlePlayBGM, - [CONTROLLER_32] = PlayerHandleCmd32, + [CONTROLLER_32] = BtlController_Empty, [CONTROLLER_TWORETURNVALUES] = PlayerHandleTwoReturnValues, [CONTROLLER_CHOSENMONRETURNVALUE] = PlayerHandleChosenMonReturnValue, [CONTROLLER_ONERETURNVALUE] = PlayerHandleOneReturnValue, [CONTROLLER_ONERETURNVALUE_DUPLICATE] = PlayerHandleOneReturnValue_Duplicate, - [CONTROLLER_CLEARUNKVAR] = PlayerHandleClearUnkVar, - [CONTROLLER_SETUNKVAR] = PlayerHandleSetUnkVar, - [CONTROLLER_CLEARUNKFLAG] = PlayerHandleClearUnkFlag, - [CONTROLLER_TOGGLEUNKFLAG] = PlayerHandleToggleUnkFlag, - [CONTROLLER_HITANIMATION] = PlayerHandleHitAnimation, - [CONTROLLER_CANTSWITCH] = PlayerHandleCantSwitch, - [CONTROLLER_PLAYSE] = PlayerHandlePlaySE, - [CONTROLLER_PLAYFANFAREORBGM] = PlayerHandlePlayFanfareOrBGM, - [CONTROLLER_FAINTINGCRY] = PlayerHandleFaintingCry, - [CONTROLLER_INTROSLIDE] = PlayerHandleIntroSlide, + [CONTROLLER_CLEARUNKVAR] = BtlController_HandleClearUnkVar, + [CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar, + [CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag, + [CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag, + [CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, + [CONTROLLER_CANTSWITCH] = BtlController_Empty, + [CONTROLLER_PLAYSE] = BtlController_HandlePlaySE, + [CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, + [CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry, + [CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, [CONTROLLER_INTROTRAINERBALLTHROW] = PlayerHandleIntroTrainerBallThrow, [CONTROLLER_DRAWPARTYSTATUSSUMMARY] = PlayerHandleDrawPartyStatusSummary, - [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = PlayerHandleHidePartyStatusSummary, + [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary, [CONTROLLER_ENDBOUNCE] = PlayerHandleEndBounceEffect, - [CONTROLLER_SPRITEINVISIBILITY] = PlayerHandleSpriteInvisibility, + [CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility, [CONTROLLER_BATTLEANIMATION] = PlayerHandleBattleAnimation, [CONTROLLER_LINKSTANDBYMSG] = PlayerHandleLinkStandbyMsg, [CONTROLLER_RESETACTIONMOVESELECTION] = PlayerHandleResetActionMoveSelection, [CONTROLLER_ENDLINKBATTLE] = PlayerHandleEndLinkBattle, [CONTROLLER_DEBUGMENU] = PlayerHandleBattleDebug, - [CONTROLLER_TERMINATOR_NOP] = PlayerCmdEnd + [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop }; static EWRAM_DATA bool8 sAckBallUseBtn = FALSE; static EWRAM_DATA bool8 sBallSwapped = FALSE; -// unknown unused data -static const u8 sUnused[] = {0x48, 0x48, 0x20, 0x5a, 0x50, 0x50, 0x50, 0x58}; - -void BattleControllerDummy(void) +void SetControllerToPlayer(u32 battler) { -} - -void SetControllerToPlayer(void) -{ - gBattlerControllerFuncs[gActiveBattler] = PlayerBufferRunCommand; + gBattlerControllerEndFuncs[battler] = PlayerBufferExecCompleted; + gBattlerControllerFuncs[battler] = PlayerBufferRunCommand; gDoingBattleAnim = FALSE; gPlayerDpadHoldFrames = 0; } -static void PlayerBufferExecCompleted(void) +static void PlayerBufferExecCompleted(u32 battler) { - gBattlerControllerFuncs[gActiveBattler] = PlayerBufferRunCommand; + gBattlerControllerFuncs[battler] = PlayerBufferRunCommand; if (gBattleTypeFlags & BATTLE_TYPE_LINK) { u8 playerId = GetMultiplayerId(); PrepareBufferDataTransferLink(2, 4, &playerId); - gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; + gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP; } else { - gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; + gBattleControllerExecFlags &= ~gBitTable[battler]; } } -static void PlayerBufferRunCommand(void) +static void PlayerBufferRunCommand(u32 battler) { - if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) + if (gBattleControllerExecFlags & gBitTable[battler]) { - if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sPlayerBufferCommands)) - sPlayerBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); + if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sPlayerBufferCommands)) + sPlayerBufferCommands[gBattleResources->bufferA[battler][0]](battler); else - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } } -static void CompleteOnBankSpritePosX_0(void) +static void CompleteOnBattlerSpritePosX_0(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].x2 == 0) - PlayerBufferExecCompleted(); + if (gSprites[gBattlerSpriteIds[battler]].x2 == 0) + PlayerBufferExecCompleted(battler); } static u16 GetPrevBall(u16 ballId) @@ -251,7 +216,7 @@ static u16 GetPrevBall(u16 ballId) if (ballPrev != ITEM_NONE) return ballPrev; } - } + } i--; return gBagPockets[BALLS_POCKET].itemSlots[i].itemId; } @@ -277,12 +242,12 @@ static u16 GetNextBall(u16 ballId) } } -static void HandleInputChooseAction(void) +static void HandleInputChooseAction(u32 battler) { - u16 itemId = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); + u16 itemId = gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8); - DoBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX, 7, 1); - DoBounceEffect(gActiveBattler, BOUNCE_MON, 7, 1); + DoBounceEffect(battler, BOUNCE_HEALTHBOX, 7, 1); + DoBounceEffect(battler, BOUNCE_MON, 7, 1); if (JOY_REPEAT(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A) gPlayerDpadHoldFrames++; @@ -339,7 +304,7 @@ static void HandleInputChooseAction(void) ArrowsChangeColorLastBallCycle(FALSE); TryHideLastUsedBall(); BtlController_EmitTwoReturnValues(1, B_ACTION_THROW_BALL, 0); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } return; } @@ -350,7 +315,7 @@ static void HandleInputChooseAction(void) PlaySE(SE_SELECT); TryHideLastUsedBall(); - switch (gActionSelectionCursor[gActiveBattler]) + switch (gActionSelectionCursor[battler]) { case 0: // Top left BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_USE_MOVE, 0); @@ -365,63 +330,63 @@ static void HandleInputChooseAction(void) BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_RUN, 0); break; } - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } else if (JOY_NEW(DPAD_LEFT)) { - if (gActionSelectionCursor[gActiveBattler] & 1) // if is B_ACTION_USE_ITEM or B_ACTION_RUN + if (gActionSelectionCursor[battler] & 1) // if is B_ACTION_USE_ITEM or B_ACTION_RUN { PlaySE(SE_SELECT); - ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 1; - ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); + ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]); + gActionSelectionCursor[battler] ^= 1; + ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); } } else if (JOY_NEW(DPAD_RIGHT)) { - if (!(gActionSelectionCursor[gActiveBattler] & 1)) // if is B_ACTION_USE_MOVE or B_ACTION_SWITCH + if (!(gActionSelectionCursor[battler] & 1)) // if is B_ACTION_USE_MOVE or B_ACTION_SWITCH { PlaySE(SE_SELECT); - ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 1; - ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); + ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]); + gActionSelectionCursor[battler] ^= 1; + ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); } } else if (JOY_NEW(DPAD_UP)) { - if (gActionSelectionCursor[gActiveBattler] & 2) // if is B_ACTION_SWITCH or B_ACTION_RUN + if (gActionSelectionCursor[battler] & 2) // if is B_ACTION_SWITCH or B_ACTION_RUN { PlaySE(SE_SELECT); - ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 2; - ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); + ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]); + gActionSelectionCursor[battler] ^= 2; + ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); } } else if (JOY_NEW(DPAD_DOWN)) { - if (!(gActionSelectionCursor[gActiveBattler] & 2)) // if is B_ACTION_USE_MOVE or B_ACTION_USE_ITEM + if (!(gActionSelectionCursor[battler] & 2)) // if is B_ACTION_USE_MOVE or B_ACTION_USE_ITEM { PlaySE(SE_SELECT); - ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 2; - ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); + ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]); + gActionSelectionCursor[battler] ^= 2; + ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); } } else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59) { if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - && GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_RIGHT + && GetBattlerPosition(battler) == B_POSITION_PLAYER_RIGHT && !(gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { // Return item to bag if partner had selected one. - if (gBattleResources->bufferA[gActiveBattler][1] == B_ACTION_USE_ITEM) + if (gBattleResources->bufferA[battler][1] == B_ACTION_USE_ITEM) { AddBagItem(itemId, 1); } PlaySE(SE_SELECT); BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_CANCEL_PARTNER, 0); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } } else if (JOY_NEW(START_BUTTON)) @@ -432,7 +397,7 @@ static void HandleInputChooseAction(void) else if (JOY_NEW(SELECT_BUTTON)) { BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_DEBUG, 0); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } #endif #if B_LAST_USED_BALL == TRUE && B_LAST_USED_BALL_CYCLE == FALSE @@ -441,24 +406,17 @@ static void HandleInputChooseAction(void) PlaySE(SE_SELECT); TryHideLastUsedBall(); BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_THROW_BALL, 0); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } #endif } -static void UnusedEndBounceEffect(void) -{ - EndBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX); - EndBounceEffect(gActiveBattler, BOUNCE_MON); - gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseTarget; -} - -static void HandleInputChooseTarget(void) +static void HandleInputChooseTarget(u32 battler) { s32 i; static const u8 identities[MAX_BATTLERS_COUNT] = {B_POSITION_PLAYER_LEFT, B_POSITION_PLAYER_RIGHT, B_POSITION_OPPONENT_RIGHT, B_POSITION_OPPONENT_LEFT}; - u16 move = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler]); - u16 moveTarget = GetBattlerMoveTargetType(gActiveBattler, move); + u16 move = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_MOVE1 + gMoveSelectionCursor[battler]); + u16 moveTarget = GetBattlerMoveTargetType(battler, move); DoBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX, 15, 1); for (i = 0; i < gBattlersCount; i++) @@ -477,21 +435,21 @@ static void HandleInputChooseTarget(void) PlaySE(SE_SELECT); gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCB_HideAsMoveTarget; if (gBattleStruct->mega.playerSelect) - BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8)); + BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8)); else - BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); + BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | (gMultiUsePlayerCursor << 8)); EndBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX); TryHideLastUsedBall(); HideTriggerSprites(); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59) { PlaySE(SE_SELECT); gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCB_HideAsMoveTarget; - gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseMove; - DoBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX, 7, 1); - DoBounceEffect(gActiveBattler, BOUNCE_MON, 7, 1); + gBattlerControllerFuncs[battler] = HandleInputChooseMove; + DoBounceEffect(battler, BOUNCE_HEALTHBOX, 7, 1); + DoBounceEffect(battler, BOUNCE_MON, 7, 1); EndBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX); } else if (JOY_NEW(DPAD_LEFT | DPAD_UP)) @@ -526,7 +484,7 @@ static void HandleInputChooseTarget(void) { case B_POSITION_PLAYER_LEFT: case B_POSITION_PLAYER_RIGHT: - if (gActiveBattler != gMultiUsePlayerCursor) + if (battler != gMultiUsePlayerCursor) i++; else if (moveTarget & MOVE_TARGET_USER_OR_SELECTED) i++; @@ -538,7 +496,7 @@ static void HandleInputChooseTarget(void) } if (gAbsentBattlerFlags & gBitTable[gMultiUsePlayerCursor] - || !CanTargetBattler(gActiveBattler, gMultiUsePlayerCursor, move)) + || !CanTargetBattler(battler, gMultiUsePlayerCursor, move)) i = 0; } while (i == 0); } @@ -576,7 +534,7 @@ static void HandleInputChooseTarget(void) { case B_POSITION_PLAYER_LEFT: case B_POSITION_PLAYER_RIGHT: - if (gActiveBattler != gMultiUsePlayerCursor) + if (battler != gMultiUsePlayerCursor) i++; else if (moveTarget & MOVE_TARGET_USER_OR_SELECTED) i++; @@ -588,7 +546,7 @@ static void HandleInputChooseTarget(void) } if (gAbsentBattlerFlags & gBitTable[gMultiUsePlayerCursor] - || !CanTargetBattler(gActiveBattler, gMultiUsePlayerCursor, move)) + || !CanTargetBattler(battler, gMultiUsePlayerCursor, move)) i = 0; } while (i == 0); } @@ -610,12 +568,12 @@ static void HideAllTargets(void) } } -static void HideShownTargets(void) +static void HideShownTargets(u32 battler) { s32 i; for (i = 0; i < MAX_BATTLERS_COUNT; i++) { - if (IsBattlerAlive(i) && gBattleSpritesDataPtr->healthBoxesData[i].healthboxIsBouncing && i != gActiveBattler) + if (IsBattlerAlive(i) && gBattleSpritesDataPtr->healthBoxesData[i].healthboxIsBouncing && i != battler) { gSprites[gBattlerSpriteIds[i]].callback = SpriteCB_HideAsMoveTarget; EndBounceEffect(i, BOUNCE_HEALTHBOX); @@ -623,7 +581,7 @@ static void HideShownTargets(void) } } -static void HandleInputShowEntireFieldTargets(void) +static void HandleInputShowEntireFieldTargets(u32 battler) { if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A) gPlayerDpadHoldFrames++; @@ -635,23 +593,23 @@ static void HandleInputShowEntireFieldTargets(void) PlaySE(SE_SELECT); HideAllTargets(); if (gBattleStruct->mega.playerSelect) - BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8)); + BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8)); else - BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); + BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | (gMultiUsePlayerCursor << 8)); HideMegaTriggerSprite(); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59) { PlaySE(SE_SELECT); HideAllTargets(); - gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseMove; - DoBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX, 7, 1); - DoBounceEffect(gActiveBattler, BOUNCE_MON, 7, 1); + gBattlerControllerFuncs[battler] = HandleInputChooseMove; + DoBounceEffect(battler, BOUNCE_HEALTHBOX, 7, 1); + DoBounceEffect(battler, BOUNCE_MON, 7, 1); } } -static void HandleInputShowTargets(void) +static void HandleInputShowTargets(u32 battler) { if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A) gPlayerDpadHoldFrames++; @@ -661,22 +619,22 @@ static void HandleInputShowTargets(void) if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); - HideShownTargets(); + HideShownTargets(battler); if (gBattleStruct->mega.playerSelect) - BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8)); + BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8)); else - BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); + BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | (gMultiUsePlayerCursor << 8)); HideTriggerSprites(); TryHideLastUsedBall(); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59) { PlaySE(SE_SELECT); - HideShownTargets(); - gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseMove; - DoBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX, 7, 1); - DoBounceEffect(gActiveBattler, BOUNCE_MON, 7, 1); + HideShownTargets(battler); + gBattlerControllerFuncs[battler] = HandleInputChooseMove; + DoBounceEffect(battler, BOUNCE_HEALTHBOX, 7, 1); + DoBounceEffect(battler, BOUNCE_MON, 7, 1); } } @@ -689,11 +647,11 @@ static void TryShowAsTarget(u32 battlerId) } } -static void HandleInputChooseMove(void) +static void HandleInputChooseMove(u32 battler) { u16 moveTarget; u32 canSelectTarget = 0; - struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); + struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A) gPlayerDpadHoldFrames++; @@ -703,7 +661,7 @@ static void HandleInputChooseMove(void) if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); - if (moveInfo->moves[gMoveSelectionCursor[gActiveBattler]] == MOVE_CURSE) + if (moveInfo->moves[gMoveSelectionCursor[battler]] == MOVE_CURSE) { if (moveInfo->monType1 != TYPE_GHOST && moveInfo->monType2 != TYPE_GHOST && moveInfo->monType3 != TYPE_GHOST) moveTarget = MOVE_TARGET_USER; @@ -712,43 +670,43 @@ static void HandleInputChooseMove(void) } else { - moveTarget = GetBattlerMoveTargetType(gActiveBattler, moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]); + moveTarget = GetBattlerMoveTargetType(battler, moveInfo->moves[gMoveSelectionCursor[battler]]); } if (gBattleStruct->zmove.viewing) { - u16 chosenMove = moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]; + u16 chosenMove = moveInfo->moves[gMoveSelectionCursor[battler]]; - QueueZMove(gActiveBattler, chosenMove); + QueueZMove(battler, chosenMove); gBattleStruct->zmove.viewing = FALSE; - if (gBattleMoves[moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]].split != SPLIT_STATUS) + if (gBattleMoves[moveInfo->moves[gMoveSelectionCursor[battler]]].split != SPLIT_STATUS) moveTarget = MOVE_TARGET_SELECTED; //damaging z moves always have selected target } if (moveTarget & MOVE_TARGET_USER) - gMultiUsePlayerCursor = gActiveBattler; + gMultiUsePlayerCursor = battler; else - gMultiUsePlayerCursor = GetBattlerAtPosition(BATTLE_OPPOSITE(GET_BATTLER_SIDE(gActiveBattler))); + gMultiUsePlayerCursor = GetBattlerAtPosition(BATTLE_OPPOSITE(GET_BATTLER_SIDE(battler))); - if (!gBattleResources->bufferA[gActiveBattler][1]) // not a double battle + if (!gBattleResources->bufferA[battler][1]) // not a double battle { - if (moveTarget & MOVE_TARGET_USER_OR_SELECTED && !gBattleResources->bufferA[gActiveBattler][2]) + if (moveTarget & MOVE_TARGET_USER_OR_SELECTED && !gBattleResources->bufferA[battler][2]) canSelectTarget = 1; } else // double battle { if (!(moveTarget & (MOVE_TARGET_RANDOM | MOVE_TARGET_BOTH | MOVE_TARGET_DEPENDS | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_USER | MOVE_TARGET_ALLY))) canSelectTarget = 1; // either selected or user - if (moveTarget == (MOVE_TARGET_USER | MOVE_TARGET_ALLY) && IsBattlerAlive(BATTLE_PARTNER(gActiveBattler))) + if (moveTarget == (MOVE_TARGET_USER | MOVE_TARGET_ALLY) && IsBattlerAlive(BATTLE_PARTNER(battler))) canSelectTarget = 1; - if (moveInfo->currentPp[gMoveSelectionCursor[gActiveBattler]] == 0) + if (moveInfo->currentPp[gMoveSelectionCursor[battler]] == 0) { canSelectTarget = 0; } else if (!(moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED)) && CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) <= 1) { - gMultiUsePlayerCursor = GetDefaultMoveTarget(gActiveBattler); + gMultiUsePlayerCursor = GetDefaultMoveTarget(battler); canSelectTarget = 0; } @@ -767,7 +725,7 @@ static void HandleInputChooseMove(void) TryShowAsTarget(gMultiUsePlayerCursor); TryShowAsTarget(BATTLE_PARTNER(gMultiUsePlayerCursor)); if (moveTarget & MOVE_TARGET_FOES_AND_ALLY) - TryShowAsTarget(BATTLE_PARTNER(gActiveBattler)); + TryShowAsTarget(BATTLE_PARTNER(battler)); canSelectTarget = 2; } #endif @@ -778,18 +736,18 @@ static void HandleInputChooseMove(void) case 0: default: if (gBattleStruct->mega.playerSelect) - BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8)); + BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8)); else - BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); + BtlController_EmitTwoReturnValues(BUFFER_B, 10, gMoveSelectionCursor[battler] | (gMultiUsePlayerCursor << 8)); HideTriggerSprites(); TryHideLastUsedBall(); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); break; case 1: - gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseTarget; + gBattlerControllerFuncs[battler] = HandleInputChooseTarget; if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED)) - gMultiUsePlayerCursor = gActiveBattler; + gMultiUsePlayerCursor = battler; else if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)]) gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); else @@ -798,10 +756,10 @@ static void HandleInputChooseMove(void) gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCB_ShowAsMoveTarget; break; case 2: - gBattlerControllerFuncs[gActiveBattler] = HandleInputShowTargets; + gBattlerControllerFuncs[battler] = HandleInputShowTargets; break; case 3: // Entire field - gBattlerControllerFuncs[gActiveBattler] = HandleInputShowEntireFieldTargets; + gBattlerControllerFuncs[battler] = HandleInputShowEntireFieldTargets; break; } } @@ -810,7 +768,7 @@ static void HandleInputChooseMove(void) PlaySE(SE_SELECT); if (gBattleStruct->zmove.viewing) { - ReloadMoveNames(); + ReloadMoveNames(battler); } else { @@ -818,82 +776,82 @@ static void HandleInputChooseMove(void) gBattleStruct->zmove.viable = FALSE; BtlController_EmitTwoReturnValues(BUFFER_B, 10, 0xFFFF); HideTriggerSprites(); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } } else if (JOY_NEW(DPAD_LEFT) && !gBattleStruct->zmove.viewing) { - if (gMoveSelectionCursor[gActiveBattler] & 1) + if (gMoveSelectionCursor[battler] & 1) { - MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBattler]); - gMoveSelectionCursor[gActiveBattler] ^= 1; + MoveSelectionDestroyCursorAt(gMoveSelectionCursor[battler]); + gMoveSelectionCursor[battler] ^= 1; PlaySE(SE_SELECT); - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0); - MoveSelectionDisplayPpNumber(); - MoveSelectionDisplayMoveType(); - TryChangeZIndicator(gActiveBattler, gMoveSelectionCursor[gActiveBattler]); + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + MoveSelectionDisplayPpNumber(battler); + MoveSelectionDisplayMoveType(battler); + TryChangeZIndicator(battler, gMoveSelectionCursor[battler]); } } else if (JOY_NEW(DPAD_RIGHT) && !gBattleStruct->zmove.viewing) { - if (!(gMoveSelectionCursor[gActiveBattler] & 1) - && (gMoveSelectionCursor[gActiveBattler] ^ 1) < gNumberOfMovesToChoose) + if (!(gMoveSelectionCursor[battler] & 1) + && (gMoveSelectionCursor[battler] ^ 1) < gNumberOfMovesToChoose) { - MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBattler]); - gMoveSelectionCursor[gActiveBattler] ^= 1; + MoveSelectionDestroyCursorAt(gMoveSelectionCursor[battler]); + gMoveSelectionCursor[battler] ^= 1; PlaySE(SE_SELECT); - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0); - MoveSelectionDisplayPpNumber(); - MoveSelectionDisplayMoveType(); - TryChangeZIndicator(gActiveBattler, gMoveSelectionCursor[gActiveBattler]); + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + MoveSelectionDisplayPpNumber(battler); + MoveSelectionDisplayMoveType(battler); + TryChangeZIndicator(battler, gMoveSelectionCursor[battler]); } } else if (JOY_NEW(DPAD_UP) && !gBattleStruct->zmove.viewing) { - if (gMoveSelectionCursor[gActiveBattler] & 2) + if (gMoveSelectionCursor[battler] & 2) { - MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBattler]); - gMoveSelectionCursor[gActiveBattler] ^= 2; + MoveSelectionDestroyCursorAt(gMoveSelectionCursor[battler]); + gMoveSelectionCursor[battler] ^= 2; PlaySE(SE_SELECT); - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0); - MoveSelectionDisplayPpNumber(); - MoveSelectionDisplayMoveType(); - TryChangeZIndicator(gActiveBattler, gMoveSelectionCursor[gActiveBattler]); + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + MoveSelectionDisplayPpNumber(battler); + MoveSelectionDisplayMoveType(battler); + TryChangeZIndicator(battler, gMoveSelectionCursor[battler]); } } else if (JOY_NEW(DPAD_DOWN) && !gBattleStruct->zmove.viewing) { - if (!(gMoveSelectionCursor[gActiveBattler] & 2) - && (gMoveSelectionCursor[gActiveBattler] ^ 2) < gNumberOfMovesToChoose) + if (!(gMoveSelectionCursor[battler] & 2) + && (gMoveSelectionCursor[battler] ^ 2) < gNumberOfMovesToChoose) { - MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBattler]); - gMoveSelectionCursor[gActiveBattler] ^= 2; + MoveSelectionDestroyCursorAt(gMoveSelectionCursor[battler]); + gMoveSelectionCursor[battler] ^= 2; PlaySE(SE_SELECT); - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0); - MoveSelectionDisplayPpNumber(); - MoveSelectionDisplayMoveType(); - TryChangeZIndicator(gActiveBattler, gMoveSelectionCursor[gActiveBattler]); + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + MoveSelectionDisplayPpNumber(battler); + MoveSelectionDisplayMoveType(battler); + TryChangeZIndicator(battler, gMoveSelectionCursor[battler]); } } else if (JOY_NEW(SELECT_BUTTON) && !gBattleStruct->zmove.viewing) { if (gNumberOfMovesToChoose > 1 && !(gBattleTypeFlags & BATTLE_TYPE_LINK)) { - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 29); + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 29); - if (gMoveSelectionCursor[gActiveBattler] != 0) + if (gMoveSelectionCursor[battler] != 0) gMultiUsePlayerCursor = 0; else - gMultiUsePlayerCursor = gMoveSelectionCursor[gActiveBattler] + 1; + gMultiUsePlayerCursor = gMoveSelectionCursor[battler] + 1; MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 27); BattlePutTextOnWindow(gText_BattleSwitchWhich, B_WIN_SWITCH_PROMPT); - gBattlerControllerFuncs[gActiveBattler] = HandleMoveSwitching; + gBattlerControllerFuncs[battler] = HandleMoveSwitching; } } else if (JOY_NEW(START_BUTTON)) { - if (CanMegaEvolve(gActiveBattler)) + if (CanMegaEvolve(battler)) { gBattleStruct->mega.playerSelect ^= 1; ChangeMegaTriggerSprite(gBattleStruct->mega.triggerSpriteId, gBattleStruct->mega.playerSelect); @@ -907,23 +865,23 @@ static void HandleInputChooseMove(void) if (!gBattleStruct->zmove.viewing) MoveSelectionDisplayZMove(gBattleStruct->zmove.chosenZMove); else - ReloadMoveNames(); + ReloadMoveNames(battler); } } } -static void ReloadMoveNames(void) +static void ReloadMoveNames(u32 battler) { gBattleStruct->mega.playerSelect = FALSE; gBattleStruct->zmove.viewing = FALSE; - MoveSelectionDestroyCursorAt(0); - MoveSelectionDisplayMoveNames(); - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0); - MoveSelectionDisplayPpNumber(); - MoveSelectionDisplayMoveType(); + MoveSelectionDestroyCursorAt(battler); + MoveSelectionDisplayMoveNames(battler); + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + MoveSelectionDisplayPpNumber(battler); + MoveSelectionDisplayMoveType(battler); } -static u32 HandleMoveInputUnused(void) +static u32 HandleMoveInputUnused(u32 battler) { u32 var = 0; @@ -939,41 +897,41 @@ static u32 HandleMoveInputUnused(void) gBattle_BG0_Y = DISPLAY_HEIGHT * 2; var = 0xFF; } - if (JOY_NEW(DPAD_LEFT) && gMoveSelectionCursor[gActiveBattler] & 1) + if (JOY_NEW(DPAD_LEFT) && gMoveSelectionCursor[battler] & 1) { - MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBattler]); - gMoveSelectionCursor[gActiveBattler] ^= 1; + MoveSelectionDestroyCursorAt(gMoveSelectionCursor[battler]); + gMoveSelectionCursor[battler] ^= 1; PlaySE(SE_SELECT); - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0); + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); } - if (JOY_NEW(DPAD_RIGHT) && !(gMoveSelectionCursor[gActiveBattler] & 1) - && (gMoveSelectionCursor[gActiveBattler] ^ 1) < gNumberOfMovesToChoose) + if (JOY_NEW(DPAD_RIGHT) && !(gMoveSelectionCursor[battler] & 1) + && (gMoveSelectionCursor[battler] ^ 1) < gNumberOfMovesToChoose) { - MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBattler]); - gMoveSelectionCursor[gActiveBattler] ^= 1; + MoveSelectionDestroyCursorAt(gMoveSelectionCursor[battler]); + gMoveSelectionCursor[battler] ^= 1; PlaySE(SE_SELECT); - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0); + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); } - if (JOY_NEW(DPAD_UP) && gMoveSelectionCursor[gActiveBattler] & 2) + if (JOY_NEW(DPAD_UP) && gMoveSelectionCursor[battler] & 2) { - MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBattler]); - gMoveSelectionCursor[gActiveBattler] ^= 2; + MoveSelectionDestroyCursorAt(gMoveSelectionCursor[battler]); + gMoveSelectionCursor[battler] ^= 2; PlaySE(SE_SELECT); - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0); + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); } - if (JOY_NEW(DPAD_DOWN) && !(gMoveSelectionCursor[gActiveBattler] & 2) - && (gMoveSelectionCursor[gActiveBattler] ^ 2) < gNumberOfMovesToChoose) + if (JOY_NEW(DPAD_DOWN) && !(gMoveSelectionCursor[battler] & 2) + && (gMoveSelectionCursor[battler] ^ 2) < gNumberOfMovesToChoose) { - MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBattler]); - gMoveSelectionCursor[gActiveBattler] ^= 2; + MoveSelectionDestroyCursorAt(gMoveSelectionCursor[battler]); + gMoveSelectionCursor[battler] ^= 2; PlaySE(SE_SELECT); - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0); + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); } return var; } -static void HandleMoveSwitching(void) +static void HandleMoveSwitching(u32 battler) { u8 perMovePPBonuses[MAX_MON_MOVES]; struct ChooseMoveStruct moveStruct; @@ -981,76 +939,76 @@ static void HandleMoveSwitching(void) if (JOY_NEW(A_BUTTON | SELECT_BUTTON)) { - struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); + struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); PlaySE(SE_SELECT); - if (gMoveSelectionCursor[gActiveBattler] != gMultiUsePlayerCursor) + if (gMoveSelectionCursor[battler] != gMultiUsePlayerCursor) { - struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); + struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); s32 i; // swap moves and pp - i = moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]; - moveInfo->moves[gMoveSelectionCursor[gActiveBattler]] = moveInfo->moves[gMultiUsePlayerCursor]; + i = moveInfo->moves[gMoveSelectionCursor[battler]]; + moveInfo->moves[gMoveSelectionCursor[battler]] = moveInfo->moves[gMultiUsePlayerCursor]; moveInfo->moves[gMultiUsePlayerCursor] = i; - i = moveInfo->currentPp[gMoveSelectionCursor[gActiveBattler]]; - moveInfo->currentPp[gMoveSelectionCursor[gActiveBattler]] = moveInfo->currentPp[gMultiUsePlayerCursor]; + i = moveInfo->currentPp[gMoveSelectionCursor[battler]]; + moveInfo->currentPp[gMoveSelectionCursor[battler]] = moveInfo->currentPp[gMultiUsePlayerCursor]; moveInfo->currentPp[gMultiUsePlayerCursor] = i; - i = moveInfo->maxPp[gMoveSelectionCursor[gActiveBattler]]; - moveInfo->maxPp[gMoveSelectionCursor[gActiveBattler]] = moveInfo->maxPp[gMultiUsePlayerCursor]; + i = moveInfo->maxPp[gMoveSelectionCursor[battler]]; + moveInfo->maxPp[gMoveSelectionCursor[battler]] = moveInfo->maxPp[gMultiUsePlayerCursor]; moveInfo->maxPp[gMultiUsePlayerCursor] = i; - if (gDisableStructs[gActiveBattler].mimickedMoves & gBitTable[gMoveSelectionCursor[gActiveBattler]]) + if (gDisableStructs[battler].mimickedMoves & gBitTable[gMoveSelectionCursor[battler]]) { - gDisableStructs[gActiveBattler].mimickedMoves &= (~gBitTable[gMoveSelectionCursor[gActiveBattler]]); - gDisableStructs[gActiveBattler].mimickedMoves |= gBitTable[gMultiUsePlayerCursor]; + gDisableStructs[battler].mimickedMoves &= (~gBitTable[gMoveSelectionCursor[battler]]); + gDisableStructs[battler].mimickedMoves |= gBitTable[gMultiUsePlayerCursor]; } - MoveSelectionDisplayMoveNames(); + MoveSelectionDisplayMoveNames(battler); for (i = 0; i < MAX_MON_MOVES; i++) - perMovePPBonuses[i] = (gBattleMons[gActiveBattler].ppBonuses & (3 << (i * 2))) >> (i * 2); + perMovePPBonuses[i] = (gBattleMons[battler].ppBonuses & (3 << (i * 2))) >> (i * 2); - totalPPBonuses = perMovePPBonuses[gMoveSelectionCursor[gActiveBattler]]; - perMovePPBonuses[gMoveSelectionCursor[gActiveBattler]] = perMovePPBonuses[gMultiUsePlayerCursor]; + totalPPBonuses = perMovePPBonuses[gMoveSelectionCursor[battler]]; + perMovePPBonuses[gMoveSelectionCursor[battler]] = perMovePPBonuses[gMultiUsePlayerCursor]; perMovePPBonuses[gMultiUsePlayerCursor] = totalPPBonuses; totalPPBonuses = 0; for (i = 0; i < MAX_MON_MOVES; i++) totalPPBonuses |= perMovePPBonuses[i] << (i * 2); - gBattleMons[gActiveBattler].ppBonuses = totalPPBonuses; + gBattleMons[battler].ppBonuses = totalPPBonuses; for (i = 0; i < MAX_MON_MOVES; i++) { - gBattleMons[gActiveBattler].moves[i] = moveInfo->moves[i]; - gBattleMons[gActiveBattler].pp[i] = moveInfo->currentPp[i]; + gBattleMons[battler].moves[i] = moveInfo->moves[i]; + gBattleMons[battler].pp[i] = moveInfo->currentPp[i]; } - if (!(gBattleMons[gActiveBattler].status2 & STATUS2_TRANSFORMED)) + if (!(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)) { for (i = 0; i < MAX_MON_MOVES; i++) { - moveStruct.moves[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + i); - moveStruct.currentPp[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_PP1 + i); + moveStruct.moves[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_MOVE1 + i); + moveStruct.currentPp[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_PP1 + i); } - totalPPBonuses = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_PP_BONUSES); + totalPPBonuses = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_PP_BONUSES); for (i = 0; i < MAX_MON_MOVES; i++) perMovePPBonuses[i] = (totalPPBonuses & (3 << (i * 2))) >> (i * 2); - i = moveStruct.moves[gMoveSelectionCursor[gActiveBattler]]; - moveStruct.moves[gMoveSelectionCursor[gActiveBattler]] = moveStruct.moves[gMultiUsePlayerCursor]; + i = moveStruct.moves[gMoveSelectionCursor[battler]]; + moveStruct.moves[gMoveSelectionCursor[battler]] = moveStruct.moves[gMultiUsePlayerCursor]; moveStruct.moves[gMultiUsePlayerCursor] = i; - i = moveStruct.currentPp[gMoveSelectionCursor[gActiveBattler]]; - moveStruct.currentPp[gMoveSelectionCursor[gActiveBattler]] = moveStruct.currentPp[gMultiUsePlayerCursor]; + i = moveStruct.currentPp[gMoveSelectionCursor[battler]]; + moveStruct.currentPp[gMoveSelectionCursor[battler]] = moveStruct.currentPp[gMultiUsePlayerCursor]; moveStruct.currentPp[gMultiUsePlayerCursor] = i; - totalPPBonuses = perMovePPBonuses[gMoveSelectionCursor[gActiveBattler]]; - perMovePPBonuses[gMoveSelectionCursor[gActiveBattler]] = perMovePPBonuses[gMultiUsePlayerCursor]; + totalPPBonuses = perMovePPBonuses[gMoveSelectionCursor[battler]]; + perMovePPBonuses[gMoveSelectionCursor[battler]] = perMovePPBonuses[gMultiUsePlayerCursor]; perMovePPBonuses[gMultiUsePlayerCursor] = totalPPBonuses; totalPPBonuses = 0; @@ -1059,45 +1017,45 @@ static void HandleMoveSwitching(void) for (i = 0; i < MAX_MON_MOVES; i++) { - SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + i, &moveStruct.moves[i]); - SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_PP1 + i, &moveStruct.currentPp[i]); + SetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_MOVE1 + i, &moveStruct.moves[i]); + SetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_PP1 + i, &moveStruct.currentPp[i]); } - SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_PP_BONUSES, &totalPPBonuses); + SetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_PP_BONUSES, &totalPPBonuses); } } - gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseMove; - gMoveSelectionCursor[gActiveBattler] = gMultiUsePlayerCursor; - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0); - MoveSelectionDisplayPpString(); - MoveSelectionDisplayPpNumber(); - MoveSelectionDisplayMoveType(); - GetUsableZMoves(gActiveBattler, moveInfo->moves); + gBattlerControllerFuncs[battler] = HandleInputChooseMove; + gMoveSelectionCursor[battler] = gMultiUsePlayerCursor; + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + MoveSelectionDisplayPpString(battler); + MoveSelectionDisplayPpNumber(battler); + MoveSelectionDisplayMoveType(battler); + GetUsableZMoves(battler, moveInfo->moves); } else if (JOY_NEW(B_BUTTON | SELECT_BUTTON)) { PlaySE(SE_SELECT); MoveSelectionDestroyCursorAt(gMultiUsePlayerCursor); - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0); - gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseMove; - MoveSelectionDisplayPpString(); - MoveSelectionDisplayPpNumber(); - MoveSelectionDisplayMoveType(); + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + gBattlerControllerFuncs[battler] = HandleInputChooseMove; + MoveSelectionDisplayPpString(battler); + MoveSelectionDisplayPpNumber(battler); + MoveSelectionDisplayMoveType(battler); } else if (JOY_NEW(DPAD_LEFT)) { if (gMultiUsePlayerCursor & 1) { - if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBattler]) - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 29); + if (gMultiUsePlayerCursor == gMoveSelectionCursor[battler]) + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 29); else MoveSelectionDestroyCursorAt(gMultiUsePlayerCursor); gMultiUsePlayerCursor ^= 1; PlaySE(SE_SELECT); - if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBattler]) + if (gMultiUsePlayerCursor == gMoveSelectionCursor[battler]) MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 0); else MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 27); @@ -1107,15 +1065,15 @@ static void HandleMoveSwitching(void) { if (!(gMultiUsePlayerCursor & 1) && (gMultiUsePlayerCursor ^ 1) < gNumberOfMovesToChoose) { - if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBattler]) - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 29); + if (gMultiUsePlayerCursor == gMoveSelectionCursor[battler]) + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 29); else MoveSelectionDestroyCursorAt(gMultiUsePlayerCursor); gMultiUsePlayerCursor ^= 1; PlaySE(SE_SELECT); - if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBattler]) + if (gMultiUsePlayerCursor == gMoveSelectionCursor[battler]) MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 0); else MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 27); @@ -1125,15 +1083,15 @@ static void HandleMoveSwitching(void) { if (gMultiUsePlayerCursor & 2) { - if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBattler]) - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 29); + if (gMultiUsePlayerCursor == gMoveSelectionCursor[battler]) + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 29); else MoveSelectionDestroyCursorAt(gMultiUsePlayerCursor); gMultiUsePlayerCursor ^= 2; PlaySE(SE_SELECT); - if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBattler]) + if (gMultiUsePlayerCursor == gMoveSelectionCursor[battler]) MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 0); else MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 27); @@ -1143,15 +1101,15 @@ static void HandleMoveSwitching(void) { if (!(gMultiUsePlayerCursor & 2) && (gMultiUsePlayerCursor ^ 2) < gNumberOfMovesToChoose) { - if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBattler]) - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 29); + if (gMultiUsePlayerCursor == gMoveSelectionCursor[battler]) + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 29); else MoveSelectionDestroyCursorAt(gMultiUsePlayerCursor); gMultiUsePlayerCursor ^= 2; PlaySE(SE_SELECT); - if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBattler]) + if (gMultiUsePlayerCursor == gMoveSelectionCursor[battler]) MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 0); else MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 27); @@ -1159,7 +1117,7 @@ static void HandleMoveSwitching(void) } } -static void SetLinkBattleEndCallbacks(void) +static void SetLinkBattleEndCallbacks(u32 battler) { if (gWirelessCommType == 0) { @@ -1190,7 +1148,7 @@ static void SetLinkBattleEndCallbacks(void) } // Despite handling link battles separately, this is only ever used by link battles -void SetBattleEndCallbacks(void) +void SetBattleEndCallbacks(u32 battler) { if (!gPaletteFade.active) { @@ -1203,7 +1161,7 @@ void SetBattleEndCallbacks(void) else SetLinkStandbyCallback(); - gBattlerControllerFuncs[gActiveBattler] = SetLinkBattleEndCallbacks; + gBattlerControllerFuncs[battler] = SetLinkBattleEndCallbacks; } } else @@ -1216,148 +1174,120 @@ void SetBattleEndCallbacks(void) } } -static void CompleteOnBattlerSpriteCallbackDummy(void) +static void Intro_DelayAndEnd(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - PlayerBufferExecCompleted(); -} - -static void CompleteOnBankSpriteCallbackDummy2(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - PlayerBufferExecCompleted(); -} - -static void FreeTrainerSpriteAfterSlide(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (--gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay == (u8)-1) { - BattleGfxSfxDummy3(gSaveBlock2Ptr->playerGender); - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - PlayerBufferExecCompleted(); + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0; + PlayerBufferExecCompleted(battler); } } -static void Intro_DelayAndEnd(void) -{ - if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == (u8)-1) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; - PlayerBufferExecCompleted(); - } -} - -static bool32 TwoIntroMons(u32 battlerId) // Double battle with both player pokemon active. -{ - return (IsDoubleBattle() && IsValidForBattle(&gPlayerParty[gBattlerPartyIndexes[battlerId ^ BIT_FLANK]])); -} - -static void Intro_WaitForShinyAnimAndHealthbox(void) +static void Intro_WaitForShinyAnimAndHealthbox(u32 battler) { bool8 healthboxAnimDone = FALSE; // Check if healthbox has finished sliding in - if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + if (TwoPlayerIntroMons(battler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy) healthboxAnimDone = TRUE; } else { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) healthboxAnimDone = TRUE; } // If healthbox and shiny anim are done - if (healthboxAnimDone && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim - && gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) + if (healthboxAnimDone && gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim + && gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim) { // Reset shiny anim (even if it didn't occur) - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); - if (TwoIntroMons(gActiveBattler)) - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], BATTLE_PARTNER(gActiveBattler)); + if (TwoPlayerIntroMons(battler)) + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], BATTLE_PARTNER(battler)); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; - gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3; + gBattlerControllerFuncs[battler] = Intro_DelayAndEnd; } } -static void Intro_TryShinyAnimShowHealthbox(void) +static void Intro_TryShinyAnimShowHealthbox(u32 battler) { bool32 bgmRestored = FALSE; bool32 battlerAnimsDone = FALSE; // Start shiny animation if applicable for 1st pokemon - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) - TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) + TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]); // Start shiny animation if applicable for 2nd pokemon - if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive) - TryShinyAnimation(BATTLE_PARTNER(gActiveBattler), &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]]); + if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive) + TryShinyAnimation(BATTLE_PARTNER(battler), &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]]); // Show healthbox after ball anim - 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 (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + if (TwoPlayerIntroMons(battler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { - UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); - StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL); + StartHealthboxSlideIn(BATTLE_PARTNER(battler)); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]); } - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = TRUE; + gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = TRUE; } // Restore bgm after cry has played and healthbox anim is started - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].waitForCry - && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].waitForCry + if (!gBattleSpritesDataPtr->healthBoxesData[battler].waitForCry + && gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].waitForCry && !IsCryPlayingOrClearCrySongs()) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored) { if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK) m4aMPlayContinue(&gMPlayInfo_BGM); else m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100); } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = TRUE; + gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = TRUE; bgmRestored = TRUE; } // Wait for battler anims - if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + if (TwoPlayerIntroMons(battler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy + && gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy) { battlerAnimsDone = TRUE; } } else { - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) { battlerAnimsDone = TRUE; } @@ -1366,67 +1296,67 @@ static void Intro_TryShinyAnimShowHealthbox(void) // Clean up if (bgmRestored && battlerAnimsDone) { - if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); + if (TwoPlayerIntroMons(battler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]]); + DestroySprite(&gSprites[gBattleControllerData[battler]]); gBattleSpritesDataPtr->animationData->introAnimActive = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = FALSE; - gBattlerControllerFuncs[gActiveBattler] = Intro_WaitForShinyAnimAndHealthbox; + gBattlerControllerFuncs[battler] = Intro_WaitForShinyAnimAndHealthbox; } } -static void SwitchIn_CleanShinyAnimShowSubstitute(void) +static void SwitchIn_CleanShinyAnimShowSubstitute(u32 battler) { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy + && gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) { - CopyBattleSpriteInvisibility(gActiveBattler); + CopyBattleSpriteInvisibility(battler); // Reset shiny anim (even if it didn't occur) - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); // Check if Substitute should be shown - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) + 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()) { m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100); - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - PlayerBufferExecCompleted(); + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); + PlayerBufferExecCompleted(battler); } } -static void SwitchIn_TryShinyAnimShowHealthbox(void) +static void SwitchIn_TryShinyAnimShowHealthbox(u32 battler) { // Start shiny animation if applicable - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) - TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) + TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]); // Wait for ball anim, then show healthbox - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) { - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_CleanShinyAnimShowSubstitute; + DestroySprite(&gSprites[gBattleControllerData[battler]]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); + gBattlerControllerFuncs[battler] = SwitchIn_CleanShinyAnimShowSubstitute; } } @@ -1439,29 +1369,6 @@ void Task_PlayerController_RestoreBgmAfterCry(u8 taskId) } } -static void CompleteOnHealthbarDone(void) -{ - s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0); - - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - - if (hpValue != -1) - { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); - } - else - { - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - PlayerBufferExecCompleted(); - } -} - -static void CompleteOnInactiveTextPrinter(void) -{ - if (!IsTextPrinterActive(B_WIN_MSG)) - PlayerBufferExecCompleted(); -} - #define tExpTask_monId data[0] #define tExpTask_battler data[2] #define tExpTask_gainedExp_1 data[3] @@ -1475,6 +1382,7 @@ static s32 GetTaskExpValue(u8 taskId) static void Task_GiveExpToMon(u8 taskId) { + u32 savedActiveBattler; u32 monId = (u8)(gTasks[taskId].tExpTask_monId); u8 battlerId = gTasks[taskId].tExpTask_battler; s32 gainedExp = GetTaskExpValue(taskId); @@ -1489,8 +1397,6 @@ static void Task_GiveExpToMon(u8 taskId) if (currExp + gainedExp >= nextLvlExp) { - u8 savedActiveBattler; - SetMonData(mon, MON_DATA_EXP, &nextLvlExp); CalculateMonStats(mon); gainedExp -= nextLvlExp - currExp; @@ -1500,16 +1406,16 @@ static void Task_GiveExpToMon(u8 taskId) gActiveBattler = savedActiveBattler; if (IsDoubleBattle() == TRUE - && ((u16)(monId) == gBattlerPartyIndexes[battlerId] || (u16)(monId) == gBattlerPartyIndexes[BATTLE_PARTNER(battlerId)])) + && (monId == gBattlerPartyIndexes[battlerId] || monId == gBattlerPartyIndexes[BATTLE_PARTNER(battlerId)])) gTasks[taskId].func = Task_LaunchLvlUpAnim; else - gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter; + gTasks[taskId].func = Task_SetControllerToWaitForString; } else { currExp += gainedExp; SetMonData(mon, MON_DATA_EXP, &currExp); - gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter; + gBattlerControllerFuncs[battlerId] = Controller_WaitForString; DestroyTask(taskId); } } @@ -1540,6 +1446,10 @@ static void Task_PrepareToGiveExpWithExpBar(u8 taskId) static void Task_GiveExpWithExpBar(u8 taskId) { + u8 level; + u16 species; + s32 currExp, expOnNextLvl, newExpPoints; + if (gTasks[taskId].tExpTask_frames < 13) { gTasks[taskId].tExpTask_frames++; @@ -1549,17 +1459,11 @@ static void Task_GiveExpWithExpBar(u8 taskId) u8 monId = gTasks[taskId].tExpTask_monId; s32 gainedExp = GetTaskExpValue(taskId); u8 battlerId = gTasks[taskId].tExpTask_battler; - s32 newExpPoints; newExpPoints = MoveBattleBar(battlerId, gHealthboxSpriteIds[battlerId], EXP_BAR, 0); SetHealthboxSpriteVisible(gHealthboxSpriteIds[battlerId]); if (newExpPoints == -1) // The bar has been filled with given exp points. { - u8 level; - s32 currExp; - u16 species; - s32 expOnNextLvl; - m4aSongNumStop(SE_EXP); level = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); currExp = GetMonData(&gPlayerParty[monId], MON_DATA_EXP); @@ -1583,7 +1487,7 @@ static void Task_GiveExpWithExpBar(u8 taskId) { currExp += gainedExp; SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &currExp); - gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter; + gBattlerControllerFuncs[battlerId] = Controller_WaitForString; DestroyTask(taskId); } } @@ -1610,75 +1514,37 @@ static void Task_UpdateLvlInHealthbox(u8 taskId) { u8 monIndex = gTasks[taskId].tExpTask_monId; - GetMonData(&gPlayerParty[monIndex], MON_DATA_LEVEL); // Unused return value. - if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[BATTLE_PARTNER(battlerId)]) UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battlerId)], &gPlayerParty[monIndex], HEALTHBOX_ALL); else UpdateHealthboxAttribute(gHealthboxSpriteIds[battlerId], &gPlayerParty[monIndex], HEALTHBOX_ALL); - gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter; + gTasks[taskId].func = Task_SetControllerToWaitForString; } } -static void DestroyExpTaskAndCompleteOnInactiveTextPrinter(u8 taskId) +static void Task_SetControllerToWaitForString(u8 taskId) { - u8 monIndex; - u8 battlerId; - - monIndex = gTasks[taskId].tExpTask_monId; - GetMonData(&gPlayerParty[monIndex], MON_DATA_LEVEL); // Unused return value. - battlerId = gTasks[taskId].tExpTask_battler; - gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter; + u8 battlerId = gTasks[taskId].tExpTask_battler; + gBattlerControllerFuncs[battlerId] = Controller_WaitForString; DestroyTask(taskId); } -static void FreeMonSpriteAfterFaintAnim(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].y + gSprites[gBattlerSpriteIds[gActiveBattler]].y2 > DISPLAY_HEIGHT) - { - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - BattleGfxSfxDummy2(species); - FreeOamMatrix(gSprites[gBattlerSpriteIds[gActiveBattler]].oam.matrixNum); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - PlayerBufferExecCompleted(); - } -} - -static void FreeMonSpriteAfterSwitchOutAnim(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - PlayerBufferExecCompleted(); - } -} - -static void CompleteOnInactiveTextPrinter2(void) -{ - if (!IsTextPrinterActive(B_WIN_MSG)) - PlayerBufferExecCompleted(); -} - -static void OpenPartyMenuToChooseMon(void) +static void OpenPartyMenuToChooseMon(u32 battler) { if (!gPaletteFade.active) { u8 caseId; - gBattlerControllerFuncs[gActiveBattler] = WaitForMonSelection; - caseId = gTasks[gBattleControllerData[gActiveBattler]].data[0]; - DestroyTask(gBattleControllerData[gActiveBattler]); + gBattlerControllerFuncs[battler] = WaitForMonSelection; + caseId = gTasks[gBattleControllerData[battler]].data[0]; + DestroyTask(gBattleControllerData[battler]); FreeAllWindowBuffers(); OpenPartyMenuInBattle(caseId); } } -static void WaitForMonSelection(void) +static void WaitForMonSelection(u32 battler) { if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) { @@ -1687,59 +1553,34 @@ static void WaitForMonSelection(void) else BtlController_EmitChosenMonReturnValue(BUFFER_B, PARTY_SIZE, NULL); - if ((gBattleResources->bufferA[gActiveBattler][1] & 0xF) == 1) + if ((gBattleResources->bufferA[battler][1] & 0xF) == 1) PrintLinkStandbyMsg(); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } } -static void OpenBagAndChooseItem(void) +static void OpenBagAndChooseItem(u32 battler) { if (!gPaletteFade.active) { - gBattlerControllerFuncs[gActiveBattler] = CompleteWhenChoseItem; + gBattlerControllerFuncs[battler] = CompleteWhenChoseItem; ReshowBattleScreenDummy(); FreeAllWindowBuffers(); CB2_BagMenuFromBattle(); } } -static void CompleteWhenChoseItem(void) +static void CompleteWhenChoseItem(u32 battler) { if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) { BtlController_EmitOneReturnValue(BUFFER_B, gSpecialVar_ItemId); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } } -static void CompleteOnSpecialAnimDone(void) -{ - if (!gDoingBattleAnim || !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - PlayerBufferExecCompleted(); -} - -static void DoHitAnimBlinkSpriteEffect(void) -{ - u8 spriteId = gBattlerSpriteIds[gActiveBattler]; - - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = FALSE; - PlayerBufferExecCompleted(); - } - else - { - if ((gSprites[spriteId].data[1] % 4) == 0) - gSprites[spriteId].invisible ^= 1; - gSprites[spriteId].data[1]++; - } -} - -static void PlayerHandleYesNoInput(void) +static void PlayerHandleYesNoInput(u32 battler) { if (JOY_NEW(DPAD_UP) && gMultiUsePlayerCursor != 0) { @@ -1765,20 +1606,20 @@ static void PlayerHandleYesNoInput(void) else BtlController_EmitTwoReturnValues(BUFFER_B, 0xD, 0); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } if (JOY_NEW(B_BUTTON)) { HandleBattleWindow(YESNOBOX_X_Y, WINDOW_CLEAR); PlaySE(SE_SELECT); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } } -static void MoveSelectionDisplayMoveNames(void) +static void MoveSelectionDisplayMoveNames(u32 battler) { s32 i; - struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); + struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); gNumberOfMovesToChoose = 0; for (i = 0; i < MAX_MON_MOVES; i++) @@ -1792,40 +1633,40 @@ static void MoveSelectionDisplayMoveNames(void) } } -static void MoveSelectionDisplayPpString(void) +static void MoveSelectionDisplayPpString(u32 battler) { StringCopy(gDisplayedStringBattle, gText_MoveInterfacePP); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_PP); } -static void MoveSelectionDisplayPpNumber(void) +static void MoveSelectionDisplayPpNumber(u32 battler) { u8 *txtPtr; struct ChooseMoveStruct *moveInfo; - if (gBattleResources->bufferA[gActiveBattler][2] == TRUE) // check if we didn't want to display pp number + if (gBattleResources->bufferA[battler][2] == TRUE) // check if we didn't want to display pp number return; SetPpNumbersPaletteInMoveSelection(); - moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); - txtPtr = ConvertIntToDecimalStringN(gDisplayedStringBattle, moveInfo->currentPp[gMoveSelectionCursor[gActiveBattler]], STR_CONV_MODE_RIGHT_ALIGN, 2); + moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); + txtPtr = ConvertIntToDecimalStringN(gDisplayedStringBattle, moveInfo->currentPp[gMoveSelectionCursor[battler]], STR_CONV_MODE_RIGHT_ALIGN, 2); *(txtPtr)++ = CHAR_SLASH; - ConvertIntToDecimalStringN(txtPtr, moveInfo->maxPp[gMoveSelectionCursor[gActiveBattler]], STR_CONV_MODE_RIGHT_ALIGN, 2); + ConvertIntToDecimalStringN(txtPtr, moveInfo->maxPp[gMoveSelectionCursor[battler]], STR_CONV_MODE_RIGHT_ALIGN, 2); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_PP_REMAINING); } -static void MoveSelectionDisplayMoveType(void) +static void MoveSelectionDisplayMoveType(u32 battler) { u8 *txtPtr; - struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); + struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); txtPtr = StringCopy(gDisplayedStringBattle, gText_MoveInterfaceType); *(txtPtr)++ = EXT_CTRL_CODE_BEGIN; *(txtPtr)++ = EXT_CTRL_CODE_FONT; *(txtPtr)++ = FONT_NORMAL; - StringCopy(txtPtr, gTypeNames[gBattleMoves[moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]].type]); + StringCopy(txtPtr, gTypeNames[gBattleMoves[moveInfo->moves[gMoveSelectionCursor[battler]]].type]); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MOVE_TYPE); } @@ -1879,18 +1720,6 @@ void CB2_SetUpReshowBattleScreenAfterMenu2(void) SetMainCallback2(ReshowBattleScreenAfterMenu); } -static void CompleteOnFinishedStatusAnimation(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive) - PlayerBufferExecCompleted(); -} - -static void CompleteOnFinishedBattleAnimation(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive) - PlayerBufferExecCompleted(); -} - static void PrintLinkStandbyMsg(void) { if (gBattleTypeFlags & BATTLE_TYPE_LINK) @@ -1901,724 +1730,62 @@ static void PrintLinkStandbyMsg(void) } } -static void PlayerHandleGetMonData(void) +static void PlayerHandleLoadMonSprite(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 - u32 size = 0; - u8 monToCheck; - s32 i; + BattleLoadMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); + gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = battler; + gBattlerControllerFuncs[battler] = CompleteOnBattlerSpritePosX_0; +} - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - size += CopyPlayerMonData(gBattlerPartyIndexes[gActiveBattler], monData); - } +static void PlayerHandleSwitchInAnim(u32 battler) +{ + gActionSelectionCursor[battler] = 0; + gMoveSelectionCursor[battler] = 0; + BtlController_HandleSwitchInAnim(battler, TRUE, SwitchIn_TryShinyAnimShowHealthbox); +} + +u32 LinkPlayerGetTrainerPicId(u32 multiplayerId) +{ + u32 trainerPicId; + + u8 gender = gLinkPlayers[multiplayerId].gender; + u8 version = gLinkPlayers[multiplayerId].version & 0xFF; + + if (version == VERSION_FIRE_RED || version == VERSION_LEAF_GREEN) + trainerPicId = gender + TRAINER_BACK_PIC_RED; + else if (version == VERSION_RUBY || version == VERSION_SAPPHIRE) + trainerPicId = gender + TRAINER_BACK_PIC_RUBY_SAPPHIRE_BRENDAN; else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - size += CopyPlayerMonData(i, monData + size); - monToCheck >>= 1; - } - } - BtlController_EmitDataTransfer(BUFFER_B, size, monData); - PlayerBufferExecCompleted(); + trainerPicId = gender + TRAINER_BACK_PIC_BRENDAN; + + return trainerPicId; } -static u32 CopyPlayerMonData(u8 monId, u8 *dst) +static u32 PlayerGetTrainerBackPicId(void) { - struct BattlePokemon battleMon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; + u32 trainerPicId; - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - battleMon.species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); - battleMon.item = GetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM); - for (size = 0; size < MAX_MON_MOVES; size++) - { - battleMon.moves[size] = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + size); - battleMon.pp[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - } - battleMon.ppBonuses = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - battleMon.friendship = GetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP); - battleMon.experience = GetMonData(&gPlayerParty[monId], MON_DATA_EXP); - battleMon.hpIV = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - battleMon.attackIV = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - battleMon.defenseIV = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - battleMon.speedIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - battleMon.spAttackIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - battleMon.spDefenseIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - battleMon.personality = GetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY); - battleMon.status1 = GetMonData(&gPlayerParty[monId], MON_DATA_STATUS); - battleMon.level = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); - battleMon.hp = GetMonData(&gPlayerParty[monId], MON_DATA_HP); - battleMon.maxHP = GetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP); - battleMon.attack = GetMonData(&gPlayerParty[monId], MON_DATA_ATK); - battleMon.defense = GetMonData(&gPlayerParty[monId], MON_DATA_DEF); - battleMon.speed = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED); - battleMon.spAttack = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK); - battleMon.spDefense = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF); - battleMon.abilityNum = GetMonData(&gPlayerParty[monId], MON_DATA_ABILITY_NUM); - battleMon.otId = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID); - battleMon.metLevel = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL); - GetMonData(&gPlayerParty[monId], MON_DATA_NICKNAME, nickname); - StringCopy_Nickname(battleMon.nickname, nickname); - GetMonData(&gPlayerParty[monId], MON_DATA_OT_NAME, battleMon.otName); - src = (u8 *)&battleMon; - for (size = 0; size < sizeof(battleMon); size++) - dst[size] = src[size]; - break; - case REQUEST_SPECIES_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_HELDITEM_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MOVES_PP_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - { - moveData.moves[size] = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - src = (u8 *)(&moveData); - for (size = 0; size < sizeof(moveData); size++) - dst[size] = src[size]; - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_PP_DATA_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - dst[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - dst[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - size++; - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE); - size = 1; - break; - case REQUEST_OTID_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_EXP_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_EXP); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_HP_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_EV); - size = 1; - break; - case REQUEST_ATK_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_EV); - size = 1; - break; - case REQUEST_DEF_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_EV); - size = 1; - break; - case REQUEST_SPEED_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_EV); - size = 1; - break; - case REQUEST_SPATK_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_EV); - size = 1; - break; - case REQUEST_SPDEF_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_EV); - size = 1; - break; - case REQUEST_FRIENDSHIP_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP); - size = 1; - break; - case REQUEST_POKERUS_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_POKERUS); - size = 1; - break; - case REQUEST_MET_LOCATION_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LOCATION); - size = 1; - break; - case REQUEST_MET_LEVEL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL); - size = 1; - break; - case REQUEST_MET_GAME_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_GAME); - size = 1; - break; - case REQUEST_POKEBALL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_POKEBALL); - size = 1; - break; - case REQUEST_ALL_IVS_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - dst[1] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - dst[2] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - dst[3] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - dst[4] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - dst[5] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - size = 6; - break; - case REQUEST_HP_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - size = 1; - break; - case REQUEST_ATK_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - size = 1; - break; - case REQUEST_DEF_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - size = 1; - break; - case REQUEST_SPEED_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - size = 1; - break; - case REQUEST_SPATK_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - size = 1; - break; - case REQUEST_SPDEF_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - size = 1; - break; - case REQUEST_PERSONALITY_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_CHECKSUM_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_CHECKSUM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_STATUS_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_STATUS); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_LEVEL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); - size = 1; - break; - case REQUEST_HP_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MAX_HP_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_ATK_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_ATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_DEF_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_DEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPEED_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPATK_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPDEF_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_COOL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_COOL); - size = 1; - break; - case REQUEST_BEAUTY_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY); - size = 1; - break; - case REQUEST_CUTE_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_CUTE); - size = 1; - break; - case REQUEST_SMART_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SMART); - size = 1; - break; - case REQUEST_TOUGH_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_TOUGH); - size = 1; - break; - case REQUEST_SHEEN_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SHEEN); - size = 1; - break; - case REQUEST_COOL_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_COOL_RIBBON); - size = 1; - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case REQUEST_CUTE_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case REQUEST_SMART_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SMART_RIBBON); - size = 1; - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - - return size; -} - -void PlayerHandleGetRawMonData(void) -{ - struct BattlePokemon battleMon; - u8 *src = (u8 *)&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleResources->bufferA[gActiveBattler][1]; - u8 *dst = (u8 *)&battleMon + gBattleResources->bufferA[gActiveBattler][1]; - u8 i; - - for (i = 0; i < gBattleResources->bufferA[gActiveBattler][2]; i++) - dst[i] = src[i]; - - BtlController_EmitDataTransfer(BUFFER_B, gBattleResources->bufferA[gActiveBattler][2], dst); - PlayerBufferExecCompleted(); -} - -static void PlayerHandleSetMonData(void) -{ - u8 monToCheck; - u8 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - SetPlayerMonData(gBattlerPartyIndexes[gActiveBattler]); - } + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + trainerPicId = LinkPlayerGetTrainerPicId(GetMultiplayerId()); else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - SetPlayerMonData(i); - monToCheck >>= 1; - } - } - PlayerBufferExecCompleted(); + trainerPicId = gSaveBlock2Ptr->playerGender + TRAINER_BACK_PIC_BRENDAN; + + return trainerPicId; } -static void SetPlayerMonData(u8 monId) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleResources->bufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleResources->bufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - { - u8 iv; - - SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gPlayerParty[monId], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gPlayerParty[monId], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gPlayerParty[monId], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gPlayerParty[monId], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gPlayerParty[monId], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case REQUEST_SPECIES_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HELDITEM_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MOVES_PP_BATTLE: - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PP_DATA_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PP1, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP2, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP3, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP4, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &gBattleResources->bufferA[gActiveBattler][7]); - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_OTID_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_OT_ID, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_EXP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_FRIENDSHIP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKERUS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_POKERUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LOCATION_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_LOCATION, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LEVEL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_GAME_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_GAME, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKEBALL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_POKEBALL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ALL_IVS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][7]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][8]); - break; - case REQUEST_HP_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PERSONALITY_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CHECKSUM_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CHECKSUM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_STATUS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_STATUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_LEVEL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MAX_HP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_COOL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CUTE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SMART, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_TOUGH, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SHEEN_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SHEEN, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_COOL_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CUTE_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SMART_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_TOUGH_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - } - - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); -} - -static void PlayerHandleSetRawMonData(void) -{ - u8 *dst = (u8 *)&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleResources->bufferA[gActiveBattler][1]; - u8 i; - - for (i = 0; i < gBattleResources->bufferA[gActiveBattler][2]; i++) - dst[i] = gBattleResources->bufferA[gActiveBattler][3 + i]; - - PlayerBufferExecCompleted(); -} - -static void PlayerHandleLoadMonSprite(void) -{ - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBankSpritePosX_0; -} - -static void PlayerHandleSwitchInAnim(void) -{ - ClearTemporarySpeciesSpriteData(gActiveBattler, gBattleResources->bufferA[gActiveBattler][2]); - gBattlerPartyIndexes[gActiveBattler] = gBattleResources->bufferA[gActiveBattler][1]; - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - gActionSelectionCursor[gActiveBattler] = 0; - gMoveSelectionCursor[gActiveBattler] = 0; - StartSendOutAnim(gActiveBattler, gBattleResources->bufferA[gActiveBattler][2]); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_TryShinyAnimShowHealthbox; -} - -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit) -{ - u16 species; - - ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit); - gBattlerPartyIndexes[battlerId] = gBattleResources->bufferA[battlerId][1]; - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); - gBattleControllerData[battlerId] = CreateInvisibleSpriteWithCallback(SpriteCB_WaitForBattlerBallReleaseAnim); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battlerId)); - - gBattlerSpriteIds[battlerId] = CreateSprite( - &gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(battlerId), - GetBattlerSpriteSubpriority(battlerId)); - - gSprites[gBattleControllerData[battlerId]].data[1] = gBattlerSpriteIds[battlerId]; - gSprites[gBattleControllerData[battlerId]].data[2] = battlerId; - - gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId; - gSprites[gBattlerSpriteIds[battlerId]].data[2] = species; - gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId; - - StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], 0); - - gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE; - gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy; - - gSprites[gBattleControllerData[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT); -} - -static void PlayerHandleReturnMonToBall(void) -{ - if (!gBattleResources->bufferA[gActiveBattler][1]) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = DoSwitchOutAnimation; - } - else - { - // Skip animation, just remove battler - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - PlayerBufferExecCompleted(); - } -} - -static void DoSwitchOutAnimation(void) -{ - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SWITCH_OUT_PLAYER_MON); - gBattlerControllerFuncs[gActiveBattler] = FreeMonSpriteAfterSwitchOutAnim; - } - break; - } -} - -#define sSpeedX data[0] - // 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 an animated back pic. -static void PlayerHandleDrawTrainerPic(void) +static void PlayerHandleDrawTrainerPic(u32 battler) { + bool32 isFrontPic; s16 xPos, yPos; - u32 trainerPicId; - - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - if ((gLinkPlayers[GetMultiplayerId()].version & 0xFF) == VERSION_FIRE_RED - || (gLinkPlayers[GetMultiplayerId()].version & 0xFF) == VERSION_LEAF_GREEN) - { - trainerPicId = gLinkPlayers[GetMultiplayerId()].gender + TRAINER_BACK_PIC_RED; - } - else if ((gLinkPlayers[GetMultiplayerId()].version & 0xFF) == VERSION_RUBY - || (gLinkPlayers[GetMultiplayerId()].version & 0xFF) == VERSION_SAPPHIRE) - { - trainerPicId = gLinkPlayers[GetMultiplayerId()].gender + TRAINER_BACK_PIC_RUBY_SAPPHIRE_BRENDAN; - } - else - { - trainerPicId = gLinkPlayers[GetMultiplayerId()].gender + TRAINER_BACK_PIC_BRENDAN; - } - } - else - { - trainerPicId = gSaveBlock2Ptr->playerGender; - } + u32 trainerPicId, gender; + trainerPicId = PlayerGetTrainerBackPicId(); if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { - if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != B_FLANK_LEFT) // Second mon, on the right. + if ((GetBattlerPosition(battler) & BIT_FLANK) != B_FLANK_LEFT) // Second mon, on the right. xPos = 90; else // First mon, on the left. xPos = 32; @@ -2640,267 +1807,90 @@ static void PlayerHandleDrawTrainerPic(void) yPos = (8 - gTrainerBackPicCoords[trainerPicId].size) * 4 + 80; } - // Use front pic table for any tag battles unless your partner is Steven. + // Use front pic table for any tag battles unless your partner is Steven or a custom partner. if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && gPartnerTrainerId != TRAINER_STEVEN_PARTNER && gPartnerTrainerId < TRAINER_CUSTOM_PARTNER) { trainerPicId = PlayerGenderToFrontTrainerPicId(gSaveBlock2Ptr->playerGender); - DecompressTrainerFrontPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerFront(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, xPos, yPos, GetBattlerSpriteSubpriority(gActiveBattler)); - - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].y2 = 48; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = -2; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineMode = ST_OAM_AFFINE_OFF; - gSprites[gBattlerSpriteIds[gActiveBattler]].hFlip = 1; + isFrontPic = TRUE; } - // Use the back pic in any other scenario. - else + else // Use back pic in all the other usual circumstances. { - DecompressTrainerBackPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, xPos, yPos, GetBattlerSpriteSubpriority(gActiveBattler)); - - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = -2; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; + isFrontPic = FALSE; } - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy; + BtlController_HandleDrawTrainerPic(battler, trainerPicId, isFrontPic, xPos, yPos, -1); } -static void PlayerHandleTrainerSlide(void) +static void PlayerHandleTrainerSlide(u32 battler) { - u32 trainerPicId; - - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - if ((gLinkPlayers[GetMultiplayerId()].version & 0xFF) == VERSION_FIRE_RED - || (gLinkPlayers[GetMultiplayerId()].version & 0xFF) == VERSION_LEAF_GREEN) - { - trainerPicId = gLinkPlayers[GetMultiplayerId()].gender + TRAINER_BACK_PIC_RED; - } - else if ((gLinkPlayers[GetMultiplayerId()].version & 0xFF) == VERSION_RUBY - || (gLinkPlayers[GetMultiplayerId()].version & 0xFF) == VERSION_SAPPHIRE) - { - trainerPicId = gLinkPlayers[GetMultiplayerId()].gender + TRAINER_BACK_PIC_RUBY_SAPPHIRE_BRENDAN; - } - else - { - trainerPicId = gLinkPlayers[GetMultiplayerId()].gender + TRAINER_BACK_PIC_BRENDAN; - } - } - else - { - trainerPicId = gSaveBlock2Ptr->playerGender + TRAINER_BACK_PIC_BRENDAN; - } - - DecompressTrainerBackPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, 80, (8 - gTrainerBackPicCoords[trainerPicId].size) * 4 + 80, 30); - - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -96; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = 2; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBankSpriteCallbackDummy2; + u32 trainerPicId = PlayerGetTrainerBackPicId(); + BtlController_HandleTrainerSlide(battler, trainerPicId); } -#undef sSpeedX - -static void PlayerHandleTrainerSlideBack(void) +static void PlayerHandleTrainerSlideBack(u32 battler) { - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 50; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCallbackDummy); - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 1); - gBattlerControllerFuncs[gActiveBattler] = FreeTrainerSpriteAfterSlide; + BtlController_HandleTrainerSlideBack(battler, 50, TRUE); } -#define sSpeedX data[1] -#define sSpeedY data[2] - -static void PlayerHandleFaintAnimation(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState == 0) - { - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState++; - } - else - { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - PlaySE12WithPanning(SE_FAINT, SOUND_PAN_ATTACKER); - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = 0; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedY = 5; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_FaintSlideAnim; - gBattlerControllerFuncs[gActiveBattler] = FreeMonSpriteAfterFaintAnim; - } - } -} - -#undef sSpeedX -#undef sSpeedY - -static void PlayerHandlePaletteFade(void) +static void PlayerHandlePaletteFade(u32 battler) { BeginNormalPaletteFade(PALETTES_ALL, 2, 0, 16, RGB_BLACK); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } -static void PlayerHandleSuccessBallThrowAnim(void) +static void PlayerHandleSuccessBallThrowAnim(u32 battler) { - gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS; - gDoingBattleAnim = TRUE; - if (IsCriticalCapture()) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gBattlerTarget, B_ANIM_CRITICAL_CAPTURE_THROW); - else - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gBattlerTarget, B_ANIM_BALL_THROW); - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnSpecialAnimDone; + BtlController_HandleSuccessBallThrowAnim(battler, gBattlerTarget, B_ANIM_BALL_THROW, TRUE); } -static void PlayerHandleBallThrowAnim(void) +static void PlayerHandleBallThrowAnim(u32 battler) { - u8 ballThrowCaseId = gBattleResources->bufferA[gActiveBattler][1]; - - gBattleSpritesDataPtr->animationData->ballThrowCaseId = ballThrowCaseId; - gDoingBattleAnim = TRUE; - if (IsCriticalCapture()) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gBattlerTarget, B_ANIM_CRITICAL_CAPTURE_THROW); - else - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gBattlerTarget, B_ANIM_BALL_THROW); - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnSpecialAnimDone; + BtlController_HandleBallThrowAnim(battler, gBattlerTarget, B_ANIM_BALL_THROW, TRUE); } -static void PlayerHandlePause(void) +static void PlayerHandlePause(u32 battler) { - u8 timer = gBattleResources->bufferA[gActiveBattler][1]; + u8 timer = gBattleResources->bufferA[battler][1]; while (timer != 0) timer--; - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } -static void PlayerHandleMoveAnimation(void) +static void PlayerHandleMoveAnimation(u32 battler) { - if (!IsBattleSEPlaying(gActiveBattler)) - { - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleResources->bufferA[gActiveBattler][3]; - gAnimMovePower = gBattleResources->bufferA[gActiveBattler][4] | (gBattleResources->bufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleResources->bufferA[gActiveBattler][6] | (gBattleResources->bufferA[gActiveBattler][7] << 8) | (gBattleResources->bufferA[gActiveBattler][8] << 16) | (gBattleResources->bufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleResources->bufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleResources->bufferA[gActiveBattler][12] | (gBattleResources->bufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - gTransformedOtIds[gActiveBattler] = gAnimDisableStructPtr->transformedMonOtId; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = PlayerDoMoveAnimation; - BattleTv_SetDataBasedOnMove(move, gWeatherMoveAnim, gAnimDisableStructPtr); - } + BtlController_HandleMoveAnimation(battler, TRUE); } -static void PlayerDoMoveAnimation(void) +static void PlayerHandlePrintString(u32 battler) { - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - u8 multihit = gBattleResources->bufferA[gActiveBattler][11]; - - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute - && !gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8) - { - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 1; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF); - DoMoveAnim(move); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL); - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute && multihit < 2) - { - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 0; - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 3; - } - break; - case 3: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - CopyAllBattleSpritesInvisibilities(); - TrySetBehindSubstituteSpriteBit(gActiveBattler, gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - PlayerBufferExecCompleted(); - } - break; - } + BtlController_HandlePrintString(battler, TRUE, TRUE); } -static void PlayerHandlePrintString(void) +static void PlayerHandlePrintSelectionString(u32 battler) { - u16 *stringId; - - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - stringId = (u16 *)(&gBattleResources->bufferA[gActiveBattler][2]); - BufferStringBattle(*stringId); - BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter2; - BattleTv_SetDataBasedOnString(*stringId); - BattleArena_DeductSkillPoints(gActiveBattler, *stringId); -} - -static void PlayerHandlePrintSelectionString(void) -{ - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - PlayerHandlePrintString(); + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + PlayerHandlePrintString(battler); else - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } -static void HandleChooseActionAfterDma3(void) +static void HandleChooseActionAfterDma3(u32 battler) { if (!IsDma3ManagerBusyWithBgCopy()) { gBattle_BG0_X = 0; gBattle_BG0_Y = DISPLAY_HEIGHT; - gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseAction; + gBattlerControllerFuncs[battler] = HandleInputChooseAction; } } -static void PlayerHandleChooseAction(void) +static void PlayerHandleChooseAction(u32 battler) { s32 i; - gBattlerControllerFuncs[gActiveBattler] = HandleChooseActionAfterDma3; + gBattlerControllerFuncs[battler] = HandleChooseActionAfterDma3; BattleTv_ClearExplosionFaintCause(); BattlePutTextOnWindow(gText_BattleMenu, B_WIN_ACTION_MENU); @@ -2908,180 +1898,155 @@ static void PlayerHandleChooseAction(void) ActionSelectionDestroyCursorAt(i); TryRestoreLastUsedBall(); - ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); + ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT); } -static void PlayerHandleYesNoBox(void) +static void PlayerHandleYesNoBox(u32 battler) { - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) + if (GetBattlerSide(battler) == B_SIDE_PLAYER) { HandleBattleWindow(YESNOBOX_X_Y, 0); BattlePutTextOnWindow(gText_BattleYesNoChoice, B_WIN_YESNO); gMultiUsePlayerCursor = 1; BattleCreateYesNoCursorAt(1); - gBattlerControllerFuncs[gActiveBattler] = PlayerHandleYesNoInput; + gBattlerControllerFuncs[battler] = PlayerHandleYesNoInput; } else { - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } } -static void HandleChooseMoveAfterDma3(void) +static void HandleChooseMoveAfterDma3(u32 battler) { if (!IsDma3ManagerBusyWithBgCopy()) { gBattle_BG0_X = 0; gBattle_BG0_Y = DISPLAY_HEIGHT * 2; - gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseMove; + gBattlerControllerFuncs[battler] = HandleInputChooseMove; } } // arenaMindPoints is used here as a placeholder for a timer. -static void PlayerChooseMoveInBattlePalace(void) +static void PlayerChooseMoveInBattlePalace(u32 battler) { - if (--*(gBattleStruct->arenaMindPoints + gActiveBattler) == 0) + if (--*(gBattleStruct->arenaMindPoints + battler) == 0) { gBattlePalaceMoveSelectionRngValue = gRngValue; BtlController_EmitTwoReturnValues(BUFFER_B, 10, ChooseMoveAndTargetInBattlePalace()); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } } -static void PlayerHandleChooseMove(void) +static void PlayerHandleChooseMove(u32 battler) { if (gBattleTypeFlags & BATTLE_TYPE_PALACE) { - *(gBattleStruct->arenaMindPoints + gActiveBattler) = 8; - gBattlerControllerFuncs[gActiveBattler] = PlayerChooseMoveInBattlePalace; + *(gBattleStruct->arenaMindPoints + battler) = 8; + gBattlerControllerFuncs[battler] = PlayerChooseMoveInBattlePalace; } else { - struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); + struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); - InitMoveSelectionsVarsAndStrings(); + InitMoveSelectionsVarsAndStrings(battler); gBattleStruct->mega.playerSelect = FALSE; if (!IsMegaTriggerSpriteActive()) gBattleStruct->mega.triggerSpriteId = 0xFF; - if (CanMegaEvolve(gActiveBattler)) - CreateMegaTriggerSprite(gActiveBattler, 0); + if (CanMegaEvolve(battler)) + CreateMegaTriggerSprite(battler, 0); if (!IsZMoveTriggerSpriteActive()) gBattleStruct->zmove.triggerSpriteId = 0xFF; - GetUsableZMoves(gActiveBattler, moveInfo->moves); - gBattleStruct->zmove.viable = IsZMoveUsable(gActiveBattler, gMoveSelectionCursor[gActiveBattler]); - CreateZMoveTriggerSprite(gActiveBattler, gBattleStruct->zmove.viable); - gBattlerControllerFuncs[gActiveBattler] = HandleChooseMoveAfterDma3; + GetUsableZMoves(battler, moveInfo->moves); + gBattleStruct->zmove.viable = IsZMoveUsable(battler, gMoveSelectionCursor[battler]); + CreateZMoveTriggerSprite(battler, gBattleStruct->zmove.viable); + gBattlerControllerFuncs[battler] = HandleChooseMoveAfterDma3; } } -void InitMoveSelectionsVarsAndStrings(void) +void InitMoveSelectionsVarsAndStrings(u32 battler) { - MoveSelectionDisplayMoveNames(); + MoveSelectionDisplayMoveNames(battler); gMultiUsePlayerCursor = 0xFF; - MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0); - MoveSelectionDisplayPpString(); - MoveSelectionDisplayPpNumber(); - MoveSelectionDisplayMoveType(); + MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + MoveSelectionDisplayPpString(battler); + MoveSelectionDisplayPpNumber(battler); + MoveSelectionDisplayMoveType(battler); } -static void PlayerHandleChooseItem(void) +static void PlayerHandleChooseItem(u32 battler) { s32 i; BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); - gBattlerControllerFuncs[gActiveBattler] = OpenBagAndChooseItem; - gBattlerInMenuId = gActiveBattler; + gBattlerControllerFuncs[battler] = OpenBagAndChooseItem; + gBattlerInMenuId = battler; for (i = 0; i < ARRAY_COUNT(gBattlePartyCurrentOrder); i++) - gBattlePartyCurrentOrder[i] = gBattleResources->bufferA[gActiveBattler][1 + i]; + gBattlePartyCurrentOrder[i] = gBattleResources->bufferA[battler][1 + i]; } -static void PlayerHandleChoosePokemon(void) +static void PlayerHandleChoosePokemon(u32 battler) { s32 i; for (i = 0; i < ARRAY_COUNT(gBattlePartyCurrentOrder); i++) - gBattlePartyCurrentOrder[i] = gBattleResources->bufferA[gActiveBattler][4 + i]; + gBattlePartyCurrentOrder[i] = gBattleResources->bufferA[battler][4 + i]; - if (gBattleTypeFlags & BATTLE_TYPE_ARENA && (gBattleResources->bufferA[gActiveBattler][1] & 0xF) != PARTY_ACTION_CANT_SWITCH - && (gBattleResources->bufferA[gActiveBattler][1] & 0xF) != PARTY_ACTION_CHOOSE_FAINTED_MON) + if (gBattleTypeFlags & BATTLE_TYPE_ARENA && (gBattleResources->bufferA[battler][1] & 0xF) != PARTY_ACTION_CANT_SWITCH + && (gBattleResources->bufferA[battler][1] & 0xF) != PARTY_ACTION_CHOOSE_FAINTED_MON) { - BtlController_EmitChosenMonReturnValue(BUFFER_B, gBattlerPartyIndexes[gActiveBattler] + 1, gBattlePartyCurrentOrder); - PlayerBufferExecCompleted(); + BtlController_EmitChosenMonReturnValue(BUFFER_B, gBattlerPartyIndexes[battler] + 1, gBattlePartyCurrentOrder); + PlayerBufferExecCompleted(battler); } else { - gBattleControllerData[gActiveBattler] = CreateTask(TaskDummy, 0xFF); - gTasks[gBattleControllerData[gActiveBattler]].data[0] = gBattleResources->bufferA[gActiveBattler][1] & 0xF; - *(&gBattleStruct->battlerPreventingSwitchout) = gBattleResources->bufferA[gActiveBattler][1] >> 4; - *(&gBattleStruct->prevSelectedPartySlot) = gBattleResources->bufferA[gActiveBattler][2]; - *(&gBattleStruct->abilityPreventingSwitchout) = (gBattleResources->bufferA[gActiveBattler][3] & 0xFF) | (gBattleResources->bufferA[gActiveBattler][7] << 8); + gBattleControllerData[battler] = CreateTask(TaskDummy, 0xFF); + gTasks[gBattleControllerData[battler]].data[0] = gBattleResources->bufferA[battler][1] & 0xF; + *(&gBattleStruct->battlerPreventingSwitchout) = gBattleResources->bufferA[battler][1] >> 4; + *(&gBattleStruct->prevSelectedPartySlot) = gBattleResources->bufferA[battler][2]; + *(&gBattleStruct->abilityPreventingSwitchout) = (gBattleResources->bufferA[battler][3] & 0xFF) | (gBattleResources->bufferA[battler][7] << 8); BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); - gBattlerControllerFuncs[gActiveBattler] = OpenPartyMenuToChooseMon; - gBattlerInMenuId = gActiveBattler; + gBattlerControllerFuncs[battler] = OpenPartyMenuToChooseMon; + gBattlerInMenuId = battler; } } -static void PlayerHandleCmd23(void) +static void PlayerHandleCmd23(u32 battler) { BattleStopLowHpSound(); BeginNormalPaletteFade(PALETTES_ALL, 2, 0, 16, RGB_BLACK); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } -static void PlayerHandleHealthBarUpdate(void) +static void PlayerHandleHealthBarUpdate(u32 battler) { - s16 hpVal; - - LoadBattleBarGfx(0); - hpVal = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - // gPlayerPartyLostHP used by Battle Dome, but never read - if (hpVal > 0) - gPlayerPartyLostHP += hpVal; - - if (hpVal != INSTANT_HP_BAR_DROP) - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - u32 curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); - - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, curHP, hpVal); - } - else - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, 0, maxHP); - } - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone; + BtlController_HandleHealthBarUpdate(battler, TRUE); } -static void PlayerHandleExpUpdate(void) +void PlayerHandleExpUpdate(u32 battler) { - u8 monId = gBattleResources->bufferA[gActiveBattler][1]; + u8 monId = gBattleResources->bufferA[battler][1]; s32 taskId, expPointsToGive; if (GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL) >= MAX_LEVEL) { - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } else { LoadBattleBarGfx(1); - GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); // Unused return value. - expPointsToGive = T1_READ_32(&gBattleResources->bufferA[gActiveBattler][2]); + expPointsToGive = T1_READ_32(&gBattleResources->bufferA[battler][2]); taskId = CreateTask(Task_GiveExpToMon, 10); gTasks[taskId].tExpTask_monId = monId; gTasks[taskId].tExpTask_gainedExp_1 = expPointsToGive; gTasks[taskId].tExpTask_gainedExp_2 = expPointsToGive >> 16; - gTasks[taskId].tExpTask_battler = gActiveBattler; - gBattlerControllerFuncs[gActiveBattler] = BattleControllerDummy; + gTasks[taskId].tExpTask_battler = battler; + gBattlerControllerFuncs[battler] = BattleControllerDummy; } } @@ -3091,51 +2056,23 @@ static void PlayerHandleExpUpdate(void) #undef tExpTask_gainedExp_2 #undef tExpTask_frames -static void PlayerHandleStatusIconUpdate(void) +static void PlayerHandleStatusXor(u32 battler) { - if (!IsBattleSEPlaying(gActiveBattler)) - { - u8 battlerId; + u8 val = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_STATUS) ^ gBattleResources->bufferA[battler][1]; - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON); - battlerId = gActiveBattler; - gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0; - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - } + SetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_STATUS, &val); + PlayerBufferExecCompleted(battler); } -static void PlayerHandleStatusAnimation(void) +static void PlayerHandleDMA3Transfer(u32 battler) { - if (!IsBattleSEPlaying(gActiveBattler)) - { - InitAndLaunchChosenStatusAnimation(gBattleResources->bufferA[gActiveBattler][1], - gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8) | (gBattleResources->bufferA[gActiveBattler][4] << 16) | (gBattleResources->bufferA[gActiveBattler][5] << 24)); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - } -} + u32 dstArg = gBattleResources->bufferA[battler][1] + | (gBattleResources->bufferA[battler][2] << 8) + | (gBattleResources->bufferA[battler][3] << 16) + | (gBattleResources->bufferA[battler][4] << 24); + u16 sizeArg = gBattleResources->bufferA[battler][5] | (gBattleResources->bufferA[battler][6] << 8); -static void PlayerHandleStatusXor(void) -{ - u8 val = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_STATUS) ^ gBattleResources->bufferA[gActiveBattler][1]; - - SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_STATUS, &val); - PlayerBufferExecCompleted(); -} - -static void PlayerHandleDataTransfer(void) -{ - PlayerBufferExecCompleted(); -} - -static void PlayerHandleDMA3Transfer(void) -{ - u32 dstArg = gBattleResources->bufferA[gActiveBattler][1] - | (gBattleResources->bufferA[gActiveBattler][2] << 8) - | (gBattleResources->bufferA[gActiveBattler][3] << 16) - | (gBattleResources->bufferA[gActiveBattler][4] << 24); - u16 sizeArg = gBattleResources->bufferA[gActiveBattler][5] | (gBattleResources->bufferA[gActiveBattler][6] << 8); - - const u8 *src = &gBattleResources->bufferA[gActiveBattler][7]; + const u8 *src = &gBattleResources->bufferA[battler][7]; u8 *dst = (u8 *)(dstArg); u32 size = sizeArg; @@ -3151,351 +2088,121 @@ static void PlayerHandleDMA3Transfer(void) dst += 0x1000; size -= 0x1000; } - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } -static void PlayerHandlePlayBGM(void) +static void PlayerHandlePlayBGM(u32 battler) { - PlayBGM(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - PlayerBufferExecCompleted(); + PlayBGM(gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8)); + PlayerBufferExecCompleted(battler); } -static void PlayerHandleCmd32(void) -{ - PlayerBufferExecCompleted(); -} - -static void PlayerHandleTwoReturnValues(void) +static void PlayerHandleTwoReturnValues(u32 battler) { BtlController_EmitTwoReturnValues(BUFFER_B, 0, 0); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } -static void PlayerHandleChosenMonReturnValue(void) +static void PlayerHandleChosenMonReturnValue(u32 battler) { BtlController_EmitChosenMonReturnValue(BUFFER_B, 0, NULL); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } -static void PlayerHandleOneReturnValue(void) +static void PlayerHandleOneReturnValue(u32 battler) { BtlController_EmitOneReturnValue(BUFFER_B, 0); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } -static void PlayerHandleOneReturnValue_Duplicate(void) +static void PlayerHandleOneReturnValue_Duplicate(u32 battler) { BtlController_EmitOneReturnValue_Duplicate(BUFFER_B, 0); - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } -static void PlayerHandleClearUnkVar(void) +static void PlayerHandleIntroTrainerBallThrow(u32 battler) { - gUnusedControllerStruct.unk = 0; - PlayerBufferExecCompleted(); + const u32 *trainerPal = gTrainerBackPicPaletteTable[gSaveBlock2Ptr->playerGender].data; + BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F8, trainerPal, 31, Intro_TryShinyAnimShowHealthbox); } -static void PlayerHandleSetUnkVar(void) +static void PlayerHandleDrawPartyStatusSummary(u32 battler) { - gUnusedControllerStruct.unk = gBattleResources->bufferA[gActiveBattler][1]; - PlayerBufferExecCompleted(); + BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, TRUE); } -static void PlayerHandleClearUnkFlag(void) +static void PlayerHandleEndBounceEffect(u32 battler) { - gUnusedControllerStruct.flag = 0; - PlayerBufferExecCompleted(); + EndBounceEffect(battler, BOUNCE_HEALTHBOX); + EndBounceEffect(battler, BOUNCE_MON); + PlayerBufferExecCompleted(battler); } -static void PlayerHandleToggleUnkFlag(void) +static void PlayerHandleBattleAnimation(u32 battler) { - gUnusedControllerStruct.flag ^= 1; - PlayerBufferExecCompleted(); + BtlController_HandleBattleAnimation(battler, FALSE, TRUE); } -static void PlayerHandleHitAnimation(void) +static void PlayerHandleLinkStandbyMsg(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].invisible == TRUE) - { - PlayerBufferExecCompleted(); - } - else - { - gDoingBattleAnim = TRUE; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[1] = 0; - DoHitAnimHealthboxEffect(gActiveBattler); - gBattlerControllerFuncs[gActiveBattler] = DoHitAnimBlinkSpriteEffect; - } -} - -static void PlayerHandleCantSwitch(void) -{ - PlayerBufferExecCompleted(); -} - -static void PlayerHandlePlaySE(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - pan = SOUND_PAN_ATTACKER; - else - pan = SOUND_PAN_TARGET; - - PlaySE12WithPanning(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8), pan); - PlayerBufferExecCompleted(); -} - -static void PlayerHandlePlayFanfareOrBGM(void) -{ - if (gBattleResources->bufferA[gActiveBattler][3]) - { - BattleStopLowHpSound(); - PlayBGM(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - else - { - PlayFanfare(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - - PlayerBufferExecCompleted(); -} - -static void PlayerHandleFaintingCry(void) -{ - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - PlayCry_ByMode(species, -25, CRY_MODE_FAINT); - PlayerBufferExecCompleted(); -} - -static void PlayerHandleIntroSlide(void) -{ - HandleIntroSlide(gBattleResources->bufferA[gActiveBattler][1]); - gIntroSlideFlags |= 1; - PlayerBufferExecCompleted(); -} - -// Task data for Task_StartSendOutAnim -#define tBattlerId data[0] -#define tStartTimer data[1] - -#define sBattlerId data[5] - -static void PlayerHandleIntroTrainerBallThrow(void) -{ - u8 paletteNum; - u8 taskId; - - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 50; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - gSprites[gBattlerSpriteIds[gActiveBattler]].sBattlerId = gActiveBattler; - - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCB_FreePlayerSpriteLoadMonSprite); - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 1); - - paletteNum = AllocSpritePalette(0xD6F8); - LoadCompressedPalette(gTrainerBackPicPaletteTable[gSaveBlock2Ptr->playerGender].data, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP); - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = paletteNum; - - taskId = CreateTask(Task_StartSendOutAnim, 5); - gTasks[taskId].tBattlerId = gActiveBattler; - - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - - gBattleSpritesDataPtr->animationData->introAnimActive = TRUE; - gBattlerControllerFuncs[gActiveBattler] = BattleControllerDummy; -} - -void SpriteCB_FreePlayerSpriteLoadMonSprite(struct Sprite *sprite) -{ - u8 battlerId = sprite->sBattlerId; - - // Free player trainer sprite - FreeSpriteOamMatrix(sprite); - FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum)); - DestroySprite(sprite); - - // Load mon sprite - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battlerId]], battlerId); - StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], 0); -} - -#undef sBattlerId - -// Send out at start of battle -static void Task_StartSendOutAnim(u8 taskId) -{ - if (gTasks[taskId].tStartTimer < 31) - { - gTasks[taskId].tStartTimer++; - } - else - { - u8 savedActiveBattler = gActiveBattler; - - gActiveBattler = gTasks[taskId].tBattlerId; - if (TwoIntroMons(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler ^= BIT_FLANK; - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler ^= BIT_FLANK; - } - else - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - } - gBattlerControllerFuncs[gActiveBattler] = Intro_TryShinyAnimShowHealthbox; - gActiveBattler = savedActiveBattler; - DestroyTask(taskId); - } -} - -#undef tBattlerId -#undef tStartTimer - -static void PlayerHandleDrawPartyStatusSummary(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - { - PlayerBufferExecCompleted(); - } - else - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown = 1; - gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleResources->bufferA[gActiveBattler][4], gBattleResources->bufferA[gActiveBattler][1], gBattleResources->bufferA[gActiveBattler][2]); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - - // If intro, skip the delay after drawing - if (gBattleResources->bufferA[gActiveBattler][2] != 0) - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 93; - - gBattlerControllerFuncs[gActiveBattler] = EndDrawPartyStatusSummary; - } -} - -static void EndDrawPartyStatusSummary(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer++ > 92) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - PlayerBufferExecCompleted(); - } -} - -static void PlayerHandleHidePartyStatusSummary(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - PlayerBufferExecCompleted(); -} - -static void PlayerHandleEndBounceEffect(void) -{ - EndBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX); - EndBounceEffect(gActiveBattler, BOUNCE_MON); - PlayerBufferExecCompleted(); -} - -static void PlayerHandleSpriteInvisibility(void) -{ - if (IsBattlerSpritePresent(gActiveBattler)) - { - gSprites[gBattlerSpriteIds[gActiveBattler]].invisible = gBattleResources->bufferA[gActiveBattler][1]; - CopyBattleSpriteInvisibility(gActiveBattler); - } - PlayerBufferExecCompleted(); -} - -static void PlayerHandleBattleAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u8 animationId = gBattleResources->bufferA[gActiveBattler][1]; - u16 argument = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (TryHandleLaunchBattleTableAnimation(gActiveBattler, gActiveBattler, gActiveBattler, animationId, argument)) - PlayerBufferExecCompleted(); - else - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; - - BattleTv_SetDataBasedOnAnimation(animationId); - } -} - -static void PlayerHandleLinkStandbyMsg(void) -{ - RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[gActiveBattler][2]); - switch (gBattleResources->bufferA[gActiveBattler][1]) + RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][2]); + switch (gBattleResources->bufferA[battler][1]) { case LINK_STANDBY_MSG_STOP_BOUNCE: PrintLinkStandbyMsg(); // fall through case LINK_STANDBY_STOP_BOUNCE_ONLY: - EndBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX); - EndBounceEffect(gActiveBattler, BOUNCE_MON); + EndBounceEffect(battler, BOUNCE_HEALTHBOX); + EndBounceEffect(battler, BOUNCE_MON); break; case LINK_STANDBY_MSG_ONLY: PrintLinkStandbyMsg(); break; } - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } -static void PlayerHandleResetActionMoveSelection(void) +static void PlayerHandleResetActionMoveSelection(u32 battler) { - switch (gBattleResources->bufferA[gActiveBattler][1]) + switch (gBattleResources->bufferA[battler][1]) { case RESET_ACTION_MOVE_SELECTION: - gActionSelectionCursor[gActiveBattler] = 0; - gMoveSelectionCursor[gActiveBattler] = 0; + gActionSelectionCursor[battler] = 0; + gMoveSelectionCursor[battler] = 0; break; case RESET_ACTION_SELECTION: - gActionSelectionCursor[gActiveBattler] = 0; + gActionSelectionCursor[battler] = 0; break; case RESET_MOVE_SELECTION: - gMoveSelectionCursor[gActiveBattler] = 0; + gMoveSelectionCursor[battler] = 0; break; } - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } -static void PlayerHandleEndLinkBattle(void) +static void PlayerHandleEndLinkBattle(u32 battler) { - RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[gActiveBattler][4]); - gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; - gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[gActiveBattler][2]; + RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]); + gBattleOutcome = gBattleResources->bufferA[battler][1]; + gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2]; FadeOutMapMusic(5); BeginFastPaletteFade(3); - PlayerBufferExecCompleted(); - gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; + PlayerBufferExecCompleted(battler); + gBattlerControllerFuncs[battler] = SetBattleEndCallbacks; } -static void WaitForDebug(void) +static void Controller_WaitForDebug(u32 battler) { if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) { - PlayerBufferExecCompleted(); + PlayerBufferExecCompleted(battler); } } -static void PlayerHandleBattleDebug(void) +static void PlayerHandleBattleDebug(u32 battler) { BeginNormalPaletteFade(-1, 0, 0, 0x10, 0); SetMainCallback2(CB2_BattleDebugMenu); - gBattlerControllerFuncs[gActiveBattler] = WaitForDebug; -} - -static void PlayerCmdEnd(void) -{ + gBattlerControllerFuncs[battler] = Controller_WaitForDebug; } diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c index 3a4beeca9..3f6014302 100644 --- a/src/battle_controller_player_partner.c +++ b/src/battle_controller_player_partner.c @@ -31,211 +31,126 @@ #include "constants/party_menu.h" #include "constants/trainers.h" -static void PlayerPartnerHandleGetMonData(void); -static void PlayerPartnerHandleGetRawMonData(void); -static void PlayerPartnerHandleSetMonData(void); -static void PlayerPartnerHandleSetRawMonData(void); -static void PlayerPartnerHandleLoadMonSprite(void); -static void PlayerPartnerHandleSwitchInAnim(void); -static void PlayerPartnerHandleReturnMonToBall(void); -static void PlayerPartnerHandleDrawTrainerPic(void); -static void PlayerPartnerHandleTrainerSlide(void); -static void PlayerPartnerHandleTrainerSlideBack(void); -static void PlayerPartnerHandleFaintAnimation(void); -static void PlayerPartnerHandlePaletteFade(void); -static void PlayerPartnerHandleSuccessBallThrowAnim(void); -static void PlayerPartnerHandleBallThrowAnim(void); -static void PlayerPartnerHandlePause(void); -static void PlayerPartnerHandleMoveAnimation(void); -static void PlayerPartnerHandlePrintString(void); -static void PlayerPartnerHandlePrintSelectionString(void); -static void PlayerPartnerHandleChooseAction(void); -static void PlayerPartnerHandleYesNoBox(void); -static void PlayerPartnerHandleChooseMove(void); -static void PlayerPartnerHandleChooseItem(void); -static void PlayerPartnerHandleChoosePokemon(void); -static void PlayerPartnerHandleCmd23(void); -static void PlayerPartnerHandleHealthBarUpdate(void); -static void PlayerPartnerHandleExpUpdate(void); -static void PlayerPartnerHandleStatusIconUpdate(void); -static void PlayerPartnerHandleStatusAnimation(void); -static void PlayerPartnerHandleStatusXor(void); -static void PlayerPartnerHandleDataTransfer(void); -static void PlayerPartnerHandleDMA3Transfer(void); -static void PlayerPartnerHandlePlayBGM(void); -static void PlayerPartnerHandleCmd32(void); -static void PlayerPartnerHandleTwoReturnValues(void); -static void PlayerPartnerHandleChosenMonReturnValue(void); -static void PlayerPartnerHandleOneReturnValue(void); -static void PlayerPartnerHandleOneReturnValue_Duplicate(void); -static void PlayerPartnerHandleClearUnkVar(void); -static void PlayerPartnerHandleSetUnkVar(void); -static void PlayerPartnerHandleClearUnkFlag(void); -static void PlayerPartnerHandleToggleUnkFlag(void); -static void PlayerPartnerHandleHitAnimation(void); -static void PlayerPartnerHandleCantSwitch(void); -static void PlayerPartnerHandlePlaySE(void); -static void PlayerPartnerHandlePlayFanfareOrBGM(void); -static void PlayerPartnerHandleFaintingCry(void); -static void PlayerPartnerHandleIntroSlide(void); -static void PlayerPartnerHandleIntroTrainerBallThrow(void); -static void PlayerPartnerHandleDrawPartyStatusSummary(void); -static void PlayerPartnerHandleHidePartyStatusSummary(void); -static void PlayerPartnerHandleEndBounceEffect(void); -static void PlayerPartnerHandleSpriteInvisibility(void); -static void PlayerPartnerHandleBattleAnimation(void); -static void PlayerPartnerHandleLinkStandbyMsg(void); -static void PlayerPartnerHandleResetActionMoveSelection(void); -static void PlayerPartnerHandleEndLinkBattle(void); -static void PlayerPartnerHandleBattleDebug(void); -static void PlayerPartnerCmdEnd(void); +static void PlayerPartnerHandleLoadMonSprite(u32 battler); +static void PlayerPartnerHandleSwitchInAnim(u32 battler); +static void PlayerPartnerHandleDrawTrainerPic(u32 battler); +static void PlayerPartnerHandleTrainerSlideBack(u32 battler); +static void PlayerPartnerHandleMoveAnimation(u32 battler); +static void PlayerPartnerHandlePrintString(u32 battler); +static void PlayerPartnerHandleChooseAction(u32 battler); +static void PlayerPartnerHandleChooseMove(u32 battler); +static void PlayerPartnerHandleChoosePokemon(u32 battler); +static void PlayerPartnerHandleHealthBarUpdate(u32 battler); +static void PlayerPartnerHandleIntroTrainerBallThrow(u32 battler); +static void PlayerPartnerHandleDrawPartyStatusSummary(u32 battler); +static void PlayerPartnerHandleBattleAnimation(u32 battler); +static void PlayerPartnerHandleEndLinkBattle(u32 battler); -static void PlayerPartnerBufferRunCommand(void); -static void PlayerPartnerBufferExecCompleted(void); -static void Task_LaunchLvlUpAnim(u8 taskId); -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 u32 CopyPlayerPartnerMonData(u8 monId, u8 *dst); -static void SetPlayerPartnerMonData(u8 monId); -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit); -static void DoSwitchOutAnimation(void); -static void PlayerPartnerDoMoveAnimation(void); -static void Task_StartSendOutAnim(u8 taskId); -static void EndDrawPartyStatusSummary(void); +static void PlayerPartnerBufferRunCommand(u32 battler); +static void PlayerPartnerBufferExecCompleted(u32 battler); +static void SwitchIn_WaitAndEnd(u32 battler); -static void (*const sPlayerPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(void) = +static void (*const sPlayerPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) = { - [CONTROLLER_GETMONDATA] = PlayerPartnerHandleGetMonData, - [CONTROLLER_GETRAWMONDATA] = PlayerPartnerHandleGetRawMonData, - [CONTROLLER_SETMONDATA] = PlayerPartnerHandleSetMonData, - [CONTROLLER_SETRAWMONDATA] = PlayerPartnerHandleSetRawMonData, + [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, + [CONTROLLER_GETRAWMONDATA] = BtlController_Empty, + [CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, + [CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData, [CONTROLLER_LOADMONSPRITE] = PlayerPartnerHandleLoadMonSprite, [CONTROLLER_SWITCHINANIM] = PlayerPartnerHandleSwitchInAnim, - [CONTROLLER_RETURNMONTOBALL] = PlayerPartnerHandleReturnMonToBall, + [CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, [CONTROLLER_DRAWTRAINERPIC] = PlayerPartnerHandleDrawTrainerPic, - [CONTROLLER_TRAINERSLIDE] = PlayerPartnerHandleTrainerSlide, + [CONTROLLER_TRAINERSLIDE] = BtlController_Empty, [CONTROLLER_TRAINERSLIDEBACK] = PlayerPartnerHandleTrainerSlideBack, - [CONTROLLER_FAINTANIMATION] = PlayerPartnerHandleFaintAnimation, - [CONTROLLER_PALETTEFADE] = PlayerPartnerHandlePaletteFade, - [CONTROLLER_SUCCESSBALLTHROWANIM] = PlayerPartnerHandleSuccessBallThrowAnim, - [CONTROLLER_BALLTHROWANIM] = PlayerPartnerHandleBallThrowAnim, - [CONTROLLER_PAUSE] = PlayerPartnerHandlePause, + [CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, + [CONTROLLER_PALETTEFADE] = BtlController_Empty, + [CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty, + [CONTROLLER_BALLTHROWANIM] = BtlController_Empty, + [CONTROLLER_PAUSE] = BtlController_Empty, [CONTROLLER_MOVEANIMATION] = PlayerPartnerHandleMoveAnimation, [CONTROLLER_PRINTSTRING] = PlayerPartnerHandlePrintString, - [CONTROLLER_PRINTSTRINGPLAYERONLY] = PlayerPartnerHandlePrintSelectionString, + [CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty, [CONTROLLER_CHOOSEACTION] = PlayerPartnerHandleChooseAction, - [CONTROLLER_YESNOBOX] = PlayerPartnerHandleYesNoBox, + [CONTROLLER_YESNOBOX] = BtlController_Empty, [CONTROLLER_CHOOSEMOVE] = PlayerPartnerHandleChooseMove, - [CONTROLLER_OPENBAG] = PlayerPartnerHandleChooseItem, + [CONTROLLER_OPENBAG] = BtlController_Empty, [CONTROLLER_CHOOSEPOKEMON] = PlayerPartnerHandleChoosePokemon, - [CONTROLLER_23] = PlayerPartnerHandleCmd23, + [CONTROLLER_23] = BtlController_Empty, [CONTROLLER_HEALTHBARUPDATE] = PlayerPartnerHandleHealthBarUpdate, - [CONTROLLER_EXPUPDATE] = PlayerPartnerHandleExpUpdate, - [CONTROLLER_STATUSICONUPDATE] = PlayerPartnerHandleStatusIconUpdate, - [CONTROLLER_STATUSANIMATION] = PlayerPartnerHandleStatusAnimation, - [CONTROLLER_STATUSXOR] = PlayerPartnerHandleStatusXor, - [CONTROLLER_DATATRANSFER] = PlayerPartnerHandleDataTransfer, - [CONTROLLER_DMA3TRANSFER] = PlayerPartnerHandleDMA3Transfer, - [CONTROLLER_PLAYBGM] = PlayerPartnerHandlePlayBGM, - [CONTROLLER_32] = PlayerPartnerHandleCmd32, - [CONTROLLER_TWORETURNVALUES] = PlayerPartnerHandleTwoReturnValues, - [CONTROLLER_CHOSENMONRETURNVALUE] = PlayerPartnerHandleChosenMonReturnValue, - [CONTROLLER_ONERETURNVALUE] = PlayerPartnerHandleOneReturnValue, - [CONTROLLER_ONERETURNVALUE_DUPLICATE] = PlayerPartnerHandleOneReturnValue_Duplicate, - [CONTROLLER_CLEARUNKVAR] = PlayerPartnerHandleClearUnkVar, - [CONTROLLER_SETUNKVAR] = PlayerPartnerHandleSetUnkVar, - [CONTROLLER_CLEARUNKFLAG] = PlayerPartnerHandleClearUnkFlag, - [CONTROLLER_TOGGLEUNKFLAG] = PlayerPartnerHandleToggleUnkFlag, - [CONTROLLER_HITANIMATION] = PlayerPartnerHandleHitAnimation, - [CONTROLLER_CANTSWITCH] = PlayerPartnerHandleCantSwitch, - [CONTROLLER_PLAYSE] = PlayerPartnerHandlePlaySE, - [CONTROLLER_PLAYFANFAREORBGM] = PlayerPartnerHandlePlayFanfareOrBGM, - [CONTROLLER_FAINTINGCRY] = PlayerPartnerHandleFaintingCry, - [CONTROLLER_INTROSLIDE] = PlayerPartnerHandleIntroSlide, + [CONTROLLER_EXPUPDATE] = PlayerHandleExpUpdate, // Partner's player gets experience the same way as the player. + [CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate, + [CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation, + [CONTROLLER_STATUSXOR] = BtlController_Empty, + [CONTROLLER_DATATRANSFER] = BtlController_Empty, + [CONTROLLER_DMA3TRANSFER] = BtlController_Empty, + [CONTROLLER_PLAYBGM] = BtlController_Empty, + [CONTROLLER_32] = BtlController_Empty, + [CONTROLLER_TWORETURNVALUES] = BtlController_Empty, + [CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, + [CONTROLLER_CLEARUNKVAR] = BtlController_HandleClearUnkVar, + [CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar, + [CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag, + [CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag, + [CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, + [CONTROLLER_CANTSWITCH] = BtlController_Empty, + [CONTROLLER_PLAYSE] = BtlController_HandlePlaySE, + [CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, + [CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry, + [CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, [CONTROLLER_INTROTRAINERBALLTHROW] = PlayerPartnerHandleIntroTrainerBallThrow, [CONTROLLER_DRAWPARTYSTATUSSUMMARY] = PlayerPartnerHandleDrawPartyStatusSummary, - [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = PlayerPartnerHandleHidePartyStatusSummary, - [CONTROLLER_ENDBOUNCE] = PlayerPartnerHandleEndBounceEffect, - [CONTROLLER_SPRITEINVISIBILITY] = PlayerPartnerHandleSpriteInvisibility, + [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary, + [CONTROLLER_ENDBOUNCE] = BtlController_Empty, + [CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility, [CONTROLLER_BATTLEANIMATION] = PlayerPartnerHandleBattleAnimation, - [CONTROLLER_LINKSTANDBYMSG] = PlayerPartnerHandleLinkStandbyMsg, - [CONTROLLER_RESETACTIONMOVESELECTION] = PlayerPartnerHandleResetActionMoveSelection, + [CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty, + [CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, [CONTROLLER_ENDLINKBATTLE] = PlayerPartnerHandleEndLinkBattle, - [CONTROLLER_DEBUGMENU] = PlayerPartnerHandleBattleDebug, - [CONTROLLER_TERMINATOR_NOP] = PlayerPartnerCmdEnd + [CONTROLLER_DEBUGMENU] = BtlController_Empty, + [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop }; -// unknown unused data -static const u8 sUnused[] = -{ - 0x83, 0x4d, 0xf3, 0x5f, 0x6f, 0x4f, 0xeb, 0x3e, - 0x67, 0x2e, 0x10, 0x46, 0x8c, 0x3d, 0x28, 0x35, - 0xc5, 0x2c, 0x15, 0x7f, 0xb5, 0x56, 0x9d, 0x53, - 0x3b, 0x43, 0xda, 0x36, 0x79, 0x2a, 0x0e, 0x53, -}; - -static void PlayerPartnerDummy(void) +void SetControllerToPlayerPartner(u32 battler) { + gBattlerControllerEndFuncs[battler] = PlayerPartnerBufferExecCompleted; + gBattlerControllerFuncs[battler] = PlayerPartnerBufferRunCommand; } -void SetControllerToPlayerPartner(void) +static void PlayerPartnerBufferRunCommand(u32 battler) { - gBattlerControllerFuncs[gActiveBattler] = PlayerPartnerBufferRunCommand; -} - -static void PlayerPartnerBufferRunCommand(void) -{ - if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) + if (gBattleControllerExecFlags & gBitTable[battler]) { - if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sPlayerPartnerBufferCommands)) - sPlayerPartnerBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); + if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sPlayerPartnerBufferCommands)) + sPlayerPartnerBufferCommands[gBattleResources->bufferA[battler][0]](battler); else - PlayerPartnerBufferExecCompleted(); + PlayerPartnerBufferExecCompleted(battler); } } -static void CompleteOnBattlerSpriteCallbackDummy(void) +static void Intro_DelayAndEnd(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - PlayerPartnerBufferExecCompleted(); -} - -static void FreeTrainerSpriteAfterSlide(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (--gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay == (u8)-1) { - BattleGfxSfxDummy3(MALE); - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - PlayerPartnerBufferExecCompleted(); + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0; + BattleControllerComplete(battler); } } -static void Intro_DelayAndEnd(void) -{ - if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == (u8)-1) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; - PlayerPartnerBufferExecCompleted(); - } -} - -static void Intro_WaitForHealthbox(void) +static void Intro_WaitForHealthbox(u32 battler) { bool32 finished = FALSE; if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) finished = TRUE; } else { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy) { finished = TRUE; } @@ -246,1061 +161,137 @@ static void Intro_WaitForHealthbox(void) if (finished) { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; - gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3; + gBattlerControllerFuncs[battler] = Intro_DelayAndEnd; } } -static void Intro_ShowHealthbox(void) +// Also used by the link partner. +void Controller_PlayerPartnerShowIntroHealthbox(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive - && gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && ++gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay != 1) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive + && gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy + && ++gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay != 1) { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0; if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { - DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); - UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); - StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); + DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL); + StartHealthboxSlideIn(BATTLE_PARTNER(battler)); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]); } - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + DestroySprite(&gSprites[gBattleControllerData[battler]]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); 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) - PlayerPartnerBufferExecCompleted(); + if (gSprites[gBattlerSpriteIds[battler]].animEnded && gSprites[gBattlerSpriteIds[battler]].x2 == 0) + PlayerPartnerBufferExecCompleted(battler); } -static void CompleteOnHealthbarDone(void) +static void SwitchIn_ShowSubstitute(u32 battler) { - s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0); - - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - - if (hpValue != -1) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); - } - else - { - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - PlayerPartnerBufferExecCompleted(); + CopyBattleSpriteInvisibility(battler); + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE); + + gBattlerControllerFuncs[battler] = SwitchIn_WaitAndEnd; } } -static void CompleteOnInactiveTextPrinter(void) +static void SwitchIn_WaitAndEnd(u32 battler) { - if (!IsTextPrinterActive(B_WIN_MSG)) - PlayerPartnerBufferExecCompleted(); -} - -// the whole exp task is copied&pasted from player controller -#define tExpTask_monId data[0] -#define tExpTask_gainedExp data[1] -#define tExpTask_bank data[2] -#define tExpTask_frames data[10] - -static void Task_GiveExpToMon(u8 taskId) -{ - u32 monId = (u8)(gTasks[taskId].tExpTask_monId); - u8 battlerId = gTasks[taskId].tExpTask_bank; - s16 gainedExp = gTasks[taskId].tExpTask_gainedExp; - - if (IsDoubleBattle() == TRUE || monId != gBattlerPartyIndexes[battlerId]) // give exp without the expbar + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) { - struct Pokemon *mon = &gPlayerParty[monId]; - u16 species = GetMonData(mon, MON_DATA_SPECIES); - u8 level = GetMonData(mon, MON_DATA_LEVEL); - u32 currExp = GetMonData(mon, MON_DATA_EXP); - u32 nextLvlExp = gExperienceTables[gSpeciesInfo[species].growthRate][level + 1]; - - if (currExp + gainedExp >= nextLvlExp) - { - u8 savedActiveBank; - - SetMonData(mon, MON_DATA_EXP, &nextLvlExp); - CalculateMonStats(mon); - gainedExp -= nextLvlExp - currExp; - savedActiveBank = gActiveBattler; - gActiveBattler = battlerId; - BtlController_EmitTwoReturnValues(BUFFER_B, RET_VALUE_LEVELED_UP, gainedExp); - gActiveBattler = savedActiveBank; - - if (IsDoubleBattle() == TRUE - && ((u16)(monId) == gBattlerPartyIndexes[battlerId] || (u16)(monId) == gBattlerPartyIndexes[BATTLE_PARTNER(battlerId)])) - gTasks[taskId].func = Task_LaunchLvlUpAnim; - else - gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter; - } - else - { - currExp += gainedExp; - SetMonData(mon, MON_DATA_EXP, &currExp); - gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter; - DestroyTask(taskId); - } - } - else - { - gTasks[taskId].func = Task_PrepareToGiveExpWithExpBar; + PlayerPartnerBufferExecCompleted(battler); } } -static void Task_PrepareToGiveExpWithExpBar(u8 taskId) +static void SwitchIn_ShowHealthbox(u32 battler) { - u8 monIndex = gTasks[taskId].tExpTask_monId; - s32 gainedExp = gTasks[taskId].tExpTask_gainedExp; - u8 battlerId = gTasks[taskId].tExpTask_bank; - struct Pokemon *mon = &gPlayerParty[monIndex]; - u8 level = GetMonData(mon, MON_DATA_LEVEL); - u16 species = GetMonData(mon, MON_DATA_SPECIES); - u32 exp = GetMonData(mon, MON_DATA_EXP); - u32 currLvlExp = gExperienceTables[gSpeciesInfo[species].growthRate][level]; - u32 expToNextLvl; - - exp -= currLvlExp; - expToNextLvl = gExperienceTables[gSpeciesInfo[species].growthRate][level + 1] - currLvlExp; - SetBattleBarStruct(battlerId, gHealthboxSpriteIds[battlerId], expToNextLvl, exp, -gainedExp); - PlaySE(SE_EXP); - gTasks[taskId].func = Task_GiveExpWithExpBar; -} - -static void Task_GiveExpWithExpBar(u8 taskId) -{ - if (gTasks[taskId].tExpTask_frames < 13) + if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim) { - gTasks[taskId].tExpTask_frames++; - } - else - { - u8 monId = gTasks[taskId].tExpTask_monId; - s16 gainedExp = gTasks[taskId].tExpTask_gainedExp; - u8 battlerId = gTasks[taskId].tExpTask_bank; - s16 r4; - - r4 = MoveBattleBar(battlerId, gHealthboxSpriteIds[battlerId], EXP_BAR, 0); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[battlerId]); - if (r4 == -1) - { - u8 level; - s32 currExp; - u16 species; - s32 expOnNextLvl; - - m4aSongNumStop(SE_EXP); - level = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); - currExp = GetMonData(&gPlayerParty[monId], MON_DATA_EXP); - species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); - expOnNextLvl = gExperienceTables[gSpeciesInfo[species].growthRate][level + 1]; - - if (currExp + gainedExp >= expOnNextLvl) - { - u8 savedActiveBank; - - SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &expOnNextLvl); - CalculateMonStats(&gPlayerParty[monId]); - gainedExp -= expOnNextLvl - currExp; - savedActiveBank = gActiveBattler; - gActiveBattler = battlerId; - BtlController_EmitTwoReturnValues(BUFFER_B, RET_VALUE_LEVELED_UP, gainedExp); - gActiveBattler = savedActiveBank; - gTasks[taskId].func = Task_LaunchLvlUpAnim; - } - else - { - currExp += gainedExp; - SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &currExp); - gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter; - DestroyTask(taskId); - } - } - } -} - -static void Task_LaunchLvlUpAnim(u8 taskId) -{ - u8 battlerId = gTasks[taskId].tExpTask_bank; - u8 monIndex = gTasks[taskId].tExpTask_monId; - - if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[BATTLE_PARTNER(battlerId)]) - battlerId ^= BIT_FLANK; - - InitAndLaunchSpecialAnimation(battlerId, battlerId, battlerId, B_ANIM_LVL_UP); - gTasks[taskId].func = Task_UpdateLvlInHealthbox; -} - -static void Task_UpdateLvlInHealthbox(u8 taskId) -{ - u8 battlerId = gTasks[taskId].tExpTask_bank; - - if (!gBattleSpritesDataPtr->healthBoxesData[battlerId].specialAnimActive) - { - u8 monIndex = gTasks[taskId].tExpTask_monId; - - GetMonData(&gPlayerParty[monIndex], MON_DATA_LEVEL); // Unused return value - - if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[BATTLE_PARTNER(battlerId)]) - UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battlerId)], &gPlayerParty[monIndex], HEALTHBOX_ALL); - else - UpdateHealthboxAttribute(gHealthboxSpriteIds[battlerId], &gPlayerParty[monIndex], HEALTHBOX_ALL); - - gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter; - } -} - -static void DestroyExpTaskAndCompleteOnInactiveTextPrinter(u8 taskId) -{ - u8 monIndex; - u8 battlerId; - - monIndex = gTasks[taskId].tExpTask_monId; - GetMonData(&gPlayerParty[monIndex], MON_DATA_LEVEL); // Unused return value - battlerId = gTasks[taskId].tExpTask_bank; - gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter; - DestroyTask(taskId); -} - -static void FreeMonSpriteAfterFaintAnim(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].y + gSprites[gBattlerSpriteIds[gActiveBattler]].y2 > DISPLAY_HEIGHT) - { - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - BattleGfxSfxDummy2(species); - FreeOamMatrix(gSprites[gBattlerSpriteIds[gActiveBattler]].oam.matrixNum); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - PlayerPartnerBufferExecCompleted(); - } -} - -static void FreeMonSpriteAfterSwitchOutAnim(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - PlayerPartnerBufferExecCompleted(); - } -} - -static void CompleteOnInactiveTextPrinter2(void) -{ - if (!IsTextPrinterActive(B_WIN_MSG)) - PlayerPartnerBufferExecCompleted(); -} - -static void DoHitAnimBlinkSpriteEffect(void) -{ - u8 spriteId = gBattlerSpriteIds[gActiveBattler]; - - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = FALSE; - PlayerPartnerBufferExecCompleted(); - } - else - { - if ((gSprites[spriteId].data[1] % 4) == 0) - gSprites[spriteId].invisible ^= 1; - gSprites[spriteId].data[1]++; - } -} - -static void SwitchIn_ShowSubstitute(void) -{ - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - CopyBattleSpriteInvisibility(gActiveBattler); - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_WaitAndEnd; - } -} - -static void SwitchIn_WaitAndEnd(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - PlayerPartnerBufferExecCompleted(); - } -} - -static void SwitchIn_ShowHealthbox(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); CreateTask(Task_PlayerController_RestoreBgmAfterCry, 10); - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); + StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 0); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + 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 - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) { - TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]); } - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) { - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowHealthbox; + DestroySprite(&gSprites[gBattleControllerData[battler]]); + gBattlerControllerFuncs[battler] = SwitchIn_ShowHealthbox; } } -static void PlayerPartnerBufferExecCompleted(void) +static void PlayerPartnerBufferExecCompleted(u32 battler) { - gBattlerControllerFuncs[gActiveBattler] = PlayerPartnerBufferRunCommand; + gBattlerControllerFuncs[battler] = PlayerPartnerBufferRunCommand; if (gBattleTypeFlags & BATTLE_TYPE_LINK) { u8 playerId = GetMultiplayerId(); PrepareBufferDataTransferLink(2, 4, &playerId); - gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; + gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP; } else { - gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; + gBattleControllerExecFlags &= ~gBitTable[battler]; } } -static void CompleteOnFinishedStatusAnimation(void) +static void PlayerPartnerHandleLoadMonSprite(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive) - PlayerPartnerBufferExecCompleted(); + BtlController_HandleLoadMonSprite(battler, WaitForMonAnimAfterLoad); } -static void CompleteOnFinishedBattleAnimation(void) +static void PlayerPartnerHandleSwitchInAnim(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive) - PlayerPartnerBufferExecCompleted(); + BtlController_HandleSwitchInAnim(battler, TRUE, SwitchIn_TryShinyAnim); } -static void PlayerPartnerHandleGetMonData(void) -{ - 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 size = 0; - u8 monToCheck; - s32 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - size += CopyPlayerPartnerMonData(gBattlerPartyIndexes[gActiveBattler], monData); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - size += CopyPlayerPartnerMonData(i, monData + size); - monToCheck >>= 1; - } - } - BtlController_EmitDataTransfer(BUFFER_B, size, monData); - PlayerPartnerBufferExecCompleted(); -} - -static u32 CopyPlayerPartnerMonData(u8 monId, u8 *dst) -{ - struct BattlePokemon battleMon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - battleMon.species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); - battleMon.item = GetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM); - for (size = 0; size < MAX_MON_MOVES; size++) - { - battleMon.moves[size] = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + size); - battleMon.pp[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - } - battleMon.ppBonuses = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - battleMon.friendship = GetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP); - battleMon.experience = GetMonData(&gPlayerParty[monId], MON_DATA_EXP); - battleMon.hpIV = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - battleMon.attackIV = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - battleMon.defenseIV = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - battleMon.speedIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - battleMon.spAttackIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - battleMon.spDefenseIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - battleMon.personality = GetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY); - battleMon.status1 = GetMonData(&gPlayerParty[monId], MON_DATA_STATUS); - battleMon.level = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); - battleMon.hp = GetMonData(&gPlayerParty[monId], MON_DATA_HP); - battleMon.maxHP = GetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP); - battleMon.attack = GetMonData(&gPlayerParty[monId], MON_DATA_ATK); - battleMon.defense = GetMonData(&gPlayerParty[monId], MON_DATA_DEF); - battleMon.speed = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED); - battleMon.spAttack = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK); - battleMon.spDefense = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF); - battleMon.abilityNum = GetMonData(&gPlayerParty[monId], MON_DATA_ABILITY_NUM); - battleMon.otId = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID); - battleMon.metLevel = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL); - GetMonData(&gPlayerParty[monId], MON_DATA_NICKNAME, nickname); - StringCopy_Nickname(battleMon.nickname, nickname); - GetMonData(&gPlayerParty[monId], MON_DATA_OT_NAME, battleMon.otName); - src = (u8 *)&battleMon; - for (size = 0; size < sizeof(battleMon); size++) - dst[size] = src[size]; - break; - case REQUEST_SPECIES_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_HELDITEM_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MOVES_PP_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - { - moveData.moves[size] = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - src = (u8 *)(&moveData); - for (size = 0; size < sizeof(moveData); size++) - dst[size] = src[size]; - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_PP_DATA_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - dst[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - dst[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - size++; - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE); - size = 1; - break; - case REQUEST_OTID_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_EXP_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_EXP); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_HP_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_EV); - size = 1; - break; - case REQUEST_ATK_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_EV); - size = 1; - break; - case REQUEST_DEF_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_EV); - size = 1; - break; - case REQUEST_SPEED_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_EV); - size = 1; - break; - case REQUEST_SPATK_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_EV); - size = 1; - break; - case REQUEST_SPDEF_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_EV); - size = 1; - break; - case REQUEST_FRIENDSHIP_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP); - size = 1; - break; - case REQUEST_POKERUS_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_POKERUS); - size = 1; - break; - case REQUEST_MET_LOCATION_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LOCATION); - size = 1; - break; - case REQUEST_MET_LEVEL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL); - size = 1; - break; - case REQUEST_MET_GAME_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_GAME); - size = 1; - break; - case REQUEST_POKEBALL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_POKEBALL); - size = 1; - break; - case REQUEST_ALL_IVS_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - dst[1] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - dst[2] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - dst[3] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - dst[4] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - dst[5] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - size = 6; - break; - case REQUEST_HP_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - size = 1; - break; - case REQUEST_ATK_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - size = 1; - break; - case REQUEST_DEF_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - size = 1; - break; - case REQUEST_SPEED_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - size = 1; - break; - case REQUEST_SPATK_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - size = 1; - break; - case REQUEST_SPDEF_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - size = 1; - break; - case REQUEST_PERSONALITY_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_CHECKSUM_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_CHECKSUM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_STATUS_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_STATUS); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_LEVEL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); - size = 1; - break; - case REQUEST_HP_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MAX_HP_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_ATK_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_ATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_DEF_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_DEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPEED_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPATK_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPDEF_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_COOL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_COOL); - size = 1; - break; - case REQUEST_BEAUTY_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY); - size = 1; - break; - case REQUEST_CUTE_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_CUTE); - size = 1; - break; - case REQUEST_SMART_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SMART); - size = 1; - break; - case REQUEST_TOUGH_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_TOUGH); - size = 1; - break; - case REQUEST_SHEEN_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SHEEN); - size = 1; - break; - case REQUEST_COOL_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_COOL_RIBBON); - size = 1; - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case REQUEST_CUTE_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case REQUEST_SMART_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SMART_RIBBON); - size = 1; - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - - return size; -} - -static void PlayerPartnerHandleGetRawMonData(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleSetMonData(void) -{ - u8 monToCheck; - u8 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - SetPlayerPartnerMonData(gBattlerPartyIndexes[gActiveBattler]); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - SetPlayerPartnerMonData(i); - monToCheck >>= 1; - } - } - PlayerPartnerBufferExecCompleted(); -} - -static void SetPlayerPartnerMonData(u8 monId) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleResources->bufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleResources->bufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - { - u8 iv; - - SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gPlayerParty[monId], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gPlayerParty[monId], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gPlayerParty[monId], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gPlayerParty[monId], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gPlayerParty[monId], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case REQUEST_SPECIES_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HELDITEM_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MOVES_PP_BATTLE: - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PP_DATA_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PP1, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP2, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP3, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP4, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &gBattleResources->bufferA[gActiveBattler][7]); - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_OTID_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_OT_ID, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_EXP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_FRIENDSHIP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKERUS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_POKERUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LOCATION_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_LOCATION, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LEVEL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_GAME_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_GAME, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKEBALL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_POKEBALL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ALL_IVS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][7]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][8]); - break; - case REQUEST_HP_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PERSONALITY_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CHECKSUM_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CHECKSUM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_STATUS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_STATUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_LEVEL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MAX_HP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_COOL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CUTE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SMART, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_TOUGH, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SHEEN_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SHEEN, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_COOL_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CUTE_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SMART_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_TOUGH_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - } - - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); -} - -static void PlayerPartnerHandleSetRawMonData(void) -{ - u8 *dst = (u8 *)&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleResources->bufferA[gActiveBattler][1]; - u8 i; - - for (i = 0; i < gBattleResources->bufferA[gActiveBattler][2]; i++) - dst[i] = gBattleResources->bufferA[gActiveBattler][3 + i]; - - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleLoadMonSprite(void) -{ - u16 species; - - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(gActiveBattler)); - - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(gActiveBattler, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(gActiveBattler), - GetBattlerSpriteSubpriority(gActiveBattler)); - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); - gBattlerControllerFuncs[gActiveBattler] = WaitForMonAnimAfterLoad; -} - -static void PlayerPartnerHandleSwitchInAnim(void) -{ - ClearTemporarySpeciesSpriteData(gActiveBattler, gBattleResources->bufferA[gActiveBattler][2]); - gBattlerPartyIndexes[gActiveBattler] = gBattleResources->bufferA[gActiveBattler][1]; - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - StartSendOutAnim(gActiveBattler, gBattleResources->bufferA[gActiveBattler][2]); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_TryShinyAnim; -} - -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit) -{ - u16 species; - - ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit); - gBattlerPartyIndexes[battlerId] = gBattleResources->bufferA[battlerId][1]; - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); - gBattleControllerData[battlerId] = CreateInvisibleSpriteWithCallback(SpriteCB_WaitForBattlerBallReleaseAnim); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battlerId)); - - gBattlerSpriteIds[battlerId] = CreateSprite( - &gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(battlerId), - GetBattlerSpriteSubpriority(battlerId)); - - gSprites[gBattleControllerData[battlerId]].data[1] = gBattlerSpriteIds[battlerId]; - gSprites[gBattleControllerData[battlerId]].data[2] = battlerId; - - gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId; - gSprites[gBattlerSpriteIds[battlerId]].data[2] = species; - gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId; - - StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], 0); - - gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE; - gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy; - - gSprites[gBattleControllerData[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT); -} - -static void PlayerPartnerHandleReturnMonToBall(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] == 0) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = DoSwitchOutAnimation; - } - else - { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - PlayerPartnerBufferExecCompleted(); - } -} - -static void DoSwitchOutAnimation(void) -{ - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SWITCH_OUT_PLAYER_MON); - gBattlerControllerFuncs[gActiveBattler] = FreeMonSpriteAfterSwitchOutAnim; - } - break; - } -} - -#define sSpeedX data[0] - // some explanation here // 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 -static void PlayerPartnerHandleDrawTrainerPic(void) +static void PlayerPartnerHandleDrawTrainerPic(u32 battler) { + bool32 isFrontPic; s16 xPos, yPos; u32 trainerPicId; @@ -1323,209 +314,46 @@ static void PlayerPartnerHandleDrawTrainerPic(void) yPos = (8 - gTrainerFrontPicCoords[trainerPicId].size) * 4 + 80; } - // Use back pic only if the partner is Steven + // Use back pic only if the partner is Steven or a custom partner. if (gPartnerTrainerId == TRAINER_STEVEN_PARTNER || gPartnerTrainerId >= TRAINER_CUSTOM_PARTNER) - { - DecompressTrainerBackPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, xPos, yPos, GetBattlerSpriteSubpriority(gActiveBattler)); - - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = -2; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - } - else // otherwise use front sprite - { - DecompressTrainerFrontPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerFront(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, xPos, yPos, GetBattlerSpriteSubpriority(gActiveBattler)); - - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].y2 = 48; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = -2; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineMode = ST_OAM_AFFINE_OFF; - gSprites[gBattlerSpriteIds[gActiveBattler]].hFlip = 1; - } - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy; -} - -#undef sSpeedX - -static void PlayerPartnerHandleTrainerSlide(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleTrainerSlideBack(void) -{ - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCallbackDummy); - gBattlerControllerFuncs[gActiveBattler] = FreeTrainerSpriteAfterSlide; -} - -#define sSpeedX data[1] -#define sSpeedY data[2] - -static void PlayerPartnerHandleFaintAnimation(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState == 0) - { - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState++; - } + isFrontPic = FALSE; else - { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - PlaySE12WithPanning(SE_FAINT, SOUND_PAN_ATTACKER); - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = 0; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedY = 5; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_FaintSlideAnim; - gBattlerControllerFuncs[gActiveBattler] = FreeMonSpriteAfterFaintAnim; - } - } + isFrontPic = TRUE; + + BtlController_HandleDrawTrainerPic(battler, trainerPicId, isFrontPic, xPos, yPos, -1); } -#undef sSpeedX -#undef sSpeedY - -static void PlayerPartnerHandlePaletteFade(void) +static void PlayerPartnerHandleTrainerSlideBack(u32 battler) { - PlayerPartnerBufferExecCompleted(); + BtlController_HandleTrainerSlideBack(battler, 35, FALSE); } -static void PlayerPartnerHandleSuccessBallThrowAnim(void) +static void PlayerPartnerHandleMoveAnimation(u32 battler) { - PlayerPartnerBufferExecCompleted(); + BtlController_HandleMoveAnimation(battler, FALSE); } -static void PlayerPartnerHandleBallThrowAnim(void) +static void PlayerPartnerHandlePrintString(u32 battler) { - PlayerPartnerBufferExecCompleted(); + BtlController_HandlePrintString(battler, FALSE, FALSE); } -static void PlayerPartnerHandlePause(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleMoveAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleResources->bufferA[gActiveBattler][3]; - gAnimMovePower = gBattleResources->bufferA[gActiveBattler][4] | (gBattleResources->bufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleResources->bufferA[gActiveBattler][6] | (gBattleResources->bufferA[gActiveBattler][7] << 8) | (gBattleResources->bufferA[gActiveBattler][8] << 16) | (gBattleResources->bufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleResources->bufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleResources->bufferA[gActiveBattler][12] | (gBattleResources->bufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - gTransformedOtIds[gActiveBattler] = gAnimDisableStructPtr->transformedMonOtId; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = PlayerPartnerDoMoveAnimation; - } -} - -static void PlayerPartnerDoMoveAnimation(void) -{ - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - u8 multihit = gBattleResources->bufferA[gActiveBattler][11]; - - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute - && !gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8) - { - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 1; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF); - DoMoveAnim(move); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL); - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute && multihit < 2) - { - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 0; - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 3; - } - break; - case 3: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - CopyAllBattleSpritesInvisibilities(); - TrySetBehindSubstituteSpriteBit(gActiveBattler, gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - PlayerPartnerBufferExecCompleted(); - } - break; - } -} - -static void PlayerPartnerHandlePrintString(void) -{ - u16 *stringId; - - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - stringId = (u16 *)(&gBattleResources->bufferA[gActiveBattler][2]); - BufferStringBattle(*stringId); - BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter2; -} - -static void PlayerPartnerHandlePrintSelectionString(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleChooseAction(void) +static void PlayerPartnerHandleChooseAction(u32 battler) { AI_TrySwitchOrUseItem(); - PlayerPartnerBufferExecCompleted(); + PlayerPartnerBufferExecCompleted(battler); } -static void PlayerPartnerHandleYesNoBox(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleChooseMove(void) +static void PlayerPartnerHandleChooseMove(u32 battler) { u8 chosenMoveId; - struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); + struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); - chosenMoveId = gBattleStruct->aiMoveOrAction[gActiveBattler]; - gBattlerTarget = gBattleStruct->aiChosenTarget[gActiveBattler]; + chosenMoveId = gBattleStruct->aiMoveOrAction[battler]; + gBattlerTarget = gBattleStruct->aiChosenTarget[battler]; 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) { gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); @@ -1533,30 +361,25 @@ static void PlayerPartnerHandleChooseMove(void) gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); } - if (ShouldUseZMove(gActiveBattler, gBattlerTarget, moveInfo->moves[chosenMoveId])) - QueueZMove(gActiveBattler, moveInfo->moves[chosenMoveId]); + if (ShouldUseZMove(battler, gBattlerTarget, moveInfo->moves[chosenMoveId])) + QueueZMove(battler, moveInfo->moves[chosenMoveId]); // If partner can mega evolve, do it. - if (CanMegaEvolve(gActiveBattler)) + if (CanMegaEvolve(battler)) BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8)); else BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (gBattlerTarget << 8)); - PlayerPartnerBufferExecCompleted(); + PlayerPartnerBufferExecCompleted(battler); } -static void PlayerPartnerHandleChooseItem(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleChoosePokemon(void) +static void PlayerPartnerHandleChoosePokemon(u32 battler) { s32 chosenMonId; // 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 else @@ -1577,391 +400,46 @@ static void PlayerPartnerHandleChoosePokemon(void) } } } - *(gBattleStruct->monToSwitchIntoId + gActiveBattler) = chosenMonId; + *(gBattleStruct->monToSwitchIntoId + battler) = chosenMonId; } BtlController_EmitChosenMonReturnValue(BUFFER_B, chosenMonId, NULL); - PlayerPartnerBufferExecCompleted(); + PlayerPartnerBufferExecCompleted(battler); } -static void PlayerPartnerHandleCmd23(void) +static void PlayerPartnerHandleHealthBarUpdate(u32 battler) { - PlayerPartnerBufferExecCompleted(); + BtlController_HandleHealthBarUpdate(battler, FALSE); } -static void PlayerPartnerHandleHealthBarUpdate(void) +static void PlayerPartnerHandleIntroTrainerBallThrow(u32 battler) { - s16 hpVal; + const u32 *trainerPal; - LoadBattleBarGfx(0); - hpVal = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (hpVal != INSTANT_HP_BAR_DROP) - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - u32 curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); - - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, curHP, hpVal); - } - else - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); - } - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone; -} - -static void PlayerPartnerHandleExpUpdate(void) -{ - u8 monId = gBattleResources->bufferA[gActiveBattler][1]; - - if (GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL) >= MAX_LEVEL) - { - PlayerPartnerBufferExecCompleted(); - } - else - { - s16 expPointsToGive; - u8 taskId; - - LoadBattleBarGfx(1); - GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); // unused return value - expPointsToGive = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - taskId = CreateTask(Task_GiveExpToMon, 10); - gTasks[taskId].tExpTask_monId = monId; - gTasks[taskId].tExpTask_gainedExp = expPointsToGive; - gTasks[taskId].tExpTask_bank = gActiveBattler; - gBattlerControllerFuncs[gActiveBattler] = BattleControllerDummy; - } -} - -#undef tExpTask_monId -#undef tExpTask_gainedExp -#undef tExpTask_bank -#undef tExpTask_frames - -static void PlayerPartnerHandleStatusIconUpdate(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u8 battlerId; - - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON); - battlerId = gActiveBattler; - gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0; - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - } -} - -static void PlayerPartnerHandleStatusAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - InitAndLaunchChosenStatusAnimation(gBattleResources->bufferA[gActiveBattler][1], - gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8) | (gBattleResources->bufferA[gActiveBattler][4] << 16) | (gBattleResources->bufferA[gActiveBattler][5] << 24)); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - } -} - -static void PlayerPartnerHandleStatusXor(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleDataTransfer(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleDMA3Transfer(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandlePlayBGM(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleCmd32(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleTwoReturnValues(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleChosenMonReturnValue(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleOneReturnValue(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleOneReturnValue_Duplicate(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleClearUnkVar(void) -{ - gUnusedControllerStruct.unk = 0; - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleSetUnkVar(void) -{ - gUnusedControllerStruct.unk = gBattleResources->bufferA[gActiveBattler][1]; - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleClearUnkFlag(void) -{ - gUnusedControllerStruct.flag = 0; - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleToggleUnkFlag(void) -{ - gUnusedControllerStruct.flag ^= 1; - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleHitAnimation(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].invisible == TRUE) - { - PlayerPartnerBufferExecCompleted(); - } - else - { - gDoingBattleAnim = TRUE; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[1] = 0; - DoHitAnimHealthboxEffect(gActiveBattler); - gBattlerControllerFuncs[gActiveBattler] = DoHitAnimBlinkSpriteEffect; - } -} - -static void PlayerPartnerHandleCantSwitch(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandlePlaySE(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - pan = SOUND_PAN_ATTACKER; - else - pan = SOUND_PAN_TARGET; - - PlaySE12WithPanning(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8), pan); - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandlePlayFanfareOrBGM(void) -{ - if (gBattleResources->bufferA[gActiveBattler][3]) - { - BattleStopLowHpSound(); - PlayBGM(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - else - { - PlayFanfare(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleFaintingCry(void) -{ - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - PlayCry_ByMode(species, -25, CRY_MODE_FAINT); - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleIntroSlide(void) -{ - HandleIntroSlide(gBattleResources->bufferA[gActiveBattler][1]); - gIntroSlideFlags |= 1; - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleIntroTrainerBallThrow(void) -{ - u8 paletteNum; - u8 taskId; - - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 50; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[5] = gActiveBattler; - - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCB_FreePlayerSpriteLoadMonSprite); - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 1); - - paletteNum = AllocSpritePalette(0xD6F9); if (gPartnerTrainerId == TRAINER_STEVEN_PARTNER) - { - u8 spriteId = TRAINER_BACK_PIC_STEVEN; - LoadCompressedPalette(gTrainerBackPicPaletteTable[spriteId].data, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP); - } - else if (gPartnerTrainerId >= TRAINER_CUSTOM_PARTNER) - { - u8 spriteId = gPartnerSpriteId; - LoadCompressedPalette(gTrainerBackPicPaletteTable[spriteId].data, 0x100 + paletteNum * 16, 32); - } + trainerPal = gTrainerBackPicPaletteTable[TRAINER_STEVEN_PARTNER].data; + else if (gPartnerTrainerId >= TRAINER_CUSTOM_PARTNER) // Custom multi battle. + trainerPal = gTrainerBackPicPaletteTable[gPartnerSpriteId].data; else - { - u8 spriteId = GetFrontierTrainerFrontSpriteId(gPartnerTrainerId); - LoadCompressedPalette(gTrainerFrontPicPaletteTable[spriteId].data, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP); - } + trainerPal = gTrainerFrontPicPaletteTable[GetFrontierTrainerFrontSpriteId(gPartnerTrainerId)].data; // 2 vs 2 multi battle in Battle Frontier, load front sprite and pal. - - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = paletteNum; - - taskId = CreateTask(Task_StartSendOutAnim, 5); - gTasks[taskId].data[0] = gActiveBattler; - - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - - gBattleSpritesDataPtr->animationData->introAnimActive = TRUE; - gBattlerControllerFuncs[gActiveBattler] = PlayerPartnerDummy; + BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F9, trainerPal, 24, Controller_PlayerPartnerShowIntroHealthbox); } -static void Task_StartSendOutAnim(u8 taskId) +static void PlayerPartnerHandleDrawPartyStatusSummary(u32 battler) { - if (gTasks[taskId].data[1] < 24) - { - gTasks[taskId].data[1]++; - } - else - { - u8 savedActiveBank = gActiveBattler; - - gActiveBattler = gTasks[taskId].data[0]; - if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - } - else - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler ^= BIT_FLANK; - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler ^= BIT_FLANK; - } - gBattlerControllerFuncs[gActiveBattler] = Intro_ShowHealthbox; - gActiveBattler = savedActiveBank; - DestroyTask(taskId); - } + BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, TRUE); } -static void PlayerPartnerHandleDrawPartyStatusSummary(void) +static void PlayerPartnerHandleBattleAnimation(u32 battler) { - if (gBattleResources->bufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - { - PlayerPartnerBufferExecCompleted(); - } - else - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown = 1; - gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleResources->bufferA[gActiveBattler][4], gBattleResources->bufferA[gActiveBattler][1], gBattleResources->bufferA[gActiveBattler][2]); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - - if (gBattleResources->bufferA[gActiveBattler][2] != 0) - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 93; - - gBattlerControllerFuncs[gActiveBattler] = EndDrawPartyStatusSummary; - } + BtlController_HandleBattleAnimation(battler, FALSE, FALSE); } -static void EndDrawPartyStatusSummary(void) +static void PlayerPartnerHandleEndLinkBattle(u32 battler) { - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer++ > 92) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - PlayerPartnerBufferExecCompleted(); - } -} - -static void PlayerPartnerHandleHidePartyStatusSummary(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleEndBounceEffect(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleSpriteInvisibility(void) -{ - if (IsBattlerSpritePresent(gActiveBattler)) - { - gSprites[gBattlerSpriteIds[gActiveBattler]].invisible = gBattleResources->bufferA[gActiveBattler][1]; - CopyBattleSpriteInvisibility(gActiveBattler); - } - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleBattleAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u8 animationId = gBattleResources->bufferA[gActiveBattler][1]; - u16 argument = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (TryHandleLaunchBattleTableAnimation(gActiveBattler, gActiveBattler, gActiveBattler, animationId, argument)) - PlayerPartnerBufferExecCompleted(); - else - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; - } -} - -static void PlayerPartnerHandleLinkStandbyMsg(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleResetActionMoveSelection(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerHandleEndLinkBattle(void) -{ - gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; + gBattleOutcome = gBattleResources->bufferA[battler][1]; FadeOutMapMusic(5); BeginFastPaletteFade(3); - PlayerPartnerBufferExecCompleted(); - gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; -} - -static void PlayerPartnerHandleBattleDebug(void) -{ - PlayerPartnerBufferExecCompleted(); -} - -static void PlayerPartnerCmdEnd(void) -{ + PlayerPartnerBufferExecCompleted(battler); + gBattlerControllerFuncs[battler] = SetBattleEndCallbacks; } diff --git a/src/battle_controller_recorded_opponent.c b/src/battle_controller_recorded_opponent.c index 283388fcf..478970888 100644 --- a/src/battle_controller_recorded_opponent.c +++ b/src/battle_controller_recorded_opponent.c @@ -32,273 +32,214 @@ #include "constants/songs.h" #include "constants/trainers.h" -static void RecordedOpponentHandleGetMonData(void); -static void RecordedOpponentHandleGetRawMonData(void); -static void RecordedOpponentHandleSetMonData(void); -static void RecordedOpponentHandleSetRawMonData(void); -static void RecordedOpponentHandleLoadMonSprite(void); -static void RecordedOpponentHandleSwitchInAnim(void); -static void RecordedOpponentHandleReturnMonToBall(void); -static void RecordedOpponentHandleDrawTrainerPic(void); -static void RecordedOpponentHandleTrainerSlide(void); -static void RecordedOpponentHandleTrainerSlideBack(void); -static void RecordedOpponentHandleFaintAnimation(void); -static void RecordedOpponentHandlePaletteFade(void); -static void RecordedOpponentHandleSuccessBallThrowAnim(void); -static void RecordedOpponentHandleBallThrowAnim(void); -static void RecordedOpponentHandlePause(void); -static void RecordedOpponentHandleMoveAnimation(void); -static void RecordedOpponentHandlePrintString(void); -static void RecordedOpponentHandlePrintSelectionString(void); -static void RecordedOpponentHandleChooseAction(void); -static void RecordedOpponentHandleYesNoBox(void); -static void RecordedOpponentHandleChooseMove(void); -static void RecordedOpponentHandleChooseItem(void); -static void RecordedOpponentHandleChoosePokemon(void); -static void RecordedOpponentHandleCmd23(void); -static void RecordedOpponentHandleHealthBarUpdate(void); -static void RecordedOpponentHandleExpUpdate(void); -static void RecordedOpponentHandleStatusIconUpdate(void); -static void RecordedOpponentHandleStatusAnimation(void); -static void RecordedOpponentHandleStatusXor(void); -static void RecordedOpponentHandleDataTransfer(void); -static void RecordedOpponentHandleDMA3Transfer(void); -static void RecordedOpponentHandlePlayBGM(void); -static void RecordedOpponentHandleCmd32(void); -static void RecordedOpponentHandleTwoReturnValues(void); -static void RecordedOpponentHandleChosenMonReturnValue(void); -static void RecordedOpponentHandleOneReturnValue(void); -static void RecordedOpponentHandleOneReturnValue_Duplicate(void); -static void RecordedOpponentHandleClearUnkVar(void); -static void RecordedOpponentHandleSetUnkVar(void); -static void RecordedOpponentHandleClearUnkFlag(void); -static void RecordedOpponentHandleToggleUnkFlag(void); -static void RecordedOpponentHandleHitAnimation(void); -static void RecordedOpponentHandleCantSwitch(void); -static void RecordedOpponentHandlePlaySE(void); -static void RecordedOpponentHandlePlayFanfareOrBGM(void); -static void RecordedOpponentHandleFaintingCry(void); -static void RecordedOpponentHandleIntroSlide(void); -static void RecordedOpponentHandleIntroTrainerBallThrow(void); -static void RecordedOpponentHandleDrawPartyStatusSummary(void); -static void RecordedOpponentHandleHidePartyStatusSummary(void); -static void RecordedOpponentHandleEndBounceEffect(void); -static void RecordedOpponentHandleSpriteInvisibility(void); -static void RecordedOpponentHandleBattleAnimation(void); -static void RecordedOpponentHandleLinkStandbyMsg(void); -static void RecordedOpponentHandleResetActionMoveSelection(void); -static void RecordedOpponentHandleEndLinkBattle(void); -static void RecordedOpponentHandleBattleDebug(void); -static void RecordedOpponentCmdEnd(void); +static void RecordedOpponentHandleLoadMonSprite(u32 battler); +static void RecordedOpponentHandleSwitchInAnim(u32 battler); +static void RecordedOpponentHandleDrawTrainerPic(u32 battler); +static void RecordedOpponentHandleTrainerSlideBack(u32 battler); +static void RecordedOpponentHandleMoveAnimation(u32 battler); +static void RecordedOpponentHandlePrintString(u32 battler); +static void RecordedOpponentHandleChooseAction(u32 battler); +static void RecordedOpponentHandleChooseMove(u32 battler); +static void RecordedOpponentHandleChooseItem(u32 battler); +static void RecordedOpponentHandleChoosePokemon(u32 battler); +static void RecordedOpponentHandleHealthBarUpdate(u32 battler); +static void RecordedOpponentHandleStatusIconUpdate(u32 battler); +static void RecordedOpponentHandleStatusAnimation(u32 battler); +static void RecordedOpponentHandleIntroTrainerBallThrow(u32 battler); +static void RecordedOpponentHandleDrawPartyStatusSummary(u32 battler); +static void RecordedOpponentHandleBattleAnimation(u32 battler); +static void RecordedOpponentHandleEndLinkBattle(u32 battler); -static void RecordedOpponentBufferRunCommand(void); -static void RecordedOpponentBufferExecCompleted(void); -static void SwitchIn_HandleSoundAndEnd(void); -static u32 CopyRecordedOpponentMonData(u8 monId, u8 *dst); -static void SetRecordedOpponentMonData(u8 monId); -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit); -static void DoSwitchOutAnimation(void); -static void RecordedOpponentDoMoveAnimation(void); -static void Task_StartSendOutAnim(u8 taskId); -static void SpriteCB_FreeOpponentSprite(struct Sprite *sprite); -static void EndDrawPartyStatusSummary(void); +static void RecordedOpponentBufferRunCommand(u32 battler); +static void RecordedOpponentBufferExecCompleted(u32 battler); +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] = RecordedOpponentHandleGetMonData, - [CONTROLLER_GETRAWMONDATA] = RecordedOpponentHandleGetRawMonData, - [CONTROLLER_SETMONDATA] = RecordedOpponentHandleSetMonData, - [CONTROLLER_SETRAWMONDATA] = RecordedOpponentHandleSetRawMonData, + [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, + [CONTROLLER_GETRAWMONDATA] = BtlController_Empty, + [CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, + [CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData, [CONTROLLER_LOADMONSPRITE] = RecordedOpponentHandleLoadMonSprite, [CONTROLLER_SWITCHINANIM] = RecordedOpponentHandleSwitchInAnim, - [CONTROLLER_RETURNMONTOBALL] = RecordedOpponentHandleReturnMonToBall, + [CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, [CONTROLLER_DRAWTRAINERPIC] = RecordedOpponentHandleDrawTrainerPic, - [CONTROLLER_TRAINERSLIDE] = RecordedOpponentHandleTrainerSlide, + [CONTROLLER_TRAINERSLIDE] = BtlController_Empty, [CONTROLLER_TRAINERSLIDEBACK] = RecordedOpponentHandleTrainerSlideBack, - [CONTROLLER_FAINTANIMATION] = RecordedOpponentHandleFaintAnimation, - [CONTROLLER_PALETTEFADE] = RecordedOpponentHandlePaletteFade, - [CONTROLLER_SUCCESSBALLTHROWANIM] = RecordedOpponentHandleSuccessBallThrowAnim, - [CONTROLLER_BALLTHROWANIM] = RecordedOpponentHandleBallThrowAnim, - [CONTROLLER_PAUSE] = RecordedOpponentHandlePause, + [CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, + [CONTROLLER_PALETTEFADE] = BtlController_Empty, + [CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty, + [CONTROLLER_BALLTHROWANIM] = BtlController_Empty, + [CONTROLLER_PAUSE] = BtlController_Empty, [CONTROLLER_MOVEANIMATION] = RecordedOpponentHandleMoveAnimation, [CONTROLLER_PRINTSTRING] = RecordedOpponentHandlePrintString, - [CONTROLLER_PRINTSTRINGPLAYERONLY] = RecordedOpponentHandlePrintSelectionString, + [CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty, [CONTROLLER_CHOOSEACTION] = RecordedOpponentHandleChooseAction, - [CONTROLLER_YESNOBOX] = RecordedOpponentHandleYesNoBox, + [CONTROLLER_YESNOBOX] = BtlController_Empty, [CONTROLLER_CHOOSEMOVE] = RecordedOpponentHandleChooseMove, [CONTROLLER_OPENBAG] = RecordedOpponentHandleChooseItem, [CONTROLLER_CHOOSEPOKEMON] = RecordedOpponentHandleChoosePokemon, - [CONTROLLER_23] = RecordedOpponentHandleCmd23, + [CONTROLLER_23] = BtlController_Empty, [CONTROLLER_HEALTHBARUPDATE] = RecordedOpponentHandleHealthBarUpdate, - [CONTROLLER_EXPUPDATE] = RecordedOpponentHandleExpUpdate, + [CONTROLLER_EXPUPDATE] = BtlController_Empty, [CONTROLLER_STATUSICONUPDATE] = RecordedOpponentHandleStatusIconUpdate, [CONTROLLER_STATUSANIMATION] = RecordedOpponentHandleStatusAnimation, - [CONTROLLER_STATUSXOR] = RecordedOpponentHandleStatusXor, - [CONTROLLER_DATATRANSFER] = RecordedOpponentHandleDataTransfer, - [CONTROLLER_DMA3TRANSFER] = RecordedOpponentHandleDMA3Transfer, - [CONTROLLER_PLAYBGM] = RecordedOpponentHandlePlayBGM, - [CONTROLLER_32] = RecordedOpponentHandleCmd32, - [CONTROLLER_TWORETURNVALUES] = RecordedOpponentHandleTwoReturnValues, - [CONTROLLER_CHOSENMONRETURNVALUE] = RecordedOpponentHandleChosenMonReturnValue, - [CONTROLLER_ONERETURNVALUE] = RecordedOpponentHandleOneReturnValue, - [CONTROLLER_ONERETURNVALUE_DUPLICATE] = RecordedOpponentHandleOneReturnValue_Duplicate, - [CONTROLLER_CLEARUNKVAR] = RecordedOpponentHandleClearUnkVar, - [CONTROLLER_SETUNKVAR] = RecordedOpponentHandleSetUnkVar, - [CONTROLLER_CLEARUNKFLAG] = RecordedOpponentHandleClearUnkFlag, - [CONTROLLER_TOGGLEUNKFLAG] = RecordedOpponentHandleToggleUnkFlag, - [CONTROLLER_HITANIMATION] = RecordedOpponentHandleHitAnimation, - [CONTROLLER_CANTSWITCH] = RecordedOpponentHandleCantSwitch, - [CONTROLLER_PLAYSE] = RecordedOpponentHandlePlaySE, - [CONTROLLER_PLAYFANFAREORBGM] = RecordedOpponentHandlePlayFanfareOrBGM, - [CONTROLLER_FAINTINGCRY] = RecordedOpponentHandleFaintingCry, - [CONTROLLER_INTROSLIDE] = RecordedOpponentHandleIntroSlide, + [CONTROLLER_STATUSXOR] = BtlController_Empty, + [CONTROLLER_DATATRANSFER] = BtlController_Empty, + [CONTROLLER_DMA3TRANSFER] = BtlController_Empty, + [CONTROLLER_PLAYBGM] = BtlController_Empty, + [CONTROLLER_32] = BtlController_Empty, + [CONTROLLER_TWORETURNVALUES] = BtlController_Empty, + [CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, + [CONTROLLER_CLEARUNKVAR] = BtlController_HandleClearUnkVar, + [CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar, + [CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag, + [CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag, + [CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, + [CONTROLLER_CANTSWITCH] = BtlController_Empty, + [CONTROLLER_PLAYSE] = BtlController_HandlePlaySE, + [CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, + [CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry, + [CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, [CONTROLLER_INTROTRAINERBALLTHROW] = RecordedOpponentHandleIntroTrainerBallThrow, [CONTROLLER_DRAWPARTYSTATUSSUMMARY] = RecordedOpponentHandleDrawPartyStatusSummary, - [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = RecordedOpponentHandleHidePartyStatusSummary, - [CONTROLLER_ENDBOUNCE] = RecordedOpponentHandleEndBounceEffect, - [CONTROLLER_SPRITEINVISIBILITY] = RecordedOpponentHandleSpriteInvisibility, + [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary, + [CONTROLLER_ENDBOUNCE] = BtlController_Empty, + [CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility, [CONTROLLER_BATTLEANIMATION] = RecordedOpponentHandleBattleAnimation, - [CONTROLLER_LINKSTANDBYMSG] = RecordedOpponentHandleLinkStandbyMsg, - [CONTROLLER_RESETACTIONMOVESELECTION] = RecordedOpponentHandleResetActionMoveSelection, + [CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty, + [CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, [CONTROLLER_ENDLINKBATTLE] = RecordedOpponentHandleEndLinkBattle, - [CONTROLLER_DEBUGMENU] = RecordedOpponentHandleBattleDebug, - [CONTROLLER_TERMINATOR_NOP] = RecordedOpponentCmdEnd + [CONTROLLER_DEBUGMENU] = BtlController_Empty, + [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop }; -static void RecordedOpponentDummy(void) +void SetControllerToRecordedOpponent(u32 battler) { + gBattlerControllerEndFuncs[battler] = RecordedOpponentBufferExecCompleted; + gBattlerControllerFuncs[battler] = RecordedOpponentBufferRunCommand; } -void SetControllerToRecordedOpponent(void) +static void RecordedOpponentBufferRunCommand(u32 battler) { - gBattlerControllerFuncs[gActiveBattler] = RecordedOpponentBufferRunCommand; -} - -static void RecordedOpponentBufferRunCommand(void) -{ - if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) + if (gBattleControllerExecFlags & gBitTable[battler]) { - if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sRecordedOpponentBufferCommands)) - sRecordedOpponentBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); + if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sRecordedOpponentBufferCommands)) + sRecordedOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler); else - RecordedOpponentBufferExecCompleted(); + RecordedOpponentBufferExecCompleted(battler); } } -static void CompleteOnBattlerSpriteCallbackDummy(void) +static void RecordedOpponentBufferExecCompleted(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - RecordedOpponentBufferExecCompleted(); -} - -static void CompleteOnBankSpriteCallbackDummy2(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - RecordedOpponentBufferExecCompleted(); -} - -static void FreeTrainerSpriteAfterSlide(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + gBattlerControllerFuncs[battler] = RecordedOpponentBufferRunCommand; + if (gBattleTypeFlags & BATTLE_TYPE_LINK) { - FreeTrainerFrontPicPalette(gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam); - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - RecordedOpponentBufferExecCompleted(); - } -} + u8 playerId = GetMultiplayerId(); -static void Intro_DelayAndEnd(void) -{ - if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == (u8)-1) + PrepareBufferDataTransferLink(2, 4, &playerId); + gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP; + } + else { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; - RecordedOpponentBufferExecCompleted(); + gBattleControllerExecFlags &= ~gBitTable[battler]; } } -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; if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].animEnded) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[battler]].animEnded) healthboxAnimDone = TRUE; } else { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].animEnded - && gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gActiveBattler)]].animEnded) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[battler]].animEnded + && gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler)]].animEnded) healthboxAnimDone = TRUE; } 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; - if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) + if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim) return; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; - gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3; + gBattlerControllerFuncs[battler] = Intro_DelayAndEnd; } } -static void Intro_TryShinyAnimShowHealthbox(void) +static void Intro_TryShinyAnimShowHealthbox(u32 battler) { bool32 bgmRestored = FALSE; bool32 battlerAnimsDone = FALSE; - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) - TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) + TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]); - if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive) - TryShinyAnimation(BATTLE_PARTNER(gActiveBattler), &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]]); + if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive) + 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)) { - UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); - StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL); + StartHealthboxSlideIn(BATTLE_PARTNER(battler)); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]); } - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gEnemyParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = TRUE; + gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = TRUE; } - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].waitForCry - && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].waitForCry + if (!gBattleSpritesDataPtr->healthBoxesData[battler].waitForCry + && gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].waitForCry && !IsCryPlayingOrClearCrySongs()) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored) { 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); } else @@ -306,24 +247,24 @@ static void Intro_TryShinyAnimShowHealthbox(void) m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100); } } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = TRUE; + gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = TRUE; bgmRestored = TRUE; } if (!IsDoubleBattle()) { - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) { battlerAnimsDone = TRUE; } } else { - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy + && gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy) { battlerAnimsDone = TRUE; } @@ -333,891 +274,130 @@ static void Intro_TryShinyAnimShowHealthbox(void) { if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { - DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); - SetBattlerShadowSpriteCallback(BATTLE_PARTNER(gActiveBattler), GetMonData(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], MON_DATA_SPECIES)); + DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]]); + SetBattlerShadowSpriteCallback(BATTLE_PARTNER(battler), GetMonData(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], MON_DATA_SPECIES)); } - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + DestroySprite(&gSprites[gBattleControllerData[battler]]); + SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES)); gBattleSpritesDataPtr->animationData->introAnimActive = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = 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 - && gSprites[gBattlerSpriteIds[gActiveBattler]].x2 == 0) + if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy + && 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) + if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim) { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); - RecordedOpponentBufferExecCompleted(); + RecordedOpponentBufferExecCompleted(battler); } } } } -static void CompleteOnHealthbarDone(void) +static void SwitchIn_ShowSubstitute(u32 battler) { - s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0); - - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - - if (hpValue != -1) - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); - else - RecordedOpponentBufferExecCompleted(); -} - -static void HideHealthboxAfterMonFaint(void) -{ - if (!gSprites[gBattlerSpriteIds[gActiveBattler]].inUse) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) { - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - RecordedOpponentBufferExecCompleted(); + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE); + + gBattlerControllerFuncs[battler] = SwitchIn_HandleSoundAndEnd; } } -static void FreeMonSpriteAfterSwitchOutAnim(void) +static void SwitchIn_HandleSoundAndEnd(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - HideBattlerShadowSprite(gActiveBattler); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - RecordedOpponentBufferExecCompleted(); - } -} - -static void CompleteOnInactiveTextPrinter(void) -{ - if (!IsTextPrinterActive(B_WIN_MSG)) - RecordedOpponentBufferExecCompleted(); -} - -static void DoHitAnimBlinkSpriteEffect(void) -{ - u8 spriteId = gBattlerSpriteIds[gActiveBattler]; - - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = FALSE; - RecordedOpponentBufferExecCompleted(); - } - else - { - if ((gSprites[spriteId].data[1] % 4) == 0) - gSprites[spriteId].invisible ^= 1; - gSprites[spriteId].data[1]++; - } -} - -static void SwitchIn_ShowSubstitute(void) -{ - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_HandleSoundAndEnd; - } -} - -static void SwitchIn_HandleSoundAndEnd(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive && !IsCryPlayingOrClearCrySongs()) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - || gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy_2) + if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy + || gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy_2) { 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 - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(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); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - CopyBattleSpriteInvisibility(gActiveBattler); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowSubstitute; + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gEnemyParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); + CopyBattleSpriteInvisibility(battler); + gBattlerControllerFuncs[battler] = SwitchIn_ShowSubstitute; } } -static void SwitchIn_TryShinyAnim(void) +static void SwitchIn_TryShinyAnim(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim) - TryShinyAnimation(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive + && !gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim) + TryShinyAnimation(battler, &gEnemyParty[gBattlerPartyIndexes[battler]]); - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) { - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowHealthbox; + DestroySprite(&gSprites[gBattleControllerData[battler]]); + SetBattlerShadowSpriteCallback(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES)); + gBattlerControllerFuncs[battler] = SwitchIn_ShowHealthbox; } } -static void CompleteOnFinishedStatusAnimation(void) +static void RecordedOpponentHandleLoadMonSprite(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive) - RecordedOpponentBufferExecCompleted(); + BtlController_HandleLoadMonSprite(battler, TryShinyAnimAfterMonAnim); } -static void CompleteOnFinishedBattleAnimation(void) +static void RecordedOpponentHandleSwitchInAnim(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive) - RecordedOpponentBufferExecCompleted(); + BtlController_HandleSwitchInAnim(battler, FALSE, SwitchIn_TryShinyAnim); } -static void RecordedOpponentBufferExecCompleted(void) -{ - gBattlerControllerFuncs[gActiveBattler] = RecordedOpponentBufferRunCommand; - 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 RecordedOpponentHandleGetMonData(void) -{ - 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 size = 0; - u8 monToCheck; - s32 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - size += CopyRecordedOpponentMonData(gBattlerPartyIndexes[gActiveBattler], monData); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - size += CopyRecordedOpponentMonData(i, monData + size); - monToCheck >>= 1; - } - } - BtlController_EmitDataTransfer(BUFFER_B, size, monData); - RecordedOpponentBufferExecCompleted(); -} - -static u32 CopyRecordedOpponentMonData(u8 monId, u8 *dst) -{ - struct BattlePokemon battleMon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - battleMon.species = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES); - battleMon.item = GetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM); - for (size = 0; size < MAX_MON_MOVES; size++) - { - battleMon.moves[size] = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + size); - battleMon.pp[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size); - } - battleMon.ppBonuses = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES); - battleMon.friendship = GetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP); - battleMon.experience = GetMonData(&gEnemyParty[monId], MON_DATA_EXP); - battleMon.hpIV = GetMonData(&gEnemyParty[monId], MON_DATA_HP_IV); - battleMon.attackIV = GetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV); - battleMon.defenseIV = GetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV); - battleMon.speedIV = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV); - battleMon.spAttackIV = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV); - battleMon.spDefenseIV = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV); - battleMon.personality = GetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY); - battleMon.status1 = GetMonData(&gEnemyParty[monId], MON_DATA_STATUS); - battleMon.level = GetMonData(&gEnemyParty[monId], MON_DATA_LEVEL); - battleMon.hp = GetMonData(&gEnemyParty[monId], MON_DATA_HP); - battleMon.maxHP = GetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP); - battleMon.attack = GetMonData(&gEnemyParty[monId], MON_DATA_ATK); - battleMon.defense = GetMonData(&gEnemyParty[monId], MON_DATA_DEF); - battleMon.speed = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED); - battleMon.spAttack = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK); - battleMon.spDefense = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF); - battleMon.abilityNum = GetMonData(&gEnemyParty[monId], MON_DATA_ABILITY_NUM); - battleMon.otId = GetMonData(&gEnemyParty[monId], MON_DATA_OT_ID); - battleMon.metLevel = GetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL); - GetMonData(&gEnemyParty[monId], MON_DATA_NICKNAME, nickname); - StringCopy_Nickname(battleMon.nickname, nickname); - GetMonData(&gEnemyParty[monId], MON_DATA_OT_NAME, battleMon.otName); - src = (u8 *)&battleMon; - for (size = 0; size < sizeof(battleMon); size++) - dst[size] = src[size]; - break; - case REQUEST_SPECIES_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_SPECIES); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_HELDITEM_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MOVES_PP_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - { - moveData.moves[size] = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES); - src = (u8 *)(&moveData); - for (size = 0; size < sizeof(moveData); size++) - dst[size] = src[size]; - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_PP_DATA_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - dst[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + size); - dst[size] = GetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES); - size++; - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE); - size = 1; - break; - case REQUEST_OTID_BATTLE: - data32 = GetMonData(&gEnemyParty[monId], MON_DATA_OT_ID); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_EXP_BATTLE: - data32 = GetMonData(&gEnemyParty[monId], MON_DATA_EXP); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_HP_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_HP_EV); - size = 1; - break; - case REQUEST_ATK_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_ATK_EV); - size = 1; - break; - case REQUEST_DEF_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_DEF_EV); - size = 1; - break; - case REQUEST_SPEED_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED_EV); - size = 1; - break; - case REQUEST_SPATK_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK_EV); - size = 1; - break; - case REQUEST_SPDEF_EV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_EV); - size = 1; - break; - case REQUEST_FRIENDSHIP_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP); - size = 1; - break; - case REQUEST_POKERUS_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_POKERUS); - size = 1; - break; - case REQUEST_MET_LOCATION_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_MET_LOCATION); - size = 1; - break; - case REQUEST_MET_LEVEL_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL); - size = 1; - break; - case REQUEST_MET_GAME_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_MET_GAME); - size = 1; - break; - case REQUEST_POKEBALL_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_POKEBALL); - size = 1; - break; - case REQUEST_ALL_IVS_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_HP_IV); - dst[1] = GetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV); - dst[2] = GetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV); - dst[3] = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV); - dst[4] = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV); - dst[5] = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV); - size = 6; - break; - case REQUEST_HP_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_HP_IV); - size = 1; - break; - case REQUEST_ATK_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV); - size = 1; - break; - case REQUEST_DEF_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV); - size = 1; - break; - case REQUEST_SPEED_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV); - size = 1; - break; - case REQUEST_SPATK_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV); - size = 1; - break; - case REQUEST_SPDEF_IV_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV); - size = 1; - break; - case REQUEST_PERSONALITY_BATTLE: - data32 = GetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_CHECKSUM_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_CHECKSUM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_STATUS_BATTLE: - data32 = GetMonData(&gEnemyParty[monId], MON_DATA_STATUS); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_LEVEL_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_LEVEL); - size = 1; - break; - case REQUEST_HP_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MAX_HP_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_ATK_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_ATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_DEF_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_DEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPEED_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_SPEED); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPATK_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_SPATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPDEF_BATTLE: - data16 = GetMonData(&gEnemyParty[monId], MON_DATA_SPDEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_COOL_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_COOL); - size = 1; - break; - case REQUEST_BEAUTY_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY); - size = 1; - break; - case REQUEST_CUTE_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_CUTE); - size = 1; - break; - case REQUEST_SMART_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SMART); - size = 1; - break; - case REQUEST_TOUGH_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_TOUGH); - size = 1; - break; - case REQUEST_SHEEN_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SHEEN); - size = 1; - break; - case REQUEST_COOL_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_COOL_RIBBON); - size = 1; - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case REQUEST_CUTE_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case REQUEST_SMART_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_SMART_RIBBON); - size = 1; - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - dst[0] = GetMonData(&gEnemyParty[monId], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - - return size; -} - -static void RecordedOpponentHandleGetRawMonData(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleSetMonData(void) -{ - u8 monToCheck; - u8 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - SetRecordedOpponentMonData(gBattlerPartyIndexes[gActiveBattler]); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - SetRecordedOpponentMonData(i); - monToCheck >>= 1; - } - } - RecordedOpponentBufferExecCompleted(); -} - -static void SetRecordedOpponentMonData(u8 monId) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleResources->bufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleResources->bufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - { - u8 iv; - - SetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gEnemyParty[monId], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gEnemyParty[monId], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gEnemyParty[monId], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gEnemyParty[monId], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gEnemyParty[monId], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gEnemyParty[monId], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case REQUEST_SPECIES_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPECIES, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HELDITEM_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MOVES_PP_BATTLE: - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PP_DATA_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_PP1, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP2, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP3, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP4, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES, &gBattleResources->bufferA[gActiveBattler][7]); - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_OTID_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_OT_ID, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_EXP_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_EXP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HP_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_ATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_DEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_EV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_FRIENDSHIP_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKERUS_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_POKERUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LOCATION_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MET_LOCATION, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LEVEL_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_GAME_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MET_GAME, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKEBALL_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_POKEBALL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ALL_IVS_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][7]); - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][8]); - break; - case REQUEST_HP_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_IV_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PERSONALITY_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CHECKSUM_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_CHECKSUM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_STATUS_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_STATUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_LEVEL_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MAX_HP_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_ATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_DEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPEED, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_COOL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_CUTE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SMART, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_TOUGH, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SHEEN_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SHEEN, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_COOL_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_CUTE_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_SMART_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - SetMonData(&gEnemyParty[monId], MON_DATA_TOUGH_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - } -} - -static void RecordedOpponentHandleSetRawMonData(void) -{ - u8 *dst = (u8 *)&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleResources->bufferA[gActiveBattler][1]; - u8 i; - - for (i = 0; i < gBattleResources->bufferA[gActiveBattler][2]; i++) - dst[i] = gBattleResources->bufferA[gActiveBattler][3 + i]; - - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleLoadMonSprite(void) -{ - u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(gActiveBattler)); - - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(gActiveBattler, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(gActiveBattler), - GetBattlerSpriteSubpriority(gActiveBattler)); - - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); - - SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - - gBattlerControllerFuncs[gActiveBattler] = TryShinyAnimAfterMonAnim; -} - -static void RecordedOpponentHandleSwitchInAnim(void) -{ - gBattlerPartyIndexes[gActiveBattler] = gBattleResources->bufferA[gActiveBattler][1]; - StartSendOutAnim(gActiveBattler, gBattleResources->bufferA[gActiveBattler][2]); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_TryShinyAnim; -} - -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit) -{ - u16 species; - - ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit); - gBattlerPartyIndexes[battlerId] = gBattleResources->bufferA[battlerId][1]; - species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); - gBattleControllerData[battlerId] = CreateInvisibleSpriteWithCallback(SpriteCB_WaitForBattlerBallReleaseAnim); - BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battlerId)); - - gBattlerSpriteIds[battlerId] = CreateSprite(&gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(battlerId), - GetBattlerSpriteSubpriority(battlerId)); - - gSprites[gBattleControllerData[battlerId]].data[1] = gBattlerSpriteIds[battlerId]; - gSprites[gBattleControllerData[battlerId]].data[2] = battlerId; - - gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId; - gSprites[gBattlerSpriteIds[battlerId]].data[2] = species; - gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId; - - StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], 0); - - gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE; - gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy; - - gSprites[gBattleControllerData[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_OPPONENT_SENDOUT); -} - -static void RecordedOpponentHandleReturnMonToBall(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] == 0) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = DoSwitchOutAnimation; - } - else - { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - HideBattlerShadowSprite(gActiveBattler); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - RecordedOpponentBufferExecCompleted(); - } -} - -static void DoSwitchOutAnimation(void) -{ - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SWITCH_OUT_OPPONENT_MON); - gBattlerControllerFuncs[gActiveBattler] = FreeMonSpriteAfterSwitchOutAnim; - } - break; - } -} - -#define sSpeedX data[0] - -static void RecordedOpponentHandleDrawTrainerPic(void) +static void RecordedOpponentHandleDrawTrainerPic(u32 battler) { s16 xPos; u32 trainerPicId; if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { - if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != 0) // second mon + if ((GetBattlerPosition(battler) & BIT_FLANK) != 0) // second mon xPos = 152; else // first mon xPos = 200; if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) { - if (gActiveBattler == 1) + if (battler == B_POSITION_OPPONENT_LEFT) trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); else trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B); @@ -1240,155 +420,28 @@ static void RecordedOpponentHandleDrawTrainerPic(void) } } - DecompressTrainerFrontPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, - xPos, - (8 - gTrainerFrontPicCoords[trainerPicId].size) * 4 + 40, - GetBattlerSpriteSubpriority(gActiveBattler)); - - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = 2; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam = trainerPicId; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy; + BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, + xPos, 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicId].size), + -1); } -#undef sSpeedX - -static void RecordedOpponentHandleTrainerSlide(void) +static void RecordedOpponentHandleTrainerSlideBack(u32 battler) { - RecordedOpponentBufferExecCompleted(); + BtlController_HandleTrainerSlideBack(battler, 35, FALSE); } -static void RecordedOpponentHandleTrainerSlideBack(void) +static void RecordedOpponentHandleMoveAnimation(u32 battler) { - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = 280; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCallbackDummy); - gBattlerControllerFuncs[gActiveBattler] = FreeTrainerSpriteAfterSlide; + BtlController_HandleMoveAnimation(battler, FALSE); } -static void RecordedOpponentHandleFaintAnimation(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState == 0) - { - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState++; - } - else - { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - PlaySE12WithPanning(SE_FAINT, SOUND_PAN_TARGET); - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_FaintOpponentMon; - gBattlerControllerFuncs[gActiveBattler] = HideHealthboxAfterMonFaint; - } - } -} - -static void RecordedOpponentHandlePaletteFade(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleSuccessBallThrowAnim(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleBallThrowAnim(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandlePause(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleMoveAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleResources->bufferA[gActiveBattler][3]; - gAnimMovePower = gBattleResources->bufferA[gActiveBattler][4] | (gBattleResources->bufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleResources->bufferA[gActiveBattler][6] | (gBattleResources->bufferA[gActiveBattler][7] << 8) | (gBattleResources->bufferA[gActiveBattler][8] << 16) | (gBattleResources->bufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleResources->bufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleResources->bufferA[gActiveBattler][12] | (gBattleResources->bufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - gTransformedOtIds[gActiveBattler] = gAnimDisableStructPtr->transformedMonOtId; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = RecordedOpponentDoMoveAnimation; - } -} - -static void RecordedOpponentDoMoveAnimation(void) -{ - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - u8 multihit = gBattleResources->bufferA[gActiveBattler][11]; - - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute - && !gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8) - { - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 1; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF); - DoMoveAnim(move); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL); - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute && multihit < 2) - { - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 0; - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 3; - } - break; - case 3: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - CopyAllBattleSpritesInvisibilities(); - TrySetBehindSubstituteSpriteBit(gActiveBattler, gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - RecordedOpponentBufferExecCompleted(); - } - break; - } -} - -static void RecordedOpponentHandlePrintString(void) +static void RecordedOpponentHandlePrintString(u32 battler) { u16 *stringId; gBattle_BG0_X = 0; gBattle_BG0_Y = 0; - stringId = (u16 *)(&gBattleResources->bufferA[gActiveBattler][2]); + stringId = (u16 *)(&gBattleResources->bufferA[battler][2]); BufferStringBattle(*stringId); if (gTestRunnerEnabled) @@ -1396,32 +449,22 @@ static void RecordedOpponentHandlePrintString(void) TestRunner_Battle_RecordMessage(gDisplayedStringBattle); if (gTestRunnerHeadless) { - RecordedOpponentBufferExecCompleted(); + RecordedOpponentBufferExecCompleted(battler); return; } } BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter; + gBattlerControllerFuncs[battler] = Controller_WaitForString; } -static void RecordedOpponentHandlePrintSelectionString(void) +static void RecordedOpponentHandleChooseAction(u32 battler) { - RecordedOpponentBufferExecCompleted(); + BtlController_EmitTwoReturnValues(BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_ACTION_TYPE, battler), 0); + RecordedOpponentBufferExecCompleted(battler); } -static void RecordedOpponentHandleChooseAction(void) -{ - BtlController_EmitTwoReturnValues(BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_ACTION_TYPE, gActiveBattler), 0); - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleYesNoBox(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleChooseMove(void) +static void RecordedOpponentHandleChooseMove(u32 battler) { if (gBattleTypeFlags & BATTLE_TYPE_PALACE) { @@ -1429,386 +472,97 @@ static void RecordedOpponentHandleChooseMove(void) } else { - u8 moveId = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, gActiveBattler); - u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, gActiveBattler); + u8 moveId = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, battler); + u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, battler); 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 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler); - gBattleStruct->chosenItem[gActiveBattler] = (byte1 << 8) | byte2; - gBattleStruct->itemPartyIndex[gActiveBattler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_TARGET, gActiveBattler); - gBattleStruct->itemMoveIndex[gActiveBattler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_MOVE, gActiveBattler); - BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[gActiveBattler]); - RecordedOpponentBufferExecCompleted(); + u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, battler); + u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, battler); + gBattleStruct->chosenItem[battler] = (byte1 << 8) | byte2; + gBattleStruct->itemPartyIndex[battler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_TARGET, battler); + gBattleStruct->itemMoveIndex[battler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_MOVE, battler); + BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[battler]); + RecordedOpponentBufferExecCompleted(battler); } -static void RecordedOpponentHandleChoosePokemon(void) +static void RecordedOpponentHandleChoosePokemon(u32 battler) { - *(gBattleStruct->monToSwitchIntoId + gActiveBattler) = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, gActiveBattler); - gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[gActiveBattler]; // Revival Blessing - BtlController_EmitChosenMonReturnValue(BUFFER_B, *(gBattleStruct->monToSwitchIntoId + gActiveBattler), NULL); - RecordedOpponentBufferExecCompleted(); + *(gBattleStruct->monToSwitchIntoId + battler) = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, battler); + gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[battler]; // Revival Blessing + BtlController_EmitChosenMonReturnValue(BUFFER_B, *(gBattleStruct->monToSwitchIntoId + battler), NULL); + RecordedOpponentBufferExecCompleted(battler); } -static void RecordedOpponentHandleCmd23(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleHealthBarUpdate(void) +static void RecordedOpponentHandleHealthBarUpdate(u32 battler) { s16 hpVal; s32 maxHP, curHP; 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); - curHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); + maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP); + curHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_HP); if (hpVal != INSTANT_HP_BAR_DROP) { - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, curHP, hpVal); - TestRunner_Battle_RecordHP(gActiveBattler, curHP, min(maxHP, max(0, curHP - hpVal))); + SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, curHP, hpVal); + TestRunner_Battle_RecordHP(battler, curHP, min(maxHP, max(0, curHP - hpVal))); } else { - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); - TestRunner_Battle_RecordHP(gActiveBattler, curHP, 0); + SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, 0, hpVal); + TestRunner_Battle_RecordHP(battler, curHP, 0); } - gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone; + gBattlerControllerFuncs[battler] = Controller_WaitForHealthBar; } -static void RecordedOpponentHandleExpUpdate(void) +static void RecordedOpponentHandleStatusIconUpdate(u32 battler) { - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleStatusIconUpdate(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) + if (!IsBattleSEPlaying(battler)) { - u8 battlerId; - - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON); - battlerId = gActiveBattler; - gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0; - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - + DoStatusIconUpdate(battler); if (gTestRunnerEnabled) - TestRunner_Battle_RecordStatus1(battlerId, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_STATUS)); + TestRunner_Battle_RecordStatus1(battler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_STATUS)); } } -static void RecordedOpponentHandleStatusAnimation(void) +static void RecordedOpponentHandleStatusAnimation(u32 battler) { - if (!IsBattleSEPlaying(gActiveBattler)) - { - InitAndLaunchChosenStatusAnimation(gBattleResources->bufferA[gActiveBattler][1], - gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8) | (gBattleResources->bufferA[gActiveBattler][4] << 16) | (gBattleResources->bufferA[gActiveBattler][5] << 24)); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - } + BtlController_HandleStatusAnimation(battler); } -static void RecordedOpponentHandleStatusXor(void) +static void RecordedOpponentHandleIntroTrainerBallThrow(u32 battler) { - RecordedOpponentBufferExecCompleted(); + BtlController_HandleIntroTrainerBallThrow(battler, 0, NULL, 0, Intro_TryShinyAnimShowHealthbox); } -static void RecordedOpponentHandleDataTransfer(void) +static void RecordedOpponentHandleDrawPartyStatusSummary(u32 battler) { - RecordedOpponentBufferExecCompleted(); + BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_OPPONENT, TRUE); } -static void RecordedOpponentHandleDMA3Transfer(void) +static void RecordedOpponentHandleBattleAnimation(u32 battler) { - RecordedOpponentBufferExecCompleted(); + BtlController_HandleBattleAnimation(battler, FALSE, FALSE); } -static void RecordedOpponentHandlePlayBGM(void) +static void RecordedOpponentHandleEndLinkBattle(u32 battler) { - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleCmd32(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleTwoReturnValues(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleChosenMonReturnValue(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleOneReturnValue(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleOneReturnValue_Duplicate(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleClearUnkVar(void) -{ - gUnusedControllerStruct.unk = 0; - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleSetUnkVar(void) -{ - gUnusedControllerStruct.unk = gBattleResources->bufferA[gActiveBattler][1]; - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleClearUnkFlag(void) -{ - gUnusedControllerStruct.flag = 0; - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleToggleUnkFlag(void) -{ - gUnusedControllerStruct.flag ^= 1; - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleHitAnimation(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].invisible == TRUE) - { - RecordedOpponentBufferExecCompleted(); - } + if (gBattleResources->bufferA[battler][1] == B_OUTCOME_DREW) + gBattleOutcome = gBattleResources->bufferA[battler][1]; else - { - gDoingBattleAnim = TRUE; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[1] = 0; - DoHitAnimHealthboxEffect(gActiveBattler); - gBattlerControllerFuncs[gActiveBattler] = DoHitAnimBlinkSpriteEffect; - } -} - -static void RecordedOpponentHandleCantSwitch(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandlePlaySE(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - pan = SOUND_PAN_ATTACKER; - else - pan = SOUND_PAN_TARGET; - - PlaySE12WithPanning(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8), pan); - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandlePlayFanfareOrBGM(void) -{ - if (gBattleResources->bufferA[gActiveBattler][3]) - { - BattleStopLowHpSound(); - PlayBGM(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - else - { - PlayFanfare(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleFaintingCry(void) -{ - u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - PlayCry_ByMode(species, 25, CRY_MODE_FAINT); - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleIntroSlide(void) -{ - HandleIntroSlide(gBattleResources->bufferA[gActiveBattler][1]); - gIntroSlideFlags |= 1; - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleIntroTrainerBallThrow(void) -{ - u8 taskId; - - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = 280; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCB_FreeOpponentSprite); - - taskId = CreateTask(Task_StartSendOutAnim, 5); - gTasks[taskId].data[0] = gActiveBattler; - - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - - gBattleSpritesDataPtr->animationData->introAnimActive = TRUE; - gBattlerControllerFuncs[gActiveBattler] = RecordedOpponentDummy; -} - -static void Task_StartSendOutAnim(u8 taskId) -{ - u8 savedActiveBank = gActiveBattler; - - gActiveBattler = gTasks[taskId].data[0]; - if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - } - else - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler ^= BIT_FLANK; - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler ^= BIT_FLANK; - } - gBattlerControllerFuncs[gActiveBattler] = Intro_TryShinyAnimShowHealthbox; - gActiveBattler = savedActiveBank; - DestroyTask(taskId); -} - -static void SpriteCB_FreeOpponentSprite(struct Sprite *sprite) -{ - FreeTrainerFrontPicPalette(sprite->oam.affineParam); - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); -} - -static void RecordedOpponentHandleDrawPartyStatusSummary(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - { - RecordedOpponentBufferExecCompleted(); - } - else - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown = 1; - - if (gBattleResources->bufferA[gActiveBattler][2] != 0) - { - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay < 2) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay++; - return; - } - else - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].opponentDrawPartyStatusSummaryDelay = 0; - } - } - - gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleResources->bufferA[gActiveBattler][4], gBattleResources->bufferA[gActiveBattler][1], gBattleResources->bufferA[gActiveBattler][2]); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - - if (gBattleResources->bufferA[gActiveBattler][2] != 0) - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 93; - - gBattlerControllerFuncs[gActiveBattler] = EndDrawPartyStatusSummary; - } -} - -static void EndDrawPartyStatusSummary(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer++ > 92) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - RecordedOpponentBufferExecCompleted(); - } -} - -static void RecordedOpponentHandleHidePartyStatusSummary(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleEndBounceEffect(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleSpriteInvisibility(void) -{ - if (IsBattlerSpritePresent(gActiveBattler)) - { - gSprites[gBattlerSpriteIds[gActiveBattler]].invisible = gBattleResources->bufferA[gActiveBattler][1]; - CopyBattleSpriteInvisibility(gActiveBattler); - } - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleBattleAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u8 animationId = gBattleResources->bufferA[gActiveBattler][1]; - u16 argument = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (TryHandleLaunchBattleTableAnimation(gActiveBattler, gActiveBattler, gActiveBattler, animationId, argument)) - RecordedOpponentBufferExecCompleted(); - else - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; - } -} - -static void RecordedOpponentHandleLinkStandbyMsg(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleResetActionMoveSelection(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentHandleEndLinkBattle(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] == B_OUTCOME_DREW) - gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; - else - gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1] ^ B_OUTCOME_DREW; + gBattleOutcome = gBattleResources->bufferA[battler][1] ^ B_OUTCOME_DREW; FadeOutMapMusic(5); BeginFastPaletteFade(3); - RecordedOpponentBufferExecCompleted(); - gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; -} - -static void RecordedOpponentHandleBattleDebug(void) -{ - RecordedOpponentBufferExecCompleted(); -} - -static void RecordedOpponentCmdEnd(void) -{ + RecordedOpponentBufferExecCompleted(battler); + gBattlerControllerFuncs[battler] = SetBattleEndCallbacks; } diff --git a/src/battle_controller_recorded_player.c b/src/battle_controller_recorded_player.c index 86cb49198..aac42824c 100644 --- a/src/battle_controller_recorded_player.c +++ b/src/battle_controller_recorded_player.c @@ -27,234 +27,169 @@ #include "window.h" #include "constants/battle_anim.h" #include "constants/songs.h" +#include "constants/trainers.h" -static void RecordedPlayerHandleGetMonData(void); -static void RecordedPlayerHandleGetRawMonData(void); -static void RecordedPlayerHandleSetMonData(void); -static void RecordedPlayerHandleSetRawMonData(void); -static void RecordedPlayerHandleLoadMonSprite(void); -static void RecordedPlayerHandleSwitchInAnim(void); -static void RecordedPlayerHandleReturnMonToBall(void); -static void RecordedPlayerHandleDrawTrainerPic(void); -static void RecordedPlayerHandleTrainerSlide(void); -static void RecordedPlayerHandleTrainerSlideBack(void); -static void RecordedPlayerHandleFaintAnimation(void); -static void RecordedPlayerHandlePaletteFade(void); -static void RecordedPlayerHandleSuccessBallThrowAnim(void); -static void RecordedPlayerHandleBallThrowAnim(void); -static void RecordedPlayerHandlePause(void); -static void RecordedPlayerHandleMoveAnimation(void); -static void RecordedPlayerHandlePrintString(void); -static void RecordedPlayerHandlePrintSelectionString(void); -static void RecordedPlayerHandleChooseAction(void); -static void RecordedPlayerHandleYesNoBox(void); -static void RecordedPlayerHandleChooseMove(void); -static void RecordedPlayerHandleChooseItem(void); -static void RecordedPlayerHandleChoosePokemon(void); -static void RecordedPlayerHandleCmd23(void); -static void RecordedPlayerHandleHealthBarUpdate(void); -static void RecordedPlayerHandleExpUpdate(void); -static void RecordedPlayerHandleStatusIconUpdate(void); -static void RecordedPlayerHandleStatusAnimation(void); -static void RecordedPlayerHandleStatusXor(void); -static void RecordedPlayerHandleDataTransfer(void); -static void RecordedPlayerHandleDMA3Transfer(void); -static void RecordedPlayerHandlePlayBGM(void); -static void RecordedPlayerHandleCmd32(void); -static void RecordedPlayerHandleTwoReturnValues(void); -static void RecordedPlayerHandleChosenMonReturnValue(void); -static void RecordedPlayerHandleOneReturnValue(void); -static void RecordedPlayerHandleOneReturnValue_Duplicate(void); -static void RecordedPlayerHandleClearUnkVar(void); -static void RecordedPlayerHandleSetUnkVar(void); -static void RecordedPlayerHandleClearUnkFlag(void); -static void RecordedPlayerHandleToggleUnkFlag(void); -static void RecordedPlayerHandleHitAnimation(void); -static void RecordedPlayerHandleCantSwitch(void); -static void RecordedPlayerHandlePlaySE(void); -static void RecordedPlayerHandlePlayFanfareOrBGM(void); -static void RecordedPlayerHandleFaintingCry(void); -static void RecordedPlayerHandleIntroSlide(void); -static void RecordedPlayerHandleIntroTrainerBallThrow(void); -static void RecordedPlayerHandleDrawPartyStatusSummary(void); -static void RecordedPlayerHandleHidePartyStatusSummary(void); -static void RecordedPlayerHandleEndBounceEffect(void); -static void RecordedPlayerHandleSpriteInvisibility(void); -static void RecordedPlayerHandleBattleAnimation(void); -static void RecordedPlayerHandleLinkStandbyMsg(void); -static void RecordedPlayerHandleResetActionMoveSelection(void); -static void RecordedPlayerHandleEndLinkBattle(void); -static void RecordedPlayerCmdEnd(void); +static void RecordedPlayerHandleLoadMonSprite(u32 battler); +static void RecordedPlayerHandleSwitchInAnim(u32 battler); +static void RecordedPlayerHandleDrawTrainerPic(u32 battler); +static void RecordedPlayerHandleTrainerSlideBack(u32 battler); +static void RecordedPlayerHandleMoveAnimation(u32 battler); +static void RecordedPlayerHandlePrintString(u32 battler); +static void RecordedPlayerHandleChooseAction(u32 battler); +static void RecordedPlayerHandleChooseMove(u32 battler); +static void RecordedPlayerHandleChooseItem(u32 battler); +static void RecordedPlayerHandleChoosePokemon(u32 battler); +static void RecordedPlayerHandleHealthBarUpdate(u32 battler); +static void RecordedPlayerHandleStatusIconUpdate(u32 battler); +static void RecordedPlayerHandleStatusAnimation(u32 battler); +static void RecordedPlayerHandleIntroTrainerBallThrow(u32 battler); +static void RecordedPlayerHandleDrawPartyStatusSummary(u32 battler); +static void RecordedPlayerHandleBattleAnimation(u32 battler); +static void RecordedPlayerHandleEndLinkBattle(u32 battler); -static void RecordedPlayerBufferRunCommand(void); -static void RecordedPlayerBufferExecCompleted(void); -static void SwitchIn_WaitAndEnd(void); -static u32 CopyRecordedPlayerMonData(u8 monId, u8 *dst); -static void SetRecordedPlayerMonData(u8 monId); -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit); -static void DoSwitchOutAnimation(void); -static void RecordedPlayerDoMoveAnimation(void); -static void Task_StartSendOutAnim(u8 taskId); -static void EndDrawPartyStatusSummary(void); +static void RecordedPlayerBufferRunCommand(u32 battler); +static void RecordedPlayerBufferExecCompleted(u32 battler); +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] = RecordedPlayerHandleGetMonData, - [CONTROLLER_GETRAWMONDATA] = RecordedPlayerHandleGetRawMonData, - [CONTROLLER_SETMONDATA] = RecordedPlayerHandleSetMonData, - [CONTROLLER_SETRAWMONDATA] = RecordedPlayerHandleSetRawMonData, + [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, + [CONTROLLER_GETRAWMONDATA] = BtlController_Empty, + [CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, + [CONTROLLER_SETRAWMONDATA] = BtlController_HandleSetRawMonData, [CONTROLLER_LOADMONSPRITE] = RecordedPlayerHandleLoadMonSprite, [CONTROLLER_SWITCHINANIM] = RecordedPlayerHandleSwitchInAnim, - [CONTROLLER_RETURNMONTOBALL] = RecordedPlayerHandleReturnMonToBall, + [CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, [CONTROLLER_DRAWTRAINERPIC] = RecordedPlayerHandleDrawTrainerPic, - [CONTROLLER_TRAINERSLIDE] = RecordedPlayerHandleTrainerSlide, + [CONTROLLER_TRAINERSLIDE] = BtlController_Empty, [CONTROLLER_TRAINERSLIDEBACK] = RecordedPlayerHandleTrainerSlideBack, - [CONTROLLER_FAINTANIMATION] = RecordedPlayerHandleFaintAnimation, - [CONTROLLER_PALETTEFADE] = RecordedPlayerHandlePaletteFade, - [CONTROLLER_SUCCESSBALLTHROWANIM] = RecordedPlayerHandleSuccessBallThrowAnim, - [CONTROLLER_BALLTHROWANIM] = RecordedPlayerHandleBallThrowAnim, - [CONTROLLER_PAUSE] = RecordedPlayerHandlePause, + [CONTROLLER_FAINTANIMATION] = BtlController_HandleFaintAnimation, + [CONTROLLER_PALETTEFADE] = BtlController_Empty, + [CONTROLLER_SUCCESSBALLTHROWANIM] = BtlController_Empty, + [CONTROLLER_BALLTHROWANIM] = BtlController_Empty, + [CONTROLLER_PAUSE] = BtlController_Empty, [CONTROLLER_MOVEANIMATION] = RecordedPlayerHandleMoveAnimation, [CONTROLLER_PRINTSTRING] = RecordedPlayerHandlePrintString, - [CONTROLLER_PRINTSTRINGPLAYERONLY] = RecordedPlayerHandlePrintSelectionString, + [CONTROLLER_PRINTSTRINGPLAYERONLY] = BtlController_Empty, [CONTROLLER_CHOOSEACTION] = RecordedPlayerHandleChooseAction, - [CONTROLLER_YESNOBOX] = RecordedPlayerHandleYesNoBox, + [CONTROLLER_YESNOBOX] = BtlController_Empty, [CONTROLLER_CHOOSEMOVE] = RecordedPlayerHandleChooseMove, [CONTROLLER_OPENBAG] = RecordedPlayerHandleChooseItem, [CONTROLLER_CHOOSEPOKEMON] = RecordedPlayerHandleChoosePokemon, - [CONTROLLER_23] = RecordedPlayerHandleCmd23, + [CONTROLLER_23] = BtlController_Empty, [CONTROLLER_HEALTHBARUPDATE] = RecordedPlayerHandleHealthBarUpdate, - [CONTROLLER_EXPUPDATE] = RecordedPlayerHandleExpUpdate, + [CONTROLLER_EXPUPDATE] = BtlController_Empty, [CONTROLLER_STATUSICONUPDATE] = RecordedPlayerHandleStatusIconUpdate, [CONTROLLER_STATUSANIMATION] = RecordedPlayerHandleStatusAnimation, - [CONTROLLER_STATUSXOR] = RecordedPlayerHandleStatusXor, - [CONTROLLER_DATATRANSFER] = RecordedPlayerHandleDataTransfer, - [CONTROLLER_DMA3TRANSFER] = RecordedPlayerHandleDMA3Transfer, - [CONTROLLER_PLAYBGM] = RecordedPlayerHandlePlayBGM, - [CONTROLLER_32] = RecordedPlayerHandleCmd32, - [CONTROLLER_TWORETURNVALUES] = RecordedPlayerHandleTwoReturnValues, - [CONTROLLER_CHOSENMONRETURNVALUE] = RecordedPlayerHandleChosenMonReturnValue, - [CONTROLLER_ONERETURNVALUE] = RecordedPlayerHandleOneReturnValue, - [CONTROLLER_ONERETURNVALUE_DUPLICATE] = RecordedPlayerHandleOneReturnValue_Duplicate, - [CONTROLLER_CLEARUNKVAR] = RecordedPlayerHandleClearUnkVar, - [CONTROLLER_SETUNKVAR] = RecordedPlayerHandleSetUnkVar, - [CONTROLLER_CLEARUNKFLAG] = RecordedPlayerHandleClearUnkFlag, - [CONTROLLER_TOGGLEUNKFLAG] = RecordedPlayerHandleToggleUnkFlag, - [CONTROLLER_HITANIMATION] = RecordedPlayerHandleHitAnimation, - [CONTROLLER_CANTSWITCH] = RecordedPlayerHandleCantSwitch, - [CONTROLLER_PLAYSE] = RecordedPlayerHandlePlaySE, - [CONTROLLER_PLAYFANFAREORBGM] = RecordedPlayerHandlePlayFanfareOrBGM, - [CONTROLLER_FAINTINGCRY] = RecordedPlayerHandleFaintingCry, - [CONTROLLER_INTROSLIDE] = RecordedPlayerHandleIntroSlide, + [CONTROLLER_STATUSXOR] = BtlController_Empty, + [CONTROLLER_DATATRANSFER] = BtlController_Empty, + [CONTROLLER_DMA3TRANSFER] = BtlController_Empty, + [CONTROLLER_PLAYBGM] = BtlController_Empty, + [CONTROLLER_32] = BtlController_Empty, + [CONTROLLER_TWORETURNVALUES] = BtlController_Empty, + [CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, + [CONTROLLER_CLEARUNKVAR] = BtlController_HandleClearUnkVar, + [CONTROLLER_SETUNKVAR] = BtlController_HandleSetUnkVar, + [CONTROLLER_CLEARUNKFLAG] = BtlController_HandleClearUnkFlag, + [CONTROLLER_TOGGLEUNKFLAG] = BtlController_HandleToggleUnkFlag, + [CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, + [CONTROLLER_CANTSWITCH] = BtlController_Empty, + [CONTROLLER_PLAYSE] = BtlController_HandlePlaySE, + [CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, + [CONTROLLER_FAINTINGCRY] = BtlController_HandleFaintingCry, + [CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, [CONTROLLER_INTROTRAINERBALLTHROW] = RecordedPlayerHandleIntroTrainerBallThrow, [CONTROLLER_DRAWPARTYSTATUSSUMMARY] = RecordedPlayerHandleDrawPartyStatusSummary, - [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = RecordedPlayerHandleHidePartyStatusSummary, - [CONTROLLER_ENDBOUNCE] = RecordedPlayerHandleEndBounceEffect, - [CONTROLLER_SPRITEINVISIBILITY] = RecordedPlayerHandleSpriteInvisibility, + [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_HandleHidePartyStatusSummary, + [CONTROLLER_ENDBOUNCE] = BtlController_Empty, + [CONTROLLER_SPRITEINVISIBILITY] = BtlController_HandleSpriteInvisibility, [CONTROLLER_BATTLEANIMATION] = RecordedPlayerHandleBattleAnimation, - [CONTROLLER_LINKSTANDBYMSG] = RecordedPlayerHandleLinkStandbyMsg, - [CONTROLLER_RESETACTIONMOVESELECTION] = RecordedPlayerHandleResetActionMoveSelection, + [CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty, + [CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, [CONTROLLER_ENDLINKBATTLE] = RecordedPlayerHandleEndLinkBattle, - [CONTROLLER_TERMINATOR_NOP] = RecordedPlayerCmdEnd + [CONTROLLER_DEBUGMENU] = BtlController_Empty, + [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop }; -static void RecordedPlayerDummy(void) +void SetControllerToRecordedPlayer(u32 battler) { + gBattlerControllerEndFuncs[battler] = RecordedPlayerBufferExecCompleted; + gBattlerControllerFuncs[battler] = RecordedPlayerBufferRunCommand; } -void SetControllerToRecordedPlayer(void) +static void RecordedPlayerBufferRunCommand(u32 battler) { - gBattlerControllerFuncs[gActiveBattler] = RecordedPlayerBufferRunCommand; -} - -static void RecordedPlayerBufferRunCommand(void) -{ - if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) + if (gBattleControllerExecFlags & gBitTable[battler]) { - if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sRecordedPlayerBufferCommands)) - sRecordedPlayerBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); + if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sRecordedPlayerBufferCommands)) + sRecordedPlayerBufferCommands[gBattleResources->bufferA[battler][0]](battler); else - RecordedPlayerBufferExecCompleted(); + RecordedPlayerBufferExecCompleted(battler); } } -static void CompleteOnBattlerSpriteCallbackDummy(void) +static void Intro_DelayAndEnd(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - RecordedPlayerBufferExecCompleted(); -} - -static void FreeTrainerSpriteAfterSlide(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (--gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay == (u8)-1) { - BattleGfxSfxDummy3(MALE); - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - RecordedPlayerBufferExecCompleted(); + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 0; + RecordedPlayerBufferExecCompleted(battler); } } -static void Intro_DelayAndEnd(void) -{ - if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay == (u8)-1) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 0; - RecordedPlayerBufferExecCompleted(); - } -} - -static void Intro_WaitForShinyAnimAndHealthbox(void) +static void Intro_WaitForShinyAnimAndHealthbox(u32 battler) { 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 (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) healthboxAnimDone = TRUE; } else { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy) { healthboxAnimDone = TRUE; } } - if (healthboxAnimDone && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim - && gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) + if (healthboxAnimDone && gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim + && gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim) { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); 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; - gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3; + gBattlerControllerFuncs[battler] = Intro_DelayAndEnd; } } else { if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) healthboxAnimDone = TRUE; } else { - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxSpriteIds[BATTLE_PARTNER(battler)]].callback == SpriteCallbackDummy) { healthboxAnimDone = TRUE; } @@ -265,55 +200,55 @@ static void Intro_WaitForShinyAnimAndHealthbox(void) if (healthboxAnimDone) { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].introEndDelay = 3; - gBattlerControllerFuncs[gActiveBattler] = Intro_DelayAndEnd; + gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3; + gBattlerControllerFuncs[battler] = Intro_DelayAndEnd; } } } -static void Intro_TryShinyAnimShowHealthbox(void) +static void Intro_TryShinyAnimShowHealthbox(u32 battler) { bool32 bgmRestored = FALSE; - if (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_LEFT) + if (GetBattlerPosition(battler) == B_POSITION_PLAYER_LEFT) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) - TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) + TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]); - if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive) - TryShinyAnimation(BATTLE_PARTNER(gActiveBattler), &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]]); + if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive) + TryShinyAnimation(BATTLE_PARTNER(battler), &gPlayerParty[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)) { - UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); - StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL); + StartHealthboxSlideIn(BATTLE_PARTNER(battler)); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]); } - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = TRUE; + gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = TRUE; } - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].waitForCry - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].waitForCry + if (gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted + && !gBattleSpritesDataPtr->healthBoxesData[battler].waitForCry + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].waitForCry && !IsCryPlayingOrClearCrySongs()) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored) { 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); } else @@ -322,870 +257,117 @@ static void Intro_TryShinyAnimShowHealthbox(void) } } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].bgmRestored = TRUE; + gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = TRUE; bgmRestored = TRUE; } - if (bgmRestored && gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (bgmRestored && gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) { 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->healthBoxesData[gActiveBattler].bgmRestored = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].healthboxSlideInStarted = FALSE; - gBattlerControllerFuncs[gActiveBattler] = Intro_WaitForShinyAnimAndHealthbox; + gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].healthboxSlideInStarted = FALSE; + gBattlerControllerFuncs[battler] = Intro_WaitForShinyAnimAndHealthbox; } } -static void WaitForMonAnimAfterLoad(void) +static void WaitForMonAnimAfterLoad(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].animEnded && gSprites[gBattlerSpriteIds[gActiveBattler]].x2 == 0) - RecordedPlayerBufferExecCompleted(); + if (gSprites[gBattlerSpriteIds[battler]].animEnded && gSprites[gBattlerSpriteIds[battler]].x2 == 0) + RecordedPlayerBufferExecCompleted(battler); } -static void CompleteOnHealthbarDone(void) +static void SwitchIn_ShowSubstitute(u32 battler) { - s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0); - - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - - if (hpValue != -1) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); - } - else - { - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - RecordedPlayerBufferExecCompleted(); + CopyBattleSpriteInvisibility(battler); + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE); + + gBattlerControllerFuncs[battler] = SwitchIn_WaitAndEnd; } } -static void FreeMonSpriteAfterFaintAnim(void) +static void SwitchIn_WaitAndEnd(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].y + gSprites[gBattlerSpriteIds[gActiveBattler]].y2 > DISPLAY_HEIGHT) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) { - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - BattleGfxSfxDummy2(species); - FreeOamMatrix(gSprites[gBattlerSpriteIds[gActiveBattler]].oam.matrixNum); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - RecordedPlayerBufferExecCompleted(); + RecordedPlayerBufferExecCompleted(battler); } } -static void FreeMonSpriteAfterSwitchOutAnim(void) +static void SwitchIn_ShowHealthbox(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) + if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim) { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - RecordedPlayerBufferExecCompleted(); - } -} - -static void CompleteOnInactiveTextPrinter(void) -{ - if (!IsTextPrinterActive(B_WIN_MSG)) - RecordedPlayerBufferExecCompleted(); -} - -static void DoHitAnimBlinkSpriteEffect(void) -{ - u8 spriteId = gBattlerSpriteIds[gActiveBattler]; - - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = FALSE; - RecordedPlayerBufferExecCompleted(); - } - else - { - if ((gSprites[spriteId].data[1] % 4) == 0) - gSprites[spriteId].invisible ^= 1; - gSprites[spriteId].data[1]++; - } -} - -static void SwitchIn_ShowSubstitute(void) -{ - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - CopyBattleSpriteInvisibility(gActiveBattler); - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_WaitAndEnd; - } -} - -static void SwitchIn_WaitAndEnd(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - RecordedPlayerBufferExecCompleted(); - } -} - -static void SwitchIn_ShowHealthbox(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); CreateTask(Task_PlayerController_RestoreBgmAfterCry, 10); - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); + StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 0); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + 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 - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) { - TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]); } - if (gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) + if (gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) { - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_ShowHealthbox; + DestroySprite(&gSprites[gBattleControllerData[battler]]); + gBattlerControllerFuncs[battler] = SwitchIn_ShowHealthbox; } } -static void RecordedPlayerBufferExecCompleted(void) +static void RecordedPlayerBufferExecCompleted(u32 battler) { - gBattlerControllerFuncs[gActiveBattler] = RecordedPlayerBufferRunCommand; + gBattlerControllerFuncs[battler] = RecordedPlayerBufferRunCommand; if (gBattleTypeFlags & BATTLE_TYPE_LINK) { u8 playerId = GetMultiplayerId(); PrepareBufferDataTransferLink(2, 4, &playerId); - gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; + gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP; } else { - gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; + gBattleControllerExecFlags &= ~gBitTable[battler]; } } -static void CompleteOnFinishedStatusAnimation(void) +static void RecordedPlayerHandleLoadMonSprite(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive) - RecordedPlayerBufferExecCompleted(); + BtlController_HandleLoadMonSprite(battler, WaitForMonAnimAfterLoad); } -static void CompleteOnFinishedBattleAnimation(void) +static void RecordedPlayerHandleSwitchInAnim(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive) - RecordedPlayerBufferExecCompleted(); + BtlController_HandleSwitchInAnim(battler, TRUE, SwitchIn_TryShinyAnim); } -static void RecordedPlayerHandleGetMonData(void) -{ - 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 size = 0; - u8 monToCheck; - s32 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - size += CopyRecordedPlayerMonData(gBattlerPartyIndexes[gActiveBattler], monData); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - size += CopyRecordedPlayerMonData(i, monData + size); - monToCheck >>= 1; - } - } - BtlController_EmitDataTransfer(BUFFER_B, size, monData); - RecordedPlayerBufferExecCompleted(); -} - -static u32 CopyRecordedPlayerMonData(u8 monId, u8 *dst) -{ - struct BattlePokemon battleMon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - battleMon.species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); - battleMon.item = GetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM); - for (size = 0; size < MAX_MON_MOVES; size++) - { - battleMon.moves[size] = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + size); - battleMon.pp[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - } - battleMon.ppBonuses = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - battleMon.friendship = GetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP); - battleMon.experience = GetMonData(&gPlayerParty[monId], MON_DATA_EXP); - battleMon.hpIV = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - battleMon.attackIV = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - battleMon.defenseIV = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - battleMon.speedIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - battleMon.spAttackIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - battleMon.spDefenseIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - battleMon.personality = GetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY); - battleMon.status1 = GetMonData(&gPlayerParty[monId], MON_DATA_STATUS); - battleMon.level = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); - battleMon.hp = GetMonData(&gPlayerParty[monId], MON_DATA_HP); - battleMon.maxHP = GetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP); - battleMon.attack = GetMonData(&gPlayerParty[monId], MON_DATA_ATK); - battleMon.defense = GetMonData(&gPlayerParty[monId], MON_DATA_DEF); - battleMon.speed = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED); - battleMon.spAttack = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK); - battleMon.spDefense = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF); - battleMon.abilityNum = GetMonData(&gPlayerParty[monId], MON_DATA_ABILITY_NUM); - battleMon.otId = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID); - battleMon.metLevel = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL); - GetMonData(&gPlayerParty[monId], MON_DATA_NICKNAME, nickname); - StringCopy_Nickname(battleMon.nickname, nickname); - GetMonData(&gPlayerParty[monId], MON_DATA_OT_NAME, battleMon.otName); - src = (u8 *)&battleMon; - for (size = 0; size < sizeof(battleMon); size++) - dst[size] = src[size]; - break; - case REQUEST_SPECIES_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_HELDITEM_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MOVES_PP_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - { - moveData.moves[size] = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - src = (u8 *)(&moveData); - for (size = 0; size < sizeof(moveData); size++) - dst[size] = src[size]; - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_PP_DATA_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - dst[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - dst[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - size++; - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE); - size = 1; - break; - case REQUEST_OTID_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_EXP_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_EXP); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_HP_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_EV); - size = 1; - break; - case REQUEST_ATK_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_EV); - size = 1; - break; - case REQUEST_DEF_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_EV); - size = 1; - break; - case REQUEST_SPEED_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_EV); - size = 1; - break; - case REQUEST_SPATK_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_EV); - size = 1; - break; - case REQUEST_SPDEF_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_EV); - size = 1; - break; - case REQUEST_FRIENDSHIP_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP); - size = 1; - break; - case REQUEST_POKERUS_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_POKERUS); - size = 1; - break; - case REQUEST_MET_LOCATION_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LOCATION); - size = 1; - break; - case REQUEST_MET_LEVEL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL); - size = 1; - break; - case REQUEST_MET_GAME_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_GAME); - size = 1; - break; - case REQUEST_POKEBALL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_POKEBALL); - size = 1; - break; - case REQUEST_ALL_IVS_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - dst[1] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - dst[2] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - dst[3] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - dst[4] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - dst[5] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - size = 6; - break; - case REQUEST_HP_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - size = 1; - break; - case REQUEST_ATK_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - size = 1; - break; - case REQUEST_DEF_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - size = 1; - break; - case REQUEST_SPEED_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - size = 1; - break; - case REQUEST_SPATK_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - size = 1; - break; - case REQUEST_SPDEF_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - size = 1; - break; - case REQUEST_PERSONALITY_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_CHECKSUM_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_CHECKSUM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_STATUS_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_STATUS); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_LEVEL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); - size = 1; - break; - case REQUEST_HP_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MAX_HP_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_ATK_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_ATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_DEF_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_DEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPEED_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPATK_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPDEF_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_COOL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_COOL); - size = 1; - break; - case REQUEST_BEAUTY_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY); - size = 1; - break; - case REQUEST_CUTE_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_CUTE); - size = 1; - break; - case REQUEST_SMART_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SMART); - size = 1; - break; - case REQUEST_TOUGH_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_TOUGH); - size = 1; - break; - case REQUEST_SHEEN_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SHEEN); - size = 1; - break; - case REQUEST_COOL_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_COOL_RIBBON); - size = 1; - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case REQUEST_CUTE_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case REQUEST_SMART_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SMART_RIBBON); - size = 1; - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - - return size; -} - -static void RecordedPlayerHandleGetRawMonData(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleSetMonData(void) -{ - u8 monToCheck; - u8 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - SetRecordedPlayerMonData(gBattlerPartyIndexes[gActiveBattler]); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - SetRecordedPlayerMonData(i); - monToCheck >>= 1; - } - } - RecordedPlayerBufferExecCompleted(); -} - -static void SetRecordedPlayerMonData(u8 monId) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleResources->bufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleResources->bufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - { - u8 iv; - - SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gPlayerParty[monId], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gPlayerParty[monId], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gPlayerParty[monId], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gPlayerParty[monId], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gPlayerParty[monId], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case REQUEST_SPECIES_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HELDITEM_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MOVES_PP_BATTLE: - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PP_DATA_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PP1, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP2, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP3, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP4, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &gBattleResources->bufferA[gActiveBattler][7]); - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_OTID_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_OT_ID, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_EXP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_FRIENDSHIP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKERUS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_POKERUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LOCATION_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_LOCATION, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LEVEL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_GAME_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_GAME, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKEBALL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_POKEBALL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ALL_IVS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][7]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][8]); - break; - case REQUEST_HP_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PERSONALITY_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CHECKSUM_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CHECKSUM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_STATUS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_STATUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_LEVEL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MAX_HP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_COOL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CUTE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SMART, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_TOUGH, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SHEEN_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SHEEN, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_COOL_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CUTE_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SMART_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_TOUGH_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - } - - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); -} - -static void RecordedPlayerHandleSetRawMonData(void) -{ - u8 *dst = (u8 *)&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleResources->bufferA[gActiveBattler][1]; - u8 i; - - for (i = 0; i < gBattleResources->bufferA[gActiveBattler][2]; i++) - dst[i] = gBattleResources->bufferA[gActiveBattler][3 + i]; - - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleLoadMonSprite(void) -{ - u16 species; - - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(gActiveBattler)); - - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(gActiveBattler, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(gActiveBattler), - GetBattlerSpriteSubpriority(gActiveBattler)); - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); - gBattlerControllerFuncs[gActiveBattler] = WaitForMonAnimAfterLoad; -} - -static void RecordedPlayerHandleSwitchInAnim(void) -{ - ClearTemporarySpeciesSpriteData(gActiveBattler, gBattleResources->bufferA[gActiveBattler][2]); - gBattlerPartyIndexes[gActiveBattler] = gBattleResources->bufferA[gActiveBattler][1]; - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - StartSendOutAnim(gActiveBattler, gBattleResources->bufferA[gActiveBattler][2]); - gBattlerControllerFuncs[gActiveBattler] = SwitchIn_TryShinyAnim; -} - -static void StartSendOutAnim(u8 battlerId, bool8 dontClearSubstituteBit) -{ - u16 species; - - ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit); - gBattlerPartyIndexes[battlerId] = gBattleResources->bufferA[battlerId][1]; - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); - gBattleControllerData[battlerId] = CreateInvisibleSpriteWithCallback(SpriteCB_WaitForBattlerBallReleaseAnim); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battlerId)); - - gBattlerSpriteIds[battlerId] = CreateSprite( - &gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(battlerId), - GetBattlerSpriteSubpriority(battlerId)); - - gSprites[gBattleControllerData[battlerId]].data[1] = gBattlerSpriteIds[battlerId]; - gSprites[gBattleControllerData[battlerId]].data[2] = battlerId; - - gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId; - gSprites[gBattlerSpriteIds[battlerId]].data[2] = species; - gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId; - - StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], 0); - - gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE; - gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy; - - gSprites[gBattleControllerData[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT); -} - -static void RecordedPlayerHandleReturnMonToBall(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] == 0) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = DoSwitchOutAnimation; - } - else - { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - RecordedPlayerBufferExecCompleted(); - } -} - -static void DoSwitchOutAnimation(void) -{ - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SWITCH_OUT_PLAYER_MON); - gBattlerControllerFuncs[gActiveBattler] = FreeMonSpriteAfterSwitchOutAnim; - } - break; - } -} - -#define sSpeedX data[0] - -static void RecordedPlayerHandleDrawTrainerPic(void) +static void RecordedPlayerHandleDrawTrainerPic(u32 battler) { + bool32 isFrontPic; s16 xPos, yPos; u32 trainerPicId; @@ -1203,7 +385,7 @@ static void RecordedPlayerHandleDrawTrainerPic(void) if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { - if ((GetBattlerPosition(gActiveBattler) & BIT_FLANK) != 0) // second mon + if ((GetBattlerPosition(battler) & BIT_FLANK) != 0) // second mon xPos = 90; else // first mon xPos = 32; @@ -1226,177 +408,30 @@ static void RecordedPlayerHandleDrawTrainerPic(void) } if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) - { - trainerPicId = PlayerGenderToFrontTrainerPicId(gSaveBlock2Ptr->playerGender); - DecompressTrainerFrontPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerFront(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, xPos, yPos, GetBattlerSpriteSubpriority(gActiveBattler)); - - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].y2 = 48; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = -2; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineMode = ST_OAM_AFFINE_OFF; - gSprites[gBattlerSpriteIds[gActiveBattler]].hFlip = 1; - } + isFrontPic = TRUE; else - { - DecompressTrainerBackPic(trainerPicId, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, xPos, yPos, GetBattlerSpriteSubpriority(gActiveBattler)); + isFrontPic = FALSE; - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = -2; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - } - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy; + BtlController_HandleDrawTrainerPic(battler, trainerPicId, isFrontPic, xPos, yPos, -1); } -#undef sSpeedX - -static void RecordedPlayerHandleTrainerSlide(void) +static void RecordedPlayerHandleTrainerSlideBack(u32 battler) { - RecordedPlayerBufferExecCompleted(); + BtlController_HandleTrainerSlideBack(battler, 35, FALSE); } -static void RecordedPlayerHandleTrainerSlideBack(void) +static void RecordedPlayerHandleMoveAnimation(u32 battler) { - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCallbackDummy); - gBattlerControllerFuncs[gActiveBattler] = FreeTrainerSpriteAfterSlide; + BtlController_HandleMoveAnimation(battler, FALSE); } -#define sSpeedX data[1] -#define sSpeedY data[2] - -static void RecordedPlayerHandleFaintAnimation(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState == 0) - { - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState++; - } - else - { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - PlaySE12WithPanning(SE_FAINT, -64); - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = 0; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedY = 5; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_FaintSlideAnim; - gBattlerControllerFuncs[gActiveBattler] = FreeMonSpriteAfterFaintAnim; - } - } -} - -#undef sSpeedX -#undef sSpeedY - -static void RecordedPlayerHandlePaletteFade(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleSuccessBallThrowAnim(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleBallThrowAnim(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandlePause(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleMoveAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleResources->bufferA[gActiveBattler][3]; - gAnimMovePower = gBattleResources->bufferA[gActiveBattler][4] | (gBattleResources->bufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleResources->bufferA[gActiveBattler][6] | (gBattleResources->bufferA[gActiveBattler][7] << 8) | (gBattleResources->bufferA[gActiveBattler][8] << 16) | (gBattleResources->bufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleResources->bufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleResources->bufferA[gActiveBattler][12] | (gBattleResources->bufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - gTransformedOtIds[gActiveBattler] = gAnimDisableStructPtr->transformedMonOtId; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = RecordedPlayerDoMoveAnimation; - } -} - -static void RecordedPlayerDoMoveAnimation(void) -{ - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - u8 multihit = gBattleResources->bufferA[gActiveBattler][11]; - - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute - && !gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8) - { - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 1; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF); - DoMoveAnim(move); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL); - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute && multihit < 2) - { - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - gBattleSpritesDataPtr->battlerData[gActiveBattler].flag_x8 = 0; - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 3; - } - break; - case 3: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - CopyAllBattleSpritesInvisibilities(); - TrySetBehindSubstituteSpriteBit(gActiveBattler, gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - RecordedPlayerBufferExecCompleted(); - } - break; - } -} - -static void RecordedPlayerHandlePrintString(void) +static void RecordedPlayerHandlePrintString(u32 battler) { u16 *stringId; gBattle_BG0_X = 0; gBattle_BG0_Y = 0; - stringId = (u16 *)(&gBattleResources->bufferA[gActiveBattler][2]); + stringId = (u16 *)(&gBattleResources->bufferA[battler][2]); BufferStringBattle(*stringId); if (gTestRunnerEnabled) @@ -1404,48 +439,38 @@ static void RecordedPlayerHandlePrintString(void) TestRunner_Battle_RecordMessage(gDisplayedStringBattle); if (gTestRunnerHeadless) { - RecordedPlayerBufferExecCompleted(); + RecordedPlayerBufferExecCompleted(battler); return; } } BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter; + gBattlerControllerFuncs[battler] = Controller_WaitForString; } -static void RecordedPlayerHandlePrintSelectionString(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void ChooseActionInBattlePalace(void) +static void ChooseActionInBattlePalace(u32 battler) { if (gBattleCommunication[4] >= gBattlersCount / 2) { - BtlController_EmitTwoReturnValues(BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_BATTLE_PALACE_ACTION, gActiveBattler), 0); - RecordedPlayerBufferExecCompleted(); + BtlController_EmitTwoReturnValues(BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_BATTLE_PALACE_ACTION, battler), 0); + RecordedPlayerBufferExecCompleted(battler); } } -static void RecordedPlayerHandleChooseAction(void) +static void RecordedPlayerHandleChooseAction(u32 battler) { if (gBattleTypeFlags & BATTLE_TYPE_PALACE) { - gBattlerControllerFuncs[gActiveBattler] = ChooseActionInBattlePalace; + gBattlerControllerFuncs[battler] = ChooseActionInBattlePalace; } else { - BtlController_EmitTwoReturnValues(BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_ACTION_TYPE, gActiveBattler), 0); - RecordedPlayerBufferExecCompleted(); + BtlController_EmitTwoReturnValues(BUFFER_B, RecordedBattle_GetBattlerAction(RECORDED_ACTION_TYPE, battler), 0); + RecordedPlayerBufferExecCompleted(battler); } } -static void RecordedPlayerHandleYesNoBox(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleChooseMove(void) +static void RecordedPlayerHandleChooseMove(u32 battler) { if (gBattleTypeFlags & BATTLE_TYPE_PALACE) { @@ -1453,379 +478,103 @@ static void RecordedPlayerHandleChooseMove(void) } else { - u8 moveId = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, gActiveBattler); - u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, gActiveBattler); + u8 moveId = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, battler); + u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, battler); 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 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, gActiveBattler); - gBattleStruct->chosenItem[gActiveBattler] = (byte1 << 8) | byte2; - gBattleStruct->itemPartyIndex[gActiveBattler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_TARGET, gActiveBattler); - gBattleStruct->itemMoveIndex[gActiveBattler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_MOVE, gActiveBattler); - BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[gActiveBattler]); - RecordedPlayerBufferExecCompleted(); + u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, battler); + u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, battler); + gBattleStruct->chosenItem[battler] = (byte1 << 8) | byte2; + gBattleStruct->itemPartyIndex[battler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_TARGET, battler); + gBattleStruct->itemMoveIndex[battler] = RecordedBattle_GetBattlerAction(RECORDED_ITEM_MOVE, battler); + BtlController_EmitOneReturnValue(BUFFER_B, gBattleStruct->chosenItem[battler]); + RecordedPlayerBufferExecCompleted(battler); } -static void RecordedPlayerHandleChoosePokemon(void) +static void RecordedPlayerHandleChoosePokemon(u32 battler) { - *(gBattleStruct->monToSwitchIntoId + gActiveBattler) = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, gActiveBattler); - gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[gActiveBattler]; // Revival Blessing - BtlController_EmitChosenMonReturnValue(BUFFER_B, *(gBattleStruct->monToSwitchIntoId + gActiveBattler), NULL); - RecordedPlayerBufferExecCompleted(); + *(gBattleStruct->monToSwitchIntoId + battler) = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, battler); + gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[battler]; // Revival Blessing + BtlController_EmitChosenMonReturnValue(BUFFER_B, *(gBattleStruct->monToSwitchIntoId + battler), NULL); + RecordedPlayerBufferExecCompleted(battler); } -static void RecordedPlayerHandleCmd23(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleHealthBarUpdate(void) +static void RecordedPlayerHandleHealthBarUpdate(u32 battler) { s16 hpVal; s32 maxHP, curHP; 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); - curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); + maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP); + curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_HP); if (hpVal != INSTANT_HP_BAR_DROP) { - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, curHP, hpVal); - TestRunner_Battle_RecordHP(gActiveBattler, curHP, min(maxHP, max(0, curHP - hpVal))); + SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, curHP, hpVal); + TestRunner_Battle_RecordHP(battler, curHP, min(maxHP, max(0, curHP - hpVal))); } else { - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, 0, maxHP); - TestRunner_Battle_RecordHP(gActiveBattler, curHP, 0); + SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, 0, hpVal); + UpdateHpTextInHealthbox(gHealthboxSpriteIds[battler], HP_CURRENT, 0, maxHP); + TestRunner_Battle_RecordHP(battler, curHP, 0); } - gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone; + gBattlerControllerFuncs[battler] = Controller_WaitForHealthBar; } -static void RecordedPlayerHandleExpUpdate(void) +static void RecordedPlayerHandleStatusIconUpdate(u32 battler) { - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleStatusIconUpdate(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) + if (!IsBattleSEPlaying(battler)) { - u8 battlerId; - - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON); - battlerId = gActiveBattler; - gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0; - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - + DoStatusIconUpdate(battler); if (gTestRunnerEnabled) - TestRunner_Battle_RecordStatus1(battlerId, GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_STATUS)); + TestRunner_Battle_RecordStatus1(battler, GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_STATUS)); } } -static void RecordedPlayerHandleStatusAnimation(void) +static void RecordedPlayerHandleStatusAnimation(u32 battler) { - if (!IsBattleSEPlaying(gActiveBattler)) - { - InitAndLaunchChosenStatusAnimation(gBattleResources->bufferA[gActiveBattler][1], - gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8) | (gBattleResources->bufferA[gActiveBattler][4] << 16) | (gBattleResources->bufferA[gActiveBattler][5] << 24)); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation; - } + BtlController_HandleStatusAnimation(battler); } -static void RecordedPlayerHandleStatusXor(void) +static void RecordedPlayerHandleIntroTrainerBallThrow(u32 battler) { - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleDataTransfer(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleDMA3Transfer(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandlePlayBGM(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleCmd32(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleTwoReturnValues(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleChosenMonReturnValue(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleOneReturnValue(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleOneReturnValue_Duplicate(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleClearUnkVar(void) -{ - gUnusedControllerStruct.unk = 0; - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleSetUnkVar(void) -{ - gUnusedControllerStruct.unk = gBattleResources->bufferA[gActiveBattler][1]; - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleClearUnkFlag(void) -{ - gUnusedControllerStruct.flag = 0; - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleToggleUnkFlag(void) -{ - gUnusedControllerStruct.flag ^= 1; - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleHitAnimation(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].invisible == TRUE) - { - RecordedPlayerBufferExecCompleted(); - } - else - { - gDoingBattleAnim = TRUE; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[1] = 0; - DoHitAnimHealthboxEffect(gActiveBattler); - gBattlerControllerFuncs[gActiveBattler] = DoHitAnimBlinkSpriteEffect; - } -} - -static void RecordedPlayerHandleCantSwitch(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandlePlaySE(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - pan = SOUND_PAN_ATTACKER; - else - pan = SOUND_PAN_TARGET; - - PlaySE12WithPanning(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8), pan); - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandlePlayFanfareOrBGM(void) -{ - if (gBattleResources->bufferA[gActiveBattler][3]) - { - BattleStopLowHpSound(); - PlayBGM(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - else - { - PlayFanfare(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleFaintingCry(void) -{ - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - PlayCry_ByMode(species, -25, CRY_MODE_FAINT); - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleIntroSlide(void) -{ - HandleIntroSlide(gBattleResources->bufferA[gActiveBattler][1]); - gIntroSlideFlags |= 1; - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleIntroTrainerBallThrow(void) -{ - u8 paletteNum; - u8 taskId; u32 trainerPicId; + const u32 *trainerPal; - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 50; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[5] = gActiveBattler; - - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCB_FreePlayerSpriteLoadMonSprite); - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 1); - - paletteNum = AllocSpritePalette(0xD6F9); if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK) - trainerPicId = gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender; + trainerPicId = gLinkPlayers[GetBattlerMultiplayerId(battler)].gender + TRAINER_BACK_PIC_BRENDAN; else - trainerPicId = gSaveBlock2Ptr->playerGender; + trainerPicId = gSaveBlock2Ptr->playerGender + TRAINER_BACK_PIC_BRENDAN; - LoadCompressedPalette(gTrainerBackPicPaletteTable[trainerPicId].data, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP); - - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = paletteNum; - - taskId = CreateTask(Task_StartSendOutAnim, 5); - gTasks[taskId].data[0] = gActiveBattler; - - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - - gBattleSpritesDataPtr->animationData->introAnimActive = TRUE; - gBattlerControllerFuncs[gActiveBattler] = RecordedPlayerDummy; + trainerPal = gTrainerFrontPicPaletteTable[trainerPicId].data; + BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F9, trainerPal, 24, Intro_TryShinyAnimShowHealthbox); } -static void Task_StartSendOutAnim(u8 taskId) +static void RecordedPlayerHandleDrawPartyStatusSummary(u32 battler) { - if (gTasks[taskId].data[1] < 24) - { - gTasks[taskId].data[1]++; - } - else - { - u8 savedActiveBank = gActiveBattler; - - gActiveBattler = gTasks[taskId].data[0]; - if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - } - else - { - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler ^= BIT_FLANK; - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - StartSendOutAnim(gActiveBattler, FALSE); - gActiveBattler ^= BIT_FLANK; - } - gBattlerControllerFuncs[gActiveBattler] = Intro_TryShinyAnimShowHealthbox; - gActiveBattler = savedActiveBank; - DestroyTask(taskId); - } + BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, TRUE); } -static void RecordedPlayerHandleDrawPartyStatusSummary(void) +static void RecordedPlayerHandleBattleAnimation(u32 battler) { - if (gBattleResources->bufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - { - RecordedPlayerBufferExecCompleted(); - } - else - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown = 1; - gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleResources->bufferA[gActiveBattler][4], gBattleResources->bufferA[gActiveBattler][1], gBattleResources->bufferA[gActiveBattler][2]); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - - if (gBattleResources->bufferA[gActiveBattler][2] != 0) - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 93; - - gBattlerControllerFuncs[gActiveBattler] = EndDrawPartyStatusSummary; - } + BtlController_HandleBattleAnimation(battler, FALSE, FALSE); } -static void EndDrawPartyStatusSummary(void) +static void RecordedPlayerHandleEndLinkBattle(u32 battler) { - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer++ > 92) - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusDelayTimer = 0; - RecordedPlayerBufferExecCompleted(); - } -} - -static void RecordedPlayerHandleHidePartyStatusSummary(void) -{ - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleEndBounceEffect(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleSpriteInvisibility(void) -{ - if (IsBattlerSpritePresent(gActiveBattler)) - { - gSprites[gBattlerSpriteIds[gActiveBattler]].invisible = gBattleResources->bufferA[gActiveBattler][1]; - CopyBattleSpriteInvisibility(gActiveBattler); - } - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleBattleAnimation(void) -{ - if (!IsBattleSEPlaying(gActiveBattler)) - { - u8 animationId = gBattleResources->bufferA[gActiveBattler][1]; - u16 argument = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (TryHandleLaunchBattleTableAnimation(gActiveBattler, gActiveBattler, gActiveBattler, animationId, argument)) - RecordedPlayerBufferExecCompleted(); - else - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; - } -} - -static void RecordedPlayerHandleLinkStandbyMsg(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleResetActionMoveSelection(void) -{ - RecordedPlayerBufferExecCompleted(); -} - -static void RecordedPlayerHandleEndLinkBattle(void) -{ - gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; + gBattleOutcome = gBattleResources->bufferA[battler][1]; FadeOutMapMusic(5); BeginFastPaletteFade(3); - RecordedPlayerBufferExecCompleted(); - gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; -} - -static void RecordedPlayerCmdEnd(void) -{ + RecordedPlayerBufferExecCompleted(battler); + gBattlerControllerFuncs[battler] = SetBattleEndCallbacks; } diff --git a/src/battle_controller_safari.c b/src/battle_controller_safari.c index 1542838db..5f9183f1b 100644 --- a/src/battle_controller_safari.c +++ b/src/battle_controller_safari.c @@ -22,160 +22,112 @@ #include "window.h" #include "constants/battle_anim.h" #include "constants/songs.h" +#include "constants/trainers.h" #include "constants/rgb.h" -static void SafariHandleGetMonData(void); -static void SafariHandleGetRawMonData(void); -static void SafariHandleSetMonData(void); -static void SafariHandleSetRawMonData(void); -static void SafariHandleLoadMonSprite(void); -static void SafariHandleSwitchInAnim(void); -static void SafariHandleReturnMonToBall(void); -static void SafariHandleDrawTrainerPic(void); -static void SafariHandleTrainerSlide(void); -static void SafariHandleTrainerSlideBack(void); -static void SafariHandleFaintAnimation(void); -static void SafariHandlePaletteFade(void); -static void SafariHandleSuccessBallThrowAnim(void); -static void SafariHandleBallThrowAnim(void); -static void SafariHandlePause(void); -static void SafariHandleMoveAnimation(void); -static void SafariHandlePrintString(void); -static void SafariHandlePrintSelectionString(void); -static void SafariHandleChooseAction(void); -static void SafariHandleYesNoBox(void); -static void SafariHandleChooseMove(void); -static void SafariHandleChooseItem(void); -static void SafariHandleChoosePokemon(void); -static void SafariHandleCmd23(void); -static void SafariHandleHealthBarUpdate(void); -static void SafariHandleExpUpdate(void); -static void SafariHandleStatusIconUpdate(void); -static void SafariHandleStatusAnimation(void); -static void SafariHandleStatusXor(void); -static void SafariHandleDataTransfer(void); -static void SafariHandleDMA3Transfer(void); -static void SafariHandlePlayBGM(void); -static void SafariHandleCmd32(void); -static void SafariHandleTwoReturnValues(void); -static void SafariHandleChosenMonReturnValue(void); -static void SafariHandleOneReturnValue(void); -static void SafariHandleOneReturnValue_Duplicate(void); -static void SafariHandleClearUnkVar(void); -static void SafariHandleSetUnkVar(void); -static void SafariHandleClearUnkFlag(void); -static void SafariHandleToggleUnkFlag(void); -static void SafariHandleHitAnimation(void); -static void SafariHandleCantSwitch(void); -static void SafariHandlePlaySE(void); -static void SafariHandlePlayFanfareOrBGM(void); -static void SafariHandleFaintingCry(void); -static void SafariHandleIntroSlide(void); -static void SafariHandleIntroTrainerBallThrow(void); -static void SafariHandleDrawPartyStatusSummary(void); -static void SafariHandleHidePartyStatusSummary(void); -static void SafariHandleEndBounceEffect(void); -static void SafariHandleSpriteInvisibility(void); -static void SafariHandleBattleAnimation(void); -static void SafariHandleLinkStandbyMsg(void); -static void SafariHandleResetActionMoveSelection(void); -static void SafariHandleEndLinkBattle(void); -static void SafariHandleBattleDebug(void); -static void SafariCmdEnd(void); +static void SafariHandleDrawTrainerPic(u32 battler); +static void SafariHandleSuccessBallThrowAnim(u32 battler); +static void SafariHandleBallThrowAnim(u32 battler); +static void SafariHandlePrintString(u32 battler); +static void SafariHandlePrintSelectionString(u32 battler); +static void SafariHandleChooseAction(u32 battler); +static void SafariHandleChooseItem(u32 battler); +static void SafariHandleStatusIconUpdate(u32 battler); +static void SafariHandleFaintingCry(u32 battler); +static void SafariHandleIntroTrainerBallThrow(u32 battler); +static void SafariHandleBattleAnimation(u32 battler); +static void SafariHandleEndLinkBattle(u32 battler); -static void SafariBufferRunCommand(void); -static void SafariBufferExecCompleted(void); -static void CompleteWhenChosePokeblock(void); +static void SafariBufferRunCommand(u32 battler); +static void SafariBufferExecCompleted(u32 battler); +static void CompleteWhenChosePokeblock(u32 battler); -static void (*const sSafariBufferCommands[CONTROLLER_CMDS_COUNT])(void) = +static void (*const sSafariBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) = { - [CONTROLLER_GETMONDATA] = SafariHandleGetMonData, - [CONTROLLER_GETRAWMONDATA] = SafariHandleGetRawMonData, - [CONTROLLER_SETMONDATA] = SafariHandleSetMonData, - [CONTROLLER_SETRAWMONDATA] = SafariHandleSetRawMonData, - [CONTROLLER_LOADMONSPRITE] = SafariHandleLoadMonSprite, - [CONTROLLER_SWITCHINANIM] = SafariHandleSwitchInAnim, - [CONTROLLER_RETURNMONTOBALL] = SafariHandleReturnMonToBall, + [CONTROLLER_GETMONDATA] = BtlController_Empty, + [CONTROLLER_GETRAWMONDATA] = BtlController_Empty, + [CONTROLLER_SETMONDATA] = BtlController_Empty, + [CONTROLLER_SETRAWMONDATA] = BtlController_Empty, + [CONTROLLER_LOADMONSPRITE] = BtlController_Empty, + [CONTROLLER_SWITCHINANIM] = BtlController_Empty, + [CONTROLLER_RETURNMONTOBALL] = BtlController_Empty, [CONTROLLER_DRAWTRAINERPIC] = SafariHandleDrawTrainerPic, - [CONTROLLER_TRAINERSLIDE] = SafariHandleTrainerSlide, - [CONTROLLER_TRAINERSLIDEBACK] = SafariHandleTrainerSlideBack, - [CONTROLLER_FAINTANIMATION] = SafariHandleFaintAnimation, - [CONTROLLER_PALETTEFADE] = SafariHandlePaletteFade, + [CONTROLLER_TRAINERSLIDE] = BtlController_Empty, + [CONTROLLER_TRAINERSLIDEBACK] = BtlController_Empty, + [CONTROLLER_FAINTANIMATION] = BtlController_Empty, + [CONTROLLER_PALETTEFADE] = BtlController_Empty, [CONTROLLER_SUCCESSBALLTHROWANIM] = SafariHandleSuccessBallThrowAnim, [CONTROLLER_BALLTHROWANIM] = SafariHandleBallThrowAnim, - [CONTROLLER_PAUSE] = SafariHandlePause, - [CONTROLLER_MOVEANIMATION] = SafariHandleMoveAnimation, + [CONTROLLER_PAUSE] = BtlController_Empty, + [CONTROLLER_MOVEANIMATION] = BtlController_Empty, [CONTROLLER_PRINTSTRING] = SafariHandlePrintString, [CONTROLLER_PRINTSTRINGPLAYERONLY] = SafariHandlePrintSelectionString, [CONTROLLER_CHOOSEACTION] = SafariHandleChooseAction, - [CONTROLLER_YESNOBOX] = SafariHandleYesNoBox, - [CONTROLLER_CHOOSEMOVE] = SafariHandleChooseMove, + [CONTROLLER_YESNOBOX] = BtlController_Empty, + [CONTROLLER_CHOOSEMOVE] = BtlController_Empty, [CONTROLLER_OPENBAG] = SafariHandleChooseItem, - [CONTROLLER_CHOOSEPOKEMON] = SafariHandleChoosePokemon, - [CONTROLLER_23] = SafariHandleCmd23, - [CONTROLLER_HEALTHBARUPDATE] = SafariHandleHealthBarUpdate, - [CONTROLLER_EXPUPDATE] = SafariHandleExpUpdate, + [CONTROLLER_CHOOSEPOKEMON] = BtlController_Empty, + [CONTROLLER_23] = BtlController_Empty, + [CONTROLLER_HEALTHBARUPDATE] = BtlController_Empty, + [CONTROLLER_EXPUPDATE] = BtlController_Empty, [CONTROLLER_STATUSICONUPDATE] = SafariHandleStatusIconUpdate, - [CONTROLLER_STATUSANIMATION] = SafariHandleStatusAnimation, - [CONTROLLER_STATUSXOR] = SafariHandleStatusXor, - [CONTROLLER_DATATRANSFER] = SafariHandleDataTransfer, - [CONTROLLER_DMA3TRANSFER] = SafariHandleDMA3Transfer, - [CONTROLLER_PLAYBGM] = SafariHandlePlayBGM, - [CONTROLLER_32] = SafariHandleCmd32, - [CONTROLLER_TWORETURNVALUES] = SafariHandleTwoReturnValues, - [CONTROLLER_CHOSENMONRETURNVALUE] = SafariHandleChosenMonReturnValue, - [CONTROLLER_ONERETURNVALUE] = SafariHandleOneReturnValue, - [CONTROLLER_ONERETURNVALUE_DUPLICATE] = SafariHandleOneReturnValue_Duplicate, - [CONTROLLER_CLEARUNKVAR] = SafariHandleClearUnkVar, - [CONTROLLER_SETUNKVAR] = SafariHandleSetUnkVar, - [CONTROLLER_CLEARUNKFLAG] = SafariHandleClearUnkFlag, - [CONTROLLER_TOGGLEUNKFLAG] = SafariHandleToggleUnkFlag, - [CONTROLLER_HITANIMATION] = SafariHandleHitAnimation, - [CONTROLLER_CANTSWITCH] = SafariHandleCantSwitch, - [CONTROLLER_PLAYSE] = SafariHandlePlaySE, - [CONTROLLER_PLAYFANFAREORBGM] = SafariHandlePlayFanfareOrBGM, + [CONTROLLER_STATUSANIMATION] = BtlController_Empty, + [CONTROLLER_STATUSXOR] = BtlController_Empty, + [CONTROLLER_DATATRANSFER] = BtlController_Empty, + [CONTROLLER_DMA3TRANSFER] = BtlController_Empty, + [CONTROLLER_PLAYBGM] = BtlController_Empty, + [CONTROLLER_32] = BtlController_Empty, + [CONTROLLER_TWORETURNVALUES] = BtlController_Empty, + [CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, + [CONTROLLER_CLEARUNKVAR] = BtlController_Empty, + [CONTROLLER_SETUNKVAR] = BtlController_Empty, + [CONTROLLER_CLEARUNKFLAG] = BtlController_Empty, + [CONTROLLER_TOGGLEUNKFLAG] = BtlController_Empty, + [CONTROLLER_HITANIMATION] = BtlController_Empty, + [CONTROLLER_CANTSWITCH] = BtlController_Empty, + [CONTROLLER_PLAYSE] = BtlController_HandlePlaySE, + [CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, [CONTROLLER_FAINTINGCRY] = SafariHandleFaintingCry, - [CONTROLLER_INTROSLIDE] = SafariHandleIntroSlide, + [CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, [CONTROLLER_INTROTRAINERBALLTHROW] = SafariHandleIntroTrainerBallThrow, - [CONTROLLER_DRAWPARTYSTATUSSUMMARY] = SafariHandleDrawPartyStatusSummary, - [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = SafariHandleHidePartyStatusSummary, - [CONTROLLER_ENDBOUNCE] = SafariHandleEndBounceEffect, - [CONTROLLER_SPRITEINVISIBILITY] = SafariHandleSpriteInvisibility, + [CONTROLLER_DRAWPARTYSTATUSSUMMARY] = BtlController_Empty, + [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_Empty, + [CONTROLLER_ENDBOUNCE] = BtlController_Empty, + [CONTROLLER_SPRITEINVISIBILITY] = BtlController_Empty, [CONTROLLER_BATTLEANIMATION] = SafariHandleBattleAnimation, - [CONTROLLER_LINKSTANDBYMSG] = SafariHandleLinkStandbyMsg, - [CONTROLLER_RESETACTIONMOVESELECTION] = SafariHandleResetActionMoveSelection, + [CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty, + [CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, [CONTROLLER_ENDLINKBATTLE] = SafariHandleEndLinkBattle, - [CONTROLLER_DEBUGMENU] = SafariHandleBattleDebug, - [CONTROLLER_TERMINATOR_NOP] = SafariCmdEnd + [CONTROLLER_DEBUGMENU] = BtlController_Empty, + [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop }; -static void SpriteCB_Null4(void) +void SetControllerToSafari(u32 battler) { + gBattlerControllerEndFuncs[battler] = SafariBufferExecCompleted; + gBattlerControllerFuncs[battler] = SafariBufferRunCommand; } -void SetControllerToSafari(void) +static void SafariBufferRunCommand(u32 battler) { - gBattlerControllerFuncs[gActiveBattler] = SafariBufferRunCommand; -} - -static void SafariBufferRunCommand(void) -{ - if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) + if (gBattleControllerExecFlags & gBitTable[battler]) { - if (gBattleResources->bufferA[gActiveBattler][0] < ARRAY_COUNT(sSafariBufferCommands)) - sSafariBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); + if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sSafariBufferCommands)) + sSafariBufferCommands[gBattleResources->bufferA[battler][0]](battler); else - SafariBufferExecCompleted(); + SafariBufferExecCompleted(battler); } } -static void HandleInputChooseAction(void) +static void HandleInputChooseAction(u32 battler) { if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); - switch (gActionSelectionCursor[gActiveBattler]) + switch (gActionSelectionCursor[battler]) { case 0: BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SAFARI_BALL, 0); @@ -190,69 +142,57 @@ static void HandleInputChooseAction(void) BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_SAFARI_RUN, 0); break; } - SafariBufferExecCompleted(); + SafariBufferExecCompleted(battler); } else if (JOY_NEW(DPAD_LEFT)) { - if (gActionSelectionCursor[gActiveBattler] & 1) + if (gActionSelectionCursor[battler] & 1) { PlaySE(SE_SELECT); - ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 1; - ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); + ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]); + gActionSelectionCursor[battler] ^= 1; + ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); } } else if (JOY_NEW(DPAD_RIGHT)) { - if (!(gActionSelectionCursor[gActiveBattler] & 1)) + if (!(gActionSelectionCursor[battler] & 1)) { PlaySE(SE_SELECT); - ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 1; - ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); + ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]); + gActionSelectionCursor[battler] ^= 1; + ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); } } else if (JOY_NEW(DPAD_UP)) { - if (gActionSelectionCursor[gActiveBattler] & 2) + if (gActionSelectionCursor[battler] & 2) { PlaySE(SE_SELECT); - ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 2; - ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); + ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]); + gActionSelectionCursor[battler] ^= 2; + ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); } } else if (JOY_NEW(DPAD_DOWN)) { - if (!(gActionSelectionCursor[gActiveBattler] & 2)) + if (!(gActionSelectionCursor[battler] & 2)) { PlaySE(SE_SELECT); - ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 2; - ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); + ActionSelectionDestroyCursorAt(gActionSelectionCursor[battler]); + gActionSelectionCursor[battler] ^= 2; + ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); } } } -static void CompleteOnBattlerSpriteCallbackDummy(void) +static void Controller_WaitForHealthbox(u32 battler) { - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - SafariBufferExecCompleted(); + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) + SafariBufferExecCompleted(battler); } -static void CompleteOnInactiveTextPrinter(void) -{ - if (!IsTextPrinterActive(B_WIN_MSG)) - SafariBufferExecCompleted(); -} - -static void CompleteOnHealthboxSpriteCallbackDummy(void) -{ - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - SafariBufferExecCompleted(); -} - -static void SafariSetBattleEndCallbacks(void) +static void SafariSetBattleEndCallbacks(u32 battler) { if (!gPaletteFade.active) { @@ -262,437 +202,141 @@ static void SafariSetBattleEndCallbacks(void) } } -static void CompleteOnSpecialAnimDone(void) -{ - if (!gDoingBattleAnim || !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - SafariBufferExecCompleted(); -} - -static void SafariOpenPokeblockCase(void) +static void SafariOpenPokeblockCase(u32 battler) { if (!gPaletteFade.active) { - gBattlerControllerFuncs[gActiveBattler] = CompleteWhenChosePokeblock; + gBattlerControllerFuncs[battler] = CompleteWhenChosePokeblock; FreeAllWindowBuffers(); OpenPokeblockCaseInBattle(); } } -static void CompleteWhenChosePokeblock(void) +static void CompleteWhenChosePokeblock(u32 battler) { if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) { BtlController_EmitOneReturnValue(BUFFER_B, gSpecialVar_ItemId); - SafariBufferExecCompleted(); + SafariBufferExecCompleted(battler); } } -static void CompleteOnFinishedBattleAnimation(void) +static void SafariBufferExecCompleted(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive) - SafariBufferExecCompleted(); -} - -static void SafariBufferExecCompleted(void) -{ - gBattlerControllerFuncs[gActiveBattler] = SafariBufferRunCommand; + gBattlerControllerFuncs[battler] = SafariBufferRunCommand; if (gBattleTypeFlags & BATTLE_TYPE_LINK) { u8 playerId = GetMultiplayerId(); PrepareBufferDataTransferLink(2, 4, &playerId); - gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; + gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP; } else { - gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; + gBattleControllerExecFlags &= ~gBitTable[battler]; } } -static void CompleteOnFinishedStatusAnimation(void) +static void SafariHandleDrawTrainerPic(u32 battler) { - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive) - SafariBufferExecCompleted(); + u32 trainerPicId = gSaveBlock2Ptr->playerGender + TRAINER_BACK_PIC_BRENDAN; + + BtlController_HandleDrawTrainerPic(battler, trainerPicId, FALSE, + 80, 80 + 4 * (8 - gTrainerBackPicCoords[trainerPicId].size), + 30); } -static void SafariHandleGetMonData(void) +static void SafariHandleSuccessBallThrowAnim(u32 battler) { - SafariBufferExecCompleted(); + BtlController_HandleSuccessBallThrowAnim(battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE); } -static void SafariHandleGetRawMonData(void) +static void SafariHandleBallThrowAnim(u32 battler) { - SafariBufferExecCompleted(); + BtlController_HandleBallThrowAnim(battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE); } -static void SafariHandleSetMonData(void) +static void SafariHandlePrintString(u32 battler) { - SafariBufferExecCompleted(); + BtlController_HandlePrintString(battler, FALSE, FALSE); } -static void SafariHandleSetRawMonData(void) +static void SafariHandlePrintSelectionString(u32 battler) { - SafariBufferExecCompleted(); -} - -static void SafariHandleLoadMonSprite(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleSwitchInAnim(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleReturnMonToBall(void) -{ - SafariBufferExecCompleted(); -} - -#define sSpeedX data[0] - -static void SafariHandleDrawTrainerPic(void) -{ - DecompressTrainerBackPic(gSaveBlock2Ptr->playerGender, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(gSaveBlock2Ptr->playerGender, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite( - &gMultiuseSpriteTemplate, - 80, - (8 - gTrainerBackPicCoords[gSaveBlock2Ptr->playerGender].size) * 4 + 80, - 30); - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = -2; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy; -} - -#undef sSpeedX - -static void SafariHandleTrainerSlide(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleTrainerSlideBack(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleFaintAnimation(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandlePaletteFade(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleSuccessBallThrowAnim(void) -{ - gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS; - gDoingBattleAnim = TRUE; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnSpecialAnimDone; -} - -static void SafariHandleBallThrowAnim(void) -{ - u8 ballThrowCaseId = gBattleResources->bufferA[gActiveBattler][1]; - - gBattleSpritesDataPtr->animationData->ballThrowCaseId = ballThrowCaseId; - gDoingBattleAnim = TRUE; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnSpecialAnimDone; -} - -static void SafariHandlePause(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleMoveAnimation(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandlePrintString(void) -{ - u16 *stringId; - - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - stringId = (u16 *)(&gBattleResources->bufferA[gActiveBattler][2]); - BufferStringBattle(*stringId); - BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter; -} - -static void SafariHandlePrintSelectionString(void) -{ - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - SafariHandlePrintString(); + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + SafariHandlePrintString(battler); else - SafariBufferExecCompleted(); + SafariBufferExecCompleted(battler); } -static void HandleChooseActionAfterDma3(void) +static void HandleChooseActionAfterDma3(u32 battler) { if (!IsDma3ManagerBusyWithBgCopy()) { gBattle_BG0_X = 0; gBattle_BG0_Y = DISPLAY_HEIGHT; - gBattlerControllerFuncs[gActiveBattler] = HandleInputChooseAction; + gBattlerControllerFuncs[battler] = HandleInputChooseAction; } } -static void SafariHandleChooseAction(void) +static void SafariHandleChooseAction(u32 battler) { s32 i; - gBattlerControllerFuncs[gActiveBattler] = HandleChooseActionAfterDma3; + gBattlerControllerFuncs[battler] = HandleChooseActionAfterDma3; BattlePutTextOnWindow(gText_SafariZoneMenu, B_WIN_ACTION_MENU); for (i = 0; i < 4; i++) ActionSelectionDestroyCursorAt(i); - ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); + ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo2); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT); } -static void SafariHandleYesNoBox(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleChooseMove(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleChooseItem(void) +static void SafariHandleChooseItem(u32 battler) { BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); - gBattlerControllerFuncs[gActiveBattler] = SafariOpenPokeblockCase; - gBattlerInMenuId = gActiveBattler; + gBattlerControllerFuncs[battler] = SafariOpenPokeblockCase; + gBattlerInMenuId = battler; } -static void SafariHandleChoosePokemon(void) +static void SafariHandleStatusIconUpdate(u32 battler) { - SafariBufferExecCompleted(); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_SAFARI_BALLS_TEXT); + SafariBufferExecCompleted(battler); } -static void SafariHandleCmd23(void) +// 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. +static void SafariHandleFaintingCry(u32 battler) { - SafariBufferExecCompleted(); -} - -static void SafariHandleHealthBarUpdate(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleExpUpdate(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleStatusIconUpdate(void) -{ - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_SAFARI_BALLS_TEXT); - SafariBufferExecCompleted(); -} - -static void SafariHandleStatusAnimation(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleStatusXor(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleDataTransfer(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleDMA3Transfer(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandlePlayBGM(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleCmd32(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleTwoReturnValues(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleChosenMonReturnValue(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleOneReturnValue(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleOneReturnValue_Duplicate(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleClearUnkVar(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleSetUnkVar(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleClearUnkFlag(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleToggleUnkFlag(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleHitAnimation(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleCantSwitch(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandlePlaySE(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - pan = SOUND_PAN_ATTACKER; - else - pan = SOUND_PAN_TARGET; - - PlaySE12WithPanning(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8), pan); - SafariBufferExecCompleted(); -} - -static void SafariHandlePlayFanfareOrBGM(void) -{ - if (gBattleResources->bufferA[gActiveBattler][3]) - { - BattleStopLowHpSound(); - PlayBGM(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - else - { - PlayFanfare(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - - SafariBufferExecCompleted(); -} - -static void SafariHandleFaintingCry(void) -{ - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); + u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES); PlayCry_Normal(species, 25); - SafariBufferExecCompleted(); + SafariBufferExecCompleted(battler); + SafariBufferExecCompleted(battler); } -static void SafariHandleIntroSlide(void) +static void SafariHandleIntroTrainerBallThrow(u32 battler) { - HandleIntroSlide(gBattleResources->bufferA[gActiveBattler][1]); - gIntroSlideFlags |= 1; - SafariBufferExecCompleted(); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_SAFARI_ALL_TEXT); + StartHealthboxSlideIn(battler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); + gBattlerControllerFuncs[battler] = Controller_WaitForHealthbox; } -static void SafariHandleIntroTrainerBallThrow(void) +static void SafariHandleBattleAnimation(u32 battler) { - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_SAFARI_ALL_TEXT); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthboxSpriteCallbackDummy; + BtlController_HandleBattleAnimation(battler, TRUE, FALSE); } -static void SafariHandleDrawPartyStatusSummary(void) +static void SafariHandleEndLinkBattle(u32 battler) { - SafariBufferExecCompleted(); -} - -static void SafariHandleHidePartyStatusSummary(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleEndBounceEffect(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleSpriteInvisibility(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleBattleAnimation(void) -{ - u8 animationId = gBattleResources->bufferA[gActiveBattler][1]; - u16 argument = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (TryHandleLaunchBattleTableAnimation(gActiveBattler, gActiveBattler, gActiveBattler, animationId, argument)) - SafariBufferExecCompleted(); - else - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; -} - -static void SafariHandleLinkStandbyMsg(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleResetActionMoveSelection(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariHandleEndLinkBattle(void) -{ - gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; + gBattleOutcome = gBattleResources->bufferA[battler][1]; FadeOutMapMusic(5); BeginFastPaletteFade(3); - SafariBufferExecCompleted(); + SafariBufferExecCompleted(battler); if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && !(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)) - gBattlerControllerFuncs[gActiveBattler] = SafariSetBattleEndCallbacks; -} - -static void SafariHandleBattleDebug(void) -{ - SafariBufferExecCompleted(); -} - -static void SafariCmdEnd(void) -{ + gBattlerControllerFuncs[battler] = SafariSetBattleEndCallbacks; } diff --git a/src/battle_controller_wally.c b/src/battle_controller_wally.c index 00a825dba..cff966567 100644 --- a/src/battle_controller_wally.c +++ b/src/battle_controller_wally.c @@ -32,162 +32,113 @@ #include "constants/trainers.h" #include "constants/rgb.h" -// this file's functions -static void WallyHandleGetMonData(void); -static void WallyHandleGetRawMonData(void); -static void WallyHandleSetMonData(void); -static void WallyHandleSetRawMonData(void); -static void WallyHandleLoadMonSprite(void); -static void WallyHandleSwitchInAnim(void); -static void WallyHandleReturnMonToBall(void); -static void WallyHandleDrawTrainerPic(void); -static void WallyHandleTrainerSlide(void); -static void WallyHandleTrainerSlideBack(void); -static void WallyHandleFaintAnimation(void); -static void WallyHandlePaletteFade(void); -static void WallyHandleSuccessBallThrowAnim(void); -static void WallyHandleBallThrowAnim(void); -static void WallyHandlePause(void); -static void WallyHandleMoveAnimation(void); -static void WallyHandlePrintString(void); -static void WallyHandlePrintSelectionString(void); -static void WallyHandleChooseAction(void); -static void WallyHandleYesNoBox(void); -static void WallyHandleChooseMove(void); -static void WallyHandleChooseItem(void); -static void WallyHandleChoosePokemon(void); -static void WallyHandleCmd23(void); -static void WallyHandleHealthBarUpdate(void); -static void WallyHandleExpUpdate(void); -static void WallyHandleStatusIconUpdate(void); -static void WallyHandleStatusAnimation(void); -static void WallyHandleStatusXor(void); -static void WallyHandleDataTransfer(void); -static void WallyHandleDMA3Transfer(void); -static void WallyHandlePlayBGM(void); -static void WallyHandleCmd32(void); -static void WallyHandleTwoReturnValues(void); -static void WallyHandleChosenMonReturnValue(void); -static void WallyHandleOneReturnValue(void); -static void WallyHandleOneReturnValue_Duplicate(void); -static void WallyHandleClearUnkVar(void); -static void WallyHandleSetUnkVar(void); -static void WallyHandleClearUnkFlag(void); -static void WallyHandleToggleUnkFlag(void); -static void WallyHandleHitAnimation(void); -static void WallyHandleCantSwitch(void); -static void WallyHandlePlaySE(void); -static void WallyHandlePlayFanfareOrBGM(void); -static void WallyHandleFaintingCry(void); -static void WallyHandleIntroSlide(void); -static void WallyHandleIntroTrainerBallThrow(void); -static void WallyHandleDrawPartyStatusSummary(void); -static void WallyHandleHidePartyStatusSummary(void); -static void WallyHandleEndBounceEffect(void); -static void WallyHandleSpriteInvisibility(void); -static void WallyHandleBattleAnimation(void); -static void WallyHandleLinkStandbyMsg(void); -static void WallyHandleResetActionMoveSelection(void); -static void WallyHandleEndLinkBattle(void); -static void WallyHandleBattleDebug(void); -static void WallyCmdEnd(void); +static void WallyHandleDrawTrainerPic(u32 battler); +static void WallyHandleTrainerSlide(u32 battler); +static void WallyHandleSuccessBallThrowAnim(u32 battler); +static void WallyHandleBallThrowAnim(u32 battler); +static void WallyHandleMoveAnimation(u32 battler); +static void WallyHandlePrintString(u32 battler); +static void WallyHandlePrintSelectionString(u32 battler); +static void WallyHandleChooseAction(u32 battler); +static void WallyHandleChooseMove(u32 battler); +static void WallyHandleChooseItem(u32 battler); +static void WallyHandleHealthBarUpdate(u32 battler); +static void WallyHandlePlaySE(u32 battler); +static void WallyHandleFaintingCry(u32 battler); +static void WallyHandleIntroTrainerBallThrow(u32 battler); +static void WallyHandleDrawPartyStatusSummary(u32 battler); +static void WallyHandleBattleAnimation(u32 battler); +static void WallyHandleEndLinkBattle(u32 battler); -static void WallyBufferRunCommand(void); -static void WallyBufferExecCompleted(void); -static void CompleteOnChosenItem(void); -static void Intro_WaitForShinyAnimAndHealthbox(void); -static u32 CopyWallyMonData(u8 monId, u8 *dst); -static void SetWallyMonData(u8 monId); -static void WallyDoMoveAnimation(void); -static void Task_StartSendOutAnim(u8 taskId); +static void WallyBufferRunCommand(u32 battler); +static void WallyBufferExecCompleted(u32 battler); +static void CompleteOnChosenItem(u32 battler); +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] = WallyHandleGetMonData, - [CONTROLLER_GETRAWMONDATA] = WallyHandleGetRawMonData, - [CONTROLLER_SETMONDATA] = WallyHandleSetMonData, - [CONTROLLER_SETRAWMONDATA] = WallyHandleSetRawMonData, - [CONTROLLER_LOADMONSPRITE] = WallyHandleLoadMonSprite, - [CONTROLLER_SWITCHINANIM] = WallyHandleSwitchInAnim, - [CONTROLLER_RETURNMONTOBALL] = WallyHandleReturnMonToBall, + [CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData, + [CONTROLLER_GETRAWMONDATA] = BtlController_HandleGetRawMonData, + [CONTROLLER_SETMONDATA] = BtlController_HandleSetMonData, + [CONTROLLER_SETRAWMONDATA] = BtlController_Empty, + [CONTROLLER_LOADMONSPRITE] = BtlController_Empty, + [CONTROLLER_SWITCHINANIM] = BtlController_Empty, + [CONTROLLER_RETURNMONTOBALL] = BtlController_HandleReturnMonToBall, [CONTROLLER_DRAWTRAINERPIC] = WallyHandleDrawTrainerPic, [CONTROLLER_TRAINERSLIDE] = WallyHandleTrainerSlide, - [CONTROLLER_TRAINERSLIDEBACK] = WallyHandleTrainerSlideBack, - [CONTROLLER_FAINTANIMATION] = WallyHandleFaintAnimation, - [CONTROLLER_PALETTEFADE] = WallyHandlePaletteFade, + [CONTROLLER_TRAINERSLIDEBACK] = BtlController_Empty, + [CONTROLLER_FAINTANIMATION] = BtlController_Empty, + [CONTROLLER_PALETTEFADE] = BtlController_Empty, [CONTROLLER_SUCCESSBALLTHROWANIM] = WallyHandleSuccessBallThrowAnim, [CONTROLLER_BALLTHROWANIM] = WallyHandleBallThrowAnim, - [CONTROLLER_PAUSE] = WallyHandlePause, + [CONTROLLER_PAUSE] = BtlController_Empty, [CONTROLLER_MOVEANIMATION] = WallyHandleMoveAnimation, [CONTROLLER_PRINTSTRING] = WallyHandlePrintString, [CONTROLLER_PRINTSTRINGPLAYERONLY] = WallyHandlePrintSelectionString, [CONTROLLER_CHOOSEACTION] = WallyHandleChooseAction, - [CONTROLLER_YESNOBOX] = WallyHandleYesNoBox, + [CONTROLLER_YESNOBOX] = BtlController_Empty, [CONTROLLER_CHOOSEMOVE] = WallyHandleChooseMove, [CONTROLLER_OPENBAG] = WallyHandleChooseItem, - [CONTROLLER_CHOOSEPOKEMON] = WallyHandleChoosePokemon, - [CONTROLLER_23] = WallyHandleCmd23, + [CONTROLLER_CHOOSEPOKEMON] = BtlController_Empty, + [CONTROLLER_23] = BtlController_Empty, [CONTROLLER_HEALTHBARUPDATE] = WallyHandleHealthBarUpdate, - [CONTROLLER_EXPUPDATE] = WallyHandleExpUpdate, - [CONTROLLER_STATUSICONUPDATE] = WallyHandleStatusIconUpdate, - [CONTROLLER_STATUSANIMATION] = WallyHandleStatusAnimation, - [CONTROLLER_STATUSXOR] = WallyHandleStatusXor, - [CONTROLLER_DATATRANSFER] = WallyHandleDataTransfer, - [CONTROLLER_DMA3TRANSFER] = WallyHandleDMA3Transfer, - [CONTROLLER_PLAYBGM] = WallyHandlePlayBGM, - [CONTROLLER_32] = WallyHandleCmd32, - [CONTROLLER_TWORETURNVALUES] = WallyHandleTwoReturnValues, - [CONTROLLER_CHOSENMONRETURNVALUE] = WallyHandleChosenMonReturnValue, - [CONTROLLER_ONERETURNVALUE] = WallyHandleOneReturnValue, - [CONTROLLER_ONERETURNVALUE_DUPLICATE] = WallyHandleOneReturnValue_Duplicate, - [CONTROLLER_CLEARUNKVAR] = WallyHandleClearUnkVar, - [CONTROLLER_SETUNKVAR] = WallyHandleSetUnkVar, - [CONTROLLER_CLEARUNKFLAG] = WallyHandleClearUnkFlag, - [CONTROLLER_TOGGLEUNKFLAG] = WallyHandleToggleUnkFlag, - [CONTROLLER_HITANIMATION] = WallyHandleHitAnimation, - [CONTROLLER_CANTSWITCH] = WallyHandleCantSwitch, + [CONTROLLER_EXPUPDATE] = BtlController_Empty, + [CONTROLLER_STATUSICONUPDATE] = BtlController_Empty, + [CONTROLLER_STATUSANIMATION] = BtlController_Empty, + [CONTROLLER_STATUSXOR] = BtlController_Empty, + [CONTROLLER_DATATRANSFER] = BtlController_Empty, + [CONTROLLER_DMA3TRANSFER] = BtlController_Empty, + [CONTROLLER_PLAYBGM] = BtlController_Empty, + [CONTROLLER_32] = BtlController_Empty, + [CONTROLLER_TWORETURNVALUES] = BtlController_Empty, + [CONTROLLER_CHOSENMONRETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE] = BtlController_Empty, + [CONTROLLER_ONERETURNVALUE_DUPLICATE] = BtlController_Empty, + [CONTROLLER_CLEARUNKVAR] = BtlController_Empty, + [CONTROLLER_SETUNKVAR] = BtlController_Empty, + [CONTROLLER_CLEARUNKFLAG] = BtlController_Empty, + [CONTROLLER_TOGGLEUNKFLAG] = BtlController_Empty, + [CONTROLLER_HITANIMATION] = BtlController_HandleHitAnimation, + [CONTROLLER_CANTSWITCH] = BtlController_Empty, [CONTROLLER_PLAYSE] = WallyHandlePlaySE, - [CONTROLLER_PLAYFANFAREORBGM] = WallyHandlePlayFanfareOrBGM, + [CONTROLLER_PLAYFANFAREORBGM] = BtlController_HandlePlayFanfareOrBGM, [CONTROLLER_FAINTINGCRY] = WallyHandleFaintingCry, - [CONTROLLER_INTROSLIDE] = WallyHandleIntroSlide, + [CONTROLLER_INTROSLIDE] = BtlController_HandleIntroSlide, [CONTROLLER_INTROTRAINERBALLTHROW] = WallyHandleIntroTrainerBallThrow, [CONTROLLER_DRAWPARTYSTATUSSUMMARY] = WallyHandleDrawPartyStatusSummary, - [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = WallyHandleHidePartyStatusSummary, - [CONTROLLER_ENDBOUNCE] = WallyHandleEndBounceEffect, - [CONTROLLER_SPRITEINVISIBILITY] = WallyHandleSpriteInvisibility, + [CONTROLLER_HIDEPARTYSTATUSSUMMARY] = BtlController_Empty, + [CONTROLLER_ENDBOUNCE] = BtlController_Empty, + [CONTROLLER_SPRITEINVISIBILITY] = BtlController_Empty, [CONTROLLER_BATTLEANIMATION] = WallyHandleBattleAnimation, - [CONTROLLER_LINKSTANDBYMSG] = WallyHandleLinkStandbyMsg, - [CONTROLLER_RESETACTIONMOVESELECTION] = WallyHandleResetActionMoveSelection, + [CONTROLLER_LINKSTANDBYMSG] = BtlController_Empty, + [CONTROLLER_RESETACTIONMOVESELECTION] = BtlController_Empty, [CONTROLLER_ENDLINKBATTLE] = WallyHandleEndLinkBattle, - [CONTROLLER_DEBUGMENU] = WallyHandleBattleDebug, - [CONTROLLER_TERMINATOR_NOP] = WallyCmdEnd + [CONTROLLER_DEBUGMENU] = BtlController_Empty, + [CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop }; -static void SpriteCB_Null7(void) +void SetControllerToWally(u32 battler) { -} - -void SetControllerToWally(void) -{ - gBattlerControllerFuncs[gActiveBattler] = WallyBufferRunCommand; + gBattlerControllerEndFuncs[battler] = WallyBufferExecCompleted; + gBattlerControllerFuncs[battler] = WallyBufferRunCommand; gBattleStruct->wallyBattleState = 0; gBattleStruct->wallyMovesState = 0; gBattleStruct->wallyWaitFrames = 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)) - sWallyBufferCommands[gBattleResources->bufferA[gActiveBattler][0]](); + if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sWallyBufferCommands)) + sWallyBufferCommands[gBattleResources->bufferA[battler][0]](battler); else - WallyBufferExecCompleted(); + WallyBufferExecCompleted(battler); } } -static void WallyHandleActions(void) +static void WallyHandleActions(u32 battler) { switch (gBattleStruct->wallyBattleState) { @@ -199,7 +150,7 @@ static void WallyHandleActions(void) { PlaySE(SE_SELECT); BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_USE_MOVE, 0); - WallyBufferExecCompleted(); + WallyBufferExecCompleted(battler); gBattleStruct->wallyBattleState++; gBattleStruct->wallyMovesState = 0; gBattleStruct->wallyWaitFrames = B_WAIT_TIME_LONG; @@ -210,7 +161,7 @@ static void WallyHandleActions(void) { PlaySE(SE_SELECT); BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_USE_MOVE, 0); - WallyBufferExecCompleted(); + WallyBufferExecCompleted(battler); gBattleStruct->wallyBattleState++; gBattleStruct->wallyMovesState = 0; gBattleStruct->wallyWaitFrames = B_WAIT_TIME_LONG; @@ -220,7 +171,7 @@ static void WallyHandleActions(void) if (--gBattleStruct->wallyWaitFrames == 0) { BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_WALLY_THROW, 0); - WallyBufferExecCompleted(); + WallyBufferExecCompleted(battler); gBattleStruct->wallyBattleState++; gBattleStruct->wallyMovesState = 0; gBattleStruct->wallyWaitFrames = B_WAIT_TIME_LONG; @@ -241,986 +192,181 @@ static void WallyHandleActions(void) { PlaySE(SE_SELECT); BtlController_EmitTwoReturnValues(BUFFER_B, B_ACTION_USE_ITEM, 0); - WallyBufferExecCompleted(); + WallyBufferExecCompleted(battler); } break; } } -static void CompleteOnBattlerSpriteCallbackDummy(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - WallyBufferExecCompleted(); -} - -static void CompleteOnInactiveTextPrinter(void) -{ - if (!IsTextPrinterActive(B_WIN_MSG)) - WallyBufferExecCompleted(); -} - -static void CompleteOnFinishedAnimation(void) -{ - if (!gDoingBattleAnim) - WallyBufferExecCompleted(); -} - -static void OpenBagAfterPaletteFade(void) +static void OpenBagAfterPaletteFade(u32 battler) { if (!gPaletteFade.active) { - gBattlerControllerFuncs[gActiveBattler] = CompleteOnChosenItem; + gBattlerControllerFuncs[battler] = CompleteOnChosenItem; ReshowBattleScreenDummy(); FreeAllWindowBuffers(); DoWallyTutorialBagMenu(); } } -static void CompleteOnChosenItem(void) +static void CompleteOnChosenItem(u32 battler) { if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) { 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 - && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) - TryShinyAnimation(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive) + TryShinyAnimation(battler, &gPlayerParty[gBattlerPartyIndexes[battler]]); - if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive) - TryShinyAnimation(BATTLE_PARTNER(gActiveBattler), &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]]); + if (!gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive) + TryShinyAnimation(BATTLE_PARTNER(battler), &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]]); - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive - && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].ballAnimActive - && gSprites[gBattleControllerData[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive + && !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive + && gSprites[gBattleControllerData[battler]].callback == SpriteCallbackDummy + && gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) { if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { - DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(gActiveBattler)]]); - UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]], HEALTHBOX_ALL); - StartHealthboxSlideIn(BATTLE_PARTNER(gActiveBattler)); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(gActiveBattler)]); + DestroySprite(&gSprites[gBattleControllerData[BATTLE_PARTNER(battler)]]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[BATTLE_PARTNER(battler)], &gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]], HEALTHBOX_ALL); + StartHealthboxSlideIn(BATTLE_PARTNER(battler)); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[BATTLE_PARTNER(battler)]); } - DestroySprite(&gSprites[gBattleControllerData[gActiveBattler]]); - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); - StartHealthboxSlideIn(gActiveBattler); - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + DestroySprite(&gSprites[gBattleControllerData[battler]]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &gPlayerParty[gBattlerPartyIndexes[battler]], HEALTHBOX_ALL); + StartHealthboxSlideIn(battler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); 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; - if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy) healthboxAnimDone = TRUE; - if (healthboxAnimDone && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim - && gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim) + if (healthboxAnimDone && gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim + && gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim) { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].triedShinyMonAnim = FALSE; - gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(gActiveBattler)].finishedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim = FALSE; + gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim = FALSE; FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS); FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS); CreateTask(Task_PlayerController_RestoreBgmAfterCry, 10); - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); - WallyBufferExecCompleted(); + WallyBufferExecCompleted(battler); } } -static void CompleteOnHealthbarDone(void) +static void WallyBufferExecCompleted(u32 battler) { - s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0); - - SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); - - if (hpValue != -1) - { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); - } - else - { - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - WallyBufferExecCompleted(); - } -} - -static void DoHitAnimBlinkSpriteEffect(void) -{ - u8 spriteId = gBattlerSpriteIds[gActiveBattler]; - - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = FALSE; - WallyBufferExecCompleted(); - } - else - { - if ((gSprites[spriteId].data[1] % 4) == 0) - gSprites[spriteId].invisible ^= 1; - gSprites[spriteId].data[1]++; - } -} - -static void DoSwitchOutAnimation(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - WallyBufferExecCompleted(); - } -} - -static void CompleteOnBankSpriteCallbackDummy2(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - WallyBufferExecCompleted(); -} - -static void CompleteOnFinishedBattleAnimation(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive) - WallyBufferExecCompleted(); -} - -static void WallyBufferExecCompleted(void) -{ - gBattlerControllerFuncs[gActiveBattler] = WallyBufferRunCommand; + gBattlerControllerFuncs[battler] = WallyBufferRunCommand; if (gBattleTypeFlags & BATTLE_TYPE_LINK) { u8 playerId = GetMultiplayerId(); PrepareBufferDataTransferLink(2, 4, &playerId); - gBattleResources->bufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; + gBattleResources->bufferA[battler][0] = CONTROLLER_TERMINATOR_NOP; } else { - gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; - } -} - -static void CompleteOnFinishedStatusAnimation(void) -{ - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive) - WallyBufferExecCompleted(); -} - -static void WallyHandleGetMonData(void) -{ - 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 size = 0; - u8 monToCheck; - s32 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - size += CopyWallyMonData(gBattlerPartyIndexes[gActiveBattler], monData); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - size += CopyWallyMonData(i, monData + size); - monToCheck >>= 1; - } - } - BtlController_EmitDataTransfer(BUFFER_B, size, monData); - WallyBufferExecCompleted(); -} - -static u32 CopyWallyMonData(u8 monId, u8 *dst) -{ - struct BattlePokemon battleMon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - battleMon.species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); - battleMon.item = GetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM); - for (size = 0; size < MAX_MON_MOVES; size++) - { - battleMon.moves[size] = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + size); - battleMon.pp[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - } - battleMon.ppBonuses = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - battleMon.friendship = GetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP); - battleMon.experience = GetMonData(&gPlayerParty[monId], MON_DATA_EXP); - battleMon.hpIV = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - battleMon.attackIV = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - battleMon.defenseIV = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - battleMon.speedIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - battleMon.spAttackIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - battleMon.spDefenseIV = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - battleMon.personality = GetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY); - battleMon.status1 = GetMonData(&gPlayerParty[monId], MON_DATA_STATUS); - battleMon.level = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); - battleMon.hp = GetMonData(&gPlayerParty[monId], MON_DATA_HP); - battleMon.maxHP = GetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP); - battleMon.attack = GetMonData(&gPlayerParty[monId], MON_DATA_ATK); - battleMon.defense = GetMonData(&gPlayerParty[monId], MON_DATA_DEF); - battleMon.speed = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED); - battleMon.spAttack = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK); - battleMon.spDefense = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF); - battleMon.abilityNum = GetMonData(&gPlayerParty[monId], MON_DATA_ABILITY_NUM); - battleMon.otId = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID); - battleMon.metLevel = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL); - GetMonData(&gPlayerParty[monId], MON_DATA_NICKNAME, nickname); - StringCopy_Nickname(battleMon.nickname, nickname); - GetMonData(&gPlayerParty[monId], MON_DATA_OT_NAME, battleMon.otName); - src = (u8 *)&battleMon; - for (size = 0; size < sizeof(battleMon); size++) - dst[size] = src[size]; - break; - case REQUEST_SPECIES_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_HELDITEM_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MOVES_PP_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - { - moveData.moves[size] = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - src = (u8 *)(&moveData); - for (size = 0; size < sizeof(moveData); size++) - dst[size] = src[size]; - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_PP_DATA_BATTLE: - for (size = 0; size < MAX_MON_MOVES; size++) - dst[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + size); - dst[size] = GetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES); - size++; - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE); - size = 1; - break; - case REQUEST_OTID_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_OT_ID); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_EXP_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_EXP); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case REQUEST_HP_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_EV); - size = 1; - break; - case REQUEST_ATK_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_EV); - size = 1; - break; - case REQUEST_DEF_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_EV); - size = 1; - break; - case REQUEST_SPEED_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_EV); - size = 1; - break; - case REQUEST_SPATK_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_EV); - size = 1; - break; - case REQUEST_SPDEF_EV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_EV); - size = 1; - break; - case REQUEST_FRIENDSHIP_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP); - size = 1; - break; - case REQUEST_POKERUS_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_POKERUS); - size = 1; - break; - case REQUEST_MET_LOCATION_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LOCATION); - size = 1; - break; - case REQUEST_MET_LEVEL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL); - size = 1; - break; - case REQUEST_MET_GAME_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_MET_GAME); - size = 1; - break; - case REQUEST_POKEBALL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_POKEBALL); - size = 1; - break; - case REQUEST_ALL_IVS_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - dst[1] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - dst[2] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - dst[3] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - dst[4] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - dst[5] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - size = 6; - break; - case REQUEST_HP_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_HP_IV); - size = 1; - break; - case REQUEST_ATK_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV); - size = 1; - break; - case REQUEST_DEF_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV); - size = 1; - break; - case REQUEST_SPEED_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV); - size = 1; - break; - case REQUEST_SPATK_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV); - size = 1; - break; - case REQUEST_SPDEF_IV_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV); - size = 1; - break; - case REQUEST_PERSONALITY_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_CHECKSUM_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_CHECKSUM); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_STATUS_BATTLE: - data32 = GetMonData(&gPlayerParty[monId], MON_DATA_STATUS); - dst[0] = (data32 & 0x000000FF); - dst[1] = (data32 & 0x0000FF00) >> 8; - dst[2] = (data32 & 0x00FF0000) >> 16; - dst[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case REQUEST_LEVEL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); - size = 1; - break; - case REQUEST_HP_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_MAX_HP_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_ATK_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_ATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_DEF_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_DEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPEED_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPEED); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPATK_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPATK); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_SPDEF_BATTLE: - data16 = GetMonData(&gPlayerParty[monId], MON_DATA_SPDEF); - dst[0] = data16; - dst[1] = data16 >> 8; - size = 2; - break; - case REQUEST_COOL_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_COOL); - size = 1; - break; - case REQUEST_BEAUTY_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY); - size = 1; - break; - case REQUEST_CUTE_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_CUTE); - size = 1; - break; - case REQUEST_SMART_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SMART); - size = 1; - break; - case REQUEST_TOUGH_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_TOUGH); - size = 1; - break; - case REQUEST_SHEEN_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SHEEN); - size = 1; - break; - case REQUEST_COOL_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_COOL_RIBBON); - size = 1; - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case REQUEST_CUTE_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case REQUEST_SMART_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_SMART_RIBBON); - size = 1; - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - dst[0] = GetMonData(&gPlayerParty[monId], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - - return size; -} - -static void WallyHandleGetRawMonData(void) -{ - PlayerHandleGetRawMonData(); -} - -static void WallyHandleSetMonData(void) -{ - u8 monToCheck; - u8 i; - - if (gBattleResources->bufferA[gActiveBattler][2] == 0) - { - SetWallyMonData(gBattlerPartyIndexes[gActiveBattler]); - } - else - { - monToCheck = gBattleResources->bufferA[gActiveBattler][2]; - for (i = 0; i < PARTY_SIZE; i++) - { - if (monToCheck & 1) - SetWallyMonData(i); - monToCheck >>= 1; - } - } - WallyBufferExecCompleted(); -} - -static void SetWallyMonData(u8 monId) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleResources->bufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleResources->bufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleResources->bufferA[gActiveBattler][1]) - { - case REQUEST_ALL_BATTLE: - { - u8 iv; - - SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gPlayerParty[monId], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gPlayerParty[monId], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gPlayerParty[monId], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gPlayerParty[monId], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gPlayerParty[monId], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case REQUEST_SPECIES_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HELDITEM_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HELD_ITEM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MOVES_PP_BATTLE: - for (i = 0; i < MAX_MON_MOVES; i++) - { - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case REQUEST_MOVE1_BATTLE: - case REQUEST_MOVE2_BATTLE: - case REQUEST_MOVE3_BATTLE: - case REQUEST_MOVE4_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PP_DATA_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PP1, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP2, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP3, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP4, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[monId], MON_DATA_PP_BONUSES, &gBattleResources->bufferA[gActiveBattler][7]); - break; - case REQUEST_PPMOVE1_BATTLE: - case REQUEST_PPMOVE2_BATTLE: - case REQUEST_PPMOVE3_BATTLE: - case REQUEST_PPMOVE4_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PP1 + gBattleResources->bufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_OTID_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_OT_ID, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_EXP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_EV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_EV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_FRIENDSHIP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_FRIENDSHIP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKERUS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_POKERUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LOCATION_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_LOCATION, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_LEVEL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MET_GAME_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MET_GAME, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_POKEBALL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_POKEBALL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ALL_IVS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][7]); - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][8]); - break; - case REQUEST_HP_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_IV_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_PERSONALITY_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_PERSONALITY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CHECKSUM_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CHECKSUM, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_STATUS_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_STATUS, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_LEVEL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_LEVEL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_HP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_MAX_HP_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_MAX_HP, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_ATK_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_ATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_DEF_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_DEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPEED_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPEED, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPATK_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPATK, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SPDEF_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SPDEF, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_COOL, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CUTE, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SMART, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_TOUGH, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SHEEN_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SHEEN, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_COOL_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_COOL_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_BEAUTY_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_BEAUTY_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_CUTE_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_CUTE_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_SMART_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_SMART_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - case REQUEST_TOUGH_RIBBON_BATTLE: - SetMonData(&gPlayerParty[monId], MON_DATA_TOUGH_RIBBON, &gBattleResources->bufferA[gActiveBattler][3]); - break; - } - - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); -} - -static void WallyHandleSetRawMonData(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleLoadMonSprite(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleSwitchInAnim(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleReturnMonToBall(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] == 0) - { - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SWITCH_OUT_PLAYER_MON); - gBattlerControllerFuncs[gActiveBattler] = DoSwitchOutAnimation; - } - else - { - FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); - WallyBufferExecCompleted(); + gBattleControllerExecFlags &= ~gBitTable[battler]; } } #define sSpeedX data[0] -static void WallyHandleDrawTrainerPic(void) +static void WallyHandleDrawTrainerPic(u32 battler) { - DecompressTrainerBackPic(TRAINER_BACK_PIC_WALLY, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(TRAINER_BACK_PIC_WALLY, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, - 80, - 80 + 4 * (8 - gTrainerBackPicCoords[TRAINER_BACK_PIC_WALLY].size), - 30); - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = DISPLAY_WIDTH; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = -2; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy; + BtlController_HandleDrawTrainerPic(battler, TRAINER_BACK_PIC_WALLY, FALSE, + 80, 80 + 4 * (8 - gTrainerBackPicCoords[TRAINER_BACK_PIC_WALLY].size), + 30); } -static void WallyHandleTrainerSlide(void) +static void WallyHandleTrainerSlide(u32 battler) { - DecompressTrainerBackPic(TRAINER_BACK_PIC_WALLY, gActiveBattler); - SetMultiuseSpriteTemplateToTrainerBack(TRAINER_BACK_PIC_WALLY, GetBattlerPosition(gActiveBattler)); - gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, - 80, - 80 + 4 * (8 - gTrainerBackPicCoords[TRAINER_BACK_PIC_WALLY].size), - 30); - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBattlerSpriteIds[gActiveBattler]].x2 = -96; - gSprites[gBattlerSpriteIds[gActiveBattler]].sSpeedX = 2; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_TrainerSlideIn; - gBattlerControllerFuncs[gActiveBattler] = CompleteOnBankSpriteCallbackDummy2; + BtlController_HandleTrainerSlide(battler, TRAINER_BACK_PIC_WALLY); } #undef sSpeedX -static void WallyHandleTrainerSlideBack(void) +static void WallyHandleSuccessBallThrowAnim(u32 battler) { - WallyBufferExecCompleted(); + BtlController_HandleSuccessBallThrowAnim(battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE); } -static void WallyHandleFaintAnimation(void) +static void WallyHandleBallThrowAnim(u32 battler) { - WallyBufferExecCompleted(); + BtlController_HandleBallThrowAnim(battler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER, FALSE); } -static void WallyHandlePaletteFade(void) +static void WallyHandleMoveAnimation(u32 battler) { - WallyBufferExecCompleted(); + BtlController_HandleMoveAnimation(battler, FALSE); } -static void WallyHandleSuccessBallThrowAnim(void) +static void WallyHandlePrintString(u32 battler) { - gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS; - gDoingBattleAnim = TRUE; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedAnimation; + BtlController_HandlePrintString(battler, FALSE, FALSE); } -static void WallyHandleBallThrowAnim(void) +static void WallyHandlePrintSelectionString(u32 battler) { - u8 ballThrowCaseId = gBattleResources->bufferA[gActiveBattler][1]; - - gBattleSpritesDataPtr->animationData->ballThrowCaseId = ballThrowCaseId; - gDoingBattleAnim = TRUE; - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW_WITH_TRAINER); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedAnimation; -} - -static void WallyHandlePause(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleMoveAnimation(void) -{ - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleResources->bufferA[gActiveBattler][3]; - gAnimMovePower = gBattleResources->bufferA[gActiveBattler][4] | (gBattleResources->bufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleResources->bufferA[gActiveBattler][6] | (gBattleResources->bufferA[gActiveBattler][7] << 8) | (gBattleResources->bufferA[gActiveBattler][8] << 16) | (gBattleResources->bufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleResources->bufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleResources->bufferA[gActiveBattler][12] | (gBattleResources->bufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - gTransformedOtIds[gActiveBattler] = gAnimDisableStructPtr->transformedMonOtId; - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - gBattlerControllerFuncs[gActiveBattler] = WallyDoMoveAnimation; -} - -static void WallyDoMoveAnimation(void) -{ - u16 move = gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8); - - switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState) - { - case 0: - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - { - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON); - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1; - break; - case 1: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF); - DoMoveAnim(move); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL); - if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) - { - InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); - } - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 3; - } - break; - case 3: - if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) - { - CopyAllBattleSpritesInvisibilities(); - TrySetBehindSubstituteSpriteBit(gActiveBattler, gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; - WallyBufferExecCompleted(); - } - break; - } -} - -static void WallyHandlePrintString(void) -{ - u16 *stringId; - - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - stringId = (u16 *)(&gBattleResources->bufferA[gActiveBattler][2]); - BufferStringBattle(*stringId); - BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); - gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter; -} - -static void WallyHandlePrintSelectionString(void) -{ - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - WallyHandlePrintString(); + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + WallyHandlePrintString(battler); else - WallyBufferExecCompleted(); + WallyBufferExecCompleted(battler); } -static void HandleChooseActionAfterDma3(void) +static void HandleChooseActionAfterDma3(u32 battler) { if (!IsDma3ManagerBusyWithBgCopy()) { gBattle_BG0_X = 0; gBattle_BG0_Y = DISPLAY_HEIGHT; - gBattlerControllerFuncs[gActiveBattler] = WallyHandleActions; + gBattlerControllerFuncs[battler] = WallyHandleActions; } } -static void WallyHandleChooseAction(void) +static void WallyHandleChooseAction(u32 battler) { s32 i; - gBattlerControllerFuncs[gActiveBattler] = HandleChooseActionAfterDma3; + gBattlerControllerFuncs[battler] = HandleChooseActionAfterDma3; BattlePutTextOnWindow(gText_BattleMenu, B_WIN_ACTION_MENU); for (i = 0; i < 4; i++) ActionSelectionDestroyCursorAt(i); - ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0); + ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0); BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillWallyDo); BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT); } -static void WallyHandleYesNoBox(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleChooseMove(void) +static void WallyHandleChooseMove(u32 battler) { switch (gBattleStruct->wallyMovesState) { case 0: - InitMoveSelectionsVarsAndStrings(); + InitMoveSelectionsVarsAndStrings(battler); gBattleStruct->wallyMovesState++; gBattleStruct->wallyMoveFrames = 80; break; @@ -1237,334 +383,64 @@ static void WallyHandleChooseMove(void) { PlaySE(SE_SELECT); BtlController_EmitTwoReturnValues(BUFFER_B, 10, 0x100); - WallyBufferExecCompleted(); + WallyBufferExecCompleted(battler); } break; } } -static void WallyHandleChooseItem(void) +static void WallyHandleChooseItem(u32 battler) { BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); - gBattlerControllerFuncs[gActiveBattler] = OpenBagAfterPaletteFade; - gBattlerInMenuId = gActiveBattler; + gBattlerControllerFuncs[battler] = OpenBagAfterPaletteFade; + gBattlerInMenuId = battler; } -static void WallyHandleChoosePokemon(void) +static void WallyHandleHealthBarUpdate(u32 battler) { - WallyBufferExecCompleted(); + BtlController_HandleHealthBarUpdate(battler, TRUE); } -static void WallyHandleCmd23(void) +// For some reason Wally's SE don't take side into account and pan is always the same. Possibly a bug +static void WallyHandlePlaySE(u32 battler) { - WallyBufferExecCompleted(); + PlaySE(gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8)); + WallyBufferExecCompleted(battler); } -static void WallyHandleHealthBarUpdate(void) +// 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. +static void WallyHandleFaintingCry(u32 battler) { - s16 hpVal; + u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES); - LoadBattleBarGfx(0); - hpVal = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (hpVal != INSTANT_HP_BAR_DROP) - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - u32 curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); - - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, curHP, hpVal); - } - else - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - - SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, 0, maxHP); - } - - gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone; -} - -static void WallyHandleExpUpdate(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleStatusIconUpdate(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleStatusAnimation(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleStatusXor(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleDataTransfer(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleDMA3Transfer(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandlePlayBGM(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleCmd32(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleTwoReturnValues(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleChosenMonReturnValue(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleOneReturnValue(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleOneReturnValue_Duplicate(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleClearUnkVar(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleSetUnkVar(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleClearUnkFlag(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleToggleUnkFlag(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleHitAnimation(void) -{ - if (gSprites[gBattlerSpriteIds[gActiveBattler]].invisible == TRUE) - { - WallyBufferExecCompleted(); - } - else - { - gDoingBattleAnim = TRUE; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[1] = 0; - DoHitAnimHealthboxEffect(gActiveBattler); - gBattlerControllerFuncs[gActiveBattler] = DoHitAnimBlinkSpriteEffect; - } -} - -static void WallyHandleCantSwitch(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandlePlaySE(void) -{ - PlaySE(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - WallyBufferExecCompleted(); -} - -static void WallyHandlePlayFanfareOrBGM(void) -{ - if (gBattleResources->bufferA[gActiveBattler][3]) - { - BattleStopLowHpSound(); - PlayBGM(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - else - { - PlayFanfare(gBattleResources->bufferA[gActiveBattler][1] | (gBattleResources->bufferA[gActiveBattler][2] << 8)); - } - - WallyBufferExecCompleted(); -} - -static void WallyHandleFaintingCry(void) -{ - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - // Seems that it doesn't bother using CRY_MODE_FAINT because - // Wally's Pokémon during the tutorial is never intended to faint. PlayCry_Normal(species, 25); - WallyBufferExecCompleted(); + WallyBufferExecCompleted(battler); } -static void WallyHandleIntroSlide(void) +static void WallyHandleIntroTrainerBallThrow(u32 battler) { - HandleIntroSlide(gBattleResources->bufferA[gActiveBattler][1]); - gIntroSlideFlags |= 1; - WallyBufferExecCompleted(); + const u32 *trainerPal = gTrainerBackPicPaletteTable[TRAINER_BACK_PIC_WALLY].data; + BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F8, trainerPal, 31, Intro_TryShinyAnimShowHealthbox); } -static void WallyHandleIntroTrainerBallThrow(void) +static void WallyHandleDrawPartyStatusSummary(u32 battler) { - u8 paletteNum; - u8 taskId; - - SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); - - gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 50; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].y; - gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - gSprites[gBattlerSpriteIds[gActiveBattler]].data[5] = gActiveBattler; - - StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCB_FreePlayerSpriteLoadMonSprite); - StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 1); - - paletteNum = AllocSpritePalette(0xD6F8); - LoadCompressedPalette(gTrainerBackPicPaletteTable[TRAINER_BACK_PIC_WALLY].data, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP); - gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = paletteNum; - - taskId = CreateTask(Task_StartSendOutAnim, 5); - gTasks[taskId].data[0] = gActiveBattler; - - if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) - gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; - - gBattleSpritesDataPtr->animationData->introAnimActive = TRUE; - gBattlerControllerFuncs[gActiveBattler] = BattleControllerDummy; + BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, FALSE); } -static void StartSendOutAnim(u8 battlerId) +static void WallyHandleBattleAnimation(u32 battler) { - u16 species; - - gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies = 0; - gBattlerPartyIndexes[battlerId] = gBattleResources->bufferA[battlerId][1]; - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); - gBattleControllerData[battlerId] = CreateInvisibleSpriteWithCallback(SpriteCB_WaitForBattlerBallReleaseAnim); - SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battlerId)); - gBattlerSpriteIds[battlerId] = CreateSprite(&gMultiuseSpriteTemplate, - GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2), - GetBattlerSpriteDefault_Y(battlerId), - GetBattlerSpriteSubpriority(battlerId)); - - gSprites[gBattleControllerData[battlerId]].data[1] = gBattlerSpriteIds[battlerId]; - gSprites[gBattleControllerData[battlerId]].data[2] = battlerId; - - gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId; - gSprites[gBattlerSpriteIds[battlerId]].data[2] = species; - gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId; - - StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], 0); - gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE; - gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy; - gSprites[gBattleControllerData[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT); + BtlController_HandleBattleAnimation(battler, TRUE, FALSE); } -static void Task_StartSendOutAnim(u8 taskId) +static void WallyHandleEndLinkBattle(u32 battler) { - if (gTasks[taskId].data[1] < 31) - { - gTasks[taskId].data[1]++; - } - else - { - u8 savedActiveBank = gActiveBattler; - - gActiveBattler = gTasks[taskId].data[0]; - gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - StartSendOutAnim(gActiveBattler); - gBattlerControllerFuncs[gActiveBattler] = Intro_TryShinyAnimShowHealthbox; - gActiveBattler = savedActiveBank; - DestroyTask(taskId); - } -} - -static void WallyHandleDrawPartyStatusSummary(void) -{ - if (gBattleResources->bufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - { - WallyBufferExecCompleted(); - } - else - { - gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown = 1; - gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleResources->bufferA[gActiveBattler][4], gBattleResources->bufferA[gActiveBattler][1], gBattleResources->bufferA[gActiveBattler][2]); - WallyBufferExecCompleted(); - } -} - -static void WallyHandleHidePartyStatusSummary(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleEndBounceEffect(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleSpriteInvisibility(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleBattleAnimation(void) -{ - u8 animationId = gBattleResources->bufferA[gActiveBattler][1]; - u16 argument = gBattleResources->bufferA[gActiveBattler][2] | (gBattleResources->bufferA[gActiveBattler][3] << 8); - - if (TryHandleLaunchBattleTableAnimation(gActiveBattler, gActiveBattler, gActiveBattler, animationId, argument)) - WallyBufferExecCompleted(); - else - gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; -} - -static void WallyHandleLinkStandbyMsg(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleResetActionMoveSelection(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyHandleEndLinkBattle(void) -{ - gBattleOutcome = gBattleResources->bufferA[gActiveBattler][1]; + gBattleOutcome = gBattleResources->bufferA[battler][1]; FadeOutMapMusic(5); BeginFastPaletteFade(3); - WallyBufferExecCompleted(); + WallyBufferExecCompleted(battler); if (!(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER) && gBattleTypeFlags & BATTLE_TYPE_LINK) - gBattlerControllerFuncs[gActiveBattler] = SetBattleEndCallbacks; -} - -static void WallyHandleBattleDebug(void) -{ - WallyBufferExecCompleted(); -} - -static void WallyCmdEnd(void) -{ + gBattlerControllerFuncs[battler] = SetBattleEndCallbacks; } diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 50058cb83..1518e4634 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -1,31 +1,46 @@ #include "global.h" #include "battle.h" #include "battle_ai_main.h" +#include "battle_arena.h" #include "battle_anim.h" #include "battle_controllers.h" +#include "battle_gfx_sfx_util.h" +#include "battle_interface.h" #include "battle_message.h" #include "battle_setup.h" +#include "battle_tv.h" #include "cable_club.h" #include "link.h" #include "link_rfu.h" +#include "palette.h" #include "party_menu.h" #include "recorded_battle.h" +#include "string_util.h" +#include "sound.h" #include "task.h" #include "util.h" +#include "text.h" #include "constants/abilities.h" +#include "constants/songs.h" static EWRAM_DATA u8 sLinkSendTaskId = 0; static EWRAM_DATA u8 sLinkReceiveTaskId = 0; -static EWRAM_DATA u8 sUnused = 0; // Debug? Never read EWRAM_DATA struct UnusedControllerStruct gUnusedControllerStruct = {}; // Debug? Unused code that writes to it, never read 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 InitLinkBtlControllers(void); static void InitSinglePlayerBtlControllers(void); static void SetBattlePartyIds(void); static void Task_HandleSendLinkBuffersData(u8 taskId); static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId); +static void Task_StartSendOutAnim(u8 taskId); +static void SpriteCB_FreePlayerSpriteLoadMonSprite(struct Sprite *sprite); +static void SpriteCB_FreeOpponentSprite(struct Sprite *sprite); void HandleLinkBattleSetup(void) { @@ -694,8 +709,6 @@ static void CreateTasksForSendRecvLinkBuffers(void) gTasks[sLinkReceiveTaskId].data[13] = 0; gTasks[sLinkReceiveTaskId].data[14] = 0; gTasks[sLinkReceiveTaskId].data[15] = 0; - - sUnused = 0; } enum @@ -861,7 +874,7 @@ void TryReceiveLinkBattleData(void) static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId) { u16 blockSize; - u8 battlerId; + u8 battler; u8 var; if (gTasks[taskId].data[15] != gTasks[taskId].data[14]) @@ -872,17 +885,17 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId) gTasks[taskId].data[12] = 0; gTasks[taskId].data[15] = 0; } - battlerId = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_ACTIVE_BATTLER]; + battler = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_ACTIVE_BATTLER]; blockSize = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_LO] | (gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_SIZE_HI] << 8); switch (gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 0]) { case 0: - if (gBattleControllerExecFlags & gBitTable[battlerId]) + if (gBattleControllerExecFlags & gBitTable[battler]) return; - memcpy(gBattleResources->bufferA[battlerId], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize); - MarkBattlerReceivedLinkData(battlerId); + memcpy(gBattleResources->bufferA[battler], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize); + MarkBattlerReceivedLinkData(battler); if (!(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER)) { @@ -893,11 +906,11 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId) } break; case 1: - memcpy(gBattleResources->bufferB[battlerId], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize); + memcpy(gBattleResources->bufferB[battler], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize); break; case 2: var = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA]; - gBattleControllerExecFlags &= ~(gBitTable[battlerId] << (var * 4)); + gBattleControllerExecFlags &= ~(gBitTable[battler] << (var * 4)); break; } @@ -1546,3 +1559,1484 @@ void BtlController_EmitDebugMenu(u8 bufferId) sBattleBuffersTransferData[0] = CONTROLLER_DEBUGMENU; PrepareBufferDataTransfer(bufferId, sBattleBuffersTransferData, 1); } + +// Standardized Controller functions + +// Can be used for all the controllers. +void BattleControllerComplete(u32 battler) +{ + gBattlerControllerEndFuncs[battler](battler); +} + +static u32 GetBattlerMonData(u32 battler, struct Pokemon *party, u32 monId, u8 *dst) +{ + struct BattlePokemon battleMon; + struct MovePpInfo moveData; + u8 nickname[POKEMON_NAME_LENGTH * 2]; + u8 *src; + s16 data16; + u32 data32; + s32 size = 0; + + switch (gBattleResources->bufferA[battler][1]) + { + case REQUEST_ALL_BATTLE: + battleMon.species = GetMonData(&party[monId], MON_DATA_SPECIES); + battleMon.item = GetMonData(&party[monId], MON_DATA_HELD_ITEM); + for (size = 0; size < MAX_MON_MOVES; size++) + { + battleMon.moves[size] = GetMonData(&party[monId], MON_DATA_MOVE1 + size); + battleMon.pp[size] = GetMonData(&party[monId], MON_DATA_PP1 + size); + } + battleMon.ppBonuses = GetMonData(&party[monId], MON_DATA_PP_BONUSES); + battleMon.friendship = GetMonData(&party[monId], MON_DATA_FRIENDSHIP); + battleMon.experience = GetMonData(&party[monId], MON_DATA_EXP); + battleMon.hpIV = GetMonData(&party[monId], MON_DATA_HP_IV); + battleMon.attackIV = GetMonData(&party[monId], MON_DATA_ATK_IV); + battleMon.defenseIV = GetMonData(&party[monId], MON_DATA_DEF_IV); + battleMon.speedIV = GetMonData(&party[monId], MON_DATA_SPEED_IV); + battleMon.spAttackIV = GetMonData(&party[monId], MON_DATA_SPATK_IV); + battleMon.spDefenseIV = GetMonData(&party[monId], MON_DATA_SPDEF_IV); + battleMon.personality = GetMonData(&party[monId], MON_DATA_PERSONALITY); + battleMon.status1 = GetMonData(&party[monId], MON_DATA_STATUS); + battleMon.level = GetMonData(&party[monId], MON_DATA_LEVEL); + battleMon.hp = GetMonData(&party[monId], MON_DATA_HP); + battleMon.maxHP = GetMonData(&party[monId], MON_DATA_MAX_HP); + battleMon.attack = GetMonData(&party[monId], MON_DATA_ATK); + battleMon.defense = GetMonData(&party[monId], MON_DATA_DEF); + battleMon.speed = GetMonData(&party[monId], MON_DATA_SPEED); + battleMon.spAttack = GetMonData(&party[monId], MON_DATA_SPATK); + battleMon.spDefense = GetMonData(&party[monId], MON_DATA_SPDEF); + battleMon.abilityNum = GetMonData(&party[monId], MON_DATA_ABILITY_NUM); + battleMon.otId = GetMonData(&party[monId], MON_DATA_OT_ID); + battleMon.metLevel = GetMonData(&party[monId], MON_DATA_MET_LEVEL); + GetMonData(&party[monId], MON_DATA_NICKNAME, nickname); + StringCopy_Nickname(battleMon.nickname, nickname); + GetMonData(&party[monId], MON_DATA_OT_NAME, battleMon.otName); + src = (u8 *)&battleMon; + for (size = 0; size < sizeof(battleMon); size++) + dst[size] = src[size]; + break; + case REQUEST_SPECIES_BATTLE: + data16 = GetMonData(&party[monId], MON_DATA_SPECIES); + dst[0] = data16; + dst[1] = data16 >> 8; + size = 2; + break; + case REQUEST_HELDITEM_BATTLE: + data16 = GetMonData(&party[monId], MON_DATA_HELD_ITEM); + dst[0] = data16; + dst[1] = data16 >> 8; + size = 2; + break; + case REQUEST_MOVES_PP_BATTLE: + for (size = 0; size < MAX_MON_MOVES; size++) + { + moveData.moves[size] = GetMonData(&party[monId], MON_DATA_MOVE1 + size); + moveData.pp[size] = GetMonData(&party[monId], MON_DATA_PP1 + size); + } + moveData.ppBonuses = GetMonData(&party[monId], MON_DATA_PP_BONUSES); + src = (u8 *)(&moveData); + for (size = 0; size < sizeof(moveData); size++) + dst[size] = src[size]; + break; + case REQUEST_MOVE1_BATTLE: + case REQUEST_MOVE2_BATTLE: + case REQUEST_MOVE3_BATTLE: + case REQUEST_MOVE4_BATTLE: + data16 = GetMonData(&party[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[battler][1] - REQUEST_MOVE1_BATTLE); + dst[0] = data16; + dst[1] = data16 >> 8; + size = 2; + break; + case REQUEST_PP_DATA_BATTLE: + for (size = 0; size < MAX_MON_MOVES; size++) + dst[size] = GetMonData(&party[monId], MON_DATA_PP1 + size); + dst[size] = GetMonData(&party[monId], MON_DATA_PP_BONUSES); + size++; + break; + case REQUEST_PPMOVE1_BATTLE: + case REQUEST_PPMOVE2_BATTLE: + case REQUEST_PPMOVE3_BATTLE: + case REQUEST_PPMOVE4_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_PP1 + gBattleResources->bufferA[battler][1] - REQUEST_PPMOVE1_BATTLE); + size = 1; + break; + case REQUEST_OTID_BATTLE: + data32 = GetMonData(&party[monId], MON_DATA_OT_ID); + dst[0] = (data32 & 0x000000FF); + dst[1] = (data32 & 0x0000FF00) >> 8; + dst[2] = (data32 & 0x00FF0000) >> 16; + size = 3; + break; + case REQUEST_EXP_BATTLE: + data32 = GetMonData(&party[monId], MON_DATA_EXP); + dst[0] = (data32 & 0x000000FF); + dst[1] = (data32 & 0x0000FF00) >> 8; + dst[2] = (data32 & 0x00FF0000) >> 16; + size = 3; + break; + case REQUEST_HP_EV_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_HP_EV); + size = 1; + break; + case REQUEST_ATK_EV_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_ATK_EV); + size = 1; + break; + case REQUEST_DEF_EV_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_DEF_EV); + size = 1; + break; + case REQUEST_SPEED_EV_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_SPEED_EV); + size = 1; + break; + case REQUEST_SPATK_EV_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_SPATK_EV); + size = 1; + break; + case REQUEST_SPDEF_EV_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_SPDEF_EV); + size = 1; + break; + case REQUEST_FRIENDSHIP_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_FRIENDSHIP); + size = 1; + break; + case REQUEST_POKERUS_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_POKERUS); + size = 1; + break; + case REQUEST_MET_LOCATION_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_MET_LOCATION); + size = 1; + break; + case REQUEST_MET_LEVEL_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_MET_LEVEL); + size = 1; + break; + case REQUEST_MET_GAME_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_MET_GAME); + size = 1; + break; + case REQUEST_POKEBALL_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_POKEBALL); + size = 1; + break; + case REQUEST_ALL_IVS_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_HP_IV); + dst[1] = GetMonData(&party[monId], MON_DATA_ATK_IV); + dst[2] = GetMonData(&party[monId], MON_DATA_DEF_IV); + dst[3] = GetMonData(&party[monId], MON_DATA_SPEED_IV); + dst[4] = GetMonData(&party[monId], MON_DATA_SPATK_IV); + dst[5] = GetMonData(&party[monId], MON_DATA_SPDEF_IV); + size = 6; + break; + case REQUEST_HP_IV_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_HP_IV); + size = 1; + break; + case REQUEST_ATK_IV_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_ATK_IV); + size = 1; + break; + case REQUEST_DEF_IV_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_DEF_IV); + size = 1; + break; + case REQUEST_SPEED_IV_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_SPEED_IV); + size = 1; + break; + case REQUEST_SPATK_IV_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_SPATK_IV); + size = 1; + break; + case REQUEST_SPDEF_IV_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_SPDEF_IV); + size = 1; + break; + case REQUEST_PERSONALITY_BATTLE: + data32 = GetMonData(&party[monId], MON_DATA_PERSONALITY); + dst[0] = (data32 & 0x000000FF); + dst[1] = (data32 & 0x0000FF00) >> 8; + dst[2] = (data32 & 0x00FF0000) >> 16; + dst[3] = (data32 & 0xFF000000) >> 24; + size = 4; + break; + case REQUEST_CHECKSUM_BATTLE: + data16 = GetMonData(&party[monId], MON_DATA_CHECKSUM); + dst[0] = data16; + dst[1] = data16 >> 8; + size = 2; + break; + case REQUEST_STATUS_BATTLE: + data32 = GetMonData(&party[monId], MON_DATA_STATUS); + dst[0] = (data32 & 0x000000FF); + dst[1] = (data32 & 0x0000FF00) >> 8; + dst[2] = (data32 & 0x00FF0000) >> 16; + dst[3] = (data32 & 0xFF000000) >> 24; + size = 4; + break; + case REQUEST_LEVEL_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_LEVEL); + size = 1; + break; + case REQUEST_HP_BATTLE: + data16 = GetMonData(&party[monId], MON_DATA_HP); + dst[0] = data16; + dst[1] = data16 >> 8; + size = 2; + break; + case REQUEST_MAX_HP_BATTLE: + data16 = GetMonData(&party[monId], MON_DATA_MAX_HP); + dst[0] = data16; + dst[1] = data16 >> 8; + size = 2; + break; + case REQUEST_ATK_BATTLE: + data16 = GetMonData(&party[monId], MON_DATA_ATK); + dst[0] = data16; + dst[1] = data16 >> 8; + size = 2; + break; + case REQUEST_DEF_BATTLE: + data16 = GetMonData(&party[monId], MON_DATA_DEF); + dst[0] = data16; + dst[1] = data16 >> 8; + size = 2; + break; + case REQUEST_SPEED_BATTLE: + data16 = GetMonData(&party[monId], MON_DATA_SPEED); + dst[0] = data16; + dst[1] = data16 >> 8; + size = 2; + break; + case REQUEST_SPATK_BATTLE: + data16 = GetMonData(&party[monId], MON_DATA_SPATK); + dst[0] = data16; + dst[1] = data16 >> 8; + size = 2; + break; + case REQUEST_SPDEF_BATTLE: + data16 = GetMonData(&party[monId], MON_DATA_SPDEF); + dst[0] = data16; + dst[1] = data16 >> 8; + size = 2; + break; + case REQUEST_COOL_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_COOL); + size = 1; + break; + case REQUEST_BEAUTY_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_BEAUTY); + size = 1; + break; + case REQUEST_CUTE_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_CUTE); + size = 1; + break; + case REQUEST_SMART_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_SMART); + size = 1; + break; + case REQUEST_TOUGH_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_TOUGH); + size = 1; + break; + case REQUEST_SHEEN_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_SHEEN); + size = 1; + break; + case REQUEST_COOL_RIBBON_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_COOL_RIBBON); + size = 1; + break; + case REQUEST_BEAUTY_RIBBON_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_BEAUTY_RIBBON); + size = 1; + break; + case REQUEST_CUTE_RIBBON_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_CUTE_RIBBON); + size = 1; + break; + case REQUEST_SMART_RIBBON_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_SMART_RIBBON); + size = 1; + break; + case REQUEST_TOUGH_RIBBON_BATTLE: + dst[0] = GetMonData(&party[monId], MON_DATA_TOUGH_RIBBON); + size = 1; + break; + } + + return size; +} + +static void SetBattlerMonData(u32 battler, struct Pokemon *party, u32 monId) +{ + struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleResources->bufferA[battler][3]; + struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleResources->bufferA[battler][3]; + s32 i; + + switch (gBattleResources->bufferA[battler][1]) + { + case REQUEST_ALL_BATTLE: + { + u8 iv; + + SetMonData(&party[monId], MON_DATA_SPECIES, &battlePokemon->species); + SetMonData(&party[monId], MON_DATA_HELD_ITEM, &battlePokemon->item); + for (i = 0; i < MAX_MON_MOVES; i++) + { + SetMonData(&party[monId], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); + SetMonData(&party[monId], MON_DATA_PP1 + i, &battlePokemon->pp[i]); + } + SetMonData(&party[monId], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); + SetMonData(&party[monId], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); + SetMonData(&party[monId], MON_DATA_EXP, &battlePokemon->experience); + iv = battlePokemon->hpIV; + SetMonData(&party[monId], MON_DATA_HP_IV, &iv); + iv = battlePokemon->attackIV; + SetMonData(&party[monId], MON_DATA_ATK_IV, &iv); + iv = battlePokemon->defenseIV; + SetMonData(&party[monId], MON_DATA_DEF_IV, &iv); + iv = battlePokemon->speedIV; + SetMonData(&party[monId], MON_DATA_SPEED_IV, &iv); + iv = battlePokemon->spAttackIV; + SetMonData(&party[monId], MON_DATA_SPATK_IV, &iv); + iv = battlePokemon->spDefenseIV; + SetMonData(&party[monId], MON_DATA_SPDEF_IV, &iv); + SetMonData(&party[monId], MON_DATA_PERSONALITY, &battlePokemon->personality); + SetMonData(&party[monId], MON_DATA_STATUS, &battlePokemon->status1); + SetMonData(&party[monId], MON_DATA_LEVEL, &battlePokemon->level); + SetMonData(&party[monId], MON_DATA_HP, &battlePokemon->hp); + SetMonData(&party[monId], MON_DATA_MAX_HP, &battlePokemon->maxHP); + SetMonData(&party[monId], MON_DATA_ATK, &battlePokemon->attack); + SetMonData(&party[monId], MON_DATA_DEF, &battlePokemon->defense); + SetMonData(&party[monId], MON_DATA_SPEED, &battlePokemon->speed); + SetMonData(&party[monId], MON_DATA_SPATK, &battlePokemon->spAttack); + SetMonData(&party[monId], MON_DATA_SPDEF, &battlePokemon->spDefense); + } + break; + case REQUEST_SPECIES_BATTLE: + SetMonData(&party[monId], MON_DATA_SPECIES, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_HELDITEM_BATTLE: + SetMonData(&party[monId], MON_DATA_HELD_ITEM, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_MOVES_PP_BATTLE: + for (i = 0; i < MAX_MON_MOVES; i++) + { + SetMonData(&party[monId], MON_DATA_MOVE1 + i, &moveData->moves[i]); + SetMonData(&party[monId], MON_DATA_PP1 + i, &moveData->pp[i]); + } + SetMonData(&party[monId], MON_DATA_PP_BONUSES, &moveData->ppBonuses); + break; + case REQUEST_MOVE1_BATTLE: + case REQUEST_MOVE2_BATTLE: + case REQUEST_MOVE3_BATTLE: + case REQUEST_MOVE4_BATTLE: + SetMonData(&party[monId], MON_DATA_MOVE1 + gBattleResources->bufferA[battler][1] - REQUEST_MOVE1_BATTLE, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_PP_DATA_BATTLE: + SetMonData(&party[monId], MON_DATA_PP1, &gBattleResources->bufferA[battler][3]); + SetMonData(&party[monId], MON_DATA_PP2, &gBattleResources->bufferA[battler][4]); + SetMonData(&party[monId], MON_DATA_PP3, &gBattleResources->bufferA[battler][5]); + SetMonData(&party[monId], MON_DATA_PP4, &gBattleResources->bufferA[battler][6]); + SetMonData(&party[monId], MON_DATA_PP_BONUSES, &gBattleResources->bufferA[battler][7]); + break; + case REQUEST_PPMOVE1_BATTLE: + case REQUEST_PPMOVE2_BATTLE: + case REQUEST_PPMOVE3_BATTLE: + case REQUEST_PPMOVE4_BATTLE: + SetMonData(&party[monId], MON_DATA_PP1 + gBattleResources->bufferA[battler][1] - REQUEST_PPMOVE1_BATTLE, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_OTID_BATTLE: + SetMonData(&party[monId], MON_DATA_OT_ID, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_EXP_BATTLE: + SetMonData(&party[monId], MON_DATA_EXP, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_HP_EV_BATTLE: + SetMonData(&party[monId], MON_DATA_HP_EV, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_ATK_EV_BATTLE: + SetMonData(&party[monId], MON_DATA_ATK_EV, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_DEF_EV_BATTLE: + SetMonData(&party[monId], MON_DATA_DEF_EV, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_SPEED_EV_BATTLE: + SetMonData(&party[monId], MON_DATA_SPEED_EV, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_SPATK_EV_BATTLE: + SetMonData(&party[monId], MON_DATA_SPATK_EV, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_SPDEF_EV_BATTLE: + SetMonData(&party[monId], MON_DATA_SPDEF_EV, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_FRIENDSHIP_BATTLE: + SetMonData(&party[monId], MON_DATA_FRIENDSHIP, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_POKERUS_BATTLE: + SetMonData(&party[monId], MON_DATA_POKERUS, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_MET_LOCATION_BATTLE: + SetMonData(&party[monId], MON_DATA_MET_LOCATION, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_MET_LEVEL_BATTLE: + SetMonData(&party[monId], MON_DATA_MET_LEVEL, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_MET_GAME_BATTLE: + SetMonData(&party[monId], MON_DATA_MET_GAME, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_POKEBALL_BATTLE: + SetMonData(&party[monId], MON_DATA_POKEBALL, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_ALL_IVS_BATTLE: + SetMonData(&party[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[battler][3]); + SetMonData(&party[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[battler][4]); + SetMonData(&party[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[battler][5]); + SetMonData(&party[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[battler][6]); + SetMonData(&party[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[battler][7]); + SetMonData(&party[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[battler][8]); + break; + case REQUEST_HP_IV_BATTLE: + SetMonData(&party[monId], MON_DATA_HP_IV, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_ATK_IV_BATTLE: + SetMonData(&party[monId], MON_DATA_ATK_IV, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_DEF_IV_BATTLE: + SetMonData(&party[monId], MON_DATA_DEF_IV, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_SPEED_IV_BATTLE: + SetMonData(&party[monId], MON_DATA_SPEED_IV, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_SPATK_IV_BATTLE: + SetMonData(&party[monId], MON_DATA_SPATK_IV, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_SPDEF_IV_BATTLE: + SetMonData(&party[monId], MON_DATA_SPDEF_IV, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_PERSONALITY_BATTLE: + SetMonData(&party[monId], MON_DATA_PERSONALITY, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_CHECKSUM_BATTLE: + SetMonData(&party[monId], MON_DATA_CHECKSUM, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_STATUS_BATTLE: + SetMonData(&party[monId], MON_DATA_STATUS, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_LEVEL_BATTLE: + SetMonData(&party[monId], MON_DATA_LEVEL, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_HP_BATTLE: + SetMonData(&party[monId], MON_DATA_HP, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_MAX_HP_BATTLE: + SetMonData(&party[monId], MON_DATA_MAX_HP, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_ATK_BATTLE: + SetMonData(&party[monId], MON_DATA_ATK, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_DEF_BATTLE: + SetMonData(&party[monId], MON_DATA_DEF, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_SPEED_BATTLE: + SetMonData(&party[monId], MON_DATA_SPEED, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_SPATK_BATTLE: + SetMonData(&party[monId], MON_DATA_SPATK, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_SPDEF_BATTLE: + SetMonData(&party[monId], MON_DATA_SPDEF, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_COOL_BATTLE: + SetMonData(&party[monId], MON_DATA_COOL, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_BEAUTY_BATTLE: + SetMonData(&party[monId], MON_DATA_BEAUTY, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_CUTE_BATTLE: + SetMonData(&party[monId], MON_DATA_CUTE, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_SMART_BATTLE: + SetMonData(&party[monId], MON_DATA_SMART, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_TOUGH_BATTLE: + SetMonData(&party[monId], MON_DATA_TOUGH, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_SHEEN_BATTLE: + SetMonData(&party[monId], MON_DATA_SHEEN, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_COOL_RIBBON_BATTLE: + SetMonData(&party[monId], MON_DATA_COOL_RIBBON, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_BEAUTY_RIBBON_BATTLE: + SetMonData(&party[monId], MON_DATA_BEAUTY_RIBBON, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_CUTE_RIBBON_BATTLE: + SetMonData(&party[monId], MON_DATA_CUTE_RIBBON, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_SMART_RIBBON_BATTLE: + SetMonData(&party[monId], MON_DATA_SMART_RIBBON, &gBattleResources->bufferA[battler][3]); + break; + case REQUEST_TOUGH_RIBBON_BATTLE: + SetMonData(&party[monId], MON_DATA_TOUGH_RIBBON, &gBattleResources->bufferA[battler][3]); + break; + } + + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + HandleLowHpMusicChange(&party[gBattlerPartyIndexes[battler]], battler); +} + +void StartSendOutAnim(u32 battler, bool32 dontClearSubstituteBit) +{ + u16 species; + u32 side = GetBattlerSide(battler); + struct Pokemon *party = GetBattlerParty(battler); + + ClearTemporarySpeciesSpriteData(battler, dontClearSubstituteBit); + gBattlerPartyIndexes[battler] = gBattleResources->bufferA[battler][1]; + species = GetIllusionMonSpecies(battler); + if (species == SPECIES_NONE) + species = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES); + gBattleControllerData[battler] = CreateInvisibleSpriteWithCallback(SpriteCB_WaitForBattlerBallReleaseAnim); + // Load sprite for opponent only, player sprite is expected to be already loaded. + if (side == B_SIDE_OPPONENT) + BattleLoadMonSpriteGfx(&party[gBattlerPartyIndexes[battler]], battler); + SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battler)); + + gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, + GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2), + GetBattlerSpriteDefault_Y(battler), + GetBattlerSpriteSubpriority(battler)); + + gSprites[gBattlerSpriteIds[battler]].data[0] = battler; + gSprites[gBattlerSpriteIds[battler]].data[2] = species; + gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = battler; + StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 0); + gSprites[gBattlerSpriteIds[battler]].invisible = TRUE; + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCallbackDummy; + + gSprites[gBattleControllerData[battler]].data[1] = gBattlerSpriteIds[battler]; + gSprites[gBattleControllerData[battler]].data[2] = battler; + gSprites[gBattleControllerData[battler]].data[0] = DoPokeballSendOutAnimation(0, (side == B_SIDE_OPPONENT) ? POKEBALL_OPPONENT_SENDOUT : POKEBALL_PLAYER_SENDOUT); +} + +static void FreeMonSprite(u32 battler) +{ + FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[battler]]); + DestroySprite(&gSprites[gBattlerSpriteIds[battler]]); + if (GetBattlerSide(battler) == B_SIDE_OPPONENT) + HideBattlerShadowSprite(battler); + SetHealthboxSpriteInvisible(gHealthboxSpriteIds[battler]); +} + +static void Controller_ReturnMonToBall2(u32 battler) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) + { + FreeMonSprite(battler); + BattleControllerComplete(battler); + } +} + +static void Controller_ReturnMonToBall(u32 battler) +{ + switch (gBattleSpritesDataPtr->healthBoxesData[battler].animationState) + { + case 0: + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_SUBSTITUTE_TO_MON); + + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 1; + break; + case 1: + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) + { + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0; + InitAndLaunchSpecialAnimation(battler, battler, battler, (GetBattlerSide(battler) == B_SIDE_OPPONENT) ? B_ANIM_SWITCH_OUT_OPPONENT_MON : B_ANIM_SWITCH_OUT_PLAYER_MON); + gBattlerControllerFuncs[battler] = Controller_ReturnMonToBall2; + } + break; + } +} + +static void Controller_FaintPlayerMon(u32 battler) +{ + u32 spriteId = gBattlerSpriteIds[battler]; + if (gSprites[spriteId].y + gSprites[spriteId].y2 > DISPLAY_HEIGHT) + { + BattleGfxSfxDummy2(GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES)); + FreeOamMatrix(gSprites[spriteId].oam.matrixNum); + DestroySprite(&gSprites[spriteId]); + SetHealthboxSpriteInvisible(gHealthboxSpriteIds[battler]); + BattleControllerComplete(battler); + } +} + +static void Controller_FaintOpponentMon(u32 battler) +{ + if (!gSprites[gBattlerSpriteIds[battler]].inUse) + { + SetHealthboxSpriteInvisible(gHealthboxSpriteIds[battler]); + BattleControllerComplete(battler); + } +} + +static void Controller_DoMoveAnimation(u32 battler) +{ + u16 move = gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8); + + switch (gBattleSpritesDataPtr->healthBoxesData[battler].animationState) + { + case 0: + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute + && !gBattleSpritesDataPtr->battlerData[battler].flag_x8) + { + gBattleSpritesDataPtr->battlerData[battler].flag_x8 = 1; + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_SUBSTITUTE_TO_MON); + } + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 1; + break; + case 1: + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) + { + SetBattlerSpriteAffineMode(ST_OAM_AFFINE_OFF); + DoMoveAnim(move); + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 2; + } + break; + case 2: + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + u8 multihit = gBattleResources->bufferA[battler][11]; + + SetBattlerSpriteAffineMode(ST_OAM_AFFINE_NORMAL); + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute && multihit < 2) + { + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_MON_TO_SUBSTITUTE); + gBattleSpritesDataPtr->battlerData[battler].flag_x8 = 0; + } + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 3; + } + break; + case 3: + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) + { + CopyAllBattleSpritesInvisibilities(); + TrySetBehindSubstituteSpriteBit(battler, gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8)); + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0; + BattleControllerComplete(battler); + } + break; + } +} + +static void Controller_HandleTrainerSlideBack(u32 battler) +{ + if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) + { + if (GetBattlerSide(battler) == B_SIDE_OPPONENT) + FreeTrainerFrontPicPalette(gSprites[gBattlerSpriteIds[battler]].oam.affineParam); + FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[battler]]); + DestroySprite(&gSprites[gBattlerSpriteIds[battler]]); + BattleControllerComplete(battler); + } +} + +void Controller_WaitForHealthBar(u32 battler) +{ + s16 hpValue = MoveBattleBar(battler, gHealthboxSpriteIds[battler], HEALTH_BAR, 0); + + SetHealthboxSpriteVisible(gHealthboxSpriteIds[battler]); + if (hpValue != -1) + { + UpdateHpTextInHealthbox(gHealthboxSpriteIds[battler], HP_CURRENT, hpValue, gBattleMons[battler].maxHP); + } + else + { + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); + BattleControllerComplete(battler); + } +} + +static void Controller_WaitForBallThrow(u32 battler) +{ + if (!gDoingBattleAnim || !gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) + BattleControllerComplete(battler); +} + +static void Controller_WaitForBattleAnimation(u32 battler) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[battler].animFromTableActive) + BattleControllerComplete(battler); +} + +static void Controller_WaitForStatusAnimation(u32 battler) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive) + BattleControllerComplete(battler); +} + +static void Controller_WaitForTrainerPic(u32 battler) +{ + if (gSprites[gBattlerSpriteIds[battler]].callback == SpriteCallbackDummy) + BattleControllerComplete(battler); +} + +void Controller_WaitForString(u32 battler) +{ + if (!IsTextPrinterActive(B_WIN_MSG)) + BattleControllerComplete(battler); +} + +static void Controller_WaitForPartyStatusSummary(u32 battler) +{ + if (gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusDelayTimer++ > 92) + { + gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusDelayTimer = 0; + BattleControllerComplete(battler); + } +} + +static void Controller_HitAnimation(u32 battler) +{ + u32 spriteId = gBattlerSpriteIds[battler]; + + if (gSprites[spriteId].data[1] == 32) + { + gSprites[spriteId].data[1] = 0; + gSprites[spriteId].invisible = FALSE; + gDoingBattleAnim = FALSE; + BattleControllerComplete(battler); + } + else + { + if ((gSprites[spriteId].data[1] % 4) == 0) + gSprites[spriteId].invisible ^= 1; + gSprites[spriteId].data[1]++; + } +} + +// Used for all the commands which do nothing. +void BtlController_Empty(u32 battler) +{ + BattleControllerComplete(battler); +} + +// Dummy function at the end of the table. +void BtlController_TerminatorNop(u32 battler) +{ +} + +void BattleControllerDummy(u32 battler) +{ +} + +// Handlers of the controller commands +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 + struct Pokemon *party = GetBattlerParty(battler); + u32 size = 0; + u8 monToCheck; + s32 i; + + if (gBattleResources->bufferA[battler][2] == 0) + { + size += GetBattlerMonData(battler, party, gBattlerPartyIndexes[battler], monData); + } + else + { + monToCheck = gBattleResources->bufferA[battler][2]; + for (i = 0; i < PARTY_SIZE; i++) + { + if (monToCheck & 1) + size += GetBattlerMonData(battler, party, i, monData + size); + monToCheck >>= 1; + } + } + BtlController_EmitDataTransfer(BUFFER_B, size, monData); + BattleControllerComplete(battler); +} + +void BtlController_HandleGetRawMonData(u32 battler) +{ + struct BattlePokemon battleMon; + struct Pokemon *party = GetBattlerParty(battler); + + u8 *src = (u8 *)&party[gBattlerPartyIndexes[battler]] + gBattleResources->bufferA[battler][1]; + u8 *dst = (u8 *)&battleMon + gBattleResources->bufferA[battler][1]; + u8 i; + + for (i = 0; i < gBattleResources->bufferA[battler][2]; i++) + dst[i] = src[i]; + + BtlController_EmitDataTransfer(BUFFER_B, gBattleResources->bufferA[battler][2], dst); + BattleControllerComplete(battler); +} + +void BtlController_HandleSetMonData(u32 battler) +{ + struct Pokemon *party = GetBattlerParty(battler); + u32 i, monToCheck; + + if (gBattleResources->bufferA[battler][2] == 0) + { + SetBattlerMonData(battler, party, gBattlerPartyIndexes[battler]); + } + else + { + monToCheck = gBattleResources->bufferA[battler][2]; + for (i = 0; i < PARTY_SIZE; i++) + { + if (monToCheck & 1) + SetBattlerMonData(battler, party, i); + monToCheck >>= 1; + } + } + BattleControllerComplete(battler); +} + +void BtlController_HandleSetRawMonData(u32 battler) +{ + u32 i; + struct Pokemon *party = GetBattlerParty(battler); + u8 *dst = (u8 *)&party[gBattlerPartyIndexes[battler]] + gBattleResources->bufferA[battler][1]; + + for (i = 0; i < gBattleResources->bufferA[battler][2]; i++) + dst[i] = gBattleResources->bufferA[battler][3 + i]; + + BattleControllerComplete(battler); +} + +void BtlController_HandleLoadMonSprite(u32 battler, void (*controllerCallback)(u32 battler)) +{ + struct Pokemon *party = GetBattlerParty(battler); + u16 species = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES); + + BattleLoadMonSpriteGfx(&party[gBattlerPartyIndexes[battler]], battler); + SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battler)); + + gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, + GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2), + GetBattlerSpriteDefault_Y(battler), + GetBattlerSpriteSubpriority(battler)); + + gSprites[gBattlerSpriteIds[battler]].x2 = -DISPLAY_WIDTH; + gSprites[gBattlerSpriteIds[battler]].data[0] = battler; + gSprites[gBattlerSpriteIds[battler]].data[2] = species; + gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = battler; + StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 0); + + SetBattlerShadowSpriteCallback(battler, species); + + gBattlerControllerFuncs[battler] = controllerCallback; +} + +void BtlController_HandleSwitchInAnim(u32 battler, bool32 isPlayerSide, void (*controllerCallback)(u32 battler)) +{ + if (isPlayerSide) + ClearTemporarySpeciesSpriteData(battler, gBattleResources->bufferA[battler][2]); + gBattlerPartyIndexes[battler] = gBattleResources->bufferA[battler][1]; + if (isPlayerSide) + BattleLoadMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); + StartSendOutAnim(battler, gBattleResources->bufferA[battler][2]); + gBattlerControllerFuncs[battler] = controllerCallback; +} + +void BtlController_HandleReturnMonToBall(u32 battler) +{ + if (gBattleResources->bufferA[battler][1] == 0) + { + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0; + gBattlerControllerFuncs[battler] = Controller_ReturnMonToBall; + } + else + { + FreeMonSprite(battler); + BattleControllerComplete(battler); + } +} + +// 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 an animated back pic. + +#define sSpeedX data[0] + +void BtlController_HandleDrawTrainerPic(u32 battler, u32 trainerPicId, bool32 isFrontPic, s16 xPos, s16 yPos, s32 subpriority) +{ + if (GetBattlerSide(battler) == B_SIDE_OPPONENT) // Always the front sprite for the opponent. + { + DecompressTrainerFrontPic(trainerPicId, battler); + SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(battler)); + if (subpriority == -1) + subpriority = GetBattlerSpriteSubpriority(battler); + gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, + xPos, + yPos, + subpriority); + + gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); + gSprites[gBattlerSpriteIds[battler]].x2 = -DISPLAY_WIDTH; + gSprites[gBattlerSpriteIds[battler]].sSpeedX = 2; + gSprites[gBattlerSpriteIds[battler]].oam.affineParam = trainerPicId; + } + else // Player's side + { + if (isFrontPic) + { + DecompressTrainerFrontPic(trainerPicId, battler); + SetMultiuseSpriteTemplateToTrainerFront(trainerPicId, GetBattlerPosition(battler)); + if (subpriority == -1) + subpriority = GetBattlerSpriteSubpriority(battler); + gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, + xPos, + yPos, + subpriority); + + gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); + gSprites[gBattlerSpriteIds[battler]].oam.affineMode = ST_OAM_AFFINE_OFF; + gSprites[gBattlerSpriteIds[battler]].hFlip = 1; + gSprites[gBattlerSpriteIds[battler]].y2 = 48; + } + else + { + DecompressTrainerBackPic(trainerPicId, battler); + SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(battler)); + if (subpriority == -1) + subpriority = GetBattlerSpriteSubpriority(battler); + gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, + xPos, + yPos, + subpriority); + + gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = battler; + } + gSprites[gBattlerSpriteIds[battler]].x2 = DISPLAY_WIDTH; + gSprites[gBattlerSpriteIds[battler]].sSpeedX = -2; + } + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn; + + gBattlerControllerFuncs[battler] = Controller_WaitForTrainerPic; +} + +void BtlController_HandleTrainerSlide(u32 battler, u32 trainerPicId) +{ + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + { + DecompressTrainerBackPic(trainerPicId, battler); + SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(battler)); + gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, + 80, + (8 - gTrainerBackPicCoords[trainerPicId].size) * 4 + 80, + 30); + gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = battler; + gSprites[gBattlerSpriteIds[battler]].x2 = -96; + gSprites[gBattlerSpriteIds[battler]].sSpeedX = 2; + } + else + { + DecompressTrainerFrontPic(trainerPicId, battler); + SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(battler)); + gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, + 176, + (8 - gTrainerFrontPicCoords[trainerPicId].size) * 4 + 40, + 30); + gSprites[gBattlerSpriteIds[battler]].oam.affineParam = trainerPicId; + gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); + gSprites[gBattlerSpriteIds[battler]].x2 = 96; + gSprites[gBattlerSpriteIds[battler]].x += 32; + gSprites[gBattlerSpriteIds[battler]].sSpeedX = -2; + } + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn; + + gBattlerControllerFuncs[battler] = Controller_WaitForTrainerPic; +} + +#undef sSpeedX + +void BtlController_HandleTrainerSlideBack(u32 battlerId, s16 data0, bool32 startAnim) +{ + u32 side = GetBattlerSide(battlerId); + + SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[battlerId]]); + gSprites[gBattlerSpriteIds[battlerId]].data[0] = data0; + gSprites[gBattlerSpriteIds[battlerId]].data[2] = (side == B_SIDE_PLAYER) ? -40 : 280; + gSprites[gBattlerSpriteIds[battlerId]].data[4] = gSprites[gBattlerSpriteIds[battlerId]].y; + gSprites[gBattlerSpriteIds[battlerId]].callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[battlerId]], SpriteCallbackDummy); + if (startAnim) + StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], 1); + gBattlerControllerFuncs[battlerId] = Controller_HandleTrainerSlideBack; +} + +#define sSpeedX data[1] +#define sSpeedY data[2] + +void BtlController_HandleFaintAnimation(u32 battler) +{ + if (gBattleSpritesDataPtr->healthBoxesData[battler].animationState == 0) + { + if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) + InitAndLaunchSpecialAnimation(battler, battler, battler, B_ANIM_SUBSTITUTE_TO_MON); + gBattleSpritesDataPtr->healthBoxesData[battler].animationState++; + } + else + { + if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive) + { + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0; + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + { + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); + gSprites[gBattlerSpriteIds[battler]].sSpeedX = 0; + gSprites[gBattlerSpriteIds[battler]].sSpeedY = 5; + PlaySE12WithPanning(SE_FAINT, SOUND_PAN_ATTACKER); + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_FaintSlideAnim; + gBattlerControllerFuncs[battler] = Controller_FaintPlayerMon; + } + else + { + PlaySE12WithPanning(SE_FAINT, SOUND_PAN_TARGET); + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_FaintOpponentMon; + gBattlerControllerFuncs[battler] = Controller_FaintOpponentMon; + } + // The player's sprite callback just slides the mon, the opponent's removes the sprite. + // The player's sprite is removed in Controller_FaintPlayerMon. Controller_FaintOpponentMon only removes the healthbox once the sprite is removed by SpriteCB_FaintOpponentMon. + } + } +} + +#undef sSpeedX +#undef sSpeedY + +static void HandleBallThrow(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture) +{ + gDoingBattleAnim = TRUE; + if (allowCriticalCapture && IsCriticalCapture()) + animId = B_ANIM_CRITICAL_CAPTURE_THROW; + InitAndLaunchSpecialAnimation(battler, battler, target, animId); + + gBattlerControllerFuncs[battler] = Controller_WaitForBallThrow; +} + +void BtlController_HandleSuccessBallThrowAnim(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture) +{ + gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS; + HandleBallThrow(battler, target, animId, allowCriticalCapture); +} + +void BtlController_HandleBallThrowAnim(u32 battler, u32 target, u32 animId, bool32 allowCriticalCapture) +{ + gBattleSpritesDataPtr->animationData->ballThrowCaseId = gBattleResources->bufferA[battler][1]; + HandleBallThrow(battler, target, animId, allowCriticalCapture); +} + +void BtlController_HandleMoveAnimation(u32 battler, bool32 updateTvData) +{ + if (!IsBattleSEPlaying(battler)) + { + u16 move = gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8); + + gAnimMoveTurn = gBattleResources->bufferA[battler][3]; + gAnimMovePower = gBattleResources->bufferA[battler][4] | (gBattleResources->bufferA[battler][5] << 8); + gAnimMoveDmg = gBattleResources->bufferA[battler][6] | (gBattleResources->bufferA[battler][7] << 8) | (gBattleResources->bufferA[battler][8] << 16) | (gBattleResources->bufferA[battler][9] << 24); + gAnimFriendship = gBattleResources->bufferA[battler][10]; + gWeatherMoveAnim = gBattleResources->bufferA[battler][12] | (gBattleResources->bufferA[battler][13] << 8); + gAnimDisableStructPtr = (struct DisableStruct *)&gBattleResources->bufferA[battler][16]; + gTransformedPersonalities[battler] = gAnimDisableStructPtr->transformedMonPersonality; + gTransformedOtIds[battler] = gAnimDisableStructPtr->transformedMonOtId; + gBattleSpritesDataPtr->healthBoxesData[battler].animationState = 0; + gBattlerControllerFuncs[battler] = Controller_DoMoveAnimation; + if (updateTvData) + BattleTv_SetDataBasedOnMove(move, gWeatherMoveAnim, gAnimDisableStructPtr); + } +} + +void BtlController_HandlePrintString(u32 battler, bool32 updateTvData, bool32 arenaPtsDeduct) +{ + u16 *stringId; + + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + stringId = (u16 *)(&gBattleResources->bufferA[battler][2]); + BufferStringBattle(*stringId); + BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MSG); + gBattlerControllerFuncs[battler] = Controller_WaitForString; + if (updateTvData) + BattleTv_SetDataBasedOnString(*stringId); + if (arenaPtsDeduct) + BattleArena_DeductSkillPoints(battler, *stringId); +} + +void BtlController_HandleHealthBarUpdate(u32 battler, bool32 updateHpText) +{ + s16 hpVal; + struct Pokemon *party = GetBattlerParty(battler); + + LoadBattleBarGfx(0); + hpVal = gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8); + + if (hpVal != INSTANT_HP_BAR_DROP) + { + u32 maxHP = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP); + u32 curHP = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_HP); + + SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, curHP, hpVal); + } + else + { + u32 maxHP = GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_MAX_HP); + + SetBattleBarStruct(battler, gHealthboxSpriteIds[battler], maxHP, 0, hpVal); + if (updateHpText) + UpdateHpTextInHealthbox(gHealthboxSpriteIds[battler], HP_CURRENT, 0, maxHP); + } + + gBattlerControllerFuncs[battler] = Controller_WaitForHealthBar; +} + +void DoStatusIconUpdate(u32 battler) +{ + struct Pokemon *party = GetBattlerParty(battler); + + UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], &party[gBattlerPartyIndexes[battler]], HEALTHBOX_STATUS_ICON); + gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = 0; + gBattlerControllerFuncs[battler] = Controller_WaitForStatusAnimation; +} + +void BtlController_HandleStatusIconUpdate(u32 battler) +{ + if (!IsBattleSEPlaying(battler)) + { + DoStatusIconUpdate(battler); + } +} + +void BtlController_HandleStatusAnimation(u32 battler) +{ + if (!IsBattleSEPlaying(battler)) + { + InitAndLaunchChosenStatusAnimation(gBattleResources->bufferA[battler][1], + gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8) | (gBattleResources->bufferA[battler][4] << 16) | (gBattleResources->bufferA[battler][5] << 24)); + gBattlerControllerFuncs[battler] = Controller_WaitForStatusAnimation; + } +} + +void BtlController_HandleClearUnkVar(u32 battler) +{ + gUnusedControllerStruct.unk = 0; + BattleControllerComplete(battler); +} + +void BtlController_HandleSetUnkVar(u32 battler) +{ + gUnusedControllerStruct.unk = gBattleResources->bufferA[battler][1]; + BattleControllerComplete(battler); +} + +void BtlController_HandleClearUnkFlag(u32 battler) +{ + gUnusedControllerStruct.flag = 0; + BattleControllerComplete(battler); +} + +void BtlController_HandleToggleUnkFlag(u32 battler) +{ + gUnusedControllerStruct.flag ^= 1; + BattleControllerComplete(battler); +} + +void BtlController_HandleHitAnimation(u32 battler) +{ + if (gSprites[gBattlerSpriteIds[battler]].invisible == TRUE) + { + BattleControllerComplete(battler); + } + else + { + gDoingBattleAnim = TRUE; + gSprites[gBattlerSpriteIds[battler]].data[1] = 0; + DoHitAnimHealthboxEffect(battler); + gBattlerControllerFuncs[battler] = Controller_HitAnimation; + } +} + +void BtlController_HandlePlaySE(u32 battler) +{ + s8 pan = (GetBattlerSide(battler) == B_SIDE_PLAYER) ? SOUND_PAN_ATTACKER : SOUND_PAN_TARGET; + + PlaySE12WithPanning(gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8), pan); + BattleControllerComplete(battler); +} + +void BtlController_HandlePlayFanfareOrBGM(u32 battler) +{ + if (gBattleResources->bufferA[battler][3]) + { + BattleStopLowHpSound(); + PlayBGM(gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8)); + } + else + { + PlayFanfare(gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8)); + } + + BattleControllerComplete(battler); +} + +void BtlController_HandleFaintingCry(u32 battler) +{ + struct Pokemon *party; + s8 pan; + + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + { + party = gPlayerParty; + pan = -25; + } + else + { + party = gEnemyParty; + pan = 25; + } + + PlayCry_ByMode(GetMonData(&party[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES), pan, CRY_MODE_FAINT); + BattleControllerComplete(battler); +} + +void BtlController_HandleIntroSlide(u32 battler) +{ + HandleIntroSlide(gBattleResources->bufferA[battler][1]); + gIntroSlideFlags |= 1; + BattleControllerComplete(battler); +} + +void BtlController_HandleSpriteInvisibility(u32 battler) +{ + if (IsBattlerSpritePresent(battler)) + { + gSprites[gBattlerSpriteIds[battler]].invisible = gBattleResources->bufferA[battler][1]; + CopyBattleSpriteInvisibility(battler); + } + BattleControllerComplete(battler); +} + +bool32 TwoPlayerIntroMons(u32 battler) // Double battle with both player pokemon active. +{ + return (IsDoubleBattle() && IsValidForBattle(&gPlayerParty[gBattlerPartyIndexes[battler ^ BIT_FLANK]])); +} + +bool32 TwoOpponentIntroMons(u32 battler) // Double battle with both opponent pokemon active. +{ + return (IsDoubleBattle() + && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[battler]]) + && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]])); +} + +// Task data for Task_StartSendOutAnim +#define tBattlerId data[0] +#define tStartTimer data[1] +#define tFramesToWait data[2] +#define tControllerFunc_1 3 // Stored as two halfwords +#define tControllerFunc_2 4 + +// Sprite data for SpriteCB_FreePlayerSpriteLoadMonSprite +#define sBattlerId data[5] + +void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, const u32 *trainerPal, s16 framesToWait, void (*controllerCallback)(u32 battler)) +{ + u8 paletteNum, taskId; + u32 side = GetBattlerSide(battler); + + SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[battler]]); + if (side == B_SIDE_PLAYER) + { + gSprites[gBattlerSpriteIds[battler]].data[0] = 50; + gSprites[gBattlerSpriteIds[battler]].data[2] = -40; + } + else + { + gSprites[gBattlerSpriteIds[battler]].data[0] = 35; + gSprites[gBattlerSpriteIds[battler]].data[2] = 280; + } + + gSprites[gBattlerSpriteIds[battler]].data[4] = gSprites[gBattlerSpriteIds[battler]].y; + gSprites[gBattlerSpriteIds[battler]].callback = StartAnimLinearTranslation; + gSprites[gBattlerSpriteIds[battler]].sBattlerId = battler; + + if (side == B_SIDE_PLAYER) + { + StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[battler]], SpriteCB_FreePlayerSpriteLoadMonSprite); + StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 1); + + paletteNum = AllocSpritePalette(tagTrainerPal); + LoadCompressedPalette(trainerPal, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP); + gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = paletteNum; + } + else + { + StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[battler]], SpriteCB_FreeOpponentSprite); + } + + taskId = CreateTask(Task_StartSendOutAnim, 5); + gTasks[taskId].tBattlerId = battler; + gTasks[taskId].tFramesToWait = framesToWait; + SetWordTaskArg(taskId, tControllerFunc_1, (uint32_t)(controllerCallback)); + + if (gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusSummaryShown) + gTasks[gBattlerStatusSummaryTaskId[battler]].func = Task_HidePartyStatusSummary; + + gBattleSpritesDataPtr->animationData->introAnimActive = TRUE; + gBattlerControllerFuncs[battler] = BattleControllerDummy; +} + +static bool32 TwoMonsAtSendOut(u32 battler) +{ + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + { + if (TwoPlayerIntroMons(battler) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + return TRUE; + else + return FALSE; + } + else + { + if ((!TwoOpponentIntroMons(battler) || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) && !BATTLE_TWO_VS_ONE_OPPONENT) + return FALSE; + else if ((gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) || (BATTLE_TWO_VS_ONE_OPPONENT && !TwoOpponentIntroMons(battler))) + return FALSE; + else + return TRUE; + } + return FALSE; +} + +// Send out at start of battle +static void Task_StartSendOutAnim(u8 taskId) +{ + if (gTasks[taskId].tFramesToWait != 0 && gTasks[taskId].tStartTimer < gTasks[taskId].tFramesToWait) + { + gTasks[taskId].tStartTimer++; + } + else + { + u8 savedActiveBattler = gActiveBattler; + + gActiveBattler = gTasks[taskId].tBattlerId; + if (TwoMonsAtSendOut(gActiveBattler)) + { + gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + StartSendOutAnim(gActiveBattler, FALSE); + gActiveBattler ^= BIT_FLANK; + gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + BattleLoadMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + StartSendOutAnim(gActiveBattler, FALSE); + gActiveBattler ^= BIT_FLANK; + } + else + { + gBattleResources->bufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + StartSendOutAnim(gActiveBattler, FALSE); + } + gBattlerControllerFuncs[gActiveBattler] = (void*)(GetWordTaskArg(taskId, tControllerFunc_1)); + gActiveBattler = savedActiveBattler; + DestroyTask(taskId); + } +} + +#undef tBattlerId +#undef tStartTimer +#undef tFramesToWait +#undef tControllerFunc_1 +#undef tControllerFunc_2 + +static void SpriteCB_FreePlayerSpriteLoadMonSprite(struct Sprite *sprite) +{ + u8 battler = sprite->sBattlerId; + + // Free player trainer sprite + FreeSpriteOamMatrix(sprite); + FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum)); + DestroySprite(sprite); + + // Load mon sprite + BattleLoadMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); + StartSpriteAnim(&gSprites[gBattlerSpriteIds[battler]], 0); +} + +static void SpriteCB_FreeOpponentSprite(struct Sprite *sprite) +{ + FreeTrainerFrontPicPalette(sprite->oam.affineParam); + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); +} + +#undef sBattlerId + +void BtlController_HandleDrawPartyStatusSummary(u32 battler, u32 side, bool32 considerDelay) +{ + if (gBattleResources->bufferA[battler][1] != 0 && GetBattlerSide(battler) == B_SIDE_PLAYER) + { + BattleControllerComplete(battler); + } + else + { + gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusSummaryShown = 1; + + if (side == B_SIDE_OPPONENT && gBattleResources->bufferA[battler][2] != 0) + { + if (gBattleSpritesDataPtr->healthBoxesData[battler].opponentDrawPartyStatusSummaryDelay < 2) + { + gBattleSpritesDataPtr->healthBoxesData[battler].opponentDrawPartyStatusSummaryDelay++; + return; + } + else + { + gBattleSpritesDataPtr->healthBoxesData[battler].opponentDrawPartyStatusSummaryDelay = 0; + } + } + + gBattlerStatusSummaryTaskId[battler] = CreatePartyStatusSummarySprites(battler, (struct HpAndStatus *)&gBattleResources->bufferA[battler][4], gBattleResources->bufferA[battler][1], gBattleResources->bufferA[battler][2]); + gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusDelayTimer = 0; + + // If intro, skip the delay after drawing + if (considerDelay && gBattleResources->bufferA[battler][2] != 0) + gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusDelayTimer = 93; + + gBattlerControllerFuncs[battler] = Controller_WaitForPartyStatusSummary; + } +} + +void BtlController_HandleHidePartyStatusSummary(u32 battler) +{ + if (gBattleSpritesDataPtr->healthBoxesData[battler].partyStatusSummaryShown) + gTasks[gBattlerStatusSummaryTaskId[battler]].func = Task_HidePartyStatusSummary; + BattleControllerComplete(battler); +} + +void BtlController_HandleBattleAnimation(u32 battler, bool32 ignoreSE, bool32 updateTvData) +{ + if (ignoreSE || !IsBattleSEPlaying(battler)) + { + u8 animationId = gBattleResources->bufferA[battler][1]; + u16 argument = gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8); + + if (TryHandleLaunchBattleTableAnimation(battler, battler, battler, animationId, argument)) + BattleControllerComplete(battler); + else + gBattlerControllerFuncs[battler] = Controller_WaitForBattleAnimation; + + if (updateTvData) + BattleTv_SetDataBasedOnAnimation(animationId); + } +} diff --git a/src/battle_dome.c b/src/battle_dome.c index e94261f72..7f5b7abec 100644 --- a/src/battle_dome.c +++ b/src/battle_dome.c @@ -157,8 +157,6 @@ static void BufferLastDomeWinnerName(void); static void InitRandomTourneyTreeResults(void); static void InitDomeTrainers(void); -EWRAM_DATA u32 gPlayerPartyLostHP = 0; // never read -static EWRAM_DATA u32 sPlayerPartyMaxHP = 0; // never read static EWRAM_DATA struct TourneyTreeInfoCard *sInfoCard = {0}; static EWRAM_DATA u8 *sTilemapBuffer = NULL; @@ -2544,9 +2542,6 @@ static void BufferDomeOpponentName(void) static void InitDomeOpponentParty(void) { - gPlayerPartyLostHP = 0; - sPlayerPartyMaxHP = GetMonData(&gPlayerParty[0], MON_DATA_MAX_HP, NULL); - sPlayerPartyMaxHP += GetMonData(&gPlayerParty[1], MON_DATA_MAX_HP, NULL); CalculatePlayerPartyCount(); CreateDomeOpponentMons(TrainerIdToTournamentId(gTrainerBattleOpponent_A)); } diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index b7cf2c238..9da563057 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -544,7 +544,7 @@ bool8 IsBattleSEPlaying(u8 battlerId) return TRUE; } -static void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId, bool32 opponent) +void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId) { u32 monsPersonality, currentPersonality, otId, currentOtId, species, paletteOffset, position; const void *lzPaletteData; @@ -577,7 +577,7 @@ static void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId, bool32 op } position = GetBattlerPosition(battlerId); - if (opponent) + if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT) { HandleLoadSpecialPokePic(TRUE, gMonSpritesGfxPtr->sprites.ptr[position], @@ -609,16 +609,6 @@ static void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId, bool32 op } } -void BattleLoadOpponentMonSpriteGfx(struct Pokemon *mon, u8 battlerId) -{ - BattleLoadMonSpriteGfx(mon, battlerId, TRUE); -} - -void BattleLoadPlayerMonSpriteGfx(struct Pokemon *mon, u8 battlerId) -{ - BattleLoadMonSpriteGfx(mon, battlerId, FALSE); -} - void BattleGfxSfxDummy2(u16 species) { } @@ -642,10 +632,6 @@ void DecompressTrainerBackPic(u16 backPicId, u8 battlerId) OBJ_PLTT_ID(battlerId), PLTT_SIZE_4BPP); } -void BattleGfxSfxDummy3(u8 gender) -{ -} - void FreeTrainerFrontPicPalette(u16 frontPicId) { FreeSpritePaletteByTag(gTrainerFrontPicPaletteTable[frontPicId].tag); @@ -968,12 +954,7 @@ void BattleLoadSubstituteOrMonSpriteGfx(u8 battlerId, bool8 loadMonSprite) else { if (!IsContest()) - { - if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) - BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId); - else - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battlerId]], battlerId); - } + BattleLoadMonSpriteGfx(&GetBattlerParty(battlerId)[gBattlerPartyIndexes[battlerId]], battlerId); } } diff --git a/src/battle_main.c b/src/battle_main.c index e6640fda7..ed26436f8 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -251,11 +251,9 @@ void (*gPreBattleCallback1)(void); void (*gBattleMainFunc)(void); struct BattleResults gBattleResults; u8 gLeveledUpInBattle; -void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; u8 gMultiUsePlayerCursor; 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 = { @@ -567,8 +565,8 @@ static void CB2_InitBattleInternal(void) gBattle_BG3_X = 0; gBattle_BG3_Y = 0; -#if DEBUG_OVERWORLD_MENU == FALSE - +#if DEBUG_OVERWORLD_MENU == FALSE + gBattleTerrain = BattleSetup_GetTerrainId(); #else if (!gIsDebugBattle) @@ -596,7 +594,7 @@ static void CB2_InitBattleInternal(void) else SetMainCallback2(CB2_HandleStartBattle); -#if DEBUG_OVERWORLD_MENU == FALSE +#if DEBUG_OVERWORLD_MENU == FALSE if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED))) { CreateNPCTrainerParty(&gEnemyParty[0], gTrainerBattleOpponent_A, TRUE); @@ -2743,8 +2741,6 @@ void SpriteCB_FaintOpponentMon(struct Sprite *sprite) else species = sprite->sSpeciesId; - GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_PERSONALITY); // Unused return value. - if (species == SPECIES_UNOWN) { species = GetUnownSpeciesId(personality); @@ -3006,7 +3002,7 @@ static void BattleMainCB1(void) gBattleMainFunc(); for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - gBattlerControllerFuncs[gActiveBattler](); + gBattlerControllerFuncs[gActiveBattler](gActiveBattler); } static void BattleStartClearSetData(void) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 2ab173a49..a8e689dc6 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9961,13 +9961,13 @@ static void Cmd_various(void) if (IsBattlerAlive(gActiveBattler)) { SetBattlerShadowSpriteCallback(gActiveBattler, gBattleMons[gActiveBattler].species); - BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + BattleLoadMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); } i = BATTLE_PARTNER(gActiveBattler); if (IsBattlerAlive(i)) { SetBattlerShadowSpriteCallback(i, gBattleMons[i].species); - BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[i]], i); + BattleLoadMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[i]], i); } } gBattlescriptCurrInstr = cmd->nextInstr; diff --git a/src/reshow_battle_screen.c b/src/reshow_battle_screen.c index 9ea0b1180..38999e1c7 100644 --- a/src/reshow_battle_screen.c +++ b/src/reshow_battle_screen.c @@ -187,7 +187,7 @@ static bool8 LoadBattlerSpriteGfx(u8 battler) if (GetBattlerSide(battler) != B_SIDE_PLAYER) { if (!gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) - BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battler]], battler); + BattleLoadMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battler]], battler); else BattleLoadSubstituteOrMonSpriteGfx(battler, FALSE); } @@ -196,7 +196,7 @@ static bool8 LoadBattlerSpriteGfx(u8 battler) else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && battler == B_POSITION_PLAYER_LEFT) // Should be checking position, not battler. DecompressTrainerBackPic(TRAINER_BACK_PIC_WALLY, battler); else if (!gBattleSpritesDataPtr->battlerData[battler].behindSubstitute) - BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); + BattleLoadMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battler]], battler); else BattleLoadSubstituteOrMonSpriteGfx(battler, FALSE); diff --git a/sym_common.txt b/sym_common.txt index 7eebcac74..170aee2f4 100644 --- a/sym_common.txt +++ b/sym_common.txt @@ -37,6 +37,7 @@ gReservedSpritePaletteCount: .include "link_rfu_2.o" .include "rtc.o" .include "battle_main.o" + .include "battle_controllers.o" .include "random.o" .include "load_save.o" .include "berry_blender.o"