2017-10-24 15:25:20 +02:00
# include "global.h"
# include "battle.h"
2020-12-20 14:47:20 -07:00
# include "battle_ai_main.h"
2018-11-14 00:01:50 +00:00
# include "battle_anim.h"
2017-10-24 15:25:20 +02:00
# include "battle_controllers.h"
# include "battle_interface.h"
2018-11-14 00:01:50 +00:00
# include "battle_message.h"
# include "battle_setup.h"
2018-12-24 00:02:29 +01:00
# include "battle_tower.h"
2018-02-27 20:40:09 +01:00
# include "battle_tv.h"
2018-11-14 00:01:50 +00:00
# include "bg.h"
2019-04-04 23:53:06 +02:00
# include "data.h"
2017-10-24 15:25:20 +02:00
# include "link.h"
# include "main.h"
# include "m4a.h"
# include "palette.h"
2018-11-14 00:01:50 +00:00
# include "pokeball.h"
# include "pokemon.h"
2019-03-05 20:07:59 +01:00
# include "recorded_battle.h"
2018-11-14 00:01:50 +00:00
# include "reshow_battle_screen.h"
# include "sound.h"
# include "string_util.h"
2017-10-24 15:25:20 +02:00
# include "task.h"
# include "text.h"
2018-11-14 00:01:50 +00:00
# include "util.h"
# include "window.h"
# include "constants/battle_anim.h"
# include "constants/songs.h"
# include "constants/trainers.h"
2019-03-01 22:32:50 -05:00
# include "recorded_battle.h"
2017-10-24 15:25:20 +02:00
2023-08-07 12:51:58 +02:00
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 ( u32 battler ) ;
static void LinkOpponentBufferExecCompleted ( u32 battler ) ;
static void SwitchIn_HandleSoundAndEnd ( u32 battler ) ;
static void ( * const sLinkOpponentBufferCommands [ CONTROLLER_CMDS_COUNT ] ) ( u32 battler ) =
2017-10-24 15:25:20 +02:00
{
2023-08-05 12:53:14 +02:00
[ CONTROLLER_GETMONDATA ] = BtlController_HandleGetMonData ,
2023-08-05 11:39:42 +02:00
[ CONTROLLER_GETRAWMONDATA ] = BtlController_Empty ,
2023-08-05 12:53:14 +02:00
[ CONTROLLER_SETMONDATA ] = BtlController_HandleSetMonData ,
[ CONTROLLER_SETRAWMONDATA ] = BtlController_HandleSetRawMonData ,
2020-12-29 16:51:44 -05:00
[ CONTROLLER_LOADMONSPRITE ] = LinkOpponentHandleLoadMonSprite ,
[ CONTROLLER_SWITCHINANIM ] = LinkOpponentHandleSwitchInAnim ,
2023-08-05 14:11:25 +02:00
[ CONTROLLER_RETURNMONTOBALL ] = BtlController_HandleReturnMonToBall ,
2020-12-29 16:51:44 -05:00
[ CONTROLLER_DRAWTRAINERPIC ] = LinkOpponentHandleDrawTrainerPic ,
[ CONTROLLER_TRAINERSLIDE ] = LinkOpponentHandleTrainerSlide ,
[ CONTROLLER_TRAINERSLIDEBACK ] = LinkOpponentHandleTrainerSlideBack ,
2023-08-05 14:11:25 +02:00
[ CONTROLLER_FAINTANIMATION ] = BtlController_HandleFaintAnimation ,
2023-08-05 11:39:42 +02:00
[ CONTROLLER_PALETTEFADE ] = BtlController_Empty ,
[ CONTROLLER_SUCCESSBALLTHROWANIM ] = BtlController_Empty ,
[ CONTROLLER_BALLTHROWANIM ] = BtlController_Empty ,
[ CONTROLLER_PAUSE ] = BtlController_Empty ,
2020-12-29 16:51:44 -05:00
[ CONTROLLER_MOVEANIMATION ] = LinkOpponentHandleMoveAnimation ,
[ CONTROLLER_PRINTSTRING ] = LinkOpponentHandlePrintString ,
2023-08-05 11:39:42 +02:00
[ 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 ,
2020-12-29 16:51:44 -05:00
[ CONTROLLER_HEALTHBARUPDATE ] = LinkOpponentHandleHealthBarUpdate ,
2023-08-05 11:39:42 +02:00
[ CONTROLLER_EXPUPDATE ] = BtlController_Empty ,
2023-08-05 20:42:19 +02:00
[ CONTROLLER_STATUSICONUPDATE ] = BtlController_HandleStatusIconUpdate ,
[ CONTROLLER_STATUSANIMATION ] = BtlController_HandleStatusAnimation ,
2023-08-05 11:39:42 +02:00
[ 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 ,
2023-08-05 14:11:25 +02:00
[ CONTROLLER_CLEARUNKVAR ] = BtlController_HandleClearUnkVar ,
[ CONTROLLER_SETUNKVAR ] = BtlController_HandleSetUnkVar ,
[ CONTROLLER_CLEARUNKFLAG ] = BtlController_HandleClearUnkFlag ,
[ CONTROLLER_TOGGLEUNKFLAG ] = BtlController_HandleToggleUnkFlag ,
[ CONTROLLER_HITANIMATION ] = BtlController_HandleHitAnimation ,
2023-08-05 11:39:42 +02:00
[ CONTROLLER_CANTSWITCH ] = BtlController_Empty ,
2023-08-05 12:13:50 +02:00
[ CONTROLLER_PLAYSE ] = BtlController_HandlePlaySE ,
[ CONTROLLER_PLAYFANFAREORBGM ] = BtlController_HandlePlayFanfareOrBGM ,
[ CONTROLLER_FAINTINGCRY ] = BtlController_HandleFaintingCry ,
2023-08-05 14:11:25 +02:00
[ CONTROLLER_INTROSLIDE ] = BtlController_HandleIntroSlide ,
2020-12-29 16:51:44 -05:00
[ CONTROLLER_INTROTRAINERBALLTHROW ] = LinkOpponentHandleIntroTrainerBallThrow ,
[ CONTROLLER_DRAWPARTYSTATUSSUMMARY ] = LinkOpponentHandleDrawPartyStatusSummary ,
2023-08-05 23:27:56 +02:00
[ CONTROLLER_HIDEPARTYSTATUSSUMMARY ] = BtlController_HandleHidePartyStatusSummary ,
2023-08-05 11:39:42 +02:00
[ CONTROLLER_ENDBOUNCE ] = BtlController_Empty ,
2023-08-05 14:11:25 +02:00
[ CONTROLLER_SPRITEINVISIBILITY ] = BtlController_HandleSpriteInvisibility ,
2020-12-29 16:51:44 -05:00
[ CONTROLLER_BATTLEANIMATION ] = LinkOpponentHandleBattleAnimation ,
[ CONTROLLER_LINKSTANDBYMSG ] = LinkOpponentHandleLinkStandbyMsg ,
2023-08-05 11:39:42 +02:00
[ CONTROLLER_RESETACTIONMOVESELECTION ] = BtlController_Empty ,
2021-01-22 02:48:22 -05:00
[ CONTROLLER_ENDLINKBATTLE ] = LinkOpponentHandleEndLinkBattle ,
2023-08-05 11:39:42 +02:00
[ CONTROLLER_DEBUGMENU ] = BtlController_Empty ,
[ CONTROLLER_TERMINATOR_NOP ] = BtlController_TerminatorNop
2017-10-24 15:25:20 +02:00
} ;
2023-08-07 12:51:58 +02:00
void SetControllerToLinkOpponent ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
gBattlerControllerEndFuncs [ battler ] = LinkOpponentBufferExecCompleted ;
gBattlerControllerFuncs [ battler ] = LinkOpponentBufferRunCommand ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentBufferRunCommand ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( gBattleControllerExecFlags & gBitTable [ battler ] )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( gBattleResources - > bufferA [ battler ] [ 0 ] < ARRAY_COUNT ( sLinkOpponentBufferCommands ) )
sLinkOpponentBufferCommands [ gBattleResources - > bufferA [ battler ] [ 0 ] ] ( battler ) ;
2017-10-24 15:25:20 +02:00
else
2023-08-07 12:51:58 +02:00
LinkOpponentBufferExecCompleted ( battler ) ;
2017-10-24 15:25:20 +02:00
}
}
2023-08-07 12:51:58 +02:00
static void Intro_DelayAndEnd ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( - - gBattleSpritesDataPtr - > healthBoxesData [ battler ] . introEndDelay = = ( u8 ) - 1 )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . introEndDelay = 0 ;
LinkOpponentBufferExecCompleted ( battler ) ;
2017-10-24 15:25:20 +02:00
}
}
2023-08-07 12:51:58 +02:00
static void Intro_WaitForShinyAnimAndHealthbox ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2021-01-22 21:47:00 -05:00
bool32 healthboxAnimDone = FALSE ;
bool32 twoMons = FALSE ;
2017-10-24 15:25:20 +02:00
if ( ! IsDoubleBattle ( ) | | ( IsDoubleBattle ( ) & & ( gBattleTypeFlags & BATTLE_TYPE_MULTI ) ) )
{
2023-08-07 12:51:58 +02:00
if ( gSprites [ gHealthboxSpriteIds [ battler ] ] . callback = = SpriteCallbackDummy )
2021-01-22 21:47:00 -05:00
healthboxAnimDone = TRUE ;
2017-10-24 15:25:20 +02:00
}
else
{
2023-08-07 12:51:58 +02:00
if ( gSprites [ gHealthboxSpriteIds [ battler ] ] . callback = = SpriteCallbackDummy
& & gSprites [ gHealthboxSpriteIds [ BATTLE_PARTNER ( battler ) ] ] . callback = = SpriteCallbackDummy )
2017-10-24 15:25:20 +02:00
{
2021-01-22 21:47:00 -05:00
healthboxAnimDone = TRUE ;
2017-10-24 15:25:20 +02:00
}
2021-01-22 21:47:00 -05:00
twoMons = TRUE ;
2017-10-24 15:25:20 +02:00
}
2021-01-22 21:47:00 -05:00
if ( healthboxAnimDone )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( twoMons | | ! IsBattlerSpriteVisible ( BATTLE_PARTNER ( battler ) ) )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . finishedShinyMonAnim )
2017-10-24 15:25:20 +02:00
return ;
2023-08-07 12:51:58 +02:00
if ( ! gBattleSpritesDataPtr - > healthBoxesData [ BATTLE_PARTNER ( battler ) ] . finishedShinyMonAnim )
2017-10-24 15:25:20 +02:00
return ;
2023-08-07 12:51:58 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . triedShinyMonAnim = FALSE ;
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . finishedShinyMonAnim = FALSE ;
2017-10-24 15:25:20 +02:00
2023-08-07 12:51:58 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ BATTLE_PARTNER ( battler ) ] . triedShinyMonAnim = FALSE ;
gBattleSpritesDataPtr - > healthBoxesData [ BATTLE_PARTNER ( battler ) ] . finishedShinyMonAnim = FALSE ;
2017-10-24 15:25:20 +02:00
2021-01-22 20:03:21 -05:00
FreeSpriteTilesByTag ( ANIM_TAG_GOLD_STARS ) ;
FreeSpritePaletteByTag ( ANIM_TAG_GOLD_STARS ) ;
2017-10-24 15:25:20 +02:00
}
else
{
2023-08-07 12:51:58 +02:00
if ( ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . finishedShinyMonAnim )
2017-10-24 15:25:20 +02:00
return ;
2023-08-07 12:51:58 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . triedShinyMonAnim = FALSE ;
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . finishedShinyMonAnim = FALSE ;
2017-10-24 15:25:20 +02:00
2023-08-07 12:51:58 +02:00
if ( GetBattlerPosition ( battler ) = = B_POSITION_OPPONENT_RIGHT )
2017-10-24 15:25:20 +02:00
{
2021-01-22 20:03:21 -05:00
FreeSpriteTilesByTag ( ANIM_TAG_GOLD_STARS ) ;
FreeSpritePaletteByTag ( ANIM_TAG_GOLD_STARS ) ;
2017-10-24 15:25:20 +02:00
}
}
2023-08-07 12:51:58 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . introEndDelay = 3 ;
gBattlerControllerFuncs [ battler ] = Intro_DelayAndEnd ;
2017-10-24 15:25:20 +02:00
}
}
2023-08-07 12:51:58 +02:00
static void Intro_TryShinyAnimShowHealthbox ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2021-01-22 21:47:00 -05:00
bool32 bgmRestored = FALSE ;
2017-10-24 15:25:20 +02:00
2023-08-07 12:51:58 +02:00
if ( ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . ballAnimActive
& & ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . triedShinyMonAnim
& & ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . finishedShinyMonAnim )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
TryShinyAnimation ( battler , & gEnemyParty [ gBattlerPartyIndexes [ battler ] ] ) ;
2017-10-24 15:25:20 +02:00
}
if ( ! ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
2023-08-07 12:51:58 +02:00
& & ! gBattleSpritesDataPtr - > healthBoxesData [ BATTLE_PARTNER ( battler ) ] . ballAnimActive
& & ! gBattleSpritesDataPtr - > healthBoxesData [ BATTLE_PARTNER ( battler ) ] . triedShinyMonAnim
& & ! gBattleSpritesDataPtr - > healthBoxesData [ BATTLE_PARTNER ( battler ) ] . finishedShinyMonAnim )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
TryShinyAnimation ( BATTLE_PARTNER ( battler ) , & gEnemyParty [ gBattlerPartyIndexes [ BATTLE_PARTNER ( battler ) ] ] ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
if ( ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . ballAnimActive & & ! gBattleSpritesDataPtr - > healthBoxesData [ BATTLE_PARTNER ( battler ) ] . ballAnimActive )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . healthboxSlideInStarted )
2017-10-24 15:25:20 +02:00
{
if ( IsDoubleBattle ( ) & & ! ( gBattleTypeFlags & BATTLE_TYPE_MULTI ) )
{
2023-08-07 12:51:58 +02:00
UpdateHealthboxAttribute ( gHealthboxSpriteIds [ BATTLE_PARTNER ( battler ) ] , & gEnemyParty [ gBattlerPartyIndexes [ BATTLE_PARTNER ( battler ) ] ] , HEALTHBOX_ALL ) ;
StartHealthboxSlideIn ( BATTLE_PARTNER ( battler ) ) ;
SetHealthboxSpriteVisible ( gHealthboxSpriteIds [ BATTLE_PARTNER ( battler ) ] ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
UpdateHealthboxAttribute ( gHealthboxSpriteIds [ battler ] , & gEnemyParty [ gBattlerPartyIndexes [ battler ] ] , HEALTHBOX_ALL ) ;
StartHealthboxSlideIn ( battler ) ;
SetHealthboxSpriteVisible ( gHealthboxSpriteIds [ battler ] ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . healthboxSlideInStarted = TRUE ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
if ( ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . waitForCry
& & gBattleSpritesDataPtr - > healthBoxesData [ battler ] . healthboxSlideInStarted
& & ! gBattleSpritesDataPtr - > healthBoxesData [ BATTLE_PARTNER ( battler ) ] . waitForCry
2017-10-24 15:25:20 +02:00
& & ! IsCryPlayingOrClearCrySongs ( ) )
{
2023-08-07 12:51:58 +02:00
if ( ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . bgmRestored )
2017-10-24 15:25:20 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_MULTI & & gBattleTypeFlags & BATTLE_TYPE_LINK )
{
2023-08-07 12:51:58 +02:00
if ( GetBattlerPosition ( battler ) = = B_POSITION_OPPONENT_LEFT )
2018-01-09 21:30:54 -06:00
m4aMPlayContinue ( & gMPlayInfo_BGM ) ;
2017-10-24 15:25:20 +02:00
}
else
{
2021-10-09 11:33:37 -04:00
m4aMPlayVolumeControl ( & gMPlayInfo_BGM , TRACKS_ALL , 0x100 ) ;
2017-10-24 15:25:20 +02:00
}
}
2023-08-07 12:51:58 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . bgmRestored = TRUE ;
2021-01-22 21:47:00 -05:00
bgmRestored = TRUE ;
2017-10-24 15:25:20 +02:00
}
2021-01-22 21:47:00 -05:00
if ( bgmRestored )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( gSprites [ gBattleControllerData [ battler ] ] . callback = = SpriteCallbackDummy
& & gSprites [ gBattlerSpriteIds [ battler ] ] . callback = = SpriteCallbackDummy )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_MULTI & & GetBattlerPosition ( battler ) = = B_POSITION_OPPONENT_RIGHT )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( + + gBattleSpritesDataPtr - > healthBoxesData [ battler ] . introEndDelay = = 1 )
2017-10-24 15:25:20 +02:00
return ;
2023-08-07 12:51:58 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . introEndDelay = 0 ;
2017-10-24 15:25:20 +02:00
}
if ( IsDoubleBattle ( ) & & ! ( gBattleTypeFlags & BATTLE_TYPE_MULTI ) )
{
2023-08-07 12:51:58 +02:00
DestroySprite ( & gSprites [ gBattleControllerData [ BATTLE_PARTNER ( battler ) ] ] ) ;
SetBattlerShadowSpriteCallback ( BATTLE_PARTNER ( battler ) , GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ BATTLE_PARTNER ( battler ) ] ] , MON_DATA_SPECIES ) ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
DestroySprite ( & gSprites [ gBattleControllerData [ battler ] ] ) ;
SetBattlerShadowSpriteCallback ( battler , GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ battler ] ] , MON_DATA_SPECIES ) ) ;
2017-10-24 15:25:20 +02:00
2021-01-22 20:03:21 -05:00
gBattleSpritesDataPtr - > animationData - > introAnimActive = FALSE ;
2023-08-07 12:51:58 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . bgmRestored = FALSE ;
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . healthboxSlideInStarted = FALSE ;
2017-10-24 15:25:20 +02:00
2023-08-07 12:51:58 +02:00
gBattlerControllerFuncs [ battler ] = Intro_WaitForShinyAnimAndHealthbox ;
2017-10-24 15:25:20 +02:00
}
}
}
2023-08-07 12:51:58 +02:00
static void TryShinyAnimAfterMonAnim ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( gSprites [ gBattlerSpriteIds [ battler ] ] . callback = = SpriteCallbackDummy
& & gSprites [ gBattlerSpriteIds [ battler ] ] . x2 = = 0 )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . triedShinyMonAnim )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
TryShinyAnimation ( battler , & gEnemyParty [ gBattlerPartyIndexes [ battler ] ] ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
else if ( gBattleSpritesDataPtr - > healthBoxesData [ battler ] . finishedShinyMonAnim )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . triedShinyMonAnim = FALSE ;
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . finishedShinyMonAnim = FALSE ;
2022-08-18 14:23:45 -04:00
FreeSpriteTilesByTag ( ANIM_TAG_GOLD_STARS ) ;
FreeSpritePaletteByTag ( ANIM_TAG_GOLD_STARS ) ;
2023-08-07 12:51:58 +02:00
LinkOpponentBufferExecCompleted ( battler ) ;
2017-10-24 15:25:20 +02:00
}
}
}
2023-08-07 12:51:58 +02:00
static void SwitchIn_ShowSubstitute ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( gSprites [ gHealthboxSpriteIds [ battler ] ] . callback = = SpriteCallbackDummy )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( gBattleSpritesDataPtr - > battlerData [ battler ] . behindSubstitute )
InitAndLaunchSpecialAnimation ( battler , battler , battler , B_ANIM_MON_TO_SUBSTITUTE ) ;
2017-10-24 15:25:20 +02:00
2023-08-07 12:51:58 +02:00
gBattlerControllerFuncs [ battler ] = SwitchIn_HandleSoundAndEnd ;
2017-10-24 15:25:20 +02:00
}
}
2023-08-07 12:51:58 +02:00
static void SwitchIn_HandleSoundAndEnd ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . specialAnimActive & & ! IsCryPlayingOrClearCrySongs ( ) )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( gSprites [ gBattlerSpriteIds [ battler ] ] . callback = = SpriteCallbackDummy
| | gSprites [ gBattlerSpriteIds [ battler ] ] . callback = = SpriteCallbackDummy_2 )
2017-10-24 15:25:20 +02:00
{
2021-10-09 11:33:37 -04:00
m4aMPlayVolumeControl ( & gMPlayInfo_BGM , TRACKS_ALL , 0x100 ) ;
2023-08-07 12:51:58 +02:00
LinkOpponentBufferExecCompleted ( battler ) ;
2017-10-24 15:25:20 +02:00
}
}
}
2023-08-07 12:51:58 +02:00
static void SwitchIn_ShowHealthbox ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( gBattleSpritesDataPtr - > healthBoxesData [ battler ] . finishedShinyMonAnim
& & gSprites [ gBattlerSpriteIds [ battler ] ] . callback = = SpriteCallbackDummy )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . triedShinyMonAnim = FALSE ;
gBattleSpritesDataPtr - > healthBoxesData [ battler ] . finishedShinyMonAnim = FALSE ;
2017-10-24 15:25:20 +02:00
2021-01-22 20:03:21 -05:00
FreeSpriteTilesByTag ( ANIM_TAG_GOLD_STARS ) ;
FreeSpritePaletteByTag ( ANIM_TAG_GOLD_STARS ) ;
2017-10-24 15:25:20 +02:00
2023-08-07 12:51:58 +02:00
StartSpriteAnim ( & gSprites [ gBattlerSpriteIds [ battler ] ] , 0 ) ;
2017-10-24 15:25:20 +02:00
2023-08-07 12:51:58 +02:00
UpdateHealthboxAttribute ( gHealthboxSpriteIds [ battler ] , & gEnemyParty [ gBattlerPartyIndexes [ battler ] ] , HEALTHBOX_ALL ) ;
StartHealthboxSlideIn ( battler ) ;
SetHealthboxSpriteVisible ( gHealthboxSpriteIds [ battler ] ) ;
CopyBattleSpriteInvisibility ( battler ) ;
gBattlerControllerFuncs [ battler ] = SwitchIn_ShowSubstitute ;
2017-10-24 15:25:20 +02:00
}
}
2023-08-07 12:51:58 +02:00
static void SwitchIn_TryShinyAnim ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . ballAnimActive
& & ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . triedShinyMonAnim )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
TryShinyAnimation ( battler , & gEnemyParty [ gBattlerPartyIndexes [ battler ] ] ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
if ( gSprites [ gBattleControllerData [ battler ] ] . callback = = SpriteCallbackDummy
& & ! gBattleSpritesDataPtr - > healthBoxesData [ battler ] . ballAnimActive )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
DestroySprite ( & gSprites [ gBattleControllerData [ battler ] ] ) ;
SetBattlerShadowSpriteCallback ( battler , GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ battler ] ] , MON_DATA_SPECIES ) ) ;
gBattlerControllerFuncs [ battler ] = SwitchIn_ShowHealthbox ;
2017-10-24 15:25:20 +02:00
}
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentBufferExecCompleted ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
gBattlerControllerFuncs [ battler ] = LinkOpponentBufferRunCommand ;
2017-10-24 15:25:20 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_LINK )
{
u8 playerId = GetMultiplayerId ( ) ;
2023-08-29 15:21:31 +02:00
PrepareBufferDataTransferLink ( battler , 2 , 4 , & playerId ) ;
2023-08-07 12:51:58 +02:00
gBattleResources - > bufferA [ battler ] [ 0 ] = CONTROLLER_TERMINATOR_NOP ;
2017-10-24 15:25:20 +02:00
}
else
{
2023-08-07 12:51:58 +02:00
gBattleControllerExecFlags & = ~ gBitTable [ battler ] ;
2017-10-24 15:25:20 +02:00
}
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandleLoadMonSprite ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-21 09:43:01 +02:00
BtlController_HandleLoadMonSprite ( battler , TryShinyAnimAfterMonAnim ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandleSwitchInAnim ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
BtlController_HandleSwitchInAnim ( battler , FALSE , SwitchIn_TryShinyAnim ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandleDrawTrainerPic ( u32 battler )
2017-10-24 15:25:20 +02:00
{
s16 xPos ;
u32 trainerPicId ;
if ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
{
2023-08-07 12:51:58 +02:00
if ( ( GetBattlerPosition ( battler ) & BIT_FLANK ) ! = 0 ) // second mon
2017-10-24 15:25:20 +02:00
xPos = 152 ;
else // first mon
xPos = 200 ;
if ( gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER )
{
2023-08-07 12:51:58 +02:00
if ( battler = = B_POSITION_OPPONENT_LEFT )
2017-10-24 15:25:20 +02:00
trainerPicId = GetFrontierTrainerFrontSpriteId ( gTrainerBattleOpponent_A ) ;
else
trainerPicId = GetFrontierTrainerFrontSpriteId ( gTrainerBattleOpponent_B ) ;
}
else
{
2023-08-07 12:51:58 +02:00
if ( ( gLinkPlayers [ GetBattlerMultiplayerId ( battler ) ] . version & 0xFF ) = = VERSION_FIRE_RED
| | ( gLinkPlayers [ GetBattlerMultiplayerId ( battler ) ] . version & 0xFF ) = = VERSION_LEAF_GREEN )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( gLinkPlayers [ GetBattlerMultiplayerId ( battler ) ] . gender ! = MALE )
2018-12-02 22:35:11 -05:00
trainerPicId = gFacilityClassToPicIndex [ FACILITY_CLASS_LEAF ] ;
2017-10-24 15:25:20 +02:00
else
2018-12-02 22:35:11 -05:00
trainerPicId = gFacilityClassToPicIndex [ FACILITY_CLASS_RED ] ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
else if ( ( gLinkPlayers [ GetBattlerMultiplayerId ( battler ) ] . version & 0xFF ) = = VERSION_RUBY
| | ( gLinkPlayers [ GetBattlerMultiplayerId ( battler ) ] . version & 0xFF ) = = VERSION_SAPPHIRE )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
if ( gLinkPlayers [ GetBattlerMultiplayerId ( battler ) ] . gender ! = MALE )
2018-12-02 22:35:11 -05:00
trainerPicId = gFacilityClassToPicIndex [ FACILITY_CLASS_RS_MAY ] ;
2017-10-24 15:25:20 +02:00
else
2018-12-02 22:35:11 -05:00
trainerPicId = gFacilityClassToPicIndex [ FACILITY_CLASS_RS_BRENDAN ] ;
2017-10-24 15:25:20 +02:00
}
else
{
2023-08-07 12:51:58 +02:00
trainerPicId = PlayerGenderToFrontTrainerPicId ( gLinkPlayers [ GetBattlerMultiplayerId ( battler ) ] . gender ) ;
2017-10-24 15:25:20 +02:00
}
}
}
else
{
xPos = 176 ;
2020-06-03 15:28:29 -04:00
if ( gTrainerBattleOpponent_A = = TRAINER_UNION_ROOM )
2017-10-24 15:25:20 +02:00
{
2020-06-03 15:28:29 -04:00
trainerPicId = GetUnionRoomTrainerPic ( ) ;
2017-10-24 15:25:20 +02:00
}
else if ( ( gLinkPlayers [ GetMultiplayerId ( ) ^ BIT_SIDE ] . version & 0xFF ) = = VERSION_FIRE_RED
| | ( gLinkPlayers [ GetMultiplayerId ( ) ^ BIT_SIDE ] . version & 0xFF ) = = VERSION_LEAF_GREEN )
{
2019-02-02 15:53:47 -06:00
if ( gLinkPlayers [ GetMultiplayerId ( ) ^ BIT_SIDE ] . gender ! = MALE )
2018-12-02 22:35:11 -05:00
trainerPicId = gFacilityClassToPicIndex [ FACILITY_CLASS_LEAF ] ;
2017-10-24 15:25:20 +02:00
else
2018-12-02 22:35:11 -05:00
trainerPicId = gFacilityClassToPicIndex [ FACILITY_CLASS_RED ] ;
2017-10-24 15:25:20 +02:00
}
else if ( ( gLinkPlayers [ GetMultiplayerId ( ) ^ BIT_SIDE ] . version & 0xFF ) = = VERSION_RUBY
| | ( gLinkPlayers [ GetMultiplayerId ( ) ^ BIT_SIDE ] . version & 0xFF ) = = VERSION_SAPPHIRE )
{
2019-02-02 15:53:47 -06:00
if ( gLinkPlayers [ GetMultiplayerId ( ) ^ BIT_SIDE ] . gender ! = MALE )
2018-12-02 22:35:11 -05:00
trainerPicId = gFacilityClassToPicIndex [ FACILITY_CLASS_RS_MAY ] ;
2017-10-24 15:25:20 +02:00
else
2018-12-02 22:35:11 -05:00
trainerPicId = gFacilityClassToPicIndex [ FACILITY_CLASS_RS_BRENDAN ] ;
2017-10-24 15:25:20 +02:00
}
else
{
trainerPicId = PlayerGenderToFrontTrainerPicId ( gLinkPlayers [ GetMultiplayerId ( ) ^ BIT_SIDE ] . gender ) ;
}
}
2023-08-07 12:51:58 +02:00
BtlController_HandleDrawTrainerPic ( battler , trainerPicId , TRUE ,
2023-08-06 21:50:59 +02:00
xPos , 40 + 4 * ( 8 - gTrainerFrontPicCoords [ trainerPicId ] . size ) ,
- 1 ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandleTrainerSlide ( u32 battler )
2017-10-24 15:25:20 +02:00
{
u32 trainerPicId ;
2023-08-07 12:51:58 +02:00
if ( battler = = B_POSITION_OPPONENT_LEFT )
2017-10-24 15:25:20 +02:00
trainerPicId = GetFrontierTrainerFrontSpriteId ( gTrainerBattleOpponent_A ) ;
else
trainerPicId = GetFrontierTrainerFrontSpriteId ( gTrainerBattleOpponent_B ) ;
2023-08-07 12:51:58 +02:00
BtlController_HandleTrainerSlide ( battler , trainerPicId ) ;
LinkOpponentBufferExecCompleted ( battler ) ; // Possibly a bug, because execution should be completed after the slide in finishes. See Controller_WaitForTrainerPic.
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandleTrainerSlideBack ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
BtlController_HandleTrainerSlideBack ( battler , 35 , FALSE ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandleMoveAnimation ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
BtlController_HandleMoveAnimation ( battler , TRUE ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandlePrintString ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
BtlController_HandlePrintString ( battler , TRUE , FALSE ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandleHealthBarUpdate ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
BtlController_HandleHealthBarUpdate ( battler , FALSE ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandleIntroTrainerBallThrow ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
BtlController_HandleIntroTrainerBallThrow ( battler , 0 , NULL , 0 , Intro_TryShinyAnimShowHealthbox ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandleDrawPartyStatusSummary ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
BtlController_HandleDrawPartyStatusSummary ( battler , B_SIDE_OPPONENT , TRUE ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandleBattleAnimation ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
BtlController_HandleBattleAnimation ( battler , FALSE , TRUE ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandleLinkStandbyMsg ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
RecordedBattle_RecordAllBattlerData ( & gBattleResources - > bufferA [ battler ] [ 2 ] ) ;
LinkOpponentBufferExecCompleted ( battler ) ;
2017-10-24 15:25:20 +02:00
}
2023-08-07 12:51:58 +02:00
static void LinkOpponentHandleEndLinkBattle ( u32 battler )
2017-10-24 15:25:20 +02:00
{
2023-08-07 12:51:58 +02:00
RecordedBattle_RecordAllBattlerData ( & gBattleResources - > bufferA [ battler ] [ 4 ] ) ;
2017-10-24 15:25:20 +02:00
2023-08-07 12:51:58 +02:00
if ( gBattleResources - > bufferA [ battler ] [ 1 ] = = B_OUTCOME_DREW )
gBattleOutcome = gBattleResources - > bufferA [ battler ] [ 1 ] ;
2017-10-24 15:25:20 +02:00
else
2023-08-07 12:51:58 +02:00
gBattleOutcome = gBattleResources - > bufferA [ battler ] [ 1 ] ^ B_OUTCOME_DREW ;
2017-10-24 15:25:20 +02:00
2023-08-07 12:51:58 +02:00
gSaveBlock2Ptr - > frontier . disableRecordBattle = gBattleResources - > bufferA [ battler ] [ 2 ] ;
2017-10-24 15:25:20 +02:00
FadeOutMapMusic ( 5 ) ;
BeginFastPaletteFade ( 3 ) ;
2023-08-07 12:51:58 +02:00
LinkOpponentBufferExecCompleted ( battler ) ;
gBattlerControllerFuncs [ battler ] = SetBattleEndCallbacks ;
2017-10-24 15:25:20 +02:00
}