diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/battle_controller_link_opponent.c | 1686 | ||||
-rw-r--r-- | src/battle_controller_opponent.c | 2 | ||||
-rw-r--r-- | src/battle_controller_player.c | 4 | ||||
-rw-r--r-- | src/battle_util.c | 2 | ||||
-rw-r--r-- | src/pokemon.c | 4 |
5 files changed, 1692 insertions, 6 deletions
diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c new file mode 100644 index 000000000..72d3a42fc --- /dev/null +++ b/src/battle_controller_link_opponent.c @@ -0,0 +1,1686 @@ +#include "global.h" +#include "bg.h" +#include "data2.h" +#include "link.h" +#include "main.h" +#include "m4a.h" +#include "palette.h" +#include "pokeball.h" +#include "pokemon.h" +#include "reshow_battle_screen.h" +#include "sound.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "util.h" +#include "window.h" +#include "battle.h" +#include "battle_ai_script_commands.h" +#include "battle_anim.h" +#include "battle_controllers.h" +#include "battle_interface.h" +#include "battle_message.h" +#include "battle_setup.h" +#include "battle_tower.h" +#include "constants/battle_anim.h" +#include "constants/songs.h" +#include "constants/facility_trainer_classes.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 LinkOpponentHandleUnknownYesNoBox(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 LinkOpponentHandleCmd37(void); +static void LinkOpponentHandleCmd38(void); +static void LinkOpponentHandleCmd39(void); +static void LinkOpponentHandleCmd40(void); +static void LinkOpponentHandleHitAnimation(void); +static void LinkOpponentHandleCmd42(void); +static void LinkOpponentHandlePlaySE(void); +static void LinkOpponentHandlePlayFanfare(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 LinkOpponentHandleCmd55(void); +static void LinkOpponentCmdEnd(void); + +static void LinkOpponentBufferRunCommand(void); +static void LinkOpponentBufferExecCompleted(void); +static u32 CopyLinkOpponentMonData(u8 monId, u8 *dst); +static void SetLinkOpponentMonData(u8 monId); +static void DoSwitchOutAnimation(void); +static void LinkOpponentDoMoveAnimation(void); +static void sub_803AEDC(void); +static void sub_803C550(u8 battlerId, bool8 dontClearSubstituteBit); +static void sub_803D564(u8 taskId); +static void sub_803D648(struct Sprite *sprite); +static void sub_803D790(void); + +static void (*const sLinkOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(void) = +{ + LinkOpponentHandleGetMonData, + LinkOpponentHandleGetRawMonData, + LinkOpponentHandleSetMonData, + LinkOpponentHandleSetRawMonData, + LinkOpponentHandleLoadMonSprite, + LinkOpponentHandleSwitchInAnim, + LinkOpponentHandleReturnMonToBall, + LinkOpponentHandleDrawTrainerPic, + LinkOpponentHandleTrainerSlide, + LinkOpponentHandleTrainerSlideBack, + LinkOpponentHandleFaintAnimation, + LinkOpponentHandlePaletteFade, + LinkOpponentHandleSuccessBallThrowAnim, + LinkOpponentHandleBallThrowAnim, + LinkOpponentHandlePause, + LinkOpponentHandleMoveAnimation, + LinkOpponentHandlePrintString, + LinkOpponentHandlePrintSelectionString, + LinkOpponentHandleChooseAction, + LinkOpponentHandleUnknownYesNoBox, + LinkOpponentHandleChooseMove, + LinkOpponentHandleChooseItem, + LinkOpponentHandleChoosePokemon, + LinkOpponentHandleCmd23, + LinkOpponentHandleHealthBarUpdate, + LinkOpponentHandleExpUpdate, + LinkOpponentHandleStatusIconUpdate, + LinkOpponentHandleStatusAnimation, + LinkOpponentHandleStatusXor, + LinkOpponentHandleDataTransfer, + LinkOpponentHandleDMA3Transfer, + LinkOpponentHandlePlayBGM, + LinkOpponentHandleCmd32, + LinkOpponentHandleTwoReturnValues, + LinkOpponentHandleChosenMonReturnValue, + LinkOpponentHandleOneReturnValue, + LinkOpponentHandleOneReturnValue_Duplicate, + LinkOpponentHandleCmd37, + LinkOpponentHandleCmd38, + LinkOpponentHandleCmd39, + LinkOpponentHandleCmd40, + LinkOpponentHandleHitAnimation, + LinkOpponentHandleCmd42, + LinkOpponentHandlePlaySE, + LinkOpponentHandlePlayFanfare, + LinkOpponentHandleFaintingCry, + LinkOpponentHandleIntroSlide, + LinkOpponentHandleIntroTrainerBallThrow, + LinkOpponentHandleDrawPartyStatusSummary, + LinkOpponentHandleHidePartyStatusSummary, + LinkOpponentHandleEndBounceEffect, + LinkOpponentHandleSpriteInvisibility, + LinkOpponentHandleBattleAnimation, + LinkOpponentHandleLinkStandbyMsg, + LinkOpponentHandleResetActionMoveSelection, + LinkOpponentHandleCmd55, + LinkOpponentCmdEnd +}; + + +static void nullsub_19(void) +{ +} + +void SetControllerToLinkOpponent(void) +{ + gBattlerControllerFuncs[gActiveBattler] = LinkOpponentBufferRunCommand; +} + +static void LinkOpponentBufferRunCommand(void) +{ + if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) + { + if (gBattleBufferA[gActiveBattler][0] < NELEMS(sLinkOpponentBufferCommands)) + sLinkOpponentBufferCommands[gBattleBufferA[gActiveBattler][0]](); + else + LinkOpponentBufferExecCompleted(); + } +} + +static void CompleteOnBattlerSpriteCallbackDummy(void) +{ + if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + LinkOpponentBufferExecCompleted(); +} + +static void sub_803A70C(void) +{ + if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + { + FreeTrainerFrontPicPaletteAndTile(gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam); + gSprites[gBattlerSpriteIds[gActiveBattler]].oam.tileNum = gSprites[gBattlerSpriteIds[gActiveBattler]].data[5]; + FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); + LinkOpponentBufferExecCompleted(); + } +} + +static void sub_803A79C(void) +{ + if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_9 == 0xFF) + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_9 = 0; + LinkOpponentBufferExecCompleted(); + } +} + +static void sub_803A7E4(void) +{ + bool8 var = FALSE; + + if (!IsDoubleBattle() || ((IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)))) + { + if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + var = TRUE; + } + else if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK]].callback == gSprites[gHealthboxSpriteIds[gActiveBattler]].callback) + { + var = TRUE; + } + if (IsCryPlayingOrClearCrySongs()) + var = FALSE; + if (var) + { + if (GetBattlerPosition(gActiveBattler) == B_POSITION_OPPONENT_LEFT) + { + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1 + || !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].field_1_x1) + return; + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].flag_x80 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].field_1_x1 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + } + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (GetBattlerPosition(gActiveBattler) == B_POSITION_OPPONENT_LEFT) + m4aMPlayContinue(&gMPlayInfo_BGM); + } + else + { + m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 256); + } + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_9 = 3; + gBattlerControllerFuncs[gActiveBattler] = sub_803A79C; + } +} + +static void sub_803A9CC(void) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive + && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive) + { + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80) + sub_80F1720(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].flag_x80) + sub_80F1720(gActiveBattler ^ BIT_FLANK, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]); + if (gBattleTypeFlags & BATTLE_TYPE_MULTI && GetBattlerPosition(gActiveBattler) == 3) + { + if (++gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_9 == 1) + return; + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_9 = 0; + } + if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + DestroySprite(&gSprites[gUnknown_3004FFC[gActiveBattler ^ BIT_FLANK]]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK], + &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], + HEALTHBOX_ALL); + sub_804BD94(gActiveBattler ^ BIT_FLANK); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK]); + SetBattlerShadowSpriteCallback(gActiveBattler ^ BIT_FLANK, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]], MON_DATA_SPECIES)); + } + DestroySprite(&gSprites[gUnknown_3004FFC[gActiveBattler]]); + UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], + &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], + HEALTHBOX_ALL); + sub_804BD94(gActiveBattler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + gBattleSpritesDataPtr->animationData->field_9_x1 = 0; + gBattlerControllerFuncs[gActiveBattler] = sub_803A7E4; + } +} + +static void sub_803AC14(void) +{ + if (gSprites[gBattlerSpriteIds[gActiveBattler]].animEnded == TRUE + && gSprites[gBattlerSpriteIds[gActiveBattler]].pos2.x == 0) + { + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80) + { + sub_80F1720(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + } + else if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1) + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + LinkOpponentBufferExecCompleted(); + } + } +} + +static void CompleteOnHealthbarDone(void) +{ + s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0); + + SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + if (hpValue != -1) + UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT); + else + LinkOpponentBufferExecCompleted(); +} + +static void sub_803AD20(void) +{ + if (!gSprites[gBattlerSpriteIds[gActiveBattler]].inUse) + { + SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); + LinkOpponentBufferExecCompleted(); + } +} + +static void sub_803AD64(void) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive) + { + FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]); + HideBattlerShadowSprite(gActiveBattler); + SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]); + LinkOpponentBufferExecCompleted(); + } +} + +static void CompleteOnInactiveTextPrinter(void) +{ + if (!IsTextPrinterActive(0)) + 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)) + gSprites[spriteId].invisible ^= 1; + ++gSprites[spriteId].data[1]; + } +} + +static void sub_803AE6C(void) +{ + if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + { + if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute) + InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE); + gBattlerControllerFuncs[gActiveBattler] = sub_803AEDC; + } +} + +static void sub_803AEDC(void) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive && !IsCryPlayingOrClearCrySongs()) + { + m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 0x100); + LinkOpponentBufferExecCompleted(); + } +} + +static void sub_803AF28(void) +{ + if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1) + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 0); + UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_ALL); + sub_804BD94(gActiveBattler); + SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); + CopyBattleSpriteInvisibility(gActiveBattler); + gBattlerControllerFuncs[gActiveBattler] = sub_803AE6C; + } +} + +static void sub_803AFFC(void) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive + && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80) + sub_80F1720(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + + if (gSprites[gUnknown_3004FFC[gActiveBattler]].callback == SpriteCallbackDummy + && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive) + { + DestroySprite(&gSprites[gUnknown_3004FFC[gActiveBattler]]); + SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + gBattlerControllerFuncs[gActiveBattler] = sub_803AF28; + } +} + +static void CompleteOnFinishedStatusAnimation(void) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive) + LinkOpponentBufferExecCompleted(); +} + +static void CompleteOnFinishedBattleAnimation(void) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive) + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentBufferExecCompleted(void) +{ + gBattlerControllerFuncs[gActiveBattler] = LinkOpponentBufferRunCommand; + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + u8 playerId = GetMultiplayerId(); + + PrepareBufferDataTransferLink(2, 4, &playerId); + gBattleBufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP; + } + else + { + gBattleControllerExecFlags &= ~gBitTable[gActiveBattler]; + } +} + +static void LinkOpponentHandleGetMonData(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 (!gBattleBufferA[gActiveBattler][2]) + { + size += CopyLinkOpponentMonData(gBattlerPartyIndexes[gActiveBattler], monData); + } + else + { + monToCheck = gBattleBufferA[gActiveBattler][2]; + for (i = 0; i < PARTY_SIZE; ++i) + { + if (monToCheck & 1) + size += CopyLinkOpponentMonData(i, monData + size); + monToCheck >>= 1; + } + } + BtlController_EmitDataTransfer(1, size, monData); + LinkOpponentBufferExecCompleted(); +} + +static u32 CopyLinkOpponentMonData(u8 monId, u8 *dst) +{ + struct BattlePokemon battleMon; + struct MovePpInfo moveData; + u8 nickname[20]; + u8 *src; + s16 data16; + u32 data32; + s32 size = 0; + + switch (gBattleBufferA[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.isEgg = GetMonData(&gEnemyParty[monId], MON_DATA_IS_EGG); + battleMon.abilityNum = GetMonData(&gEnemyParty[monId], MON_DATA_ABILITY_NUM); + battleMon.otId = GetMonData(&gEnemyParty[monId], MON_DATA_OT_ID); + GetMonData(&gEnemyParty[monId], MON_DATA_NICKNAME, nickname); + StringCopy10(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 + gBattleBufferA[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 + gBattleBufferA[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 LinkOpponentHandleGetRawMonData(void) +{ + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleSetMonData(void) +{ + u8 monToCheck; + u8 i; + + if (!gBattleBufferA[gActiveBattler][2]) + { + SetLinkOpponentMonData(gBattlerPartyIndexes[gActiveBattler]); + } + else + { + monToCheck = gBattleBufferA[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 *)&gBattleBufferA[gActiveBattler][3]; + struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBattler][3]; + s32 i; + + switch (gBattleBufferA[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, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_HELDITEM_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM, &gBattleBufferA[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 + gBattleBufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_PP_DATA_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_PP1, &gBattleBufferA[gActiveBattler][3]); + SetMonData(&gEnemyParty[monId], MON_DATA_PP2, &gBattleBufferA[gActiveBattler][4]); + SetMonData(&gEnemyParty[monId], MON_DATA_PP3, &gBattleBufferA[gActiveBattler][5]); + SetMonData(&gEnemyParty[monId], MON_DATA_PP4, &gBattleBufferA[gActiveBattler][6]); + SetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES, &gBattleBufferA[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 + gBattleBufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_OTID_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_OT_ID, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_EXP_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_EXP, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_HP_EV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_HP_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_ATK_EV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_DEF_EV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_SPEED_EV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_SPATK_EV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_SPDEF_EV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_FRIENDSHIP_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_POKERUS_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_POKERUS, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_MET_LOCATION_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_MET_LEVEL_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_MET_GAME_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_POKEBALL_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_ALL_IVS_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); + SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][4]); + SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][5]); + SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][6]); + SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][7]); + SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][8]); + break; + case REQUEST_HP_IV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_ATK_IV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_DEF_IV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_SPEED_IV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_SPATK_IV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_SPDEF_IV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_PERSONALITY_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_CHECKSUM_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_STATUS_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_STATUS, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_LEVEL_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_LEVEL, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_HP_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_HP, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_MAX_HP_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_ATK_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_ATK, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_DEF_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_DEF, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_SPEED_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPEED, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_SPATK_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPATK, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_SPDEF_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_COOL_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_COOL, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_BEAUTY_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_CUTE_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_CUTE, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_SMART_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SMART, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_TOUGH_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_TOUGH, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_SHEEN_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SHEEN, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_COOL_RIBBON_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_BEAUTY_RIBBON_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_CUTE_RIBBON_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_SMART_RIBBON_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case REQUEST_TOUGH_RIBBON_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + } +} + +static void LinkOpponentHandleSetRawMonData(void) +{ + u8 *dst = (u8 *)&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1]; + u8 i; + + for (i = 0; i < gBattleBufferA[gActiveBattler][2]; ++i) + dst[i] = gBattleBufferA[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, 2), + GetBattlerSpriteDefault_Y(gActiveBattler), + GetBattlerSpriteSubpriority(gActiveBattler)); + gSprites[gBattlerSpriteIds[gActiveBattler]].pos2.x = -240; + gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = gActiveBattler; + gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; + StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], gBattleMonForms[gActiveBattler]); + SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + gBattlerControllerFuncs[gActiveBattler] = sub_803AC14; +} + +static void LinkOpponentHandleSwitchInAnim(void) +{ + gBattlerPartyIndexes[gActiveBattler] = gBattleBufferA[gActiveBattler][1]; + sub_803C550(gActiveBattler, gBattleBufferA[gActiveBattler][2]); + gBattlerControllerFuncs[gActiveBattler] = sub_803AFFC; +} + +static void sub_803C550(u8 battlerId, bool8 dontClearSubstituteBit) +{ + u16 species; + + ClearTemporarySpeciesSpriteData(battlerId, dontClearSubstituteBit); + gBattlerPartyIndexes[battlerId] = gBattleBufferA[battlerId][1]; + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + gUnknown_3004FFC[battlerId] = CreateInvisibleSpriteWithCallback(sub_8033E3C); + BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId); + SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battlerId)); + gBattlerSpriteIds[battlerId] = CreateSprite(&gMultiuseSpriteTemplate, + GetBattlerSpriteCoord(battlerId, 2), + GetBattlerSpriteDefault_Y(battlerId), + GetBattlerSpriteSubpriority(battlerId)); + gSprites[gUnknown_3004FFC[battlerId]].data[1] = gBattlerSpriteIds[battlerId]; + gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId; + gSprites[gBattlerSpriteIds[battlerId]].data[2] = species; + gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId; + StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], gBattleMonForms[battlerId]); + gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE; + gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy; + gSprites[gUnknown_3004FFC[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_OPPONENT_SENDOUT); +} + +static void LinkOpponentHandleReturnMonToBall(void) +{ + if (!gBattleBufferA[gActiveBattler][1]) + { + 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] = sub_803AD64; + } + break; + } +} + +static void LinkOpponentHandleDrawTrainerPic(void) +{ + s16 xPos; + u32 trainerPicId; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (GetBattlerPosition(gActiveBattler) & BIT_FLANK) // second mon + xPos = 152; + else // first mon + xPos = 200; + if ((gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_RUBY + || (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_SAPPHIRE + || (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].version & 0xFF) == VERSION_EMERALD) + { + if (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender != MALE) + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_5]; + else + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_2]; + } + else if (gLinkPlayers[GetBattlerMultiplayerId(gActiveBattler)].gender != MALE) + { + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PLAYER_4]; + } + else + { + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PLAYER_3]; + } + } + else + { + xPos = 176; + if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_C00) + { + trainerPicId = sub_80447AC(); + } + else if ((gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].version & 0xFF) == VERSION_RUBY + || (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].version & 0xFF) == VERSION_SAPPHIRE + || (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].version & 0xFF) == VERSION_EMERALD) + { + if (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].gender != MALE) + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_5]; + else + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_2]; + } + else if (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].gender != MALE) + { + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PLAYER_4]; + } + else + { + trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PLAYER_3]; + } + } + DecompressTrainerFrontPic(trainerPicId, gActiveBattler); + SetMultiuseSpriteTemplateToTrainerBack(trainerPicId, GetBattlerPosition(gActiveBattler)); + gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate, + xPos, + (8 - gTrainerFrontPicCoords[trainerPicId].size) * 4 + 40, + GetBattlerSpriteSubpriority(gActiveBattler)); + gSprites[gBattlerSpriteIds[gActiveBattler]].pos2.x = -240; + gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 2; + gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); + gSprites[gBattlerSpriteIds[gActiveBattler]].data[5] = gSprites[gBattlerSpriteIds[gActiveBattler]].oam.tileNum; + gSprites[gBattlerSpriteIds[gActiveBattler]].oam.tileNum = GetSpriteTileStartByTag(gTrainerFrontPicTable[trainerPicId].tag); + gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam = trainerPicId; + gSprites[gBattlerSpriteIds[gActiveBattler]].callback = sub_8033EEC; + gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy; +} + +static void LinkOpponentHandleTrainerSlide(void) +{ + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleTrainerSlideBack(void) +{ + SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]); + gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 35; + gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = 280; + gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].pos1.y; + gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], SpriteCallbackDummy); + gBattlerControllerFuncs[gActiveBattler] = sub_803A70C; +} + +static void LinkOpponentHandleFaintAnimation(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_POKE_DEAD, SOUND_PAN_TARGET); + gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_FaintOpponentMon; + gBattlerControllerFuncs[gActiveBattler] = sub_803AD20; + } + } +} + +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 (!mplay_80342A4(gActiveBattler)) + { + u16 move = gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8); + + gAnimMoveTurn = gBattleBufferA[gActiveBattler][3]; + gAnimMovePower = gBattleBufferA[gActiveBattler][4] | (gBattleBufferA[gActiveBattler][5] << 8); + gAnimMoveDmg = gBattleBufferA[gActiveBattler][6] | (gBattleBufferA[gActiveBattler][7] << 8) | (gBattleBufferA[gActiveBattler][8] << 16) | (gBattleBufferA[gActiveBattler][9] << 24); + gAnimFriendship = gBattleBufferA[gActiveBattler][10]; + gWeatherMoveAnim = gBattleBufferA[gActiveBattler][12] | (gBattleBufferA[gActiveBattler][13] << 8); + gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBattler][16]; + gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; + if (IsMoveWithoutAnimation(move, gAnimMoveTurn)) // always returns FALSE + { + LinkOpponentBufferExecCompleted(); + } + else + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0; + gBattlerControllerFuncs[gActiveBattler] = LinkOpponentDoMoveAnimation; + } + } +} + +static void LinkOpponentDoMoveAnimation(void) +{ + u16 move = gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8); + u8 multihit = gBattleBufferA[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) + { + sub_8035450(0); + DoMoveAnim(move); + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 2; + } + break; + case 2: + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + sub_8035450(1); + 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, gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[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 *)(&gBattleBufferA[gActiveBattler][2]); + BufferStringBattle(*stringId); + if (sub_80D89B0(*stringId)) + BattlePutTextOnWindow(gDisplayedStringBattle, 0x40); + else + BattlePutTextOnWindow(gDisplayedStringBattle, 0); + gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter; +} + +static void LinkOpponentHandlePrintSelectionString(void) +{ + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleChooseAction(void) +{ + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleUnknownYesNoBox(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 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[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 (!mplay_80342A4(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 (!mplay_80342A4(gActiveBattler)) + { + InitAndLaunchChosenStatusAnimation(gBattleBufferA[gActiveBattler][1], + gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8) | (gBattleBufferA[gActiveBattler][4] << 16) | (gBattleBufferA[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 LinkOpponentHandleCmd37(void) +{ + gUnknown_2022870.field_0 = 0; + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleCmd38(void) +{ + gUnknown_2022870.field_0 = gBattleBufferA[gActiveBattler][1]; + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleCmd39(void) +{ + gUnknown_2022870.flag_x80 = 0; + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleCmd40(void) +{ + gUnknown_2022870.flag_x80 ^= 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 LinkOpponentHandleCmd42(void) +{ + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandlePlaySE(void) +{ + s8 pan; + + if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) + pan = SOUND_PAN_ATTACKER; + else + pan = SOUND_PAN_TARGET; + PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan); + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandlePlayFanfare(void) +{ + PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleFaintingCry(void) +{ + u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); + + PlayCry3(species, 25, 5); + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleIntroSlide(void) +{ + HandleIntroSlide(gBattleBufferA[gActiveBattler][1]); + gIntroSlideFlags |= 1; + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleIntroTrainerBallThrow(void) +{ + u8 paletteNum, 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]].pos1.y; + gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], sub_803D648); + taskId = CreateTask(sub_803D564, 5); + gTasks[taskId].data[0] = gActiveBattler; + if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown) + gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary; + gBattleSpritesDataPtr->animationData->field_9_x1 = 1; + gBattlerControllerFuncs[gActiveBattler] = nullsub_19; +} + +static void sub_803D564(u8 taskId) +{ + u8 savedActiveBank = gActiveBattler; + + gActiveBattler = gTasks[taskId].data[0]; + if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_803C550(gActiveBattler, FALSE); + } + else + { + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_803C550(gActiveBattler, FALSE); + gActiveBattler = BATTLE_PARTNER(gActiveBattler); + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_803C550(gActiveBattler, FALSE); + gActiveBattler = BATTLE_PARTNER(gActiveBattler); + } + gBattlerControllerFuncs[gActiveBattler] = sub_803A9CC; + gActiveBattler = savedActiveBank; + DestroyTask(taskId); +} + +static void sub_803D648(struct Sprite *sprite) +{ + FreeTrainerFrontPicPaletteAndTile(sprite->oam.affineParam); + sprite->oam.tileNum = sprite->data[5]; + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); +} + +static void LinkOpponentHandleDrawPartyStatusSummary(void) +{ + if (gBattleBufferA[gActiveBattler][1] && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) + { + LinkOpponentBufferExecCompleted(); + } + else + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown = 1; + + if (gBattleBufferA[gActiveBattler][2]) + { + if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1E < 2) + { + ++gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1E; + return; + } + else + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1E = 0; + } + } + gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler, (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_5 = 0; + if (gBattleBufferA[gActiveBattler][2]) + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_5 = 0x5D; + gBattlerControllerFuncs[gActiveBattler] = sub_803D790; + } +} + +static void sub_803D790(void) +{ + if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_5++ > 0x5C) + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_5 = 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 = gBattleBufferA[gActiveBattler][1]; + CopyBattleSpriteInvisibility(gActiveBattler); + } + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleBattleAnimation(void) +{ + if (!mplay_80342A4(gActiveBattler)) + { + u8 animationId = gBattleBufferA[gActiveBattler][1]; + u16 argument = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + + if (TryHandleLaunchBattleTableAnimation(gActiveBattler, gActiveBattler, gActiveBattler, animationId, argument)) + LinkOpponentBufferExecCompleted(); + else + gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation; + } +} + +static void LinkOpponentHandleLinkStandbyMsg(void) +{ + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleResetActionMoveSelection(void) +{ + LinkOpponentBufferExecCompleted(); +} + +static void LinkOpponentHandleCmd55(void) +{ + if (gBattleBufferA[gActiveBattler][1] == B_OUTCOME_DREW) + gBattleOutcome = gBattleBufferA[gActiveBattler][1]; + else + gBattleOutcome = gBattleBufferA[gActiveBattler][1] ^ B_OUTCOME_DREW; + FadeOutMapMusic(5); + BeginFastPaletteFade(3); + LinkOpponentBufferExecCompleted(); + gBattlerControllerFuncs[gActiveBattler] = sub_802F6A8; +} + +static void LinkOpponentCmdEnd(void) +{ +} diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index c925e3af1..e5288194b 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -178,7 +178,7 @@ static void OpponentBufferRunCommand(void) { if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) { - if (gBattleBufferA[gActiveBattler][0] < ARRAY_COUNT(sOpponentBufferCommands)) + if (gBattleBufferA[gActiveBattler][0] < NELEMS(sOpponentBufferCommands)) sOpponentBufferCommands[gBattleBufferA[gActiveBattler][0]](); else OpponentBufferExecCompleted(); diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index cdf72e4e1..0b1257e1a 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -211,7 +211,7 @@ static void PlayerBufferRunCommand(void) { if (gBattleControllerExecFlags & gBitTable[gActiveBattler]) { - if (gBattleBufferA[gActiveBattler][0] < ARRAY_COUNT(sPlayerBufferCommands)) + if (gBattleBufferA[gActiveBattler][0] < NELEMS(sPlayerBufferCommands)) sPlayerBufferCommands[gBattleBufferA[gActiveBattler][0]](); else PlayerBufferExecCompleted(); @@ -329,7 +329,7 @@ static void HandleInputChooseTarget(void) s32 i; u8 identities[4]; - memcpy(identities, sTargetIdentities, ARRAY_COUNT(sTargetIdentities)); + memcpy(identities, sTargetIdentities, NELEMS(sTargetIdentities)); DoBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX, 15, 1); i = 0; if (gBattlersCount != 0) diff --git a/src/battle_util.c b/src/battle_util.c index cf91b122f..83d24f5e1 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1482,7 +1482,7 @@ bool8 HasNoMonsToSwitch(u8 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2) { if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { - playerId = GetBankMultiplayerId(battler); + playerId = GetBattlerMultiplayerId(battler); if (GetBattlerSide(battler) == B_SIDE_PLAYER) party = gPlayerParty; else diff --git a/src/pokemon.c b/src/pokemon.c index 94cf8f607..d840efa91 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -6482,7 +6482,7 @@ bool8 GetLinkTrainerFlankId(u8 linkPlayerId) return retVal; } -s32 GetBankMultiplayerId(u16 a1) +s32 GetBattlerMultiplayerId(u16 a1) { s32 id; for (id = 0; id < MAX_LINK_PLAYERS; id++) @@ -7133,7 +7133,7 @@ static bool8 IsShinyOtIdPersonality(u32 otId, u32 personality) u8 *GetTrainerPartnerName(void) { u8 id = GetMultiplayerId(); - return gLinkPlayers[GetBankMultiplayerId(gLinkPlayers[id].id ^ 2)].name; + return gLinkPlayers[GetBattlerMultiplayerId(gLinkPlayers[id].id ^ 2)].name; } u8 GetPlayerPartyHighestLevel(void) |