mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-11-18 12:37:38 +01:00
1601 lines
52 KiB
C
1601 lines
52 KiB
C
|
#include "global.h"
|
||
|
#include "battle.h"
|
||
|
#include "battle_controllers.h"
|
||
|
#include "battle_message.h"
|
||
|
#include "battle_interface.h"
|
||
|
#include "battle_anim.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"
|
||
|
|
||
|
extern u32 gBattleExecBuffer;
|
||
|
extern u8 gActiveBank;
|
||
|
extern u8 gBankSpriteIds[BATTLE_BANKS_COUNT];
|
||
|
extern u8 gActionSelectionCursor[BATTLE_BANKS_COUNT];
|
||
|
extern u8 gMoveSelectionCursor[BATTLE_BANKS_COUNT];
|
||
|
extern u8 gAbsentBankFlags;
|
||
|
extern u8 gNoOfAllBanks;
|
||
|
extern bool8 gDoingBattleAnim;
|
||
|
extern u8 gUnknown_020244CC;
|
||
|
extern void (*gBattleBankFunc[BATTLE_BANKS_COUNT])(void);
|
||
|
extern void (*gPreBattleCallback1)(void);
|
||
|
extern u16 gBattlePartyID[BATTLE_BANKS_COUNT];
|
||
|
extern u8 gBattleBufferA[BATTLE_BANKS_COUNT][0x200];
|
||
|
extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200];
|
||
|
extern u8 gMultiUsePlayerCursor;
|
||
|
extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
|
||
|
extern struct MusicPlayerInfo gMPlay_BGM;
|
||
|
|
||
|
extern const struct BattleMove gBattleMoves[];
|
||
|
|
||
|
extern void dp11b_obj_instanciate(u8, u8, s8, s8);
|
||
|
extern void dp11b_obj_free(u8, u8);
|
||
|
extern void sub_800AC34(void);
|
||
|
|
||
|
// this file's functions
|
||
|
void PlayerHandleGetMonData(void);
|
||
|
void PlayerHandleGetRawMonData(void);
|
||
|
void PlayerHandleSetMonData(void);
|
||
|
void PlayerHandleSetRawMonData(void);
|
||
|
void PlayerHandleLoadMonSprite(void);
|
||
|
void PlayerHandleSwitchInAnim(void);
|
||
|
void PlayerHandleReturnMonToBall(void);
|
||
|
void PlayerHandleDrawTrainerPic(void);
|
||
|
void PlayerHandleTrainerSlide(void);
|
||
|
void PlayerHandleTrainerSlideBack(void);
|
||
|
void PlayerHandleFaintAnimation(void);
|
||
|
void PlayerHandleCmd11(void);
|
||
|
void PlayerHandleCmd12(void);
|
||
|
void PlayerHandleBallThrow(void);
|
||
|
void PlayerHandlePause(void);
|
||
|
void PlayerHandleMoveAnimation(void);
|
||
|
void PlayerHandlePrintString(void);
|
||
|
void PlayerHandlePrintStringPlayerOnly(void);
|
||
|
void PlayerHandleChooseAction(void);
|
||
|
void PlayerHandleCmd19(void);
|
||
|
void PlayerHandleChooseMove(void);
|
||
|
void PlayerHandleOpenBag(void);
|
||
|
void PlayerHandleChoosePokemon(void);
|
||
|
void PlayerHandleCmd23(void);
|
||
|
void PlayerHandleHealthBarUpdate(void);
|
||
|
void PlayerHandleExpUpdate(void);
|
||
|
void PlayerHandleStatusIconUpdate(void);
|
||
|
void PlayerHandleStatusAnimation(void);
|
||
|
void PlayerHandleStatusXor(void);
|
||
|
void PlayerHandleDataTransfer(void);
|
||
|
void PlayerHandleDMA3Transfer(void);
|
||
|
void PlayerHandlePlayBGM(void);
|
||
|
void PlayerHandleCmd32(void);
|
||
|
void PlayerHandleCmd33(void);
|
||
|
void PlayerHandleCmd34(void);
|
||
|
void PlayerHandleCmd35(void);
|
||
|
void PlayerHandleCmd36(void);
|
||
|
void PlayerHandleCmd37(void);
|
||
|
void PlayerHandleCmd38(void);
|
||
|
void PlayerHandleCmd39(void);
|
||
|
void PlayerHandleCmd40(void);
|
||
|
void PlayerHandleHitAnimation(void);
|
||
|
void PlayerHandleCmd42(void);
|
||
|
void PlayerHandleEffectivenessSound(void);
|
||
|
void PlayerHandlePlayFanfareOrBGM(void);
|
||
|
void PlayerHandleFaintingCry(void);
|
||
|
void PlayerHandleIntroSlide(void);
|
||
|
void PlayerHandleIntroTrainerBallThrow(void);
|
||
|
void PlayerHandleDrawPartyStatusSummary(void);
|
||
|
void PlayerHandleCmd49(void);
|
||
|
void PlayerHandleCmd50(void);
|
||
|
void PlayerHandleSpriteInvisibility(void);
|
||
|
void PlayerHandleBattleAnimation(void);
|
||
|
void PlayerHandleLinkStandbyMsg(void);
|
||
|
void PlayerHandleResetActionMoveSelection(void);
|
||
|
void PlayerHandleCmd55(void);
|
||
|
void nullsub_22(void);
|
||
|
|
||
|
void PlayerBufferRunCommand(void);
|
||
|
void HandleInputChooseTarget(void);
|
||
|
void HandleInputChooseMove(void);
|
||
|
void MoveSelectionCreateCursorAt(u8 cursorPos, u8 arg1);
|
||
|
void MoveSelectionDestroyCursorAt(u8 cursorPos);
|
||
|
void MoveSelectionDisplayPpNumber(void);
|
||
|
void MoveSelectionDisplayPpString(void);
|
||
|
void MoveSelectionDisplayMoveType(void);
|
||
|
void MoveSelectionDisplayMoveNames(void);
|
||
|
void HandleMoveSwitchting(void);
|
||
|
void sub_8058FC0(void);
|
||
|
void sub_8059828(void);
|
||
|
void sub_80598E0(void);
|
||
|
void sub_8059544(u8 taskId);
|
||
|
void sub_8059330(u8 taskId);
|
||
|
void DestroyExpTaskAndCompleteOnInactiveTextPrinter(u8 taskId);
|
||
|
void sub_8059400(u8 taskId);
|
||
|
void sub_80595A4(u8 taskId);
|
||
|
void PrintLinkStandbyMsg(void);
|
||
|
|
||
|
void (*const gPlayerBufferCommands[CONTOLLER_CMDS_COUNT])(void) =
|
||
|
{
|
||
|
PlayerHandleGetMonData,
|
||
|
PlayerHandleGetRawMonData,
|
||
|
PlayerHandleSetMonData,
|
||
|
PlayerHandleSetRawMonData,
|
||
|
PlayerHandleLoadMonSprite,
|
||
|
PlayerHandleSwitchInAnim,
|
||
|
PlayerHandleReturnMonToBall,
|
||
|
PlayerHandleDrawTrainerPic,
|
||
|
PlayerHandleTrainerSlide,
|
||
|
PlayerHandleTrainerSlideBack,
|
||
|
PlayerHandleFaintAnimation,
|
||
|
PlayerHandleCmd11,
|
||
|
PlayerHandleCmd12,
|
||
|
PlayerHandleBallThrow,
|
||
|
PlayerHandlePause,
|
||
|
PlayerHandleMoveAnimation,
|
||
|
PlayerHandlePrintString,
|
||
|
PlayerHandlePrintStringPlayerOnly,
|
||
|
PlayerHandleChooseAction,
|
||
|
PlayerHandleCmd19,
|
||
|
PlayerHandleChooseMove,
|
||
|
PlayerHandleOpenBag,
|
||
|
PlayerHandleChoosePokemon,
|
||
|
PlayerHandleCmd23,
|
||
|
PlayerHandleHealthBarUpdate,
|
||
|
PlayerHandleExpUpdate,
|
||
|
PlayerHandleStatusIconUpdate,
|
||
|
PlayerHandleStatusAnimation,
|
||
|
PlayerHandleStatusXor,
|
||
|
PlayerHandleDataTransfer,
|
||
|
PlayerHandleDMA3Transfer,
|
||
|
PlayerHandlePlayBGM,
|
||
|
PlayerHandleCmd32,
|
||
|
PlayerHandleCmd33,
|
||
|
PlayerHandleCmd34,
|
||
|
PlayerHandleCmd35,
|
||
|
PlayerHandleCmd36,
|
||
|
PlayerHandleCmd37,
|
||
|
PlayerHandleCmd38,
|
||
|
PlayerHandleCmd39,
|
||
|
PlayerHandleCmd40,
|
||
|
PlayerHandleHitAnimation,
|
||
|
PlayerHandleCmd42,
|
||
|
PlayerHandleEffectivenessSound,
|
||
|
PlayerHandlePlayFanfareOrBGM,
|
||
|
PlayerHandleFaintingCry,
|
||
|
PlayerHandleIntroSlide,
|
||
|
PlayerHandleIntroTrainerBallThrow,
|
||
|
PlayerHandleDrawPartyStatusSummary,
|
||
|
PlayerHandleCmd49,
|
||
|
PlayerHandleCmd50,
|
||
|
PlayerHandleSpriteInvisibility,
|
||
|
PlayerHandleBattleAnimation,
|
||
|
PlayerHandleLinkStandbyMsg,
|
||
|
PlayerHandleResetActionMoveSelection,
|
||
|
PlayerHandleCmd55,
|
||
|
nullsub_22
|
||
|
};
|
||
|
|
||
|
static const u8 sTargetIdentities[] = {IDENTITY_PLAYER_MON1, IDENTITY_PLAYER_MON2, IDENTITY_OPPONENT_MON2, IDENTITY_OPPONENT_MON1};
|
||
|
|
||
|
// unknown unused data
|
||
|
static const u8 gUnknown_0831C5FC[] = {0x48, 0x48, 0x20, 0x5a, 0x50, 0x50, 0x50, 0x58};
|
||
|
|
||
|
void nullsub_21(void)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void SetBankFuncToPlayerBufferRunCommand(void)
|
||
|
{
|
||
|
gBattleBankFunc[gActiveBank] = PlayerBufferRunCommand;
|
||
|
gDoingBattleAnim = FALSE;
|
||
|
gUnknown_020244CC = 0;
|
||
|
}
|
||
|
|
||
|
void PlayerBufferExecCompleted(void)
|
||
|
{
|
||
|
gBattleBankFunc[gActiveBank] = PlayerBufferRunCommand;
|
||
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
||
|
{
|
||
|
u8 playerId = GetMultiplayerId();
|
||
|
|
||
|
PrepareBufferDataTransferLink(2, 4, &playerId);
|
||
|
gBattleBufferA[gActiveBank][0] = CONTOLLER_CMDS_COUNT - 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gBattleExecBuffer &= ~gBitTable[gActiveBank];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PlayerBufferRunCommand(void)
|
||
|
{
|
||
|
if (gBattleExecBuffer & gBitTable[gActiveBank])
|
||
|
{
|
||
|
if (gBattleBufferA[gActiveBank][0] < ARRAY_COUNT(gPlayerBufferCommands))
|
||
|
gPlayerBufferCommands[gBattleBufferA[gActiveBank][0]]();
|
||
|
else
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CompleteOnBankSpritePosX_0(void)
|
||
|
{
|
||
|
if (gSprites[gBankSpriteIds[gActiveBank]].pos2.x == 0)
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
|
||
|
void HandleInputChooseAction(void)
|
||
|
{
|
||
|
u16 itemId = gBattleBufferA[gActiveBank][2] | (gBattleBufferA[gActiveBank][3] << 8);
|
||
|
|
||
|
dp11b_obj_instanciate(gActiveBank, 1, 7, 1);
|
||
|
dp11b_obj_instanciate(gActiveBank, 0, 7, 1);
|
||
|
|
||
|
if (gMain.newAndRepeatedKeys & DPAD_ANY && gSaveBlock2Ptr->optionsButtonMode == 2)
|
||
|
gUnknown_020244CC++;
|
||
|
else
|
||
|
gUnknown_020244CC = 0;
|
||
|
|
||
|
if (gMain.newKeys & A_BUTTON)
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
|
||
|
switch (gActionSelectionCursor[gActiveBank])
|
||
|
{
|
||
|
case ACTION_USE_MOVE:
|
||
|
EmitCmd33(1, ACTION_USE_MOVE, 0);
|
||
|
break;
|
||
|
case ACTION_USE_ITEM:
|
||
|
EmitCmd33(1, ACTION_USE_ITEM, 0);
|
||
|
break;
|
||
|
case ACTION_SWITCH:
|
||
|
EmitCmd33(1, ACTION_SWITCH, 0);
|
||
|
break;
|
||
|
case ACTION_RUN:
|
||
|
EmitCmd33(1, ACTION_RUN, 0);
|
||
|
break;
|
||
|
}
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
else if (gMain.newKeys & DPAD_LEFT)
|
||
|
{
|
||
|
if (gActionSelectionCursor[gActiveBank] & 1) // if is ACTION_USE_ITEM or ACTION_RUN
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBank]);
|
||
|
gActionSelectionCursor[gActiveBank] ^= 1;
|
||
|
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBank], 0);
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & DPAD_RIGHT)
|
||
|
{
|
||
|
if (!(gActionSelectionCursor[gActiveBank] & 1)) // if is ACTION_USE_MOVE or ACTION_SWITCH
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBank]);
|
||
|
gActionSelectionCursor[gActiveBank] ^= 1;
|
||
|
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBank], 0);
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & DPAD_UP)
|
||
|
{
|
||
|
if (gActionSelectionCursor[gActiveBank] & 2) // if is ACTION_SWITCH or ACTION_RUN
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBank]);
|
||
|
gActionSelectionCursor[gActiveBank] ^= 2;
|
||
|
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBank], 0);
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & DPAD_DOWN)
|
||
|
{
|
||
|
if (!(gActionSelectionCursor[gActiveBank] & 2)) // if is ACTION_USE_MOVE or ACTION_USE_ITEM
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBank]);
|
||
|
gActionSelectionCursor[gActiveBank] ^= 2;
|
||
|
ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBank], 0);
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & B_BUTTON || gUnknown_020244CC > 59)
|
||
|
{
|
||
|
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
|
||
|
&& GetBankIdentity(gActiveBank) == IDENTITY_PLAYER_MON2
|
||
|
&& !(gAbsentBankFlags & gBitTable[GetBankByIdentity(IDENTITY_PLAYER_MON1)])
|
||
|
&& !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
|
||
|
{
|
||
|
if (gBattleBufferA[gActiveBank][1] == ACTION_USE_ITEM)
|
||
|
{
|
||
|
// Add item to bag if it is a ball
|
||
|
if (itemId <= ITEM_PREMIER_BALL)
|
||
|
AddBagItem(itemId, 1);
|
||
|
else
|
||
|
return;
|
||
|
}
|
||
|
PlaySE(SE_SELECT);
|
||
|
EmitCmd33(1, ACTION_CANCEL_PARTNER, 0);
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & START_BUTTON)
|
||
|
{
|
||
|
SwapHpBarsWithHpText();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void sub_80577F0(void) // unused
|
||
|
{
|
||
|
dp11b_obj_free(gActiveBank, 1);
|
||
|
dp11b_obj_free(gActiveBank, 0);
|
||
|
gBattleBankFunc[gActiveBank] = HandleInputChooseTarget;
|
||
|
}
|
||
|
|
||
|
void HandleInputChooseTarget(void)
|
||
|
{
|
||
|
s32 i;
|
||
|
u8 identities[4];
|
||
|
memcpy(identities, sTargetIdentities, ARRAY_COUNT(sTargetIdentities));
|
||
|
|
||
|
dp11b_obj_instanciate(gMultiUsePlayerCursor, 1, 0xF, 1);
|
||
|
|
||
|
// what a weird loop
|
||
|
i = 0;
|
||
|
if (gNoOfAllBanks != 0)
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
if (i != gMultiUsePlayerCursor)
|
||
|
dp11b_obj_free(i, 1);
|
||
|
i++;
|
||
|
} while (i < gNoOfAllBanks);
|
||
|
}
|
||
|
|
||
|
if (gMain.heldKeys & DPAD_ANY && gSaveBlock2Ptr->optionsButtonMode == 2)
|
||
|
gUnknown_020244CC++;
|
||
|
else
|
||
|
gUnknown_020244CC = 0;
|
||
|
|
||
|
if (gMain.newKeys & A_BUTTON)
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
gSprites[gBankSpriteIds[gMultiUsePlayerCursor]].callback = sub_8039B2C;
|
||
|
EmitCmd33(1, 10, gMoveSelectionCursor[gActiveBank] | (gMultiUsePlayerCursor << 8));
|
||
|
dp11b_obj_free(gMultiUsePlayerCursor, 1);
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
else if (gMain.newKeys & B_BUTTON || gUnknown_020244CC > 59)
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
gSprites[gBankSpriteIds[gMultiUsePlayerCursor]].callback = sub_8039B2C;
|
||
|
gBattleBankFunc[gActiveBank] = HandleInputChooseMove;
|
||
|
dp11b_obj_instanciate(gActiveBank, 1, 7, 1);
|
||
|
dp11b_obj_instanciate(gActiveBank, 0, 7, 1);
|
||
|
dp11b_obj_free(gMultiUsePlayerCursor, 1);
|
||
|
}
|
||
|
else if (gMain.newKeys & (DPAD_LEFT | DPAD_UP))
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
gSprites[gBankSpriteIds[gMultiUsePlayerCursor]].callback = sub_8039B2C;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
u8 currSelIdentity = GetBankIdentity(gMultiUsePlayerCursor);
|
||
|
|
||
|
for (i = 0; i < BATTLE_BANKS_COUNT; i++)
|
||
|
{
|
||
|
if (currSelIdentity == identities[i])
|
||
|
break;
|
||
|
}
|
||
|
do
|
||
|
{
|
||
|
if (--i < 0)
|
||
|
i = 4; // UB: array out of range
|
||
|
gMultiUsePlayerCursor = GetBankByIdentity(identities[i]);
|
||
|
} while (gMultiUsePlayerCursor == gNoOfAllBanks);
|
||
|
|
||
|
i = 0;
|
||
|
switch (GetBankIdentity(gMultiUsePlayerCursor))
|
||
|
{
|
||
|
case IDENTITY_PLAYER_MON1:
|
||
|
case IDENTITY_PLAYER_MON2:
|
||
|
if (gActiveBank != gMultiUsePlayerCursor)
|
||
|
i++;
|
||
|
else if (gBattleMoves[GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBank])].target & MOVE_TARGET_USER)
|
||
|
i++;
|
||
|
break;
|
||
|
case IDENTITY_OPPONENT_MON1:
|
||
|
case IDENTITY_OPPONENT_MON2:
|
||
|
i++;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (gAbsentBankFlags & gBitTable[gMultiUsePlayerCursor])
|
||
|
i = 0;
|
||
|
} while (i == 0);
|
||
|
gSprites[gBankSpriteIds[gMultiUsePlayerCursor]].callback = sub_8039AD8;
|
||
|
}
|
||
|
else if (gMain.newKeys & (DPAD_RIGHT | DPAD_DOWN))
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
gSprites[gBankSpriteIds[gMultiUsePlayerCursor]].callback = sub_8039B2C;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
u8 currSelIdentity = GetBankIdentity(gMultiUsePlayerCursor);
|
||
|
|
||
|
for (i = 0; i < BATTLE_BANKS_COUNT; i++)
|
||
|
{
|
||
|
if (currSelIdentity == identities[i])
|
||
|
break;
|
||
|
}
|
||
|
do
|
||
|
{
|
||
|
if (++i > 3)
|
||
|
i = 0;
|
||
|
gMultiUsePlayerCursor = GetBankByIdentity(identities[i]);
|
||
|
} while (gMultiUsePlayerCursor == gNoOfAllBanks);
|
||
|
|
||
|
i = 0;
|
||
|
switch (GetBankIdentity(gMultiUsePlayerCursor))
|
||
|
{
|
||
|
case IDENTITY_PLAYER_MON1:
|
||
|
case IDENTITY_PLAYER_MON2:
|
||
|
if (gActiveBank != gMultiUsePlayerCursor)
|
||
|
i++;
|
||
|
else if (gBattleMoves[GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBank])].target & MOVE_TARGET_USER)
|
||
|
i++;
|
||
|
break;
|
||
|
case IDENTITY_OPPONENT_MON1:
|
||
|
case IDENTITY_OPPONENT_MON2:
|
||
|
i++;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (gAbsentBankFlags & gBitTable[gMultiUsePlayerCursor])
|
||
|
i = 0;
|
||
|
} while (i == 0);
|
||
|
gSprites[gBankSpriteIds[gMultiUsePlayerCursor]].callback = sub_8039AD8;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern u8 gNumberOfMovesToChoose;
|
||
|
extern const u8 gText_BattleSwitchWhich[];
|
||
|
|
||
|
void HandleInputChooseMove(void)
|
||
|
{
|
||
|
bool32 canSelectTarget = FALSE;
|
||
|
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleBufferA[gActiveBank][4]);
|
||
|
|
||
|
if (gMain.heldKeys & DPAD_ANY && gSaveBlock2Ptr->optionsButtonMode == 2)
|
||
|
gUnknown_020244CC++;
|
||
|
else
|
||
|
gUnknown_020244CC = 0;
|
||
|
|
||
|
if (gMain.newKeys & A_BUTTON)
|
||
|
{
|
||
|
u8 moveTarget;
|
||
|
|
||
|
PlaySE(SE_SELECT);
|
||
|
if (moveInfo->moves[gMoveSelectionCursor[gActiveBank]] == MOVE_CURSE)
|
||
|
{
|
||
|
if (moveInfo->monType1 != TYPE_GHOST && moveInfo->monType2 != TYPE_GHOST)
|
||
|
moveTarget = MOVE_TARGET_x10;
|
||
|
else
|
||
|
moveTarget = MOVE_TARGET_SELECTED;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
moveTarget = gBattleMoves[moveInfo->moves[gMoveSelectionCursor[gActiveBank]]].target;
|
||
|
}
|
||
|
|
||
|
if (moveTarget & MOVE_TARGET_x10)
|
||
|
gMultiUsePlayerCursor = gActiveBank;
|
||
|
else
|
||
|
gMultiUsePlayerCursor = GetBankByIdentity((GetBankIdentity(gActiveBank) & BIT_SIDE) ^ BIT_SIDE);
|
||
|
|
||
|
if (!gBattleBufferA[gActiveBank][1]) // not a double battle
|
||
|
{
|
||
|
if (moveTarget & MOVE_TARGET_USER && !gBattleBufferA[gActiveBank][2])
|
||
|
canSelectTarget++;
|
||
|
}
|
||
|
else // double battle
|
||
|
{
|
||
|
if (!(moveTarget & (MOVE_TARGET_RANDOM | MOVE_TARGET_BOTH | MOVE_TARGET_DEPENDS | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_x10)))
|
||
|
canSelectTarget++; // either selected or user
|
||
|
|
||
|
if (moveInfo->currentPp[gMoveSelectionCursor[gActiveBank]] == 0)
|
||
|
{
|
||
|
canSelectTarget = FALSE;
|
||
|
}
|
||
|
else if (!(moveTarget & (MOVE_TARGET_x10 | MOVE_TARGET_USER)) && CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) <= 1)
|
||
|
{
|
||
|
gMultiUsePlayerCursor = GetDefaultMoveTarget(gActiveBank);
|
||
|
canSelectTarget = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!canSelectTarget)
|
||
|
{
|
||
|
EmitCmd33(1, 10, gMoveSelectionCursor[gActiveBank] | (gMultiUsePlayerCursor << 8));
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gBattleBankFunc[gActiveBank] = HandleInputChooseTarget;
|
||
|
|
||
|
if (moveTarget & (MOVE_TARGET_x10 | MOVE_TARGET_USER))
|
||
|
gMultiUsePlayerCursor = gActiveBank;
|
||
|
else if (gAbsentBankFlags & gBitTable[GetBankByIdentity(IDENTITY_OPPONENT_MON1)])
|
||
|
gMultiUsePlayerCursor = GetBankByIdentity(IDENTITY_OPPONENT_MON2);
|
||
|
else
|
||
|
gMultiUsePlayerCursor = GetBankByIdentity(IDENTITY_OPPONENT_MON1);
|
||
|
|
||
|
gSprites[gBankSpriteIds[gMultiUsePlayerCursor]].callback = sub_8039AD8;
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & B_BUTTON || gUnknown_020244CC > 59)
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
EmitCmd33(1, 10, 0xFFFF);
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
else if (gMain.newKeys & DPAD_LEFT)
|
||
|
{
|
||
|
if (gMoveSelectionCursor[gActiveBank] & 1)
|
||
|
{
|
||
|
MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBank]);
|
||
|
gMoveSelectionCursor[gActiveBank] ^= 1;
|
||
|
PlaySE(SE_SELECT);
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 0);
|
||
|
MoveSelectionDisplayPpNumber();
|
||
|
MoveSelectionDisplayMoveType();
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & DPAD_RIGHT)
|
||
|
{
|
||
|
if (!(gMoveSelectionCursor[gActiveBank] & 1)
|
||
|
&& (gMoveSelectionCursor[gActiveBank] ^ 1) < gNumberOfMovesToChoose)
|
||
|
{
|
||
|
MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBank]);
|
||
|
gMoveSelectionCursor[gActiveBank] ^= 1;
|
||
|
PlaySE(SE_SELECT);
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 0);
|
||
|
MoveSelectionDisplayPpNumber();
|
||
|
MoveSelectionDisplayMoveType();
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & DPAD_UP)
|
||
|
{
|
||
|
if (gMoveSelectionCursor[gActiveBank] & 2)
|
||
|
{
|
||
|
MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBank]);
|
||
|
gMoveSelectionCursor[gActiveBank] ^= 2;
|
||
|
PlaySE(SE_SELECT);
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 0);
|
||
|
MoveSelectionDisplayPpNumber();
|
||
|
MoveSelectionDisplayMoveType();
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & DPAD_DOWN)
|
||
|
{
|
||
|
if (!(gMoveSelectionCursor[gActiveBank] & 2)
|
||
|
&& (gMoveSelectionCursor[gActiveBank] ^ 2) < gNumberOfMovesToChoose)
|
||
|
{
|
||
|
MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBank]);
|
||
|
gMoveSelectionCursor[gActiveBank] ^= 2;
|
||
|
PlaySE(SE_SELECT);
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 0);
|
||
|
MoveSelectionDisplayPpNumber();
|
||
|
MoveSelectionDisplayMoveType();
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & SELECT_BUTTON)
|
||
|
{
|
||
|
if (gNumberOfMovesToChoose > 1 && !(gBattleTypeFlags & BATTLE_TYPE_LINK))
|
||
|
{
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 29);
|
||
|
|
||
|
if (gMoveSelectionCursor[gActiveBank] != 0)
|
||
|
gMultiUsePlayerCursor = 0;
|
||
|
else
|
||
|
gMultiUsePlayerCursor = gMoveSelectionCursor[gActiveBank] + 1;
|
||
|
|
||
|
MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 27);
|
||
|
sub_814F9EC(gText_BattleSwitchWhich, 0xB);
|
||
|
gBattleBankFunc[gActiveBank] = HandleMoveSwitchting;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern u16 gBattle_BG0_X;
|
||
|
extern u16 gBattle_BG0_Y;
|
||
|
|
||
|
u32 sub_8057FBC(void) // unused
|
||
|
{
|
||
|
u32 var = 0;
|
||
|
|
||
|
if (gMain.newKeys & A_BUTTON)
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
var = 1;
|
||
|
}
|
||
|
if (gMain.newKeys & B_BUTTON)
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
gBattle_BG0_X = 0;
|
||
|
gBattle_BG0_Y = 0x140;
|
||
|
var = 0xFF;
|
||
|
}
|
||
|
if (gMain.newKeys & DPAD_LEFT && gMoveSelectionCursor[gActiveBank] & 1)
|
||
|
{
|
||
|
MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBank]);
|
||
|
gMoveSelectionCursor[gActiveBank] ^= 1;
|
||
|
PlaySE(SE_SELECT);
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 0);
|
||
|
}
|
||
|
if (gMain.newKeys & DPAD_RIGHT && !(gMoveSelectionCursor[gActiveBank] & 1)
|
||
|
&& (gMoveSelectionCursor[gActiveBank] ^ 1) < gNumberOfMovesToChoose)
|
||
|
{
|
||
|
MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBank]);
|
||
|
gMoveSelectionCursor[gActiveBank] ^= 1;
|
||
|
PlaySE(SE_SELECT);
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 0);
|
||
|
}
|
||
|
if (gMain.newKeys & DPAD_UP && gMoveSelectionCursor[gActiveBank] & 2)
|
||
|
{
|
||
|
MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBank]);
|
||
|
gMoveSelectionCursor[gActiveBank] ^= 2;
|
||
|
PlaySE(SE_SELECT);
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 0);
|
||
|
}
|
||
|
if (gMain.newKeys & DPAD_DOWN && !(gMoveSelectionCursor[gActiveBank] & 2)
|
||
|
&& (gMoveSelectionCursor[gActiveBank] ^ 2) < gNumberOfMovesToChoose)
|
||
|
{
|
||
|
MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBank]);
|
||
|
gMoveSelectionCursor[gActiveBank] ^= 2;
|
||
|
PlaySE(SE_SELECT);
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 0);
|
||
|
}
|
||
|
|
||
|
return var;
|
||
|
}
|
||
|
|
||
|
void HandleMoveSwitchting(void)
|
||
|
{
|
||
|
u8 perMovePPBonuses[4];
|
||
|
struct ChooseMoveStruct moveStruct;
|
||
|
u8 totalPPBonuses;
|
||
|
|
||
|
if (gMain.newKeys & (A_BUTTON | SELECT_BUTTON))
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
|
||
|
if (gMoveSelectionCursor[gActiveBank] != gMultiUsePlayerCursor)
|
||
|
{
|
||
|
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleBufferA[gActiveBank][4]);
|
||
|
s32 i;
|
||
|
|
||
|
// swap moves and pp
|
||
|
i = moveInfo->moves[gMoveSelectionCursor[gActiveBank]];
|
||
|
moveInfo->moves[gMoveSelectionCursor[gActiveBank]] = moveInfo->moves[gMultiUsePlayerCursor];
|
||
|
moveInfo->moves[gMultiUsePlayerCursor] = i;
|
||
|
|
||
|
i = moveInfo->currentPp[gMoveSelectionCursor[gActiveBank]];
|
||
|
moveInfo->currentPp[gMoveSelectionCursor[gActiveBank]] = moveInfo->currentPp[gMultiUsePlayerCursor];
|
||
|
moveInfo->currentPp[gMultiUsePlayerCursor] = i;
|
||
|
|
||
|
i = moveInfo->maxPp[gMoveSelectionCursor[gActiveBank]];
|
||
|
moveInfo->maxPp[gMoveSelectionCursor[gActiveBank]] = moveInfo->maxPp[gMultiUsePlayerCursor];
|
||
|
moveInfo->maxPp[gMultiUsePlayerCursor] = i;
|
||
|
|
||
|
if (gDisableStructs[gActiveBank].unk18_b & gBitTable[gMoveSelectionCursor[gActiveBank]])
|
||
|
{
|
||
|
gDisableStructs[gActiveBank].unk18_b &= (~gBitTable[gMoveSelectionCursor[gActiveBank]]);
|
||
|
gDisableStructs[gActiveBank].unk18_b |= gBitTable[gMultiUsePlayerCursor];
|
||
|
}
|
||
|
|
||
|
MoveSelectionDisplayMoveNames();
|
||
|
|
||
|
for (i = 0; i < 4; i++)
|
||
|
perMovePPBonuses[i] = (gBattleMons[gActiveBank].ppBonuses & (3 << (i * 2))) >> (i * 2);
|
||
|
|
||
|
totalPPBonuses = perMovePPBonuses[gMoveSelectionCursor[gActiveBank]];
|
||
|
perMovePPBonuses[gMoveSelectionCursor[gActiveBank]] = perMovePPBonuses[gMultiUsePlayerCursor];
|
||
|
perMovePPBonuses[gMultiUsePlayerCursor] = totalPPBonuses;
|
||
|
|
||
|
totalPPBonuses = 0;
|
||
|
for (i = 0; i < 4; i++)
|
||
|
totalPPBonuses |= perMovePPBonuses[i] << (i * 2);
|
||
|
|
||
|
gBattleMons[gActiveBank].ppBonuses = totalPPBonuses;
|
||
|
|
||
|
for (i = 0; i < 4; i++)
|
||
|
{
|
||
|
gBattleMons[gActiveBank].moves[i] = moveInfo->moves[i];
|
||
|
gBattleMons[gActiveBank].pp[i] = moveInfo->currentPp[i];
|
||
|
}
|
||
|
|
||
|
if (!(gBattleMons[gActiveBank].status2 & STATUS2_TRANSFORMED))
|
||
|
{
|
||
|
for (i = 0; i < 4; i++)
|
||
|
{
|
||
|
moveStruct.moves[i] = GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_MOVE1 + i);
|
||
|
moveStruct.currentPp[i] = GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_PP1 + i);
|
||
|
}
|
||
|
|
||
|
totalPPBonuses = GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_PP_BONUSES);
|
||
|
for (i = 0; i < 4; i++)
|
||
|
perMovePPBonuses[i] = (totalPPBonuses & (3 << (i * 2))) >> (i * 2);
|
||
|
|
||
|
i = moveStruct.moves[gMoveSelectionCursor[gActiveBank]];
|
||
|
moveStruct.moves[gMoveSelectionCursor[gActiveBank]] = moveStruct.moves[gMultiUsePlayerCursor];
|
||
|
moveStruct.moves[gMultiUsePlayerCursor] = i;
|
||
|
|
||
|
i = moveStruct.currentPp[gMoveSelectionCursor[gActiveBank]];
|
||
|
moveStruct.currentPp[gMoveSelectionCursor[gActiveBank]] = moveStruct.currentPp[gMultiUsePlayerCursor];
|
||
|
moveStruct.currentPp[gMultiUsePlayerCursor] = i;
|
||
|
|
||
|
totalPPBonuses = perMovePPBonuses[gMoveSelectionCursor[gActiveBank]];
|
||
|
perMovePPBonuses[gMoveSelectionCursor[gActiveBank]] = perMovePPBonuses[gMultiUsePlayerCursor];
|
||
|
perMovePPBonuses[gMultiUsePlayerCursor] = totalPPBonuses;
|
||
|
|
||
|
totalPPBonuses = 0;
|
||
|
for (i = 0; i < 4; i++)
|
||
|
totalPPBonuses |= perMovePPBonuses[i] << (i * 2);
|
||
|
|
||
|
for (i = 0; i < 4; i++)
|
||
|
{
|
||
|
SetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_MOVE1 + i, &moveStruct.moves[i]);
|
||
|
SetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_PP1 + i, &moveStruct.currentPp[i]);
|
||
|
}
|
||
|
|
||
|
SetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_PP_BONUSES, &totalPPBonuses);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
gBattleBankFunc[gActiveBank] = HandleInputChooseMove;
|
||
|
gMoveSelectionCursor[gActiveBank] = gMultiUsePlayerCursor;
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 0);
|
||
|
MoveSelectionDisplayPpString();
|
||
|
MoveSelectionDisplayPpNumber();
|
||
|
MoveSelectionDisplayMoveType();
|
||
|
}
|
||
|
else if (gMain.newKeys & (B_BUTTON | SELECT_BUTTON))
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
MoveSelectionDestroyCursorAt(gMultiUsePlayerCursor);
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 0);
|
||
|
gBattleBankFunc[gActiveBank] = HandleInputChooseMove;
|
||
|
MoveSelectionDisplayPpString();
|
||
|
MoveSelectionDisplayPpNumber();
|
||
|
MoveSelectionDisplayMoveType();
|
||
|
}
|
||
|
else if (gMain.newKeys & DPAD_LEFT)
|
||
|
{
|
||
|
if (gMultiUsePlayerCursor & 1)
|
||
|
{
|
||
|
if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBank])
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 29);
|
||
|
else
|
||
|
MoveSelectionDestroyCursorAt(gMultiUsePlayerCursor);
|
||
|
|
||
|
gMultiUsePlayerCursor ^= 1;
|
||
|
PlaySE(SE_SELECT);
|
||
|
|
||
|
if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBank])
|
||
|
MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 0);
|
||
|
else
|
||
|
MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 27);
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & DPAD_RIGHT)
|
||
|
{
|
||
|
if (!(gMultiUsePlayerCursor & 1) && (gMultiUsePlayerCursor ^ 1) < gNumberOfMovesToChoose)
|
||
|
{
|
||
|
if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBank])
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 29);
|
||
|
else
|
||
|
MoveSelectionDestroyCursorAt(gMultiUsePlayerCursor);
|
||
|
|
||
|
gMultiUsePlayerCursor ^= 1;
|
||
|
PlaySE(SE_SELECT);
|
||
|
|
||
|
if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBank])
|
||
|
MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 0);
|
||
|
else
|
||
|
MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 27);
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & DPAD_UP)
|
||
|
{
|
||
|
if (gMultiUsePlayerCursor & 2)
|
||
|
{
|
||
|
if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBank])
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 29);
|
||
|
else
|
||
|
MoveSelectionDestroyCursorAt(gMultiUsePlayerCursor);
|
||
|
|
||
|
gMultiUsePlayerCursor ^= 2;
|
||
|
PlaySE(SE_SELECT);
|
||
|
|
||
|
if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBank])
|
||
|
MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 0);
|
||
|
else
|
||
|
MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 27);
|
||
|
}
|
||
|
}
|
||
|
else if (gMain.newKeys & DPAD_DOWN)
|
||
|
{
|
||
|
if (!(gMultiUsePlayerCursor & 2) && (gMultiUsePlayerCursor ^ 2) < gNumberOfMovesToChoose)
|
||
|
{
|
||
|
if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBank])
|
||
|
MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBank], 29);
|
||
|
else
|
||
|
MoveSelectionDestroyCursorAt(gMultiUsePlayerCursor);
|
||
|
|
||
|
gMultiUsePlayerCursor ^= 2;
|
||
|
PlaySE(SE_SELECT);
|
||
|
|
||
|
if (gMultiUsePlayerCursor == gMoveSelectionCursor[gActiveBank])
|
||
|
MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 0);
|
||
|
else
|
||
|
MoveSelectionCreateCursorAt(gMultiUsePlayerCursor, 27);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern u8 gBattleOutcome;
|
||
|
extern void sub_817E3F4(void); // battle_link_817C95C
|
||
|
|
||
|
void sub_80586F8(void)
|
||
|
{
|
||
|
if (gLinkVSyncDisabled == 0)
|
||
|
{
|
||
|
if (gReceivedRemoteLinkPlayers == 0)
|
||
|
{
|
||
|
m4aSongNumStop(SE_HINSI);
|
||
|
gMain.inBattle = 0;
|
||
|
gMain.callback1 = gPreBattleCallback1;
|
||
|
SetMainCallback2(sub_8038D64);
|
||
|
if (gBattleOutcome == BATTLE_WON)
|
||
|
sub_817E3F4();
|
||
|
FreeAllWindowBuffers();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (sub_800A520())
|
||
|
{
|
||
|
m4aSongNumStop(SE_HINSI);
|
||
|
gMain.inBattle = 0;
|
||
|
gMain.callback1 = gPreBattleCallback1;
|
||
|
SetMainCallback2(sub_8038D64);
|
||
|
if (gBattleOutcome == BATTLE_WON)
|
||
|
sub_817E3F4();
|
||
|
FreeAllWindowBuffers();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void sub_80587B0(void)
|
||
|
{
|
||
|
if (!gPaletteFade.active)
|
||
|
{
|
||
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
||
|
{
|
||
|
if (sub_800A520())
|
||
|
{
|
||
|
if (gLinkVSyncDisabled == 0)
|
||
|
sub_800AC34();
|
||
|
else
|
||
|
sub_800ADF8();
|
||
|
|
||
|
gBattleBankFunc[gActiveBank] = sub_80586F8;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m4aSongNumStop(SE_HINSI);
|
||
|
gMain.inBattle = 0;
|
||
|
gMain.callback1 = gPreBattleCallback1;
|
||
|
SetMainCallback2(gMain.savedCallback);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CompleteOnBankSpriteCallbackDummy(void)
|
||
|
{
|
||
|
if (gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy)
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
|
||
|
void CompleteOnBankSpriteCallbackDummy2(void)
|
||
|
{
|
||
|
if (gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy)
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
|
||
|
void sub_80588B4(void)
|
||
|
{
|
||
|
if (gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy)
|
||
|
{
|
||
|
nullsub_25(gSaveBlock2Ptr->playerGender);
|
||
|
FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBank]]);
|
||
|
DestroySprite(&gSprites[gBankSpriteIds[gActiveBank]]);
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void sub_8058924(void)
|
||
|
{
|
||
|
if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_9 == 0xFF)
|
||
|
{
|
||
|
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_9 = 0;
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
|
||
|
|
||
|
extern bool8 IsDoubleBattle(void);
|
||
|
|
||
|
void sub_805896C(void)
|
||
|
{
|
||
|
bool8 var = FALSE;
|
||
|
|
||
|
if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)))
|
||
|
{
|
||
|
if (gSprites[gHealthBoxesIds[gActiveBank]].callback == SpriteCallbackDummy)
|
||
|
var = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (gSprites[gHealthBoxesIds[gActiveBank]].callback == SpriteCallbackDummy
|
||
|
&& gSprites[gHealthBoxesIds[gActiveBank ^ BIT_MON]].callback == SpriteCallbackDummy)
|
||
|
var = TRUE;
|
||
|
}
|
||
|
|
||
|
if (var && 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);
|
||
|
|
||
|
sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
|
||
|
|
||
|
if (IsDoubleBattle())
|
||
|
sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank ^ BIT_MON]], gActiveBank ^ BIT_MON);
|
||
|
|
||
|
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_9 = 3;
|
||
|
gBattleBankFunc[gActiveBank] = sub_8058924;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern void sub_8172EF0(u8 bank, struct Pokemon *mon);
|
||
|
extern void sub_8076918(u8 bank);
|
||
|
extern u8 gUnknown_03005D7C[];
|
||
|
|
||
|
void sub_8058B40(void)
|
||
|
{
|
||
|
bool32 r9 = FALSE;
|
||
|
bool32 r8 = FALSE;
|
||
|
|
||
|
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x8)
|
||
|
sub_8172EF0(gActiveBank, &gPlayerParty[gBattlePartyID[gActiveBank]]);
|
||
|
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON].flag_x80 && !gBattleSpritesDataPtr->healthBoxesData[gActiveBank ^ BIT_MON].flag_x8)
|
||
|
sub_8172EF0(gActiveBank ^ BIT_MON, &gPlayerParty[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], &gPlayerParty[gBattlePartyID[gActiveBank ^ BIT_MON]], HEALTHBOX_ALL);
|
||
|
sub_8076918(gActiveBank ^ BIT_MON);
|
||
|
SetHealthboxSpriteVisible(gHealthBoxesIds[gActiveBank ^ BIT_MON]);
|
||
|
}
|
||
|
UpdateHealthboxAttribute(gHealthBoxesIds[gActiveBank], &gPlayerParty[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)
|
||
|
m4aMPlayContinue(&gMPlay_BGM);
|
||
|
else
|
||
|
m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
|
||
|
}
|
||
|
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x20 = 1;
|
||
|
r9 = TRUE;
|
||
|
}
|
||
|
|
||
|
if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI)))
|
||
|
{
|
||
|
if (gSprites[gUnknown_03005D7C[gActiveBank]].callback == SpriteCallbackDummy
|
||
|
&& gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy)
|
||
|
{
|
||
|
r8 = 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)
|
||
|
{
|
||
|
r8 = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (r9 && r8)
|
||
|
{
|
||
|
if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
|
||
|
DestroySprite(&gSprites[gUnknown_03005D7C[gActiveBank ^ BIT_MON]]);
|
||
|
DestroySprite(&gSprites[gUnknown_03005D7C[gActiveBank]]);
|
||
|
|
||
|
gBattleSpritesDataPtr->animationData->field_9_x1 = 0;
|
||
|
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x20 = 0;
|
||
|
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x80 = 0;
|
||
|
|
||
|
gBattleBankFunc[gActiveBank] = sub_805896C;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern void sub_805E408(u8 bank);
|
||
|
extern void move_anim_start_t4(u8 arg0, u8 atkBank, u8 defBank, u8 tableId);
|
||
|
|
||
|
void sub_8058EDC(void)
|
||
|
{
|
||
|
if (gSprites[gHealthBoxesIds[gActiveBank]].callback == SpriteCallbackDummy
|
||
|
&& gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x1
|
||
|
&& gSprites[gBankSpriteIds[gActiveBank]].callback == SpriteCallbackDummy)
|
||
|
{
|
||
|
sub_805E408(gActiveBank);
|
||
|
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x80 = 0;
|
||
|
gBattleSpritesDataPtr->healthBoxesData[gActiveBank].field_1_x1 = 0;
|
||
|
FreeSpriteTilesByTag(0x27F9);
|
||
|
FreeSpritePaletteByTag(0x27F9);
|
||
|
|
||
|
if (gBattleSpritesDataPtr->bankData[gActiveBank].behindSubstitute)
|
||
|
move_anim_start_t4(gActiveBank, gActiveBank, gActiveBank, 6);
|
||
|
|
||
|
gBattleBankFunc[gActiveBank] = sub_8058FC0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void sub_8058FC0(void)
|
||
|
{
|
||
|
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x40
|
||
|
&& !IsCryPlayingOrClearCrySongs())
|
||
|
{
|
||
|
m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
|
||
|
sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void sub_805902C(void)
|
||
|
{
|
||
|
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x80
|
||
|
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x8)
|
||
|
{
|
||
|
sub_8172EF0(gActiveBank, &gPlayerParty[gBattlePartyID[gActiveBank]]);
|
||
|
}
|
||
|
|
||
|
if (gSprites[gUnknown_03005D7C[gActiveBank]].callback == SpriteCallbackDummy
|
||
|
&& !gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x8)
|
||
|
{
|
||
|
DestroySprite(&gSprites[gUnknown_03005D7C[gActiveBank]]);
|
||
|
UpdateHealthboxAttribute(gHealthBoxesIds[gActiveBank], &gPlayerParty[gBattlePartyID[gActiveBank]], HEALTHBOX_ALL);
|
||
|
sub_8076918(gActiveBank);
|
||
|
SetHealthboxSpriteVisible(gHealthBoxesIds[gActiveBank]);
|
||
|
gBattleBankFunc[gActiveBank] = sub_8058EDC;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void c3_0802FDF4(u8 taskId)
|
||
|
{
|
||
|
if (!IsCryPlayingOrClearCrySongs())
|
||
|
{
|
||
|
m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100);
|
||
|
DestroyTask(taskId);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void bx_t1_healthbar_update(void)
|
||
|
{
|
||
|
s16 hpValue = sub_8074AA0(gActiveBank, gHealthBoxesIds[gActiveBank], 0, 0);
|
||
|
|
||
|
SetHealthboxSpriteVisible(gHealthBoxesIds[gActiveBank]);
|
||
|
|
||
|
if (hpValue != -1)
|
||
|
{
|
||
|
UpdateHpTextInHealthbox(gHealthBoxesIds[gActiveBank], hpValue, HP_CURRENT);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sub_805E990(&gPlayerParty[gBattlePartyID[gActiveBank]], gActiveBank);
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CompleteOnInactiveTextPrinter(void)
|
||
|
{
|
||
|
if (!IsTextPrinterActive(0))
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
|
||
|
void sub_80591B8(u8 taskId)
|
||
|
{
|
||
|
u32 monId = (u8)(gTasks[taskId].data[0]);
|
||
|
u8 bank = gTasks[taskId].data[2];
|
||
|
s16 gainedExp = gTasks[taskId].data[1];
|
||
|
|
||
|
if (IsDoubleBattle() == TRUE || monId != gBattlePartyID[bank])
|
||
|
{
|
||
|
struct Pokemon *mon = &gPlayerParty[monId];
|
||
|
u16 species = GetMonData(mon, MON_DATA_SPECIES);
|
||
|
u8 level = GetMonData(mon, MON_DATA_LEVEL);
|
||
|
u32 currExp = GetMonData(mon, MON_DATA_EXP);
|
||
|
u32 nextLvlExp = gExperienceTables[gBaseStats[species].growthRate][level + 1];
|
||
|
|
||
|
if (currExp + gainedExp >= nextLvlExp)
|
||
|
{
|
||
|
u8 savedActiveBank;
|
||
|
|
||
|
SetMonData(mon, MON_DATA_EXP, &nextLvlExp);
|
||
|
CalculateMonStats(mon);
|
||
|
gainedExp -= nextLvlExp - currExp;
|
||
|
savedActiveBank = gActiveBank;
|
||
|
gActiveBank = bank;
|
||
|
EmitCmd33(1, 11, gainedExp);
|
||
|
gActiveBank = savedActiveBank;
|
||
|
|
||
|
if (IsDoubleBattle() == TRUE
|
||
|
&& ((u16)(monId) == gBattlePartyID[bank] || (u16)(monId) == gBattlePartyID[bank ^ BIT_MON]))
|
||
|
gTasks[taskId].func = sub_8059544;
|
||
|
else
|
||
|
gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
currExp += gainedExp;
|
||
|
SetMonData(mon, MON_DATA_EXP, &currExp);
|
||
|
gBattleBankFunc[bank] = CompleteOnInactiveTextPrinter;
|
||
|
DestroyTask(taskId);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gTasks[taskId].func = sub_8059330;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void sub_8059330(u8 taskId)
|
||
|
{
|
||
|
u8 monIndex = gTasks[taskId].data[0];
|
||
|
s32 gainedExp = gTasks[taskId].data[1];
|
||
|
u8 bank = gTasks[taskId].data[2];
|
||
|
struct Pokemon *mon = &gPlayerParty[monIndex];
|
||
|
u8 level = GetMonData(mon, MON_DATA_LEVEL);
|
||
|
u16 species = GetMonData(mon, MON_DATA_SPECIES);
|
||
|
u32 exp = GetMonData(mon, MON_DATA_EXP);
|
||
|
u32 currLvlExp = gExperienceTables[gBaseStats[species].growthRate][level];
|
||
|
u32 expToNextLvl;
|
||
|
|
||
|
exp -= currLvlExp;
|
||
|
expToNextLvl = gExperienceTables[gBaseStats[species].growthRate][level + 1] - currLvlExp;
|
||
|
SetBattleBarStruct(bank, gHealthBoxesIds[bank], expToNextLvl, exp, -gainedExp);
|
||
|
PlaySE(SE_EXP);
|
||
|
gTasks[taskId].func = sub_8059400;
|
||
|
}
|
||
|
|
||
|
void sub_8059400(u8 taskId)
|
||
|
{
|
||
|
if (gTasks[taskId].data[10] < 13)
|
||
|
{
|
||
|
gTasks[taskId].data[10]++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
u8 monId = gTasks[taskId].data[0];
|
||
|
s16 gainedExp = gTasks[taskId].data[1];
|
||
|
u8 bank = gTasks[taskId].data[2];
|
||
|
s16 r4;
|
||
|
|
||
|
r4 = sub_8074AA0(bank, gHealthBoxesIds[bank], 1, 0);
|
||
|
SetHealthboxSpriteVisible(gHealthBoxesIds[bank]);
|
||
|
if (r4 == -1)
|
||
|
{
|
||
|
u8 level;
|
||
|
s32 currExp;
|
||
|
u16 species;
|
||
|
s32 expOnNextLvl;
|
||
|
|
||
|
m4aSongNumStop(SE_EXP);
|
||
|
level = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL);
|
||
|
currExp = GetMonData(&gPlayerParty[monId], MON_DATA_EXP);
|
||
|
species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES);
|
||
|
expOnNextLvl = gExperienceTables[gBaseStats[species].growthRate][level + 1];
|
||
|
|
||
|
if (currExp + gainedExp >= expOnNextLvl)
|
||
|
{
|
||
|
u8 savedActiveBank;
|
||
|
|
||
|
SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &expOnNextLvl);
|
||
|
CalculateMonStats(&gPlayerParty[monId]);
|
||
|
gainedExp -= expOnNextLvl - currExp;
|
||
|
savedActiveBank = gActiveBank;
|
||
|
gActiveBank = bank;
|
||
|
EmitCmd33(1, 11, gainedExp);
|
||
|
gActiveBank = savedActiveBank;
|
||
|
gTasks[taskId].func = sub_8059544;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
currExp += gainedExp;
|
||
|
SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &currExp);
|
||
|
gBattleBankFunc[bank] = CompleteOnInactiveTextPrinter;
|
||
|
DestroyTask(taskId);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void sub_8059544(u8 taskId)
|
||
|
{
|
||
|
u8 bank = gTasks[taskId].data[2];
|
||
|
u8 monIndex = gTasks[taskId].data[0];
|
||
|
|
||
|
if (IsDoubleBattle() == TRUE && monIndex == gBattlePartyID[bank ^ BIT_MON])
|
||
|
bank ^= BIT_MON;
|
||
|
|
||
|
move_anim_start_t4(bank, bank, bank, 0);
|
||
|
gTasks[taskId].func = sub_80595A4;
|
||
|
}
|
||
|
|
||
|
void sub_80595A4(u8 taskId)
|
||
|
{
|
||
|
u8 bank = gTasks[taskId].data[2];
|
||
|
|
||
|
if (!gBattleSpritesDataPtr->healthBoxesData[bank].flag_x40)
|
||
|
{
|
||
|
u8 monIndex = gTasks[taskId].data[0];
|
||
|
|
||
|
GetMonData(&gPlayerParty[monIndex], MON_DATA_LEVEL); // Unused return value
|
||
|
|
||
|
if (IsDoubleBattle() == TRUE && monIndex == gBattlePartyID[bank ^ BIT_MON])
|
||
|
UpdateHealthboxAttribute(gHealthBoxesIds[bank ^ BIT_MON], &gPlayerParty[monIndex], HEALTHBOX_ALL);
|
||
|
else
|
||
|
UpdateHealthboxAttribute(gHealthBoxesIds[bank], &gPlayerParty[monIndex], HEALTHBOX_ALL);
|
||
|
|
||
|
gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DestroyExpTaskAndCompleteOnInactiveTextPrinter(u8 taskId)
|
||
|
{
|
||
|
u8 monIndex;
|
||
|
u8 bank;
|
||
|
|
||
|
monIndex = gTasks[taskId].data[0];
|
||
|
GetMonData(&gPlayerParty[monIndex], MON_DATA_LEVEL); // Unused return value
|
||
|
bank = gTasks[taskId].data[2];
|
||
|
gBattleBankFunc[bank] = CompleteOnInactiveTextPrinter;
|
||
|
DestroyTask(taskId);
|
||
|
}
|
||
|
|
||
|
void sub_80596A8(void)
|
||
|
{
|
||
|
if (gSprites[gBankSpriteIds[gActiveBank]].pos1.y + gSprites[gBankSpriteIds[gActiveBank]].pos2.y > DISPLAY_HEIGHT)
|
||
|
{
|
||
|
u16 species = GetMonData(&gPlayerParty[gBattlePartyID[gActiveBank]], MON_DATA_SPECIES);
|
||
|
|
||
|
nullsub_24(species);
|
||
|
FreeOamMatrix(gSprites[gBankSpriteIds[gActiveBank]].oam.matrixNum);
|
||
|
DestroySprite(&gSprites[gBankSpriteIds[gActiveBank]]);
|
||
|
SetHealthboxSpriteInvisible(gHealthBoxesIds[gActiveBank]);
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void sub_8059744(void)
|
||
|
{
|
||
|
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x40)
|
||
|
{
|
||
|
FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBank]]);
|
||
|
DestroySprite(&gSprites[gBankSpriteIds[gActiveBank]]);
|
||
|
SetHealthboxSpriteInvisible(gHealthBoxesIds[gActiveBank]);
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CompleteOnInactiveTextPrinter2(void)
|
||
|
{
|
||
|
if (!IsTextPrinterActive(0))
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
|
||
|
extern void sub_81B89AC(u8 arg0);
|
||
|
|
||
|
void sub_80597CC(void)
|
||
|
{
|
||
|
if (!gPaletteFade.active)
|
||
|
{
|
||
|
u8 r4;
|
||
|
|
||
|
gBattleBankFunc[gActiveBank] = sub_8059828;
|
||
|
r4 = gTasks[gUnknown_03005D7C[gActiveBank]].data[0];
|
||
|
DestroyTask(gUnknown_03005D7C[gActiveBank]);
|
||
|
FreeAllWindowBuffers();
|
||
|
sub_81B89AC(r4);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern u8 gUnknown_0203CEE8;
|
||
|
extern u8 gUnknown_0203CEE9;
|
||
|
extern u8 gUnknown_0203CF00[];
|
||
|
|
||
|
void sub_8059828(void)
|
||
|
{
|
||
|
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
|
||
|
{
|
||
|
if (gUnknown_0203CEE8 == 1)
|
||
|
EmitCmd34(1, gUnknown_0203CEE9, gUnknown_0203CF00);
|
||
|
else
|
||
|
EmitCmd34(1, 6, NULL);
|
||
|
|
||
|
if ((gBattleBufferA[gActiveBank][1] & 0xF) == 1)
|
||
|
PrintLinkStandbyMsg();
|
||
|
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern void sub_81AABB0(void);
|
||
|
extern void nullsub_35(void);
|
||
|
|
||
|
void sub_80598A4(void)
|
||
|
{
|
||
|
if (!gPaletteFade.active)
|
||
|
{
|
||
|
gBattleBankFunc[gActiveBank] = sub_80598E0;
|
||
|
nullsub_35();
|
||
|
FreeAllWindowBuffers();
|
||
|
sub_81AABB0();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern u16 gScriptItemId;
|
||
|
|
||
|
void sub_80598E0(void)
|
||
|
{
|
||
|
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
|
||
|
{
|
||
|
EmitCmd35(1, gScriptItemId);
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void sub_805991C(void)
|
||
|
{
|
||
|
if (!gDoingBattleAnim || !gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x40)
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
|
||
|
void DoHitAnimBlinkEffect(void)
|
||
|
{
|
||
|
u8 spriteId = gBankSpriteIds[gActiveBank];
|
||
|
|
||
|
if (gSprites[spriteId].data1 == 32)
|
||
|
{
|
||
|
gSprites[spriteId].data1 = 0;
|
||
|
gSprites[spriteId].invisible = 0;
|
||
|
gDoingBattleAnim = FALSE;
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((gSprites[spriteId].data1 % 4) == 0)
|
||
|
gSprites[spriteId].invisible ^= 1;
|
||
|
gSprites[spriteId].data1++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void sub_80599D4(void)
|
||
|
{
|
||
|
if (gMain.newKeys & DPAD_UP && gMultiUsePlayerCursor != 0)
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
BattleDestroyYesNoCursorAt(gMultiUsePlayerCursor);
|
||
|
gMultiUsePlayerCursor = 0;
|
||
|
BattleCreateYesNoCursorAt(0);
|
||
|
}
|
||
|
if (gMain.newKeys & DPAD_DOWN && gMultiUsePlayerCursor == 0)
|
||
|
{
|
||
|
PlaySE(SE_SELECT);
|
||
|
BattleDestroyYesNoCursorAt(gMultiUsePlayerCursor);
|
||
|
gMultiUsePlayerCursor = 1;
|
||
|
BattleCreateYesNoCursorAt(1);
|
||
|
}
|
||
|
if (gMain.newKeys & A_BUTTON)
|
||
|
{
|
||
|
sub_8056A3C(0x18, 8, 0x1D, 0xD, 1);
|
||
|
PlaySE(SE_SELECT);
|
||
|
|
||
|
if (gMultiUsePlayerCursor != 0)
|
||
|
EmitCmd33(1, 0xE, 0);
|
||
|
else
|
||
|
EmitCmd33(1, 0xD, 0);
|
||
|
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
if (gMain.newKeys & B_BUTTON)
|
||
|
{
|
||
|
sub_8056A3C(0x18, 8, 0x1D, 0xD, 1);
|
||
|
PlaySE(SE_SELECT);
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
extern const u8 gText_MoveInterfacePP[];
|
||
|
extern const u8 gText_MoveInterfaceType[];
|
||
|
|
||
|
void MoveSelectionDisplayMoveNames(void)
|
||
|
{
|
||
|
s32 i;
|
||
|
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleBufferA[gActiveBank][4]);
|
||
|
gNumberOfMovesToChoose = 0;
|
||
|
|
||
|
for (i = 0; i < 4; i++)
|
||
|
{
|
||
|
MoveSelectionDestroyCursorAt(i);
|
||
|
StringCopy(gDisplayedStringBattle, gMoveNames[moveInfo->moves[i]]);
|
||
|
sub_814F9EC(gDisplayedStringBattle, i + 3);
|
||
|
if (moveInfo->moves[i] != MOVE_NONE)
|
||
|
gNumberOfMovesToChoose++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MoveSelectionDisplayPpString(void)
|
||
|
{
|
||
|
StringCopy(gDisplayedStringBattle, gText_MoveInterfacePP);
|
||
|
sub_814F9EC(gDisplayedStringBattle, 7);
|
||
|
}
|
||
|
|
||
|
void MoveSelectionDisplayPpNumber(void)
|
||
|
{
|
||
|
u8 *txtPtr;
|
||
|
struct ChooseMoveStruct *moveInfo;
|
||
|
|
||
|
if (gBattleBufferA[gActiveBank][2] == TRUE) // check if we didn't want to display pp number
|
||
|
return;
|
||
|
|
||
|
SetPpNumbersPaletteInMoveSelection();
|
||
|
moveInfo = (struct ChooseMoveStruct*)(&gBattleBufferA[gActiveBank][4]);
|
||
|
txtPtr = ConvertIntToDecimalStringN(gDisplayedStringBattle, moveInfo->currentPp[gMoveSelectionCursor[gActiveBank]], STR_CONV_MODE_RIGHT_ALIGN, 2);
|
||
|
txtPtr[0] = CHAR_SLASH;
|
||
|
txtPtr++;
|
||
|
ConvertIntToDecimalStringN(txtPtr, moveInfo->maxPp[gMoveSelectionCursor[gActiveBank]], STR_CONV_MODE_RIGHT_ALIGN, 2);
|
||
|
|
||
|
sub_814F9EC(gDisplayedStringBattle, 9);
|
||
|
}
|
||
|
|
||
|
extern const u8 gTypeNames[][7];
|
||
|
|
||
|
void MoveSelectionDisplayMoveType(void)
|
||
|
{
|
||
|
u8 *txtPtr;
|
||
|
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleBufferA[gActiveBank][4]);
|
||
|
|
||
|
txtPtr = StringCopy(gDisplayedStringBattle, gText_MoveInterfaceType);
|
||
|
txtPtr[0] = EXT_CTRL_CODE_BEGIN;
|
||
|
txtPtr++;
|
||
|
txtPtr[0] = 6;
|
||
|
txtPtr++;
|
||
|
txtPtr[0] = 1;
|
||
|
txtPtr++;
|
||
|
|
||
|
StringCopy(txtPtr, gTypeNames[gBattleMoves[moveInfo->moves[gMoveSelectionCursor[gActiveBank]]].type]);
|
||
|
sub_814F9EC(gDisplayedStringBattle, 10);
|
||
|
}
|
||
|
|
||
|
void MoveSelectionCreateCursorAt(u8 cursorPosition, u8 arg1)
|
||
|
{
|
||
|
u16 src[2];
|
||
|
src[0] = arg1 + 1;
|
||
|
src[1] = arg1 + 2;
|
||
|
|
||
|
CopyToBgTilemapBufferRect_ChangePalette(0, src, 9 * (cursorPosition & 1) + 1, 55 + (cursorPosition & 2), 1, 2, 0x11);
|
||
|
CopyBgTilemapBufferToVram(0);
|
||
|
}
|
||
|
|
||
|
void MoveSelectionDestroyCursorAt(u8 cursorPosition)
|
||
|
{
|
||
|
u16 src[2];
|
||
|
src[0] = 0x1016;
|
||
|
src[1] = 0x1016;
|
||
|
|
||
|
CopyToBgTilemapBufferRect_ChangePalette(0, src, 9 * (cursorPosition & 1) + 1, 55 + (cursorPosition & 2), 1, 2, 0x11);
|
||
|
CopyBgTilemapBufferToVram(0);
|
||
|
}
|
||
|
|
||
|
void ActionSelectionCreateCursorAt(u8 cursorPosition, u8 arg1)
|
||
|
{
|
||
|
u16 src[2];
|
||
|
src[0] = 1;
|
||
|
src[1] = 2;
|
||
|
|
||
|
CopyToBgTilemapBufferRect_ChangePalette(0, src, 7 * (cursorPosition & 1) + 16, 35 + (cursorPosition & 2), 1, 2, 0x11);
|
||
|
CopyBgTilemapBufferToVram(0);
|
||
|
}
|
||
|
|
||
|
void ActionSelectionDestroyCursorAt(u8 cursorPosition)
|
||
|
{
|
||
|
u16 src[2];
|
||
|
src[0] = 0x1016;
|
||
|
src[1] = 0x1016;
|
||
|
|
||
|
CopyToBgTilemapBufferRect_ChangePalette(0, src, 7 * (cursorPosition & 1) + 16, 35 + (cursorPosition & 2), 1, 2, 0x11);
|
||
|
CopyBgTilemapBufferToVram(0);
|
||
|
}
|
||
|
|
||
|
void SetCB2ToReshowScreenAfterMenu(void)
|
||
|
{
|
||
|
SetMainCallback2(ReshowBattleScreenAfterMenu);
|
||
|
}
|
||
|
|
||
|
void SetCB2ToReshowScreenAfterMenu2(void)
|
||
|
{
|
||
|
SetMainCallback2(ReshowBattleScreenAfterMenu);
|
||
|
}
|
||
|
|
||
|
void sub_8059D60(void)
|
||
|
{
|
||
|
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x10)
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
|
||
|
void sub_8059D90(void)
|
||
|
{
|
||
|
if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBank].flag_x20)
|
||
|
PlayerBufferExecCompleted();
|
||
|
}
|
||
|
|
||
|
extern const u8 gText_LinkStandby[];
|
||
|
|
||
|
void PrintLinkStandbyMsg(void)
|
||
|
{
|
||
|
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
|
||
|
{
|
||
|
gBattle_BG0_X = 0;
|
||
|
gBattle_BG0_Y = 0;
|
||
|
sub_814F9EC(gText_LinkStandby, 0);
|
||
|
}
|
||
|
}
|