diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/battle_controller_link_opponent.c | 19 | ||||
-rw-r--r-- | src/battle_controller_opponent.c | 1491 | ||||
-rw-r--r-- | src/battle_dome_cards.c | 6 | ||||
-rw-r--r-- | src/pokemon_2.c | 4 | ||||
-rw-r--r-- | src/pokemon_3.c | 4 |
5 files changed, 1500 insertions, 24 deletions
diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c index b8e82fe60..95cb80146 100644 --- a/src/battle_controller_link_opponent.c +++ b/src/battle_controller_link_opponent.c @@ -55,9 +55,8 @@ extern u16 gTrainerBattleOpponent_A; extern u16 gTrainerBattleOpponent_B; extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; -extern const struct CompressedSpritePalette gTrainerBackPicPaletteTable[]; extern const struct BattleMove gBattleMoves[]; -extern const u8 gUnknown_0831F578[]; +extern const u8 gTrainerClassToFrontPicId[]; extern void sub_8172EF0(u8 bank, struct Pokemon *mon); extern void sub_806A068(u16, u8); @@ -1291,17 +1290,17 @@ static void LinkOpponentHandleDrawTrainerPic(void) || (gLinkPlayers[GetBankMultiplayerId(gActiveBank)].version & 0xFF) == VERSION_LEAF_GREEN) { if (gLinkPlayers[GetBankMultiplayerId(gActiveBank)].gender != 0) - trainerPicId = gUnknown_0831F578[0x4F]; + trainerPicId = gTrainerClassToFrontPicId[0x4F]; else - trainerPicId = gUnknown_0831F578[0x4E]; + trainerPicId = gTrainerClassToFrontPicId[0x4E]; } else if ((gLinkPlayers[GetBankMultiplayerId(gActiveBank)].version & 0xFF) == VERSION_RUBY || (gLinkPlayers[GetBankMultiplayerId(gActiveBank)].version & 0xFF) == VERSION_SAPPHIRE) { if (gLinkPlayers[GetBankMultiplayerId(gActiveBank)].gender != 0) - trainerPicId = gUnknown_0831F578[0x51]; + trainerPicId = gTrainerClassToFrontPicId[0x51]; else - trainerPicId = gUnknown_0831F578[0x50]; + trainerPicId = gTrainerClassToFrontPicId[0x50]; } else { @@ -1320,17 +1319,17 @@ static void LinkOpponentHandleDrawTrainerPic(void) || (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].version & 0xFF) == VERSION_LEAF_GREEN) { if (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].gender != 0) - trainerPicId = gUnknown_0831F578[0x4F]; + trainerPicId = gTrainerClassToFrontPicId[0x4F]; else - trainerPicId = gUnknown_0831F578[0x4E]; + trainerPicId = gTrainerClassToFrontPicId[0x4E]; } else if ((gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].version & 0xFF) == VERSION_RUBY || (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].version & 0xFF) == VERSION_SAPPHIRE) { if (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].gender != 0) - trainerPicId = gUnknown_0831F578[0x51]; + trainerPicId = gTrainerClassToFrontPicId[0x51]; else - trainerPicId = gUnknown_0831F578[0x50]; + trainerPicId = gTrainerClassToFrontPicId[0x50]; } else { diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index e55d78912..664d12142 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -4,12 +4,59 @@ #include "battle_message.h" #include "battle_interface.h" #include "battle_anim.h" +#include "battle_link_817C95C.h" +#include "battle_ai_script_commands.h" +#include "pokemon.h" #include "link.h" +#include "util.h" +#include "main.h" +#include "item.h" +#include "items.h" +#include "songs.h" +#include "sound.h" +#include "moves.h" +#include "window.h" +#include "m4a.h" +#include "palette.h" +#include "task.h" +#include "text.h" +#include "string_util.h" +#include "bg.h" +#include "reshow_battle_screen.h" +#include "rng.h" +#include "pokeball.h" +extern u32 gBattleExecBuffer; extern u8 gActiveBank; +extern u8 gBankTarget; +extern u8 gAbsentBankFlags; extern bool8 gDoingBattleAnim; extern u8 gUnknown_020244CC; +extern u16 gBattlePartyID[BATTLE_BANKS_COUNT]; +extern u8 gBankSpriteIds[BATTLE_BANKS_COUNT]; +extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200]; +extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200]; +extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT]; +extern struct MusicPlayerInfo gMPlay_BGM; +extern u8 gUnknown_03005D7C[BATTLE_BANKS_COUNT]; extern void (*gBattleBankFunc[BATTLE_BANKS_COUNT])(void); +extern void *gUnknown_020244D8; +extern void *gUnknown_020244DC; +extern u8 gBattleMonForms[BATTLE_BANKS_COUNT]; +extern struct SpriteTemplate gUnknown_0202499C; +extern struct UnusedControllerStruct gUnknown_02022D0C; +extern u16 gTrainerBattleOpponent_A; +extern u16 gTrainerBattleOpponent_B; +extern u32 gTransformedPersonalities[BATTLE_BANKS_COUNT]; +extern u16 gBattle_BG0_X; +extern u16 gBattle_BG0_Y; + +extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; +extern const struct BattleMove gBattleMoves[]; + +extern void sub_8172EF0(u8 bank, struct Pokemon *mon); +extern void sub_806A068(u16, u8); +extern void sub_81A57E4(u8 bank, u16 stringId); // this file's functions void OpponentHandleGetMonData(void); @@ -23,15 +70,15 @@ void OpponentHandleDrawTrainerPic(void); void OpponentHandleTrainerSlide(void); void OpponentHandleTrainerSlideBack(void); void OpponentHandleFaintAnimation(void); -void OpponentHandleCmd11(void); -void OpponentHandleCmd12(void); +void OpponentHandlePaletteFade(void); +void OpponentHandleSuccessBallThrowAnim(void); void OpponentHandleBallThrow(void); void OpponentHandlePause(void); void OpponentHandleMoveAnimation(void); void OpponentHandlePrintString(void); void OpponentHandlePrintStringPlayerOnly(void); void OpponentHandleChooseAction(void); -void OpponentHandleCmd19(void); +void OpponentHandleUnknownYesNoBox(void); void OpponentHandleChooseMove(void); void OpponentHandleOpenBag(void); void OpponentHandleChoosePokemon(void); @@ -71,6 +118,13 @@ void OpponentHandleCmd55(void); void nullsub_91(void); void OpponentBufferRunCommand(void); +void OpponentBufferExecCompleted(void); +void bx_803AEDC(void); +u32 sub_8060004(u8 monId, u8 *dst); +void sub_8060890(u8 monId); +void sub_80613DC(u8 bank, bool8 dontClearSubstituteBit); +void DoSwitchOutAnimation(void); +void OpponentDoMoveAnimation(void); void (*const gOpponentBufferCommands[CONTOLLER_CMDS_COUNT])(void) = { @@ -85,15 +139,15 @@ void (*const gOpponentBufferCommands[CONTOLLER_CMDS_COUNT])(void) = OpponentHandleTrainerSlide, OpponentHandleTrainerSlideBack, OpponentHandleFaintAnimation, - OpponentHandleCmd11, - OpponentHandleCmd12, + OpponentHandlePaletteFade, + OpponentHandleSuccessBallThrowAnim, OpponentHandleBallThrow, OpponentHandlePause, OpponentHandleMoveAnimation, OpponentHandlePrintString, OpponentHandlePrintStringPlayerOnly, OpponentHandleChooseAction, - OpponentHandleCmd19, + OpponentHandleUnknownYesNoBox, OpponentHandleChooseMove, OpponentHandleOpenBag, OpponentHandleChoosePokemon, @@ -134,7 +188,7 @@ void (*const gOpponentBufferCommands[CONTOLLER_CMDS_COUNT])(void) = }; // unknown unused data -static const u8 gUnknown_0831C7AC[] = {0xB0, 0xB0, 0xC8, 0x98, 0x28, 0x28, 0x28, 0x20}; +static const u8 sUnknown_0831C7AC[] = {0xB0, 0xB0, 0xC8, 0x98, 0x28, 0x28, 0x28, 0x20}; void nullsub_26(void) { @@ -144,3 +198,1426 @@ void SetBankFuncToOpponentBufferRunCommand(void) { gBattleBankFunc[gActiveBank] = OpponentBufferRunCommand; } + +void OpponentBufferRunCommand(void) +{ + if (gBattleExecBuffer & gBitTable[gActiveBank]) + { + if (gBattleBufferA[gActiveBank][0] < ARRAY_COUNT(gOpponentBufferCommands)) + gOpponentBufferCommands[gBattleBufferA[gActiveBank][0]](); + else + OpponentBufferExecCompleted(); + } +} + +void CompleteOnBankSpriteCallbackDummy(void) +{ + if (gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy) + OpponentBufferExecCompleted(); +} + +void CompleteOnBankSpriteCallbackDummy2(void) +{ + if (gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy) + OpponentBufferExecCompleted(); +} + +void sub_805F240(void) +{ + if (gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy) + { + FreeTrainerFrontPicPalette(gSprites[gBankSpriteIds[gActiveBank]].oam.affineParam); + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBank]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBank]]); + OpponentBufferExecCompleted(); + } +} + +void sub_805F2A8(void) +{ + if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_9 == 0xFF) + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_9 = 0; + OpponentBufferExecCompleted(); + } +} + +void sub_805F2F0(void) +{ + bool8 var = FALSE; + bool8 var2; + + if (!IsDoubleBattle() || ((IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)) || (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS))) + { + if (gSprites[gHealthBoxesIds[gActiveBank]].callback == SpriteCallbackDummy) + var = TRUE; + var2 = FALSE; + } + else + { + if (gSprites[gHealthBoxesIds[gActiveBank]].callback == SpriteCallbackDummy + && gSprites[gHealthBoxesIds[gActiveBank ^ BIT_MON]].callback == SpriteCallbackDummy) + var = TRUE; + var2 = TRUE; + } + + gUnknown_020244D8 = &gBattleSpritesDataPtr->healthBoxesData[gActiveBank]; + gUnknown_020244DC = &gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON]; + + if (var) + { + if (var2 == TRUE) + { + if (var2 && gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x1 && gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON].field_1_x1) + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x80 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x1 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON].flag_x80 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON].field_1_x1 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + } + else + return; + } + else if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x1) + { + if (GetBankIdentity(gActiveBank) == 3) + { + if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON].flag_x80 == 0 && gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON].field_1_x1 == 0) + { + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + } + else + return; + } + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x80 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x1 = 0; + } + else + return; + + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_9 = 3; + gBattleBankFunc[gActiveBank] = sub_805F2A8; + } +} + +void sub_805F560(void) +{ + bool32 sp = FALSE; + bool32 r10 = FALSE; + + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x8 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x1) + sub_8172EF0(gActiveBank, &gEnemyParty[gBattlePartyID[gActiveBank]]); + if (!(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI) && IsDoubleBattle() && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON].flag_x8 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON].field_1_x1) + sub_8172EF0(gActiveBank ^ BIT_MON, &gEnemyParty[gBattlePartyID[gActiveBank ^ BIT_MON]]); + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x8 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON].flag_x8) + { + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x80) + { + if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + UpdateHealthboxAttribute(gHealthBoxesIds[gActiveBank ^ BIT_MON], &gEnemyParty[gBattlePartyID[gActiveBank ^ BIT_MON]], HEALTHBOX_ALL); + sub_8076918(gActiveBank ^ BIT_MON); + SetHealthboxSpriteVisible(gHealthBoxesIds[gActiveBank ^ BIT_MON]); + } + UpdateHealthboxAttribute(gHealthBoxesIds[gActiveBank], &gEnemyParty[gBattlePartyID[gActiveBank]], HEALTHBOX_ALL); + sub_8076918(gActiveBank); + SetHealthboxSpriteVisible(gHealthBoxesIds[gActiveBank]); + } + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x80 = 1; + } + + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x40 + && gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x80 + && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON].field_1_x40 + && !IsCryPlayingOrClearCrySongs()) + { + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x20) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_LINK) + { + if (GetBankIdentity(gActiveBank) == 1) + m4aMPlayContinue(&gMPlay_BGM); + } + else + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); + } + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x20 = 1; + sp = TRUE; + } + + if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) + { + if (gSprites[gUnknown_03005D7C[gActiveBank]].callback == SpriteCallbackDummy + && gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy) + { + r10 = TRUE; + } + } + else + { + if (gSprites[gUnknown_03005D7C[gActiveBank]].callback == SpriteCallbackDummy + && gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy + && gSprites[gUnknown_03005D7C[gActiveBank ^ BIT_MON]].callback == SpriteCallbackDummy + && gSprites[gBankSpriteIds[gActiveBank ^ BIT_MON]].callback == SpriteCallbackDummy) + { + r10 = TRUE; + } + } + + if (sp && r10) + { + if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + DestroySprite(&gSprites[gUnknown_03005D7C[gActiveBank ^ BIT_MON]]); + SetBankEnemyShadowSpriteCallback(gActiveBank ^ BIT_MON, GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank ^ BIT_MON]], MON_DATA_SPECIES)); + } + + DestroySprite(&gSprites[gUnknown_03005D7C[gActiveBank]]); + SetBankEnemyShadowSpriteCallback(gActiveBank, GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES)); + gBattleSpritesDataPtr->animationData->field_9_x1 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x20 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x80 = 0; + + gBattleBankFunc[gActiveBank] = sub_805F2F0; + } +} + +void sub_805F994(void) +{ + if (gSprites[gBankSpriteIds[gActiveBank]].pos2.x == 0 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x1) + sub_8172EF0(gActiveBank, &gEnemyParty[gBattlePartyID[gActiveBank]]); + + if (gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy && gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x1) + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x80 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x1 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + OpponentBufferExecCompleted(); + } +} + +void sub_805FA70(void) +{ + s16 hpValue = sub_8074AA0(gActiveBank, gHealthBoxesIds[gActiveBank], 0, 0); + SetHealthboxSpriteVisible(gHealthBoxesIds[gActiveBank]); + if (hpValue != -1) + { + UpdateHpTextInHealthbox(gHealthBoxesIds[gActiveBank], hpValue, HP_CURRENT); + } + else + OpponentBufferExecCompleted(); +} + +void sub_805FAC4(void) +{ + if (!gSprites[gBankSpriteIds[gActiveBank]].inUse) + { + SetHealthboxSpriteInvisible(gHealthBoxesIds[gActiveBank]); + OpponentBufferExecCompleted(); + } +} + +void sub_805FB08(void) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive) + { + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBank]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBank]]); + sub_805EEE0(gActiveBank); + SetHealthboxSpriteInvisible(gHealthBoxesIds[gActiveBank]); + OpponentBufferExecCompleted(); + } +} + +void CompleteOnInactiveTextPrinter(void) +{ + if (!IsTextPrinterActive(0)) + OpponentBufferExecCompleted(); +} + +void bx_blink_t7(void) +{ + u8 spriteId = gBankSpriteIds[gActiveBank]; + + if (gSprites[spriteId].data1 == 32) + { + gSprites[spriteId].data1 = 0; + gSprites[spriteId].invisible = 0; + gDoingBattleAnim = FALSE; + OpponentBufferExecCompleted(); + } + else + { + if ((gSprites[spriteId].data1 % 4) == 0) + gSprites[spriteId].invisible ^= 1; + gSprites[spriteId].data1++; + } +} + +void sub_805FC10(void) +{ + if (gSprites[gHealthBoxesIds[gActiveBank]].callback == SpriteCallbackDummy) + { + if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute) + DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE); + gBattleBankFunc[gActiveBank] = bx_803AEDC; + } +} + +void bx_803AEDC(void) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive && !IsCryPlayingOrClearCrySongs()) + { + if (gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy || gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy_2) + { + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); + OpponentBufferExecCompleted(); + } + } +} + +void sub_805FD00(void) +{ + if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x1 && gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy) + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x80 = 0; + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x1 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBank]], 0); + UpdateHealthboxAttribute(gHealthBoxesIds[gActiveBank], &gEnemyParty[gBattlePartyID[gActiveBank]], HEALTHBOX_ALL); + sub_8076918(gActiveBank); + SetHealthboxSpriteVisible(gHealthBoxesIds[gActiveBank]); + SetBattleSpriteInvisibilityBitToSpriteInvisibility(gActiveBank); + gBattleBankFunc[gActiveBank] = sub_805FC10; + } +} + +void sub_805FDF0(void) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x8) + sub_8172EF0(gActiveBank, &gEnemyParty[gBattlePartyID[gActiveBank]]); + + if (gSprites[gUnknown_03005D7C[gActiveBank]].callback == SpriteCallbackDummy + && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x8) + { + DestroySprite(&gSprites[gUnknown_03005D7C[gActiveBank]]); + SetBankEnemyShadowSpriteCallback(gActiveBank, GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES)); + gBattleBankFunc[gActiveBank] = sub_805FD00; + } +} + +void sub_805FEB8(void) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].statusAnimActive) + OpponentBufferExecCompleted(); +} + +void bx_803B0F4(void) +{ + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animFromTableActive) + OpponentBufferExecCompleted(); +} + +void OpponentBufferExecCompleted(void) +{ + gBattleBankFunc[gActiveBank] = OpponentBufferRunCommand; + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + u8 playerId = GetMultiplayerId(); + + PrepareBufferDataTransferLink(2, 4, &playerId); + gBattleBufferA[gActiveBank][0] = CONTOLLER_CMDS_COUNT - 1; + } + else + { + gBattleExecBuffer &= ~gBitTable[gActiveBank]; + } +} + +void OpponentHandleGetMonData(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 monsToCheck; + s32 i; + + if (gBattleBufferA[gActiveBank][2] == 0) + { + size += sub_8060004(gBattlePartyID[gActiveBank], monData); + } + else + { + monsToCheck = gBattleBufferA[gActiveBank][2]; + for (i = 0; i < 6; i++) + { + if (monsToCheck & 1) + size += sub_8060004(i, monData + size); + monsToCheck >>= 1; + } + } + EmitDataTransfer(1, size, monData); + OpponentBufferExecCompleted(); +} + +u32 sub_8060004(u8 monId, u8 *dst) +{ + struct BattlePokemon battleMon; + struct MovePpInfo moveData; + u8 nickname[20]; + u8 *src; + s16 data16; + u32 data32; + s32 size = 0; + + switch (gBattleBufferA[gActiveBank][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 < 4; 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.altAbility = GetMonData(&gEnemyParty[monId], MON_DATA_ALT_ABILITY); + 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 < 4; 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[gActiveBank][1] - REQUEST_MOVE1_BATTLE); + dst[0] = data16; + dst[1] = data16 >> 8; + size = 2; + break; + case REQUEST_PP_DATA_BATTLE: + for (size = 0; size < 4; 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[gActiveBank][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; +} + +void OpponentHandleGetRawMonData(void) +{ + struct BattlePokemon battleMon; + u8 *src = (u8 *)&gEnemyParty[gBattlePartyID[gActiveBank]] + gBattleBufferA[gActiveBank][1]; + u8 *dst = (u8 *)&battleMon + gBattleBufferA[gActiveBank][1]; + u8 i; + + for (i = 0; i < gBattleBufferA[gActiveBank][2]; i++) + dst[i] = src[i]; + + EmitDataTransfer(1, gBattleBufferA[gActiveBank][2], dst); + OpponentBufferExecCompleted(); +} + +void OpponentHandleSetMonData(void) +{ + u8 monsToCheck; + u8 i; + + if (gBattleBufferA[gActiveBank][2] == 0) + { + sub_8060890(gBattlePartyID[gActiveBank]); + } + else + { + monsToCheck = gBattleBufferA[gActiveBank][2]; + for (i = 0; i < 6; i++) + { + if (monsToCheck & 1) + sub_8060890(i); + monsToCheck >>= 1; + } + } + OpponentBufferExecCompleted(); +} + +void sub_8060890(u8 monId) +{ + struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBank][3]; + struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBank][3]; + s32 i; + + switch (gBattleBufferA[gActiveBank][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 < 4; 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[gActiveBank][3]); + break; + case REQUEST_HELDITEM_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_MOVES_PP_BATTLE: + for (i = 0; i < 4; 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[gActiveBank][1] - REQUEST_MOVE1_BATTLE, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_PP_DATA_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_PP1, &gBattleBufferA[gActiveBank][3]); + SetMonData(&gEnemyParty[monId], MON_DATA_PP2, &gBattleBufferA[gActiveBank][4]); + SetMonData(&gEnemyParty[monId], MON_DATA_PP3, &gBattleBufferA[gActiveBank][5]); + SetMonData(&gEnemyParty[monId], MON_DATA_PP4, &gBattleBufferA[gActiveBank][6]); + SetMonData(&gEnemyParty[monId], MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBank][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[gActiveBank][1] - REQUEST_PPMOVE1_BATTLE, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_OTID_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_OT_ID, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_EXP_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_EXP, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_HP_EV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_HP_EV, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_ATK_EV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_DEF_EV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_SPEED_EV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_SPATK_EV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_SPDEF_EV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_FRIENDSHIP_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_POKERUS_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_POKERUS, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_MET_LOCATION_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_MET_LEVEL_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_MET_GAME_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_POKEBALL_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_ALL_IVS_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &gBattleBufferA[gActiveBank][3]); + SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBank][4]); + SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBank][5]); + SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBank][6]); + SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBank][7]); + SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBank][8]); + break; + case REQUEST_HP_IV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_HP_IV, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_ATK_IV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_DEF_IV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_SPEED_IV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_SPATK_IV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_SPDEF_IV_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_PERSONALITY_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_CHECKSUM_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_STATUS_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_STATUS, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_LEVEL_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_LEVEL, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_HP_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_HP, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_MAX_HP_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_ATK_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_ATK, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_DEF_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_DEF, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_SPEED_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPEED, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_SPATK_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPATK, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_SPDEF_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SPDEF, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_COOL_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_COOL, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_BEAUTY_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_CUTE_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_CUTE, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_SMART_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SMART, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_TOUGH_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_TOUGH, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_SHEEN_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SHEEN, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_COOL_RIBBON_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_BEAUTY_RIBBON_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_CUTE_RIBBON_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_SMART_RIBBON_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBank][3]); + break; + case REQUEST_TOUGH_RIBBON_BATTLE: + SetMonData(&gEnemyParty[monId], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBank][3]); + break; + } +} + +void OpponentHandleSetRawMonData(void) +{ + u8 *dst = (u8 *)&gEnemyParty[gBattlePartyID[gActiveBank]] + gBattleBufferA[gActiveBank][1]; + u8 i; + + for (i = 0; i < gBattleBufferA[gActiveBank][2]; i++) + dst[i] = gBattleBufferA[gActiveBank][3 + i]; + + OpponentBufferExecCompleted(); +} + +void OpponentHandleLoadMonSprite(void) +{ + u16 species = GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES); + + BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlePartyID[gActiveBank]], gActiveBank); + sub_806A068(species, GetBankIdentity(gActiveBank)); + + gBankSpriteIds[gActiveBank] = CreateSprite(&gUnknown_0202499C, + sub_80A5C6C(gActiveBank, 2), + sub_80A6138(gActiveBank), + sub_80A82E4(gActiveBank)); + + gSprites[gBankSpriteIds[gActiveBank]].pos2.x = -240; + gSprites[gBankSpriteIds[gActiveBank]].data0 = gActiveBank; + gSprites[gBankSpriteIds[gActiveBank]].data2 = species; + gSprites[gBankSpriteIds[gActiveBank]].oam.paletteNum = gActiveBank; + StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBank]], gBattleMonForms[gActiveBank]); + + SetBankEnemyShadowSpriteCallback(gActiveBank, GetMonData(&gEnemyParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES)); + + gBattleBankFunc[gActiveBank] = sub_805F994; +} + +void OpponentHandleSwitchInAnim(void) +{ + *(gBattleStruct->field_5C + gActiveBank) = 6; + gBattlePartyID[gActiveBank] = gBattleBufferA[gActiveBank][1]; + sub_80613DC(gActiveBank, gBattleBufferA[gActiveBank][2]); + gBattleBankFunc[gActiveBank] = sub_805FDF0; +} + +void sub_80613DC(u8 bank, bool8 dontClearSubstituteBit) +{ + u16 species; + + ClearTemporarySpeciesSpriteData(bank, dontClearSubstituteBit); + gBattlePartyID[bank] = gBattleBufferA[bank][1]; + species = GetMonData(&gEnemyParty[gBattlePartyID[bank]], MON_DATA_SPECIES); + gUnknown_03005D7C[bank] = CreateInvisibleSpriteWithCallback(sub_805D714); + BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlePartyID[bank]], bank); + sub_806A068(species, GetBankIdentity(bank)); + + gBankSpriteIds[bank] = CreateSprite(&gUnknown_0202499C, + sub_80A5C6C(bank, 2), + sub_80A6138(bank), + sub_80A82E4(bank)); + + gSprites[gBankSpriteIds[bank]].data0 = bank; + gSprites[gBankSpriteIds[bank]].data2 = species; + + gSprites[gUnknown_03005D7C[bank]].data1 = gBankSpriteIds[bank]; + gSprites[gUnknown_03005D7C[bank]].data2 = bank; + + gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; + + StartSpriteAnim(&gSprites[gBankSpriteIds[bank]], gBattleMonForms[bank]); + + gSprites[gBankSpriteIds[bank]].invisible = TRUE; + gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; + + gSprites[gUnknown_03005D7C[bank]].data0 = sub_80753E8(0, 0xFE); +} + +void OpponentHandleReturnMonToBall(void) +{ + if (gBattleBufferA[gActiveBank][1] == 0) + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0; + gBattleBankFunc[gActiveBank] = DoSwitchOutAnimation; + } + else + { + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBank]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBank]]); + sub_805EEE0(gActiveBank); + SetHealthboxSpriteInvisible(gHealthBoxesIds[gActiveBank]); + OpponentBufferExecCompleted(); + } +} + +void DoSwitchOutAnimation(void) +{ + switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState) + { + case 0: + if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute) + DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON); + + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1; + break; + case 1: + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive) + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0; + DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SWITCH_OUT_OPPONENT_MON); + gBattleBankFunc[gActiveBank] = sub_805FB08; + } + break; + } +} + +u8 sub_81A4CB0(void); +u8 sub_81D5588(u16 trainerId); +u8 GetFrontierTrainerFrontSpriteId(u16 trainerId); +u8 GetEreaderTrainerFrontSpriteId(void); + +// todo: get rid of it once the struct is declared in a header +struct MonCoords +{ + // This would use a bitfield, but sub_8079F44 + // uses it as a u8 and casting won't match. + u8 coords; // u8 x:4, y:4; + u8 y_offset; +}; +extern const struct MonCoords gTrainerFrontPicCoords[]; + +void OpponentHandleDrawTrainerPic(void) +{ + u32 trainerPicId; + s16 xPos; + + if (gBattleTypeFlags & BATTLE_TYPE_SECRET_BASE) + { + trainerPicId = GetSecretBaseTrainerPicIndex(); + } + else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_3FE) + { + trainerPicId = sub_81A4CB0(); + } + else if (gBattleTypeFlags & BATTLE_TYPE_x4000000) + { + if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + { + if (gActiveBank == 1) + trainerPicId = sub_81D5588(gTrainerBattleOpponent_A); + else + trainerPicId = sub_81D5588(gTrainerBattleOpponent_B); + } + else + { + trainerPicId = sub_81D5588(gTrainerBattleOpponent_A); + } + } + else if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER) + { + if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000)) + { + if (gActiveBank == 1) + trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); + else + trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B); + } + else + { + trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); + } + } + else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) + { + trainerPicId = GetEreaderTrainerFrontSpriteId(); + } + else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + { + if (gActiveBank != 1) + trainerPicId = gTrainers[gTrainerBattleOpponent_B].trainerPic; + else + trainerPicId = gTrainers[gTrainerBattleOpponent_A].trainerPic; + } + else + { + trainerPicId = gTrainers[gTrainerBattleOpponent_A].trainerPic; + } + + if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS)) + { + if ((GetBankIdentity(gActiveBank) & BIT_MON) != 0) // second mon + xPos = 152; + else // first mon + xPos = 200; + } + else + { + xPos = 176; + } + + DecompressTrainerFrontPic(trainerPicId, gActiveBank); + sub_806A12C(trainerPicId, GetBankIdentity(gActiveBank)); + gBankSpriteIds[gActiveBank] = CreateSprite(&gUnknown_0202499C, + xPos, + (8 - gTrainerFrontPicCoords[trainerPicId].coords) * 4 + 40, + sub_80A82E4(gActiveBank)); + + gSprites[gBankSpriteIds[gActiveBank]].pos2.x = -240; + gSprites[gBankSpriteIds[gActiveBank]].data0 = 2; + gSprites[gBankSpriteIds[gActiveBank]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); + gSprites[gBankSpriteIds[gActiveBank]].oam.affineParam = trainerPicId; + gSprites[gBankSpriteIds[gActiveBank]].callback = sub_805D7AC; + + gBattleBankFunc[gActiveBank] = CompleteOnBankSpriteCallbackDummy; +} + +void OpponentHandleTrainerSlide(void) +{ + u32 trainerPicId; + + if (gBattleTypeFlags & BATTLE_TYPE_SECRET_BASE) + { + trainerPicId = GetSecretBaseTrainerPicIndex(); + } + else if (gTrainerBattleOpponent_A == TRAINER_OPPONENT_3FE) + { + trainerPicId = sub_81A4CB0(); + } + else if (gBattleTypeFlags & BATTLE_TYPE_x4000000) + { + if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + { + if (gActiveBank == 1) + trainerPicId = sub_81D5588(gTrainerBattleOpponent_A); + else + trainerPicId = sub_81D5588(gTrainerBattleOpponent_B); + } + else + { + trainerPicId = sub_81D5588(gTrainerBattleOpponent_A); + } + } + else if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER) + { + if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000)) + { + if (gActiveBank == 1) + trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); + else + trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_B); + } + else + { + trainerPicId = GetFrontierTrainerFrontSpriteId(gTrainerBattleOpponent_A); + } + } + else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) + { + trainerPicId = GetEreaderTrainerFrontSpriteId(); + } + else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + { + if (gActiveBank != 1) + trainerPicId = gTrainers[gTrainerBattleOpponent_B].trainerPic; + else + trainerPicId = gTrainers[gTrainerBattleOpponent_A].trainerPic; + } + else + { + trainerPicId = gTrainers[gTrainerBattleOpponent_A].trainerPic; + } + + DecompressTrainerFrontPic(trainerPicId, gActiveBank); + sub_806A12C(trainerPicId, GetBankIdentity(gActiveBank)); + gBankSpriteIds[gActiveBank] = CreateSprite(&gUnknown_0202499C, 176, (8 - gTrainerFrontPicCoords[trainerPicId].coords) * 4 + 40, 0x1E); + + gSprites[gBankSpriteIds[gActiveBank]].pos2.x = 96; + gSprites[gBankSpriteIds[gActiveBank]].pos1.x += 32; + gSprites[gBankSpriteIds[gActiveBank]].data0 = -2; + gSprites[gBankSpriteIds[gActiveBank]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicId].tag); + gSprites[gBankSpriteIds[gActiveBank]].oam.affineParam = trainerPicId; + gSprites[gBankSpriteIds[gActiveBank]].callback = sub_805D7AC; + + gBattleBankFunc[gActiveBank] = CompleteOnBankSpriteCallbackDummy2; +} + +void OpponentHandleTrainerSlideBack(void) +{ + oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBank]]); + gSprites[gBankSpriteIds[gActiveBank]].data0 = 35; + gSprites[gBankSpriteIds[gActiveBank]].data2 = 280; + gSprites[gBankSpriteIds[gActiveBank]].data4 = gSprites[gBankSpriteIds[gActiveBank]].pos1.y; + gSprites[gBankSpriteIds[gActiveBank]].callback = sub_80A6EEC; + StoreSpriteCallbackInData6(&gSprites[gBankSpriteIds[gActiveBank]], SpriteCallbackDummy); + gBattleBankFunc[gActiveBank] = sub_805F240; +} + +void OpponentHandleFaintAnimation(void) +{ + if (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState == 0) + { + if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute) + DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON); + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState++; + } + else + { + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive) + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0; + PlaySE12WithPanning(SE_POKE_DEAD, PAN_SIDE_OPPONENT); + gSprites[gBankSpriteIds[gActiveBank]].callback = sub_8039934; + gBattleBankFunc[gActiveBank] = sub_805FAC4; + } + } +} + +void OpponentHandlePaletteFade(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleSuccessBallThrowAnim(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleBallThrow(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlePause(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleMoveAnimation(void) +{ + if (!mplay_80342A4(gActiveBank)) + { + u16 move = gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8); + + gAnimMoveTurn = gBattleBufferA[gActiveBank][3]; + gAnimMovePower = gBattleBufferA[gActiveBank][4] | (gBattleBufferA[gActiveBank][5] << 8); + gAnimMoveDmg = gBattleBufferA[gActiveBank][6] | (gBattleBufferA[gActiveBank][7] << 8) | (gBattleBufferA[gActiveBank][8] << 16) | (gBattleBufferA[gActiveBank][9] << 24); + gAnimFriendship = gBattleBufferA[gActiveBank][10]; + gWeatherMoveAnim = gBattleBufferA[gActiveBank][12] | (gBattleBufferA[gActiveBank][13] << 8); + gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBank][16]; + gTransformedPersonalities[gActiveBank] = gAnimDisableStructPtr->transformedMonPersonality; + if (IsMoveWithoutAnimation(move, gAnimMoveTurn)) // always returns FALSE + { + OpponentBufferExecCompleted(); + } + else + { + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0; + gBattleBankFunc[gActiveBank] = OpponentDoMoveAnimation; + } + } +} + +void OpponentDoMoveAnimation(void) +{ + u16 move = gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8); + u8 multihit = gBattleBufferA[gActiveBank][11]; + + switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState) + { + case 0: + if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute + && !gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8) + { + gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 1; + DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_SUBSTITUTE_TO_MON); + } + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 1; + break; + case 1: + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive) + { + sub_805EB9C(0); + DoMoveAnim(move); + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 2; + } + break; + case 2: + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + sub_805EB9C(1); + if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute && multihit < 2) + { + DoSpecialBattleAnimation(gActiveBank, gActiveBank, gActiveBank, B_ANIM_MON_TO_SUBSTITUTE); + gBattleSpritesDataPtr->bankData[gActiveBank].flag_x8 = 0; + } + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 3; + } + break; + case 3: + if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].specialAnimActive) + { + sub_805E394(); + TrySetBehindSubstituteSpriteBit(gActiveBank, gBattleBufferA[gActiveBank][1] | (gBattleBufferA[gActiveBank][2] << 8)); + gBattleSpritesDataPtr->healthBoxesData[gActiveBank].animationState = 0; + OpponentBufferExecCompleted(); + } + break; + } +} + +void OpponentHandlePrintString(void) +{ + u16 *stringId; + + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + stringId = (u16*)(&gBattleBufferA[gActiveBank][2]); + BufferStringBattle(*stringId); + BattleHandleAddTextPrinter(gDisplayedStringBattle, 0); + gBattleBankFunc[gActiveBank] = CompleteOnInactiveTextPrinter; + sub_81A57E4(gActiveBank, *stringId); +} + +void OpponentHandlePrintStringPlayerOnly(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleChooseAction(void) +{ + AI_TrySwitchOrUseItem(); + OpponentBufferExecCompleted(); +} + +void OpponentHandleUnknownYesNoBox(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleChooseMove(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_PALACE) + { + EmitTwoReturnValues(1, 10, ChooseMoveAndTargetInBattlePalace()); + OpponentBufferExecCompleted(); + } + else + { + u8 chosenMoveId; + struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleBufferA[gActiveBank][4]); + + if (gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_SAFARI | BATTLE_TYPE_ROAMER)) + { + + BattleAI_SetupAIData(0xF); + chosenMoveId = BattleAI_ChooseMoveOrAction(); + + switch (chosenMoveId) + { + case 5: + EmitTwoReturnValues(1, ACTION_WATCHES_CAREFULLY, 0); + break; + case 4: + EmitTwoReturnValues(1, ACTION_RUN, 0); + break; + case 6: + EmitTwoReturnValues(1, 15, gBankTarget); + break; + default: + if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & (MOVE_TARGET_USER | MOVE_TARGET_x10)) + gBankTarget = gActiveBank; + if (gBattleMoves[moveInfo->moves[chosenMoveId]].target & MOVE_TARGET_BOTH) + { + gBankTarget = GetBankByIdentity(IDENTITY_PLAYER_MON1); + if (gAbsentBankFlags & gBitTable[gBankTarget]) + gBankTarget = GetBankByIdentity(IDENTITY_PLAYER_MON2); + } + EmitTwoReturnValues(1, 10, (chosenMoveId) | (gBankTarget << 8)); + break; + } + OpponentBufferExecCompleted(); + } + else + { + u16 move; + do + { + chosenMoveId = Random() & 3; + move = moveInfo->moves[chosenMoveId]; + } while (move == MOVE_NONE); + + if (gBattleMoves[move].target & (MOVE_TARGET_USER | MOVE_TARGET_x10)) + EmitTwoReturnValues(1, 10, (chosenMoveId) | (gActiveBank << 8)); + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + EmitTwoReturnValues(1, 10, (chosenMoveId) | (GetBankByIdentity(Random() & 2) << 8)); + else + EmitTwoReturnValues(1, 10, (chosenMoveId) | (GetBankByIdentity(IDENTITY_PLAYER_MON1) << 8)); + + OpponentBufferExecCompleted(); + } + } +} diff --git a/src/battle_dome_cards.c b/src/battle_dome_cards.c index 5251ee06a..030290a0d 100644 --- a/src/battle_dome_cards.c +++ b/src/battle_dome_cards.c @@ -19,7 +19,7 @@ extern const union AffineAnimCmd *const gUnknown_082FF694[]; extern const union AnimCmd *const gUnknown_082FF70C[]; extern const union AnimCmd *const *const gMonAnimationsSpriteAnimsPtrTable[NUM_SPECIES]; extern const union AnimCmd *const *const gUnknown_0830536C[]; -extern const u8 gUnknown_0831F578[]; +extern const u8 gTrainerClassToFrontPicId[]; // Static type declarations @@ -421,9 +421,9 @@ u8 sub_818D97C(u8 a0, u8 a1) switch (a0) { default: - return gUnknown_0831F578[0x3F]; + return gTrainerClassToFrontPicId[0x3F]; case 0: - return gUnknown_0831F578[0x3C]; + return gTrainerClassToFrontPicId[0x3C]; } } return a0; diff --git a/src/pokemon_2.c b/src/pokemon_2.c index b0ec7460d..b78fd3db8 100644 --- a/src/pokemon_2.c +++ b/src/pokemon_2.c @@ -1222,14 +1222,14 @@ void CreateSecretBaseEnemyParty(struct SecretBaseRecord *secretBaseRecord) } } -extern const u8 gUnknown_0831F578[]; +extern const u8 gTrainerClassToFrontPicId[]; extern const u8 gTrainerClassToNameIndex[]; extern const u8 gSecretBaseTrainerClasses[][5]; u8 GetSecretBaseTrainerPicIndex(void) { u8 trainerClass = gSecretBaseTrainerClasses[gBattleResources->secretBase->gender][gBattleResources->secretBase->trainerId[0] % 5]; - return gUnknown_0831F578[trainerClass]; + return gTrainerClassToFrontPicId[trainerClass]; } u8 GetSecretBaseTrainerNameIndex(void) diff --git a/src/pokemon_3.c b/src/pokemon_3.c index 73d23fe6f..f5043db01 100644 --- a/src/pokemon_3.c +++ b/src/pokemon_3.c @@ -1652,11 +1652,11 @@ u8 sub_806EF84(u8 arg0, u8 arg1) return i; } -extern const u8 gUnknown_0831F578[]; +extern const u8 gTrainerClassToFrontPicId[]; u16 sub_806EFF0(u16 arg0) { - return gUnknown_0831F578[arg0]; + return gTrainerClassToFrontPicId[arg0]; } u16 PlayerGenderToFrontTrainerPicId(u8 playerGender) |