From 00b44d588618c9a0feff1285183c183f1c97f1bb Mon Sep 17 00:00:00 2001 From: camthesaxman Date: Sun, 28 Jul 2019 20:33:25 -0500 Subject: emerald file names, part 1 --- src/battle/anim/roots.c | 6 +- src/battle/battle_2.c | 5580 --------- src/battle/battle_4.c | 15941 -------------------------- src/battle/battle_7.c | 969 -- src/battle/battle_ai.c | 2157 ---- src/battle/battle_ai_switch_items.c | 1008 -- src/battle/battle_anim.c | 3236 ------ src/battle/battle_anim_807B69C.c | 354 - src/battle/battle_anim_80A7E7C.c | 1072 -- src/battle/battle_anim_80CA710.c | 18 - src/battle/battle_anim_812C144.c | 6065 ---------- src/battle/battle_anim_813F0F4.c | 2170 ---- src/battle/battle_bg.c | 864 -- src/battle/battle_controller_linkopponent.c | 1778 --- src/battle/battle_controller_linkpartner.c | 1714 --- src/battle/battle_controller_opponent.c | 2369 ---- src/battle/battle_controller_player.c | 3239 ------ src/battle/battle_controller_safari.c | 720 -- src/battle/battle_controller_wally.c | 1605 --- src/battle/battle_interface.c | 3423 ------ src/battle/battle_message.c | 1054 -- src/battle/battle_party_menu.c | 731 -- src/battle/battle_records.c | 382 - src/battle/battle_setup.c | 1482 --- src/battle/battle_transition.c | 2511 ---- src/battle/battle_util.c | 3549 ------ src/battle/calculate_base_damage.c | 338 - src/battle/contest_link_80C2020.c | 2906 ----- src/battle/contest_link_80C857C.c | 755 -- src/battle/pokeball.c | 1203 -- src/battle/post_battle_event_funcs.c | 70 - src/battle/reshow_battle_screen.c | 316 - src/battle/smokescreen.c | 73 - src/battle_ai_script_commands.c | 2157 ++++ src/battle_ai_switch_items.c | 1008 ++ src/battle_anim.c | 3236 ++++++ src/battle_anim_effects_3.c | 6065 ++++++++++ src/battle_anim_mon_movement.c | 1072 ++ src/battle_anim_special.c | 2170 ++++ src/battle_anim_status_effects.c | 354 + src/battle_bg.c | 864 ++ src/battle_controller_link_opponent.c | 1778 +++ src/battle_controller_link_partner.c | 1714 +++ src/battle_controller_opponent.c | 2369 ++++ src/battle_controller_player.c | 3239 ++++++ src/battle_controller_safari.c | 720 ++ src/battle_controller_wally.c | 1605 +++ src/battle_gfx_sfx_util.c | 969 ++ src/battle_interface.c | 3423 ++++++ src/battle_main.c | 5580 +++++++++ src/battle_message.c | 1054 ++ src/battle_party_menu.c | 731 ++ src/battle_records.c | 382 + src/battle_script_commands.c | 15941 ++++++++++++++++++++++++++ src/battle_setup.c | 1482 +++ src/battle_transition.c | 2511 ++++ src/battle_util.c | 3549 ++++++ src/calculate_base_damage.c | 338 + src/contest_link_80C2020.c | 2906 +++++ src/contest_link_80C857C.c | 755 ++ src/pokeball.c | 1203 ++ src/pokemon_summary_screen.c | 2 +- src/post_battle_event_funcs.c | 70 + src/reshow_battle_screen.c | 316 + src/rom3.c | 2 +- src/smokescreen.c | 73 + 66 files changed, 69641 insertions(+), 69655 deletions(-) delete mode 100644 src/battle/battle_2.c delete mode 100644 src/battle/battle_4.c delete mode 100644 src/battle/battle_7.c delete mode 100644 src/battle/battle_ai.c delete mode 100644 src/battle/battle_ai_switch_items.c delete mode 100644 src/battle/battle_anim.c delete mode 100644 src/battle/battle_anim_807B69C.c delete mode 100644 src/battle/battle_anim_80A7E7C.c delete mode 100644 src/battle/battle_anim_80CA710.c delete mode 100644 src/battle/battle_anim_812C144.c delete mode 100755 src/battle/battle_anim_813F0F4.c delete mode 100644 src/battle/battle_bg.c delete mode 100644 src/battle/battle_controller_linkopponent.c delete mode 100644 src/battle/battle_controller_linkpartner.c delete mode 100644 src/battle/battle_controller_opponent.c delete mode 100644 src/battle/battle_controller_player.c delete mode 100644 src/battle/battle_controller_safari.c delete mode 100644 src/battle/battle_controller_wally.c delete mode 100644 src/battle/battle_interface.c delete mode 100644 src/battle/battle_message.c delete mode 100644 src/battle/battle_party_menu.c delete mode 100644 src/battle/battle_records.c delete mode 100644 src/battle/battle_setup.c delete mode 100644 src/battle/battle_transition.c delete mode 100644 src/battle/battle_util.c delete mode 100644 src/battle/calculate_base_damage.c delete mode 100644 src/battle/contest_link_80C2020.c delete mode 100644 src/battle/contest_link_80C857C.c delete mode 100644 src/battle/pokeball.c delete mode 100644 src/battle/post_battle_event_funcs.c delete mode 100644 src/battle/reshow_battle_screen.c delete mode 100644 src/battle/smokescreen.c create mode 100644 src/battle_ai_script_commands.c create mode 100644 src/battle_ai_switch_items.c create mode 100644 src/battle_anim.c create mode 100644 src/battle_anim_effects_3.c create mode 100644 src/battle_anim_mon_movement.c create mode 100755 src/battle_anim_special.c create mode 100644 src/battle_anim_status_effects.c create mode 100644 src/battle_bg.c create mode 100644 src/battle_controller_link_opponent.c create mode 100644 src/battle_controller_link_partner.c create mode 100644 src/battle_controller_opponent.c create mode 100644 src/battle_controller_player.c create mode 100644 src/battle_controller_safari.c create mode 100644 src/battle_controller_wally.c create mode 100644 src/battle_gfx_sfx_util.c create mode 100644 src/battle_interface.c create mode 100644 src/battle_main.c create mode 100644 src/battle_message.c create mode 100644 src/battle_party_menu.c create mode 100644 src/battle_records.c create mode 100644 src/battle_script_commands.c create mode 100644 src/battle_setup.c create mode 100644 src/battle_transition.c create mode 100644 src/battle_util.c create mode 100644 src/calculate_base_damage.c create mode 100644 src/contest_link_80C2020.c create mode 100644 src/contest_link_80C857C.c create mode 100644 src/pokeball.c create mode 100644 src/post_battle_event_funcs.c create mode 100644 src/reshow_battle_screen.c create mode 100644 src/smokescreen.c (limited to 'src') diff --git a/src/battle/anim/roots.c b/src/battle/anim/roots.c index e2dd4a2af..e0cc441aa 100644 --- a/src/battle/anim/roots.c +++ b/src/battle/anim/roots.c @@ -6,7 +6,11 @@ extern s16 gBattleAnimArgs[]; extern u8 gBattleAnimAttacker; extern u8 gBattleAnimTarget; -extern s16 gUnknown_03000728[]; + +IWRAM_DATA u32 filler_03000724; +IWRAM_DATA u16 gUnknown_03000728[4]; +IWRAM_DATA u16 gUnknown_03000730[6]; +IWRAM_DATA u32 filler_0300073c; void sub_80CB59C(struct Sprite* sprite); void sub_80CB620(struct Sprite *sprite); diff --git a/src/battle/battle_2.c b/src/battle/battle_2.c deleted file mode 100644 index 411a1ae46..000000000 --- a/src/battle/battle_2.c +++ /dev/null @@ -1,5580 +0,0 @@ -#include "global.h" -#include "constants/abilities.h" -#include "constants/battle_move_effects.h" -#include "constants/hold_effects.h" -#include "constants/items.h" -#include "constants/moves.h" -#include "constants/songs.h" -#include "constants/species.h" -#include "gba/flash_internal.h" -#include "battle.h" -#include "battle_ai.h" -#include "battle_interface.h" -#include "battle_message.h" -#include "battle_setup.h" -#include "battle_util.h" -#include "data2.h" -#include "decompress.h" -#include "event_data.h" -#include "evolution_scene.h" -#include "item.h" -#include "item_menu.h" -#include "link.h" -#include "main.h" -#include "m4a.h" -#include "name_string_util.h" -#include "overworld.h" -#include "palette.h" -#include "party_menu.h" -#include "pokeball.h" -#include "pokeblock.h" -#include "pokedex.h" -#include "pokemon.h" -#include "random.h" -#include "roamer.h" -#include "rom3.h" -#include "rom_8077ABC.h" -#include "rom_8094928.h" -#include "safari_zone.h" -#include "sound.h" -#include "sprite.h" -#include "string_util.h" -#include "task.h" -#include "text.h" -#include "trainer.h" -#include "trig.h" -#include "tv.h" -#include "scanline_effect.h" -#include "util.h" -#include "ewram.h" - -struct UnknownStruct7 -{ - u8 unk0; - u8 unk1; - u8 unk2; - u8 unk3; -}; - -struct UnknownStruct8 -{ - u8 unk0[7]; - u8 unk7; - u8 unk8[18]; - u8 unk1A; -}; - -extern void sub_802BBD4(); - -extern struct SpriteTemplate gUnknown_02024E8C; -extern const u8 Str_821F7B8[]; -extern u8 gUnknown_02023A14_50; -extern const u16 gBattleTextboxPalette[]; -extern const struct MonCoords gCastformFrontSpriteCoords[]; -extern const u8 Str_821F7EA[]; -extern const u8 gUnknown_Debug_821F7F3[]; -extern const u8 BattleText_YesNo[]; -extern u8 gStatStageRatios[][2]; -extern u8 gActionsByTurnOrder[4]; -extern struct UnknownPokemonStruct2 gMultiPartnerParty[]; -extern u8 gBattleBufferB[][0x200]; -extern u8 gActiveBattler; -extern u32 gBattleExecBuffer; -extern u8 gBattlersCount; -extern u16 gBattlerPartyIndexes[]; -extern u8 gCurrentActionFuncId; -extern u8 gBanksByTurnOrder[]; -extern u8 gBankSpriteIds[]; -extern u16 gCurrentMove; // This is mis-named. It is a species, not a move ID. -extern u8 gLastUsedAbility; -extern u8 gStringBank; -extern u8 gAbsentBattlerFlags; -extern u8 gMultiHitCounter; -extern u8 gActionForBanks[]; -extern u16 gUnknown_02024C2C[]; -extern u16 gLastUsedMove[]; -extern u16 gLastLandedMoves[]; -extern u16 gLastHitByType[]; -extern u16 gUnknown_02024C4C[]; -extern u16 gLockedMoves[]; -extern u8 gLastHitBy[]; -extern u16 gChosenMovesByBanks[]; -extern u32 gHitMarker; -extern u8 gUnknown_02024C70[]; -extern u16 gSideAffecting[]; -extern u32 gStatuses3[]; -//extern u8 gDisableStructs[][0x1C]; -extern u16 gPauseCounterBattle; -extern u16 gPaydayMoney; -extern u16 gRandomTurnNumber; -extern u8 gBattleCommunication[]; -extern u8 gUnknown_02024D1F[]; // I don't actually know what type this is. -extern u8 gBattleOutcome; -extern u16 gUnknown_02024DE8; -extern u8 gActionSelectionCursor[]; -extern u8 gMoveSelectionCursor[]; -extern u8 gUnknown_02038470[]; -extern struct Window gUnknown_030041D0; -extern struct Window gUnknown_03004210; -extern struct Window gUnknown_03004250; -extern u32 gUnknown_03004284; -extern MainCallback gPreBattleCallback1; -extern void (*gBattleMainFunc)(void); -extern u8 gLeveledUpInBattle; -extern void (*gBattleBankFunc[])(void); -extern u8 gHealthboxIDs[]; -extern u16 gBattleTypeFlags; -extern s8 gBattleTerrain; // I'm not sure if this is supposed to be s8 or u8. Regardless, it must have the same type as the return value of BattleSetup_GetTerrain. -extern u8 gReservedSpritePaletteCount; -extern u16 gTrainerBattleOpponent; -extern struct BattleEnigmaBerry gEnigmaBerries[]; -extern u16 gBlockRecvBuffer[MAX_LINK_PLAYERS][BLOCK_BUFFER_SIZE / 2]; -extern u8 gBattleMonForms[]; -extern u8 gBankAttacker; -extern u8 gBankTarget; -extern u16 gBattleWeather; -extern s32 gBattleMoveDamage; -extern struct BattlePokemon gBattleMons[]; -extern u8 gMoveResultFlags; -extern u8 BattleScript_FocusPunchSetUp[]; -extern u16 gDynamicBasePower; -extern u8 gCurrentTurnActionNumber; -extern void (* const gUnknown_081FA640[])(void); -extern void (* const gUnknown_081FA678[])(void); -extern u8* gBattlescriptCurrInstr; -extern u8 BattleScript_LinkBattleWonOrLost[]; -extern u8 BattleScript_PayDayMoneyAndPickUpItems[]; -extern u8 gUnknown_081D8E0D[]; -extern u8 BattleScript_LocalTrainerBattleWon[]; -extern u8 BattleScript_LocalBattleLost[]; -extern u8 BattleScript_GotAwaySafely[]; -extern u8 BattleScript_SmokeBallEscape[]; -extern u8 BattleScript_RanAwayUsingMonAbility[]; -extern u8 BattleScript_WildMonFled[]; -extern u8 BattleScript_ActionSwitch[]; -extern u8 BattleScript_PrintFailedToRunString[]; -extern const BattleCmdFunc gBattleScriptingCommandsTable[]; -extern u8 gCritMultiplier; -extern u8 gCurrMovePos; -extern u8 gUnknown_02024BE5; -extern u16 gChosenMove; -extern u8* gBattleScriptsForMoveEffects[]; -extern u16 gLastUsedItem; -extern u8 * const gBattlescriptsForBallThrow[]; -extern u8 * const gBattlescriptsForRunningByItem[]; -extern u8 * const gBattlescriptsForUsingItem[]; -extern u8 * const gBattlescriptsForSafariActions[]; -extern u8 gBattleTextBuff2[]; -extern u8 gNumSafariBalls; -extern u8 gUnknown_081FA70C[][3]; -extern u8 gUnknown_081FA71B[]; -extern u8 gUnknown_081FA71F[]; - -void sub_8010824(void); -static void BattlePrepIntroSlide(void); -void CheckFocusPunch_ClearVarsBeforeTurnStarts(void); -void SetActionsAndBanksTurnOrder(void); -static void TurnValuesCleanUp(u8); -void SpecialStatusesClear(void); -static void RunTurnActionsFunctions(void); -void HandleEndTurn_FinishBattle(); -static void FreeResetData_ReturnToOvOrDoEvolutions(void); -void TryEvolvePokemon(void); -static void ReturnFromBattleToOverworld(void); -static void WaitForEvoSceneToFinish(void); - -void sub_800E7C4(void) -{ - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - sub_800B858(); - SetMainCallback2(sub_800F104); - gBattleCommunication[0] = 0; - } - else - { - InitBattle(); - } -} - -void InitBattle(void) -{ - s32 i; - - SetHBlankCallback(NULL); - SetVBlankCallback(NULL); - - CpuFill32(0, (void *)VRAM, VRAM_SIZE); - - REG_MOSAIC = 0; - REG_WIN0H = 0xF0; - REG_WIN0V = 0x5051; - REG_WININ = 0; - REG_WINOUT = 0; - gBattle_WIN0H = 0xF0; - gBattle_WIN0V = 0x5051; - ScanlineEffect_Clear(); - - for (i = 0; i < 80; i++) - { - gScanlineEffectRegBuffers[0][i] = 0xF0; - gScanlineEffectRegBuffers[1][i] = 0xF0; - } - for (i = 80; i < 160; i++) - { - asm(""::"r"(i)); // Needed to stop the compiler from optimizing out the loop counter - gScanlineEffectRegBuffers[0][i] = 0xFF10; - gScanlineEffectRegBuffers[1][i] = 0xFF10; - } - //ScanlineEffect_SetParams(gUnknown_081F9674.unk0, gUnknown_081F9674.unk4, gUnknown_081F9674.unk8); - ScanlineEffect_SetParams(gUnknown_081F9674); - Text_LoadWindowTemplate(&gWindowTemplate_81E6C58); - ResetPaletteFade(); - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gBattle_BG1_X = 0; - gBattle_BG1_Y = 0; - gBattle_BG2_X = 0; - gBattle_BG2_Y = 0; - gBattle_BG3_X = 0; - gBattle_BG3_Y = 0; - -#if DEBUG - if (!(gUnknown_02023A14_50 & 8)) - gBattleTerrain = BattleSetup_GetTerrain(); -#else - gBattleTerrain = BattleSetup_GetTerrain(); -#endif - - Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58); - Text_InitWindowWithTemplate(&gUnknown_030041D0, &gWindowTemplate_81E71D0); - Text_InitWindowWithTemplate(&gUnknown_03004250, &gWindowTemplate_81E71EC); - sub_800D6D4(); - LoadBattleTextboxAndBackground(); - ResetSpriteData(); - ResetTasks(); - LoadBattleEntryBackground(); - FreeAllSpritePalettes(); - gReservedSpritePaletteCount = 4; - SetVBlankCallback(sub_800FCFC); - setup_poochyena_battle(); - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - SetMainCallback2(sub_800F298); - else - SetMainCallback2(sub_800EC9C); - if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) -#if DEBUG - && !(gUnknown_02023A14_50 & 8) -#endif - ) - { - CreateNPCTrainerParty(gEnemyParty, gTrainerBattleOpponent); - SetWildMonHeldItem(); - } - gMain.inBattle = TRUE; - for (i = 0; i < PARTY_SIZE; i++) - AdjustFriendship(&gPlayerParty[i], FRIENDSHIP_EVENT_LEAGUE_BATTLE); - gBattleCommunication[0] = 0; -} - -void sub_800E9EC(void) -{ - u16 r6 = 0; - u16 species; - u16 hp; - u32 status; - s32 i; - - for (i = 0; i < PARTY_SIZE; i++) - { - species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); - hp = GetMonData(&gPlayerParty[i], MON_DATA_HP); - status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS); - - if (species == 0) - continue; - if (species != SPECIES_EGG && hp != 0 && status == 0) - r6 |= 1 << i * 2; - - if (species == 0) - continue; - if (hp != 0 && (species == SPECIES_EGG || status != 0)) - r6 |= 2 << i * 2; - - if (species == 0) - continue; - if (species != SPECIES_EGG && hp == 0) - r6 |= 3 << i * 2; - } - gBattleStruct->unk2 = r6; - gBattleStruct->unk3 = r6 >> 8; -} - -void sub_800EAAC(void) -{ - s32 i; - struct UnknownStruct8 *_ewram4 = &ewram4; - - for (i = 0; i < 7; i++) - _ewram4->unk0[i] = gSaveBlock1.enigmaBerry.berry.name[i]; - for (i = 0; i < 18; i++) - _ewram4->unk8[i] = gSaveBlock1.enigmaBerry.itemEffect[i]; - _ewram4->unk7 = gSaveBlock1.enigmaBerry.holdEffect; - _ewram4->unk1A = gSaveBlock1.enigmaBerry.holdEffectParam; -} - -void sub_800EB08(void) -{ - s32 i; - s32 j; - - if (!(gBattleTypeFlags & BATTLE_TYPE_LINK)) - { - for (i = 0; i < 7; i++) - { - gEnigmaBerries[0].name[i] = gSaveBlock1.enigmaBerry.berry.name[i]; - gEnigmaBerries[2].name[i] = gSaveBlock1.enigmaBerry.berry.name[i]; - } - for (i = 0; i < 18; i++) - { - gEnigmaBerries[0].itemEffect[i] = gSaveBlock1.enigmaBerry.itemEffect[i]; - gEnigmaBerries[2].itemEffect[i] = gSaveBlock1.enigmaBerry.itemEffect[i]; - } - gEnigmaBerries[0].holdEffect = gSaveBlock1.enigmaBerry.holdEffect; - gEnigmaBerries[2].holdEffect = gSaveBlock1.enigmaBerry.holdEffect; - gEnigmaBerries[0].holdEffectParam = gSaveBlock1.enigmaBerry.holdEffectParam; - gEnigmaBerries[2].holdEffectParam = gSaveBlock1.enigmaBerry.holdEffectParam; - } - else - { - s32 numPlayers; - struct BattleEnigmaBerry *src; - u8 r4; - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - numPlayers = 4; - else - numPlayers = 2; - for (i = 0; i < numPlayers; i++) - { - src = (struct BattleEnigmaBerry *)(gBlockRecvBuffer[i] + 2); - r4 = gLinkPlayers[i].lp_field_18; - - for (j = 0; j < 7; j++) - gEnigmaBerries[r4].name[j] = src->name[j]; - for (j = 0; j < 18; j++) - gEnigmaBerries[r4].itemEffect[j] = src->itemEffect[j]; - gEnigmaBerries[r4].holdEffect = src->holdEffect; - gEnigmaBerries[r4].holdEffectParam = src->holdEffectParam; - } - } -} - -void shedinja_something(struct Pokemon *pkmn) -{ - u8 nickname[POKEMON_NAME_LENGTH + 1]; - u8 language = 1; - - if (GetMonData(pkmn, MON_DATA_SPECIES) == SPECIES_SHEDINJA - && GetMonData(pkmn, MON_DATA_LANGUAGE) != language) - { - GetMonData(pkmn, MON_DATA_NICKNAME, nickname); - if (StringCompareWithoutExtCtrlCodes(nickname, gUnknown_081F96C8) == 0) - SetMonData(pkmn, MON_DATA_LANGUAGE, &language); - } -} - -void sub_800EC9C(void) -{ - u8 playerId; - u8 enemyId; - s32 id; - - RunTasks(); - AnimateSprites(); - BuildOamBuffer(); - playerId = GetMultiplayerId(); - ewram160CB = playerId; - enemyId = playerId ^ 1; - - switch (gBattleCommunication[0]) - { - case 0: - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - if (gReceivedRemoteLinkPlayers != 0 && IsLinkTaskFinished()) - { - gBattleStruct->unk0 = 1; - gBattleStruct->unk1 = 1; - sub_800E9EC(); - sub_800EAAC(); -#if DEBUG - if (gUnknown_02023A14_50 & 8) - { - for (id = 0; id < 2; id++) // Why < 2 here? - { - gLinkPlayers[id].lp_field_18 = id; - gLinkPlayers[id].linkType = 0x2211; - } - } -#endif - SendBlock(bitmask_all_link_players_but_self(), gBattleStruct, 32); - gBattleCommunication[0] = 1; - } - } - else - { - gBattleTypeFlags |= BATTLE_TYPE_WILD; - gBattleCommunication[0] = 8; - sub_800EB08(); - } - break; - case 1: - if ((GetBlockReceivedStatus() & 3) == 3) - { - u8 taskId; - - ResetBlockReceivedFlags(); - id = 0; - if (gBlockRecvBuffer[0][0] == 0x100) - { - if (playerId == 0) - gBattleTypeFlags |= 12; - else - gBattleTypeFlags |= 8; - id++; - } - if (id == 0) - { - if (gBlockRecvBuffer[0][0] == gBlockRecvBuffer[1][0]) - { - if (playerId == 0) - gBattleTypeFlags |= 12; - else - gBattleTypeFlags |= 8; - id++; - } - if (id == 0) - { - while (id < 2) - { - if (gBlockRecvBuffer[id][0] > 0x0101 && id != playerId) - break; - id++; - } - if (id == 2) - gBattleTypeFlags |= 12; - else - gBattleTypeFlags |= 8; - } - } - sub_800EB08(); - taskId = CreateTask(sub_800DE30, 0); - gTasks[taskId].data[1] = 0x10E; - gTasks[taskId].data[2] = 0x5A; - gTasks[taskId].data[5] = 0; - gTasks[taskId].data[3] = gBattleStruct->unk2 | (gBattleStruct->unk3 << 8); - gTasks[taskId].data[4] = gBlockRecvBuffer[enemyId][1]; - gBattleCommunication[0]++; - } - break; - case 2: - if (IsLinkTaskFinished()) - { - SendBlock(bitmask_all_link_players_but_self(), gPlayerParty, sizeof(*gPlayerParty) * 2); - gBattleCommunication[0]++; - } - break; - case 3: - if ((GetBlockReceivedStatus() & 3) == 3) - { - ResetBlockReceivedFlags(); - memcpy(gEnemyParty, gBlockRecvBuffer[enemyId], sizeof(*gEnemyParty) * 2); - gBattleCommunication[0]++; - } - break; - case 4: - if (IsLinkTaskFinished()) - { - SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 2, sizeof(*gPlayerParty) * 2); - gBattleCommunication[0]++; - } - break; - case 5: - if ((GetBlockReceivedStatus() & 3) == 3) - { - ResetBlockReceivedFlags(); - memcpy(gEnemyParty + 2, gBlockRecvBuffer[enemyId], sizeof(*gEnemyParty) * 2); - gBattleCommunication[0]++; - } - break; - case 6: - if (IsLinkTaskFinished()) - { - SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 4, sizeof(*gPlayerParty) * 2); - gBattleCommunication[0]++; - } - break; - case 7: - if ((GetBlockReceivedStatus() & 3) == 3) - { - ResetBlockReceivedFlags(); - memcpy(gEnemyParty + 4, gBlockRecvBuffer[enemyId], sizeof(*gEnemyParty) * 2); - shedinja_something(&gEnemyParty[0]); - shedinja_something(&gEnemyParty[1]); - shedinja_something(&gEnemyParty[2]); - shedinja_something(&gEnemyParty[3]); - shedinja_something(&gEnemyParty[4]); - shedinja_something(&gEnemyParty[5]); - gBattleCommunication[0]++; - } - break; - case 8: - sub_800B950(); - gBattleCommunication[0]++; - gBattleCommunication[1] = 0; - gBattleCommunication[2] = 0; - break; - case 9: - if (battle_load_something(gUnknown_02024D1F, gUnknown_02024D1F + 1) != 0) - { - gPreBattleCallback1 = gMain.callback1; - gMain.callback1 = sub_8010824; - SetMainCallback2(BattleMainCB2); - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - gTrainerBattleOpponent = LINK_BATTLE_OPPONENT; - gBattleTypeFlags |= BATTLE_TYPE_20; - } - } - break; - } -} - -void sub_800F02C(void) -{ - s32 i; - - for (i = 0; i < 3; i++) - { - u8 *nickname = gMultiPartnerParty[i].nickname; - - gMultiPartnerParty[i].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES); - gMultiPartnerParty[i].heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); - GetMonData(&gPlayerParty[i], MON_DATA_NICKNAME, nickname); - gMultiPartnerParty[i].level = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); - gMultiPartnerParty[i].hp = GetMonData(&gPlayerParty[i], MON_DATA_HP); - gMultiPartnerParty[i].maxhp = GetMonData(&gPlayerParty[i], MON_DATA_MAX_HP); - gMultiPartnerParty[i].status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS); - gMultiPartnerParty[i].personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY); - gMultiPartnerParty[i].gender = GetMonGender(&gPlayerParty[i]); - Text_StripExtCtrlCodes(nickname); - gMultiPartnerParty[i].language = GetMonData(&gPlayerParty[i], MON_DATA_LANGUAGE); - if (gMultiPartnerParty[i].language != 1) - PadNameString(nickname, 0); - } - memcpy(gSharedMem, gMultiPartnerParty, 0x60); -} - -void sub_800F104(void) -{ - u8 playerId; - MainCallback *pSavedCallback; - u16 *pSavedBattleTypeFlags; - s32 i; - - playerId = GetMultiplayerId(); - ewram160CB = playerId; - // Seriously, Game Freak? - pSavedCallback = ewram160C4_Callback; - pSavedBattleTypeFlags = ewram160C2_Flags; - RunTasks(); - AnimateSprites(); - BuildOamBuffer(); - - switch (gBattleCommunication[0]) - { - case 0: - if (gReceivedRemoteLinkPlayers != 0) - { -#if DEBUG - if (gUnknown_02023A14_50 & 8) - { - for (i = 0; i < 4; i++) - { - gLinkPlayers[i].lp_field_18 = i; - gLinkPlayers[i].linkType = 0x2211; - } - } -#endif - if (IsLinkTaskFinished()) - { - sub_800F02C(); - SendBlock(bitmask_all_link_players_but_self(), gSharedMem, 0x60); - gBattleCommunication[0]++; - } - } - break; - case 1: - if ((GetBlockReceivedStatus() & 0xF) == 0xF) - { - //s32 i; - - ResetBlockReceivedFlags(); - for (i = 0; i < 4; i++) - { - if (i != playerId) - { - if ((!(gLinkPlayers[i].lp_field_18 & 1) && !(gLinkPlayers[playerId].lp_field_18 & 1)) - || ((gLinkPlayers[i].lp_field_18 & 1) && (gLinkPlayers[playerId].lp_field_18 & 1))) - memcpy(gMultiPartnerParty, gBlockRecvBuffer[i], 0x60); - } - } - gBattleCommunication[0]++; - *pSavedCallback = gMain.savedCallback; - *pSavedBattleTypeFlags = gBattleTypeFlags; - gMain.savedCallback = sub_800F104; - OpenPartyMenu(PARTY_MENU_TYPE_LINK_MULTI_BATTLE, 0); - } - break; - case 2: - if (!gPaletteFade.active) - { - gBattleCommunication[0] = 3; - sub_800832C(); - } - break; - case 3: - if (gReceivedRemoteLinkPlayers == 0) - { - gBattleTypeFlags = *pSavedBattleTypeFlags; - gMain.savedCallback = *pSavedCallback; - SetMainCallback2(InitBattle); - } - break; - } -} - -void sub_800F298(void) -{ - u8 playerId; - s32 id; - - playerId = GetMultiplayerId(); - ewram160CB = playerId; - RunTasks(); - AnimateSprites(); - BuildOamBuffer(); - switch (gBattleCommunication[0]) - { - case 0: - if (gReceivedRemoteLinkPlayers != 0) - { -#if DEBUG - if (gUnknown_02023A14_50 & 8) - { - for (id = 0; id < 4; id++) - { - gLinkPlayers[id].lp_field_18 = id; - gLinkPlayers[id].linkType = 0x2211; - } - } -#endif - if (IsLinkTaskFinished()) - { - gBattleStruct->unk0 = 1; - gBattleStruct->unk1 = 1; - sub_800E9EC(); - sub_800EAAC(); - SendBlock(bitmask_all_link_players_but_self(), gSharedMem, 0x20); - gBattleCommunication[0]++; - } - } - break; - case 1: - if ((GetBlockReceivedStatus() & 0xF) == 0xF) - { - u8 taskId; - - ResetBlockReceivedFlags(); - id = 0; - if (gBlockRecvBuffer[0][0] == 0x100) - { - if (playerId == 0) - gBattleTypeFlags |= 12; - else - gBattleTypeFlags |= 8; - id++; - } - if (id == 0) - { - s32 i; - - for (i = 0; i < MAX_LINK_PLAYERS; i++) - { - if (gBlockRecvBuffer[0][0] != gBlockRecvBuffer[i][0]) - break; - } - if (i == MAX_LINK_PLAYERS) - { - if (playerId == 0) - gBattleTypeFlags |= 12; - else - gBattleTypeFlags |= 8; - id++; - } - if (id == 0) - { - while (id < MAX_LINK_PLAYERS) - { - if (gBlockRecvBuffer[id][0] == 0x0101 && id != playerId) - if (id < playerId) - break; - if (gBlockRecvBuffer[id][0] > 0x0101 && id != playerId) - break; - id++; - } - if (id == MAX_LINK_PLAYERS) - gBattleTypeFlags |= 12; - else - gBattleTypeFlags |= 8; - } - } - sub_800EB08(); - memcpy(ewram1D000, gPlayerParty, sizeof(struct Pokemon) * 3); - taskId = CreateTask(sub_800DE30, 0); - gTasks[taskId].data[1] = 0x10E; - gTasks[taskId].data[2] = 0x5A; - gTasks[taskId].data[5] = 0; - gTasks[taskId].data[3] = 0; - gTasks[taskId].data[4] = 0; - for (id = 0; id < MAX_LINK_PLAYERS; id++) - { - switch (gLinkPlayers[id].lp_field_18) - { - case 0: - gTasks[taskId].data[3] |= gBlockRecvBuffer[id][1] & 0x3F; - break; - case 1: - gTasks[taskId].data[4] |= gBlockRecvBuffer[id][1] & 0x3F; - break; - case 2: - gTasks[taskId].data[3] |= (gBlockRecvBuffer[id][1] & 0x3F) << 6; - break; - case 3: - gTasks[taskId].data[4] |= (gBlockRecvBuffer[id][1] & 0x3F) << 6; - break; - } - } - ZeroPlayerPartyMons(); - ZeroEnemyPartyMons(); - gBattleCommunication[0]++; - // fallthrough - case 2: - if (IsLinkTaskFinished()) - { - SendBlock(bitmask_all_link_players_but_self(), ewram1D000, sizeof(struct Pokemon) * 2); - gBattleCommunication[0]++; - } - } - break; - case 3: - if ((GetBlockReceivedStatus() & 0xF) == 0xF) - { - ResetBlockReceivedFlags(); - for (id = 0; id < MAX_LINK_PLAYERS; id++) - { - if (id == playerId) - { - switch (gLinkPlayers[id].lp_field_18) - { - case 0: - case 3: - memcpy(gPlayerParty, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2); - break; - case 1: - case 2: - memcpy(gPlayerParty + 3, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2); - break; - } - } - else - { - if ((!(gLinkPlayers[id].lp_field_18 & 1) && !(gLinkPlayers[playerId].lp_field_18 & 1)) - || ((gLinkPlayers[id].lp_field_18 & 1) && (gLinkPlayers[playerId].lp_field_18 & 1))) - { - switch (gLinkPlayers[id].lp_field_18) - { - case 0: - case 3: - memcpy(gPlayerParty, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2); - break; - case 1: - case 2: - memcpy(gPlayerParty + 3, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2); - break; - } - } - else - { - switch (gLinkPlayers[id].lp_field_18) - { - case 0: - case 3: - memcpy(gEnemyParty, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2); - break; - case 1: - case 2: - memcpy(gEnemyParty + 3, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2); - break; - } - } - } - } - gBattleCommunication[0]++; - } - break; - case 4: - if (IsLinkTaskFinished()) - { - SendBlock(bitmask_all_link_players_but_self(), ewram1D000 + 2, sizeof(struct Pokemon)); - gBattleCommunication[0]++; - } - break; - case 5: - if ((GetBlockReceivedStatus() & 0xF) == 0xF) - { - ResetBlockReceivedFlags(); - for (id = 0; id < MAX_LINK_PLAYERS; id++) - { - if (id == playerId) - { - switch (gLinkPlayers[id].lp_field_18) - { - case 0: - case 3: - memcpy(gPlayerParty + 2, gBlockRecvBuffer[id], sizeof(struct Pokemon)); - break; - case 1: - case 2: - memcpy(gPlayerParty + 5, gBlockRecvBuffer[id], sizeof(struct Pokemon)); - break; - } - } - else - { - if ((!(gLinkPlayers[id].lp_field_18 & 1) && !(gLinkPlayers[playerId].lp_field_18 & 1)) - || ((gLinkPlayers[id].lp_field_18 & 1) && (gLinkPlayers[playerId].lp_field_18 & 1))) - { - switch (gLinkPlayers[id].lp_field_18) - { - case 0: - case 3: - memcpy(gPlayerParty + 2, gBlockRecvBuffer[id], sizeof(struct Pokemon)); - break; - case 1: - case 2: - memcpy(gPlayerParty + 5, gBlockRecvBuffer[id], sizeof(struct Pokemon)); - break; - } - } - else - { - switch (gLinkPlayers[id].lp_field_18) - { - case 0: - case 3: - memcpy(gEnemyParty + 2, gBlockRecvBuffer[id], sizeof(struct Pokemon)); - break; - case 1: - case 2: - memcpy(gEnemyParty + 5, gBlockRecvBuffer[id], sizeof(struct Pokemon)); - break; - } - } - } - } - - shedinja_something(&gPlayerParty[0]); - shedinja_something(&gPlayerParty[1]); - shedinja_something(&gPlayerParty[2]); - shedinja_something(&gPlayerParty[3]); - shedinja_something(&gPlayerParty[4]); - shedinja_something(&gPlayerParty[5]); - - shedinja_something(&gEnemyParty[0]); - shedinja_something(&gEnemyParty[1]); - shedinja_something(&gEnemyParty[2]); - shedinja_something(&gEnemyParty[3]); - shedinja_something(&gEnemyParty[4]); - shedinja_something(&gEnemyParty[5]); - - gBattleCommunication[0]++; - } - break; - case 6: - sub_800B950(); - gBattleCommunication[0]++; - gBattleCommunication[1] = 0; - gBattleCommunication[2] = 0; - break; - case 7: - if (battle_load_something(gUnknown_02024D1F, gUnknown_02024D1F + 1) != 0) - { - gPreBattleCallback1 = gMain.callback1; - gMain.callback1 = sub_8010824; - SetMainCallback2(BattleMainCB2); - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - gTrainerBattleOpponent = 0x800; - gBattleTypeFlags |= BATTLE_TYPE_20; - } - } - break; - } -} - -void BattleMainCB2(void) -{ - AnimateSprites(); - BuildOamBuffer(); - -#if DEBUG - if ((gMain.heldKeys & (R_BUTTON | SELECT_BUTTON)) == ((R_BUTTON | SELECT_BUTTON))) - { - gSpecialVar_Result = gBattleOutcome = 1; - gMain.inBattle = FALSE; - gScanlineEffect.state = 3; - gMain.callback1 = gPreBattleCallback1; - ZeroEnemyPartyMons(); - m4aSongNumStop(0x5A); - if (gBattleTypeFlags & 2) - SetMainCallback2(sub_805465C); - else - SetMainCallback2(gMain.savedCallback); - } - if (gBattleTypeFlags & 2) - { - debug_sub_8008264((gBattleTypeFlags >> 2) % 2, 1, 1, 1, 1); - debug_sub_8008264((gBattleTypeFlags >> 2) % 2, 1, 21, 1, 1); - debug_sub_8008264((gBattleTypeFlags >> 2) % 2, 1, 41, 1, 1); - } -#endif - - Text_UpdateWindowInBattle(&gUnknown_03004210); - UpdatePaletteFade(); - RunTasks(); -} - -void sub_800F828(struct Sprite *sprite) -{ - sprite->data[0] = 0; - sprite->callback = sub_800F838; -} - -void sub_800F838(struct Sprite *sprite) -{ - u16 *arr = (u16 *)gSharedMem; - - switch (sprite->data[0]) - { - case 0: - sprite->data[0]++; - sprite->data[1] = 0; - sprite->data[2] = 0x281; - sprite->data[3] = 0; - sprite->data[4] = 1; - // fall through - case 1: - sprite->data[4]--; - if (sprite->data[4] == 0) - { - s32 i; - s32 r2; - s32 r0; - - sprite->data[4] = 2; - r2 = sprite->data[1] + sprite->data[3] * 32; - r0 = sprite->data[2] - sprite->data[3] * 32; - for (i = 0; i < 29; i += 2) - { - arr[r2 + i] = 0x3D; - arr[r0 + i] = 0x3D; - } - sprite->data[3]++; - if (sprite->data[3] == 21) - { - sprite->data[0]++; - sprite->data[1] = 32; - } - } - break; - case 2: - sprite->data[1]--; - if (sprite->data[1] == 20) - SetMainCallback2(sub_800E7C4); - break; - } -} - -u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum) -{ - u32 nameHash = 0; - s32 i; - - if (trainerNum == 0x400) - return 0; - - if ((gBattleTypeFlags & 0x908) == 8) - { - ZeroEnemyPartyMons(); - for (i = 0; i < gTrainers[trainerNum].partySize; i++) - { - u32 personalityValue; - s32 j; - u8 fixedIV; - - if (gTrainers[trainerNum].doubleBattle == TRUE) - personalityValue = 0x80; - else if (gTrainers[trainerNum].encounterMusic_gender & 0x80) - personalityValue = 0x78; - else - personalityValue = 0x88; - - for (j = 0; gTrainers[trainerNum].trainerName[j] != 0xFF; j++) - nameHash += gTrainers[trainerNum].trainerName[j]; - - switch (gTrainers[trainerNum].partyFlags) - { - case 0: - { - const struct TrainerMonNoItemDefaultMoves *partyData = gTrainers[trainerNum].party.NoItemDefaultMoves; - - for (j = 0; gSpeciesNames[partyData[i].species][j] != 0xFF; j++) - nameHash += gSpeciesNames[partyData[i].species][j]; - personalityValue += nameHash << 8; - fixedIV = partyData[i].iv * 31 / 255; - CreateMon(&party[i], partyData[i].species, partyData[i].level, fixedIV, TRUE, personalityValue, 2, 0); - break; - } - case F_TRAINER_PARTY_CUSTOM_MOVESET: - { - const struct TrainerMonNoItemCustomMoves *partyData = gTrainers[trainerNum].party.NoItemCustomMoves; - - for (j = 0; gSpeciesNames[partyData[i].species][j] != 0xFF; j++) - nameHash += gSpeciesNames[partyData[i].species][j]; - personalityValue += nameHash << 8; - fixedIV = partyData[i].iv * 31 / 255; - CreateMon(&party[i], partyData[i].species, partyData[i].level, fixedIV, TRUE, personalityValue, 2, 0); - - for (j = 0; j < 4; j++) - { - SetMonData(&party[i], MON_DATA_MOVE1 + j, &partyData[i].moves[j]); - SetMonData(&party[i], MON_DATA_PP1 + j, &gBattleMoves[partyData[i].moves[j]].pp); - } - break; - } - case F_TRAINER_PARTY_HELD_ITEM: - { - const struct TrainerMonItemDefaultMoves *partyData = gTrainers[trainerNum].party.ItemDefaultMoves; - - for (j = 0; gSpeciesNames[partyData[i].species][j] != 0xFF; j++) - nameHash += gSpeciesNames[partyData[i].species][j]; - personalityValue += nameHash << 8; - fixedIV = partyData[i].iv * 31 / 255; - CreateMon(&party[i], partyData[i].species, partyData[i].level, fixedIV, TRUE, personalityValue, 2, 0); - - SetMonData(&party[i], MON_DATA_HELD_ITEM, &partyData[i].heldItem); - break; - } - case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM: - { - const struct TrainerMonItemCustomMoves *partyData = gTrainers[trainerNum].party.ItemCustomMoves; - - for (j = 0; gSpeciesNames[partyData[i].species][j] != 0xFF; j++) - nameHash += gSpeciesNames[partyData[i].species][j]; - personalityValue += nameHash << 8; - fixedIV = partyData[i].iv * 31 / 255; - CreateMon(&party[i], partyData[i].species, partyData[i].level, fixedIV, TRUE, personalityValue, 2, 0); - - SetMonData(&party[i], MON_DATA_HELD_ITEM, &partyData[i].heldItem); - for (j = 0; j < 4; j++) - { - SetMonData(&party[i], MON_DATA_MOVE1 + j, &partyData[i].moves[j]); - SetMonData(&party[i], MON_DATA_PP1 + j, &gBattleMoves[partyData[i].moves[j]].pp); - } - break; - } - } - } - gBattleTypeFlags |= gTrainers[trainerNum].doubleBattle; - } - return gTrainers[trainerNum].partySize; -} - -void sub_800FCD4(void) -{ - if (REG_VCOUNT < 0xA0 && REG_VCOUNT >= 0x6F ) - REG_BG0CNT = 0x9800; -} - -void sub_800FCFC(void) -{ - Random(); // unused return value - REG_BG0HOFS = gBattle_BG0_X; - REG_BG0VOFS = gBattle_BG0_Y; - REG_BG1HOFS = gBattle_BG1_X; - REG_BG1VOFS = gBattle_BG1_Y; - REG_BG2HOFS = gBattle_BG2_X; - REG_BG2VOFS = gBattle_BG2_Y; - REG_BG3HOFS = gBattle_BG3_X; - REG_BG3VOFS = gBattle_BG3_Y; - REG_WIN0H = gBattle_WIN0H; - REG_WIN0V = gBattle_WIN0V; - REG_WIN1H = gBattle_WIN1H; - REG_WIN1V = gBattle_WIN1V; - LoadOam(); - ProcessSpriteCopyRequests(); - TransferPlttBuffer(); - ScanlineEffect_InitHBlankDmaTransfer(); -} - -void nullsub_36(struct Sprite *sprite) -{ -} - -void sub_800FDB0(struct Sprite *sprite) -{ - if (sprite->data[0] != 0) - sprite->pos1.x = sprite->data[1] + ((sprite->data[2] & 0xFF00) >> 8); - else - sprite->pos1.x = sprite->data[1] - ((sprite->data[2] & 0xFF00) >> 8); - sprite->data[2] += 0x180; - if (sprite->affineAnimEnded) - { - FreeSpriteTilesByTag(0x2710); - FreeSpritePaletteByTag(0x2710); - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); - } -} - -void sub_800FE20(struct Sprite *sprite) -{ - StartSpriteAffineAnim(sprite, 1); - sprite->callback = sub_800FDB0; - PlaySE(SE_BT_START); -} - -void sub_800FE40(u8 taskId) -{ - struct Pokemon *sp4 = NULL; - struct Pokemon *sp8 = NULL; - u8 r2 = ewram160CB; - u32 r7; - s32 i; - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - switch (gLinkPlayers[r2].lp_field_18) - { - case 0: - case 2: - sp4 = gPlayerParty; - sp8 = gEnemyParty; - break; - case 1: - case 3: - sp4 = gEnemyParty; - sp8 = gPlayerParty; - break; - } - } - else - { - sp4 = gPlayerParty; - sp8 = gEnemyParty; - } - - r7 = 0; - for (i = 0; i < 6; i++) - { - u16 species = GetMonData(&sp4[i], MON_DATA_SPECIES2); - u16 hp = GetMonData(&sp4[i], MON_DATA_HP); - u32 status = GetMonData(&sp4[i], MON_DATA_STATUS); - - if (species == 0) - continue; - if (species != SPECIES_EGG && hp != 0 && status == 0) - r7 |= 1 << i * 2; - - if (species == 0) - continue; - if (hp != 0 && (species == SPECIES_EGG || status != 0)) - r7 |= 2 << i * 2; - - if (species == 0) - continue; - if (species != SPECIES_EGG && hp == 0) - r7 |= 3 << i * 2; - } - gTasks[taskId].data[3] = r7; - - r7 = 0; - for (i = 0; i < 6; i++) - { - u16 species = GetMonData(&sp8[i], MON_DATA_SPECIES2); - u16 hp = GetMonData(&sp8[i], MON_DATA_HP); - u32 status = GetMonData(&sp8[i], MON_DATA_STATUS); - - if (species == 0) - continue; - if (species != SPECIES_EGG && hp != 0 && status == 0) - r7 |= 1 << i * 2; - - if (species == 0) - continue; - if (hp != 0 && (species == SPECIES_EGG || status != 0)) - r7 |= 2 << i * 2; - - if (species == 0) - continue; - if (species != SPECIES_EGG && hp == 0) - r7 |= 3 << i * 2; - } - gTasks[taskId].data[4] = r7; -} - -void c2_8011A1C(void) -{ - s32 i; - u8 taskId; - - SetHBlankCallback(NULL); - SetVBlankCallback(NULL); - CpuFill32(0, (void *)VRAM, VRAM_SIZE); - REG_MOSAIC = 0; - REG_WIN0H = 0xF0; - REG_WIN0V = 0x5051; - REG_WININ = 0; - REG_WINOUT = 0; - gBattle_WIN0H = 0xF0; - gBattle_WIN0V = 0x5051; - ScanlineEffect_Clear(); - - for (i = 0; i < 80; i++) - { - gScanlineEffectRegBuffers[0][i] = 0xF0; - gScanlineEffectRegBuffers[1][i] = 0xF0; - } - for (i = 80; i < 160; i++) - { - asm(""::"r"(i)); // Needed to stop the compiler from optimizing out the loop counter - gScanlineEffectRegBuffers[0][i] = 0xFF10; - gScanlineEffectRegBuffers[1][i] = 0xFF10; - } - Text_LoadWindowTemplate(&gWindowTemplate_81E6C58); - ResetPaletteFade(); - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gBattle_BG1_X = 0; - gBattle_BG1_Y = 0; - gBattle_BG2_X = 0; - gBattle_BG2_Y = 0; - gBattle_BG3_X = 0; - gBattle_BG3_Y = 0; - - Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58); - Text_InitWindowWithTemplate(&gUnknown_030041D0, &gWindowTemplate_81E71D0); - Text_InitWindowWithTemplate(&gUnknown_03004250, &gWindowTemplate_81E71EC); - sub_800D6D4(); - LoadCompressedPalette(gBattleTextboxPalette, 0, 64); - ApplyPlayerChosenFrameToBattleMenu(); - ResetSpriteData(); - ResetTasks(); - LoadBattleEntryBackground(); - REG_WINOUT = 0x37; - FreeAllSpritePalettes(); - gReservedSpritePaletteCount = 4; - SetVBlankCallback(sub_800FCFC); - taskId = CreateTask(sub_800DE30, 0); - gTasks[taskId].data[1] = 0x10E; - gTasks[taskId].data[2] = 0x5A; - gTasks[taskId].data[5] = 1; - sub_800FE40(taskId); - SetMainCallback2(sub_80101B8); - gBattleCommunication[0] = 0; -} - -void sub_80101B8(void) -{ - c2_081284E0(); - AnimateSprites(); - BuildOamBuffer(); - UpdatePaletteFade(); - RunTasks(); -} - -void c2_081284E0(void) -{ - switch (gBattleCommunication[0]) - { - case 0: - gBattleCommunication[1] = 0xFF; - gBattleCommunication[0]++; - break; - case 1: - gBattleCommunication[1]--; - if (gBattleCommunication[1] == 0) - { - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); - gBattleCommunication[0]++; - } - break; - case 2: - if (!gPaletteFade.active) - SetMainCallback2(gMain.savedCallback); - break; - } -} - -#if DEBUG - -extern u8 gUnknown_Debug_2023B62[]; -extern const u8 Str_821F7BD[]; -extern const u8 Str_821F7DA[]; - -void debug_sub_8010818(void); -void debug_sub_80108B8(void); -void debug_sub_8010CAC(void); -void debug_sub_8011498(void); -void debug_sub_801174C(void); -void debug_sub_8011D40(void); -void debug_sub_8011E5C(void); -void debug_sub_8011E74(void); -void debug_sub_8011EA0(u8); -void debug_sub_8012294(void); -void debug_sub_80123D8(u8); -void debug_sub_8012540(void); -void debug_nullsub_3(void); -void debug_sub_80125A0(void); -void debug_sub_80125E4(void); -void debug_sub_8012628(void); -void debug_sub_8012658(void); -void debug_sub_8012688(void); -void debug_sub_8012878(void); -void debug_sub_8012D10(u8); -u32 debug_sub_8013294(u8, void *, u32); -void debug_sub_80132C8(u8, void *, u32); - -extern s16 gUnknown_Debug_2023A76[][35]; -extern s16 gUnknown_Debug_2023B02[][6][4]; -extern u8 gUnknown_Debug_03004360; -extern struct Window gUnknown_Debug_03004370; -extern u8 gUnknown_Debug_030043A0; -extern u8 gUnknown_Debug_030043A4; -extern u8 gUnknown_Debug_030043A8; -extern u8 gBattleBuffersTransferData[]; - -extern const u16 gUnknown_Debug_821F424[][5]; -extern const u16 gUnknown_Debug_821F56C[][5]; -extern const u32 gUnknown_Debug_821F798[][4]; - -extern const u8 gUnusedOldCharmap_Gfx_lz[]; -extern const u8 gUnusedOldCharmap_Tilemap_lz[]; -extern const u8 gUnusedOldCharmap_Pal_lz[]; - -void debug_sub_8010800(void) -{ - debug_sub_8010818(); - debug_sub_80108B8(); - *(u32 *)(gBattleBuffersTransferData + 0x100) = 0; -} - -void debug_sub_8010818(void) -{ - s32 i; - - gUnknown_Debug_2023A76[0][0] = 0x115; - gUnknown_Debug_2023A76[1][0] = 0x115; - for (i = 1; i < 31; i++) - { - gUnknown_Debug_2023A76[0][i] = gUnknown_Debug_821F424[i][4]; - gUnknown_Debug_2023A76[1][i] = gUnknown_Debug_821F424[i][4]; - } - - for (i = 0; i < 6; i++) - { - for (gUnknown_Debug_030043A8 = 0; gUnknown_Debug_030043A8 < 4; gUnknown_Debug_030043A8++) - { - gUnknown_Debug_2023B02[0][i][gUnknown_Debug_030043A8] = gUnknown_Debug_821F56C[gUnknown_Debug_030043A8][0]; - gUnknown_Debug_2023B02[1][i][gUnknown_Debug_030043A8] = gUnknown_Debug_821F56C[gUnknown_Debug_030043A8][0]; - } - } -} - -void debug_sub_80108B8(void) -{ - s32 i; - - m4aSoundVSyncOff(); - SetHBlankCallback(NULL); - SetVBlankCallback(NULL); - DmaFill32(3, 0, (void *)VRAM, VRAM_SIZE); - REG_IE = 1; - REG_DISPCNT = 0x1340; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gBattle_BG1_X = 0; - gBattle_BG1_Y = 0; - gBattle_BG2_X = 0; - gBattle_BG2_Y = 0; - gBattle_BG3_X = 0; - gBattle_BG3_Y = 0; - REG_BG0CNT = 0x1F09; - REG_BG1CNT = 0x4801; - REG_BLDCNT = 0; - REG_BLDY = 0; - LZDecompressVram(gUnusedOldCharmap_Gfx_lz, (void *)VRAM); - LZDecompressWram(gUnusedOldCharmap_Tilemap_lz, gSharedMem); - LZDecompressVram(gUnusedOldCharmap_Pal_lz, (void *)PLTT); - LZDecompressVram(gUnusedOldCharmap_Pal_lz, (void *)(PLTT + 0x1E0)); - m4aSoundVSyncOn(); - SetVBlankCallback(debug_sub_8011D40); - SetMainCallback2(debug_sub_8010CAC); - ResetTasks(); - ResetSpriteData(); - ScanlineEffect_Stop(); - Text_LoadWindowTemplate(&gWindowTemplate_81E6C3C); - Text_InitWindowWithTemplate(&gUnknown_Debug_03004370, &gWindowTemplate_81E6C3C); - gUnknown_Debug_03004360 = 0; - gUnknown_Debug_030043A0 = 0; - gUnknown_Debug_030043A4 = 0; - for (i = 0; i < 31; i++) - debug_sub_8011EA0(i); - for (gUnknown_Debug_030043A8 = 0; gUnknown_Debug_030043A8 < 4; gUnknown_Debug_030043A8++) - debug_sub_8012294(); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - debug_sub_8012540(); - debug_nullsub_3(); - gUnknown_Debug_030043A8 = 0; - debug_sub_80125A0(); - if (gUnknown_Debug_2023A76[0][0x22] == 8) - { - debug_sub_801174C(); - } - else - { - for (i = 0; i < 8; i++) - gSharedMem[0x160B4 + i] = 0; - } -} - -void debug_sub_8010A7C(u8 a, u8 b) -{ - s32 i; - - for (i = 0; i < b; i++) - gBattleTextBuff1[i] = a; - gBattleTextBuff1[i] = EOS; -} - -void debug_sub_8010AAC(u8 a) -{ - switch (gBaseStats[gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5]].genderRatio) - { - case 0: - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + 4] = 2; - break; - case 0xFE: - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + 4] = 3; - break; - case 0xFF: - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + 4] = 4; - break; - default: - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + 4] &= 1; - if (a != 0) - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + 4] ^= 1; - else - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + 4] = 0; - break; - } -} - -// gUnknown_Debug_2023A76 2D array -void debug_sub_8010B80(u8 a) -{ - s8 r12 = 0; - s8 r7 = gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5]; - - while (r7 >= 10) - { - r7 -= 10; - r12++; - } - - if (a & 2) - { - if (a & 1) - r12++; - else - r12--; - if (r12 < 0) - r12 = 9; - if (r12 > 9) - r12 = 0; - } - else - { - if (a & 1) - r7++; - else - r7--; - if (r7 < 1) - r7 = 9; - if (r7 > 9) - r7 = 1; - } - gUnknown_Debug_2023A76[gUnknown_Debug_03004360 ^ 1][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5] - = gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5] - = r12 * 10 + r7; -} - -void debug_sub_8010CAC(void) -{ - s32 r5; - - if (gMain.heldKeysRaw == (L_BUTTON | SELECT_BUTTON)) - DoSoftReset(); - if (gMain.newKeysRaw == SELECT_BUTTON) - { - if (gUnknown_Debug_030043A4 < 6) - { - gUnknown_Debug_030043A8 = 0; - debug_sub_8012628(); - SetMainCallback2(debug_sub_8011498); - } - if (gUnknown_Debug_030043A0 == 0 && gUnknown_Debug_030043A4 == 6) - { - gMain.savedCallback = debug_sub_80108B8; - CreateMon( - &gPlayerParty[0], - gUnknown_Debug_2023A76[0][0 * 5 + 0], - gUnknown_Debug_2023A76[0][0 * 5 + 1], - 32, - 0, 0, 0, 0); - for (r5 = 0; r5 < 4; r5++) - { - SetMonData(&gPlayerParty[0], MON_DATA_MOVE1 + r5, &gUnknown_Debug_2023B02[0][0][r5]); - SetMonData(&gPlayerParty[0], MON_DATA_PP1 + r5, &gBattleMoves[gUnknown_Debug_2023B02[0][0][r5]].pp); - } - switch (gUnknown_Debug_2023A76[0][6 * 5 + 0]) - { - case 1: - gCB2_AfterEvolution = debug_sub_80108B8; - EvolutionScene(&gPlayerParty[0], gUnknown_Debug_2023A76[0][1 * 5 + 0], 1, 0); - break; - case 2: - debug_sub_8012688(); - break; - } - } - if (gUnknown_Debug_030043A0 == 1 && gUnknown_Debug_030043A4 == 6) - { - // This is really weird - r5 = (gSaveBlock2.optionsBattleSceneOff | (gSaveBlock2.optionsSound << 1)); - r5++; - if (r5 == 4) - r5 = 0; - gSaveBlock2.optionsBattleSceneOff = (r5 & 1); - gSaveBlock2.optionsSound = (r5 & 2) >> 1; - SetPokemonCryStereo(gSaveBlock2.optionsSound); - debug_nullsub_3(); - } - } - if (gMain.newKeysRaw == START_BUTTON) - debug_sub_801174C(); - if (gMain.newKeysRaw == DPAD_UP) - { - debug_sub_80125E4(); - if (gUnknown_Debug_030043A4 != 0) - gUnknown_Debug_030043A4--; - else - gUnknown_Debug_030043A4 = 6; - debug_sub_8011E74(); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - debug_sub_80125A0(); - } - if (gMain.newKeysRaw == DPAD_DOWN) - { - debug_sub_80125E4(); - if (gUnknown_Debug_030043A4 == 6) - gUnknown_Debug_030043A4 = 0; - else - gUnknown_Debug_030043A4++; - debug_sub_8011E74(); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - debug_sub_80125A0(); - } - if (gMain.newKeysRaw == DPAD_LEFT) - { - debug_sub_80125E4(); - if (gUnknown_Debug_030043A0 != 0) - { - gUnknown_Debug_030043A0--; - } - else - { - if (gUnknown_Debug_03004360 != 0) - { - gUnknown_Debug_03004360 = 0; - gUnknown_Debug_030043A0 = 4; - gBattle_BG1_X = 0; - debug_sub_8011E5C(); - debug_sub_8011E74(); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - } - } - debug_sub_80125A0(); - } - if (gMain.newKeysRaw == DPAD_RIGHT) - { - debug_sub_80125E4(); - if (gUnknown_Debug_030043A0 != 4) - { - gUnknown_Debug_030043A0++; - } - else - { - if (gUnknown_Debug_03004360 == 0) - { - gUnknown_Debug_03004360 = 1; - gUnknown_Debug_030043A0 = 0; - gBattle_BG1_X = 0x100; - debug_sub_8011E5C(); - debug_sub_8011E74(); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - } - } - debug_sub_80125A0(); - } - if (gMain.newAndRepeatedKeys & B_BUTTON) - { - switch (gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5) - { - case 31: - debug_sub_8010818(); - debug_sub_8011E5C(); - debug_sub_8011E74(); - debug_sub_8012540(); - debug_nullsub_3(); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - break; - case 32: - debug_sub_80132C8(31, gUnknown_Debug_2023A76, 0xEC); - debug_sub_8011E5C(); - debug_sub_8011E74(); - debug_sub_8012540(); - debug_nullsub_3(); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - break; - case 33: - debug_sub_8013294(31, gUnknown_Debug_2023A76, 0xEC); - break; - case 34: - if (gUnknown_Debug_2023A76[0][6 * 5 + 4] != 0) - { - gUnknown_Debug_2023A76[0][6 * 5 + 4]--; - gUnknown_Debug_2023A76[1][6 * 5 + 4]--; - } - else - { - gUnknown_Debug_2023A76[0][6 * 5 + 4] = 8; - gUnknown_Debug_2023A76[1][6 * 5 + 4] = 8; - } - debug_sub_8012540(); - break; - case 30: - debug_sub_8010B80(0); - debug_sub_8011EA0(gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5); - break; - default: - if (gUnknown_Debug_030043A0 == 4 && gUnknown_Debug_030043A4 < 6) - { - debug_sub_8010AAC(1); - } - else - { - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5]--; - if (gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5] < gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][4]) - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5] = gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][3]; - } - if (gUnknown_Debug_030043A0 == 0) - { - debug_sub_8010AAC(0); - debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + 4); - } - debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - break; - } - } - if (gMain.newAndRepeatedKeys & A_BUTTON) - { - switch (gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5) - { - case 31: - debug_sub_8010818(); - debug_sub_8011E5C(); - debug_sub_8011E74(); - debug_sub_8012540(); - debug_nullsub_3(); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - break; - case 32: - debug_sub_80132C8(31, gUnknown_Debug_2023A76, 0xEC); - debug_sub_8011E5C(); - debug_sub_8011E74(); - debug_sub_8012540(); - debug_nullsub_3(); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - break; - case 33: - debug_sub_8013294(31, gUnknown_Debug_2023A76, 0xEC); - break; - case 34: - if (gUnknown_Debug_2023A76[0][6 * 5 + 4] < 8) - { - gUnknown_Debug_2023A76[0][6 * 5 + 4]++; - gUnknown_Debug_2023A76[1][6 * 5 + 4]++; - } - else - { - gUnknown_Debug_2023A76[0][6 * 5 + 4] = 0; - gUnknown_Debug_2023A76[1][6 * 5 + 4] = 0; - } - debug_sub_8012540(); - break; - case 30: - debug_sub_8010B80(1); - debug_sub_8011EA0(gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5); - break; - default: - if (gUnknown_Debug_030043A0 == 4 && gUnknown_Debug_030043A4 < 6) - { - debug_sub_8010AAC(1); - } - else - { - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5]++; - if (gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] > gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][3]) - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] = gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][4]; - } - if (gUnknown_Debug_030043A0 == 0) - { - debug_sub_8010AAC(0); - debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + 4); - } - debug_sub_8011EA0(gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - break; - } - } - if (gMain.newAndRepeatedKeys & L_BUTTON) - { - if (gUnknown_Debug_030043A0 == 4 && gUnknown_Debug_030043A4 < 6) - { - debug_sub_8010AAC(1); - } - else - { - if (gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0 == 30) - { - debug_sub_8010B80(2); - } - else - { - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] -= 10; - while (gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] < gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][4]) - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] += gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][3]; - } - } - if (gUnknown_Debug_030043A0 == 0) - { - debug_sub_8010AAC(0); - debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + 4); - } - debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - } - if (gMain.newAndRepeatedKeys & R_BUTTON) - { - if (gUnknown_Debug_030043A0 == 4 && gUnknown_Debug_030043A4 < 6) - { - debug_sub_8010AAC(1); - } - else - { - if (gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0 == 30) - { - debug_sub_8010B80(3); - } - else - { - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] += 10; - while (gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] > gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][3]) - gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] -= gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][3]; - } - } - if (gUnknown_Debug_030043A0 == 0) - { - debug_sub_8010AAC(0); - debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + 4); - } - debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0); - debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); - } - AnimateSprites(); - BuildOamBuffer(); -} - -extern u16 gUnknown_Debug_821F564[][5]; - -void debug_sub_8011498(void) -{ - u8 r9 = gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5; - - if (gMain.heldKeysRaw == (L_BUTTON | SELECT_BUTTON)) - DoSoftReset(); - if (gMain.newKeysRaw == SELECT_BUTTON) - { - debug_sub_8012658(); - SetMainCallback2(debug_sub_8010CAC); - } - if (gMain.newKeysRaw == START_BUTTON) - debug_sub_801174C(); - if (gMain.newKeysRaw == DPAD_UP || gMain.newKeysRaw == DPAD_DOWN) - { - debug_sub_8012658(); - gUnknown_Debug_030043A8 ^= 2; - debug_sub_8012628(); - } - if (gMain.newKeysRaw == DPAD_LEFT || gMain.newKeysRaw == DPAD_RIGHT) - { - debug_sub_8012658(); - gUnknown_Debug_030043A8 ^= 1; - debug_sub_8012628(); - } - if (gMain.newAndRepeatedKeys & B_BUTTON) - { - gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8]--; - if (gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] < gUnknown_Debug_821F564[gUnknown_Debug_030043A8][4]) - gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] = gUnknown_Debug_821F564[gUnknown_Debug_030043A8][3]; - debug_sub_8012294(); - } - if (gMain.newAndRepeatedKeys & A_BUTTON) - { - gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8]++; - if (gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] > gUnknown_Debug_821F564[gUnknown_Debug_030043A8][3]) - gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] = gUnknown_Debug_821F564[gUnknown_Debug_030043A8][4]; - debug_sub_8012294(); - } - if (gMain.newAndRepeatedKeys & L_BUTTON) - { - gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] -= 10; - while (gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] < gUnknown_Debug_821F564[gUnknown_Debug_030043A8][4]) - gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] += gUnknown_Debug_821F564[gUnknown_Debug_030043A8][3]; - debug_sub_8012294(); - } - if (gMain.newAndRepeatedKeys & R_BUTTON) - { - gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] += 10; - while (gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] > gUnknown_Debug_821F564[gUnknown_Debug_030043A8][3]) - gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] -= gUnknown_Debug_821F564[gUnknown_Debug_030043A8][3]; - debug_sub_8012294(); - } - AnimateSprites(); - BuildOamBuffer(); -} - -extern const u16 gUnknown_Debug_821F598[]; -extern const u8 str_821F631[][6]; -extern const u8 Str_821F649[]; -extern const struct Pokeblock gUnknown_Debug_821F5AC[]; - -extern u8 gUnknown_020297ED; - -extern void debug_sub_800D684(void); - -void debug_sub_801174C(void) -{ - u8 r9 = 0; - u8 r6; - s32 i; - s32 spC; - u16 sp10; - - gUnknown_020297ED = 1; - r6 = Random() % 4; - StringCopy(gSaveBlock2.playerName, str_821F631[r6]); - gSaveBlock2.playerGender = r6 >> 1; - ZeroPlayerPartyMons(); - ZeroEnemyPartyMons(); - i = gUnknown_Debug_2023A76[0][30]; - spC = 0; - if (i >= 10) - { - spC = 0; - while (i >= 10) - { - i -= 10; - spC++; - } - } - gBattleTypeFlags = gUnknown_Debug_821F598[i - 1]; - gUnknown_02023A14_50 = 8; - gBattleTerrain = spC; - if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) - EnterSafariMode(); - if (gUnknown_Debug_2023A76[0][30] >= 2 && gUnknown_Debug_2023A76[0][30] <= 4) - gTrainerBattleOpponent = (Random() & 7) + 1; - - gPlayerPartyCount = 0; - for (i = 0; i < 30; i += 5) - { - if (gUnknown_Debug_2023A76[0][i] != 0) - { - switch (gUnknown_Debug_2023A76[0][i + 4]) - { - case 0: - case 2: - r6 = 0; - break; - case 1: - case 3: - r6 = 0xFE; - break; - default: - r6 = 0xFF; - break; - } - if (gUnknown_Debug_2023A76[0][i] == 0xC9 && i + 5 < 30) - r9 = gUnknown_Debug_2023A76[0][i + 7]; - else - r9 = 0; - CreateMonWithGenderNatureLetter( - &gEnemyParty[i / 5], - gUnknown_Debug_2023A76[0][i], - gUnknown_Debug_2023A76[0][i + 1], - 0, - r6, - 0, - r9); - } - SetMonData(&gEnemyParty[i / 5], MON_DATA_HELD_ITEM, &gUnknown_Debug_2023A76[0][i + 2]); - sp10 = gUnknown_Debug_2023A76[0][i + 2] - 1; - if (sp10 <= 11) - SetMonData(&gEnemyParty[i / 5], MON_DATA_POKEBALL, &gUnknown_Debug_2023A76[0][i + 2]); - if (gUnknown_Debug_2023A76[0][i + 3] != 0 && gUnknown_Debug_2023A76[0][i + 3] != 3) - { - if (gUnknown_Debug_2023A76[0][i + 3] <= 2) - spC = gUnknown_Debug_2023A76[0][i + 3] - 1; - else - spC = gUnknown_Debug_2023A76[0][i + 3] - 4; - SetMonData(&gEnemyParty[i / 5], MON_DATA_ALT_ABILITY, &spC); - } - - if (gUnknown_Debug_2023A76[1][i] != 0) - { - switch (gUnknown_Debug_2023A76[1][i + 4]) - { - case 0: - case 2: - r6 = 0; - break; - case 1: - case 3: - r6 = 0xFE; - break; - default: - r6 = 0xFF; - break; - } - if (gUnknown_Debug_2023A76[1][i] == 0xC9 && i + 5 < 30) - r9 = gUnknown_Debug_2023A76[1][i + 7]; - else - r9 = 0; - CreateMonWithGenderNatureLetter( - &gPlayerParty[i / 5], - gUnknown_Debug_2023A76[1][i], - gUnknown_Debug_2023A76[1][i + 1], - 0, - r6, - 0, - r9); - gPlayerPartyCount++; - } - SetMonData(&gPlayerParty[i / 5], MON_DATA_HELD_ITEM, &gUnknown_Debug_2023A76[1][i + 2]); - sp10 = gUnknown_Debug_2023A76[0][i + 2] - 1; - if (sp10 <= 11) - SetMonData(&gPlayerParty[i / 5], MON_DATA_POKEBALL, &gUnknown_Debug_2023A76[1][i + 2]); - if (gUnknown_Debug_2023A76[1][i + 3] != 0 && gUnknown_Debug_2023A76[1][i + 3] != 3) - { - if (gUnknown_Debug_2023A76[1][i + 3] <= 2) - spC = gUnknown_Debug_2023A76[1][i + 3] - 1; - else - spC = gUnknown_Debug_2023A76[1][i + 3] - 4; - SetMonData(&gPlayerParty[i / 5], MON_DATA_ALT_ABILITY, &spC); - } - if (gUnknown_Debug_2023A76[1][i + 3] > 2) - { - SetMonData(&gPlayerParty[i / 5], MON_DATA_OT_NAME, Str_821F649); - gUnknown_02023A14_50 |= 0x40; - } - } - - for (spC = 0; spC < 6; spC++) - { - for (i = 0; i < 4; i++) - { - SetMonData(&gEnemyParty[spC], MON_DATA_MOVE1 + i, &gUnknown_Debug_2023B02[0][spC][i]); - SetMonData(&gEnemyParty[spC], MON_DATA_PP1 + i, &gBattleMoves[gUnknown_Debug_2023B02[0][spC][i]].pp); - SetMonData(&gPlayerParty[spC], MON_DATA_MOVE1 + i, &gUnknown_Debug_2023B02[1][spC][i]); - SetMonData(&gPlayerParty[spC], MON_DATA_PP1 + i, &gBattleMoves[gUnknown_Debug_2023B02[1][spC][i]].pp); - } - } - - if (gUnknown_Debug_2023A76[0][0x22] == 8) - { - gUnknown_02023A14_50 |= 0x80; - sub_80408BC(); - } - else if (gUnknown_Debug_2023A76[0][0x22] == 7) - { - gUnknown_02023A14_50 |= 0x20; - sub_80408BC(); - } - else if (gUnknown_Debug_2023A76[0][0x22] == 6) - { - gUnknown_02023A14_50 |= 0x10; - if (gUnknown_Debug_2023A76[0][2] > 5) - gSharedMem[0x160A3] = gUnknown_Debug_2023A76[0][2] - 2; - else - gSharedMem[0x160A3] = gUnknown_Debug_2023A76[0][2]; - sub_80408BC(); - } - else if (gUnknown_Debug_2023A76[0][0x22] == 5) - { - gUnknown_02023A14_50 |= 0x21; - sub_80408BC(); - } - else - { - if (!(gUnknown_Debug_2023A76[0][0x22] & 1)) - sub_80408BC(); - if (gUnknown_Debug_2023A76[0][0x22] & 2) - gUnknown_02023A14_50 |= 4; - if (gUnknown_Debug_2023A76[0][0x22] & 4) - gUnknown_02023A14_50 |= 6; - } - - gMain.savedCallback = debug_sub_80108B8; - SetMainCallback2(debug_sub_800D684); - - ClearBag(); - - AddBagItem(ITEM_MASTER_BALL, 10); - AddBagItem(ITEM_ULTRA_BALL, 10); - AddBagItem(ITEM_GREAT_BALL, 10); - AddBagItem(ITEM_POKE_BALL, 10); - AddBagItem(ITEM_SAFARI_BALL, 10); - AddBagItem(ITEM_NET_BALL, 10); - AddBagItem(ITEM_DIVE_BALL, 10); - AddBagItem(ITEM_NEST_BALL, 10); - AddBagItem(ITEM_REPEAT_BALL, 10); - AddBagItem(ITEM_TIMER_BALL, 10); - AddBagItem(ITEM_LUXURY_BALL, 10); - AddBagItem(ITEM_PREMIER_BALL, 10); - - AddBagItem(ITEM_FULL_RESTORE, 99); - AddBagItem(ITEM_MAX_POTION, 99); - AddBagItem(ITEM_MAX_REVIVE, 99); - AddBagItem(ITEM_ETHER, 99); - AddBagItem(ITEM_MAX_ETHER, 99); - AddBagItem(ITEM_MAX_ELIXIR, 99); - - AddBagItem(ITEM_GUARD_SPEC, 99); - AddBagItem(ITEM_DIRE_HIT, 99); - AddBagItem(ITEM_X_ATTACK, 99); - AddBagItem(ITEM_X_DEFEND, 99); - AddBagItem(ITEM_X_SPEED, 99); - AddBagItem(ITEM_X_ACCURACY, 99); - // hmm... no X Special? Why do we need Poke Doll? - AddBagItem(ITEM_POKE_DOLL, 99); - - for (i = 0; i < 15; i++) - GivePokeblock(&gUnknown_Debug_821F5AC[i]); -} - -void debug_sub_8011D40(void) -{ - DmaCopy16(3, gSharedMem, (void *)(VRAM + 0x4000), 0x1000); - REG_BG0HOFS = gBattle_BG0_X; - REG_BG0VOFS = gBattle_BG0_Y; - REG_BG1HOFS = gBattle_BG1_X; - REG_BG1VOFS = gBattle_BG1_Y; - REG_BG2HOFS = gBattle_BG2_X; - REG_BG2VOFS = gBattle_BG2_Y; - REG_BG3HOFS = gBattle_BG3_X; - REG_BG3VOFS = gBattle_BG3_Y; - LoadOam(); - ProcessSpriteCopyRequests(); -} - -void debug_nullsub_45() -{ -} - -void debug_sub_8011DD4(void) -{ - REG_BG0CNT = 0x9803; - - REG_BG0HOFS = gBattle_BG0_X; - REG_BG0VOFS = gBattle_BG0_Y; - - REG_BG1HOFS = gBattle_BG1_X; - REG_BG1VOFS = gBattle_BG1_Y; - - REG_BG2HOFS = gBattle_BG2_X; - REG_BG2VOFS = gBattle_BG2_Y; - - REG_BG3HOFS = gBattle_BG3_X; - REG_BG3VOFS = gBattle_BG3_Y; - - LoadOam(); - ProcessSpriteCopyRequests(); - TransferPlttBuffer(); - ScanlineEffect_InitHBlankDmaTransfer(); -} - -void debug_sub_8011E5C(void) -{ - s32 i; - - for (i = 0; i < 31; i++) - debug_sub_8011EA0(i); -} - -extern u8 gUnknown_Debug_030043A8; - -void debug_sub_8011E74(void) -{ - u8 r5 = gUnknown_Debug_030043A8; - - for (gUnknown_Debug_030043A8 = 0; gUnknown_Debug_030043A8 < 4; gUnknown_Debug_030043A8++) - debug_sub_8012294(); - - gUnknown_Debug_030043A8 = r5; -} - -extern const u8 Str_821F624[]; - -void debug_sub_8011EA0(u8 a) -{ - u32 length; - - switch (a) - { - case 0: - case 5: - case 10: - case 15: - case 20: - case 25: - debug_sub_8010A7C(0, 20); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F424[a][0], - gUnknown_Debug_821F424[a][1], - gUnknown_Debug_821F424[a][2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - ConvertIntToDecimalStringN(gBattleTextBuff1, gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a], 2, 3); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - 422, - gUnknown_Debug_03004360 * 32 + 25, - 0); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - gBattleTextBuff1[0] = EOS; - StringAppend(gBattleTextBuff1, gSpeciesNames[gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a]]); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F424[a][0], - gUnknown_Debug_821F424[a][1], - gUnknown_Debug_821F424[a][2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - break; - case 1: - case 6: - case 11: - case 16: - case 21: - case 26: - case 30: - ConvertIntToDecimalStringN(gBattleTextBuff1, gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a], 2, 3); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F424[a][0], - gUnknown_Debug_821F424[a][1], - gUnknown_Debug_821F424[a][2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - break; - case 2: - case 7: - case 12: - case 17: - case 22: - case 27: - debug_sub_8010A7C(0, 24); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F424[a][0], - gUnknown_Debug_821F424[a][1], - gUnknown_Debug_821F424[a][2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - ConvertIntToDecimalStringN(gBattleTextBuff1, gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a], 2, 3); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - 422, - gUnknown_Debug_03004360 * 32 + 25, - 0); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - gBattleTextBuff1[0] = EOS; - if (gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a] != 0) - StringAppend(gBattleTextBuff1, ItemId_GetName(gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a])); - else - StringAppend(gBattleTextBuff1, Str_821F624); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F424[a][0], - gUnknown_Debug_821F424[a][1], - gUnknown_Debug_821F424[a][2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - break; - case 4: - case 9: - case 14: - case 19: - case 24: - case 29: - debug_sub_8010A7C(0, 4); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F424[a][0], - gUnknown_Debug_821F424[a][1], - gUnknown_Debug_821F424[a][2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - length = 0; - switch (gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a]) - { - case 0: - gBattleTextBuff1[0] = CHAR_MALE; - length = 1; - break; - case 1: - gBattleTextBuff1[0] = CHAR_FEMALE; - length = 1; - break; - case 2: - gBattleTextBuff1[0] = CHAR_MALE; - gBattleTextBuff1[1] = CHAR_MALE; - length = 2; - break; - case 3: - gBattleTextBuff1[0] = CHAR_FEMALE; - gBattleTextBuff1[1] = CHAR_FEMALE; - length = 2; - break; - default: - gBattleTextBuff1[length] = CHAR_QUESTION_MARK; - length++; - break; - } - gBattleTextBuff1[length] = EOS; - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F424[a][0], - gUnknown_Debug_821F424[a][1], - gUnknown_Debug_821F424[a][2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - break; - case 3: - case 8: - case 13: - case 18: - case 23: - case 28: - default: - ConvertIntToDecimalStringN(gBattleTextBuff1, gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a], 2, 1); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F424[a][0], - gUnknown_Debug_821F424[a][1], - gUnknown_Debug_821F424[a][2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - break; - case 31: - case 32: - case 33: - case 34: - break; - } -} - -void debug_sub_8012294(void) -{ - u8 r5 = gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5; - - if (r5 < 30) - { - debug_sub_8010A7C(0, 24); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F564[gUnknown_Debug_030043A8][0], - gUnknown_Debug_821F564[gUnknown_Debug_030043A8][1], - gUnknown_Debug_821F564[gUnknown_Debug_030043A8][2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - ConvertIntToDecimalStringN(gBattleTextBuff1, gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r5 / 5][gUnknown_Debug_030043A8], 2, 3); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - 422, - gUnknown_Debug_03004360 * 32 + 25, - 0); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - gBattleTextBuff1[0] = EOS; - StringAppend(gBattleTextBuff1, gMoveNames[gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r5 / 5][gUnknown_Debug_030043A8]]); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F564[gUnknown_Debug_030043A8][0], - gUnknown_Debug_821F564[gUnknown_Debug_030043A8][1], - gUnknown_Debug_821F564[gUnknown_Debug_030043A8][2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - } -} - -extern const u16 gUnknown_Debug_821F58C[]; - -void debug_sub_80123D8(u8 a) -{ - if (a < 30) - { - debug_sub_8010A7C(0, 18); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F58C[0], - gUnknown_Debug_821F58C[1], - gUnknown_Debug_821F58C[2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - StringCopy(gBattleTextBuff1, gAbilityNames[gBaseStats[gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a]].ability1]); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F58C[0], - gUnknown_Debug_821F58C[1], - gUnknown_Debug_821F58C[2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - debug_sub_8010A7C(0, 18); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F58C[3], - gUnknown_Debug_821F58C[4], - gUnknown_Debug_821F58C[5]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - StringCopy(gBattleTextBuff1, gAbilityNames[gBaseStats[gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a]].ability2]); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F58C[3], - gUnknown_Debug_821F58C[4], - gUnknown_Debug_821F58C[5]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - } - else - { - StringCopy(gBattleTextBuff1, gAbilityNames[0]); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F58C[0], - gUnknown_Debug_821F58C[1], - gUnknown_Debug_821F58C[2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F58C[3], - gUnknown_Debug_821F58C[4], - gUnknown_Debug_821F58C[5]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - } -} - -void debug_sub_8012540(void) -{ - ConvertIntToDecimalStringN(gBattleTextBuff1, gUnknown_Debug_2023A76[0][0x22], 0, 1); - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - gUnknown_Debug_821F424[31][0], - gUnknown_Debug_821F424[31][1], - gUnknown_Debug_821F424[31][2]); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); -} - -void debug_nullsub_3(void) -{ -} - -extern const u32 gUnknown_Debug_821F680[][0x23]; - -void debug_sub_80125A0(void) -{ - gSharedMem[gUnknown_Debug_821F680[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5]] = 0x6D; -} - -void debug_sub_80125E4(void) -{ - gSharedMem[gUnknown_Debug_821F680[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5]] = 0x81; -} - -void debug_sub_8012628(void) -{ - gSharedMem[gUnknown_Debug_821F798[gUnknown_Debug_03004360][gUnknown_Debug_030043A8]] = 0x6D; -} - -void debug_sub_8012658(void) -{ - gSharedMem[gUnknown_Debug_821F798[gUnknown_Debug_03004360][gUnknown_Debug_030043A8]] = 0x81; -} - -void debug_sub_8012688(void) -{ - s32 i; - u8 spriteId; - u8 taskId; - - for (i = 0; i < 411; i++) - gUnknown_Debug_2023B62[i] = 0; - SetHBlankCallback(NULL); - SetVBlankCallback(NULL); - DmaFill32(3, 0, (void *)VRAM, VRAM_SIZE); - REG_MOSAIC = 0; - REG_WIN0H = 0; - REG_WIN0V = 0; - REG_WIN1H = 0; - REG_WIN1V = 0; - REG_WININ = 0; - REG_WINOUT = 0; - Text_LoadWindowTemplate(&gWindowTemplate_81E6C58); - ResetPaletteFade(); - gBattle_BG0_X = 0; - gBattle_BG0_Y = DISPLAY_HEIGHT; - gBattle_BG1_X = 0; - gBattle_BG1_Y = 0; - gBattle_BG2_X = 0; - gBattle_BG2_Y = 0; - gBattle_BG3_X = 0; - gBattle_BG3_Y = 0; - gBattleTerrain = 9; - sub_800D6D4(); - LoadBattleTextboxAndBackground(); - ResetSpriteData(); - ResetTasks(); - FreeAllSpritePalettes(); - gReservedSpritePaletteCount = 4; - gCurrentMove = 1; - Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58); - DecompressPicFromTable_2( - &gMonFrontPicTable[gCurrentMove], - gMonFrontPicCoords[gCurrentMove].coords, - gMonFrontPicCoords[gCurrentMove].y_offset, - (void *)0x02000000, - gUnknown_081FAF4C[1], - gCurrentMove); - LoadCompressedPalette(gMonPaletteTable[gCurrentMove].data, 272, 32); - GetMonSpriteTemplate_803C56C(gCurrentMove, 1); - spriteId = CreateSprite(&gUnknown_02024E8C, 176, 40 + gMonFrontPicCoords[gCurrentMove].y_offset, 40); - gSprites[spriteId].callback = nullsub_37; - gSprites[spriteId].oam.paletteNum = 1; - REG_DISPCNT = 0x1F40; - SetHBlankCallback(debug_nullsub_45); - SetVBlankCallback(debug_sub_8011DD4); - m4aMPlayAllStop(); - taskId = CreateTask(debug_sub_8012D10, 0); - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[1] = spriteId; - SetMainCallback2(debug_sub_8012878); -} - -void debug_sub_8012878(void) -{ - AnimateSprites(); - BuildOamBuffer(); - Text_UpdateWindowInBattle(&gUnknown_03004210); - UpdatePaletteFade(); - RunTasks(); - if (gMain.heldKeys == (SELECT_BUTTON | R_BUTTON)) - SetMainCallback2(debug_sub_80108B8); -} - -void debug_sub_80128B4(void) -{ - debug_sub_8010A7C(0, 9); - Text_InitWindow(&gUnknown_03004210, gBattleTextBuff1, 144, 2, 35); - Text_PrintWindow8002F44(&gUnknown_03004210); - ConvertIntToDecimalStringN(gBattleTextBuff1, gCurrentMove, 2, 3); - gBattleTextBuff1[3] = CHAR_SPACE; - gBattleTextBuff1[4] = EOS; - StringAppend(gBattleTextBuff1, gSpeciesNames[gCurrentMove]); - Text_InitWindow(&gUnknown_03004210, gBattleTextBuff1, 144, 2, 35); - Text_PrintWindow8002F44(&gUnknown_03004210); -} - -void debug_sub_8012938(u8 taskId) -{ - debug_sub_8010A7C(0, 7); - Text_InitWindow(&gUnknown_03004210, gBattleTextBuff1, 162, 2, 37); - Text_PrintWindow8002F44(&gUnknown_03004210); - StringCopy(gBattleTextBuff1, Str_821F7B8); - ConvertIntToDecimalStringN(gBattleTextBuff1 + 4, gUnknown_Debug_2023B62[gCurrentMove - 1], 2, 3); - Text_InitWindow(&gUnknown_03004210, gBattleTextBuff1, 162, 2, 37); - Text_PrintWindow8002F44(&gUnknown_03004210); - gSprites[gTasks[taskId].data[1]].pos2.y = -gUnknown_Debug_2023B62[gCurrentMove - 1]; -} - -void debug_sub_80129F8(u8 taskId) -{ - DecompressPicFromTable_2( - &gMonFrontPicTable[gCurrentMove], - gMonFrontPicCoords[gCurrentMove].coords, - gMonFrontPicCoords[gCurrentMove].y_offset, - (void *)0x02000000, - gUnknown_081FAF4C[1], - gCurrentMove); - LoadCompressedPalette(gMonPaletteTable[gCurrentMove].data, 272, 32); - gSprites[gTasks[taskId].data[1]].pos1.y = gMonFrontPicCoords[gCurrentMove].y_offset + 40; - gSprites[gTasks[taskId].data[1]].pos2.y = -gUnknown_Debug_2023B62[gCurrentMove - 1]; - StartSpriteAnim(&gSprites[gTasks[taskId].data[1]], 0); -} - -void debug_sub_8012AC0(s8 a, u8 taskId) -{ - do - { - gCurrentMove += a; - if (gCurrentMove == 0) - gCurrentMove = 411; - if (gCurrentMove == 411) - gCurrentMove = 1; - } while (gBaseStats[gCurrentMove].type1 != 2 && gBaseStats[gCurrentMove].type2 != 2); - debug_sub_80128B4(); - debug_sub_8012938(taskId); - debug_sub_80129F8(taskId); -} - -void debug_sub_8012B2C(u8 a) -{ - *(u16 *)(VRAM + 0xC000 + 0x772 + (a * 4 + 0) * 0x20) = 1; - *(u16 *)(VRAM + 0xC000 + 0x772 + (a * 4 + 2) * 0x20) = 2; -} - -void debug_sub_8012B4C(u8 a) -{ - *(u16 *)(VRAM + 0xC000 + 0x772 + (a * 4 + 0) * 0x20) = 0x1016; - *(u16 *)(VRAM + 0xC000 + 0x772 + (a * 4 + 2) * 0x20) = 0x1016; -} - -void debug_sub_8012B70(u8 taskId, u8 b) -{ - if (b != 0) - { - sub_802BBD4(24, 28, 29, 33, 1); - debug_sub_80128B4(); - debug_sub_8012938(taskId); - debug_sub_80129F8(taskId); - gTasks[taskId].data[0] = 1; - } - else - { - sub_802BBD4(24, 28, 29, 33, 0); - gTasks[taskId].data[0] = 2; - Text_InitWindow(&gUnknown_03004210, Str_821F7DA, 656, 26, 29); - Text_PrintWindow8002F44(&gUnknown_03004210); - gTasks[taskId].data[3] = 0; - debug_sub_8012B2C(0); - } -} - -void debug_sub_8012C08(u8 taskId, u8 b) -{ - debug_sub_8010A7C(0, 9); - Text_InitWindow(&gUnknown_03004210, gBattleTextBuff1, 144, 2, 35); - Text_PrintWindow8002F44(&gUnknown_03004210); - debug_sub_8010A7C(0, 7); - Text_InitWindow(&gUnknown_03004210, gBattleTextBuff1, 162, 2, 37); - Text_PrintWindow8002F44(&gUnknown_03004210); - sub_802BBD4(24, 28, 29, 33, 0); - if (b != 0) - { - gTasks[taskId].data[0] = 4; - Text_InitWindow(&gUnknown_03004210, gUnknown_Debug_821F7F3, 144, 2, 35); - } - else - { - gTasks[taskId].data[0] = 3; - Text_InitWindow(&gUnknown_03004210, Str_821F7EA, 144, 2, 35); - } - Text_PrintWindow8002F44(&gUnknown_03004210); - Text_InitWindow(&gUnknown_03004210, BattleText_YesNo, 656, 26, 29); - Text_PrintWindow8002F44(&gUnknown_03004210); - gTasks[taskId].data[3] = 1; - debug_sub_8012B2C(1); -} - -void debug_sub_8012D10(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - case 0: - debug_sub_80128B4(); - debug_sub_8012938(taskId); - Text_InitWindow(&gUnknown_03004210, Str_821F7BD, 400, 19, 35); - Text_PrintWindow8002F44(&gUnknown_03004210); - gTasks[taskId].data[0]++; - sub_802E3E4(gTasks[taskId].data[2], 0); - break; - case 1: - if (gMain.newKeys & DPAD_UP) - { - PlaySE(SE_SELECT); - nullsub_8(gTasks[taskId].data[2]); - gTasks[taskId].data[2] &= ~2; - sub_802E3E4(gTasks[taskId].data[2], 0); - } - else if (gMain.newKeys & DPAD_DOWN) - { - PlaySE(SE_SELECT); - nullsub_8(gTasks[taskId].data[2]); - gTasks[taskId].data[2] |= 2; - sub_802E3E4(gTasks[taskId].data[2], 0); - } - else if (gMain.newKeys & DPAD_LEFT) - { - PlaySE(SE_SELECT); - nullsub_8(gTasks[taskId].data[2]); - gTasks[taskId].data[2] &= ~1; - sub_802E3E4(gTasks[taskId].data[2], 0); - } - else if (gMain.newKeys & DPAD_RIGHT) - { - PlaySE(SE_SELECT); - nullsub_8(gTasks[taskId].data[2]); - gTasks[taskId].data[2] |= 1; - sub_802E3E4(gTasks[taskId].data[2], 0); - } - else if (gMain.newAndRepeatedKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - switch (gTasks[taskId].data[2]) - { - case 0: - if (gUnknown_Debug_2023B62[gCurrentMove - 1] < 64) - { - gUnknown_Debug_2023B62[gCurrentMove - 1] += 1; - debug_sub_8012938(taskId); - } - break; - case 1: - debug_sub_8012AC0(1, taskId); - break; - case 2: - if (gCurrentMove < 411) - gCurrentMove++; - else - gCurrentMove = 1; - debug_sub_80128B4(); - debug_sub_8012938(taskId); - debug_sub_80129F8(taskId); - break; - case 3: - debug_sub_8012B70(taskId, 0); - break; - } - } - else if (gMain.newAndRepeatedKeys & B_BUTTON) - { - PlaySE(SE_SELECT); - switch (gTasks[taskId].data[2]) - { - case 0: - if (gUnknown_Debug_2023B62[gCurrentMove - 1] > 0) - { - gUnknown_Debug_2023B62[gCurrentMove - 1] -= 1; - debug_sub_8012938(taskId); - } - break; - case 1: - debug_sub_8012AC0(-1, taskId); - break; - case 2: - if (gCurrentMove > 1) - gCurrentMove--; - else - gCurrentMove = 411; - debug_sub_80128B4(); - debug_sub_8012938(taskId); - debug_sub_80129F8(taskId); - break; - case 3: - debug_sub_8012B70(taskId, 0); - break; - } - } - else if (gMain.newAndRepeatedKeys & R_BUTTON) - { - PlaySE(SE_SELECT); - switch (gTasks[taskId].data[2]) - { - case 0: - if (gUnknown_Debug_2023B62[gCurrentMove - 1] < 64) - { - gUnknown_Debug_2023B62[gCurrentMove - 1] += 8; - if (gUnknown_Debug_2023B62[gCurrentMove - 1] > 64) - gUnknown_Debug_2023B62[gCurrentMove - 1] = 64; - debug_sub_8012938(taskId); - } - break; - case 1: - debug_sub_8012AC0(1, taskId); - break; - case 2: - if (gCurrentMove + 10 < 412) - gCurrentMove += 10; - else - gCurrentMove -= 400; - debug_sub_80128B4(); - debug_sub_8012938(taskId); - debug_sub_80129F8(taskId); - break; - case 3: - debug_sub_8012B70(taskId, 0); - break; - } - } - else if (gMain.newAndRepeatedKeys & L_BUTTON) - { - PlaySE(SE_SELECT); - switch (gTasks[taskId].data[2]) - { - case 0: - if (gUnknown_Debug_2023B62[gCurrentMove - 1] > 0) - { - if (gUnknown_Debug_2023B62[gCurrentMove - 1] > 8) - gUnknown_Debug_2023B62[gCurrentMove - 1] -= 8; - else - gUnknown_Debug_2023B62[gCurrentMove - 1] = 0; - debug_sub_8012938(taskId); - } - break; - case 1: - debug_sub_8012AC0(-1, taskId); - break; - case 2: - if (gCurrentMove - 10 > 1) - gCurrentMove -= 10; - else - gCurrentMove += 400; - debug_sub_80128B4(); - debug_sub_8012938(taskId); - debug_sub_80129F8(taskId); - break; - case 3: - debug_sub_8012B70(taskId, 0); - break; - } - } - break; - case 2: - if (gMain.newKeys & DPAD_UP) - { - PlaySE(SE_SELECT); - debug_sub_8012B4C(gTasks[taskId].data[3]); - gTasks[taskId].data[3] = 0; - debug_sub_8012B2C(0); - } - else if (gMain.newKeys & DPAD_DOWN) - { - PlaySE(SE_SELECT); - debug_sub_8012B4C(gTasks[taskId].data[3]); - gTasks[taskId].data[3] = 1; - debug_sub_8012B2C(1); - } - else if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - debug_sub_8012C08(taskId, gTasks[taskId].data[3]); - } - else if (gMain.newKeys & B_BUTTON) - { - PlaySE(SE_SELECT); - asm(""); - debug_sub_8012B70(taskId, 1); - } - return; - case 3: - if (gMain.newKeys & DPAD_UP) - { - PlaySE(SE_SELECT); - debug_sub_8012B4C(gTasks[taskId].data[3]); - gTasks[taskId].data[3] = 0; - debug_sub_8012B2C(0); - } - else if (gMain.newKeys & DPAD_DOWN) - { - PlaySE(SE_SELECT); - debug_sub_8012B4C(gTasks[taskId].data[3]); - gTasks[taskId].data[3] = 1; - debug_sub_8012B2C(1); - } - else if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - if (gTasks[taskId].data[3] == 0) - debug_sub_80132C8(31, gUnknown_Debug_2023B62, 411); - debug_sub_8012B70(taskId, 1); - } - else if (gMain.newKeys & B_BUTTON) - { - PlaySE(SE_SELECT); - debug_sub_8012B70(taskId, 1); - } - break; - case 4: - if (gMain.newKeys & DPAD_UP) - { - PlaySE(SE_SELECT); - debug_sub_8012B4C(gTasks[taskId].data[3]); - gTasks[taskId].data[3] = 0; - debug_sub_8012B2C(0); - } - else if (gMain.newKeys & DPAD_DOWN) - { - PlaySE(SE_SELECT); - debug_sub_8012B4C(gTasks[taskId].data[3]); - gTasks[taskId].data[3] = 1; - debug_sub_8012B2C(1); - } - else if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - if (gTasks[taskId].data[3] == 0) - debug_sub_8013294(31, gUnknown_Debug_2023B62, 411); - debug_sub_8012B70(taskId, 1); - } - else if (gMain.newKeys & B_BUTTON) - { - PlaySE(SE_SELECT); - debug_sub_8012B70(taskId, 1); - } - break; - } -} - -u8 debug_sub_8013240(void) -{ - if (IdentifyFlash() == 0) - return 0; - else - return 1; -} - -u32 debug_sub_8013258(u16 sectorNum, u8 *data, u32 size) -{ - while (1) - { - if (ProgramFlashSectorAndVerify(sectorNum, data) != 0) - return 0; - if (size <= 0x1000) - break; - size -= 0x1000; - data += 0x1000; - sectorNum++; - } - return 1; -} - -u32 debug_sub_8013294(u8 sectorNum, void *data, u32 size) -{ - u32 result; - - if (debug_sub_8013240() != 0) - return 0; - m4aSoundVSyncOff(); - result = debug_sub_8013258(sectorNum, data, size); - m4aSoundVSyncOn(); - return result; -} - -void debug_sub_80132C8(u8 a, void *b, u32 c) -{ - if (debug_sub_8013240() == 0) - ReadFlash(a, 0, b, c); -} -#endif - -void oac_poke_opponent(struct Sprite *sprite) -{ - sprite->callback = sub_8010278; - StartSpriteAnimIfDifferent(sprite, 0); - BeginNormalPaletteFade(0x00020000, 0, 10, 10, RGB(15, 15, 15)); -} - -void sub_8010278(struct Sprite *sprite) -{ - if ((gUnknown_02024DE8 & 1) == 0) - { - sprite->pos2.x += 2; - if (sprite->pos2.x == 0) - { - sprite->callback = sub_80102AC; - PlayCry1(sprite->data[2], 25); - } - } -} - -void sub_80102AC(struct Sprite *sprite) -{ - if (sprite->animEnded) - { - sub_804777C(sprite->data[0]); - sub_8043DFC(gHealthboxIDs[sprite->data[0]]); - sprite->callback = nullsub_37; - StartSpriteAnimIfDifferent(sprite, 0); - BeginNormalPaletteFade(0x00020000, 0, 10, 0, RGB(15, 15, 15)); - } -} - -void nullsub_37(struct Sprite *sprite) -{ -} - -void unref_sub_801030C(struct Sprite *sprite) -{ - sprite->data[3] = 6; - sprite->data[4] = 1; - sprite->callback = sub_8010320; -} - -void sub_8010320(struct Sprite *sprite) -{ - sprite->data[4]--; - if (sprite->data[4] == 0) - { - sprite->data[4] = 8; - sprite->invisible ^= 1; - sprite->data[3]--; - if (sprite->data[3] == 0) - { - sprite->invisible = FALSE; - sprite->callback = nullsub_37; - gUnknown_03004284 = 0; - } - } -} - -void sub_8010384(struct Sprite *sprite) -{ - u8 r6 = sprite->data[0]; - u16 species; - u8 yOffset; - - if (ewram17800[r6].transformedSpecies != 0) - species = ewram17800[r6].transformedSpecies; - else - species = sprite->data[2]; - - GetMonData(&gEnemyParty[gBattlerPartyIndexes[r6]], MON_DATA_PERSONALITY); // Unused return value - - if (species == SPECIES_UNOWN) - { - u32 personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[r6]], MON_DATA_PERSONALITY); - u16 unownForm = ((((personalityValue & 0x3000000) >> 18) | ((personalityValue & 0x30000) >> 12) | ((personalityValue & 0x300) >> 6) | (personalityValue & 3)) % 0x1C); - u16 unownSpecies; - - if (unownForm == 0) - unownSpecies = SPECIES_UNOWN; // Use the A Unown form - else - unownSpecies = NUM_SPECIES + unownForm; // Use one of the other Unown letters - - yOffset = gMonFrontPicCoords[unownSpecies].y_offset; - } - else if (species == SPECIES_CASTFORM) - { - yOffset = gCastformFrontSpriteCoords[gBattleMonForms[r6]].y_offset; - } - else if (species > NUM_SPECIES) - { - yOffset = gMonFrontPicCoords[SPECIES_NONE].y_offset; - } - else - { - yOffset = gMonFrontPicCoords[species].y_offset; - } - - sprite->data[3] = 8 - yOffset / 8; - sprite->data[4] = 1; - sprite->callback = sub_8010494; -} - -void sub_8010494(struct Sprite *sprite) -{ - s32 i; - u8 *dst; - - sprite->data[4]--; - if (sprite->data[4] == 0) - { - sprite->data[4] = 2; - sprite->pos2.y += 8; - sprite->data[3]--; - if (sprite->data[3] < 0) - { - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); - } - else - { - // this should use a MEMSET_ALT, but *(dst++) wont match with it. - dst = (u8 *)gUnknown_081FAF4C[GetBattlerPosition(sprite->data[0])] + (gBattleMonForms[sprite->data[0]] << 11) + (sprite->data[3] << 8); - for (i = 0; i < 0x100; i++) - *(dst++) = 0; - StartSpriteAnim(sprite, gBattleMonForms[sprite->data[0]]); - } - } -} - -void sub_8010520(struct Sprite *sprite) -{ - sprite->data[3] = 8; - sprite->data[4] = sprite->invisible; - sprite->callback = sub_801053C; -} - -void sub_801053C(struct Sprite *sprite) -{ - sprite->data[3]--; - if (sprite->data[3] == 0) - { - sprite->invisible ^= 1; - sprite->data[3] = 8; - } -} - -void sub_8010574(struct Sprite *sprite) -{ - sprite->invisible = sprite->data[4]; - sprite->data[4] = FALSE; - sprite->callback = nullsub_37; -} - -void sub_80105A0(struct Sprite *sprite) -{ - sprite->callback = oac_poke_ally_; -} - -void oac_poke_ally_(struct Sprite *sprite) -{ - if ((gUnknown_02024DE8 & 1) == 0) - { - sprite->pos2.x -= 2; - if (sprite->pos2.x == 0) - { - sprite->callback = nullsub_86; - sprite->data[1] = 0; - } - } -} - -void sub_80105DC(struct Sprite *sprite) -{ - sprite->callback = nullsub_86; -} - -void nullsub_86(struct Sprite *sprite) -{ -} - -void sub_80105EC(struct Sprite *sprite) -{ - if ((gUnknown_02024DE8 & 1) == 0) - { - sprite->pos2.x += sprite->data[1]; - sprite->pos2.y += sprite->data[2]; - } -} - -void dp11b_obj_instanciate(u8 bank, u8 b, s8 c, s8 d) -{ - u8 spriteId; - u8 objectID; - - if (b) - { - if (ewram17810[bank].unk0_1) - return; - } - else - { - if (ewram17810[bank].unk0_2) - return; - } - - spriteId = CreateInvisibleSpriteWithCallback(objc_dp11b_pingpong); - if (b == TRUE) - { - objectID = gHealthboxIDs[bank]; - ewram17810[bank].unk2 = spriteId; - ewram17810[bank].unk0_1 = 1; - gSprites[spriteId].data[0] = 0x80; - } - else - { - objectID = gBankSpriteIds[bank]; - ewram17810[bank].unk3 = spriteId; - ewram17810[bank].unk0_2 = 1; - gSprites[spriteId].data[0] = 0xC0; - } - gSprites[spriteId].data[1] = c; - gSprites[spriteId].data[2] = d; - gSprites[spriteId].data[3] = objectID; - gSprites[spriteId].data[4] = b; - gSprites[objectID].pos2.x = 0; - gSprites[objectID].pos2.y = 0; -} - -void dp11b_obj_free(u8 a, u8 b) -{ - u8 r4; - - if (b == TRUE) - { - if (!ewram17810[a].unk0_1) - return; - r4 = gSprites[ewram17810[a].unk2].data[3]; - DestroySprite(&gSprites[ewram17810[a].unk2]); - ewram17810[a].unk0_1 = 0; - } - else - { - if (!ewram17810[a].unk0_2) - return; - r4 = gSprites[ewram17810[a].unk3].data[3]; - DestroySprite(&gSprites[ewram17810[a].unk3]); - ewram17810[a].unk0_2 = 0; - } - gSprites[r4].pos2.x = 0; - gSprites[r4].pos2.y = 0; -} - -void objc_dp11b_pingpong(struct Sprite *sprite) -{ - u8 spriteId = sprite->data[3]; - s32 var; - - if (sprite->data[4] == 1) - var = sprite->data[0]; - else - var = sprite->data[0]; - - gSprites[spriteId].pos2.y = Sin(var, sprite->data[2]) + sprite->data[2]; - sprite->data[0] = (sprite->data[0] + sprite->data[1]) & 0xFF; -} - -void nullsub_41(void) -{ -} - -void sub_8010800(void) -{ - sub_8010874(); - gBattleCommunication[1] = 0; - gBattleMainFunc = bc_8012FAC; -} - -#if DEBUG -void debug_sub_80138CC(void) -{ - if (GetBattlerSide(gActiveBattler) == 0) - { - switch (gSharedMem[0x160FD]) - { - case 0: - if (gBattleBankFunc[gActiveBattler] == sub_802C098) - gSharedMem[0x160FD]++; - break; - case 1: - gMain.heldKeys = A_BUTTON; - gMain.newKeys = A_BUTTON; - gSharedMem[0x160FD]++; - gSharedMem[0x160FE] = 0x80; - break; - case 2: - gSharedMem[0x160FE]--; - if (gSharedMem[0x160FE] == 0) - { - gMain.heldKeys = A_BUTTON; - gMain.newKeys = A_BUTTON; - gSharedMem[0x160FD]++; - gSharedMem[0x160FE] = 0x80; - } - break; - case 3: - gSharedMem[0x160FE]--; - if (gSharedMem[0x160FE] == 0) - { - gMain.heldKeys = A_BUTTON; - gMain.newKeys = A_BUTTON; - gSharedMem[0x160FD]++; - } - break; - case 4: - gSharedMem[0x160FD] = 0; - break; - } - } -} -#endif - -void sub_8010824(void) -{ -#if DEBUG - if (gUnknown_02023A14_50 & 0x80) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - debug_sub_80138CC(); - gBattleMainFunc(); - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - gBattleBankFunc[gActiveBattler](); - } - else -#endif - { - gBattleMainFunc(); - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - gBattleBankFunc[gActiveBattler](); - } -} - -void sub_8010874(void) -{ - s32 i; - u32 j; - u8 *r4; - - TurnValuesCleanUp(0); - SpecialStatusesClear(); - - for (i = 0; i < 4; i++) - { - gStatuses3[i] = 0; - - MEMSET_ALT(&gDisableStructs[i], 0, 0x1C, j, r4); - gDisableStructs[i].isFirstTurn= 2; - gUnknown_02024C70[i] = 0; - gLastUsedMove[i] = 0; - gLastLandedMoves[i] = 0; - gLastHitByType[i] = 0; - gUnknown_02024C4C[i] = 0; - gLastHitBy[i] = 0xFF; - gLockedMoves[i] = 0; - gUnknown_02024C2C[i] = 0; - eFlashFireArr.arr[i] = 0; - } - - for (i = 0; i < 2; i++) - { - gSideAffecting[i] = 0; - MEMSET_ALT(&gSideTimers[i], 0, 12, j, r4); - } - - gBankAttacker = 0; - gBankTarget = 0; - gBattleWeather = 0; - - MEMSET_ALT(&gWishFutureKnock, 0, 0x2C, i, r4); - - gHitMarker = 0; - if ((gBattleTypeFlags & BATTLE_TYPE_LINK) == 0 && gSaveBlock2.optionsBattleSceneOff == TRUE) - gHitMarker = HITMARKER_NO_ANIMATIONS; - ewram16084 = gSaveBlock2.optionsBattleStyle; - gMultiHitCounter = 0; - gBattleOutcome = 0; - gBattleExecBuffer = 0; - gPaydayMoney = 0; - ewram17130 = 0; - ewram17160 = 0; - for (i = 0; i < 8; i++) - gBattleCommunication[i] = 0; - gPauseCounterBattle = 0; - gBattleMoveDamage = 0; - gUnknown_02024DE8 = 0; - ewram16002 = 0; - ewram160A1 = 0; - gLeveledUpInBattle = 0; - gAbsentBattlerFlags = 0; - ewram16078 = 0; - ewram16086 = 0; - ewram16087 = 0; - ewram16089 = gBaseStats[GetMonData(&gEnemyParty[0], MON_DATA_SPECIES)].catchRate * 100 / 1275; - ewram16088 = 3; - ewram1601B = 0; - ewram16056 = 1; - - for (i = 0; i < 8; i++) - { - ewram160ACarr(i) = 0; - ewram160CCarr(i) = 0; - ewram160E8arr(i) = 0; - ewram160F0arr(i) = 0; - ewram16100arr(i) = 0; - ewram16108arr(i) = 0; - } - - ewram160C8 = 6; - ewram160C9 = 6; - ewram16113 = 0; - for (i = 0; i < 11; i++) - gBattleResults.usedBalls[i] = 0; - gBattleResults.battleTurnCounter = 0; - gBattleResults.playerFaintCounter = 0; - gBattleResults.opponentFaintCounter = 0; - gBattleResults.unk2 = 0; - gBattleResults.unk3 = 0; - gBattleResults.unk4 = 0; - gBattleResults.unk5_0 = 0; - gBattleResults.unk5_1 = 0; - gBattleResults.lastOpponentSpecies = 0; - gBattleResults.lastUsedMove = 0; - gBattleResults.opponentMove = 0; - gBattleResults.poke1Species = 0; - gBattleResults.opponentSpecies = 0; - gBattleResults.caughtPoke = 0; - for (i = 0; i < 10; i++) - { - gBattleResults.pokeString1[i] = 0; - gBattleResults.pokeString2[i] = 0; - gBattleResults.caughtNick[i] = 0; - } -#if DEBUG - gSharedMem[0x1609E] = 0; - gSharedMem[0x1609F] = 0; -#endif -} - -void SwitchInClearSetData(void) -{ - struct DisableStruct sp0 = gDisableStructs[gActiveBattler]; - s32 i; - u8 *ptr; - - if (gBattleMoves[gCurrentMove].effect != EFFECT_BATON_PASS) - { - for (i = 0; i < 8; i++) - gBattleMons[gActiveBattler].statStages[i] = 6; - for (i = 0; i < gBattlersCount; i++) - { - if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].bankPreventingEscape == gActiveBattler) - gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION; - if ((gStatuses3[i] & STATUS3_ALWAYS_HITS) && gDisableStructs[i].bankWithSureHit == gActiveBattler) - { - gStatuses3[i] &= ~STATUS3_ALWAYS_HITS; - gDisableStructs[i].bankWithSureHit = 0; - } - } - } - if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS) - { - gBattleMons[gActiveBattler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED); - gStatuses3[gActiveBattler] &= (STATUS3_LEECHSEED_BANK | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED | STATUS3_MUDSPORT | STATUS3_WATERSPORT); - - for (i = 0; i < gBattlersCount; i++) - { - if (GetBattlerSide(gActiveBattler) != GetBattlerSide(i) - && (gStatuses3[i] & STATUS3_ALWAYS_HITS) != 0 - && (gDisableStructs[i].bankWithSureHit == gActiveBattler)) - { - gStatuses3[i] &= ~STATUS3_ALWAYS_HITS; - gStatuses3[i] |= 0x10; - } - } - } - else - { - gBattleMons[gActiveBattler].status2 = 0; - gStatuses3[gActiveBattler] = 0; - } - - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleMons[i].status2 & (gBitTable[gActiveBattler] << 16)) - gBattleMons[i].status2 &= ~(gBitTable[gActiveBattler] << 16); - if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && ewram16020arr(i) == gActiveBattler) - gBattleMons[i].status2 &= ~STATUS2_WRAPPED; - } - - gActionSelectionCursor[gActiveBattler] = 0; - gMoveSelectionCursor[gActiveBattler] = 0; - - MEMSET_ALT(&gDisableStructs[gActiveBattler], 0, 0x1C, i, ptr); - - if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS) - { - gDisableStructs[gActiveBattler].substituteHP = sp0.substituteHP; - gDisableStructs[gActiveBattler].bankWithSureHit = sp0.bankWithSureHit; - gDisableStructs[gActiveBattler].perishSongTimer1 = sp0.perishSongTimer1; - gDisableStructs[gActiveBattler].perishSongTimer2 = sp0.perishSongTimer2; - } - - gDisableStructs[gActiveBattler].isFirstTurn= 2; - gLastUsedMove[gActiveBattler] = 0; - gLastLandedMoves[gActiveBattler] = 0; - gLastHitByType[gActiveBattler] = 0; - gUnknown_02024C4C[gActiveBattler] = 0; - gUnknown_02024C2C[gActiveBattler] = 0; - gLastHitBy[gActiveBattler] = 0xFF; - - ewram160ACarr2(0, gActiveBattler) = 0; - ewram160ACarr2(1, gActiveBattler) = 0; - ewram16100arr2(0, gActiveBattler) = 0; - ewram16100arr2(1, gActiveBattler) = 0; - ewram16100arr2(2, gActiveBattler) = 0; - ewram16100arr2(3, gActiveBattler) = 0; - ewram160E8arr2(0, gActiveBattler) = 0; - ewram160E8arr2(1, gActiveBattler) = 0; - - eFlashFireArr.arr[gActiveBattler] = 0; - - gCurrentMove = 0; -} - -void UndoEffectsAfterFainting(void) -{ - s32 i; - u8 *ptr; - - for (i = 0; i < 8; i++) - gBattleMons[gActiveBattler].statStages[i] = 6; - gBattleMons[gActiveBattler].status2 = 0; - gStatuses3[gActiveBattler] = 0; - for (i = 0; i < gBattlersCount; i++) - { - if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].bankPreventingEscape == gActiveBattler) - gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION; - if (gBattleMons[i].status2 & (gBitTable[gActiveBattler] << 16)) - gBattleMons[i].status2 &= ~(gBitTable[gActiveBattler] << 16); - if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && ewram16020arr(i) == gActiveBattler) - gBattleMons[i].status2 &= ~STATUS2_WRAPPED; - } - gActionSelectionCursor[gActiveBattler] = 0; - gMoveSelectionCursor[gActiveBattler] = 0; - - MEMSET_ALT(&gDisableStructs[gActiveBattler], 0, 0x1C, i, ptr); - gProtectStructs[gActiveBattler].protected = 0; - gProtectStructs[gActiveBattler].endured = 0; - gProtectStructs[gActiveBattler].onlyStruggle = 0; - gProtectStructs[gActiveBattler].helpingHand = 0; - gProtectStructs[gActiveBattler].bounceMove = 0; - gProtectStructs[gActiveBattler].stealMove = 0; - gProtectStructs[gActiveBattler].flag0Unknown = 0; - gProtectStructs[gActiveBattler].prlzImmobility = 0; - gProtectStructs[gActiveBattler].confusionSelfDmg = 0; - gProtectStructs[gActiveBattler].notEffective = 0; - gProtectStructs[gActiveBattler].chargingTurn = 0; - gProtectStructs[gActiveBattler].fleeFlag = 0; - gProtectStructs[gActiveBattler].usedImprisionedMove = 0; - gProtectStructs[gActiveBattler].loveImmobility = 0; - gProtectStructs[gActiveBattler].usedDisabledMove = 0; - gProtectStructs[gActiveBattler].usedTauntedMove = 0; - gProtectStructs[gActiveBattler].flag2Unknown = 0; - gProtectStructs[gActiveBattler].flinchImmobility = 0; - gProtectStructs[gActiveBattler].notFirstStrike = 0; - - gDisableStructs[gActiveBattler].isFirstTurn= 2; - gLastUsedMove[gActiveBattler] = 0; - gLastLandedMoves[gActiveBattler] = 0; - gLastHitByType[gActiveBattler] = 0; - gUnknown_02024C4C[gActiveBattler] = 0; - gUnknown_02024C2C[gActiveBattler] = 0; - gLastHitBy[gActiveBattler] = 0xFF; - - ewram160E8arr2(0, gActiveBattler) = 0; - ewram160E8arr2(1, gActiveBattler) = 0; - ewram160ACarr2(0, gActiveBattler) = 0; - ewram160ACarr2(1, gActiveBattler) = 0; - ewram16100arr2(0, gActiveBattler) = 0; - ewram16100arr2(1, gActiveBattler) = 0; - ewram16100arr2(2, gActiveBattler) = 0; - ewram16100arr2(3, gActiveBattler) = 0; - - eFlashFireArr.arr[gActiveBattler] = 0; - - gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1; - gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2; -} - -void bc_8012FAC(void) -{ - switch (gBattleCommunication[0]) - { - case 0: - gActiveBattler = gBattleCommunication[1]; - EmitGetAttributes(0, 0, 0); - MarkBufferBankForExecution(gActiveBattler); - gBattleCommunication[0]++; - break; - case 1: - if (gBattleExecBuffer == 0) - { - gBattleCommunication[1]++; - if (gBattleCommunication[1] == gBattlersCount) - gBattleMainFunc = BattlePrepIntroSlide; - else - gBattleCommunication[0] = 0; - } - break; - } -} - -static void BattlePrepIntroSlide(void) -{ - if (gBattleExecBuffer == 0) - { - gActiveBattler = GetBattlerAtPosition(0); - EmitIntroSlide(0, gBattleTerrain); - MarkBufferBankForExecution(gActiveBattler); - gBattleMainFunc = sub_8011384; - gBattleCommunication[0] = 0; - gBattleCommunication[1] = 0; - } -} - -void sub_8011384(void) -{ - u8 *ptr; - s32 i; - - if (gBattleExecBuffer == 0) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if ((gBattleTypeFlags & BATTLE_TYPE_SAFARI) - && GetBattlerSide(gActiveBattler) == 0) - { - MEMSET_ALT(&gBattleMons[gActiveBattler], 0, 0x58, i, ptr); - } - else - { - u8 r0; - - MEMSET_ALT(&gBattleMons[gActiveBattler], gBattleBufferB[gActiveBattler][4 + i], 0x58, i, ptr); - gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1; - gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2; - gBattleMons[gActiveBattler].ability = GetAbilityBySpecies(gBattleMons[gActiveBattler].species, gBattleMons[gActiveBattler].altAbility); - r0 = GetBattlerSide(gActiveBattler); - ewram160BC[r0] = gBattleMons[gActiveBattler].hp; - for (i = 0; i < 8; i++) - gBattleMons[gActiveBattler].statStages[i] = 6; - gBattleMons[gActiveBattler].status2 = 0; - } - - if (GetBattlerPosition(gActiveBattler) == 0) - { - EmitTrainerThrow(0); - MarkBufferBankForExecution(gActiveBattler); - } - - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - { - if (GetBattlerPosition(gActiveBattler) == 1) - { - EmitTrainerThrow(0); - MarkBufferBankForExecution(gActiveBattler); - } - if (GetBattlerSide(gActiveBattler) == 1 - && !(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK))) - GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBattler].species), 2); - } - else - { - if (GetBattlerSide(gActiveBattler) == 1 - && !(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK))) - { - GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBattler].species), 2); - EmitLoadPokeSprite(0); - MarkBufferBankForExecution(gActiveBattler); - } - } - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (GetBattlerPosition(gActiveBattler) == 2 - || GetBattlerPosition(gActiveBattler) == 3) - { - EmitTrainerThrow(0); - MarkBufferBankForExecution(gActiveBattler); - } - } - } - gBattleMainFunc = bc_801333C; - } -} - -void bc_801333C(void) -{ - s32 i; - - if (gBattleExecBuffer == 0) - { - struct HpAndStatus hpStatus[6]; - - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - { - for (i = 0; i < 6; i++) - { - if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == 0 - || GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG) - { - hpStatus[i].hp = 0xFFFF; - hpStatus[i].status = 0; - } - else - { - hpStatus[i].hp = GetMonData(&gEnemyParty[i], MON_DATA_HP); - hpStatus[i].status = GetMonData(&gEnemyParty[i], MON_DATA_STATUS); - } - } - gActiveBattler = GetBattlerAtPosition(1); - EmitDrawPartyStatusSummary(0, hpStatus, 0x80); - MarkBufferBankForExecution(gActiveBattler); - - for (i = 0; i < 6; i++) - { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) == 0 - || GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) == SPECIES_EGG) - { - hpStatus[i].hp = 0xFFFF; - hpStatus[i].status = 0; - } - else - { - hpStatus[i].hp = GetMonData(&gPlayerParty[i], MON_DATA_HP); - hpStatus[i].status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS); - } - } - gActiveBattler = GetBattlerAtPosition(0); - EmitDrawPartyStatusSummary(0, hpStatus, 0x80); - MarkBufferBankForExecution(gActiveBattler); - - gBattleMainFunc = bc_battle_begin_message; - } - else - { - // The array gets set here, but nothing is ever done with it. - // Likely unfinished code. - - for (i = 0; i < 6; i++) - { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) == 0 - || GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) == SPECIES_EGG) - { - hpStatus[i].hp = 0xFFFF; - hpStatus[i].status = 0; - } - else - { - hpStatus[i].hp = GetMonData(&gPlayerParty[i], MON_DATA_HP); - hpStatus[i].status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS); - } - } - - gBattleMainFunc = bc_8013568; - } - } -} - -void bc_battle_begin_message(void) -{ - if (gBattleExecBuffer == 0) - { - gActiveBattler = GetBattlerAtPosition(1); - PrepareStringBattle(0, gActiveBattler); - gBattleMainFunc = sub_8011800; - } -} - -void bc_8013568(void) -{ - if (gBattleExecBuffer == 0) - { - gBattleMainFunc = sub_8011970; - PrepareStringBattle(0, 0); - } -} - -void sub_8011800(void) -{ - if (gBattleExecBuffer == 0) - { - PrepareStringBattle(1, GetBattlerAtPosition(1)); - gBattleMainFunc = sub_8011834; - } -} - -void sub_8011834(void) -{ - if (gBattleExecBuffer == 0) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (GetBattlerPosition(gActiveBattler) == 1) - { - EmitTrainerBallThrow(0); - MarkBufferBankForExecution(gActiveBattler); - } - if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) - && GetBattlerPosition(gActiveBattler) == 3) - { - EmitTrainerBallThrow(0); - MarkBufferBankForExecution(gActiveBattler); - } - } - gBattleMainFunc = bc_801362C; - } -} - -void bc_801362C(void) -{ - if (gBattleExecBuffer == 0) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (GetBattlerSide(gActiveBattler) == 1 - && !(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK))) - GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBattler].species), 2); - } - gBattleMainFunc = sub_8011970; - } -} - -void unref_sub_8011950(void) -{ - if (gBattleExecBuffer == 0) - gBattleMainFunc = sub_8011970; -} - -void sub_8011970(void) -{ - if (gBattleExecBuffer == 0) - { - if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) - PrepareStringBattle(1, GetBattlerAtPosition(0)); - gBattleMainFunc = sub_80119B4; - } -} - -void sub_80119B4(void) -{ - if (gBattleExecBuffer == 0) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (GetBattlerPosition(gActiveBattler) == 0) - { - EmitTrainerBallThrow(0); - MarkBufferBankForExecution(gActiveBattler); - } - if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) - && GetBattlerPosition(gActiveBattler) == 2) - { - EmitTrainerBallThrow(0); - MarkBufferBankForExecution(gActiveBattler); - } - } - ewram16058 = 0; - ewram160F9 = 0; - ewram160E6 = 0; - gBattleMainFunc = BattleBeginFirstTurn; - } -} - -void unref_sub_8011A68(void) -{ - if (gBattleExecBuffer == 0) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (GetBattlerSide(gActiveBattler) == 0) - { - EmitSendOutPoke(0, gBattlerPartyIndexes[gActiveBattler], 0); - MarkBufferBankForExecution(gActiveBattler); - } - } - ewram16058 = 0; - ewram160F9 = 0; - ewram160E6 = 0; - gBattleMainFunc = BattleBeginFirstTurn; - } -} - -void BattleBeginFirstTurn(void) -{ - s32 i; - s32 j; - u8 r9 = 0; - - if (gBattleExecBuffer == 0) - { - if (ewram16058 == 0) - { - for (i = 0; i < gBattlersCount; i++) - gBanksByTurnOrder[i] = i; - for (i = 0; i < gBattlersCount - 1; i++) - { - for (j = i + 1; j < gBattlersCount; j++) - { - if (GetWhoStrikesFirst(gBanksByTurnOrder[i], gBanksByTurnOrder[j], 1) != 0) - SwapTurnOrder(i, j); - } - } - } - if (ewram160E6 == 0 && AbilityBattleEffects(0, 0, 0, 0xFF, 0) != 0) - { - ewram160E6 = 1; - return; - } - while (ewram16058 < gBattlersCount) - { - if (AbilityBattleEffects(0, gBanksByTurnOrder[ewram16058], 0, 0, 0) != 0) - r9++; - ewram16058++; - if (r9 != 0) - return; - } - if (AbilityBattleEffects(9, 0, 0, 0, 0) != 0) - return; - if (AbilityBattleEffects(11, 0, 0, 0, 0) != 0) - return; - while (ewram160F9 < gBattlersCount) - { - if (ItemBattleEffects(0, gBanksByTurnOrder[ewram160F9], 0) != 0) - r9++; - ewram160F9++; - if (r9 != 0) - return; - } - // Absolutely pointless for-loop that somehow doesn't get optimized out - for (i = 0; i < gBattlersCount; i++) - ; - for (i = 0; i < 4; i++) - { - ewram16068arr(i) = 6; - gActionForBanks[i] = 0xFF; - gChosenMovesByBanks[i] = 0; - } - TurnValuesCleanUp(0); - SpecialStatusesClear(); - ewram160A6 = gAbsentBattlerFlags; - gBattleMainFunc = sub_8012324; - ResetSentPokesToOpponentValue(); - for (i = 0; i < 8; i++) - gBattleCommunication[i] = 0; - for (i = 0; i < gBattlersCount; i++) - gBattleMons[i].status2 &= ~8; - ewram16000 = 0; - ewram16001 = 0; - ewram16110 = 0; - ewram16111 = 0; - ewram1600C = 0; - ewram16059 = 0; - ewram1600E = 0; - gMoveResultFlags = 0; - gRandomTurnNumber = Random(); - } -} - -void bc_8013B1C(void) -{ - s32 i; - - if (gBattleExecBuffer == 0) - { - gBattleMainFunc = BattleTurnPassed; - for (i = 0; i < 8; i++) - gBattleCommunication[i] = 0; - for (i = 0; i < gBattlersCount; i++) - { - gBattleMons[i].status2 &= ~8; - if ((gBattleMons[i].status1 & 7) && (gBattleMons[i].status2 & 0x1000)) - CancelMultiTurnMoves(i); - } - ewram16000 = 0; - ewram16001 = 0; - ewram16110 = 0; - ewram16111 = 0; - ewram1600E = 0; - gMoveResultFlags = 0; - } -} - -void BattleTurnPassed(void) -{ - s32 i; - - TurnValuesCleanUp(1); - if (gBattleOutcome == 0) - { - if (UpdateTurnCounters() != 0) - return; - if (TurnBasedEffects() != 0) - return; - } - if (HandleFaintedMonActions() != 0) - return; - ewram16059 = 0; - if (HandleWishPerishSongOnTurnEnd() != 0) - return; - TurnValuesCleanUp(0); - gHitMarker &= ~HITMARKER_NO_ATTACKSTRING; - gHitMarker &= ~0x80000; - gHitMarker &= ~0x400000; - gHitMarker &= ~0x100000; - ewram16002 = 0; - ewram160A1 = 0; - ewram1600C = 0; - gBattleMoveDamage = 0; - gMoveResultFlags = 0; - for (i = 0; i < 5; i++) - gBattleCommunication[i] = 0; - if (gBattleOutcome != 0) - { - gCurrentActionFuncId = 12; - gBattleMainFunc = RunTurnActionsFunctions; - return; - } - if (gBattleResults.battleTurnCounter < 0xFF) - gBattleResults.battleTurnCounter++; - for (i = 0; i < gBattlersCount; i++) - { - gActionForBanks[i] = 0xFF; - gChosenMovesByBanks[i] = 0; - } - for (i = 0; i < 4; i++) - ewram16068arr(i) = 6; - ewram160A6 = gAbsentBattlerFlags; - gBattleMainFunc = sub_8012324; - gRandomTurnNumber = Random(); -} - -u8 CanRunFromBattle(void) -{ - u8 r2; - u8 r6; - s32 i; - - if (gBattleMons[gActiveBattler].item == ITEM_ENIGMA_BERRY) - r2 = gEnigmaBerries[gActiveBattler].holdEffect; - else - r2 = ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item); - gStringBank = gActiveBattler; - if (r2 == HOLD_EFFECT_CAN_ALWAYS_RUN) - return 0; - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - return 0; - if (gBattleMons[gActiveBattler].ability == ABILITY_RUN_AWAY) - return 0; - r6 = GetBattlerSide(gActiveBattler); - for (i = 0; i < gBattlersCount; i++) - { - if (r6 != GetBattlerSide(i) - && gBattleMons[i].ability == ABILITY_SHADOW_TAG) - { - ewram16003 = i; - gLastUsedAbility = gBattleMons[i].ability; - gBattleCommunication[5] = 2; - return 2; - } - if (r6 != GetBattlerSide(i) - && gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE - && gBattleMons[gActiveBattler].type1 != 2 - && gBattleMons[gActiveBattler].type2 != 2 - && gBattleMons[i].ability == ABILITY_ARENA_TRAP) - { - ewram16003 = i; - gLastUsedAbility = gBattleMons[i].ability; - gBattleCommunication[5] = 2; - return 2; - } - } - i = AbilityBattleEffects(15, gActiveBattler, ABILITY_MAGNET_PULL, 0, 0); - if (i != 0 && (gBattleMons[gActiveBattler].type1 == 8 || gBattleMons[gActiveBattler].type2 == 8)) - { - ewram16003 = i - 1; - gLastUsedAbility = gBattleMons[i - 1].ability; - gBattleCommunication[5] = 2; - return 2; - } - if ((gBattleMons[gActiveBattler].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED)) || (gStatuses3[gActiveBattler] & STATUS3_ROOTED)) - { - gBattleCommunication[5] = 0; - return 1; - } - if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) - { - gBattleCommunication[5] = 1; - return 1; - } - return 0; -} - -void sub_8012258(u8 a) -{ - s32 i; - u8 r4; - u8 r1; - - for (i = 0; i < 3; i++) - gUnknown_02038470[i] = ewram1606Carr(i, a); - r4 = pokemon_order_func(gBattlerPartyIndexes[a]); - r1 = pokemon_order_func(ewram16068arr(a)); - sub_8094C98(r4, r1); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - for (i = 0; i < 3; i++) - { - ewram1606Carr(i, a) = gUnknown_02038470[i]; - ewram1606Carr(i, (a ^ 2)) = gUnknown_02038470[i]; - } - } - else - { - for (i = 0; i < 3; i++) - { - ewram1606Carr(i, a) = gUnknown_02038470[i]; - } - } -} - -enum -{ - STATE_BEFORE_ACTION_CHOSEN, - STATE_WAIT_ACTION_CHOSEN, - STATE_WAIT_ACTION_CASE_CHOSEN, - STATE_WAIT_ACTION_CONFIRMED_STANDBY, - STATE_WAIT_ACTION_CONFIRMED, - STATE_SELECTION_SCRIPT, - STATE_WAIT_SET_BEFORE_ACTION, - STATE_SELECTION_SCRIPT_MAY_RUN -}; - -extern u8 * gSelectionBattleScripts[]; -extern u8 BattleScript_ActionSelectionItemsCantBeUsed[]; -extern u8 BattleScript_PrintFullBox[]; -extern u8 BattleScript_PrintCantRunFromTrainer[]; -extern u8 BattleScript_PrintCantEscapeFromBattle[]; - -void sub_8012324(void) -{ - u8 position; - s32 i; - - gBattleCommunication[4] = 0; - // inverted loop - //_0801234C - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - position = GetBattlerPosition(gActiveBattler); - switch (gBattleCommunication[gActiveBattler]) - { - case STATE_BEFORE_ACTION_CHOSEN: - ewram16068arr(gActiveBattler) = 6; - if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) - && (position & BIT_FLANK) != B_FLANK_LEFT - && !(ewram160A6 & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(position))]) - && gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(position))] != STATE_WAIT_ACTION_CONFIRMED) - break; - //_080123F8 - if (ewram160A6 & gBitTable[gActiveBattler]) - { - gActionForBanks[gActiveBattler] = 13; - if (!(gBattleTypeFlags & 0x40)) - gBattleCommunication[gActiveBattler] = 4; - //_08012454 - else - gBattleCommunication[gActiveBattler] = 3; - break; - } - //_08012468 - if ((gBattleMons[gActiveBattler].status2 & 0x1000) - || (gBattleMons[gActiveBattler].status2 & 0x400000)) - { - gActionForBanks[gActiveBattler] = 0; - gBattleCommunication[gActiveBattler] = 3; - } - else - { - Emitcmd18(0, gActionForBanks[0], gBattleBufferB[0][1] | (gBattleBufferB[0][2] << 8)); - MarkBufferBankForExecution(gActiveBattler); - gBattleCommunication[gActiveBattler]++; - } - break; - case STATE_WAIT_ACTION_CHOSEN: - if (!(gBattleExecBuffer & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) - { - gActionForBanks[gActiveBattler] = gBattleBufferB[gActiveBattler][1]; - switch (gBattleBufferB[gActiveBattler][1]) - { - case B_ACTION_USE_MOVE: - if (AreAllMovesUnusable()) - { - gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT; - ewram16060(gActiveBattler) = FALSE; - ewram16094arr(gActiveBattler) = STATE_WAIT_ACTION_CONFIRMED_STANDBY; - ewram16010arr(gActiveBattler) = gBattleBufferB[gActiveBattler][3]; - return; - } - else if (gDisableStructs[gActiveBattler].encoredMove != 0) - { - gChosenMovesByBanks[gActiveBattler] = gDisableStructs[gActiveBattler].encoredMove; - gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY; - return; - } - else - { - struct ChooseMoveStruct { - u16 moves[4]; - u8 currentPp[4]; - u8 maxPp[4]; - u16 species; - u8 monType1; - u8 monType2; - } moveInfo; - - moveInfo.species = gBattleMons[gActiveBattler].species; - moveInfo.monType1 = gBattleMons[gActiveBattler].type1; - moveInfo.monType2 = gBattleMons[gActiveBattler].type2; - - for (i = 0; i < 4; i++) - { - moveInfo.moves[i] = gBattleMons[gActiveBattler].moves[i]; - moveInfo.currentPp[i] = gBattleMons[gActiveBattler].pp[i]; - moveInfo.maxPp[i] = CalculatePPWithBonus( - gBattleMons[gActiveBattler].moves[i], - gBattleMons[gActiveBattler].ppBonuses, - i); - } - - Emitcmd20(0, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0, FALSE, (u8 *)&moveInfo); - MarkBufferBankForExecution(gActiveBattler); - } - break; - case B_ACTION_USE_ITEM: - if (gBattleTypeFlags & (BATTLE_TYPE_LINK - | BATTLE_TYPE_BATTLE_TOWER - | BATTLE_TYPE_EREADER_TRAINER)) - { - gSelectionBattleScripts[gActiveBattler] = BattleScript_ActionSelectionItemsCantBeUsed; - gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT; - ewram16060(gActiveBattler) = FALSE; - ewram16094arr(gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN; - return; - } - else - { - EmitOpenBag(0, &ewram1606Carr(0, gActiveBattler)); - MarkBufferBankForExecution(gActiveBattler); - } - break; - case B_ACTION_SWITCH: - ewram16064arr(gActiveBattler) = gBattlerPartyIndexes[gActiveBattler]; - if (gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION) - || gStatuses3[gActiveBattler] & STATUS3_ROOTED) - { - EmitChoosePokemon(0, 2, 6, ABILITY_NONE, &ewram1606Carr(0, gActiveBattler)); - } - else if ((i = ABILITY_ON_OPPOSING_FIELD(gActiveBattler, ABILITY_SHADOW_TAG)) - || ((i = ABILITY_ON_OPPOSING_FIELD(gActiveBattler, ABILITY_ARENA_TRAP)) - && !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_FLYING) - && gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE) - || ((i = AbilityBattleEffects(ABILITYEFFECT_CHECK_FIELD_EXCEPT_BATTLER, gActiveBattler, ABILITY_MAGNET_PULL, 0, 0)) - && IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL))) - { - EmitChoosePokemon(0, ((i - 1) << 4) | PARTY_ABILITY_PREVENTS, 6, gLastUsedAbility, &ewram1606Carr(0, gActiveBattler)); - } - else - { - if (gActiveBattler == 2 && gActionForBanks[0] == B_ACTION_SWITCH) - EmitChoosePokemon(0, PARTY_CHOOSE_MON, ewram16068arr(0), ABILITY_NONE, &ewram1606Carr(0, gActiveBattler)); - else if (gActiveBattler == 3 && gActionForBanks[1] == B_ACTION_SWITCH) - EmitChoosePokemon(0, PARTY_CHOOSE_MON, ewram16068arr(1), ABILITY_NONE, &ewram1606Carr(0, gActiveBattler)); - else - EmitChoosePokemon(0, PARTY_CHOOSE_MON, 6, ABILITY_NONE, &ewram1606Carr(0, gActiveBattler)); - } - MarkBufferBankForExecution(gActiveBattler); - break; - case B_ACTION_SAFARI_BALL: - if (PlayerPartyAndPokemonStorageFull()) - { - gSelectionBattleScripts[gActiveBattler] = BattleScript_PrintFullBox; - gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT; - ewram16060(gActiveBattler) = FALSE; - ewram16094arr(gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN; - return; - } - break; - case B_ACTION_SAFARI_POKEBLOCK: - EmitOpenBag(0, &ewram1606Carr(0, gActiveBattler)); - MarkBufferBankForExecution(gActiveBattler); - break; - case B_ACTION_CANCEL_PARTNER: - gBattleCommunication[gActiveBattler] = STATE_WAIT_SET_BEFORE_ACTION; - gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] = STATE_BEFORE_ACTION_CHOSEN; - Emitcmd50(0); - MarkBufferBankForExecution(gActiveBattler); - return; - } - - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER - && !(gBattleTypeFlags & (BATTLE_TYPE_LINK)) - && gBattleBufferB[gActiveBattler][1] == B_ACTION_RUN) - { - BattleScriptExecute(BattleScript_PrintCantRunFromTrainer); - gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; - } - else if (CanRunFromBattle() - && gBattleBufferB[gActiveBattler][1] == B_ACTION_RUN) - { - gSelectionBattleScripts[gActiveBattler] = BattleScript_PrintCantEscapeFromBattle; - gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT; - ewram16060(gActiveBattler) = FALSE; - ewram16094arr(gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN; - return; - } - else - { - gBattleCommunication[gActiveBattler]++; - } - } - break; - case STATE_WAIT_ACTION_CASE_CHOSEN: - if (!(gBattleExecBuffer & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) - { - switch (gActionForBanks[gActiveBattler]) - { - case B_ACTION_USE_MOVE: - switch (gBattleBufferB[gActiveBattler][1]) - { - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - gActionForBanks[gActiveBattler] = gBattleBufferB[gActiveBattler][1]; - return; - default: - if ((gBattleBufferB[gActiveBattler][2] | (gBattleBufferB[gActiveBattler][3] << 8)) == 0xFFFF) - { - gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; - } - else if (TrySetCantSelectMoveBattleScript()) - { - gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT; - ewram16060(gActiveBattler) = FALSE; - gBattleBufferB[gActiveBattler][1] = 0; - ewram16094arr(gActiveBattler) = STATE_WAIT_ACTION_CHOSEN; - return; - } - else - { - ewram1608Carr(gActiveBattler) = gBattleBufferB[gActiveBattler][2]; - gChosenMovesByBanks[gActiveBattler] = gBattleMons[gActiveBattler].moves[ewram1608Carr(gActiveBattler)]; - ewram16010arr(gActiveBattler) = gBattleBufferB[gActiveBattler][3]; - gBattleCommunication[gActiveBattler]++; - } - break; - } - break; - case B_ACTION_USE_ITEM: - if ((gBattleBufferB[gActiveBattler][1] | (gBattleBufferB[gActiveBattler][2] << 8)) == 0) - { - gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; - } - else - { - gLastUsedItem = (gBattleBufferB[gActiveBattler][1] | (gBattleBufferB[gActiveBattler][2] << 8)); - gBattleCommunication[gActiveBattler]++; - } - break; - case B_ACTION_SWITCH: - if (gBattleBufferB[gActiveBattler][1] == PARTY_SIZE) - { - gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; - } - else - { - ewram16068arr(gActiveBattler) = gBattleBufferB[gActiveBattler][1]; - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - ewram1606Carr(0, gActiveBattler) &= 0xF; - ewram1606Carr(0, gActiveBattler) |= (gBattleBufferB[gActiveBattler][2] & 0xF0); - ewram1606Carr(1, gActiveBattler) = gBattleBufferB[gActiveBattler][3]; - - ewram1606Carr(0, (gActiveBattler ^ BIT_FLANK)) &= (0xF0); - ewram1606Carr(0, (gActiveBattler ^ BIT_FLANK)) |= (gBattleBufferB[gActiveBattler][2] & 0xF0) >> 4; - ewram1606Carr(2, (gActiveBattler ^ BIT_FLANK)) = gBattleBufferB[gActiveBattler][3]; - } - gBattleCommunication[gActiveBattler]++; - } - break; - case B_ACTION_RUN: - gHitMarker |= HITMARKER_RUN; - gBattleCommunication[gActiveBattler]++; - break; - case B_ACTION_SAFARI_WATCH_CAREFULLY: - gBattleCommunication[gActiveBattler]++; - break; - case B_ACTION_SAFARI_BALL: - gBattleCommunication[gActiveBattler]++; - break; - case B_ACTION_SAFARI_POKEBLOCK: - if ((gBattleBufferB[gActiveBattler][1] | (gBattleBufferB[gActiveBattler][2] << 8)) != 0) - { - gBattleCommunication[gActiveBattler]++; - } - else - { - gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; - } - break; - case B_ACTION_SAFARI_GO_NEAR: - gBattleCommunication[gActiveBattler]++; - break; - case B_ACTION_SAFARI_RUN: - gHitMarker |= HITMARKER_RUN; - gBattleCommunication[gActiveBattler]++; - break; - case B_ACTION_WALLY_THROW: - gBattleCommunication[gActiveBattler]++; - break; - } - } - break; - case STATE_WAIT_ACTION_CONFIRMED_STANDBY: - if (!(gBattleExecBuffer & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) - { - if (((gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_DOUBLE)) != BATTLE_TYPE_DOUBLE) - || (position & BIT_FLANK) != B_FLANK_LEFT - || (ewram160A6 & gBitTable[GetBattlerAtPosition(position ^ BIT_FLANK)])) - { - EmitLinkStandbyMsg(0, 0); - } - else - { - EmitLinkStandbyMsg(0, 1); - } - MarkBufferBankForExecution(gActiveBattler); - gBattleCommunication[gActiveBattler]++; - } - break; - case STATE_WAIT_ACTION_CONFIRMED: - if (!(gBattleExecBuffer & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) - { - gBattleCommunication[ACTIONS_CONFIRMED_COUNT]++; - } - break; - case STATE_SELECTION_SCRIPT: - if (ewram16060(gActiveBattler)) - { - gBattleCommunication[gActiveBattler] = ewram16094arr(gActiveBattler); - } - else - { - gBankAttacker = gActiveBattler; - gBattlescriptCurrInstr = gSelectionBattleScripts[gActiveBattler]; - if (!(gBattleExecBuffer & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) - { - gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); - } - gSelectionBattleScripts[gActiveBattler] = gBattlescriptCurrInstr; - } - break; - case STATE_WAIT_SET_BEFORE_ACTION: - if (!(gBattleExecBuffer & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) - { - gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; - } - break; - } - } - - // Check if everyone chose actions. - if (gBattleCommunication[ACTIONS_CONFIRMED_COUNT] == gBattlersCount) - { - gBattleMainFunc = SetActionsAndBanksTurnOrder; - } -} - -void SwapTurnOrder(u8 a, u8 b) -{ - int temp; - - temp = gActionsByTurnOrder[a]; - gActionsByTurnOrder[a] = gActionsByTurnOrder[b]; - gActionsByTurnOrder[b] = temp; - - temp = gBanksByTurnOrder[a]; - gBanksByTurnOrder[a] = gBanksByTurnOrder[b]; - gBanksByTurnOrder[b] = temp; -} - -// Determines which of the two given mons will strike first in a battle. -// Returns: -// 0 = first mon moves first -// 1 = second mon moves first -// 2 = second mon moves first because it won a 50/50 roll -u8 GetWhoStrikesFirst(u8 bank1, u8 bank2, bool8 ignoreMovePriorities) -{ - int bank1SpeedMultiplier, bank2SpeedMultiplier; - u32 bank1AdjustedSpeed, bank2AdjustedSpeed; - u8 heldItemEffect; - u8 heldItemEffectParam; - u16 bank1Move; - u16 bank2Move; - u8 strikesFirst = 0; - - // Check for abilities that boost speed in weather. - if (WEATHER_HAS_EFFECT) - { - if ((gBattleMons[bank1].ability == ABILITY_SWIFT_SWIM && (gBattleWeather & WEATHER_RAIN_ANY)) - || (gBattleMons[bank1].ability == ABILITY_CHLOROPHYLL && (gBattleWeather & WEATHER_SUN_ANY))) - bank1SpeedMultiplier = 2; - else - bank1SpeedMultiplier = 1; - - if ((gBattleMons[bank2].ability == ABILITY_SWIFT_SWIM && (gBattleWeather & WEATHER_RAIN_ANY)) - || (gBattleMons[bank2].ability == ABILITY_CHLOROPHYLL && (gBattleWeather & WEATHER_SUN_ANY))) - bank2SpeedMultiplier = 2; - else - bank2SpeedMultiplier = 1; - } - else - { - bank1SpeedMultiplier = 1; - bank2SpeedMultiplier = 1; - } - - // Calculate adjusted speed for first mon. - bank1AdjustedSpeed = (gBattleMons[bank1].speed * bank1SpeedMultiplier) - * gStatStageRatios[gBattleMons[bank1].statStages[STAT_STAGE_SPEED]][0] / gStatStageRatios[gBattleMons[bank1].statStages[STAT_STAGE_SPEED]][1]; - - if (gBattleMons[bank1].item == ITEM_ENIGMA_BERRY) - { - heldItemEffect = gEnigmaBerries[bank1].holdEffect; - heldItemEffectParam = gEnigmaBerries[bank1].holdEffectParam; - } - else - { - heldItemEffect = ItemId_GetHoldEffect(gBattleMons[bank1].item); - heldItemEffectParam = ItemId_GetHoldEffectParam(gBattleMons[bank1].item); - } - - // Only give badge speed boost to the player's mon. - if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && FlagGet(FLAG_BADGE03_GET) && GetBattlerSide(bank1) == 0) - bank1AdjustedSpeed = (bank1AdjustedSpeed * 110) / 100; - - if (heldItemEffect == HOLD_EFFECT_MACHO_BRACE) - bank1AdjustedSpeed /= 2; - - if (gBattleMons[bank1].status1 & STATUS_PARALYSIS) - bank1AdjustedSpeed /= 4; - - if (heldItemEffect == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (heldItemEffectParam * 0xFFFF) / 100) - bank1AdjustedSpeed = UINT_MAX; - - // Calculate adjusted speed for second mon. - bank2AdjustedSpeed = gBattleMons[bank2].speed * bank2SpeedMultiplier - * gStatStageRatios[gBattleMons[bank2].statStages[STAT_STAGE_SPEED]][0] / gStatStageRatios[gBattleMons[bank2].statStages[STAT_STAGE_SPEED]][1]; - - if (gBattleMons[bank2].item == ITEM_ENIGMA_BERRY) - { - heldItemEffect = gEnigmaBerries[bank2].holdEffect; - heldItemEffectParam = gEnigmaBerries[bank2].holdEffectParam; - } - else - { - heldItemEffect = ItemId_GetHoldEffect(gBattleMons[bank2].item); - heldItemEffectParam = ItemId_GetHoldEffectParam(gBattleMons[bank2].item); - } - - // Only give badge speed boost to the player's mon. - if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && FlagGet(FLAG_BADGE03_GET) && GetBattlerSide(bank2) == 0) - { - bank2AdjustedSpeed = (bank2AdjustedSpeed * 110) / 100; - } - - if (heldItemEffect == HOLD_EFFECT_MACHO_BRACE) - bank2AdjustedSpeed /= 2; - - if (gBattleMons[bank2].status1 & STATUS_PARALYSIS) - bank2AdjustedSpeed /= 4; - - if (heldItemEffect == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (heldItemEffectParam * 0xFFFF) / 100) - bank2AdjustedSpeed = UINT_MAX; - - if (ignoreMovePriorities) - { - bank1Move = MOVE_NONE; - bank2Move = MOVE_NONE; - } - else - { - if (gActionForBanks[bank1] == 0) - { - if (gProtectStructs[bank1].onlyStruggle) - bank1Move = MOVE_STRUGGLE; - else - bank1Move = gBattleMons[bank1].moves[ewram1608Carr(bank1)]; - } - else - bank1Move = MOVE_NONE; - - if (gActionForBanks[bank2] == 0) - { - if (gProtectStructs[bank2].onlyStruggle) - bank2Move = MOVE_STRUGGLE; - else - bank2Move = gBattleMons[bank2].moves[ewram1608Carr(bank2)]; - } - else - bank2Move = MOVE_NONE; - } - - if (gBattleMoves[bank1Move].priority != 0 || gBattleMoves[bank2Move].priority != 0) - { - if (gBattleMoves[bank1Move].priority == gBattleMoves[bank2Move].priority) - { - if (bank1AdjustedSpeed == bank2AdjustedSpeed && (Random() & 1)) - strikesFirst = 2; - else if (bank1AdjustedSpeed < bank2AdjustedSpeed) - strikesFirst = 1; - } - else if (gBattleMoves[bank1Move].priority < gBattleMoves[bank2Move].priority) - strikesFirst = 1; - } - else - { - if (bank1AdjustedSpeed == bank2AdjustedSpeed && (Random() & 1)) - strikesFirst = 2; - else if (bank1AdjustedSpeed < bank2AdjustedSpeed) - strikesFirst = 1; - } - - return strikesFirst; -} - -void SetActionsAndBanksTurnOrder(void) -{ - s32 var = 0; - s32 i, j; - - if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - gActionsByTurnOrder[var] = gActionForBanks[gActiveBattler]; - gBanksByTurnOrder[var] = gActiveBattler; - var++; - } - } - else - { - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (gActionForBanks[gActiveBattler] == ACTION_RUN) - { - var = 5; - break; - } - } - } - else - { - if (gActionForBanks[0] == ACTION_RUN) - { - gActiveBattler = 0; - var = 5; - } - } - - if (var == 5) - { - gActionsByTurnOrder[0] = gActionForBanks[gActiveBattler]; - gBanksByTurnOrder[0] = gActiveBattler; - var = 1; - for (i = 0; i < gBattlersCount; i++) - { - if (i != gActiveBattler) - { - gActionsByTurnOrder[var] = gActionForBanks[i]; - gBanksByTurnOrder[var] = i; - var++; - } - } - gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; - eFocusPunchBattler = 0; - return; - } - else - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (gActionForBanks[gActiveBattler] == ACTION_USE_ITEM || gActionForBanks[gActiveBattler] == ACTION_SWITCH) - { - gActionsByTurnOrder[var] = gActionForBanks[gActiveBattler]; - gBanksByTurnOrder[var] = gActiveBattler; - var++; - } - } - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (gActionForBanks[gActiveBattler] != ACTION_USE_ITEM && gActionForBanks[gActiveBattler] != ACTION_SWITCH) - { - gActionsByTurnOrder[var] = gActionForBanks[gActiveBattler]; - gBanksByTurnOrder[var] = gActiveBattler; - var++; - } - } - for (i = 0; i < gBattlersCount - 1; i++) - { - for (j = i + 1; j < gBattlersCount; j++) - { - u8 bank1 = gBanksByTurnOrder[i]; - u8 bank2 = gBanksByTurnOrder[j]; - if (gActionsByTurnOrder[i] != ACTION_USE_ITEM - && gActionsByTurnOrder[j] != ACTION_USE_ITEM - && gActionsByTurnOrder[i] != ACTION_SWITCH - && gActionsByTurnOrder[j] != ACTION_SWITCH) - { - if (GetWhoStrikesFirst(bank1, bank2, FALSE)) - SwapTurnOrder(i, j); - } - } - } - } - } - - gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; - eFocusPunchBattler = 0; -} - -static void TurnValuesCleanUp(bool8 var0) -{ - s32 i; - u8 *dataPtr; - - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (var0) - { - gProtectStructs[gActiveBattler].protected = 0; - gProtectStructs[gActiveBattler].endured = 0; - } - else - { - dataPtr = (u8*)(&gProtectStructs[gActiveBattler]); - for (i = 0; i < sizeof(struct ProtectStruct); i++) - dataPtr[i] = 0; - - if (gDisableStructs[gActiveBattler].isFirstTurn) - gDisableStructs[gActiveBattler].isFirstTurn--; - - if (gDisableStructs[gActiveBattler].rechargeCounter) - { - gDisableStructs[gActiveBattler].rechargeCounter--; - if (gDisableStructs[gActiveBattler].rechargeCounter == 0) - gBattleMons[gActiveBattler].status2 &= ~(STATUS2_RECHARGE); - } - } - - if (gDisableStructs[gActiveBattler].substituteHP == 0) - gBattleMons[gActiveBattler].status2 &= ~(STATUS2_SUBSTITUTE); - } - - gSideTimers[0].followmeTimer = 0; - gSideTimers[1].followmeTimer = 0; -} - -void SpecialStatusesClear(void) -{ - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - s32 i; - u8 *dataPtr = (u8*)(&gSpecialStatuses[gActiveBattler]); - - for (i = 0; i < sizeof(struct SpecialStatus); i++) - dataPtr[i] = 0; - } -} - -void CheckFocusPunch_ClearVarsBeforeTurnStarts(void) -{ - if (!(gHitMarker & HITMARKER_RUN)) - { - while (eFocusPunchBattler < gBattlersCount) - { - gActiveBattler = gBankAttacker = eFocusPunchBattler; - eFocusPunchBattler++; - if (gChosenMovesByBanks[gActiveBattler] == MOVE_FOCUS_PUNCH - && !(gBattleMons[gActiveBattler].status1 & STATUS_SLEEP) - && !(gDisableStructs[gBankAttacker].truantCounter) - && !(gProtectStructs[gActiveBattler].onlyStruggle)) - { - BattleScriptExecute(BattleScript_FocusPunchSetUp); - return; - } - } - } - - TryClearRageStatuses(); - gCurrentTurnActionNumber = 0; - { - // something stupid needed to match - u8 zero; - gCurrentActionFuncId = gActionsByTurnOrder[(zero = 0)]; - } - - gDynamicBasePower = 0; - gBattleStruct->dynamicMoveType = 0; - gBattleMainFunc = RunTurnActionsFunctions; - gBattleCommunication[3] = 0; - gBattleCommunication[4] = 0; - eMultihitMoveEffect = 0; - ewram17130 = 0; -} - -static void RunTurnActionsFunctions(void) -{ - if (gBattleOutcome != 0) - gCurrentActionFuncId = 12; - - gBattleStruct->unk16057 = gCurrentTurnActionNumber; - gUnknown_081FA640[gCurrentActionFuncId](); - - if (gCurrentTurnActionNumber >= gBattlersCount) // everyone did their actions, turn finished - { - gHitMarker &= ~(HITMARKER_x100000); - gBattleMainFunc = gUnknown_081FA678[gBattleOutcome & 0x7F]; - } - else - { - if (gBattleStruct->unk16057 != gCurrentTurnActionNumber) // action turn has been done, clear hitmarker bits for another bank - { - gHitMarker &= ~(HITMARKER_NO_ATTACKSTRING); - gHitMarker &= ~(HITMARKER_UNABLE_TO_USE_MOVE); - } - } -} - -void HandleEndTurn_BattleWon(void) -{ - gCurrentActionFuncId = 0; - - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - gBattleTextBuff1[0] = gBattleOutcome; - gBankAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - gBattlescriptCurrInstr = BattleScript_LinkBattleWonOrLost; - gBattleOutcome &= ~(OUTCOME_LINK_BATTLE_RUN); - } - else if (gBattleTypeFlags & (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER)) - { - gBattlescriptCurrInstr = gUnknown_081D8E0D; - } - else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && !(gBattleTypeFlags & BATTLE_TYPE_LINK)) - { - BattleStopLowHpSound(); - gBattlescriptCurrInstr = BattleScript_LocalTrainerBattleWon; - - switch (gTrainers[gTrainerBattleOpponent].trainerClass) - { - case TRAINER_CLASS_ELITE_FOUR: - case TRAINER_CLASS_CHAMPION: - PlayBGM(MUS_KACHI5); - break; - case TRAINER_CLASS_TEAM_AQUA: - case TRAINER_CLASS_TEAM_MAGMA: - case TRAINER_CLASS_AQUA_ADMIN: - case TRAINER_CLASS_AQUA_LEADER: - case TRAINER_CLASS_MAGMA_ADMIN: - case TRAINER_CLASS_MAGMA_LEADER: - PlayBGM(MUS_KACHI4); - break; - case TRAINER_CLASS_LEADER: - PlayBGM(MUS_KACHI3); - break; - default: - PlayBGM(MUS_KACHI1); - break; - } - } - else - { - gBattlescriptCurrInstr = BattleScript_PayDayMoneyAndPickUpItems; - } - - gBattleMainFunc = HandleEndTurn_FinishBattle; -} - -void HandleEndTurn_BattleLost(void) -{ - gCurrentActionFuncId = 0; - - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - gBattleTextBuff1[0] = gBattleOutcome; - gBankAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - gBattlescriptCurrInstr = BattleScript_LinkBattleWonOrLost; - gBattleOutcome &= ~(OUTCOME_LINK_BATTLE_RUN); - } - else - { - gBattlescriptCurrInstr = BattleScript_LocalBattleLost; - } - - gBattleMainFunc = HandleEndTurn_FinishBattle; -} - -void HandleEndTurn_RanFromBattle(void) -{ - gCurrentActionFuncId = 0; - - switch (gProtectStructs[gBankAttacker].fleeFlag) - { - default: - gBattlescriptCurrInstr = BattleScript_GotAwaySafely; - break; - case 1: - gBattlescriptCurrInstr = BattleScript_SmokeBallEscape; - break; - case 2: - gBattlescriptCurrInstr = BattleScript_RanAwayUsingMonAbility; - break; - } - - gBattleMainFunc = HandleEndTurn_FinishBattle; -} - -void HandleEndTurn_MonFled(void) -{ - gCurrentActionFuncId = 0; - - PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBankAttacker, gBattlerPartyIndexes[gBankAttacker]); - gBattlescriptCurrInstr = BattleScript_WildMonFled; - - gBattleMainFunc = HandleEndTurn_FinishBattle; -} - -void HandleEndTurn_FinishBattle(void) -{ - if (gCurrentActionFuncId == 0xB || gCurrentActionFuncId == 0xC) - { - if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK - | BATTLE_TYPE_FIRST_BATTLE - | BATTLE_TYPE_SAFARI - | BATTLE_TYPE_EREADER_TRAINER - | BATTLE_TYPE_WALLY_TUTORIAL - | BATTLE_TYPE_BATTLE_TOWER))) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - { - if (gBattleResults.poke1Species == SPECIES_NONE) - { - gBattleResults.poke1Species = gBattleMons[gActiveBattler].species; - StringCopy(gBattleResults.pokeString1, gBattleMons[gActiveBattler].nickname); - } - else - { - gBattleResults.opponentSpecies = gBattleMons[gActiveBattler].species; - StringCopy(gBattleResults.pokeString2, gBattleMons[gActiveBattler].nickname); - } - } - } - PutPokemonTodayCaughtOnAir(); - } - - BeginFastPaletteFade(3); - FadeOutMapMusic(5); - gBattleMainFunc = FreeResetData_ReturnToOvOrDoEvolutions; - gCB2_AfterEvolution = BattleMainCB2; - } - else - { - if (gBattleExecBuffer == 0) - gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); - } -} - -static void FreeResetData_ReturnToOvOrDoEvolutions(void) -{ - if (!gPaletteFade.active) - { - ResetSpriteData(); - if (gLeveledUpInBattle == 0 || gBattleOutcome != BATTLE_WON) - { - gBattleMainFunc = ReturnFromBattleToOverworld; - return; - } - else - { - gBattleMainFunc = TryEvolvePokemon; - } - } -} - -void TryEvolvePokemon(void) -{ - s32 i; - - while (gLeveledUpInBattle != 0) - { - for (i = 0; i < 6; i++) - { - if (gLeveledUpInBattle & gBitTable[i]) - { - u16 species; - u8 levelUpBits = gLeveledUpInBattle; - - levelUpBits &= ~(gBitTable[i]); - gLeveledUpInBattle = levelUpBits; - - species = GetEvolutionTargetSpecies(&gPlayerParty[i], 0, levelUpBits); - if (species != SPECIES_NONE) - { - gBattleMainFunc = WaitForEvoSceneToFinish; - EvolutionScene(&gPlayerParty[i], species, 0x81, i); - return; - } - } - } - } - - gBattleMainFunc = ReturnFromBattleToOverworld; -} - -static void WaitForEvoSceneToFinish(void) -{ - if (gMain.callback2 == BattleMainCB2) - gBattleMainFunc = TryEvolvePokemon; -} - -static void ReturnFromBattleToOverworld(void) -{ - if (!(gBattleTypeFlags & BATTLE_TYPE_LINK)) - { - RandomlyGivePartyPokerus(gPlayerParty); - PartySpreadPokerus(gPlayerParty); - } - - if (gBattleTypeFlags & BATTLE_TYPE_LINK && gReceivedRemoteLinkPlayers != 0) - return; - - gSpecialVar_Result = gBattleOutcome; - gMain.inBattle = 0; - gMain.callback1 = gPreBattleCallback1; - - if (gBattleTypeFlags & BATTLE_TYPE_ROAMER) - { - UpdateRoamerHPStatus(&gEnemyParty[0]); - if (gBattleOutcome == BATTLE_WON || gBattleOutcome == BATTLE_CAUGHT) - SetRoamerInactive(); - } - - m4aSongNumStop(0x5A); - SetMainCallback2(gMain.savedCallback); -} - -void RunBattleScriptCommands_PopCallbacksStack(void) -{ - if (gCurrentActionFuncId == 0xB || gCurrentActionFuncId == 0xC) - { - if (B_FUNCTION_STACK->size != 0) - B_FUNCTION_STACK->size--; - gBattleMainFunc = B_FUNCTION_STACK->ptr[B_FUNCTION_STACK->size]; - } - else - { - if (gBattleExecBuffer == 0) - gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); - } -} - -void RunBattleScriptCommands(void) -{ - if (gBattleExecBuffer == 0) - gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); -} - -void HandleAction_UseMove(void) -{ - u8 side; - u8 var = 4; - - gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; - - if (ewram160A6 & gBitTable[gBankAttacker]) - { - gCurrentActionFuncId = ACTION_FINISHED; - return; - } - - gCritMultiplier = 1; - eDmgMultiplier = 1; - ewram160E7 = 0; - gMoveResultFlags = 0; - gMultiHitCounter = 0; - gBattleCommunication[6] = 0; - gCurrMovePos = gUnknown_02024BE5 = ewram1608Carr(gBankAttacker); - - // choose move - if (gProtectStructs[gBankAttacker].onlyStruggle) - { - gProtectStructs[gBankAttacker].onlyStruggle = 0; - gCurrentMove = gChosenMove = MOVE_STRUGGLE; - gHitMarker |= HITMARKER_NO_PPDEDUCT; - ewram16010arr(gBankAttacker) = GetMoveTarget(MOVE_STRUGGLE, 0); - } - else if (gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS || gBattleMons[gBankAttacker].status2 & STATUS2_RECHARGE) - { - gCurrentMove = gChosenMove = gLockedMoves[gBankAttacker]; - } - // encore forces you to use the same move - else if (gDisableStructs[gBankAttacker].encoredMove != MOVE_NONE - && gDisableStructs[gBankAttacker].encoredMove == gBattleMons[gBankAttacker].moves[gDisableStructs[gBankAttacker].encoredMovePos]) - { - gCurrentMove = gChosenMove = gDisableStructs[gBankAttacker].encoredMove; - gCurrMovePos = gUnknown_02024BE5 = gDisableStructs[gBankAttacker].encoredMovePos; - ewram16010arr(gBankAttacker) = GetMoveTarget(gCurrentMove, 0); - } - // check if the encored move wasn't overwritten - else if (gDisableStructs[gBankAttacker].encoredMove != MOVE_NONE - && gDisableStructs[gBankAttacker].encoredMove != gBattleMons[gBankAttacker].moves[gDisableStructs[gBankAttacker].encoredMovePos]) - { - gCurrMovePos = gUnknown_02024BE5 = gDisableStructs[gBankAttacker].encoredMovePos; - gCurrentMove = gChosenMove = gBattleMons[gBankAttacker].moves[gCurrMovePos]; - gDisableStructs[gBankAttacker].encoredMove = MOVE_NONE; - gDisableStructs[gBankAttacker].encoredMovePos = 0; - gDisableStructs[gBankAttacker].encoreTimer1 = 0; - ewram16010arr(gBankAttacker) = GetMoveTarget(gCurrentMove, 0); - } - else if (gBattleMons[gBankAttacker].moves[gCurrMovePos] != gChosenMovesByBanks[gBankAttacker]) - { - gCurrentMove = gChosenMove = gBattleMons[gBankAttacker].moves[gCurrMovePos]; - ewram16010arr(gBankAttacker) = GetMoveTarget(gCurrentMove, 0); - } - else - { - gCurrentMove = gChosenMove = gBattleMons[gBankAttacker].moves[gCurrMovePos]; - } - - if (GetBattlerSide(gBankAttacker) == B_SIDE_PLAYER) - gBattleResults.lastUsedMove = gCurrentMove; - else - gBattleResults.opponentMove = gCurrentMove; - - // choose target - side = GetBattlerSide(gBankAttacker) ^ BIT_SIDE; - if (gSideTimers[side].followmeTimer != 0 - && gBattleMoves[gCurrentMove].target == MOVE_TARGET_SELECTED - && GetBattlerSide(gBankAttacker) != GetBattlerSide(gSideTimers[side].followmeTarget) - && gBattleMons[gSideTimers[side].followmeTarget].hp != 0) - { - gBankTarget = gSideTimers[side].followmeTarget; - } - else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - && gSideTimers[side].followmeTimer == 0 - && (gBattleMoves[gCurrentMove].power != 0 - || gBattleMoves[gCurrentMove].target != MOVE_TARGET_x10) - && gBattleMons[ewram16010arr(gBankAttacker)].ability != ABILITY_LIGHTNING_ROD - && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) - { - side = GetBattlerSide(gBankAttacker); - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (side != GetBattlerSide(gActiveBattler) - && ewram16010arr(gBankAttacker) != gActiveBattler - && gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD - && BankGetTurnOrder(gActiveBattler) < var) - { - var = BankGetTurnOrder(gActiveBattler); - } - } - if (var == 4) - { - if (gBattleMoves[gChosenMove].target & MOVE_TARGET_RANDOM) - { - if (GetBattlerSide(gBankAttacker) == B_SIDE_PLAYER) - { - if (Random() & 1) - gBankTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - else - gBankTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); - } - else - { - if (Random() & 1) - gBankTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - else - gBankTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); - } - } - else - { - gBankTarget = ewram16010arr(gBankAttacker); - } - - if (gAbsentBattlerFlags & gBitTable[gBankTarget]) - { - if (GetBattlerSide(gBankAttacker) != GetBattlerSide(gBankTarget)) - { - gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankTarget) ^ BIT_FLANK); - } - else - { - gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ BIT_SIDE); - if (gAbsentBattlerFlags & gBitTable[gBankTarget]) - gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankTarget) ^ BIT_FLANK); - } - } - } - else - { - gActiveBattler = gBanksByTurnOrder[var]; - RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability); - gSpecialStatuses[gActiveBattler].lightningRodRedirected = 1; - gBankTarget = gActiveBattler; - } - } - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && gBattleMoves[gChosenMove].target & MOVE_TARGET_RANDOM) - { - if (GetBattlerSide(gBankAttacker) == B_SIDE_PLAYER) - { - if (Random() & 1) - gBankTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - else - gBankTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); - } - else - { - if (Random() & 1) - gBankTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - else - gBankTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); - } - - if (gAbsentBattlerFlags & gBitTable[gBankTarget] - && GetBattlerSide(gBankAttacker) != GetBattlerSide(gBankTarget)) - { - gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankTarget) ^ BIT_FLANK); - } - } - else - { - gBankTarget = ewram16010arr(gBankAttacker); - if (gAbsentBattlerFlags & gBitTable[gBankTarget]) - { - if (GetBattlerSide(gBankAttacker) != GetBattlerSide(gBankTarget)) - { - gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankTarget) ^ BIT_FLANK); - } - else - { - gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ BIT_SIDE); - if (gAbsentBattlerFlags & gBitTable[gBankTarget]) - gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankTarget) ^ BIT_FLANK); - } - } - } - - gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; - gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; -} - -void HandleAction_Switch(void) -{ - gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gActionSelectionCursor[gBankAttacker] = 0; - gMoveSelectionCursor[gBankAttacker] = 0; - - PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBankAttacker, ewram16064arr(gBankAttacker)) - - ewram16003 = gBankAttacker; - gBattlescriptCurrInstr = BattleScript_ActionSwitch; - gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; - - if (gBattleResults.unk2 < 255) - gBattleResults.unk2++; -} - -void HandleAction_UseItem(void) -{ - gBankAttacker = gBankTarget = gBanksByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gDisableStructs[gBankAttacker].furyCutterCounter = 0; - gLastUsedItem = gBattleBufferB[gBankAttacker][1] | (gBattleBufferB[gBankAttacker][2] << 8); - - if (gLastUsedItem <= ITEM_PREMIER_BALL) // is ball - { - gBattlescriptCurrInstr = gBattlescriptsForBallThrow[gLastUsedItem]; - } - else if (gLastUsedItem == ITEM_POKE_DOLL || gLastUsedItem == ITEM_FLUFFY_TAIL) - { - gBattlescriptCurrInstr = gBattlescriptsForRunningByItem[0]; - } - else if (GetBattlerSide(gBankAttacker) == B_SIDE_PLAYER) - { - gBattlescriptCurrInstr = gBattlescriptsForUsingItem[0]; - } - else - { - - switch (ewram160D8((ewram16003 = gBankAttacker))) - { - case AI_ITEM_FULL_RESTORE: - case AI_ITEM_HEAL_HP: - break; - case AI_ITEM_CURE_CONDITION: - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - if (ewram160DA(gBankAttacker) & 1) - { - if (ewram160DA(gBankAttacker) & 0x3E) - gBattleCommunication[MULTISTRING_CHOOSER] = 5; - } - else - { - while (!(ewram160DA(gBankAttacker) & 1)) - { - ewram160DA(gBankAttacker) >>= 1; - gBattleCommunication[MULTISTRING_CHOOSER]++; - } - } - break; - case AI_ITEM_X_STAT: - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - if (ewram160DA(gBankAttacker) & 0x80) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 5; - } - else - { - PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK) - PREPARE_STRING_BUFFER(gBattleTextBuff2, 0xD2) - - while (!(ewram160DA(gBankAttacker) & 1)) - { - ewram160DA(gBankAttacker) >>= 1; - gBattleTextBuff1[2]++; - } - - ewram160A4 = gBattleTextBuff1[2] + 14; - ewram160A5 = 0; - } - break; - case AI_ITEM_GUARD_SPECS: - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - break; - } - - gBattlescriptCurrInstr = gBattlescriptsForUsingItem[ewram160D8(gBankAttacker)]; - } - gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; -} - -bool8 TryRunFromBattle(u8 bank) -{ - bool8 effect = FALSE; - u8 holdEffect; - u8 speedVar; - - if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY) - holdEffect = gEnigmaBerries[bank].holdEffect; - else - holdEffect = ItemId_GetHoldEffect(gBattleMons[bank].item); - - gStringBank = bank; - - if (holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN) - { - gLastUsedItem = gBattleMons[bank].item ; - gProtectStructs[bank].fleeFlag = 1; - effect++; - } - else if (gBattleMons[bank].ability == ABILITY_RUN_AWAY) - { - gLastUsedAbility = ABILITY_RUN_AWAY; - gProtectStructs[bank].fleeFlag = 2; - effect++; - } - else - { - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - if (gBattleMons[bank].speed < gBattleMons[bank ^ BIT_SIDE].speed) - { - speedVar = (gBattleMons[bank].speed * 128) / (gBattleMons[bank ^ BIT_SIDE].speed) + (ewram16078 * 30); - if (speedVar > (Random() & 0xFF)) - effect++; - } - else // same speed or faster - { - effect++; - } - } - - ewram16078++; - } - - if (effect) - { - gCurrentTurnActionNumber = gBattlersCount; - gBattleOutcome = BATTLE_RAN; - } - - return effect; -} - -void HandleAction_Run(void) -{ - gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; - - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - gCurrentTurnActionNumber = gBattlersCount; - - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - { - if (gActionForBanks[gActiveBattler] == ACTION_RUN) - gBattleOutcome |= BATTLE_LOST; - } - else - { - if (gActionForBanks[gActiveBattler] == ACTION_RUN) - gBattleOutcome |= BATTLE_WON; - } - } - - gBattleOutcome |= OUTCOME_LINK_BATTLE_RUN; - } - else - { - if (GetBattlerSide(gBankAttacker) == B_SIDE_PLAYER) - { - if (!TryRunFromBattle(gBankAttacker)) // failed to run away - { - gBattleMons[gBankAttacker].status2 &= ~STATUS2_DESTINY_BOND; - gBattleCommunication[MULTISTRING_CHOOSER] = 3; - gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString; - gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; - } - } - else - { - if (gBattleMons[gBankAttacker].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString; - gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; - } - else - { - gCurrentTurnActionNumber = gBattlersCount; - gBattleOutcome = BATTLE_POKE_FLED; - } - } - } -} - -void HandleAction_WatchesCarefully(void) -{ - gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gBattlescriptCurrInstr = gBattlescriptsForSafariActions[0]; - gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; -} - -void HandleAction_SafariZoneBallThrow(void) -{ - gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gNumSafariBalls--; - gLastUsedItem = ITEM_SAFARI_BALL; - gBattlescriptCurrInstr = gBattlescriptsForBallThrow[ITEM_SAFARI_BALL]; - gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; -} - -void HandleAction_ThrowPokeblock(void) -{ - gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gBattleCommunication[MULTISTRING_CHOOSER] = gBattleBufferB[gBankAttacker][1] - 1; - gLastUsedItem = gBattleBufferB[gBankAttacker][2]; - - if (ewram16087 < 3) - ewram16087++; - if (ewram16088 > 1) - { - if (ewram16088 < gUnknown_081FA70C[ewram16087][gBattleCommunication[MULTISTRING_CHOOSER]]) - ewram16088 = 1; - else - ewram16088 -= gUnknown_081FA70C[ewram16087][gBattleCommunication[MULTISTRING_CHOOSER]]; - } - - gBattlescriptCurrInstr = gBattlescriptsForSafariActions[2]; - gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; -} - -void HandleAction_GoNear(void) -{ - gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - - ewram16089 += gUnknown_081FA71B[ewram16086]; - if (ewram16089 > 20) - ewram16089 = 20; - - ewram16088 += gUnknown_081FA71F[ewram16086]; - if (ewram16088 > 20) - ewram16088 = 20; - - if (ewram16086 < 3) - { - ewram16086++; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - else - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - gBattlescriptCurrInstr = gBattlescriptsForSafariActions[1]; - gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; -} - -void HandleAction_SafriZoneRun(void) -{ - gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; - PlaySE(SE_NIGERU); - gCurrentTurnActionNumber = gBattlersCount; - gBattleOutcome = BATTLE_RAN; -} - -void HandleAction_Action9(void) -{ - gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - - PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBankAttacker, gBattlerPartyIndexes[gBankAttacker]) - - gBattlescriptCurrInstr = gBattlescriptsForSafariActions[3]; - gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; - gActionsByTurnOrder[1] = ACTION_FINISHED; -} - -void HandleAction_Action11(void) -{ - if (!HandleFaintedMonActions()) - { - ewram16059 = 0; - gCurrentActionFuncId = ACTION_FINISHED; - } -} - -void HandleAction_NothingIsFainted(void) -{ - gCurrentTurnActionNumber++; - gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber]; - gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED - | HITMARKER_NO_PPDEDUCT | HITMARKER_IGNORE_SAFEGUARD | HITMARKER_IGNORE_ON_AIR - | HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000 - | HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT - | HITMARKER_x8000000 | HITMARKER_x4000000); -} - -void HandleAction_ActionFinished(void) -{ - gCurrentTurnActionNumber++; - gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber]; - SpecialStatusesClear(); - gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED - | HITMARKER_NO_PPDEDUCT | HITMARKER_IGNORE_SAFEGUARD | HITMARKER_IGNORE_ON_AIR - | HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000 - | HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT - | HITMARKER_x8000000 | HITMARKER_x4000000); - - gBattleMoveDamage = 0; - ewram16002 = 0; - ewram160A1 = 0; - gLastLandedMoves[gBankAttacker] = 0; - gLastHitByType[gBankAttacker] = 0; - eDynamicMoveType = 0; - gDynamicBasePower = 0; - ewram1600C = 0; - gBattleCommunication[3] = 0; - gBattleCommunication[4] = 0; - eMultihitMoveEffect = 0; - ewram17130 = 0; -} diff --git a/src/battle/battle_4.c b/src/battle/battle_4.c deleted file mode 100644 index a84e16116..000000000 --- a/src/battle/battle_4.c +++ /dev/null @@ -1,15941 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_message.h" -#include "battle_string_ids.h" -#include "battle_script_commands.h" -#include "battle_util.h" -#include "constants/battle_move_effects.h" -#include "constants/moves.h" -#include "constants/abilities.h" -#include "item.h" -#include "constants/items.h" -#include "data2.h" -#include "constants/hold_effects.h" -#include "random.h" -#include "rom3.h" -#include "constants/species.h" -#include "pokemon.h" -#include "text.h" -#include "palette.h" -#include "main.h" -#include "constants/songs.h" -#include "sound.h" -#include "task.h" -#include "decompress.h" -#include "pokemon_summary_screen.h" -#include "naming_screen.h" -#include "ewram.h" -#include "util.h" - -// TODO: put this into battle_controllers.h - -#define RET_VALUE_LEVELLED_UP 11 - -enum -{ - CONTROLLER_GETMONDATA, - CONTROLLER_GETRAWMONDATA, - CONTROLLER_SETMONDATA, - CONTROLLER_SETRAWMONDATA, - CONTROLLER_LOADMONSPRITE, - CONTROLLER_SWITCHINANIM, - CONTROLLER_RETURNMONTOBALL, - CONTROLLER_DRAWTRAINERPIC, - CONTROLLER_TRAINERSLIDE, - CONTROLLER_TRAINERSLIDEBACK, - CONTROLLER_FAINTANIMATION, - CONTROLLER_PALETTEFADE, - CONTROLLER_SUCCESSBALLTHROWANIM, - CONTROLLER_BALLTHROWANIM, - CONTROLLER_PAUSE, - CONTROLLER_MOVEANIMATION, - CONTROLLER_PRINTSTRING, - CONTROLLER_PRINTSTRINGPLAYERONLY, - CONTROLLER_CHOOSEACTION, - CONTROLLER_UNKNOWNYESNOBOX, - CONTROLLER_CHOOSEMOVE, - CONTROLLER_OPENBAG, - CONTROLLER_CHOOSEPOKEMON, - CONTROLLER_23, - CONTROLLER_HEALTHBARUPDATE, - CONTROLLER_EXPUPDATE, - CONTROLLER_STATUSICONUPDATE, - CONTROLLER_STATUSANIMATION, - CONTROLLER_STATUSXOR, - CONTROLLER_DATATRANSFER, - CONTROLLER_DMA3TRANSFER, - CONTROLLER_31, - CONTROLLER_32, - CONTROLLER_TWORETURNVALUES, - CONTROLLER_CHOSENMONRETURNVALUE, - CONTROLLER_ONERETURNVALUE, - CONTROLLER_ONERETURNVALUE_DUPLICATE, - CONTROLLER_37, - CONTROLLER_38, - CONTROLLER_39, - CONTROLLER_40, - CONTROLLER_HITANIMATION, - CONTROLLER_42, - CONTROLLER_EFFECTIVENESSSOUND, - CONTROLLER_PLAYFANFAREORBGM, - CONTROLLER_FAINTINGCRY, - CONTROLLER_INTROSLIDE, - CONTROLLER_INTROTRAINERBALLTHROW, - CONTROLLER_DRAWPARTYSTATUSSUMMARY, - CONTROLLER_49, - CONTROLLER_50, - CONTROLLER_SPRITEINVISIBILITY, - CONTROLLER_BATTLEANIMATION, - CONTROLLER_LINKSTANDBYMSG, - CONTROLLER_RESETACTIONMOVESELECTION, - CONTROLLER_55, - /*new controllers should go here*/ - CONTROLLER_TERMINATOR_NOP, - CONTROLLER_CMDS_COUNT -}; - -//extern needed variables -extern u8 gUnknown_02023A14_50; -extern u8 gCritMultiplier; -extern s32 gBattleMoveDamage; -extern u32 gStatuses3[MAX_BATTLERS_COUNT]; -extern u16 gBattleTypeFlags; -extern const struct BaseStats gBaseStats[]; -extern struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern u8 gActiveBattler; -extern u32 gBattleExecBuffer; -extern u8 gBattlersCount; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u8 gBanksByTurnOrder[MAX_BATTLERS_COUNT]; -extern u8 gActionsByTurnOrder[MAX_BATTLERS_COUNT]; -extern u16 gCurrentMove; -extern u8 gLastUsedAbility; -extern u16 gBattleWeather; -extern u8 gStringBank; -extern u8 gEffectBank; -extern u8 gAbsentBattlerFlags; -extern u8 gMultiHitCounter; -extern u16 gLastUsedMove[4]; -extern u16 gLockedMoves[4]; -extern u16 gChosenMovesByBanks[4]; -extern u16 gSideAffecting[2]; -extern u16 gPauseCounterBattle; -extern u16 gPaydayMoney; -extern u16 gRandomTurnNumber; -extern u8 gBattleOutcome; -extern u8 gBattleTerrain; -extern u16 gTrainerBattleOpponent; -extern u8 gBankAttacker; -extern u8 gBankTarget; -extern const u8* gBattlescriptCurrInstr; -extern u8 gCurrMovePos; -extern u8 gCurrentActionFuncId; -extern u32 gHitMarker; -extern u8 gMoveResultFlags; -extern u8 gBattleCommunication[]; -extern u16 gLastLandedMoves[4]; -extern u16 gLastHitByType[4]; -extern u8 gStringBank; -extern u16 gDynamicBasePower; -extern const u8 gTypeEffectiveness[]; -extern u16 gLastUsedItem; -extern u16 gBattleMovePower; -extern s32 gHpDealt; -extern s32 gTakenDmg[MAX_BATTLERS_COUNT]; -extern u8 gTakenDmgBanks[MAX_BATTLERS_COUNT]; -extern const u16 gMissStringIds[]; -extern u8 gSentPokesToOpponent[2]; -extern u8 gBank1; -extern u16 gExpShareExp; -extern u8 gBattleTextBuff1[]; -extern u8 gBattleTextBuff2[]; -extern u8 gBattleTextBuff3[]; -extern u8 gLeveledUpInBattle; -extern void (*gBattleMainFunc)(void); -extern struct Window gUnknown_03004210; -extern const u8 BattleText_YesNo[]; -extern u8 gPlayerPartyCount; -extern u16 gMoveToLearn; //move to learn -extern const u8 gTrainerMoney[]; -extern u16 gRandomMove; -extern u8* gBattleScriptsForMoveEffects[]; -extern u16 gChosenMove; //last used move in battle -extern u8 gBankInMenu; -extern u8 gActionForBanks[4]; -extern u16 gUnknown_02024C2C[4]; //last used moves 2, used by sketch -extern u16 gUnknown_02024C4C[4]; //last used moves by banks, another one -extern u8 gCurrentTurnActionNumber; -extern u16 gTrappingMoves[]; - -extern u8 BattleScript_MoveEffectSleep[]; -extern u8 BattleScript_MoveEffectPoison[]; -extern u8 BattleScript_MoveEffectBurn[]; -extern u8 BattleScript_MoveEffectFreeze[]; -extern u8 BattleScript_MoveEffectParalysis[]; -extern u8 BattleScript_MoveEffectToxic[]; -extern u8 BattleScript_MoveEffectConfusion[]; -extern u8 BattleScript_MoveEffectUproar[]; -extern u8 BattleScript_MoveEffectWrap[]; -extern u8 BattleScript_MoveEffectPayDay[]; -extern u8 BattleScript_MoveEffectRecoil33[]; - -//extern functions -u8 AtkCanceller_UnableToUseMove(void); -void PressurePPLose(u8 bank_atk, u8 bank_def, u16 move); -void CancelMultiTurnMoves(u8 bank); -void BattleScriptPush(const u8* BS_ptr); -void BattleScriptPushCursor(void); -void RecordAbilityBattle(u8 bank, u8 ability); -void RecordItemBattle(u8 bank, u8 holdEffect); -static bool8 IsTwoTurnsMove(u16 move); -static void TrySetDestinyBondToHappen(void); -static void CheckWonderGuardAndLevitate(void); -u8 GetBattlerPosition(u8 bank); -u8 GetBattlerSide(u8 bank); -u8 GetBattleBank(u8 bankValue); -s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 a4, u16 powerOverride, u8 typeOverride, u8 bank_atk, u8 bank_def); -static u8 AttacksThisTurn(u8 bank, u16 move); //Note: returns 1 if it's a charging turn, otherwise 2 -void UndoEffectsAfterFainting(void); -void BattleStopLowHpSound(void); -void PlayBGM(u16 songID); -void MonGainEVs(struct Pokemon*, u16 defeatedSpecies); -extern u8 gBattleBufferB[4][0x200]; -void HandleLowHpMusicChange(struct Pokemon*, u8 bank); -bool8 IsTradedMon(struct Pokemon*); -void BattleScriptPop(void); -void SwitchInClearSetData(void); -u8* ConvertIntToDecimalStringN(u8*, s32, u8, u8); -u8 GetSetPokedexFlag(u16 nationalNum, u8 caseID); -u16 SpeciesToNationalPokedexNum(u16 species); -u8 sub_803FC34(u8 bank); -u16 sub_803FBFC(u8 a); -u8 GetBattlerAtPosition(u8 ID); -void sub_8012258(u8); -//MonTryLearningNewMove teach poke a move -u16 GiveMoveToBattleMon(struct BattlePokemon *mon, u16 move); -void IncrementGameStat(u8 index); -u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale); -u16 GetPokedexHeightWeight(u16 national_num, u8 heightweight); -u8 MenuCursor_Create814A5C0(u8 a1, u16 a2, u8 a3, u16 a4, u8 a5); -void DestroyMenuCursor(void); -void sub_802BC6C(void); -u8 sub_809FA30(void); -bool32 IsHMMove2(u16 move); -void sub_802BBD4(u8 r0, u8 r1, u8 r2, u8 r3, u8 sp0); -void nullsub_6(void); -void ReshowBattleScreenAfterMenu(void); -void BattleMainCB2(void); -void AddMoney(u32* moneySaveblock, u32 to_give); -u8 CountAliveMons(u8 caseID); -void PokemonUseItemEffects(struct Pokemon*, u16 item, u8 partyID, u8 r3, u8 sp); -u8 CanRunFromBattle(void); -u8 GetMoveTarget(u16 move, u8 targetbyte); //get target of move -u8 CastformDataTypeChange(u8 bank); -u8 Overworld_GetMapTypeOfSaveblockLocation(void); -u8 CalculatePlayerPartyCount(void); -u16 Sqrt(u32 num); -u8 sub_809070C(u16 nationalNum, u32 TiD, u32 PiD); //task prepare poke dex display -void MenuCursor_SetPos814A880(u8 a1, u8 a2); -u8 CheckMoveLimitations(u8 bank, u8 unusable_moves, u8 flags); -bool8 IsLinkDoubleBattle(void); -void sub_8094B6C(u8 bank, u8 partyID, u8 r2); - -//extern BattleScripts -extern u8 BattleScript_MoveEnd[]; -extern u8 BattleScript_NoPPForMove[]; -extern u8 BattleScript_MagicCoatBounce[]; -extern u8 BattleScript_TookAttack[]; -extern u8 BattleScript_SnatchedMove[]; -extern u8 BattleScript_Pausex20[]; -extern u8 BattleScript_SubstituteFade[]; -extern u8 BattleScript_HangedOnMsg[]; -extern u8 BattleScript_OneHitKOMsg[]; -extern u8 BattleScript_EnduredMsg[]; -extern u8 BattleScript_PSNPrevention[]; -extern u8 BattleScript_BRNPrevention[]; -extern u8 BattleScript_PRLZPrevention[]; -extern u8 BattleScript_FlinchPrevention[]; -extern u8 BattleScript_StatUp[]; -extern u8 BattleScript_StatDown[]; -extern u8 BattleScript_NoItemSteal[]; -extern u8 BattleScript_ItemSteal[]; -extern u8 BattleScript_RapidSpinAway[]; -extern u8 BattleScript_TargetPRLZHeal[]; -extern u8 BattleScript_KnockedOff[]; -extern u8 BattleScript_LevelUp[]; -extern u8 BattleScript_WrapFree[]; -extern u8 BattleScript_LeechSeedFree[]; -extern u8 BattleScript_SpikesFree[]; -extern u8 BattleScript_ButItFailed[]; -extern u8 BattleScript_ObliviousPreventsAttraction[]; -extern u8 BattleScript_MistProtected[]; -extern u8 BattleScript_AbilityNoStatLoss[]; -extern u8 BattleScript_AbilityNoSpecificStatLoss[]; -extern u8 BattleScript_TrainerBallBlock[]; -extern u8 BattleScript_WallyBallThrow[]; -extern u8 BattleScript_SuccessBallThrow[]; -extern u8 BattleScript_ShakeBallThrow[]; -extern u8 BattleScript_AllStatsUp[]; -extern u8 BattleScript_AtkDefDown[]; -extern u8 BattleScript_SAtkDown2[]; - -extern u8 BattleScript_SpikesOnTarget[]; //spikes1 -extern u8 BattleScript_SpikesOnAttacker[]; //spikes2 -extern u8 BattleScript_SpikesOngBank1[]; //spikes3 -extern u8 BattleScript_HitFromCritCalc[]; //present dmg -extern u8 BattleScript_AlreadyAtFullHp[]; //present full hp -extern u8 BattleScript_PresentHealTarget[]; //present hp heal -extern u8 BattleScript_MoveMissedPause[]; -extern u8 BattleScript_CastformChange[]; -extern u8 BattleScript_DampStopsExplosion[]; -extern u8 BattleScript_SuccessForceOut[]; //bs random switchout -extern u8 BattleScript_PrintPayDayMoneyString[]; //bs payday money give -extern u8 BattleScript_FaintAttacker[]; -extern u8 BattleScript_FaintTarget[]; -extern u8 BattleScript_DestinyBondTakesLife[]; -extern u8 BattleScript_SelectingImprisionedMoveInPalace[]; - -// read via orr -#define BSScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) -#define BSScriptRead16(ptr) ((ptr)[0] | ((ptr)[1] << 8)) -#define BSScriptReadPtr(ptr) ((void *)BSScriptRead32(ptr)) - -// read via add -#define BS2ScriptRead32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24)) -#define BS2ScriptRead16(ptr) ((ptr)[0] + ((ptr)[1] << 8)) -#define BS2ScriptReadPtr(ptr) ((void *)BS2ScriptRead32(ptr)) - -#define TARGET_PROTECT_AFFECTED ((gProtectStructs[gBankTarget].protected && gBattleMoves[gCurrentMove].flags & F_AFFECTED_BY_PROTECT)) - -//array entries for battle communication -#define MOVE_EFFECT_BYTE 0x3 -#define MULTISTRING_CHOOSER 0x5 -#define MSG_DISPLAY 0x7 - -#define TARGET_SELECTED 0x0 -#define TARGET_DEPENDS 0x1 -#define TARGET_BOTH 0x8 -#define TARGET_FOES_AND_ALLY 0x20 -#define TARGET_OPPONENTS_FIELD 0x40 - -#define TYPE_FORESIGHT 0xFE -#define TYPE_ENDTABLE 0xFF - -#define CMP_EQUAL 0x0 -#define CMP_NOT_EQUAL 0x1 -#define CMP_GREATER_THAN 0x2 -#define CMP_LESS_THAN 0x3 -#define CMP_COMMON_BITS 0x4 -#define CMP_NO_COMMON_BITS 0x5 - -#define uBYTE0_16(value)(( (u8) (((u16)(value) & (0x000000FF)) >> 0x00))) -#define uBYTE1_16(value)(( (u8) (((u16)(value) & (0x0000FF00)) >> 0x08))) - -#define uBYTE0_32(value)(( (u8) (((u32)(value) & (0x000000FF)) >> 0x00))) -#define uBYTE1_32(value)(( (u8) (((u32)(value) & (0x0000FF00)) >> 0x08))) -#define uBYTE2_32(value)(( (u8) (((u32)(value) & (0x00FF0000)) >> 0x10))) -#define uBYTE3_32(value)(( (u8) (((u32)(value) & (0xFF000000)) >> 0x18))) - -#define sBYTE0_16(value)(( (u8) (((s16)(value) & (0x000000FF)) >> 0x00))) -#define sBYTE1_16(value)(( (u8) (((s16)(value) & (0x0000FF00)) >> 0x08))) - -#define sBYTE0_32(value)(( (u8) (((s32)(value) & (0x000000FF)) >> 0x00))) -#define sBYTE1_32(value)(( (u8) (((s32)(value) & (0x0000FF00)) >> 0x08))) -#define sBYTE2_32(value)(( (u8) (((s32)(value) & (0x00FF0000)) >> 0x10))) -#define sBYTE3_32(value)(( (u8) (((s32)(value) & (0xFF000000)) >> 0x18))) - -#define RecordAbilitySetField6(ability, fieldValue) \ -(gLastUsedAbility = ability, gBattleCommunication[6] = fieldValue, RecordAbilityBattle(gBankTarget, ability)) - -#define TARGET_TURN_DAMAGED (((gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special))) - -#define HP_ON_SWITCHOUT (((u16*)(ewram_addr + 0x160BC))) - -static void atk00_attackcanceler(void); -static void atk01_accuracycheck(void); -static void atk02_attackstring(void); -static void atk03_ppreduce(void); -static void atk04_critcalc(void); -static void atk05_damagecalc(void); -static void atk06_typecalc(void); -static void atk07_adjustnormaldamage(void); -static void atk08_adjustnormaldamage2(void); -static void atk09_attackanimation(void); -static void atk0A_waitanimation(void); -static void atk0B_healthbarupdate(void); -static void atk0C_datahpupdate(void); -static void atk0D_critmessage(void); -static void atk0E_effectivenesssound(void); -static void atk0F_resultmessage(void); -static void atk10_printstring(void); -static void atk11_printselectionstring(void); -static void atk12_waitmessage(void); -static void atk13_printfromtable(void); -static void atk14_printselectionstringfromtable(void); -static void atk15_seteffectwithchance(void); -static void atk16_seteffectprimary(void); -static void atk17_seteffectsecondary(void); -static void atk18_clearstatusfromeffect(void); -static void atk19_tryfaintmon(void); -static void atk1A_dofaintanimation(void); -static void atk1B_cleareffectsonfaint(void); -static void atk1C_jumpifstatus(void); -static void atk1D_jumpifstatus2(void); -static void atk1E_jumpifability(void); -static void atk1F_jumpifsideaffecting(void); -static void atk20_jumpifstat(void); -static void atk21_jumpifstatus3condition(void); -static void atk22_jumpiftype(void); -static void atk23_getexp(void); -static void atk24(void); -static void atk25_movevaluescleanup(void); -static void atk26_setmultihit(void); -static void atk27_decrementmultihit(void); -static void atk28_goto(void); -static void atk29_jumpifbyte(void); -static void atk2A_jumpifhalfword(void); -static void atk2B_jumpifword(void); -static void atk2C_jumpifarrayequal(void); -static void atk2D_jumpifarraynotequal(void); -static void atk2E_setbyte(void); -static void atk2F_addbyte(void); -static void atk30_subbyte(void); -static void atk31_copyarray(void); -static void atk32_copyarraywithindex(void); -static void atk33_orbyte(void); -static void atk34_orhalfword(void); -static void atk35_orword(void); -static void atk36_bicbyte(void); -static void atk37_bichalfword(void); -static void atk38_bicword(void); -static void atk39_pause(void); -static void atk3A_waitstate(void); -static void atk3B_healthbar_update(void); -static void atk3C_return(void); -static void atk3D_end(void); -static void atk3E_end2(void); -static void atk3F_end3(void); -static void atk40_jumpifaffectedbyprotect(void); -static void atk41_call(void); -static void atk42_jumpiftype2(void); -static void atk43_jumpifabilitypresent(void); -static void atk44_endselectionscript(void); -static void atk45_playanimation(void); -static void atk46_playanimation2(void); -static void atk47_setgraphicalstatchangevalues(void); -static void atk48_playstatchangeanimation(void); -void atk49_moveend(void); -static void atk4A_typecalc2(void); -static void atk4B_returnatktoball(void); -static void atk4C_getswitchedmondata(void); -static void atk4D_switchindataupdate(void); -static void atk4E_switchinanim(void); -static void atk4F_jumpifcantswitch(void); -static void atk50_openpartyscreen(void); -static void atk51_switchhandleorder(void); -static void atk52_switchineffects(void); -static void atk53_trainerslidein(void); -static void atk54_playse(void); -static void atk55_fanfare(void); -static void atk56_playfaintcry(void); -static void atk57(void); -static void atk58_returntoball(void); -void atk59_handlelearnnewmove(void); -static void atk5A_yesnoboxlearnmove(void); -static void atk5B_yesnoboxstoplearningmove(void); -static void atk5C_hitanimation(void); -static void atk5D_getmoneyreward(void); -static void atk5E_8025A70(void); -static void atk5F_8025B24(void); -static void atk60_incrementgamestat(void); -static void atk61_drawpartystatussummary(void); -static void atk62_08025C6C(void); -static void atk63_jumptorandomattack(void); -static void atk64_statusanimation(void); -static void atk65_status2animation(void); -static void atk66_chosenstatusanimation(void); -static void atk67_yesnobox(void); -static void atk68_cancelallactions(void); -static void atk69_adjustsetdamage(void); -void atk6A_removeitem(void); -static void atk6B_atknameinbuff1(void); -static void atk6C_drawlvlupbox(void); -static void atk6D_resetsentmonsvalue(void); -static void atk6E_setatktoplayer0(void); -static void atk6F_makevisible(void); -static void atk70_recordlastability(void); -static void atk71_buffermovetolearn(void); -static void atk72_jumpifplayerran(void); -static void atk73_hpthresholds(void); -static void atk74_hpthresholds2(void); -static void atk75_useitemonopponent(void); -static void atk76_various(void); -static void atk77_setprotectlike(void); -static void atk78_faintifabilitynotdamp(void); -static void atk79_setatkhptozero(void); -static void atk7A_jumpifnexttargetvalid(void); -static void atk7B_tryhealhalfhealth(void); -static void atk7C_trymirrormove(void); -static void atk7D_setrain(void); -static void atk7E_setreflect(void); -static void atk7F_setseeded(void); -static void atk80_manipulatedamage(void); -static void atk81_trysetrest(void); -static void atk82_jumpifnotfirstturn(void); -static void atk83_nop(void); -static void atk84_jumpifcantmakeasleep(void); -static void atk85_stockpile(void); -static void atk86_stockpiletobasedamage(void); -static void atk87_stockpiletohpheal(void); -static void atk88_negativedamage(void); -static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8 *BS_ptr); -static void atk89_statbuffchange(void); -static void atk8A_normalisebuffs(void); -static void atk8B_setbide(void); -static void atk8C_confuseifrepeatingattackends(void); -static void atk8D_setmultihitcounter(void); -static void atk8E_initmultihitstring(void); -static void atk8F_forcerandomswitch(void); -static void atk90_tryconversiontypechange(void); -static void atk91_givepaydaymoney(void); -static void atk92_setlightscreen(void); -static void atk93_tryKO(void); -static void atk94_damagetohalftargethp(void); -static void atk95_setsandstorm(void); -static void atk96_weatherdamage(void); -static void atk97_tryinfatuating(void); -static void atk98_updatestatusicon(void); -static void atk99_setmist(void); -static void atk9A_setfocusenergy(void); -static void atk9B_transformdataexecution(void); -static void atk9C_setsubstitute(void); -static void atk9D_mimicattackcopy(void); -static void atk9E_metronome(void); -static void atk9F_dmgtolevel(void); -static void atkA0_psywavedamageeffect(void); -static void atkA1_counterdamagecalculator(void); -static void atkA2_mirrorcoatdamagecalculator(void); -static void atkA3_disablelastusedattack(void); -static void atkA4_trysetencore(void); -static void atkA5_painsplitdmgcalc(void); -static void atkA6_settypetorandomresistance(void); -static void atkA7_setalwayshitflag(void); -static void atkA8_copymovepermanently(void); -static void atkA9_trychoosesleeptalkmove(void); -static void atkAA_setdestinybond(void); -static void atkAB_trysetdestinybondtohappen(void); -static void atkAC_remaininghptopower(void); -static void atkAD_tryspiteppreduce(void); -static void atkAE_healpartystatus(void); -static void atkAF_cursetarget(void); -static void atkB0_trysetspikes(void); -static void atkB1_setforesight(void); -static void atkB2_trysetperishsong(void); -static void atkB3_rolloutdamagecalculation(void); -static void atkB4_jumpifconfusedandstatmaxed(void); -static void atkB5_furycuttercalc(void); -static void atkB6_happinesstodamagecalculation(void); -static void atkB7_presentdamagecalculation(void); -static void atkB8_setsafeguard(void); -static void atkB9_magnitudedamagecalculation(void); -static void atkBA_jumpifnopursuitswitchdmg(void); -static void atkBB_setsunny(void); -static void atkBC_maxattackhalvehp(void); -static void atkBD_copyfoestats(void); -static void atkBE_rapidspinfree(void); -static void atkBF_setdefensecurlbit(void); -static void atkC0_recoverbasedonsunlight(void); -static void atkC1_hiddenpowercalc(void); -static void atkC2_selectfirstvalidtarget(void); -static void atkC3_trysetfutureattack(void); -static void atkC4_trydobeatup(void); -static void atkC5_setsemiinvulnerablebit(void); -static void atkC6_clearsemiinvulnerablebit(void); -static void atkC7_setminimize(void); -static void atkC8_sethail(void); -static void atkC9_jumpifattackandspecialattackcannotfall(void); -static void atkCA_setforcedtarget(void); -static void atkCB_setcharge(void); -static void atkCC_callterrainattack(void); -static void atkCD_cureifburnedparalysedorpoisoned(void); -static void atkCE_settorment(void); -static void atkCF_jumpifnodamage(void); -static void atkD0_settaunt(void); -static void atkD1_trysethelpinghand(void); -static void atkD2_tryswapitems(void); -static void atkD3_trycopyability(void); -static void atkD4_trywish(void); -static void atkD5_trysetroots(void); -static void atkD6_doubledamagedealtifdamaged(void); -static void atkD7_setyawn(void); -static void atkD8_setdamagetohealthdifference(void); -static void atkD9_scaledamagebyhealthratio(void); -static void atkDA_tryswapabilities(void); -static void atkDB_tryimprision(void); -static void atkDC_trysetgrudge(void); -static void atkDD_weightdamagecalculation(void); -static void atkDE_asistattackselect(void); -static void atkDF_trysetmagiccoat(void); -static void atkE0_trysetsnatch(void); -static void atkE1_trygetintimidatetarget(void); -static void atkE2_switchoutabilities(void); -static void atkE3_jumpifhasnohp(void); -static void atkE4_getsecretpowereffect(void); -static void atkE5_pickup(void); -static void atkE6_docastformchangeanimation(void); -static void atkE7_trycastformdatachange(void); -static void atkE8_settypebasedhalvers(void); -static void atkE9_setweatherballtype(void); -static void atkEA_tryrecycleitem(void); -static void atkEB_settypetoterrain(void); -static void atkEC_pursuitrelated(void); -static void atkED_snatchsetbanks(void); -static void atkEE_removelightscreenreflect(void); -void atkEF_handleballthrow(void); -static void atkF0_givecaughtmon(void); -static void atkF1_trysetcaughtmondexflags(void); -static void atkF2_displaydexinfo(void); -static void atkF3_trygivecaughtmonnick(void); -static void atkF4_subattackerhpbydmg(void); -static void atkF5_removeattackerstatus1(void); -static void atkF6_finishaction(void); -static void atkF7_finishturn(void); - -void (* const gBattleScriptingCommandsTable[])(void) = -{ - atk00_attackcanceler, - atk01_accuracycheck, - atk02_attackstring, - atk03_ppreduce, - atk04_critcalc, - atk05_damagecalc, - atk06_typecalc, - atk07_adjustnormaldamage, - atk08_adjustnormaldamage2, - atk09_attackanimation, - atk0A_waitanimation, - atk0B_healthbarupdate, - atk0C_datahpupdate, - atk0D_critmessage, - atk0E_effectivenesssound, - atk0F_resultmessage, - atk10_printstring, - atk11_printselectionstring, - atk12_waitmessage, - atk13_printfromtable, - atk14_printselectionstringfromtable, - atk15_seteffectwithchance, - atk16_seteffectprimary, - atk17_seteffectsecondary, - atk18_clearstatusfromeffect, - atk19_tryfaintmon, - atk1A_dofaintanimation, - atk1B_cleareffectsonfaint, - atk1C_jumpifstatus, - atk1D_jumpifstatus2, - atk1E_jumpifability, - atk1F_jumpifsideaffecting, - atk20_jumpifstat, - atk21_jumpifstatus3condition, - atk22_jumpiftype, - atk23_getexp, - atk24, - atk25_movevaluescleanup, - atk26_setmultihit, - atk27_decrementmultihit, - atk28_goto, - atk29_jumpifbyte, - atk2A_jumpifhalfword, - atk2B_jumpifword, - atk2C_jumpifarrayequal, - atk2D_jumpifarraynotequal, - atk2E_setbyte, - atk2F_addbyte, - atk30_subbyte, - atk31_copyarray, - atk32_copyarraywithindex, - atk33_orbyte, - atk34_orhalfword, - atk35_orword, - atk36_bicbyte, - atk37_bichalfword, - atk38_bicword, - atk39_pause, - atk3A_waitstate, - atk3B_healthbar_update, - atk3C_return, - atk3D_end, - atk3E_end2, - atk3F_end3, - atk40_jumpifaffectedbyprotect, - atk41_call, - atk42_jumpiftype2, - atk43_jumpifabilitypresent, - atk44_endselectionscript, - atk45_playanimation, - atk46_playanimation2, - atk47_setgraphicalstatchangevalues, - atk48_playstatchangeanimation, - atk49_moveend, - atk4A_typecalc2, - atk4B_returnatktoball, - atk4C_getswitchedmondata, - atk4D_switchindataupdate, - atk4E_switchinanim, - atk4F_jumpifcantswitch, - atk50_openpartyscreen, - atk51_switchhandleorder, - atk52_switchineffects, - atk53_trainerslidein, - atk54_playse, - atk55_fanfare, - atk56_playfaintcry, - atk57, - atk58_returntoball, - atk59_handlelearnnewmove, - atk5A_yesnoboxlearnmove, - atk5B_yesnoboxstoplearningmove, - atk5C_hitanimation, - atk5D_getmoneyreward, - atk5E_8025A70, - atk5F_8025B24, - atk60_incrementgamestat, - atk61_drawpartystatussummary, - atk62_08025C6C, - atk63_jumptorandomattack, - atk64_statusanimation, - atk65_status2animation, - atk66_chosenstatusanimation, - atk67_yesnobox, - atk68_cancelallactions, - atk69_adjustsetdamage, - atk6A_removeitem, - atk6B_atknameinbuff1, - atk6C_drawlvlupbox, - atk6D_resetsentmonsvalue, - atk6E_setatktoplayer0, - atk6F_makevisible, - atk70_recordlastability, - atk71_buffermovetolearn, - atk72_jumpifplayerran, - atk73_hpthresholds, - atk74_hpthresholds2, - atk75_useitemonopponent, - atk76_various, - atk77_setprotectlike, - atk78_faintifabilitynotdamp, - atk79_setatkhptozero, - atk7A_jumpifnexttargetvalid, - atk7B_tryhealhalfhealth, - atk7C_trymirrormove, - atk7D_setrain, - atk7E_setreflect, - atk7F_setseeded, - atk80_manipulatedamage, - atk81_trysetrest, - atk82_jumpifnotfirstturn, - atk83_nop, - atk84_jumpifcantmakeasleep, - atk85_stockpile, - atk86_stockpiletobasedamage, - atk87_stockpiletohpheal, - atk88_negativedamage, - atk89_statbuffchange, - atk8A_normalisebuffs, - atk8B_setbide, - atk8C_confuseifrepeatingattackends, - atk8D_setmultihitcounter, - atk8E_initmultihitstring, - atk8F_forcerandomswitch, - atk90_tryconversiontypechange, - atk91_givepaydaymoney, - atk92_setlightscreen, - atk93_tryKO, - atk94_damagetohalftargethp, - atk95_setsandstorm, - atk96_weatherdamage, - atk97_tryinfatuating, - atk98_updatestatusicon, - atk99_setmist, - atk9A_setfocusenergy, - atk9B_transformdataexecution, - atk9C_setsubstitute, - atk9D_mimicattackcopy, - atk9E_metronome, - atk9F_dmgtolevel, - atkA0_psywavedamageeffect, - atkA1_counterdamagecalculator, - atkA2_mirrorcoatdamagecalculator, - atkA3_disablelastusedattack, - atkA4_trysetencore, - atkA5_painsplitdmgcalc, - atkA6_settypetorandomresistance, - atkA7_setalwayshitflag, - atkA8_copymovepermanently, - atkA9_trychoosesleeptalkmove, - atkAA_setdestinybond, - atkAB_trysetdestinybondtohappen, - atkAC_remaininghptopower, - atkAD_tryspiteppreduce, - atkAE_healpartystatus, - atkAF_cursetarget, - atkB0_trysetspikes, - atkB1_setforesight, - atkB2_trysetperishsong, - atkB3_rolloutdamagecalculation, - atkB4_jumpifconfusedandstatmaxed, - atkB5_furycuttercalc, - atkB6_happinesstodamagecalculation, - atkB7_presentdamagecalculation, - atkB8_setsafeguard, - atkB9_magnitudedamagecalculation, - atkBA_jumpifnopursuitswitchdmg, - atkBB_setsunny, - atkBC_maxattackhalvehp, - atkBD_copyfoestats, - atkBE_rapidspinfree, - atkBF_setdefensecurlbit, - atkC0_recoverbasedonsunlight, - atkC1_hiddenpowercalc, - atkC2_selectfirstvalidtarget, - atkC3_trysetfutureattack, - atkC4_trydobeatup, - atkC5_setsemiinvulnerablebit, - atkC6_clearsemiinvulnerablebit, - atkC7_setminimize, - atkC8_sethail, - atkC9_jumpifattackandspecialattackcannotfall, - atkCA_setforcedtarget, - atkCB_setcharge, - atkCC_callterrainattack, - atkCD_cureifburnedparalysedorpoisoned, - atkCE_settorment, - atkCF_jumpifnodamage, - atkD0_settaunt, - atkD1_trysethelpinghand, - atkD2_tryswapitems, - atkD3_trycopyability, - atkD4_trywish, - atkD5_trysetroots, - atkD6_doubledamagedealtifdamaged, - atkD7_setyawn, - atkD8_setdamagetohealthdifference, - atkD9_scaledamagebyhealthratio, - atkDA_tryswapabilities, - atkDB_tryimprision, - atkDC_trysetgrudge, - atkDD_weightdamagecalculation, - atkDE_asistattackselect, - atkDF_trysetmagiccoat, - atkE0_trysetsnatch, - atkE1_trygetintimidatetarget, - atkE2_switchoutabilities, - atkE3_jumpifhasnohp, - atkE4_getsecretpowereffect, - atkE5_pickup, - atkE6_docastformchangeanimation, - atkE7_trycastformdatachange, - atkE8_settypebasedhalvers, - atkE9_setweatherballtype, - atkEA_tryrecycleitem, - atkEB_settypetoterrain, - atkEC_pursuitrelated, - atkED_snatchsetbanks, - atkEE_removelightscreenreflect, - atkEF_handleballthrow, - atkF0_givecaughtmon, - atkF1_trysetcaughtmondexflags, - atkF2_displaydexinfo, - atkF3_trygivecaughtmonnick, - atkF4_subattackerhpbydmg, - atkF5_removeattackerstatus1, - atkF6_finishaction, - atkF7_finishturn, -}; - -struct StatFractions -{ - u8 dividend; - u8 divisor; -}; - -static const struct StatFractions gAccuracyStageRatios[] = -{ - { 33, 100}, // -6 - { 36, 100}, // -5 - { 43, 100}, // -4 - { 50, 100}, // -3 - { 60, 100}, // -2 - { 75, 100}, // -1 - { 1, 1}, // 0 - {133, 100}, // +1 - {166, 100}, // +2 - { 2, 1}, // +3 - {233, 100}, // +4 - {133, 50}, // +5 - { 3, 1}, // +6 -}; - -// The chance is 1/N for each stage. -static const u16 sCriticalHitChance[] = {16, 8, 4, 3, 2}; - -static const u32 sStatusFlagsForMoveEffects[] = -{ - 0x00000000, - STATUS_SLEEP, - STATUS_POISON, - STATUS_BURN, - STATUS_FREEZE, - STATUS_PARALYSIS, - STATUS_TOXIC_POISON, - STATUS2_CONFUSION, - STATUS2_FLINCHED, - 0x00000000, - STATUS2_UPROAR, - 0x00000000, - STATUS2_MULTIPLETURNS, - STATUS2_WRAPPED, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - STATUS2_RECHARGE, - 0x00000000, - 0x00000000, - STATUS2_ESCAPE_PREVENTION, - STATUS2_NIGHTMARE, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - STATUS2_LOCK_CONFUSE, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000 -}; - -u8* const gMoveEffectBS_Ptrs[] = -{ - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectPoison, - BattleScript_MoveEffectBurn, - BattleScript_MoveEffectFreeze, - BattleScript_MoveEffectParalysis, - BattleScript_MoveEffectToxic, - BattleScript_MoveEffectConfusion, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectUproar, - BattleScript_MoveEffectPayDay, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectWrap, - BattleScript_MoveEffectRecoil33, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectSleep, - BattleScript_MoveEffectRecoil33 -}; - -const u8 sUnreferencedBitMask1[] = {0, 1, 3, 7, 0xF, 0x1F, 0x3F}; - -const u8 gLevelUpStatBoxStats[] = -{ - MON_DATA_MAX_HP, MON_DATA_SPATK, MON_DATA_ATK, - MON_DATA_SPDEF, MON_DATA_DEF, MON_DATA_SPEED -}; - -static const u16 sProtectSuccessRates[] = {0xFFFF, 0x7FFF, 0x3FFF, 0x1FFF}; - -#define MIMIC_FORBIDDEN_END 0xFFFE -#define METRONOME_FORBIDDEN_END 0xFFFF -#define ASSIST_FORBIDDEN_END 0xFFFF - -static const u16 sMovesForbiddenToCopy[] = -{ - MOVE_METRONOME, - MOVE_STRUGGLE, - MOVE_SKETCH, - MOVE_MIMIC, - MIMIC_FORBIDDEN_END, - MOVE_COUNTER, - MOVE_MIRROR_COAT, - MOVE_PROTECT, - MOVE_DETECT, - MOVE_ENDURE, - MOVE_DESTINY_BOND, - MOVE_SLEEP_TALK, - MOVE_THIEF, - MOVE_FOLLOW_ME, - MOVE_SNATCH, - MOVE_HELPING_HAND, - MOVE_COVET, - MOVE_TRICK, - MOVE_FOCUS_PUNCH, - METRONOME_FORBIDDEN_END -}; - -static const u8 sFlailHpScaleToPowerTable[] = //reversal+flail HP thresholds to power -{ - 1, 200, - 4, 150, - 9, 100, - 16, 80, - 32, 40, - 48, 20 -}; - -static const u16 sNaturePowerMoves[] = -{ - MOVE_STUN_SPORE, - MOVE_RAZOR_LEAF, - MOVE_EARTHQUAKE, - MOVE_HYDRO_PUMP, - MOVE_SURF, - MOVE_BUBBLE_BEAM, - MOVE_ROCK_SLIDE, - MOVE_SHADOW_BALL, - MOVE_SWIFT, - MOVE_SWIFT -}; - -// weight-based damage table for Low Kick -// format: min. weight (hectograms), base power -static const u16 sWeightToDamageTable[] = -{ - 100, 20, - 250, 40, - 500, 60, - 1000, 80, - 2000, 100, - 0xFFFF, 0xFFFF -}; - -static const u16 sPickupItems[] = -{ - ITEM_SUPER_POTION, 30, - ITEM_FULL_HEAL, 40, - ITEM_ULTRA_BALL, 50, - ITEM_RARE_CANDY, 60, - ITEM_FULL_RESTORE, 70, - ITEM_REVIVE, 80, - ITEM_NUGGET, 90, - ITEM_PROTEIN, 95, - ITEM_PP_UP, 99, - ITEM_KINGS_ROCK, 1 -}; - -static const u8 sTerrainToType[] = -{ - TYPE_GRASS, // tall grass - TYPE_GRASS, // long grass - TYPE_GROUND, // sand - TYPE_WATER, // underwater - TYPE_WATER, // water - TYPE_WATER, // pond water - TYPE_ROCK, // rock - TYPE_ROCK, // cave - TYPE_NORMAL, // building - TYPE_NORMAL, // plain -}; - -static const u8 sBallCatchBonuses[] = -{ - 20, 15, 10, 15 // Ultra, Great, Poke, Safari -}; - -static void atk00_attackcanceler(void) -{ - s32 i; - - if (gBattleOutcome != 0) - { - gCurrentActionFuncId = ACTION_FINISHED; - return; - } - if (gBattleMons[gBankAttacker].hp == 0 && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) - { - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - gBattlescriptCurrInstr = BattleScript_MoveEnd; - return; - } - if (AtkCanceller_UnableToUseMove()) - return; - if (AbilityBattleEffects(ABILITYEFFECT_MOVES_BLOCK, gBankTarget, 0, 0, 0)) - return; - if (!gBattleMons[gBankAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE && !(gHitMarker & 0x800200) - && !(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) - { - gBattlescriptCurrInstr = BattleScript_NoPPForMove; - gMoveResultFlags |= MOVE_RESULT_MISSED; - return; - } - - gHitMarker &= ~(HITMARKER_x800000); - - if (!(gHitMarker & HITMARKER_OBEYS) && !(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) - { - i = IsMonDisobedient(); // why use the 'i' variable...? - switch (i) - { - case 0: - break; - case 2: - gHitMarker |= HITMARKER_OBEYS; - return; - default: - gMoveResultFlags |= MOVE_RESULT_MISSED; - return; - } - } - - gHitMarker |= HITMARKER_OBEYS; - - if (gProtectStructs[gBankTarget].bounceMove && gBattleMoves[gCurrentMove].flags & F_AFFECTED_BY_MAGIC_COAT) - { - PressurePPLose(gBankAttacker, gBankTarget, MOVE_MAGIC_COAT); - gProtectStructs[gBankTarget].bounceMove = 0; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MagicCoatBounce; - return; - } - - for (i = 0; i < gBattlersCount; i++) - { - if ((gProtectStructs[gBanksByTurnOrder[i]].stealMove) && gBattleMoves[gCurrentMove].flags & F_AFFECTED_BY_SNATCH) - { - PressurePPLose(gBankAttacker, gBanksByTurnOrder[i], MOVE_SNATCH); - gProtectStructs[gBanksByTurnOrder[i]].stealMove = 0; - gBattleStruct->scriptingActive = gBanksByTurnOrder[i]; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_SnatchedMove; - return; - } - } - - if (gSpecialStatuses[gBankTarget].lightningRodRedirected) - { - gSpecialStatuses[gBankTarget].lightningRodRedirected = 0; - gLastUsedAbility = ABILITY_LIGHTNING_ROD; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_TookAttack; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - else if (TARGET_PROTECT_AFFECTED - && (gCurrentMove != MOVE_CURSE || (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST)) - && ((!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)))) - { - CancelMultiTurnMoves(gBankAttacker); - gMoveResultFlags |= MOVE_RESULT_MISSED; - gLastLandedMoves[gBankTarget] = 0; - gLastHitByType[gBankTarget] = 0; - gBattleCommunication[6] = 1; - gBattlescriptCurrInstr++; - } - else - { - gBattlescriptCurrInstr++; - } -} - -static void JumpIfMoveFailed(u8 adder, u16 move) -{ - const u8 *BS_ptr = gBattlescriptCurrInstr + adder; - if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - { - gLastLandedMoves[gBankTarget] = 0; - gLastHitByType[gBankTarget] = 0; - BS_ptr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } - else - { - TrySetDestinyBondToHappen(); - if (AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBankTarget, 0, 0, move)) - return; - } - gBattlescriptCurrInstr = BS_ptr; -} - -static void atk40_jumpifaffectedbyprotect(void) -{ - if (TARGET_PROTECT_AFFECTED) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - JumpIfMoveFailed(5, 0); - gBattleCommunication[6] = 1; - } - else - { - gBattlescriptCurrInstr += 5; - } -} - -static bool8 JumpIfMoveAffectedByProtect(u16 move) -{ - bool8 affected = FALSE; - if (TARGET_PROTECT_AFFECTED) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - JumpIfMoveFailed(7, move); - gBattleCommunication[6] = 1; - affected = TRUE; - } - return affected; -} - -static bool8 AccuracyCalcHelper(u16 move) -{ - if (gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker) - { - JumpIfMoveFailed(7, move); - return TRUE; - } - - if (!(gHitMarker & HITMARKER_IGNORE_ON_AIR) && gStatuses3[gBankTarget] & STATUS3_ON_AIR) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - JumpIfMoveFailed(7, move); - return TRUE; - } - - gHitMarker &= ~HITMARKER_IGNORE_ON_AIR; - - if (!(gHitMarker & HITMARKER_IGNORE_UNDERGROUND) && gStatuses3[gBankTarget] & STATUS3_UNDERGROUND) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - JumpIfMoveFailed(7, move); - return TRUE; - } - - gHitMarker &= ~HITMARKER_IGNORE_UNDERGROUND; - - if (!(gHitMarker & HITMARKER_IGNORE_UNDERWATER) && gStatuses3[gBankTarget] & STATUS3_UNDERWATER) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - JumpIfMoveFailed(7, move); - return TRUE; - } - - gHitMarker &= ~HITMARKER_IGNORE_UNDERWATER; - - if ((WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY) && gBattleMoves[move].effect == EFFECT_THUNDER) - || (gBattleMoves[move].effect == EFFECT_ALWAYS_HIT || gBattleMoves[move].effect == EFFECT_VITAL_THROW)) - { - JumpIfMoveFailed(7, move); - return TRUE; - } - - return FALSE; -} - -static void atk01_accuracycheck(void) -{ - u16 move = T2_READ_16(gBattlescriptCurrInstr + 5); - - if (move == 0xFFFE || move == 0xFFFF) - { - if (gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS && move == 0xFFFF && gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker) - gBattlescriptCurrInstr += 7; - else if (gStatuses3[gBankTarget] & (STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else if (!JumpIfMoveAffectedByProtect(0)) - gBattlescriptCurrInstr += 7; - } - else - { - u8 type, moveAcc, holdEffect, quality; - s8 buff; - u16 calc; - - if (move == 0) - move = gCurrentMove; - - GET_MOVE_TYPE(move, type); - - if (JumpIfMoveAffectedByProtect(move)) - return; - if (AccuracyCalcHelper(move)) - return; - - if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) - { - u8 acc = gBattleMons[gBankAttacker].statStages[STAT_STAGE_ACC]; - buff = acc; - } - else - { - u8 acc = gBattleMons[gBankAttacker].statStages[STAT_STAGE_ACC]; - buff = acc + 6 - gBattleMons[gBankTarget].statStages[STAT_STAGE_EVASION]; - } - - if (buff < 0) - buff = 0; - if (buff > 0xC) - buff = 0xC; - - moveAcc = gBattleMoves[move].accuracy; - // check Thunder on sunny weather - if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY && gBattleMoves[move].effect == EFFECT_THUNDER) - moveAcc = 50; - - calc = gAccuracyStageRatios[buff].dividend * moveAcc; - calc /= gAccuracyStageRatios[buff].divisor; - - if (gBattleMons[gBankAttacker].ability == ABILITY_COMPOUND_EYES) - calc = (calc * 130) / 100; // 1.3 compound eyes boost - if (WEATHER_HAS_EFFECT && gBattleMons[gBankTarget].ability == ABILITY_SAND_VEIL && gBattleWeather & WEATHER_SANDSTORM_ANY) - calc = (calc * 80) / 100; // 1.2 sand veil loss; - if (gBattleMons[gBankAttacker].ability == ABILITY_HUSTLE && type < 9) - calc = (calc * 80) / 100; // 1.2 hustle loss; - - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - { - holdEffect = gEnigmaBerries[gBankTarget].holdEffect; - quality = gEnigmaBerries[gBankTarget].holdEffectParam; - } - else - { - holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); - } - - gStringBank = gBankTarget; - - if (holdEffect == HOLD_EFFECT_EVASION_UP) - calc = (calc * (100 - quality)) / 100; - - // final calculation - if ((Random() % 100 + 1) > calc) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && - (gBattleMoves[move].target == 0x8 || gBattleMoves[move].target == 0x20)) - gBattleCommunication[6] = 2; - else - gBattleCommunication[6] = 0; - CheckWonderGuardAndLevitate(); - } - JumpIfMoveFailed(7, move); - } -} - -static void atk02_attackstring(void) -{ - if (gBattleExecBuffer) - return; - if (!(gHitMarker & (HITMARKER_NO_ATTACKSTRING | HITMARKER_ATTACKSTRING_PRINTED))) - { - PrepareStringBattle(4, gBankAttacker); - gHitMarker |= HITMARKER_ATTACKSTRING_PRINTED; - } - gBattlescriptCurrInstr++; - gBattleCommunication[MSG_DISPLAY] = 0; -} - -static void atk03_ppreduce(void) -{ - s32 ppToDeduct = 1; - - if (gBattleExecBuffer) - return; - - if (!gSpecialStatuses[gBankAttacker].flag20) - { - switch (gBattleMoves[gCurrentMove].target) - { - case TARGET_FOES_AND_ALLY: - ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_ON_FIELD, gBankAttacker, ABILITY_PRESSURE, 0, 0); - break; - case TARGET_BOTH: - case TARGET_OPPONENTS_FIELD: - ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIZE, gBankAttacker, ABILITY_PRESSURE, 0, 0); - break; - default: - if (gBankAttacker != gBankTarget && gBattleMons[gBankTarget].ability == ABILITY_PRESSURE) - ppToDeduct++; - break; - } - } - - if (!(gHitMarker & (HITMARKER_NO_PPDEDUCT | HITMARKER_NO_ATTACKSTRING)) && gBattleMons[gBankAttacker].pp[gCurrMovePos]) - { - gProtectStructs[gBankAttacker].notFirstStrike = 1; - - if (gBattleMons[gBankAttacker].pp[gCurrMovePos] > ppToDeduct) - gBattleMons[gBankAttacker].pp[gCurrMovePos] -= ppToDeduct; - else - gBattleMons[gBankAttacker].pp[gCurrMovePos] = 0; - - if (!(gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED) - && !((gDisableStructs[gBankAttacker].unk18_b) & gBitTable[gCurrMovePos])) - { - gActiveBattler = gBankAttacker; - EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + gCurrMovePos, 0, 1, &gBattleMons[gBankAttacker].pp[gCurrMovePos]); - MarkBufferBankForExecution(gBankAttacker); - } - } - - gHitMarker &= ~(HITMARKER_NO_PPDEDUCT); - gBattlescriptCurrInstr++; -} - -static void atk04_critcalc(void) -{ - u8 holdEffect; - u16 item, critChance; - - item = gBattleMons[gBankAttacker].item; - - if (item == ITEM_ENIGMA_BERRY) - holdEffect = gEnigmaBerries[gBankAttacker].holdEffect; - else - holdEffect = ItemId_GetHoldEffect(item); - - gStringBank = gBankAttacker; - - critChance = 2 * ((gBattleMons[gBankAttacker].status2 & STATUS2_FOCUS_ENERGY) != 0) - + (gBattleMoves[gCurrentMove].effect == EFFECT_HIGH_CRITICAL) - + (gBattleMoves[gCurrentMove].effect == EFFECT_SKY_ATTACK) - + (gBattleMoves[gCurrentMove].effect == EFFECT_BLAZE_KICK) - + (gBattleMoves[gCurrentMove].effect == EFFECT_POISON_TAIL) - + (holdEffect == HOLD_EFFECT_SCOPE_LENS) - + 2 * (holdEffect == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBankAttacker].species == SPECIES_CHANSEY) - + 2 * (holdEffect == HOLD_EFFECT_STICK && gBattleMons[gBankAttacker].species == SPECIES_FARFETCHD); - - if (critChance > 4) - critChance = 4; - - if ((gBattleMons[gBankTarget].ability != ABILITY_BATTLE_ARMOR && gBattleMons[gBankTarget].ability != ABILITY_SHELL_ARMOR) - && !(gStatuses3[gBankAttacker] & STATUS3_CANT_SCORE_A_CRIT) - && !(gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE)) - && !(Random() % sCriticalHitChance[critChance])) - gCritMultiplier = 2; - else - gCritMultiplier = 1; - - gBattlescriptCurrInstr++; -} - -static void atk05_damagecalc(void) -{ - u16 side_hword = gSideAffecting[GetBattlerPosition(gBankTarget) & 1]; - gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, - side_hword, gDynamicBasePower, - gBattleStruct->dynamicMoveType, gBankAttacker, gBankTarget); - gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleStruct->dmgMultiplier; - - if (gStatuses3[gBankAttacker] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) - gBattleMoveDamage *= 2; - if (gProtectStructs[gBankAttacker].helpingHand) - gBattleMoveDamage = gBattleMoveDamage * 15 / 10; - - gBattlescriptCurrInstr++; -} - -void AI_CalcDmg(u8 BankAtk, u8 BankDef) -{ - u16 side_hword = gSideAffecting[GetBattlerPosition(BankDef) & 1]; - gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[BankAtk], &gBattleMons[BankDef], gCurrentMove, - side_hword, gDynamicBasePower, - gBattleStruct->dynamicMoveType, BankAtk, BankDef); - gDynamicBasePower = 0; - gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleStruct->dmgMultiplier; - - if (gStatuses3[BankAtk] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) - gBattleMoveDamage *= 2; - if (gProtectStructs[BankAtk].helpingHand) - gBattleMoveDamage = gBattleMoveDamage * 15 / 10; -} - -static void ModulateDmgByType(u8 multiplier) -{ - gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; - if (gBattleMoveDamage == 0 && multiplier != 0) - gBattleMoveDamage = 1; - - switch (multiplier) - { - case 0: //no effect - gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE; - gMoveResultFlags &= ~MOVE_RESULT_NOT_VERY_EFFECTIVE; - gMoveResultFlags &= ~MOVE_RESULT_SUPER_EFFECTIVE; - break; - case 5: //not very effecting - if (gBattleMoves[gCurrentMove].power && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) - { - if (gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) - gMoveResultFlags &= ~MOVE_RESULT_SUPER_EFFECTIVE; - else - gMoveResultFlags |= MOVE_RESULT_NOT_VERY_EFFECTIVE; - } - break; - case 20: //super effective - if (gBattleMoves[gCurrentMove].power && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) - { - if (gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE) - gMoveResultFlags &= ~MOVE_RESULT_NOT_VERY_EFFECTIVE; - else - gMoveResultFlags |= MOVE_RESULT_SUPER_EFFECTIVE; - } - break; - } -} - -static void atk06_typecalc(void) -{ - int i = 0; - u8 move_type; - if (gCurrentMove != MOVE_STRUGGLE) - { - if (gBattleStruct->dynamicMoveType) - move_type = gBattleStruct->dynamicMoveType & 0x3F; - else - move_type = gBattleMoves[gCurrentMove].type; - - //check stab - if (gBattleMons[gBankAttacker].type1 == move_type || gBattleMons[gBankAttacker].type2 == move_type) - { - gBattleMoveDamage = gBattleMoveDamage * 15; - gBattleMoveDamage = gBattleMoveDamage / 10; - } - - if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && move_type == TYPE_GROUND) - { - gLastUsedAbility = gBattleMons[gBankTarget].ability; - gMoveResultFlags |= (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE); - gLastLandedMoves[gBankTarget] = 0; - gLastHitByType[gBankTarget] = 0; - gBattleCommunication[6] = move_type; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - else - { - while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) - { - if (gTypeEffectiveness[i] == TYPE_FORESIGHT) - { - if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) - break; - i += 3; - continue; - } - - else if (gTypeEffectiveness[i] == move_type) - { - //check type1 - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1) - ModulateDmgByType(gTypeEffectiveness[i + 2]); - //check type2 - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 && - gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2) - ModulateDmgByType(gTypeEffectiveness[i + 2]); - } - i += 3; - } - } - - if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2 - && (!(gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) || ((gMoveResultFlags & (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE)) == (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE))) - && gBattleMoves[gCurrentMove].power) - { - gLastUsedAbility = ABILITY_WONDER_GUARD; - gMoveResultFlags |= MOVE_RESULT_MISSED; - gLastLandedMoves[gBankTarget] = 0; - gLastHitByType[gBankTarget] = 0; - gBattleCommunication[6] = 3; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - if (gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) - gProtectStructs[gBankAttacker].notEffective = 1; - } - gBattlescriptCurrInstr++; -} -static void CheckWonderGuardAndLevitate(void) -{ - u8 flags = 0; - int i = 0; - u8 move_type; - - if (gCurrentMove == MOVE_STRUGGLE || !gBattleMoves[gCurrentMove].power) - return; - - if (gBattleStruct->dynamicMoveType) - move_type = gBattleStruct->dynamicMoveType & 0x3F; - else - move_type = gBattleMoves[gCurrentMove].type; - - if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && move_type == TYPE_GROUND) - { - RecordAbilitySetField6(ABILITY_LEVITATE, move_type); - return; - } - - while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) - { - if (gTypeEffectiveness[i] == TYPE_FORESIGHT) - { - if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) - break; - i += 3; - continue; - } - - if (gTypeEffectiveness[i] == move_type) - { - //check no effect - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 0) - { - gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE; - gProtectStructs[gBankAttacker].notEffective = 1; - } - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 && - gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 && - gTypeEffectiveness[i + 2] == 0) - { - gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE; - gProtectStructs[gBankAttacker].notEffective = 1; - } - - //check super effective - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 20) - flags |= 1; - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 - && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 - && gTypeEffectiveness[i + 2] == 20) - flags |= 1; - - //check not very effective - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 5) - flags |= 2; - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 - && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 - && gTypeEffectiveness[i + 2] == 5) - flags |= 2; - } - i += 3; - } - - if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2) - { - if (((flags & 2) || !(flags & 1)) && gBattleMoves[gCurrentMove].power) - { - RecordAbilitySetField6(ABILITY_WONDER_GUARD, 3); - } - } -} - -static void ModulateDmgByType2(u8 multiplier, u16 move, u8* flags) //a literal copy of the ModulateDmgbyType1 with different args... -{ - gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; - if (gBattleMoveDamage == 0 && multiplier != 0) - gBattleMoveDamage = 1; - - switch (multiplier) - { - case 0: //no effect - *flags |= MOVE_RESULT_DOESNT_AFFECT_FOE; - *flags &= ~MOVE_RESULT_NOT_VERY_EFFECTIVE; - *flags &= ~MOVE_RESULT_SUPER_EFFECTIVE; - break; - case 5: //not very effecting - if (gBattleMoves[move].power && !(*flags & MOVE_RESULT_NO_EFFECT)) - { - if (*flags & MOVE_RESULT_SUPER_EFFECTIVE) - *flags &= ~MOVE_RESULT_SUPER_EFFECTIVE; - else - *flags |= MOVE_RESULT_NOT_VERY_EFFECTIVE; - } - break; - case 20: //super effective - if (gBattleMoves[move].power && !(*flags & MOVE_RESULT_NO_EFFECT)) - { - if (*flags & MOVE_RESULT_NOT_VERY_EFFECTIVE) - *flags &= ~MOVE_RESULT_NOT_VERY_EFFECTIVE; - else - *flags |= MOVE_RESULT_SUPER_EFFECTIVE; - } - break; - } -} - -u8 TypeCalc(u16 move, u8 bank_atk, u8 bank_def) -{ - int i = 0; - u8 flags = 0; - u8 move_type; - - if (move == MOVE_STRUGGLE) - return 0; - - move_type = gBattleMoves[move].type; - - //check stab - if (gBattleMons[bank_atk].type1 == move_type || gBattleMons[bank_atk].type2 == move_type) - { - gBattleMoveDamage = gBattleMoveDamage * 15; - gBattleMoveDamage = gBattleMoveDamage / 10; - } - - if (gBattleMons[bank_def].ability == ABILITY_LEVITATE && move_type == TYPE_GROUND) - { - flags |= (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE); - } - else - { - while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) - { - if (gTypeEffectiveness[i] == TYPE_FORESIGHT) - { - if (gBattleMons[bank_def].status2 & STATUS2_FORESIGHT) - break; - i += 3; - continue; - } - - else if (gTypeEffectiveness[i] == move_type) - { - //check type1 - if (gTypeEffectiveness[i + 1] == gBattleMons[bank_def].type1) - ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); - //check type2 - if (gTypeEffectiveness[i + 1] == gBattleMons[bank_def].type2 && - gBattleMons[gBankTarget /* what the christ */].type1 != gBattleMons[bank_def].type2) - ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); - } - i += 3; - } - } - - if (gBattleMons[bank_def].ability == ABILITY_WONDER_GUARD && !(flags & MOVE_RESULT_MISSED) && - AttacksThisTurn(bank_atk, move) == 2 && - (!(flags & MOVE_RESULT_SUPER_EFFECTIVE) || ((flags & (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE)) == (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE))) && - gBattleMoves[move].power) - { - flags |= MOVE_RESULT_MISSED; - } - return flags; -} - -u8 AI_TypeCalc(u16 move, u16 species, u8 ability) -{ - int i = 0; - u8 flags = 0; - u8 type1 = gBaseStats[species].type1, type2 = gBaseStats[species].type2, move_type; - - if (move == MOVE_STRUGGLE) - return 0; - - move_type = gBattleMoves[move].type; - - if (ability == ABILITY_LEVITATE && move_type == TYPE_GROUND) - flags = MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE; - else - { - while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) - { - if (gTypeEffectiveness[i] == TYPE_FORESIGHT) - { - i += 3; - continue; - } - if (gTypeEffectiveness[i] == move_type) - { - //check type1 - if (gTypeEffectiveness[i + 1] == type1) - ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); - //check type2 - if (gTypeEffectiveness[i + 1] == type2 && gBattleMons[gBankTarget].type1 != type2) //gf you morons, you should check if (type1 != type2)... - ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); - } - i += 3; - } - } - if (ability == ABILITY_WONDER_GUARD - && (!(flags & MOVE_RESULT_SUPER_EFFECTIVE) || ((flags & (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE)) == (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE))) - && gBattleMoves[move].power) - flags |= MOVE_RESULT_DOESNT_AFFECT_FOE; - return flags; -} - -// Multiplies the damage by a random factor between 85% to 100% inclusive -static inline void ApplyRandomDmgMultiplier(void) -{ - u16 rand = Random(); - u16 randPercent = 100 - (rand % 16); - - if (gBattleMoveDamage != 0) - { - gBattleMoveDamage *= randPercent; - gBattleMoveDamage /= 100; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - } -} - -void Unused_ApplyRandomDmgMultiplier(void) -{ - ApplyRandomDmgMultiplier(); -} - -static void atk07_adjustnormaldamage(void) -{ - u8 hold_effect, quality; - ApplyRandomDmgMultiplier(); - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - { - hold_effect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; - } - else - { - hold_effect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); - } - - gStringBank = gBankTarget; - - if (hold_effect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) - { - RecordItemBattle(gBankTarget, hold_effect); - gSpecialStatuses[gBankTarget].focusBanded = 1; - } - if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) - goto END; - if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE && !gProtectStructs[gBankTarget].endured - && !gSpecialStatuses[gBankTarget].focusBanded) - goto END; - - if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) - goto END; - - gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; - - if (gProtectStructs[gBankTarget].endured) - { - gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED; - goto END; - } - if (gSpecialStatuses[gBankTarget].focusBanded) - { - gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON; - gLastUsedItem = gBattleMons[gBankTarget].item; - } - - END: - gBattlescriptCurrInstr++; -} - -static void atk08_adjustnormaldamage2(void) //literally the same as 0x7 except it doesn't check for false swipe move effect... -{ - u8 hold_effect, quality; - ApplyRandomDmgMultiplier(); - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - { - hold_effect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; - } - else - { - hold_effect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); - } - - gStringBank = gBankTarget; - - if (hold_effect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) - { - RecordItemBattle(gBankTarget, hold_effect); - gSpecialStatuses[gBankTarget].focusBanded = 1; - } - if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) - goto END; - if (!gProtectStructs[gBankTarget].endured - && !gSpecialStatuses[gBankTarget].focusBanded) - goto END; - - if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) - goto END; - - gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; - - if (gProtectStructs[gBankTarget].endured) - { - gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED; - goto END; - } - if (gSpecialStatuses[gBankTarget].focusBanded) - { - gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON; - gLastUsedItem = gBattleMons[gBankTarget].item; - } - - END: - gBattlescriptCurrInstr++; -} - -static void atk09_attackanimation(void) -{ - if (gBattleExecBuffer) - return; - - if ((gHitMarker & HITMARKER_NO_ANIMATIONS) && (gCurrentMove != MOVE_TRANSFORM && gCurrentMove != MOVE_SUBSTITUTE)) - { - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_Pausex20; - gBattleStruct->animTurn += 1; - gBattleStruct->animTargetsHit += 1; - } - else - { - if ((gBattleMoves[gCurrentMove].target & TARGET_BOTH || gBattleMoves[gCurrentMove].target & TARGET_FOES_AND_ALLY || gBattleMoves[gCurrentMove].target & TARGET_DEPENDS) && gBattleStruct->animTargetsHit) - { - gBattlescriptCurrInstr++; - return; - } - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) - { - gActiveBattler = gBankAttacker; - - EmitMoveAnimation(0, gCurrentMove, gBattleStruct->animTurn, gBattleMovePower, gBattleMoveDamage, gBattleMons[gBankAttacker].friendship, &gDisableStructs[gBankAttacker]); - gBattleStruct->animTurn += 1; - gBattleStruct->animTargetsHit += 1; - MarkBufferBankForExecution(gBankAttacker); - gBattlescriptCurrInstr++; - } - else - { - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_Pausex20; - } - } -} - -static void atk0A_waitanimation(void) -{ - if (gBattleExecBuffer == 0) - gBattlescriptCurrInstr++; -} - -static void atk0B_healthbarupdate(void) -{ - if (gBattleExecBuffer) - return; - - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) - { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); - - if (gBattleMons[gActiveBattler].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBattler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) - { - PrepareStringBattle(0x80, gActiveBattler); - } - else - { - // Emerald - /* - s16 healthValue; - - s32 currDmg = gBattleMoveDamage; - s32 maxPossibleDmgValue = 10000; // not present in R/S, ensures that huge damage values don't change sign - - if (currDmg <= maxPossibleDmgValue) - healthValue = currDmg; - else - healthValue = maxPossibleDmgValue; - - EmitHealthBarUpdate(0, healthValue); - */ - - EmitHealthBarUpdate(0, gBattleMoveDamage); - MarkBufferBankForExecution(gActiveBattler); - - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER && gBattleMoveDamage > 0) - gBattleResults.unk5_0 = 1; - } - } - - gBattlescriptCurrInstr += 2; -} - -static void atk0C_datahpupdate(void) -{ - u32 moveType; - - if (gBattleExecBuffer) - return; - - if (gBattleStruct->dynamicMoveType == 0) - moveType = gBattleMoves[gCurrentMove].type; - else if (!(gBattleStruct->dynamicMoveType & 0x40)) - moveType = gBattleStruct->dynamicMoveType & 0x3F; - else - moveType = gBattleMoves[gCurrentMove].type; - - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) - { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); - if (gBattleMons[gActiveBattler].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBattler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) - { - if (gDisableStructs[gActiveBattler].substituteHP >= gBattleMoveDamage) - { - if (gSpecialStatuses[gActiveBattler].moveturnLostHP == 0) - gSpecialStatuses[gActiveBattler].moveturnLostHP = gBattleMoveDamage; - gDisableStructs[gActiveBattler].substituteHP -= gBattleMoveDamage; - gHpDealt = gBattleMoveDamage; - } - else - { - if (gSpecialStatuses[gActiveBattler].moveturnLostHP == 0) - gSpecialStatuses[gActiveBattler].moveturnLostHP = gDisableStructs[gActiveBattler].substituteHP; - gHpDealt = gDisableStructs[gActiveBattler].substituteHP; - gDisableStructs[gActiveBattler].substituteHP = 0; - } - // check substitute fading - if (gDisableStructs[gActiveBattler].substituteHP == 0) - { - gBattlescriptCurrInstr += 2; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_SubstituteFade; - return; - } - } - else - { - gHitMarker &= ~(HITMARKER_IGNORE_SUBSTITUTE); - if (gBattleMoveDamage < 0) // hp goes up - { - gBattleMons[gActiveBattler].hp -= gBattleMoveDamage; - if (gBattleMons[gActiveBattler].hp > gBattleMons[gActiveBattler].maxHP) - gBattleMons[gActiveBattler].hp = gBattleMons[gActiveBattler].maxHP; - - } - else // hp goes down - { - if (gHitMarker & HITMARKER_x20) - { - gHitMarker &= ~(HITMARKER_x20); - } - else - { - gTakenDmg[gActiveBattler] += gBattleMoveDamage; - if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) - gTakenDmgBanks[gActiveBattler] = gBankAttacker; - else - gTakenDmgBanks[gActiveBattler] = gBankTarget; - } - - if (gBattleMons[gActiveBattler].hp > gBattleMoveDamage) - { - gBattleMons[gActiveBattler].hp -= gBattleMoveDamage; - gHpDealt = gBattleMoveDamage; - } - else - { - gHpDealt = gBattleMons[gActiveBattler].hp; - gBattleMons[gActiveBattler].hp = 0; - } - - if (!gSpecialStatuses[gActiveBattler].moveturnLostHP && !(gHitMarker & HITMARKER_x100000)) - gSpecialStatuses[gActiveBattler].moveturnLostHP = gHpDealt; - - if (TYPE_IS_PHYSICAL(moveType) && !(gHitMarker & HITMARKER_x100000) && gCurrentMove != MOVE_PAIN_SPLIT) - { - gProtectStructs[gActiveBattler].physicalDmg = gHpDealt; - gSpecialStatuses[gActiveBattler].moveturnLostHP_physical = gHpDealt; - if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) - { - gProtectStructs[gActiveBattler].physicalBank = gBankAttacker; - gSpecialStatuses[gActiveBattler].moveturnPhysicalBank = gBankAttacker; - } - else - { - gProtectStructs[gActiveBattler].physicalBank = gBankTarget; - gSpecialStatuses[gActiveBattler].moveturnPhysicalBank = gBankTarget; - } - } - else if (!TYPE_IS_PHYSICAL(moveType) && !(gHitMarker & HITMARKER_x100000)) - { - gProtectStructs[gActiveBattler].specialDmg = gHpDealt; - gSpecialStatuses[gActiveBattler].moveturnLostHP_special = gHpDealt; - if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) - { - gProtectStructs[gActiveBattler].specialBank = gBankAttacker; - gSpecialStatuses[gActiveBattler].moveturnSpecialBank = gBankAttacker; - } - else - { - gProtectStructs[gActiveBattler].specialBank = gBankTarget; - gSpecialStatuses[gActiveBattler].moveturnSpecialBank = gBankTarget; - } - } - } - gHitMarker &= ~(HITMARKER_x100000); - EmitSetMonData(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBattler].hp); - MarkBufferBankForExecution(gActiveBattler); - } - } - else - { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); - if (gSpecialStatuses[gActiveBattler].moveturnLostHP == 0) - gSpecialStatuses[gActiveBattler].moveturnLostHP = 0xFFFF; - } - gBattlescriptCurrInstr += 2; -} - -static void atk0D_critmessage(void) -{ - if (gBattleExecBuffer == 0) - { - if (gCritMultiplier == 2 && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) - { - PrepareStringBattle(0xD9, gBankAttacker); - gBattleCommunication[MSG_DISPLAY] = 1; - } - gBattlescriptCurrInstr++; - } -} - -static void atk0E_effectivenesssound(void) -{ - if (gBattleExecBuffer) - return; - - gActiveBattler = gBankTarget; - if (!(gMoveResultFlags & MOVE_RESULT_MISSED)) - { - u8 flag = ~MOVE_RESULT_MISSED; - switch (gMoveResultFlags & flag) - { - case MOVE_RESULT_SUPER_EFFECTIVE: - EmitEffectivenessSound(0, 14); - MarkBufferBankForExecution(gActiveBattler); - break; - case MOVE_RESULT_NOT_VERY_EFFECTIVE: - EmitEffectivenessSound(0, 12); - MarkBufferBankForExecution(gActiveBattler); - break; - case MOVE_RESULT_DOESNT_AFFECT_FOE: - case MOVE_RESULT_FAILED: - break; - case MOVE_RESULT_FOE_ENDURED: - case MOVE_RESULT_ONE_HIT_KO: - case MOVE_RESULT_FOE_HUNG_ON: - default: - if (gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) - { - EmitEffectivenessSound(0, 14); - MarkBufferBankForExecution(gActiveBattler); - } - else if (gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE) - { - EmitEffectivenessSound(0, 12); - MarkBufferBankForExecution(gActiveBattler); - } - else if (!(gMoveResultFlags & (MOVE_RESULT_DOESNT_AFFECT_FOE | MOVE_RESULT_FAILED))) - { - EmitEffectivenessSound(0, 13); - MarkBufferBankForExecution(gActiveBattler); - } - break; - } - } - gBattlescriptCurrInstr++; -} - -static void atk0F_resultmessage(void) -{ - u32 stringId = 0; - - if (gBattleExecBuffer) - return; - - if (gMoveResultFlags & MOVE_RESULT_MISSED && (!(gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) || gBattleCommunication[6] > 2)) - { - stringId = gMissStringIds[gBattleCommunication[6]]; - gBattleCommunication[MSG_DISPLAY] = 1; - } - else - { - gBattleCommunication[MSG_DISPLAY] = 1; - switch (gMoveResultFlags & (u8)(~(MOVE_RESULT_MISSED))) - { - case MOVE_RESULT_SUPER_EFFECTIVE: - stringId = STRINGID_SUPEREFFECTIVE; - break; - case MOVE_RESULT_NOT_VERY_EFFECTIVE: - stringId = STRINGID_NOTVERYEFFECTIVE; - break; - case MOVE_RESULT_ONE_HIT_KO: - stringId = STRINGID_ONEHITKO; - break; - case MOVE_RESULT_FOE_ENDURED: - stringId = STRINGID_PKMNENDUREDHIT; - break; - case MOVE_RESULT_FAILED: - stringId = STRINGID_BUTITFAILED; - break; - case MOVE_RESULT_DOESNT_AFFECT_FOE: - stringId = STRINGID_ITDOESNTAFFECT; - break; - case MOVE_RESULT_FOE_HUNG_ON: - gLastUsedItem = gBattleMons[gBankTarget].item; - gStringBank = gBankTarget; - gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_HangedOnMsg; - return; - default: - if (gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) - { - stringId = STRINGID_ITDOESNTAFFECT; - } - else if (gMoveResultFlags & MOVE_RESULT_ONE_HIT_KO) - { - gMoveResultFlags &= ~(MOVE_RESULT_ONE_HIT_KO); - gMoveResultFlags &= ~(MOVE_RESULT_SUPER_EFFECTIVE); - gMoveResultFlags &= ~(MOVE_RESULT_NOT_VERY_EFFECTIVE); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_OneHitKOMsg; - return; - } - else if (gMoveResultFlags & MOVE_RESULT_FOE_ENDURED) - { - gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_EnduredMsg; - return; - } - else if (gMoveResultFlags & MOVE_RESULT_FOE_HUNG_ON) - { - gLastUsedItem = gBattleMons[gBankTarget].item; - gStringBank = gBankTarget; - gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_HangedOnMsg; - return; - } - else if (gMoveResultFlags & MOVE_RESULT_FAILED) - { - stringId = STRINGID_BUTITFAILED; - } - else - { - gBattleCommunication[MSG_DISPLAY] = 0; - } - } - } - - if (stringId) - PrepareStringBattle(stringId, gBankAttacker); - - gBattlescriptCurrInstr++; -} - -static void atk10_printstring(void) -{ - if (gBattleExecBuffer == 0) - { - u16 var = T2_READ_16(gBattlescriptCurrInstr + 1); - PrepareStringBattle(var, gBankAttacker); - gBattlescriptCurrInstr += 3; - gBattleCommunication[MSG_DISPLAY] = 1; - } -} - -static void atk11_printselectionstring(void) -{ - gActiveBattler = gBankAttacker; - EmitPrintStringPlayerOnly(0, T2_READ_16(gBattlescriptCurrInstr + 1)); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 3; - gBattleCommunication[MSG_DISPLAY] = 1; -} - -static void atk12_waitmessage(void) -{ - if (gBattleExecBuffer == 0) - { - if (!gBattleCommunication[MSG_DISPLAY]) - { - gBattlescriptCurrInstr += 3; - } - else - { - u16 to_wait = T2_READ_16(gBattlescriptCurrInstr + 1); - if (++gPauseCounterBattle >= to_wait) - { - gPauseCounterBattle = 0; - gBattlescriptCurrInstr += 3; - gBattleCommunication[MSG_DISPLAY] = 0; - } - } - } -} - -static void atk13_printfromtable(void) -{ - if (gBattleExecBuffer == 0) - { - u16 *ptr = (u16 *)T1_READ_PTR(gBattlescriptCurrInstr + 1); - ptr += gBattleCommunication[MULTISTRING_CHOOSER]; - PrepareStringBattle(*(u16*)ptr, gBankAttacker); - gBattlescriptCurrInstr += 5; - gBattleCommunication[MSG_DISPLAY] = 1; - } -} - -static void atk14_printselectionstringfromtable(void) -{ - if (gBattleExecBuffer == 0) - { - u16 *ptr = (u16 *)T1_READ_PTR(gBattlescriptCurrInstr + 1); // FIXME - ptr += gBattleCommunication[MULTISTRING_CHOOSER]; - gActiveBattler = gBankAttacker; - EmitPrintStringPlayerOnly(0, *(u16*)ptr); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 5; - gBattleCommunication[MSG_DISPLAY] = 1; - } -} - -u8 BankGetTurnOrder(u8 bank) -{ - int i; - for (i = 0; i < gBattlersCount; i++) - { - if (gBanksByTurnOrder[i] == bank) - break; - } - return i; -} - -//Someone please decompile this monstrosity below... -#ifdef NONMATCHING -void SetMoveEffect(bool8 primary, u8 certainArg) -{ - #define EffectAffectsUser 0x40 - register u8 certain asm("r5") = certainArg; - register bool32 StatusChanged asm("r10") = 0; - register int AffectsUser asm("r6") = 0; //0x40 otherwise - bool32 NoSunCanFreeze = 1; - - if (gBattleCommunication[MOVE_EFFECT_BYTE] & EffectAffectsUser) - { - gEffectBank = gBankAttacker; //bank that effects get applied on - gBattleCommunication[MOVE_EFFECT_BYTE] &= ~(EffectAffectsUser); - AffectsUser = EffectAffectsUser; - gBattleStruct->scriptingActive = gBankTarget; //theoretically the attacker - } - else - { - gEffectBank = gBankTarget; - gBattleStruct->scriptingActive = gBankAttacker; - } - - if (gBattleMons[gEffectBank].ability == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && - !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 9) - {gBattlescriptCurrInstr++; return;} - - if (gSideAffecting[GetBattlerPosition(gEffectBank) & 1] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && - !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 7) - {gBattlescriptCurrInstr++; return;} - - //make sure at least ONE HP except payday and thief - if (gBattleMons[gEffectBank].hp == 0 && gBattleCommunication[MOVE_EFFECT_BYTE] != 0xB && gBattleCommunication[MOVE_EFFECT_BYTE] != 0x1F) - {gBattlescriptCurrInstr++; return;} - - if (gBattleMons[gEffectBank].status2 & STATUS2_SUBSTITUTE && AffectsUser != EffectAffectsUser) - {gBattlescriptCurrInstr++; return;} - - if (gBattleCommunication[MOVE_EFFECT_BYTE] <= 6) //status change - { - switch (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) - { - case STATUS_SLEEP: - //check active uproar - if (gBattleMons[gEffectBank].ability != ABILITY_SOUNDPROOF) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount && !(gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR); gActiveBattler++) {} - } - else - gActiveBattler = gBattlersCount; - if (gBattleMons[gEffectBank].status1) {break;} - if (gActiveBattler != gBattlersCount) {break;} //nice way of checking uproar... - if (gBattleMons[gEffectBank].ability == ABILITY_VITAL_SPIRIT) {break;} - if (gBattleMons[gEffectBank].ability == ABILITY_INSOMNIA) {break;} - - CancelMultiTurnMoves(gEffectBank); - StatusChanged = 1; - break; - case STATUS_POISON: - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY && (primary == 1 || certain == 0x80)) - { - gLastUsedAbility = ABILITY_IMMUNITY; - RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); - BattleScriptPush(gBattlescriptCurrInstr + 1); - //_0801E664: - gBattlescriptCurrInstr = BattleScript_PSNPrevention; - if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); - return; - } - else - {gBattleCommunication[MULTISTRING_CHOOSER] = 0; return;} - } - if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) - && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && (primary == 1 || certain == 0x80)) - { - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_PSNPrevention; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - return; - } - if (gBattleMons[gEffectBank].type1 == TYPE_POISON) {break;} - if (gBattleMons[gEffectBank].type2 == TYPE_POISON) {break;} - if (gBattleMons[gEffectBank].type1 == TYPE_STEEL) {break;} - if (gBattleMons[gEffectBank].type2 == TYPE_STEEL) {break;} - if (gBattleMons[gEffectBank].status1) {break;} - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY) {break;} - - StatusChanged = 1; - break; - case STATUS_BURN: - if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL && (primary == 1 || certain == 0x80)) - { - gLastUsedAbility = ABILITY_WATER_VEIL; - RecordAbilityBattle(gEffectBank, ABILITY_WATER_VEIL); - BattleScriptPush(gBattlescriptCurrInstr + 1); - //_0801E664: - gBattlescriptCurrInstr = BattleScript_BRNPrevention; - if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); - return; - } - else - {gBattleCommunication[MULTISTRING_CHOOSER] = 0; return;} - } - if ((gBattleMons[gEffectBank].type1 == TYPE_FIRE || gBattleMons[gEffectBank].type2 == TYPE_FIRE) - && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && (primary == 1 || certain == 0x80)) - { - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_BRNPrevention; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - return; - } - if (gBattleMons[gEffectBank].type1 == TYPE_FIRE) {break;} - if (gBattleMons[gEffectBank].type2 == TYPE_FIRE) {break;} - if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL) {break;} - if (gBattleMons[gEffectBank].status1 == 0) {break;} - StatusChanged = 1; - break; - case STATUS_FREEZE: - if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY) {NoSunCanFreeze = 0;} - if (gBattleMons[gEffectBank].type1 == TYPE_ICE) {break;} - if (gBattleMons[gEffectBank].type2 == TYPE_ICE) {break;} - if (gBattleMons[gEffectBank].status1) {break;} - if (NoSunCanFreeze == 0) {break;} - if (gBattleMons[gEffectBank].ability == ABILITY_MAGMA_ARMOR) {break;} - - CancelMultiTurnMoves(gEffectBank); - StatusChanged = 1; - break; - case STATUS_PARALYSIS: - if (gBattleMons[gEffectBank].ability == ABILITY_LIMBER) - { - if ((primary == 1 || certain == 0x80)) - { - gLastUsedAbility = ABILITY_LIMBER; - RecordAbilityBattle(gEffectBank, ABILITY_LIMBER); - BattleScriptPush(gBattlescriptCurrInstr + 1); - //_0801E664: - gBattlescriptCurrInstr = BattleScript_PRLZPrevention; - if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); - return; - } - else - {gBattleCommunication[MULTISTRING_CHOOSER] = 0; return;} - } - else {break;} - } - if (gBattleMons[gEffectBank].status1) {break;} - StatusChanged = 1; - break; - case STATUS_TOXIC_POISON: - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY && (primary == 1 || certain == 0x80)) - { - gLastUsedAbility = ABILITY_IMMUNITY; - RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); - BattleScriptPush(gBattlescriptCurrInstr + 1); - //_0801E664: - gBattlescriptCurrInstr = BattleScript_PSNPrevention; - if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); - return; - } - else - {gBattleCommunication[MULTISTRING_CHOOSER] = 0; return;} - } - if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) - && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && (primary == 1 || certain == 0x80)) - { - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_PSNPrevention; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - return; - } - if (gBattleMons[gEffectBank].status1) {break;} - if (gBattleMons[gEffectBank].type1 != TYPE_POISON && - gBattleMons[gEffectBank].type2 != TYPE_POISON && - gBattleMons[gEffectBank].type1 != TYPE_STEEL && - gBattleMons[gEffectBank].type2 != TYPE_STEEL) - { - if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY) {break;} - gBattleMons[gEffectBank].status1 &= ~(0x9); //This gets (correctly) optimized out... - StatusChanged = 1; - break; - } - else - gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE; - break; - } - if (StatusChanged == 1) - { - BattleScriptPush(gBattlescriptCurrInstr + 1); - if (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]] == STATUS_SLEEP) - gBattleMons[gEffectBank].status1 |= ((Random() & 3) + 2); - else - gBattleMons[gEffectBank].status1 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - gActiveBattler = gEffectBank; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gEffectBank].status1); - MarkBufferBankForExecution(gActiveBattler); - if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); - } - else - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - if (gBattleCommunication[MOVE_EFFECT_BYTE] == 2 || gBattleCommunication[MOVE_EFFECT_BYTE] == 6 || gBattleCommunication[MOVE_EFFECT_BYTE] == 5 || gBattleCommunication[MOVE_EFFECT_BYTE] == 3) - { - gBattleStruct->synchroniseEffect = gBattleCommunication[MOVE_EFFECT_BYTE]; - gHitMarker |= HITMARKER_SYNCHRONISE_EFFECT; - } - return; - } - else if (StatusChanged == 0) - {gBattlescriptCurrInstr++; return;} - } - else - { - if (gBattleMons[gEffectBank].status2 & sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) - { - gBattlescriptCurrInstr++; - return; - } - switch (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) - { - case 7: //confusion - if (gBattleMons[gEffectBank].ability == ABILITY_OWN_TEMPO) - {gBattlescriptCurrInstr++; return;} - if (gBattleMons[gEffectBank].status2 & STATUS2_CONFUSION) - {gBattlescriptCurrInstr++; return;} - gBattleMons[gEffectBank].status2 |= (((Random()) % 0x4)) + 2; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - break; - case 8: //flinch - if (gBattleMons[gEffectBank].ability == ABILITY_INNER_FOCUS) - { - if (primary == 1 || certain == 0x80) - { - gLastUsedAbility = ABILITY_INNER_FOCUS; - RecordAbilityBattle(gEffectBank, ABILITY_INNER_FOCUS); - gBattlescriptCurrInstr = BattleScript_FlinchPrevention; - return; - } - else - {gBattlescriptCurrInstr++; return;} - } - else - { - if (BankGetTurnOrder(gEffectBank) > gCurrentTurnActionNumber) - gBattleMons[gEffectBank].status2 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; - gBattlescriptCurrInstr++; return; - } - break; - case 10: //uproar - if (gBattleMons[gEffectBank].status2 & STATUS2_UPROAR) - {gBattlescriptCurrInstr++; return;} - gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gEffectBank] = gCurrentMove; - gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 2) << 4; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - break; - case 11: //pay day - if (!(GetBattlerPosition(gBankAttacker) & 1)) - { - u16 PayDay = gPaydayMoney; - gPaydayMoney += (gBattleMons[gBankAttacker].level * 5); - if (PayDay > gPaydayMoney) - gPaydayMoney = 0xFFFF; - } - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - break; - case 9: //tri attack - if (gBattleMons[gEffectBank].status1) - {gBattlescriptCurrInstr++; return;} - gBattleCommunication[MOVE_EFFECT_BYTE] = Random() % 3 + 3; - SetMoveEffect(0, 0); - break; - case 12: //charging move - gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gEffectBank] = gCurrentMove; - gProtectStructs[gEffectBank].chargingTurn = 1; - gBattlescriptCurrInstr++; - break; - case 13: //wrap - if (gBattleMons[gEffectBank].status2 & STATUS2_WRAPPED) - {gBattlescriptCurrInstr++; return;} - gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 2) << 0xD; - gBattleStruct->wrappedMove[gEffectBank*2] = (u8)gCurrentMove; - (1 + gBattleStruct->wrappedMove)[gEffectBank*2] = gCurrentMove >> 8; //don't ask. - gBattleStruct->wrappedBy[gEffectBank] = gBankAttacker; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - while (gBattleCommunication[MULTISTRING_CHOOSER] <= 4 - && gCurrentMove != gTrappingMoves[gBattleCommunication[MULTISTRING_CHOOSER]]) - gBattleCommunication[MULTISTRING_CHOOSER]++; - break; - case 14: //25% recoil - gBattleMoveDamage = (gHpDealt) / 4; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - break; - case 15 ... 21: //stat + 1 - if (ChangeStatBuffs(0x10, gBattleCommunication[MOVE_EFFECT_BYTE] + 0xF2, certain, 0)) {gBattlescriptCurrInstr++;} - else - { - gBattleStruct->animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; //TODO: the arg ptr is wrong by one - gBattleStruct->animArg2 = 0; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_StatUp; - } - break; - case 22 ... 28: //stat - 1 - if (ChangeStatBuffs(~(0x6f), gBattleCommunication[MOVE_EFFECT_BYTE] + 0xEB, certain, 0)) {gBattlescriptCurrInstr++;} //TODO: negation doesnt work correctly - else - { - gBattleStruct->animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; - gBattleStruct->animArg2 = 0; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_StatDown; - } - break; - case 39 ... 45: //stat + 2 - if (ChangeStatBuffs(0x20, gBattleCommunication[MOVE_EFFECT_BYTE] + 0xDA, certain, 0)) {gBattlescriptCurrInstr++;} - else - { - gBattleStruct->animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; - gBattleStruct->animArg2 = 0; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_StatUp; - } - break; - case 46 ... 52: //stat - 2 - if (ChangeStatBuffs(~(0x5f), gBattleCommunication[MOVE_EFFECT_BYTE] + 0xD3, certain, 0)) {gBattlescriptCurrInstr++;} - else - { - gBattleStruct->animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; - gBattleStruct->animArg2 = 0; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_StatDown; - } - break; - case 29: //recharge - gBattleMons[gEffectBank].status2 |= STATUS2_RECHARGE; - gDisableStructs[gEffectBank].rechargeCounter = 2; - gLockedMoves[gEffectBank] = gCurrentMove; - gBattlescriptCurrInstr++; - break; - case 30: //rage - gBattleMons[gBankAttacker].status2 |= STATUS2_RAGE; - gBattlescriptCurrInstr++; - break; - case 31: //item steal - { - u8 side = GetBattlerSide(gBankAttacker); - if (GetBattlerSide(gBankAttacker) == 1 && !(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK)) && gTrainerBattleOpponent != 0x400) - {gBattlescriptCurrInstr++; return;} - if (!(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK)) && gTrainerBattleOpponent != 0x400 && (gWishFutureKnock.knockedOffPokes[side] & gBitTable[gBattlerPartyIndexes[gBankAttacker]])) - {gBattlescriptCurrInstr++; return;} - if (gBattleMons[gBankTarget].item && gBattleMons[gBankTarget].ability == ABILITY_STICKY_HOLD) - { - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_NoItemSteal; - gLastUsedAbility = gBattleMons[gBankTarget].ability; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - return; - } - if (gBattleMons[gBankAttacker].item) - {gBattlescriptCurrInstr++; return;} - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - {gBattlescriptCurrInstr++; return;} - if (gBattleMons[gBankTarget].item == 0) - {gBattlescriptCurrInstr++; return;} - - gLastUsedItem = gBattleMons[gBankTarget].item; - USED_HELD_ITEM(bank) = gLastUsedItem; - gBattleMons[gBankTarget].item = 0; - - gActiveBattler = gBankAttacker; - EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gLastUsedItem); - MarkBufferBankForExecution(gBankAttacker); - - gActiveBattler = gBankTarget; - EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBankTarget].item); - MarkBufferBankForExecution(gBankTarget); - - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_ItemSteal; - - CHOICED_MOVE(gBankTarget) = 0; - } - break; - case 32: //escape prevention - gBattleMons[gBankTarget].status2 |= STATUS2_RECHARGE; - gDisableStructs[gBankTarget].bankPreventingEscape = gBankAttacker; - gBattlescriptCurrInstr++; - break; - case 33: //nightmare - gBattleMons[gBankTarget].status2 |= STATUS2_NIGHTMARE; - gBattlescriptCurrInstr++; - break; - case 34: //ancientpower - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_AllStatsUp; - return; - case 35: //break free rapidspin - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_RapidSpinAway; - return; - case 36: //paralysis removal - if (gBattleMons[gBankTarget].status1 & STATUS_PARALYSIS) - { - gBattleMons[gBankTarget].status1 &= ~(STATUS_PARALYSIS); - gActiveBattler = gBankTarget; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBankTarget].status1); - MarkBufferBankForExecution(gActiveBattler); - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal; - } - else - {gBattlescriptCurrInstr++; return;} - break; - case 37: //superpower - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_AtkDefDown; - return; - case 38: //33% recoil - gBattleMoveDamage = gHpDealt / 3; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; - break; - case 53: //thrash - if (!(gBattleMons[gEffectBank].status2 & STATUS2_LOCK_CONFUSE)) - { - gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gEffectBank] = gCurrentMove; - gBattleMons[gEffectBank].status2 |= (((Random() & 1) + 2) << 0xA); - } - else - {gBattlescriptCurrInstr++; return;} - break; - case 54: //knock off - if (gBattleMons[gEffectBank].ability == ABILITY_STICKY_HOLD) - { - if (gBattleMons[gEffectBank].item == 0) - {gBattlescriptCurrInstr++; return;} - gLastUsedAbility = ABILITY_STICKY_HOLD; - gBattlescriptCurrInstr = BattleScript_NoItemSteal; - RecordAbilityBattle(gEffectBank, ABILITY_STICKY_HOLD); - return; - } - if (gBattleMons[gEffectBank].item == 0) - {gBattlescriptCurrInstr++; return;} - else - { - u8 side = GetBattlerSide(gEffectBank); - gLastUsedItem = gBattleMons[gEffectBank].item; - gBattleMons[gEffectBank].item = 0; - gWishFutureKnock.knockedOffPokes[side] |= gBitTable[gBattlerPartyIndexes[gEffectBank]]; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_KnockedOff; - - CHOICED_MOVE(gEffectBank) = 0; - } - break; - case 59: //overheat - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_SAtkDown2; - return; - } - } -} -#else -NAKED -void SetMoveEffect(bool8 primary, u8 certainArg) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x8\n\ - lsls r0, 24\n\ - lsrs r4, r0, 24\n\ - lsls r1, 24\n\ - lsrs r5, r1, 24\n\ - movs r0, 0\n\ - mov r10, r0\n\ - movs r6, 0\n\ - movs r1, 0x1\n\ - str r1, [sp, 0x4]\n\ - ldr r1, _0801E430 @ =gBattleCommunication\n\ - ldrb r3, [r1, 0x3]\n\ - movs r0, 0x40\n\ - ands r0, r3\n\ - adds r7, r1, 0\n\ - cmp r0, 0\n\ - beq _0801E444\n\ - ldr r2, _0801E434 @ =gEffectBank\n\ - ldr r0, _0801E438 @ =gBankAttacker\n\ - ldrb r0, [r0]\n\ - strb r0, [r2]\n\ - movs r0, 0xBF\n\ - ands r0, r3\n\ - strb r0, [r7, 0x3]\n\ - movs r6, 0x40\n\ - ldr r0, _0801E43C @ =gSharedMem\n\ - ldr r1, _0801E440 @ =gBankTarget\n\ - b _0801E450\n\ - .align 2, 0\n\ -_0801E430: .4byte gBattleCommunication\n\ -_0801E434: .4byte gEffectBank\n\ -_0801E438: .4byte gBankAttacker\n\ -_0801E43C: .4byte gSharedMem\n\ -_0801E440: .4byte gBankTarget\n\ -_0801E444:\n\ - ldr r2, _0801E538 @ =gEffectBank\n\ - ldr r0, _0801E53C @ =gBankTarget\n\ - ldrb r0, [r0]\n\ - strb r0, [r2]\n\ - ldr r0, _0801E540 @ =gSharedMem\n\ - ldr r1, _0801E544 @ =gBankAttacker\n\ -_0801E450:\n\ - ldrb r1, [r1]\n\ - ldr r3, _0801E548 @ =0x00016003\n\ - adds r0, r3\n\ - strb r1, [r0]\n\ - mov r8, r2\n\ - ldr r2, _0801E54C @ =gBattleMons\n\ - mov r0, r8\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r2\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x13\n\ - bne _0801E48A\n\ - ldr r0, _0801E550 @ =gHitMarker\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 6\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _0801E48A\n\ - cmp r4, 0\n\ - bne _0801E48A\n\ - ldrb r0, [r7, 0x3]\n\ - cmp r0, 0x9\n\ - bhi _0801E48A\n\ - bl _0801F5DC\n\ -_0801E48A:\n\ - mov r1, r8\n\ - ldrb r0, [r1]\n\ - bl GetBattlerPosition\n\ - ldr r2, _0801E554 @ =gSideAffecting\n\ - movs r1, 0x1\n\ - ands r1, r0\n\ - lsls r1, 1\n\ - adds r1, r2\n\ - ldrh r1, [r1]\n\ - movs r0, 0x20\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0801E4C4\n\ - ldr r0, _0801E550 @ =gHitMarker\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 6\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _0801E4C4\n\ - cmp r4, 0\n\ - bne _0801E4C4\n\ - ldr r0, _0801E558 @ =gBattleCommunication\n\ - ldrb r0, [r0, 0x3]\n\ - cmp r0, 0x7\n\ - bhi _0801E4C4\n\ - bl _0801F5DC\n\ -_0801E4C4:\n\ - ldr r3, _0801E54C @ =gBattleMons\n\ - ldr r2, _0801E538 @ =gEffectBank\n\ - ldrb r1, [r2]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r3\n\ - ldrh r0, [r0, 0x28]\n\ - mov r8, r2\n\ - mov r9, r3\n\ - cmp r0, 0\n\ - bne _0801E4EA\n\ - ldr r0, _0801E558 @ =gBattleCommunication\n\ - ldrb r0, [r0, 0x3]\n\ - cmp r0, 0xB\n\ - beq _0801E4EA\n\ - cmp r0, 0x1F\n\ - beq _0801E4EA\n\ - bl _0801F5DC\n\ -_0801E4EA:\n\ - mov r2, r8\n\ - ldrb r1, [r2]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - mov r1, r9\n\ - adds r1, 0x50\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 17\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0801E50C\n\ - cmp r6, 0x40\n\ - beq _0801E50C\n\ - bl _0801F5DC\n\ -_0801E50C:\n\ - ldr r0, _0801E558 @ =gBattleCommunication\n\ - ldrb r1, [r0, 0x3]\n\ - adds r7, r0, 0\n\ - cmp r1, 0x6\n\ - bls _0801E518\n\ - b _0801EB4A\n\ -_0801E518:\n\ - ldr r1, _0801E55C @ =sStatusFlagsForMoveEffects\n\ - ldrb r0, [r7, 0x3]\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - cmp r0, 0x10\n\ - bne _0801E528\n\ - b _0801E714\n\ -_0801E528:\n\ - cmp r0, 0x10\n\ - bhi _0801E560\n\ - cmp r0, 0x7\n\ - beq _0801E57A\n\ - cmp r0, 0x8\n\ - bne _0801E536\n\ - b _0801E630\n\ -_0801E536:\n\ - b _0801EA14\n\ - .align 2, 0\n\ -_0801E538: .4byte gEffectBank\n\ -_0801E53C: .4byte gBankTarget\n\ -_0801E540: .4byte gSharedMem\n\ -_0801E544: .4byte gBankAttacker\n\ -_0801E548: .4byte 0x00016003\n\ -_0801E54C: .4byte gBattleMons\n\ -_0801E550: .4byte gHitMarker\n\ -_0801E554: .4byte gSideAffecting\n\ -_0801E558: .4byte gBattleCommunication\n\ -_0801E55C: .4byte sStatusFlagsForMoveEffects\n\ -_0801E560:\n\ - cmp r0, 0x40\n\ - bne _0801E566\n\ - b _0801E888\n\ -_0801E566:\n\ - cmp r0, 0x40\n\ - bhi _0801E572\n\ - cmp r0, 0x20\n\ - bne _0801E570\n\ - b _0801E7EA\n\ -_0801E570:\n\ - b _0801EA14\n\ -_0801E572:\n\ - cmp r0, 0x80\n\ - bne _0801E578\n\ - b _0801E8E4\n\ -_0801E578:\n\ - b _0801EA14\n\ -_0801E57A:\n\ - mov r3, r8\n\ - ldrb r1, [r3]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - add r0, r9\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x2B\n\ - beq _0801E5DC\n\ - ldr r0, _0801E5D4 @ =gActiveBattler\n\ - movs r1, 0\n\ - strb r1, [r0]\n\ - ldr r1, _0801E5D8 @ =gBattlersCount\n\ - ldrb r3, [r1]\n\ - adds r7, r0, 0\n\ - mov r12, r1\n\ - cmp r3, 0\n\ - beq _0801E5E8\n\ - mov r4, r9\n\ - ldr r0, [r4, 0x50]\n\ - movs r1, 0x70\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _0801E5E8\n\ - adds r1, r7, 0\n\ - mov r6, r9\n\ - adds r6, 0x50\n\ - movs r5, 0x58\n\ - movs r4, 0x70\n\ -_0801E5B4:\n\ - ldrb r0, [r1]\n\ - adds r0, 0x1\n\ - strb r0, [r1]\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, r3\n\ - bcs _0801E5E8\n\ - ldrb r0, [r7]\n\ - muls r0, r5\n\ - adds r0, r6\n\ - ldr r0, [r0]\n\ - ands r0, r4\n\ - cmp r0, 0\n\ - beq _0801E5B4\n\ - b _0801E5E8\n\ - .align 2, 0\n\ -_0801E5D4: .4byte gActiveBattler\n\ -_0801E5D8: .4byte gBattlersCount\n\ -_0801E5DC:\n\ - ldr r0, _0801E628 @ =gActiveBattler\n\ - ldr r2, _0801E62C @ =gBattlersCount\n\ - ldrb r1, [r2]\n\ - strb r1, [r0]\n\ - adds r7, r0, 0\n\ - mov r12, r2\n\ -_0801E5E8:\n\ - mov r0, r8\n\ - ldrb r2, [r0]\n\ - movs r0, 0x58\n\ - adds r1, r2, 0\n\ - muls r1, r0\n\ - mov r0, r9\n\ - adds r0, 0x4C\n\ - adds r0, r1, r0\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - beq _0801E600\n\ - b _0801EA14\n\ -_0801E600:\n\ - ldrb r0, [r7]\n\ - mov r3, r12\n\ - ldrb r3, [r3]\n\ - cmp r0, r3\n\ - beq _0801E60C\n\ - b _0801EA14\n\ -_0801E60C:\n\ - mov r4, r9\n\ - adds r0, r1, r4\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x48\n\ - bne _0801E61A\n\ - b _0801EA14\n\ -_0801E61A:\n\ - cmp r0, 0xF\n\ - bne _0801E620\n\ - b _0801EA14\n\ -_0801E620:\n\ - adds r0, r2, 0\n\ - bl CancelMultiTurnMoves\n\ - b _0801EA04\n\ - .align 2, 0\n\ -_0801E628: .4byte gActiveBattler\n\ -_0801E62C: .4byte gBattlersCount\n\ -_0801E630:\n\ - mov r2, r8\n\ - ldrb r1, [r2]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - add r0, r9\n\ - adds r0, 0x20\n\ - ldrb r1, [r0]\n\ - cmp r1, 0x11\n\ - bne _0801E688\n\ - cmp r4, 0x1\n\ - beq _0801E64A\n\ - cmp r5, 0x80\n\ - bne _0801E688\n\ -_0801E64A:\n\ - ldr r0, _0801E678 @ =gLastUsedAbility\n\ - strb r1, [r0]\n\ - mov r3, r8\n\ - ldrb r0, [r3]\n\ - movs r1, 0x11\n\ - bl RecordAbilityBattle\n\ - ldr r4, _0801E67C @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801E680 @ =BattleScript_PSNPrevention\n\ -_0801E664:\n\ - str r0, [r4]\n\ - ldr r2, _0801E684 @ =gHitMarker\n\ - ldr r1, [r2]\n\ - movs r0, 0x80\n\ - lsls r0, 6\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0801E676\n\ - b _0801E928\n\ -_0801E676:\n\ - b _0801E94C\n\ - .align 2, 0\n\ -_0801E678: .4byte gLastUsedAbility\n\ -_0801E67C: .4byte gBattlescriptCurrInstr\n\ -_0801E680: .4byte BattleScript_PSNPrevention\n\ -_0801E684: .4byte gHitMarker\n\ -_0801E688:\n\ - mov r1, r8\n\ - ldrb r0, [r1]\n\ - movs r1, 0x58\n\ - muls r0, r1\n\ - add r0, r9\n\ - adds r1, r0, 0\n\ - adds r1, 0x21\n\ - ldrb r1, [r1]\n\ - cmp r1, 0x3\n\ - beq _0801E6AC\n\ - adds r0, 0x22\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x3\n\ - beq _0801E6AC\n\ - cmp r1, 0x8\n\ - beq _0801E6AC\n\ - cmp r0, 0x8\n\ - bne _0801E6C6\n\ -_0801E6AC:\n\ - ldr r0, _0801E710 @ =gHitMarker\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 6\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0801E6C6\n\ - cmp r4, 0x1\n\ - bne _0801E6C0\n\ - b _0801E98C\n\ -_0801E6C0:\n\ - cmp r5, 0x80\n\ - bne _0801E6C6\n\ - b _0801E98C\n\ -_0801E6C6:\n\ - mov r2, r8\n\ - ldrb r1, [r2]\n\ - movs r0, 0x58\n\ - muls r1, r0\n\ - mov r4, r9\n\ - adds r3, r1, r4\n\ - adds r0, r3, 0\n\ - adds r0, 0x21\n\ - ldrb r4, [r0]\n\ - cmp r4, 0x3\n\ - bne _0801E6DE\n\ - b _0801EA14\n\ -_0801E6DE:\n\ - adds r0, 0x1\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x3\n\ - bne _0801E6E8\n\ - b _0801EA14\n\ -_0801E6E8:\n\ - cmp r4, 0x8\n\ - bne _0801E6EE\n\ - b _0801EA14\n\ -_0801E6EE:\n\ - cmp r0, 0x8\n\ - bne _0801E6F4\n\ - b _0801EA14\n\ -_0801E6F4:\n\ - mov r0, r9\n\ - adds r0, 0x4C\n\ - adds r0, r1, r0\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - beq _0801E702\n\ - b _0801EA14\n\ -_0801E702:\n\ - adds r0, r3, 0\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x11\n\ - bne _0801E70E\n\ - b _0801EA14\n\ -_0801E70E:\n\ - b _0801EA04\n\ - .align 2, 0\n\ -_0801E710: .4byte gHitMarker\n\ -_0801E714:\n\ - mov r2, r8\n\ - ldrb r1, [r2]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - add r0, r9\n\ - adds r0, 0x20\n\ - ldrb r1, [r0]\n\ - cmp r1, 0x29\n\ - bne _0801E758\n\ - cmp r4, 0x1\n\ - beq _0801E72E\n\ - cmp r5, 0x80\n\ - bne _0801E758\n\ -_0801E72E:\n\ - ldr r0, _0801E74C @ =gLastUsedAbility\n\ - strb r1, [r0]\n\ - mov r3, r8\n\ - ldrb r0, [r3]\n\ - movs r1, 0x29\n\ - bl RecordAbilityBattle\n\ - ldr r4, _0801E750 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801E754 @ =BattleScript_BRNPrevention\n\ - b _0801E664\n\ - .align 2, 0\n\ -_0801E74C: .4byte gLastUsedAbility\n\ -_0801E750: .4byte gBattlescriptCurrInstr\n\ -_0801E754: .4byte BattleScript_BRNPrevention\n\ -_0801E758:\n\ - mov r0, r8\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - mov r2, r9\n\ - adds r1, r0, r2\n\ - adds r0, r1, 0\n\ - adds r0, 0x21\n\ - ldrb r0, [r0]\n\ - cmp r0, 0xA\n\ - beq _0801E778\n\ - adds r0, r1, 0\n\ - adds r0, 0x22\n\ - ldrb r0, [r0]\n\ - cmp r0, 0xA\n\ - bne _0801E7A8\n\ -_0801E778:\n\ - ldr r0, _0801E79C @ =gHitMarker\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 6\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0801E7A8\n\ - cmp r4, 0x1\n\ - beq _0801E78E\n\ - cmp r5, 0x80\n\ - bne _0801E7A8\n\ -_0801E78E:\n\ - ldr r4, _0801E7A0 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801E7A4 @ =BattleScript_BRNPrevention\n\ - b _0801E998\n\ - .align 2, 0\n\ -_0801E79C: .4byte gHitMarker\n\ -_0801E7A0: .4byte gBattlescriptCurrInstr\n\ -_0801E7A4: .4byte BattleScript_BRNPrevention\n\ -_0801E7A8:\n\ - mov r3, r8\n\ - ldrb r0, [r3]\n\ - movs r1, 0x58\n\ - adds r2, r0, 0\n\ - muls r2, r1\n\ - mov r4, r9\n\ - adds r1, r2, r4\n\ - adds r0, r1, 0\n\ - adds r0, 0x21\n\ - ldrb r0, [r0]\n\ - cmp r0, 0xA\n\ - bne _0801E7C2\n\ - b _0801EA14\n\ -_0801E7C2:\n\ - adds r0, r1, 0\n\ - adds r0, 0x22\n\ - ldrb r0, [r0]\n\ - cmp r0, 0xA\n\ - bne _0801E7CE\n\ - b _0801EA14\n\ -_0801E7CE:\n\ - adds r0, r1, 0\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x29\n\ - bne _0801E7DA\n\ - b _0801EA14\n\ -_0801E7DA:\n\ - mov r0, r9\n\ - adds r0, 0x4C\n\ - adds r0, r2, r0\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - beq _0801E7E8\n\ - b _0801EA14\n\ -_0801E7E8:\n\ - b _0801EA04\n\ -_0801E7EA:\n\ - movs r0, 0\n\ - str r0, [sp]\n\ - movs r0, 0x13\n\ - movs r1, 0\n\ - movs r2, 0xD\n\ - movs r3, 0\n\ - bl AbilityBattleEffects\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0\n\ - bne _0801E826\n\ - str r0, [sp]\n\ - movs r0, 0x13\n\ - movs r1, 0\n\ - movs r2, 0x4D\n\ - movs r3, 0\n\ - bl AbilityBattleEffects\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _0801E826\n\ - ldr r0, _0801E87C @ =gBattleWeather\n\ - ldrh r1, [r0]\n\ - movs r0, 0x60\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0801E826\n\ - movs r1, 0\n\ - str r1, [sp, 0x4]\n\ -_0801E826:\n\ - ldr r4, _0801E880 @ =gBattleMons\n\ - ldr r0, _0801E884 @ =gEffectBank\n\ - ldrb r3, [r0]\n\ - movs r0, 0x58\n\ - adds r2, r3, 0\n\ - muls r2, r0\n\ - adds r1, r2, r4\n\ - adds r0, r1, 0\n\ - adds r0, 0x21\n\ - ldrb r0, [r0]\n\ - cmp r0, 0xF\n\ - bne _0801E840\n\ - b _0801EA14\n\ -_0801E840:\n\ - adds r0, r1, 0\n\ - adds r0, 0x22\n\ - ldrb r0, [r0]\n\ - cmp r0, 0xF\n\ - bne _0801E84C\n\ - b _0801EA14\n\ -_0801E84C:\n\ - adds r0, r4, 0\n\ - adds r0, 0x4C\n\ - adds r0, r2, r0\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - beq _0801E85A\n\ - b _0801EA14\n\ -_0801E85A:\n\ - ldr r2, [sp, 0x4]\n\ - cmp r2, 0\n\ - bne _0801E862\n\ - b _0801EA14\n\ -_0801E862:\n\ - adds r0, r1, 0\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x28\n\ - bne _0801E86E\n\ - b _0801EA14\n\ -_0801E86E:\n\ - adds r0, r3, 0\n\ - bl CancelMultiTurnMoves\n\ - movs r3, 0x1\n\ - mov r10, r3\n\ - b _0801EA14\n\ - .align 2, 0\n\ -_0801E87C: .4byte gBattleWeather\n\ -_0801E880: .4byte gBattleMons\n\ -_0801E884: .4byte gEffectBank\n\ -_0801E888:\n\ - mov r0, r8\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - muls r1, r0\n\ - mov r2, r9\n\ - adds r0, r1, r2\n\ - adds r0, 0x20\n\ - ldrb r2, [r0]\n\ - cmp r2, 0x7\n\ - bne _0801E8D0\n\ - cmp r4, 0x1\n\ - beq _0801E8A6\n\ - cmp r5, 0x80\n\ - beq _0801E8A6\n\ - b _0801EA14\n\ -_0801E8A6:\n\ - ldr r0, _0801E8C4 @ =gLastUsedAbility\n\ - strb r2, [r0]\n\ - mov r3, r8\n\ - ldrb r0, [r3]\n\ - movs r1, 0x7\n\ - bl RecordAbilityBattle\n\ - ldr r4, _0801E8C8 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801E8CC @ =BattleScript_PRLZPrevention\n\ - b _0801E664\n\ - .align 2, 0\n\ -_0801E8C4: .4byte gLastUsedAbility\n\ -_0801E8C8: .4byte gBattlescriptCurrInstr\n\ -_0801E8CC: .4byte BattleScript_PRLZPrevention\n\ -_0801E8D0:\n\ - mov r0, r9\n\ - adds r0, 0x4C\n\ - adds r0, r1, r0\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - beq _0801E8DE\n\ - b _0801EA14\n\ -_0801E8DE:\n\ - movs r4, 0x1\n\ - mov r10, r4\n\ - b _0801EA14\n\ -_0801E8E4:\n\ - mov r0, r8\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - add r0, r9\n\ - adds r0, 0x20\n\ - ldrb r1, [r0]\n\ - cmp r1, 0x11\n\ - bne _0801E952\n\ - cmp r4, 0x1\n\ - beq _0801E8FE\n\ - cmp r5, 0x80\n\ - bne _0801E952\n\ -_0801E8FE:\n\ - ldr r0, _0801E938 @ =gLastUsedAbility\n\ - strb r1, [r0]\n\ - mov r1, r8\n\ - ldrb r0, [r1]\n\ - movs r1, 0x11\n\ - bl RecordAbilityBattle\n\ - ldr r4, _0801E93C @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801E940 @ =BattleScript_PSNPrevention\n\ - str r0, [r4]\n\ - ldr r2, _0801E944 @ =gHitMarker\n\ - ldr r1, [r2]\n\ - movs r0, 0x80\n\ - lsls r0, 6\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0801E94C\n\ -_0801E928:\n\ - movs r0, 0x1\n\ - strb r0, [r7, 0x5]\n\ - ldr r0, _0801E948 @ =0xffffdfff\n\ - ands r1, r0\n\ - str r1, [r2]\n\ - bl _0801F5FA\n\ - .align 2, 0\n\ -_0801E938: .4byte gLastUsedAbility\n\ -_0801E93C: .4byte gBattlescriptCurrInstr\n\ -_0801E940: .4byte BattleScript_PSNPrevention\n\ -_0801E944: .4byte gHitMarker\n\ -_0801E948: .4byte 0xffffdfff\n\ -_0801E94C:\n\ - strb r0, [r7, 0x5]\n\ - bl _0801F5FA\n\ -_0801E952:\n\ - mov r2, r8\n\ - ldrb r0, [r2]\n\ - movs r1, 0x58\n\ - muls r0, r1\n\ - add r0, r9\n\ - adds r1, r0, 0\n\ - adds r1, 0x21\n\ - ldrb r1, [r1]\n\ - cmp r1, 0x3\n\ - beq _0801E976\n\ - adds r0, 0x22\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x3\n\ - beq _0801E976\n\ - cmp r1, 0x8\n\ - beq _0801E976\n\ - cmp r0, 0x8\n\ - bne _0801E9B4\n\ -_0801E976:\n\ - ldr r0, _0801E9A4 @ =gHitMarker\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 6\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0801E9B4\n\ - cmp r4, 0x1\n\ - beq _0801E98C\n\ - cmp r5, 0x80\n\ - bne _0801E9B4\n\ -_0801E98C:\n\ - ldr r4, _0801E9A8 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801E9AC @ =BattleScript_PSNPrevention\n\ -_0801E998:\n\ - str r0, [r4]\n\ - ldr r1, _0801E9B0 @ =gBattleCommunication\n\ - movs r0, 0x2\n\ - strb r0, [r1, 0x5]\n\ - bl _0801F5FA\n\ - .align 2, 0\n\ -_0801E9A4: .4byte gHitMarker\n\ -_0801E9A8: .4byte gBattlescriptCurrInstr\n\ -_0801E9AC: .4byte BattleScript_PSNPrevention\n\ -_0801E9B0: .4byte gBattleCommunication\n\ -_0801E9B4:\n\ - mov r3, r8\n\ - ldrb r0, [r3]\n\ - movs r6, 0x58\n\ - muls r0, r6\n\ - mov r2, r9\n\ - adds r2, 0x4C\n\ - adds r5, r0, r2\n\ - ldr r4, [r5]\n\ - cmp r4, 0\n\ - bne _0801EA14\n\ - mov r3, r9\n\ - adds r1, r0, r3\n\ - adds r0, r1, 0\n\ - adds r0, 0x21\n\ - ldrb r3, [r0]\n\ - cmp r3, 0x3\n\ - beq _0801EA0A\n\ - adds r0, 0x1\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x3\n\ - beq _0801EA0A\n\ - cmp r3, 0x8\n\ - beq _0801EA0A\n\ - cmp r0, 0x8\n\ - beq _0801EA0A\n\ - adds r0, r1, 0\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x11\n\ - beq _0801EA14\n\ - mov r4, r8\n\ - ldrb r0, [r4]\n\ - adds r1, r0, 0\n\ - muls r1, r6\n\ - adds r1, r2\n\ - ldr r0, [r1]\n\ - movs r2, 0x9\n\ - negs r2, r2\n\ - ands r0, r2\n\ - str r0, [r1]\n\ -_0801EA04:\n\ - movs r0, 0x1\n\ - mov r10, r0\n\ - b _0801EA14\n\ -_0801EA0A:\n\ - ldr r0, _0801EA58 @ =gMoveResultFlags\n\ - ldrb r1, [r0]\n\ - movs r2, 0x8\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ -_0801EA14:\n\ - mov r1, r10\n\ - cmp r1, 0x1\n\ - beq _0801EA1C\n\ - b _0801EB3C\n\ -_0801EA1C:\n\ - ldr r0, _0801EA5C @ =gBattlescriptCurrInstr\n\ - ldr r0, [r0]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r1, _0801EA60 @ =sStatusFlagsForMoveEffects\n\ - ldr r0, _0801EA64 @ =gBattleCommunication\n\ - ldrb r0, [r0, 0x3]\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldr r3, [r0]\n\ - cmp r3, 0x7\n\ - bne _0801EA70\n\ - bl Random\n\ - ldr r2, _0801EA68 @ =gBattleMons\n\ - ldr r1, _0801EA6C @ =gEffectBank\n\ - ldrb r3, [r1]\n\ - movs r1, 0x58\n\ - muls r3, r1\n\ - adds r2, 0x4C\n\ - adds r3, r2\n\ - movs r1, 0x3\n\ - ands r1, r0\n\ - adds r1, 0x2\n\ - ldr r0, [r3]\n\ - orrs r0, r1\n\ - str r0, [r3]\n\ - b _0801EA84\n\ - .align 2, 0\n\ -_0801EA58: .4byte gMoveResultFlags\n\ -_0801EA5C: .4byte gBattlescriptCurrInstr\n\ -_0801EA60: .4byte sStatusFlagsForMoveEffects\n\ -_0801EA64: .4byte gBattleCommunication\n\ -_0801EA68: .4byte gBattleMons\n\ -_0801EA6C: .4byte gEffectBank\n\ -_0801EA70:\n\ - ldr r2, _0801EAD4 @ =gBattleMons\n\ - ldr r0, _0801EAD8 @ =gEffectBank\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - muls r1, r0\n\ - adds r2, 0x4C\n\ - adds r1, r2\n\ - ldr r0, [r1]\n\ - orrs r0, r3\n\ - str r0, [r1]\n\ -_0801EA84:\n\ - ldr r2, _0801EADC @ =gBattlescriptCurrInstr\n\ - ldr r1, _0801EAE0 @ =gMoveEffectBS_Ptrs\n\ - ldr r5, _0801EAE4 @ =gBattleCommunication\n\ - ldrb r0, [r5, 0x3]\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - str r0, [r2]\n\ - ldr r4, _0801EAE8 @ =gActiveBattler\n\ - ldr r1, _0801EAD8 @ =gEffectBank\n\ - ldrb r0, [r1]\n\ - strb r0, [r4]\n\ - ldrb r1, [r1]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - ldr r1, _0801EAEC @ =gBattleMons+0x4C @ gBattleMons.status1\n\ - adds r0, r1\n\ - str r0, [sp]\n\ - movs r0, 0\n\ - movs r1, 0x28\n\ - movs r2, 0\n\ - movs r3, 0x4\n\ - bl EmitSetMonData\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - ldr r2, _0801EAF0 @ =gHitMarker\n\ - ldr r1, [r2]\n\ - movs r0, 0x80\n\ - lsls r0, 6\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0801EAF8\n\ - movs r0, 0x1\n\ - strb r0, [r5, 0x5]\n\ - ldr r0, _0801EAF4 @ =0xffffdfff\n\ - ands r1, r0\n\ - str r1, [r2]\n\ - b _0801EAFA\n\ - .align 2, 0\n\ -_0801EAD4: .4byte gBattleMons\n\ -_0801EAD8: .4byte gEffectBank\n\ -_0801EADC: .4byte gBattlescriptCurrInstr\n\ -_0801EAE0: .4byte gMoveEffectBS_Ptrs\n\ -_0801EAE4: .4byte gBattleCommunication\n\ -_0801EAE8: .4byte gActiveBattler\n\ -_0801EAEC: .4byte gBattleMons+0x4C @ gBattleMons.status1\n\ -_0801EAF0: .4byte gHitMarker\n\ -_0801EAF4: .4byte 0xffffdfff\n\ -_0801EAF8:\n\ - strb r0, [r5, 0x5]\n\ -_0801EAFA:\n\ - ldr r0, _0801EB2C @ =gBattleCommunication\n\ - ldrb r2, [r0, 0x3]\n\ - adds r7, r0, 0\n\ - cmp r2, 0x2\n\ - beq _0801EB14\n\ - cmp r2, 0x6\n\ - beq _0801EB14\n\ - cmp r2, 0x5\n\ - beq _0801EB14\n\ - cmp r2, 0x3\n\ - beq _0801EB14\n\ - bl _0801F5FA\n\ -_0801EB14:\n\ - ldr r0, _0801EB30 @ =gSharedMem\n\ - ldrb r1, [r7, 0x3]\n\ - ldr r2, _0801EB34 @ =0x000160ca\n\ - adds r0, r2\n\ - strb r1, [r0]\n\ - ldr r2, _0801EB38 @ =gHitMarker\n\ - ldr r0, [r2]\n\ - movs r1, 0x80\n\ - lsls r1, 7\n\ - bl _0801F4F2\n\ - .align 2, 0\n\ -_0801EB2C: .4byte gBattleCommunication\n\ -_0801EB30: .4byte gSharedMem\n\ -_0801EB34: .4byte 0x000160ca\n\ -_0801EB38: .4byte gHitMarker\n\ -_0801EB3C:\n\ - mov r3, r10\n\ - cmp r3, 0\n\ - beq _0801EB46\n\ - bl _0801F5FA\n\ -_0801EB46:\n\ - bl _0801F5DC\n\ -_0801EB4A:\n\ - mov r0, r8\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - muls r1, r0\n\ - mov r0, r9\n\ - adds r0, 0x50\n\ - adds r1, r0\n\ - ldr r2, _0801EB84 @ =sStatusFlagsForMoveEffects\n\ - ldrb r3, [r7, 0x3]\n\ - lsls r0, r3, 2\n\ - adds r0, r2\n\ - ldr r1, [r1]\n\ - ldr r0, [r0]\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - beq _0801EB6E\n\ - bl _0801F5DC\n\ -_0801EB6E:\n\ - subs r0, r3, 0x7\n\ - cmp r0, 0x34\n\ - bls _0801EB78\n\ - bl _0801F5FA\n\ -_0801EB78:\n\ - lsls r0, 2\n\ - ldr r1, _0801EB88 @ =_0801EB8C\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - mov pc, r0\n\ - .align 2, 0\n\ -_0801EB84: .4byte sStatusFlagsForMoveEffects\n\ -_0801EB88: .4byte _0801EB8C\n\ - .align 2, 0\n\ -_0801EB8C:\n\ - .4byte _0801EC60\n\ - .4byte _0801ECD4\n\ - .4byte _0801EE4C\n\ - .4byte _0801ED60\n\ - .4byte _0801EDDC\n\ - .4byte _0801EE84\n\ - .4byte _0801EECC\n\ - .4byte _0801EFA8\n\ - .4byte _0801EFEC\n\ - .4byte _0801EFEC\n\ - .4byte _0801EFEC\n\ - .4byte _0801EFEC\n\ - .4byte _0801EFEC\n\ - .4byte _0801EFEC\n\ - .4byte _0801EFEC\n\ - .4byte _0801F040\n\ - .4byte _0801F040\n\ - .4byte _0801F040\n\ - .4byte _0801F040\n\ - .4byte _0801F040\n\ - .4byte _0801F040\n\ - .4byte _0801F040\n\ - .4byte _0801F13C\n\ - .4byte _0801F184\n\ - .4byte _0801F1A4\n\ - .4byte _0801F364\n\ - .4byte _0801F3A0\n\ - .4byte _0801F3BC\n\ - .4byte _0801F3D4\n\ - .4byte _0801F3EC\n\ - .4byte _0801F44C\n\ - .4byte _0801F464\n\ - .4byte _0801F094\n\ - .4byte _0801F094\n\ - .4byte _0801F094\n\ - .4byte _0801F094\n\ - .4byte _0801F094\n\ - .4byte _0801F094\n\ - .4byte _0801F094\n\ - .4byte _0801F0E8\n\ - .4byte _0801F0E8\n\ - .4byte _0801F0E8\n\ - .4byte _0801F0E8\n\ - .4byte _0801F0E8\n\ - .4byte _0801F0E8\n\ - .4byte _0801F0E8\n\ - .4byte _0801F4A8\n\ - .4byte _0801F500\n\ - .4byte _0801F5FA\n\ - .4byte _0801F5FA\n\ - .4byte _0801F5FA\n\ - .4byte _0801F5FA\n\ - .4byte _0801F5EC\n\ -_0801EC60:\n\ - mov r1, r8\n\ - ldrb r0, [r1]\n\ - movs r5, 0x58\n\ - adds r1, r0, 0\n\ - muls r1, r5\n\ - mov r2, r9\n\ - adds r0, r1, r2\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x14\n\ - bne _0801EC7A\n\ - bl _0801F5DC\n\ -_0801EC7A:\n\ - mov r4, r9\n\ - adds r4, 0x50\n\ - adds r0, r1, r4\n\ - ldr r0, [r0]\n\ - movs r1, 0x7\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0801EC8E\n\ - bl _0801F5DC\n\ -_0801EC8E:\n\ - bl Random\n\ - mov r3, r8\n\ - ldrb r1, [r3]\n\ - adds r2, r1, 0\n\ - muls r2, r5\n\ - adds r2, r4\n\ - lsls r0, 16\n\ - movs r1, 0xC0\n\ - lsls r1, 10\n\ - ands r1, r0\n\ - lsrs r1, 16\n\ - adds r1, 0x2\n\ - ldr r0, [r2]\n\ - orrs r0, r1\n\ - str r0, [r2]\n\ - ldr r4, _0801ECC8 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r1, _0801ECCC @ =gMoveEffectBS_Ptrs\n\ - ldr r0, _0801ECD0 @ =gBattleCommunication\n\ - ldrb r0, [r0, 0x3]\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - bl _0801F5F8\n\ - .align 2, 0\n\ -_0801ECC8: .4byte gBattlescriptCurrInstr\n\ -_0801ECCC: .4byte gMoveEffectBS_Ptrs\n\ -_0801ECD0: .4byte gBattleCommunication\n\ -_0801ECD4:\n\ - mov r0, r8\n\ - ldrb r2, [r0]\n\ - movs r6, 0x58\n\ - adds r0, r2, 0\n\ - muls r0, r6\n\ - add r0, r9\n\ - adds r0, 0x20\n\ - ldrb r1, [r0]\n\ - cmp r1, 0x27\n\ - bne _0801ED18\n\ - cmp r4, 0x1\n\ - beq _0801ECF4\n\ - cmp r5, 0x80\n\ - beq _0801ECF4\n\ - bl _0801F5DC\n\ -_0801ECF4:\n\ - ldr r0, _0801ED0C @ =gLastUsedAbility\n\ - strb r1, [r0]\n\ - mov r1, r8\n\ - ldrb r0, [r1]\n\ - movs r1, 0x27\n\ - bl RecordAbilityBattle\n\ - ldr r1, _0801ED10 @ =gBattlescriptCurrInstr\n\ - ldr r0, _0801ED14 @ =BattleScript_FlinchPrevention\n\ - str r0, [r1]\n\ - bl _0801F5FA\n\ - .align 2, 0\n\ -_0801ED0C: .4byte gLastUsedAbility\n\ -_0801ED10: .4byte gBattlescriptCurrInstr\n\ -_0801ED14: .4byte BattleScript_FlinchPrevention\n\ -_0801ED18:\n\ - adds r0, r2, 0\n\ - bl BankGetTurnOrder\n\ - ldr r1, _0801ED54 @ =gCurrentTurnActionNumber\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - ldrb r1, [r1]\n\ - cmp r0, r1\n\ - bhi _0801ED2E\n\ - bl _0801F5DC\n\ -_0801ED2E:\n\ - mov r2, r8\n\ - ldrb r0, [r2]\n\ - adds r2, r0, 0\n\ - muls r2, r6\n\ - mov r0, r9\n\ - adds r0, 0x50\n\ - adds r2, r0\n\ - ldr r1, _0801ED58 @ =sStatusFlagsForMoveEffects\n\ - ldr r0, _0801ED5C @ =gBattleCommunication\n\ - ldrb r0, [r0, 0x3]\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldr r1, [r2]\n\ - ldr r0, [r0]\n\ - orrs r1, r0\n\ - str r1, [r2]\n\ - bl _0801F5DC\n\ - .align 2, 0\n\ -_0801ED54: .4byte gCurrentTurnActionNumber\n\ -_0801ED58: .4byte sStatusFlagsForMoveEffects\n\ -_0801ED5C: .4byte gBattleCommunication\n\ -_0801ED60:\n\ - mov r3, r8\n\ - ldrb r0, [r3]\n\ - movs r5, 0x58\n\ - muls r0, r5\n\ - mov r4, r9\n\ - adds r4, 0x50\n\ - adds r2, r0, r4\n\ - ldr r1, [r2]\n\ - movs r0, 0x70\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0801ED7C\n\ - bl _0801F5DC\n\ -_0801ED7C:\n\ - movs r0, 0x80\n\ - lsls r0, 5\n\ - orrs r1, r0\n\ - str r1, [r2]\n\ - ldr r1, _0801EDC8 @ =gLockedMoves\n\ - ldrb r0, [r3]\n\ - lsls r0, 1\n\ - adds r0, r1\n\ - ldr r1, _0801EDCC @ =gCurrentMove\n\ - ldrh r1, [r1]\n\ - strh r1, [r0]\n\ - bl Random\n\ - mov r2, r8\n\ - ldrb r1, [r2]\n\ - adds r2, r1, 0\n\ - muls r2, r5\n\ - adds r2, r4\n\ - movs r1, 0x3\n\ - ands r1, r0\n\ - adds r1, 0x2\n\ - lsls r1, 4\n\ - ldr r0, [r2]\n\ - orrs r0, r1\n\ - str r0, [r2]\n\ - ldr r4, _0801EDD0 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r1, _0801EDD4 @ =gMoveEffectBS_Ptrs\n\ - ldr r0, _0801EDD8 @ =gBattleCommunication\n\ - ldrb r0, [r0, 0x3]\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - bl _0801F5F8\n\ - .align 2, 0\n\ -_0801EDC8: .4byte gLockedMoves\n\ -_0801EDCC: .4byte gCurrentMove\n\ -_0801EDD0: .4byte gBattlescriptCurrInstr\n\ -_0801EDD4: .4byte gMoveEffectBS_Ptrs\n\ -_0801EDD8: .4byte gBattleCommunication\n\ -_0801EDDC:\n\ - ldr r5, _0801EE30 @ =gBankAttacker\n\ - ldrb r0, [r5]\n\ - bl GetBattlerPosition\n\ - movs r1, 0x1\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - bne _0801EE14\n\ - ldr r4, _0801EE34 @ =gPaydayMoney\n\ - ldrh r3, [r4]\n\ - ldr r2, _0801EE38 @ =gBattleMons\n\ - ldrb r1, [r5]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r2\n\ - adds r0, 0x2A\n\ - ldrb r1, [r0]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - adds r0, r3, r0\n\ - strh r0, [r4]\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - cmp r3, r0\n\ - bls _0801EE14\n\ - ldr r3, _0801EE3C @ =0x0000ffff\n\ - adds r0, r3, 0\n\ - strh r0, [r4]\n\ -_0801EE14:\n\ - ldr r4, _0801EE40 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r1, _0801EE44 @ =gMoveEffectBS_Ptrs\n\ - ldr r0, _0801EE48 @ =gBattleCommunication\n\ - ldrb r0, [r0, 0x3]\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - bl _0801F5F8\n\ - .align 2, 0\n\ -_0801EE30: .4byte gBankAttacker\n\ -_0801EE34: .4byte gPaydayMoney\n\ -_0801EE38: .4byte gBattleMons\n\ -_0801EE3C: .4byte 0x0000ffff\n\ -_0801EE40: .4byte gBattlescriptCurrInstr\n\ -_0801EE44: .4byte gMoveEffectBS_Ptrs\n\ -_0801EE48: .4byte gBattleCommunication\n\ -_0801EE4C:\n\ - mov r4, r8\n\ - ldrb r1, [r4]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - mov r1, r9\n\ - adds r1, 0x4C\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - beq _0801EE62\n\ - b _0801F5DC\n\ -_0801EE62:\n\ - bl Random\n\ - ldr r4, _0801EE80 @ =gBattleCommunication\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - movs r1, 0x3\n\ - bl __umodsi3\n\ - adds r0, 0x3\n\ - strb r0, [r4, 0x3]\n\ - movs r0, 0\n\ - movs r1, 0\n\ - bl SetMoveEffect\n\ - b _0801F5FA\n\ - .align 2, 0\n\ -_0801EE80: .4byte gBattleCommunication\n\ -_0801EE84:\n\ - mov r0, r8\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - adds r2, r1, 0\n\ - muls r2, r0\n\ - mov r0, r9\n\ - adds r0, 0x50\n\ - adds r2, r0\n\ - ldr r0, [r2]\n\ - movs r1, 0x80\n\ - lsls r1, 5\n\ - orrs r0, r1\n\ - str r0, [r2]\n\ - ldr r1, _0801EEC0 @ =gLockedMoves\n\ - mov r2, r8\n\ - ldrb r0, [r2]\n\ - lsls r0, 1\n\ - adds r0, r1\n\ - ldr r1, _0801EEC4 @ =gCurrentMove\n\ - ldrh r1, [r1]\n\ - strh r1, [r0]\n\ - ldr r0, _0801EEC8 @ =gProtectStructs\n\ - ldrb r1, [r2]\n\ - lsls r1, 4\n\ - adds r1, r0\n\ - ldrb r0, [r1, 0x1]\n\ - movs r2, 0x4\n\ - orrs r0, r2\n\ - strb r0, [r1, 0x1]\n\ - b _0801F5DC\n\ - .align 2, 0\n\ -_0801EEC0: .4byte gLockedMoves\n\ -_0801EEC4: .4byte gCurrentMove\n\ -_0801EEC8: .4byte gProtectStructs\n\ -_0801EECC:\n\ - mov r3, r8\n\ - ldrb r0, [r3]\n\ - movs r6, 0x58\n\ - muls r0, r6\n\ - mov r4, r9\n\ - adds r4, 0x50\n\ - adds r0, r4\n\ - ldr r5, [r0]\n\ - movs r0, 0xE0\n\ - lsls r0, 8\n\ - ands r5, r0\n\ - cmp r5, 0\n\ - beq _0801EEE8\n\ - b _0801F5DC\n\ -_0801EEE8:\n\ - bl Random\n\ - mov r2, r8\n\ - ldrb r1, [r2]\n\ - adds r2, r1, 0\n\ - muls r2, r6\n\ - adds r2, r4\n\ - movs r1, 0x3\n\ - ands r1, r0\n\ - adds r1, 0x3\n\ - lsls r1, 13\n\ - ldr r0, [r2]\n\ - orrs r0, r1\n\ - str r0, [r2]\n\ - ldr r2, _0801EF80 @ =gSharedMem\n\ - mov r3, r8\n\ - ldrb r0, [r3]\n\ - lsls r0, 1\n\ - ldr r4, _0801EF84 @ =0x00016004\n\ - adds r0, r4\n\ - adds r0, r2\n\ - ldr r6, _0801EF88 @ =gCurrentMove\n\ - ldrh r1, [r6]\n\ - strb r1, [r0]\n\ - ldrb r0, [r3]\n\ - lsls r0, 1\n\ - ldr r1, _0801EF8C @ =0x00016005\n\ - adds r0, r1\n\ - adds r0, r2\n\ - ldrh r1, [r6]\n\ - lsrs r1, 8\n\ - strb r1, [r0]\n\ - ldrb r0, [r3]\n\ - ldr r3, _0801EF90 @ =0x00016020\n\ - adds r0, r3\n\ - adds r0, r2\n\ - ldr r1, _0801EF94 @ =gBankAttacker\n\ - ldrb r1, [r1]\n\ - strb r1, [r0]\n\ - ldr r4, _0801EF98 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r1, _0801EF9C @ =gMoveEffectBS_Ptrs\n\ - ldr r2, _0801EFA0 @ =gBattleCommunication\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - str r0, [r4]\n\ - strb r5, [r2, 0x5]\n\ - ldr r1, _0801EFA4 @ =gTrappingMoves\n\ - ldrh r0, [r1]\n\ - ldrh r4, [r6]\n\ - cmp r0, r4\n\ - bne _0801EF5C\n\ - b _0801F5FA\n\ -_0801EF5C:\n\ - adds r3, r1, 0\n\ - adds r1, r6, 0\n\ -_0801EF60:\n\ - ldrb r0, [r2, 0x5]\n\ - adds r0, 0x1\n\ - strb r0, [r2, 0x5]\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0x4\n\ - bls _0801EF70\n\ - b _0801F5FA\n\ -_0801EF70:\n\ - ldrb r0, [r2, 0x5]\n\ - lsls r0, 1\n\ - adds r0, r3\n\ - ldrh r0, [r0]\n\ - ldrh r4, [r1]\n\ - cmp r0, r4\n\ - bne _0801EF60\n\ - b _0801F5FA\n\ - .align 2, 0\n\ -_0801EF80: .4byte gSharedMem\n\ -_0801EF84: .4byte 0x00016004\n\ -_0801EF88: .4byte gCurrentMove\n\ -_0801EF8C: .4byte 0x00016005\n\ -_0801EF90: .4byte 0x00016020\n\ -_0801EF94: .4byte gBankAttacker\n\ -_0801EF98: .4byte gBattlescriptCurrInstr\n\ -_0801EF9C: .4byte gMoveEffectBS_Ptrs\n\ -_0801EFA0: .4byte gBattleCommunication\n\ -_0801EFA4: .4byte gTrappingMoves\n\ -_0801EFA8:\n\ - ldr r1, _0801EFD8 @ =gBattleMoveDamage\n\ - ldr r0, _0801EFDC @ =gHpDealt\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - bge _0801EFB4\n\ - adds r0, 0x3\n\ -_0801EFB4:\n\ - asrs r0, 2\n\ - str r0, [r1]\n\ - cmp r0, 0\n\ - bne _0801EFC0\n\ - movs r0, 0x1\n\ - str r0, [r1]\n\ -_0801EFC0:\n\ - ldr r4, _0801EFE0 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r1, _0801EFE4 @ =gMoveEffectBS_Ptrs\n\ - ldr r0, _0801EFE8 @ =gBattleCommunication\n\ - ldrb r0, [r0, 0x3]\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - b _0801F5F8\n\ - .align 2, 0\n\ -_0801EFD8: .4byte gBattleMoveDamage\n\ -_0801EFDC: .4byte gHpDealt\n\ -_0801EFE0: .4byte gBattlescriptCurrInstr\n\ -_0801EFE4: .4byte gMoveEffectBS_Ptrs\n\ -_0801EFE8: .4byte gBattleCommunication\n\ -_0801EFEC:\n\ - ldrb r1, [r7, 0x3]\n\ - adds r1, 0xF2\n\ - lsls r1, 24\n\ - lsrs r1, 24\n\ - movs r0, 0x10\n\ - adds r2, r6, 0\n\ - movs r3, 0\n\ - bl ChangeStatBuffs\n\ - lsls r0, 24\n\ - lsrs r3, r0, 24\n\ - cmp r3, 0\n\ - beq _0801F008\n\ - b _0801F5DC\n\ -_0801F008:\n\ - ldr r2, _0801F02C @ =gSharedMem\n\ - ldrb r1, [r7, 0x3]\n\ - movs r0, 0x3F\n\ - ands r0, r1\n\ - ldr r4, _0801F030 @ =0x000160a4\n\ - adds r1, r2, r4\n\ - strb r0, [r1]\n\ - ldr r0, _0801F034 @ =0x000160a5\n\ - adds r2, r0\n\ - strb r3, [r2]\n\ - ldr r4, _0801F038 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801F03C @ =BattleScript_StatUp\n\ - b _0801F5F8\n\ - .align 2, 0\n\ -_0801F02C: .4byte gSharedMem\n\ -_0801F030: .4byte 0x000160a4\n\ -_0801F034: .4byte 0x000160a5\n\ -_0801F038: .4byte gBattlescriptCurrInstr\n\ -_0801F03C: .4byte BattleScript_StatUp\n\ -_0801F040:\n\ - movs r0, 0x70\n\ - negs r0, r0\n\ - ldrb r1, [r7, 0x3]\n\ - adds r1, 0xEB\n\ - lsls r1, 24\n\ - lsrs r1, 24\n\ - adds r2, r6, 0\n\ - movs r3, 0\n\ - bl ChangeStatBuffs\n\ - lsls r0, 24\n\ - lsrs r3, r0, 24\n\ - cmp r3, 0\n\ - beq _0801F05E\n\ - b _0801F5DC\n\ -_0801F05E:\n\ - ldr r2, _0801F080 @ =gSharedMem\n\ - ldrb r1, [r7, 0x3]\n\ - movs r0, 0x3F\n\ - ands r0, r1\n\ - ldr r4, _0801F084 @ =0x000160a4\n\ - adds r1, r2, r4\n\ - strb r0, [r1]\n\ - ldr r0, _0801F088 @ =0x000160a5\n\ - adds r2, r0\n\ - strb r3, [r2]\n\ - ldr r4, _0801F08C @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801F090 @ =BattleScript_StatDown\n\ - b _0801F5F8\n\ - .align 2, 0\n\ -_0801F080: .4byte gSharedMem\n\ -_0801F084: .4byte 0x000160a4\n\ -_0801F088: .4byte 0x000160a5\n\ -_0801F08C: .4byte gBattlescriptCurrInstr\n\ -_0801F090: .4byte BattleScript_StatDown\n\ -_0801F094:\n\ - ldrb r1, [r7, 0x3]\n\ - adds r1, 0xDA\n\ - lsls r1, 24\n\ - lsrs r1, 24\n\ - movs r0, 0x20\n\ - adds r2, r6, 0\n\ - movs r3, 0\n\ - bl ChangeStatBuffs\n\ - lsls r0, 24\n\ - lsrs r3, r0, 24\n\ - cmp r3, 0\n\ - beq _0801F0B0\n\ - b _0801F5DC\n\ -_0801F0B0:\n\ - ldr r2, _0801F0D4 @ =gSharedMem\n\ - ldrb r1, [r7, 0x3]\n\ - movs r0, 0x3F\n\ - ands r0, r1\n\ - ldr r4, _0801F0D8 @ =0x000160a4\n\ - adds r1, r2, r4\n\ - strb r0, [r1]\n\ - ldr r0, _0801F0DC @ =0x000160a5\n\ - adds r2, r0\n\ - strb r3, [r2]\n\ - ldr r4, _0801F0E0 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801F0E4 @ =BattleScript_StatUp\n\ - b _0801F5F8\n\ - .align 2, 0\n\ -_0801F0D4: .4byte gSharedMem\n\ -_0801F0D8: .4byte 0x000160a4\n\ -_0801F0DC: .4byte 0x000160a5\n\ -_0801F0E0: .4byte gBattlescriptCurrInstr\n\ -_0801F0E4: .4byte BattleScript_StatUp\n\ -_0801F0E8:\n\ - movs r0, 0x60\n\ - negs r0, r0\n\ - ldrb r1, [r7, 0x3]\n\ - adds r1, 0xD3\n\ - lsls r1, 24\n\ - lsrs r1, 24\n\ - adds r2, r6, 0\n\ - movs r3, 0\n\ - bl ChangeStatBuffs\n\ - lsls r0, 24\n\ - lsrs r3, r0, 24\n\ - cmp r3, 0\n\ - beq _0801F106\n\ - b _0801F5DC\n\ -_0801F106:\n\ - ldr r2, _0801F128 @ =gSharedMem\n\ - ldrb r1, [r7, 0x3]\n\ - movs r0, 0x3F\n\ - ands r0, r1\n\ - ldr r4, _0801F12C @ =0x000160a4\n\ - adds r1, r2, r4\n\ - strb r0, [r1]\n\ - ldr r0, _0801F130 @ =0x000160a5\n\ - adds r2, r0\n\ - strb r3, [r2]\n\ - ldr r4, _0801F134 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801F138 @ =BattleScript_StatDown\n\ - b _0801F5F8\n\ - .align 2, 0\n\ -_0801F128: .4byte gSharedMem\n\ -_0801F12C: .4byte 0x000160a4\n\ -_0801F130: .4byte 0x000160a5\n\ -_0801F134: .4byte gBattlescriptCurrInstr\n\ -_0801F138: .4byte BattleScript_StatDown\n\ -_0801F13C:\n\ - mov r2, r8\n\ - ldrb r1, [r2]\n\ - movs r0, 0x58\n\ - adds r2, r1, 0\n\ - muls r2, r0\n\ - mov r0, r9\n\ - adds r0, 0x50\n\ - adds r2, r0\n\ - ldr r0, [r2]\n\ - movs r1, 0x80\n\ - lsls r1, 15\n\ - orrs r0, r1\n\ - str r0, [r2]\n\ - ldr r2, _0801F178 @ =gDisableStructs\n\ - mov r3, r8\n\ - ldrb r1, [r3]\n\ - lsls r0, r1, 3\n\ - subs r0, r1\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - movs r1, 0x2\n\ - strb r1, [r0, 0x19]\n\ - ldr r1, _0801F17C @ =gLockedMoves\n\ - ldrb r0, [r3]\n\ - lsls r0, 1\n\ - adds r0, r1\n\ - ldr r1, _0801F180 @ =gCurrentMove\n\ - ldrh r1, [r1]\n\ - strh r1, [r0]\n\ - b _0801F5DC\n\ - .align 2, 0\n\ -_0801F178: .4byte gDisableStructs\n\ -_0801F17C: .4byte gLockedMoves\n\ -_0801F180: .4byte gCurrentMove\n\ -_0801F184:\n\ - ldr r0, _0801F1A0 @ =gBankAttacker\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - adds r2, r1, 0\n\ - muls r2, r0\n\ - mov r0, r9\n\ - adds r0, 0x50\n\ - adds r2, r0\n\ - ldr r0, [r2]\n\ - movs r1, 0x80\n\ - lsls r1, 16\n\ -_0801F19A:\n\ - orrs r0, r1\n\ - str r0, [r2]\n\ - b _0801F5DC\n\ - .align 2, 0\n\ -_0801F1A0: .4byte gBankAttacker\n\ -_0801F1A4:\n\ - ldr r4, _0801F254 @ =gBankAttacker\n\ - ldrb r0, [r4]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - lsrs r6, r0, 24\n\ - ldrb r0, [r4]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0x1\n\ - bne _0801F1D8\n\ - ldr r0, _0801F258 @ =gBattleTypeFlags\n\ - ldrh r1, [r0]\n\ - ldr r0, _0801F25C @ =0x00000902\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _0801F214\n\ - ldr r0, _0801F260 @ =gTrainerBattleOpponent\n\ - ldrh r1, [r0]\n\ - movs r0, 0x80\n\ - lsls r0, 3\n\ - cmp r1, r0\n\ - beq _0801F1D8\n\ - b _0801F5DC\n\ -_0801F1D8:\n\ - ldr r0, _0801F258 @ =gBattleTypeFlags\n\ - ldrh r1, [r0]\n\ - ldr r0, _0801F25C @ =0x00000902\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _0801F214\n\ - ldr r0, _0801F260 @ =gTrainerBattleOpponent\n\ - ldrh r1, [r0]\n\ - movs r0, 0x80\n\ - lsls r0, 3\n\ - cmp r1, r0\n\ - beq _0801F214\n\ - ldr r0, _0801F264 @ =gWishFutureKnock\n\ - adds r0, 0x29\n\ - adds r0, r6, r0\n\ - ldrb r1, [r0]\n\ - ldr r3, _0801F268 @ =gBitTable\n\ - ldr r2, _0801F26C @ =gBattlerPartyIndexes\n\ - ldr r0, _0801F254 @ =gBankAttacker\n\ - ldrb r0, [r0]\n\ - lsls r0, 1\n\ - adds r0, r2\n\ - ldrh r0, [r0]\n\ - lsls r0, 2\n\ - adds r0, r3\n\ - ldr r0, [r0]\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - beq _0801F214\n\ - b _0801F5DC\n\ -_0801F214:\n\ - ldr r2, _0801F270 @ =gBattleMons\n\ - ldr r1, _0801F274 @ =gBankTarget\n\ - ldrb r0, [r1]\n\ - movs r3, 0x58\n\ - muls r0, r3\n\ - adds r4, r0, r2\n\ - ldrh r0, [r4, 0x2E]\n\ - adds r7, r1, 0\n\ - mov r9, r2\n\ - cmp r0, 0\n\ - beq _0801F284\n\ - adds r0, r4, 0\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x3C\n\ - bne _0801F284\n\ - ldr r1, _0801F278 @ =gBattlescriptCurrInstr\n\ - ldr r0, _0801F27C @ =BattleScript_NoItemSteal\n\ - str r0, [r1]\n\ - ldr r1, _0801F280 @ =gLastUsedAbility\n\ - ldrb r0, [r7]\n\ - muls r0, r3\n\ - add r0, r9\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - strb r0, [r1]\n\ - ldrb r0, [r7]\n\ - ldrb r1, [r1]\n\ - bl RecordAbilityBattle\n\ - b _0801F5FA\n\ - .align 2, 0\n\ -_0801F254: .4byte gBankAttacker\n\ -_0801F258: .4byte gBattleTypeFlags\n\ -_0801F25C: .4byte 0x00000902\n\ -_0801F260: .4byte gTrainerBattleOpponent\n\ -_0801F264: .4byte gWishFutureKnock\n\ -_0801F268: .4byte gBitTable\n\ -_0801F26C: .4byte gBattlerPartyIndexes\n\ -_0801F270: .4byte gBattleMons\n\ -_0801F274: .4byte gBankTarget\n\ -_0801F278: .4byte gBattlescriptCurrInstr\n\ -_0801F27C: .4byte BattleScript_NoItemSteal\n\ -_0801F280: .4byte gLastUsedAbility\n\ -_0801F284:\n\ - ldr r4, _0801F340 @ =gBankAttacker\n\ - mov r10, r4\n\ - ldrb r1, [r4]\n\ - movs r0, 0x58\n\ - mov r8, r0\n\ - mov r0, r8\n\ - muls r0, r1\n\ - add r0, r9\n\ - ldrh r3, [r0, 0x2E]\n\ - cmp r3, 0\n\ - beq _0801F29C\n\ - b _0801F5DC\n\ -_0801F29C:\n\ - ldrb r0, [r7]\n\ - mov r2, r8\n\ - muls r2, r0\n\ - adds r0, r2, 0\n\ - add r0, r9\n\ - ldrh r2, [r0, 0x2E]\n\ - adds r0, r2, 0\n\ - cmp r0, 0xAF\n\ - bne _0801F2B0\n\ - b _0801F5DC\n\ -_0801F2B0:\n\ - cmp r0, 0\n\ - bne _0801F2B6\n\ - b _0801F5DC\n\ -_0801F2B6:\n\ - lsls r0, r1, 1\n\ - ldr r5, _0801F344 @ =gSharedMem + 0x160F0\n\ - adds r0, r5\n\ - ldr r1, _0801F348 @ =gLastUsedItem\n\ - strh r2, [r0]\n\ - strh r2, [r1]\n\ - ldrb r0, [r7]\n\ - mov r4, r8\n\ - muls r4, r0\n\ - adds r0, r4, 0\n\ - add r0, r9\n\ - movs r6, 0\n\ - strh r3, [r0, 0x2E]\n\ - ldr r4, _0801F34C @ =gActiveBattler\n\ - mov r2, r10\n\ - ldrb r0, [r2]\n\ - strb r0, [r4]\n\ - str r1, [sp]\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - movs r2, 0\n\ - movs r3, 0x2\n\ - bl EmitSetMonData\n\ - mov r3, r10\n\ - ldrb r0, [r3]\n\ - bl MarkBufferBankForExecution\n\ - ldrb r0, [r7]\n\ - strb r0, [r4]\n\ - ldrb r0, [r7]\n\ - mov r4, r8\n\ - muls r4, r0\n\ - adds r0, r4, 0\n\ - mov r1, r9\n\ - adds r1, 0x2E\n\ - adds r0, r1\n\ - str r0, [sp]\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - movs r2, 0\n\ - movs r3, 0x2\n\ - bl EmitSetMonData\n\ - ldrb r0, [r7]\n\ - bl MarkBufferBankForExecution\n\ - ldr r4, _0801F350 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801F354 @ =BattleScript_ItemSteal\n\ - str r0, [r4]\n\ - ldr r0, _0801F358 @ =0xfffe9f10\n\ - adds r5, r0\n\ - ldrb r0, [r7]\n\ - lsls r0, 1\n\ - ldr r1, _0801F35C @ =0x000160e8\n\ - adds r0, r1\n\ - adds r0, r5\n\ - strb r6, [r0]\n\ - ldrb r0, [r7]\n\ - lsls r0, 1\n\ - ldr r2, _0801F360 @ =0x000160e9\n\ - adds r0, r2\n\ - adds r0, r5\n\ - strb r6, [r0]\n\ - b _0801F5FA\n\ - .align 2, 0\n\ -_0801F340: .4byte gBankAttacker\n\ -_0801F344: .4byte gSharedMem + 0x160F0\n\ -_0801F348: .4byte gLastUsedItem\n\ -_0801F34C: .4byte gActiveBattler\n\ -_0801F350: .4byte gBattlescriptCurrInstr\n\ -_0801F354: .4byte BattleScript_ItemSteal\n\ -_0801F358: .4byte 0xfffe9f10\n\ -_0801F35C: .4byte 0x000160e8\n\ -_0801F360: .4byte 0x000160e9\n\ -_0801F364:\n\ - ldr r3, _0801F394 @ =gBankTarget\n\ - ldrb r1, [r3]\n\ - movs r0, 0x58\n\ - adds r2, r1, 0\n\ - muls r2, r0\n\ - mov r0, r9\n\ - adds r0, 0x50\n\ - adds r2, r0\n\ - ldr r0, [r2]\n\ - movs r1, 0x80\n\ - lsls r1, 19\n\ - orrs r0, r1\n\ - str r0, [r2]\n\ - ldr r2, _0801F398 @ =gDisableStructs\n\ - ldrb r1, [r3]\n\ - lsls r0, r1, 3\n\ - subs r0, r1\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldr r1, _0801F39C @ =gBankAttacker\n\ - ldrb r1, [r1]\n\ - strb r1, [r0, 0x14]\n\ - b _0801F5DC\n\ - .align 2, 0\n\ -_0801F394: .4byte gBankTarget\n\ -_0801F398: .4byte gDisableStructs\n\ -_0801F39C: .4byte gBankAttacker\n\ -_0801F3A0:\n\ - ldr r0, _0801F3B8 @ =gBankTarget\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - adds r2, r1, 0\n\ - muls r2, r0\n\ - mov r0, r9\n\ - adds r0, 0x50\n\ - adds r2, r0\n\ - ldr r0, [r2]\n\ - movs r1, 0x80\n\ - lsls r1, 20\n\ - b _0801F19A\n\ - .align 2, 0\n\ -_0801F3B8: .4byte gBankTarget\n\ -_0801F3BC:\n\ - ldr r4, _0801F3CC @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801F3D0 @ =BattleScript_AllStatsUp\n\ - b _0801F5F8\n\ - .align 2, 0\n\ -_0801F3CC: .4byte gBattlescriptCurrInstr\n\ -_0801F3D0: .4byte BattleScript_AllStatsUp\n\ -_0801F3D4:\n\ - ldr r4, _0801F3E4 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801F3E8 @ =BattleScript_RapidSpinAway\n\ - b _0801F5F8\n\ - .align 2, 0\n\ -_0801F3E4: .4byte gBattlescriptCurrInstr\n\ -_0801F3E8: .4byte BattleScript_RapidSpinAway\n\ -_0801F3EC:\n\ - ldr r6, _0801F43C @ =gBankTarget\n\ - ldrb r0, [r6]\n\ - movs r2, 0x58\n\ - muls r0, r2\n\ - mov r1, r9\n\ - adds r1, 0x4C\n\ - adds r5, r0, r1\n\ - ldr r4, [r5]\n\ - movs r0, 0x40\n\ - ands r0, r4\n\ - cmp r0, 0\n\ - bne _0801F406\n\ - b _0801F5DC\n\ -_0801F406:\n\ - movs r0, 0x41\n\ - negs r0, r0\n\ - ands r4, r0\n\ - str r4, [r5]\n\ - ldr r4, _0801F440 @ =gActiveBattler\n\ - ldrb r0, [r6]\n\ - strb r0, [r4]\n\ - ldrb r0, [r4]\n\ - muls r0, r2\n\ - adds r0, r1\n\ - str r0, [sp]\n\ - movs r0, 0\n\ - movs r1, 0x28\n\ - movs r2, 0\n\ - movs r3, 0x4\n\ - bl EmitSetMonData\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - ldr r4, _0801F444 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801F448 @ =BattleScript_TargetPRLZHeal\n\ - b _0801F5F8\n\ - .align 2, 0\n\ -_0801F43C: .4byte gBankTarget\n\ -_0801F440: .4byte gActiveBattler\n\ -_0801F444: .4byte gBattlescriptCurrInstr\n\ -_0801F448: .4byte BattleScript_TargetPRLZHeal\n\ -_0801F44C:\n\ - ldr r4, _0801F45C @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801F460 @ =BattleScript_AtkDefDown\n\ - b _0801F5F8\n\ - .align 2, 0\n\ -_0801F45C: .4byte gBattlescriptCurrInstr\n\ -_0801F460: .4byte BattleScript_AtkDefDown\n\ -_0801F464:\n\ - ldr r4, _0801F494 @ =gBattleMoveDamage\n\ - ldr r0, _0801F498 @ =gHpDealt\n\ - ldr r0, [r0]\n\ - movs r1, 0x3\n\ - bl __divsi3\n\ - str r0, [r4]\n\ - cmp r0, 0\n\ - bne _0801F47A\n\ - movs r0, 0x1\n\ - str r0, [r4]\n\ -_0801F47A:\n\ - ldr r4, _0801F49C @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r1, _0801F4A0 @ =gMoveEffectBS_Ptrs\n\ - ldr r0, _0801F4A4 @ =gBattleCommunication\n\ - ldrb r0, [r0, 0x3]\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - b _0801F5F8\n\ - .align 2, 0\n\ -_0801F494: .4byte gBattleMoveDamage\n\ -_0801F498: .4byte gHpDealt\n\ -_0801F49C: .4byte gBattlescriptCurrInstr\n\ -_0801F4A0: .4byte gMoveEffectBS_Ptrs\n\ -_0801F4A4: .4byte gBattleCommunication\n\ -_0801F4A8:\n\ - mov r3, r8\n\ - ldrb r0, [r3]\n\ - movs r5, 0x58\n\ - muls r0, r5\n\ - mov r4, r9\n\ - adds r4, 0x50\n\ - adds r2, r0, r4\n\ - ldr r1, [r2]\n\ - movs r0, 0xC0\n\ - lsls r0, 4\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0801F4C4\n\ - b _0801F5DC\n\ -_0801F4C4:\n\ - movs r0, 0x80\n\ - lsls r0, 5\n\ - orrs r1, r0\n\ - str r1, [r2]\n\ - ldr r1, _0801F4F8 @ =gLockedMoves\n\ - ldrb r0, [r3]\n\ - lsls r0, 1\n\ - adds r0, r1\n\ - ldr r1, _0801F4FC @ =gCurrentMove\n\ - ldrh r1, [r1]\n\ - strh r1, [r0]\n\ - bl Random\n\ - mov r2, r8\n\ - ldrb r1, [r2]\n\ - adds r2, r1, 0\n\ - muls r2, r5\n\ - adds r2, r4\n\ - movs r1, 0x1\n\ - ands r1, r0\n\ - adds r1, 0x2\n\ - lsls r1, 10\n\ - ldr r0, [r2]\n\ -_0801F4F2:\n\ - orrs r0, r1\n\ - str r0, [r2]\n\ - b _0801F5FA\n\ - .align 2, 0\n\ -_0801F4F8: .4byte gLockedMoves\n\ -_0801F4FC: .4byte gCurrentMove\n\ -_0801F500:\n\ - mov r5, r8\n\ - ldrb r3, [r5]\n\ - movs r4, 0x58\n\ - adds r0, r3, 0\n\ - muls r0, r4\n\ - mov r2, r9\n\ - adds r1, r0, r2\n\ - adds r0, r1, 0\n\ - adds r0, 0x20\n\ - ldrb r2, [r0]\n\ - cmp r2, 0x3C\n\ - bne _0801F540\n\ - ldrh r0, [r1, 0x2E]\n\ - cmp r0, 0\n\ - beq _0801F5DC\n\ - ldr r0, _0801F534 @ =gLastUsedAbility\n\ - strb r2, [r0]\n\ - ldr r1, _0801F538 @ =gBattlescriptCurrInstr\n\ - ldr r0, _0801F53C @ =BattleScript_NoItemSteal\n\ - str r0, [r1]\n\ - ldrb r0, [r5]\n\ - movs r1, 0x3C\n\ - bl RecordAbilityBattle\n\ - b _0801F5FA\n\ - .align 2, 0\n\ -_0801F534: .4byte gLastUsedAbility\n\ -_0801F538: .4byte gBattlescriptCurrInstr\n\ -_0801F53C: .4byte BattleScript_NoItemSteal\n\ -_0801F540:\n\ - ldrh r0, [r1, 0x2E]\n\ - cmp r0, 0\n\ - beq _0801F5DC\n\ - adds r0, r3, 0\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - lsrs r6, r0, 24\n\ - ldr r1, _0801F5B8 @ =gLastUsedItem\n\ - mov r3, r8\n\ - ldrb r0, [r3]\n\ - muls r0, r4\n\ - add r0, r9\n\ - ldrh r0, [r0, 0x2E]\n\ - strh r0, [r1]\n\ - ldrb r0, [r3]\n\ - muls r0, r4\n\ - add r0, r9\n\ - movs r5, 0\n\ - movs r1, 0\n\ - strh r1, [r0, 0x2E]\n\ - ldr r2, _0801F5BC @ =gWishFutureKnock\n\ - adds r2, 0x29\n\ - adds r2, r6, r2\n\ - ldr r3, _0801F5C0 @ =gBitTable\n\ - ldr r1, _0801F5C4 @ =gBattlerPartyIndexes\n\ - mov r4, r8\n\ - ldrb r0, [r4]\n\ - lsls r0, 1\n\ - adds r0, r1\n\ - ldrh r0, [r0]\n\ - lsls r0, 2\n\ - adds r0, r3\n\ - ldr r0, [r0]\n\ - ldrb r1, [r2]\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ - ldr r4, _0801F5C8 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801F5CC @ =BattleScript_KnockedOff\n\ - str r0, [r4]\n\ - ldr r1, _0801F5D0 @ =gSharedMem\n\ - mov r2, r8\n\ - ldrb r0, [r2]\n\ - lsls r0, 1\n\ - ldr r3, _0801F5D4 @ =0x000160e8\n\ - adds r0, r3\n\ - adds r0, r1\n\ - strb r5, [r0]\n\ - ldrb r0, [r2]\n\ - lsls r0, 1\n\ - ldr r4, _0801F5D8 @ =0x000160e9\n\ - adds r0, r4\n\ - adds r0, r1\n\ - strb r5, [r0]\n\ - b _0801F5FA\n\ - .align 2, 0\n\ -_0801F5B8: .4byte gLastUsedItem\n\ -_0801F5BC: .4byte gWishFutureKnock\n\ -_0801F5C0: .4byte gBitTable\n\ -_0801F5C4: .4byte gBattlerPartyIndexes\n\ -_0801F5C8: .4byte gBattlescriptCurrInstr\n\ -_0801F5CC: .4byte BattleScript_KnockedOff\n\ -_0801F5D0: .4byte gSharedMem\n\ -_0801F5D4: .4byte 0x000160e8\n\ -_0801F5D8: .4byte 0x000160e9\n\ -_0801F5DC:\n\ - ldr r1, _0801F5E8 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x1\n\ - str r0, [r1]\n\ - b _0801F5FA\n\ - .align 2, 0\n\ -_0801F5E8: .4byte gBattlescriptCurrInstr\n\ -_0801F5EC:\n\ - ldr r4, _0801F60C @ =gBattlescriptCurrInstr\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - bl BattleScriptPush\n\ - ldr r0, _0801F610 @ =BattleScript_SAtkDown2\n\ -_0801F5F8:\n\ - str r0, [r4]\n\ -_0801F5FA:\n\ - add sp, 0x8\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_0801F60C: .4byte gBattlescriptCurrInstr\n\ -_0801F610: .4byte BattleScript_SAtkDown2\n\ - .syntax divided\n"); -} -#endif // NONMATCHING - -static void atk15_seteffectwithchance(void) -{ - u32 PercentChance; - - if (gBattleMons[gBankAttacker].ability == ABILITY_SERENE_GRACE) - PercentChance = gBattleMoves[gCurrentMove].secondaryEffectChance * 2; - else - PercentChance = gBattleMoves[gCurrentMove].secondaryEffectChance; - - if (DEBUG && (gUnknown_02023A14_50 & 4) - && !(gBattleCommunication[MOVE_EFFECT_BYTE] & 0x80) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) - { - SetMoveEffect(0, 0); - } - else if ((gBattleCommunication[MOVE_EFFECT_BYTE] & 0x80) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) - { - gBattleCommunication[MOVE_EFFECT_BYTE] &= 0x7F; - SetMoveEffect(0, 0x80); - } - else if (Random() % 100 <= PercentChance && gBattleCommunication[MOVE_EFFECT_BYTE] != 0 && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) - { - if (PercentChance >= 100) - SetMoveEffect(0, 0x80); - else - SetMoveEffect(0, 0); - } - else - { - gBattlescriptCurrInstr++; - } - - gBattleCommunication[MOVE_EFFECT_BYTE] = 0; - gBattleStruct->unk16112 = 0; -} - -static void atk16_seteffectprimary(void) -{ - SetMoveEffect(1, 0); -} - -static void atk17_seteffectsecondary(void) -{ - SetMoveEffect(0, 0); -} - -static void atk18_clearstatusfromeffect(void) -{ - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - if (gBattleCommunication[MOVE_EFFECT_BYTE] <= 6) - gBattleMons[gActiveBattler].status1 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); - else - gBattleMons[gActiveBattler].status2 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); - - gBattleCommunication[MOVE_EFFECT_BYTE] = 0; - gBattlescriptCurrInstr += 2; - gBattleStruct->unk16112 = 0; -} - -static void atk19_tryfaintmon(void) -{ - u8 *r4; - - if (gBattlescriptCurrInstr[2] != 0) - { - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); - if (gHitMarker & HITMARKER_FAINTED(gActiveBattler)) - { - r4 = T1_READ_PTR(gBattlescriptCurrInstr + 3); - - BattleScriptPop(); - gBattlescriptCurrInstr = r4; - gSideAffecting[GetBattlerSide(gActiveBattler)] &= ~SIDE_STATUS_SPIKES_DAMAGED; - } - else - { - gBattlescriptCurrInstr += 7; - } - } - else - { - u8 bank; - - if (gBattlescriptCurrInstr[1] == 1) - { - gActiveBattler = gBankAttacker; - bank = gBankTarget; - r4 = BattleScript_FaintAttacker; - } - else - { - gActiveBattler = gBankTarget; - bank = gBankAttacker; - r4 = BattleScript_FaintTarget; - } - if (!(gAbsentBattlerFlags & gBitTable[gActiveBattler]) - && gBattleMons[gActiveBattler].hp == 0) - { - ewram160ACarr2(0, bank) = 0; - ewram160ACarr2(1, bank) = 0; - ewram16100arr2(0, bank) = 0; - ewram16100arr2(1, bank) = 0; - ewram16100arr2(2, bank) = 0; - ewram16100arr2(3, bank) = 0; - - gHitMarker |= HITMARKER_FAINTED(gActiveBattler); - BattleScriptPush(gBattlescriptCurrInstr + 7); - gBattlescriptCurrInstr = r4; - if (GetBattlerSide(gActiveBattler) == 0) - { - gHitMarker |= HITMARKER_x400000; - if (gBattleResults.playerFaintCounter < 0xFF) - gBattleResults.playerFaintCounter++; - if (gBattleMons[bank].level > gBattleMons[gActiveBattler].level) - { - if (gBattleMons[bank].level - gBattleMons[gActiveBattler].level > 29) - AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], FRIENDSHIP_EVENT_FAINT_LARGE); - else - AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], FRIENDSHIP_EVENT_FAINT_SMALL); - } - } - else - { - if (gBattleResults.opponentFaintCounter < 0xFF) - gBattleResults.opponentFaintCounter++; - gBattleResults.lastOpponentSpecies = gBattleMons[gActiveBattler].species; - } - if ((gHitMarker & HITMARKER_DESTINYBOND) && gBattleMons[gBankAttacker].hp != 0) - { - BattleScriptPush(gBattlescriptCurrInstr); - gBattleMoveDamage = gBattleMons[bank].hp; - gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife; - } - if ((gStatuses3[gBankTarget] & STATUS3_GRUDGE) - && !(gHitMarker & HITMARKER_GRUDGE) - && GetBattlerSide(gBankAttacker) != GetBattlerSide(gBankTarget) - && gBattleMons[gBankAttacker].hp != 0 - && gCurrentMove != MOVE_STRUGGLE) - { - u8 moveIndex = ewram1608Carr(gBankAttacker); - - gBattleMons[gBankAttacker].pp[moveIndex] = 0; - BattleScriptPush(gBattlescriptCurrInstr); - gBattlescriptCurrInstr = BattleScript_SelectingImprisionedMoveInPalace; - gActiveBattler = gBankAttacker; - EmitSetMonData(0, moveIndex + 9, 0, 1, &gBattleMons[gActiveBattler].pp[moveIndex]); - MarkBufferBankForExecution(gActiveBattler); - - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = gBattleMons[gBankAttacker].moves[moveIndex]; - gBattleTextBuff1[3] = gBattleMons[gBankAttacker].moves[moveIndex] >> 8; - gBattleTextBuff1[4] = EOS; - } - } - else - { - gBattlescriptCurrInstr += 7; - } - } -} - -static void atk1A_dofaintanimation(void) -{ - if (gBattleExecBuffer == 0) - { - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - Emitcmd10(0); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 2; - } -} - -static void atk1B_cleareffectsonfaint(void) -{ - //Clears things like attraction or trapping to other banks - if (gBattleExecBuffer == 0) - { - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - gBattleMons[gActiveBattler].status1 = 0; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 0x4, &gBattleMons[gActiveBattler].status1); - MarkBufferBankForExecution(gActiveBattler); - UndoEffectsAfterFainting(); - gBattlescriptCurrInstr += 2; - } -} - -static void atk1C_jumpifstatus(void) -{ - u8 bank = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - u32 flags = T2_READ_32(gBattlescriptCurrInstr + 2); - void* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 6); - if (gBattleMons[bank].status1 & flags && gBattleMons[bank].hp) - gBattlescriptCurrInstr = jump_loc; - else - gBattlescriptCurrInstr += 10; -} - -static void atk1D_jumpifstatus2(void) -{ - u8 bank = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - u32 flags = T2_READ_32(gBattlescriptCurrInstr + 2); - void* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 6); - if (gBattleMons[bank].status2 & flags && gBattleMons[bank].hp) - gBattlescriptCurrInstr = jump_loc; - else - gBattlescriptCurrInstr += 10; -} - -static void atk1E_jumpifability(void) -{ - u8 bank; - u8 ability = T2_READ_8(gBattlescriptCurrInstr + 2); - void* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 3); - if (T2_READ_8(gBattlescriptCurrInstr + 1) == 8) - { - bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_BANK_SIDE, gBankAttacker, ability, 0, 0); - if (bank) - { - gLastUsedAbility = ability; - gBattlescriptCurrInstr = jump_loc; - RecordAbilityBattle(bank -1, gLastUsedAbility); - ewram160F8 = bank - 1; - } - else - gBattlescriptCurrInstr += 7; - } - else if (T2_READ_8(gBattlescriptCurrInstr + 1) == 9) - { - bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gBankAttacker, ability, 0, 0); - if (bank) - { - gLastUsedAbility = ability; - gBattlescriptCurrInstr = jump_loc; - RecordAbilityBattle(bank - 1, gLastUsedAbility); - ewram160F8 = bank - 1; - } - else - gBattlescriptCurrInstr += 7; - } - else - { - bank = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - if (gBattleMons[bank].ability == ability) - { - gLastUsedAbility = ability; - gBattlescriptCurrInstr = jump_loc; - RecordAbilityBattle(bank, gLastUsedAbility); - ewram160F8 = bank; - } - else - gBattlescriptCurrInstr += 7; - } -} - -static void atk1F_jumpifsideaffecting(void) -{ - u8 side; - u16 flags; - void* jump_loc; - if (T2_READ_8(gBattlescriptCurrInstr + 1) == 1) - side = GetBattlerPosition(gBankAttacker) & 1; - else - side = GetBattlerPosition(gBankTarget) & 1; - - flags = T2_READ_16(gBattlescriptCurrInstr + 2); - jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 4); - - if (gSideAffecting[side] & flags) - gBattlescriptCurrInstr = jump_loc; - else - gBattlescriptCurrInstr += 8; -} - -static void atk20_jumpifstat(void) -{ - u8 ret = 0; - u8 bank = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - u8 value = gBattleMons[bank].statStages[T2_READ_8(gBattlescriptCurrInstr + 3)]; - switch (T2_READ_8(gBattlescriptCurrInstr + 2)) - { - case CMP_EQUAL: - if (value == T2_READ_8(gBattlescriptCurrInstr + 4)) - ret++; - break; - case CMP_NOT_EQUAL: - if (value != T2_READ_8(gBattlescriptCurrInstr + 4)) - ret++; - break; - case CMP_GREATER_THAN: - if (value > T2_READ_8(gBattlescriptCurrInstr + 4)) - ret++; - break; - case CMP_LESS_THAN: - if (value < T2_READ_8(gBattlescriptCurrInstr + 4)) - ret++; - break; - case CMP_COMMON_BITS: - if (value & T2_READ_8(gBattlescriptCurrInstr + 4)) - ret++; - break; - case CMP_NO_COMMON_BITS: - if (!(value & T2_READ_8(gBattlescriptCurrInstr + 4))) - ret++; - break; - } - if (ret) - gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 5); - else - gBattlescriptCurrInstr += 9; -} - -static void atk21_jumpifstatus3condition(void) -{ - u32 flags; - void* jump_loc; - - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - flags = T2_READ_32(gBattlescriptCurrInstr + 2); - jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 7); - if (T2_READ_8(gBattlescriptCurrInstr + 6)) - { - if ((gStatuses3[gActiveBattler] & flags) != 0) - gBattlescriptCurrInstr += 11; - else - gBattlescriptCurrInstr = jump_loc; - } - else - { - if ((gStatuses3[gActiveBattler] & flags) != 0) - gBattlescriptCurrInstr = jump_loc; - else - gBattlescriptCurrInstr += 11; - } -} - -static void atk22_jumpiftype(void) //u8 bank, u8 type, *ptr -{ - u8 bank = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - u8 type = T2_READ_8(gBattlescriptCurrInstr + 2); - void* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 3); - - if (gBattleMons[bank].type1 == type || gBattleMons[bank].type2 == type) - gBattlescriptCurrInstr = jump_loc; - else - gBattlescriptCurrInstr += 7; -} - -static void atk23_getexp(void) -{ - u16 item; - s32 i; // also used as stringId - u8 holdEffect; - s32 sentIn; - - s32 viaExpShare = 0; - u16* exp = &gBattleStruct->exp; - - gBank1 = GetBattleBank(gBattlescriptCurrInstr[1]); - sentIn = gSentPokesToOpponent[(gBank1 & 2) >> 1]; - - switch (gBattleStruct->getexpStateTracker) - { - case 0: // check if should receive exp at all - if (GetBattlerSide(gBank1) != B_SIDE_OPPONENT || (gBattleTypeFlags & - (BATTLE_TYPE_LINK - | BATTLE_TYPE_SAFARI - | BATTLE_TYPE_BATTLE_TOWER - | BATTLE_TYPE_EREADER_TRAINER))) - { - gBattleStruct->getexpStateTracker = 6; // goto last case - } - else - { - gBattleStruct->getexpStateTracker++; - gBattleStruct->unk16113 |= gBitTable[gBattlerPartyIndexes[gBank1]]; - } - break; - case 1: // calculate experience points to redistribute - { - u16 calculatedExp; - s32 viaSentIn; - - for (viaSentIn = 0, i = 0; i < 6; i++) - { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == SPECIES_NONE || GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0) - continue; - if (gBitTable[i] & sentIn) - viaSentIn++; - - item = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); - - if (item == ITEM_ENIGMA_BERRY) - holdEffect = gSaveBlock1.enigmaBerry.holdEffect; - else - holdEffect = ItemId_GetHoldEffect(item); - - if (holdEffect == HOLD_EFFECT_EXP_SHARE) - viaExpShare++; - } - - calculatedExp = gBaseStats[gBattleMons[gBank1].species].expYield * gBattleMons[gBank1].level / 7; - - if (viaExpShare) // at least one mon is getting exp via exp share - { - *exp = calculatedExp / 2 / viaSentIn; - if (*exp == 0) - *exp = 1; - - gExpShareExp = calculatedExp / 2 / viaExpShare; - if (gExpShareExp == 0) - gExpShareExp = 1; - } - else - { - *exp = calculatedExp / viaSentIn; - if (*exp == 0) - *exp = 1; - gExpShareExp = 0; - } - - gBattleStruct->getexpStateTracker++; - gBattleStruct->expGetterID = 0; - gBattleStruct->sentInPokes = sentIn; - } - // fall through - case 2: // set exp value to the poke in expgetter_id and print message - if (gBattleExecBuffer == 0) - { - item = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_HELD_ITEM); - - if (item == ITEM_ENIGMA_BERRY) - holdEffect = gSaveBlock1.enigmaBerry.holdEffect; - else - holdEffect = ItemId_GetHoldEffect(item); - - if (holdEffect != HOLD_EFFECT_EXP_SHARE && !(gBattleStruct->sentInPokes & 1)) - { - gBattleStruct->sentInPokes >>= 1; - gBattleStruct->getexpStateTracker = 5; - gBattleMoveDamage = 0; // used for exp - } - else if (GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_LEVEL) == 100) - { - gBattleStruct->sentInPokes >>= 1; - gBattleStruct->getexpStateTracker = 5; - gBattleMoveDamage = 0; // used for exp - } - else - { - // music change in wild battle after fainting a poke - if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) && gBattleMons[0].hp && !gBattleStruct->wildVictorySong) - { - BattleStopLowHpSound(); - PlayBGM(0x161); - gBattleStruct->wildVictorySong++; - } - - if (GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_HP)) - { - if (gBattleStruct->sentInPokes & 1) - gBattleMoveDamage = *exp; - else - gBattleMoveDamage = 0; - - if (holdEffect == HOLD_EFFECT_EXP_SHARE) - gBattleMoveDamage += gExpShareExp; - if (holdEffect == HOLD_EFFECT_LUCKY_EGG) - gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; - - if (IsTradedMon(&gPlayerParty[gBattleStruct->expGetterID])) - { - gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; - i = 0x14A; - } - else - { - i = 0x149; - } - - // get exp getter bank - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - if (!(gBattlerPartyIndexes[2] != gBattleStruct->expGetterID) && !(gAbsentBattlerFlags & gBitTable[2])) - gBattleStruct->expGetterBank = 2; - else - { - if (!(gAbsentBattlerFlags & gBitTable[0])) - gBattleStruct->expGetterBank = 0; - else - gBattleStruct->expGetterBank = 2; - } - } - else - gBattleStruct->expGetterBank = 0; - - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattleStruct->expGetterBank, gBattleStruct->expGetterID) - - // buffer 'gained' or 'gained a boosted' - PREPARE_STRING_BUFFER(gBattleTextBuff2, i) - - PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 5, gBattleMoveDamage) - - PrepareStringBattle(STRINGID_PKMNGAINEDEXP, gBattleStruct->expGetterBank); - MonGainEVs(&gPlayerParty[gBattleStruct->expGetterID], gBattleMons[gBank1].species); - } - gBattleStruct->sentInPokes >>= 1; - gBattleStruct->getexpStateTracker++; - } - } - break; - case 3: // Set stats and give exp - if (gBattleExecBuffer == 0) - { - gBattleBufferB[gBattleStruct->expGetterBank][0] = 0; - if (GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_HP) && GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_LEVEL) != 100) - { - gBattleResources_statsBeforeLvlUp->hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_MAX_HP); - gBattleResources_statsBeforeLvlUp->atk = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_ATK); - gBattleResources_statsBeforeLvlUp->def = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_DEF); - gBattleResources_statsBeforeLvlUp->spd = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPEED); - gBattleResources_statsBeforeLvlUp->spAtk = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPATK); - gBattleResources_statsBeforeLvlUp->spDef = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPDEF); - - gActiveBattler = gBattleStruct->expGetterBank; - - EmitExpBarUpdate(0, gBattleStruct->expGetterID, gBattleMoveDamage); - MarkBufferBankForExecution(gActiveBattler); - } - gBattleStruct->getexpStateTracker++; - } - break; - case 4: // lvl up if necessary - if (gBattleExecBuffer == 0) - { - gActiveBattler = gBattleStruct->expGetterBank; - if (gBattleBufferB[gActiveBattler][0] == CONTROLLER_TWORETURNVALUES - && gBattleBufferB[gActiveBattler][1] == RET_VALUE_LEVELLED_UP) - { - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterID) - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - - PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gActiveBattler, gBattleStruct->expGetterID) - - PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 3, GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_LEVEL)) - - BattleScriptPushCursor(); - gLeveledUpInBattle |= gBitTable[gBattleStruct->expGetterID]; - gBattlescriptCurrInstr = BattleScript_LevelUp; - gBattleMoveDamage = (gBattleBufferB[gActiveBattler][2] | (gBattleBufferB[gActiveBattler][3] << 8)); - AdjustFriendship(&gPlayerParty[gBattleStruct->expGetterID], FRIENDSHIP_EVENT_GROW_LEVEL); - - // update battle mon structure after level up - if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterID && gBattleMons[0].hp) - { - gBattleMons[0].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_LEVEL); - gBattleMons[0].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_HP); - gBattleMons[0].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_MAX_HP); - gBattleMons[0].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_ATK); - gBattleMons[0].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_DEF); - // Why is this duplicated? - gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPEED); - gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPEED); - gBattleMons[0].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPATK); - gBattleMons[0].spDefense = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPDEF); - } - // What is else if? - if (gBattlerPartyIndexes[2] == gBattleStruct->expGetterID && gBattleMons[2].hp && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - gBattleMons[2].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_LEVEL); - gBattleMons[2].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_HP); - gBattleMons[2].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_MAX_HP); - gBattleMons[2].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_ATK); - gBattleMons[2].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_DEF); - // Duplicated again, but this time there's no Sp Defense - gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPEED); - gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPEED); - gBattleMons[2].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPATK); - } - } - else - { - gBattleMoveDamage = 0; - } - gBattleStruct->getexpStateTracker = 5; - } - break; - case 5: // looper increment - if (gBattleMoveDamage) // there is exp to give, goto case 3 that gives exp - gBattleStruct->getexpStateTracker = 3; - else - { - gBattleStruct->expGetterID++; - if (gBattleStruct->expGetterID <= 5) - gBattleStruct->getexpStateTracker = 2; // loop again - else - gBattleStruct->getexpStateTracker = 6; // we're done - } - break; - case 6: // increment instruction - if (gBattleExecBuffer == 0) - { - // not sure why gf clears the item and ability here - gBattleMons[gBank1].item = 0; - gBattleMons[gBank1].ability = 0; - gBattlescriptCurrInstr += 2; - } - break; - } -} - -#ifdef NONMATCHING -static void atk24(void) -{ - u16 HP_count = 0; - int i; - if (gBattleExecBuffer) {return;} - - for (i = 0; i < 6; i++) - { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)) - HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); - } - - if (HP_count == 0) - gBattleOutcome |= BATTLE_LOST; - - for (HP_count = 0, i = 0; i < 6; i++) - { - if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES) && !GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG)) - HP_count += GetMonData(&gEnemyParty[i], MON_DATA_HP); - } - - if (!HP_count) - gBattleOutcome |= BATTLE_WON; - - if (!gBattleOutcome && (gBattleTypeFlags & BATTLE_TYPE_LINK)) - { - register int found1 asm("r2"); - register int found2 asm("r4"); - - //I can't for the love of god decompile that part - - for (found1 = 0, i = 0; i < gBattlersCount; i += 2) - { - if ((gHitMarker & HITMARKER_UNK(i)) && !gSpecialStatuses[i].flag40) - found1++; - } - - for (found2 = 0, i = 1; i < gBattlersCount; i += 2) - { - if ((gHitMarker & HITMARKER_UNK(i)) && !gSpecialStatuses[i].flag40) - found2++; - } - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (found2 + found1 > 1) - gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr += 5; - } - else - { - if (found2 != 0 && found1 != 0) - gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr += 5; - } - } - else - gBattlescriptCurrInstr += 5; - -} -#else -NAKED -static void atk24(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r8\n\ - push {r7}\n\ - movs r6, 0\n\ - ldr r0, _08020AF0 @ =gBattleExecBuffer\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - beq _080209C6\n\ - b _08020B46\n\ -_080209C6:\n\ - movs r5, 0\n\ -_080209C8:\n\ - movs r0, 0x64\n\ - adds r1, r5, 0\n\ - muls r1, r0\n\ - ldr r0, _08020AF4 @ =gPlayerParty\n\ - adds r4, r1, r0\n\ - adds r0, r4, 0\n\ - movs r1, 0xB\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _080209F8\n\ - adds r0, r4, 0\n\ - movs r1, 0x2D\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - bne _080209F8\n\ - adds r0, r4, 0\n\ - movs r1, 0x39\n\ - bl GetMonData\n\ - adds r0, r6, r0\n\ - lsls r0, 16\n\ - lsrs r6, r0, 16\n\ -_080209F8:\n\ - adds r5, 0x1\n\ - cmp r5, 0x5\n\ - ble _080209C8\n\ - cmp r6, 0\n\ - bne _08020A0C\n\ - ldr r0, _08020AF8 @ =gBattleOutcome\n\ - ldrb r1, [r0]\n\ - movs r2, 0x2\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ -_08020A0C:\n\ - movs r6, 0\n\ - movs r5, 0\n\ -_08020A10:\n\ - movs r0, 0x64\n\ - adds r1, r5, 0\n\ - muls r1, r0\n\ - ldr r0, _08020AFC @ =gEnemyParty\n\ - adds r4, r1, r0\n\ - adds r0, r4, 0\n\ - movs r1, 0xB\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _08020A40\n\ - adds r0, r4, 0\n\ - movs r1, 0x2D\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - bne _08020A40\n\ - adds r0, r4, 0\n\ - movs r1, 0x39\n\ - bl GetMonData\n\ - adds r0, r6, r0\n\ - lsls r0, 16\n\ - lsrs r6, r0, 16\n\ -_08020A40:\n\ - adds r5, 0x1\n\ - cmp r5, 0x5\n\ - ble _08020A10\n\ - ldr r2, _08020AF8 @ =gBattleOutcome\n\ - cmp r6, 0\n\ - bne _08020A54\n\ - ldrb r0, [r2]\n\ - movs r1, 0x1\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ -_08020A54:\n\ - ldrb r0, [r2]\n\ - cmp r0, 0\n\ - bne _08020B3E\n\ - ldr r2, _08020B00 @ =gBattleTypeFlags\n\ - ldrh r1, [r2]\n\ - movs r0, 0x2\n\ - ands r0, r1\n\ - mov r8, r2\n\ - cmp r0, 0\n\ - beq _08020B3E\n\ - movs r2, 0\n\ - movs r5, 0\n\ - ldr r0, _08020B04 @ =gBattlersCount\n\ - ldrb r3, [r0]\n\ - mov r12, r0\n\ - ldr r7, _08020B08 @ =gBattlescriptCurrInstr\n\ - cmp r2, r3\n\ - bge _08020AA0\n\ - ldr r0, _08020B0C @ =gHitMarker\n\ - movs r1, 0x80\n\ - lsls r1, 21\n\ - ldr r6, [r0]\n\ - adds r4, r3, 0\n\ - ldr r3, _08020B10 @ =gSpecialStatuses\n\ -_08020A84:\n\ - adds r0, r1, 0\n\ - lsls r0, r5\n\ - ands r0, r6\n\ - cmp r0, 0\n\ - beq _08020A98\n\ - ldrb r0, [r3]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _08020A98\n\ - adds r2, 0x1\n\ -_08020A98:\n\ - adds r3, 0x28\n\ - adds r5, 0x2\n\ - cmp r5, r4\n\ - blt _08020A84\n\ -_08020AA0:\n\ - movs r4, 0\n\ - movs r5, 0x1\n\ - mov r0, r12\n\ - ldrb r3, [r0]\n\ - cmp r5, r3\n\ - bge _08020ADA\n\ - ldr r0, _08020B0C @ =gHitMarker\n\ - movs r1, 0x80\n\ - lsls r1, 21\n\ - mov r12, r1\n\ - ldr r1, [r0]\n\ - ldr r0, _08020B10 @ =gSpecialStatuses\n\ - adds r6, r3, 0\n\ - adds r3, r0, 0\n\ - adds r3, 0x14\n\ -_08020ABE:\n\ - mov r0, r12\n\ - lsls r0, r5\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08020AD2\n\ - ldrb r0, [r3]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _08020AD2\n\ - adds r4, 0x1\n\ -_08020AD2:\n\ - adds r3, 0x28\n\ - adds r5, 0x2\n\ - cmp r5, r6\n\ - blt _08020ABE\n\ -_08020ADA:\n\ - mov r0, r8\n\ - ldrh r1, [r0]\n\ - movs r0, 0x40\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08020B14\n\ - adds r0, r4, r2\n\ - cmp r0, 0x1\n\ - bgt _08020B1C\n\ - b _08020B36\n\ - .align 2, 0\n\ -_08020AF0: .4byte gBattleExecBuffer\n\ -_08020AF4: .4byte gPlayerParty\n\ -_08020AF8: .4byte gBattleOutcome\n\ -_08020AFC: .4byte gEnemyParty\n\ -_08020B00: .4byte gBattleTypeFlags\n\ -_08020B04: .4byte gBattlersCount\n\ -_08020B08: .4byte gBattlescriptCurrInstr\n\ -_08020B0C: .4byte gHitMarker\n\ -_08020B10: .4byte gSpecialStatuses\n\ -_08020B14:\n\ - cmp r4, 0\n\ - beq _08020B36\n\ - cmp r2, 0\n\ - beq _08020B36\n\ -_08020B1C:\n\ - ldr r2, [r7]\n\ - ldrb r1, [r2, 0x1]\n\ - ldrb r0, [r2, 0x2]\n\ - lsls r0, 8\n\ - adds r1, r0\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 16\n\ - adds r1, r0\n\ - ldrb r0, [r2, 0x4]\n\ - lsls r0, 24\n\ - adds r1, r0\n\ - str r1, [r7]\n\ - b _08020B46\n\ -_08020B36:\n\ - ldr r0, [r7]\n\ - adds r0, 0x5\n\ - str r0, [r7]\n\ - b _08020B46\n\ -_08020B3E:\n\ - ldr r1, _08020B50 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x5\n\ - str r0, [r1]\n\ -_08020B46:\n\ - pop {r3}\n\ - mov r8, r3\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_08020B50: .4byte gBattlescriptCurrInstr\n\ - .syntax divided\n"); -} -#endif - -static void MoveValuesCleanUp(void) -{ - gMoveResultFlags = 0; - gBattleStruct->dmgMultiplier = 1; - gCritMultiplier = 1; - gBattleCommunication[MOVE_EFFECT_BYTE] = 0; - gBattleCommunication[6] = 0; - gHitMarker &= ~(HITMARKER_DESTINYBOND); - gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT); -} - -static void atk25_movevaluescleanup(void) -{ - MoveValuesCleanUp(); - gBattlescriptCurrInstr += 1; -} - -static void atk26_setmultihit(void) -{ - gMultiHitCounter = T2_READ_8(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr += 2; -} - -static void atk27_decrementmultihit(void) -{ - if (--gMultiHitCounter == 0) - gBattlescriptCurrInstr += 5; - else - gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atk28_goto(void) -{ - gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atk29_jumpifbyte(void) -{ - u8 caseID = T2_READ_8(gBattlescriptCurrInstr + 1); - u8* ptr = T2_READ_PTR(gBattlescriptCurrInstr + 2); - u8 value = T2_READ_8(gBattlescriptCurrInstr + 6); - u8* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 7); - gBattlescriptCurrInstr += 11; - switch (caseID) - { - case CMP_EQUAL: - if (*ptr == value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_NOT_EQUAL: - if (*ptr != value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_GREATER_THAN: - if (*ptr > value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_LESS_THAN: - if (*ptr < value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_COMMON_BITS: - if (*ptr & value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_NO_COMMON_BITS: - if (!(*ptr & value)) - gBattlescriptCurrInstr = jump_loc; - break; - } -} - -static void atk2A_jumpifhalfword(void) -{ - u8 caseID = T2_READ_8(gBattlescriptCurrInstr + 1); - u16* ptr = T2_READ_PTR(gBattlescriptCurrInstr + 2); - u16 value = T2_READ_16(gBattlescriptCurrInstr + 6); - u8* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 8); - gBattlescriptCurrInstr += 12; - switch (caseID) - { - case CMP_EQUAL: - if (*ptr == value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_NOT_EQUAL: - if (*ptr != value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_GREATER_THAN: - if (*ptr > value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_LESS_THAN: - if (*ptr < value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_COMMON_BITS: - if (*ptr & value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_NO_COMMON_BITS: - if (!(*ptr & value)) - gBattlescriptCurrInstr = jump_loc; - break; - } -} - -// Strange that there's an instance of T1_READ_32 in what seems to be a T2 function. see global.h for the distinction. -static void atk2B_jumpifword(void) -{ - u8 caseID = T2_READ_8(gBattlescriptCurrInstr + 1); - u32* ptr = T2_READ_PTR(gBattlescriptCurrInstr + 2); - u32 value = T1_READ_32(gBattlescriptCurrInstr + 6); - u8* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 10); - gBattlescriptCurrInstr += 14; - switch (caseID) - { - case CMP_EQUAL: - if (*ptr == value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_NOT_EQUAL: - if (*ptr != value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_GREATER_THAN: - if (*ptr > value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_LESS_THAN: - if (*ptr < value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_COMMON_BITS: - if (*ptr & value) - gBattlescriptCurrInstr = jump_loc; - break; - case CMP_NO_COMMON_BITS: - if (!(*ptr & value)) - gBattlescriptCurrInstr = jump_loc; - break; - } -} - -static void atk2C_jumpifarrayequal(void) -{ - //Mem1, Mem2, Size, Jump Loc - u8* mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1); - u8* mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5); - u32 size = T2_READ_8(gBattlescriptCurrInstr + 9); - u8* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 10); - - u8 i; - for (i = 0; i < size; i++) - { - if (*mem1 != *mem2) - { - gBattlescriptCurrInstr += 14; - break; - } - mem1++, mem2++; - } - - if (i == size) - gBattlescriptCurrInstr = jump_loc; -} - -static void atk2D_jumpifarraynotequal(void) -{ - //Mem1, Mem2, Size, Jump Loc - u8 equal_bytes = 0; - u8* mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1); - u8* mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5); - u32 size = T2_READ_8(gBattlescriptCurrInstr + 9); - u8* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 10); - - u8 i; - for (i = 0; i < size; i++) - { - if (*mem1 == *mem2) - { - equal_bytes++; - } - mem1++, mem2++; - } - - if (equal_bytes != size) - gBattlescriptCurrInstr = jump_loc; - else - gBattlescriptCurrInstr += 14; -} - -static void atk2E_setbyte(void) -{ - u8* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); - *mem = T2_READ_8(gBattlescriptCurrInstr + 5); - gBattlescriptCurrInstr += 6; -} - -static void atk2F_addbyte(void) -{ - u8* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); - *mem += T2_READ_8(gBattlescriptCurrInstr + 5); - gBattlescriptCurrInstr += 6; -} - -static void atk30_subbyte(void) -{ - u8* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); - *mem -= T2_READ_8(gBattlescriptCurrInstr + 5); - gBattlescriptCurrInstr += 6; -} - -static void atk31_copyarray(void) -{ - u8* mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1); - u8* mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5); - s32 size = T2_READ_8(gBattlescriptCurrInstr + 9); - - s32 i; - for (i = 0; i < size; i++) - { - mem1[i] = mem2[i]; - } - - gBattlescriptCurrInstr += 10; -} - -static void atk32_copyarraywithindex(void) -{ - u8* mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1); - u8* mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5); - u8* index = T2_READ_PTR(gBattlescriptCurrInstr + 9); - s32 size = T2_READ_8(gBattlescriptCurrInstr + 13); - - s32 i; - for (i = 0; i < size; i++) - { - mem1[i] = mem2[i + *index]; - } - - gBattlescriptCurrInstr += 14; -} - -static void atk33_orbyte(void) -{ - u8* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); - *mem |= T2_READ_8(gBattlescriptCurrInstr + 5); - gBattlescriptCurrInstr += 6; -} - -static void atk34_orhalfword(void) -{ - u16* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); - u16 val = T2_READ_16(gBattlescriptCurrInstr + 5); - - *mem |= val; - gBattlescriptCurrInstr += 7; -} - -static void atk35_orword(void) -{ - u32* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); - u32 val = T2_READ_32(gBattlescriptCurrInstr + 5); - - *mem |= val; - gBattlescriptCurrInstr += 9; -} - -static void atk36_bicbyte(void) -{ - u8* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); - *mem &= ~(T2_READ_8(gBattlescriptCurrInstr + 5)); - gBattlescriptCurrInstr += 6; -} - -static void atk37_bichalfword(void) -{ - u16* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); - u16 val = T2_READ_16(gBattlescriptCurrInstr + 5); - - *mem &= ~val; - gBattlescriptCurrInstr += 7; -} - -static void atk38_bicword(void) -{ - u32* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); - u32 val = T2_READ_32(gBattlescriptCurrInstr + 5); - - *mem &= ~val; - gBattlescriptCurrInstr += 9; -} - -static void atk39_pause(void) -{ - if (gBattleExecBuffer == 0) - { - u16 value = T2_READ_16(gBattlescriptCurrInstr + 1); - if (++gPauseCounterBattle >= value) - { - gPauseCounterBattle = 0; - gBattlescriptCurrInstr += 3; - } - } -} - -static void atk3A_waitstate(void) -{ - if (gBattleExecBuffer == 0) - gBattlescriptCurrInstr++; -} - -static void atk3B_healthbar_update(void) -{ - if (!T2_READ_8(gBattlescriptCurrInstr + 1)) - gActiveBattler = gBankTarget; - else - gActiveBattler = gBankAttacker; - - EmitHealthBarUpdate(0, gBattleMoveDamage); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 2; -} - -static void atk3C_return(void) -{ - BattleScriptPop(); -} - -static void atk3D_end(void) -{ - gMoveResultFlags = 0; - gActiveBattler = 0; - gCurrentActionFuncId = 0xB; -} - -static void atk3E_end2(void) -{ - //not much difference between this and 3D. It's more apparent in Emerald - gActiveBattler = 0; - gCurrentActionFuncId = 0xB; -} - -static void atk3F_end3(void) //pops the main function stack -{ - BattleScriptPop(); - if (B_FUNCTION_STACK->size) - B_FUNCTION_STACK->size--; - gBattleMainFunc = B_FUNCTION_STACK->ptr[B_FUNCTION_STACK->size]; -} - -static void atk41_call(void) -{ - BattleScriptPush(gBattlescriptCurrInstr + 5); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atk42_jumpiftype2(void) //u8 bank, u8 type, *ptr -{ - u8 bank = GetBattleBank(T1_READ_8(gBattlescriptCurrInstr + 1)); - - if (T1_READ_8(gBattlescriptCurrInstr + 2) == gBattleMons[bank].type1 || T1_READ_8(gBattlescriptCurrInstr + 2) == gBattleMons[bank].type2) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); - else - gBattlescriptCurrInstr += 7; -} - -static void atk43_jumpifabilitypresent(void) -{ - if (AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, T2_READ_8(gBattlescriptCurrInstr + 1), 0, 0)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; -} - -static void atk44_endselectionscript(void) -{ - ewram16060(gBankAttacker) = 1; -} - -static void atk45_playanimation(void) -{ - const u16* argumentPtr; - - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); - argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); - - if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE - || gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE - || gBattlescriptCurrInstr[2] == B_ANIM_SUBSTITUTE_FADE) - { - EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 7; - } - else if (gHitMarker & HITMARKER_NO_ANIMATIONS) - { - BattleScriptPush(gBattlescriptCurrInstr + 7); - gBattlescriptCurrInstr = BattleScript_Pausex20; - } - else if (gBattlescriptCurrInstr[2] == B_ANIM_RAIN_CONTINUES - || gBattlescriptCurrInstr[2] == B_ANIM_SUN_CONTINUES - || gBattlescriptCurrInstr[2] == B_ANIM_SANDSTORM_CONTINUES - || gBattlescriptCurrInstr[2] == B_ANIM_HAIL_CONTINUES) - { - EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 7; - } - else if (gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) - { - gBattlescriptCurrInstr += 7; - } - else - { - EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 7; - } -} - -static void atk46_playanimation2(void) // animation Id is stored in the first pointer -{ - const u16* argumentPtr; - const u8* animationIdPtr; - - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); - animationIdPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); - argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); - - if (*animationIdPtr == B_ANIM_STATS_CHANGE - || *animationIdPtr == B_ANIM_SNATCH_MOVE - || *animationIdPtr == B_ANIM_SUBSTITUTE_FADE) - { - EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 10; - } - else if (gHitMarker & HITMARKER_NO_ANIMATIONS) - { - gBattlescriptCurrInstr += 10; - } - else if (*animationIdPtr == B_ANIM_RAIN_CONTINUES - || *animationIdPtr == B_ANIM_SUN_CONTINUES - || *animationIdPtr == B_ANIM_SANDSTORM_CONTINUES - || *animationIdPtr == B_ANIM_HAIL_CONTINUES) - { - EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 10; - } - else if (gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) - { - gBattlescriptCurrInstr += 10; - } - else - { - EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 10; - } -} - -static void atk47_setgraphicalstatchangevalues(void) -{ - u8 to_add = 0; - switch (gBattleStruct->statChanger & 0xF0) - { - case 0x10: //+1 - to_add = 0xF; - break; - case 0x20: //+2 - to_add = 0x27; - break; - case 0x90: //-1 - to_add = 0x16; - break; - case 0xA0: //-2 - to_add = 0x2E; - break; - } - gBattleStruct->animArg1 = (gBattleStruct->statChanger & 0xF) + to_add - 1; - gBattleStruct->animArg2 = 0; - gBattlescriptCurrInstr++; -} - -#ifdef NONMATCHING -static void atk48_playstatchangeanimation(void) -{ - int curr_stat = 0; - u16 stat_animID = 0; - int changeable_stats = 0; - u32 stats_to_check; - u8 arg3; - - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - stats_to_check = T2_READ_8(gBattlescriptCurrInstr + 2); - arg3 = T2_READ_8(gBattlescriptCurrInstr + 3); - if (arg3 & 1) - { - u16 r1 = 0x15; - if (arg3 & 0x2) - r1 = 0x2D; - while (stats_to_check != 0) - { - if (!(stats_to_check & 1)) - continue; - if (!(T2_READ_8(gBattlescriptCurrInstr + 3))) - { - u8 ability; - if (gSideTimers[GetBattlerPosition(gActiveBattler) & 1].mistTimer) - continue; - ability = gBattleMons[gActiveBattler].ability; - if (ability == ABILITY_CLEAR_BODY || ability == ABILITY_WHITE_SMOKE || (ability == ABILITY_KEEN_EYE && curr_stat == 6) || (ability == ABILITY_HYPER_CUTTER && curr_stat == 1)) - continue; - } - if (gBattleMons[gActiveBattler].statStages[curr_stat] > 0) - { - stat_animID = r1; - changeable_stats++; - } - - stats_to_check >>= 1; - r1 += 1; - curr_stat++; - } - if (changeable_stats > 1 && T2_READ_8(gBattlescriptCurrInstr + 3) & 2) - stat_animID = 0x39; - else - stat_animID = 0x3A; - } - else - { - u16 r1 = 0x15; - if (arg3 & 0x2) - r1 = 0x2D; - while (stats_to_check != 0) - { - if (!(stats_to_check & 1)) - continue; - if (gBattleMons[gActiveBattler].statStages[curr_stat] < 0xB) - { - stat_animID = r1; - changeable_stats++; - } - - stats_to_check >>= 1; - r1 += 1; - curr_stat++; - } - if (changeable_stats > 1 && T2_READ_8(gBattlescriptCurrInstr + 3) & 2) - stat_animID = 0x37; - else - stat_animID = 0x38; - } - if ((T2_READ_8(gBattlescriptCurrInstr + 3) & 2 && changeable_stats <= 1) - || changeable_stats == 0 || gBattleStruct->filler2[0] != 0) - gBattlescriptCurrInstr += 4; - else - { - EmitBattleAnimation(0, 1, stat_animID); - MarkBufferBankForExecution(gActiveBattler); - if ((T2_READ_8(gBattlescriptCurrInstr + 3) & 4) && changeable_stats > 1) - gBattleStruct->filler2[0] = 1; - gBattlescriptCurrInstr += 4; - } -} - -#else -NAKED -static void atk48_playstatchangeanimation(void) -{ - asm(".syntax unified\n\ -push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x4\n\ - movs r7, 0\n\ - movs r0, 0\n\ - mov r8, r0\n\ - movs r3, 0\n\ - ldr r5, _08021670 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r5]\n\ - ldrb r0, [r0, 0x1]\n\ - str r3, [sp]\n\ - bl GetBattleBank\n\ - ldr r2, _08021674 @ =gActiveBattler\n\ - strb r0, [r2]\n\ - ldr r0, [r5]\n\ - ldrb r4, [r0, 0x2]\n\ - ldrb r1, [r0, 0x3]\n\ - movs r0, 0x1\n\ - ands r0, r1\n\ - ldr r3, [sp]\n\ - cmp r0, 0\n\ - beq _08021710\n\ - movs r0, 0x2\n\ - ands r0, r1\n\ - movs r1, 0x15\n\ - cmp r0, 0\n\ - beq _0802163C\n\ - movs r1, 0x2D\n\ -_0802163C:\n\ - cmp r4, 0\n\ - beq _080216E4\n\ - movs r0, 0x1\n\ - mov r10, r0\n\ - ldr r0, _08021678 @ =gBattleMons+0x18 @ gBattleMons.statStages\n\ - mov r9, r0\n\ - lsls r5, r1, 16\n\ -_0802164A:\n\ - adds r0, r4, 0\n\ - mov r1, r10\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _080216D6\n\ - ldr r0, _08021670 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r0]\n\ - ldrb r1, [r0, 0x3]\n\ - movs r0, 0x8\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0802167C\n\ - ldr r0, _08021674 @ =gActiveBattler\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r7, r0\n\ - b _080216C4\n\ - .align 2, 0\n\ -_08021670: .4byte gBattlescriptCurrInstr\n\ -_08021674: .4byte gActiveBattler\n\ -_08021678: .4byte gBattleMons+0x18 @ gBattleMons.statStages\n\ -_0802167C:\n\ - ldr r6, _08021700 @ =gActiveBattler\n\ - ldrb r0, [r6]\n\ - str r3, [sp]\n\ - bl GetBattlerPosition\n\ - mov r1, r10\n\ - ands r1, r0\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - ldr r1, _08021704 @ =gSideTimers\n\ - adds r0, r1\n\ - ldrb r0, [r0, 0x2]\n\ - ldr r3, [sp]\n\ - cmp r0, 0\n\ - bne _080216D6\n\ - ldr r0, _08021708 @ =gBattleMons\n\ - ldrb r2, [r6]\n\ - movs r1, 0x58\n\ - muls r2, r1\n\ - adds r0, r2, r0\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x1D\n\ - beq _080216D6\n\ - cmp r0, 0x49\n\ - beq _080216D6\n\ - cmp r0, 0x33\n\ - bne _080216BA\n\ - cmp r7, 0x6\n\ - beq _080216D6\n\ -_080216BA:\n\ - cmp r0, 0x34\n\ - bne _080216C2\n\ - cmp r7, 0x1\n\ - beq _080216D6\n\ -_080216C2:\n\ - adds r0, r7, r2\n\ -_080216C4:\n\ - add r0, r9\n\ - ldrb r0, [r0]\n\ - lsls r0, 24\n\ - asrs r0, 24\n\ - cmp r0, 0\n\ - ble _080216D6\n\ - lsrs r0, r5, 16\n\ - mov r8, r0\n\ - adds r3, 0x1\n\ -_080216D6:\n\ - lsrs r4, 1\n\ - movs r1, 0x80\n\ - lsls r1, 9\n\ - adds r5, r1\n\ - adds r7, 0x1\n\ - cmp r4, 0\n\ - bne _0802164A\n\ -_080216E4:\n\ - ldr r0, _0802170C @ =gBattlescriptCurrInstr\n\ - mov r9, r0\n\ - cmp r3, 0x1\n\ - ble _08021772\n\ - ldr r0, [r0]\n\ - ldrb r1, [r0, 0x3]\n\ - movs r0, 0x2\n\ - ands r0, r1\n\ - movs r1, 0x39\n\ - mov r8, r1\n\ - cmp r0, 0\n\ - beq _08021772\n\ - movs r0, 0x3A\n\ - b _08021770\n\ - .align 2, 0\n\ -_08021700: .4byte gActiveBattler\n\ -_08021704: .4byte gSideTimers\n\ -_08021708: .4byte gBattleMons\n\ -_0802170C: .4byte gBattlescriptCurrInstr\n\ -_08021710:\n\ - movs r0, 0x2\n\ - ands r0, r1\n\ - movs r1, 0xE\n\ - cmp r0, 0\n\ - beq _0802171C\n\ - movs r1, 0x26\n\ -_0802171C:\n\ - mov r9, r5\n\ - cmp r4, 0\n\ - beq _08021758\n\ - ldr r6, _0802178C @ =gBattleMons+0x18 @ gBattleMons.statStages\n\ - adds r5, r2, 0\n\ - lsls r2, r1, 16\n\ -_08021728:\n\ - movs r0, 0x1\n\ - ands r0, r4\n\ - cmp r0, 0\n\ - beq _0802174A\n\ - ldrb r1, [r5]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r7, r0\n\ - adds r0, r6\n\ - ldrb r0, [r0]\n\ - lsls r0, 24\n\ - asrs r0, 24\n\ - cmp r0, 0xB\n\ - bgt _0802174A\n\ - lsrs r1, r2, 16\n\ - mov r8, r1\n\ - adds r3, 0x1\n\ -_0802174A:\n\ - lsrs r4, 1\n\ - movs r0, 0x80\n\ - lsls r0, 9\n\ - adds r2, r0\n\ - adds r7, 0x1\n\ - cmp r4, 0\n\ - bne _08021728\n\ -_08021758:\n\ - cmp r3, 0x1\n\ - ble _08021772\n\ - mov r1, r9\n\ - ldr r0, [r1]\n\ - ldrb r1, [r0, 0x3]\n\ - movs r0, 0x2\n\ - ands r0, r1\n\ - movs r1, 0x37\n\ - mov r8, r1\n\ - cmp r0, 0\n\ - beq _08021772\n\ - movs r0, 0x38\n\ -_08021770:\n\ - mov r8, r0\n\ -_08021772:\n\ - mov r1, r9\n\ - ldr r2, [r1]\n\ - ldrb r1, [r2, 0x3]\n\ - movs r0, 0x4\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08021790\n\ - cmp r3, 0x1\n\ - bgt _08021790\n\ - adds r0, r2, 0x4\n\ - mov r1, r9\n\ - b _080217E6\n\ - .align 2, 0\n\ -_0802178C: .4byte gBattleMons+0x18 @ gBattleMons.statStages\n\ -_08021790:\n\ - cmp r3, 0\n\ - beq _080217E0\n\ - ldr r0, _080217D0 @ =gSharedMem\n\ - ldr r1, _080217D4 @ =0x000160dc\n\ - adds r4, r0, r1\n\ - ldrb r0, [r4]\n\ - cmp r0, 0\n\ - bne _080217E0\n\ - movs r0, 0\n\ - movs r1, 0x1\n\ - mov r2, r8\n\ - str r3, [sp]\n\ - bl EmitBattleAnimation\n\ - ldr r0, _080217D8 @ =gActiveBattler\n\ - ldrb r0, [r0]\n\ - bl MarkBufferBankForExecution\n\ - ldr r0, _080217DC @ =gBattlescriptCurrInstr\n\ - ldr r0, [r0]\n\ - ldrb r1, [r0, 0x3]\n\ - movs r0, 0x4\n\ - ands r0, r1\n\ - ldr r3, [sp]\n\ - cmp r0, 0\n\ - beq _080217CC\n\ - cmp r3, 0x1\n\ - ble _080217CC\n\ - movs r0, 0x1\n\ - strb r0, [r4]\n\ -_080217CC:\n\ - ldr r1, _080217DC @ =gBattlescriptCurrInstr\n\ - b _080217E2\n\ - .align 2, 0\n\ -_080217D0: .4byte gSharedMem\n\ -_080217D4: .4byte 0x000160dc\n\ -_080217D8: .4byte gActiveBattler\n\ -_080217DC: .4byte gBattlescriptCurrInstr\n\ -_080217E0:\n\ - mov r1, r9\n\ -_080217E2:\n\ - ldr r0, [r1]\n\ - adds r0, 0x4\n\ -_080217E6:\n\ - str r0, [r1]\n\ - add sp, 0x4\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .syntax divided"); -} - -#endif // NONMATCHING - -#ifdef NONMATCHING -static void atk49_moveend(void) -{ - int i; - int effect = 0; - u16 last_move = 0, *choiced_move_atk; - int arg1, arg2, hold_effect_atk, move_type; - if (gLastUsedMove != 0xFFFF) - last_move = gLastUsedMove; - - arg1 = T2_READ_8(gBattlescriptCurrInstr + 1); - arg2 = T2_READ_8(gBattlescriptCurrInstr + 2); - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - hold_effect_atk = gEnigmaBerries[gBankAttacker].holdEffect; - else - hold_effect_atk = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); - - choiced_move_atk = (u16*)(gBankAttacker * (ewram_addr + 0x160E8)); - if (gBattleStruct->dynamicMoveType) - move_type = gBattleStruct->dynamicMoveType & 0x3F; - else - move_type = gBattleMoves[gCurrentMove].type; - - do - { - switch (gBattleStruct->cmd49StateTracker) - { - case 0: //rage check - if (gBattleMons[gBankTarget].status2 & STATUS2_RAGE - && gBattleMons[gBankTarget].hp && gBankAttacker != gBankTarget - && GetBattlerSide(gBankAttacker) != GetBattlerSide(gBankTarget) - && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && TARGET_TURN_DAMAGED - && gBattleMoves[gCurrentMove].power && gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] <= 0xB) - { - gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK]++; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_RageIsBuilding; - effect = 1; - } - gBattleStruct->cmd49StateTracker++; - break; - case 1: //defrosting check - if (gBattleMons[gBankTarget].status1 & STATUS_FREEZE - && gBattleMons[gBankTarget].hp && gBankAttacker != gBankTarget - && gSpecialStatuses[gBankTarget].moveturnLostHP - && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && move_type == TYPE_FIRE) - { - gBattleMons[gBankTarget].status1 &= ~(STATUS_FREEZE); - gActiveBattler = gBankTarget; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBankTarget].status1); - MarkBufferBankForExecution(gActiveBattler); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_DefrostedViaFireMove; - effect = 1; - } - gBattleStruct->cmd49StateTracker++; - break; - case 2: //target synchronize - if (AbilityBattleEffects(ABILITYEFFECT_SYNCHRONIZE, gBankTarget, 0, 0, 0)) - effect = 1; - gBattleStruct->cmd49StateTracker++; - break; - case 3: //contact abilities - if (AbilityBattleEffects(ABILITYEFFECT_CONTACT, gBankTarget, 0, 0, 0)) - effect = 1; - gBattleStruct->cmd49StateTracker++; - break; - case 4: //status immunities - if (AbilityBattleEffects(ABILITYEFFECT_IMMUNITY, 0, 0, 0, 0)) - effect = 1; //it loops through 4 banks, so we increment after its done with all banks - else - gBattleStruct->cmd49StateTracker++; - break; - case 5: //attacker synchronize - if (AbilityBattleEffects(ABILITYEFFECT_ATK_SYNCHRONIZE, gBankAttacker, 0, 0, 0)) - effect = 1; - gBattleStruct->cmd49StateTracker++; - break; - case 6: //update choice band move - if (gHitMarker & HITMARKER_OBEYS && hold_effect_atk == HOLD_EFFECT_CHOICE_BAND - && gLastUsedMove != MOVE_STRUGGLE && (*choiced_move_atk == 0 || *choiced_move_atk == 0xFFF) - && gLastUsedMove != MOVE_BATON_PASS && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) - { - *choiced_move_atk = gLastUsedMove; - for (i = 0; i < 4 && gBattleMons[gBankAttacker].moves[i] != *choiced_move_atk; i++){} - if (i == 4) - *choiced_move_atk = 0; - } - gBattleStruct->cmd49StateTracker++; - break; - case 7: //changed held items - for (i = 0; i < gBattlersCount; i++) - { - #define CHANGED_ITEM (((*u16)(gSharedMem + 0x160F0))) - if (CHANGED_ITEM(i)) - gBattleMons[i].item = CHANGED_ITEM(i); - } - gBattleStruct->cmd49StateTracker++; - break; - case 8: //make sprite invisible - if (gStatuses3[gBankAttacker] & (STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER) - && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) - { - gActiveBattler = gBankAttacker; - EmitSpriteInvisibility(0, 1); - MarkBufferBankForExecution(gActiveBattler); - } - gBattleStruct->cmd49StateTracker++; - break; - case 9: //semi-invlurneable attacker make visible - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) || !(gStatuses3[gBankAttacker] & (STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) - || WasUnableToUseMove(gBankAttacker)) - { - gActiveBattler = gBankAttacker; - EmitSpriteInvisibility(0, 0); - MarkBufferBankForExecution(gActiveBattler); - gStatuses3 &= ~(STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER); - gSpecialStatuses[gBankAttacker].restored_bank_sprite = 1; - } - gBattleStruct->cmd49StateTracker++; - break; - case 10: //semi-invlurneable target make visible - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) || !(gStatuses3[gBankTarget] & (STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) - || WasUnableToUseMove(gBankTarget)) - { - gActiveBattler = gBankTarget; - EmitSpriteInvisibility(0, 0); - MarkBufferBankForExecution(gActiveBattler); - gStatuses3 &= ~(STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER); - gSpecialStatuses[gBankTarget].restored_bank_sprite = 1; - } - gBattleStruct->cmd49StateTracker++; - break; - case 11: // - } - - } while (effect == 0) -} -#else -NAKED -void atk49_moveend(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x18\n\ - movs r0, 0\n\ - mov r10, r0\n\ - ldr r0, _08021834 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r0]\n\ - ldrb r1, [r0, 0x1]\n\ - str r1, [sp, 0x10]\n\ - ldrb r0, [r0, 0x2]\n\ - str r0, [sp, 0x14]\n\ - ldr r1, _08021838 @ =gBattleMons\n\ - ldr r0, _0802183C @ =gBankAttacker\n\ - ldrb r2, [r0]\n\ - movs r0, 0x58\n\ - muls r0, r2\n\ - adds r1, r0, r1\n\ - ldrh r0, [r1, 0x2E]\n\ - cmp r0, 0xAF\n\ - bne _08021844\n\ - ldr r1, _08021840 @ =gEnigmaBerries\n\ - lsls r0, r2, 3\n\ - subs r0, r2\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldrb r0, [r0, 0x7]\n\ - b _0802184E\n\ - .align 2, 0\n\ -_08021834: .4byte gBattlescriptCurrInstr\n\ -_08021838: .4byte gBattleMons\n\ -_0802183C: .4byte gBankAttacker\n\ -_08021840: .4byte gEnigmaBerries\n\ -_08021844:\n\ - ldrh r0, [r1, 0x2E]\n\ - bl ItemId_GetHoldEffect\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ -_0802184E:\n\ - str r0, [sp, 0x8]\n\ - ldr r0, _0802186C @ =gBankAttacker\n\ - ldrb r1, [r0]\n\ - lsls r1, 1\n\ - ldr r0, _08021870 @ =gSharedMem + 0x160E8\n\ - adds r1, r0\n\ - str r1, [sp, 0xC]\n\ - subs r0, 0xCC\n\ - ldrb r0, [r0]\n\ - cmp r0, 0\n\ - beq _080218C0\n\ - movs r2, 0x3F\n\ - ands r2, r0\n\ - str r2, [sp, 0x4]\n\ - b _080218D2\n\ - .align 2, 0\n\ -_0802186C: .4byte gBankAttacker\n\ -_08021870: .4byte gSharedMem + 0x160E8\n\ -_08021874:\n\ - strb r2, [r7]\n\ - ldr r0, [r5]\n\ - orrs r0, r6\n\ - str r0, [r5]\n\ - ldr r0, _080218AC @ =gSharedMem\n\ - ldr r3, _080218B0 @ =0x0001600c\n\ - adds r0, r3\n\ - strb r4, [r0]\n\ - bl MoveValuesCleanUp\n\ - ldr r2, _080218B4 @ =gBattleScriptsForMoveEffects\n\ - mov r4, r8\n\ - ldrh r1, [r4]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - add r0, r9\n\ - ldrb r0, [r0]\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldr r0, [r0]\n\ - bl BattleScriptPush\n\ - ldr r1, _080218B8 @ =gBattlescriptCurrInstr\n\ - ldr r0, _080218BC @ =gUnknown_081D9B2D\n\ - bl _0802229C\n\ - .align 2, 0\n\ -_080218AC: .4byte gSharedMem\n\ -_080218B0: .4byte 0x0001600c\n\ -_080218B4: .4byte gBattleScriptsForMoveEffects\n\ -_080218B8: .4byte gBattlescriptCurrInstr\n\ -_080218BC: .4byte gUnknown_081D9B2D\n\ -_080218C0:\n\ - ldr r2, _080218D8 @ =gBattleMoves\n\ - ldr r0, _080218DC @ =gCurrentMove\n\ - ldrh r1, [r0]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldrb r0, [r0, 0x2]\n\ - str r0, [sp, 0x4]\n\ -_080218D2:\n\ - ldr r5, _080218E0 @ =gSharedMem\n\ - mov r12, r5\n\ - b _080218EE\n\ - .align 2, 0\n\ -_080218D8: .4byte gBattleMoves\n\ -_080218DC: .4byte gCurrentMove\n\ -_080218E0: .4byte gSharedMem\n\ -_080218E4:\n\ - mov r0, r10\n\ - cmp r0, 0\n\ - beq _080218EE\n\ - bl _08022286\n\ -_080218EE:\n\ - ldr r0, _08021908 @ =0x0001600c\n\ - add r0, r12\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x11\n\ - bls _080218FC\n\ - bl _0802224E\n\ -_080218FC:\n\ - lsls r0, 2\n\ - ldr r1, _0802190C @ =_08021910\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - mov pc, r0\n\ - .align 2, 0\n\ -_08021908: .4byte 0x0001600c\n\ -_0802190C: .4byte _08021910\n\ - .align 2, 0\n\ -_08021910:\n\ - .4byte _08021958\n\ - .4byte _08021A34\n\ - .4byte _08021AF0\n\ - .4byte _08021B20\n\ - .4byte _08021B44\n\ - .4byte _08021B78\n\ - .4byte _08021B9C\n\ - .4byte _08021C40\n\ - .4byte _08021C78\n\ - .4byte _08021CA8\n\ - .4byte _08021CCC\n\ - .4byte _08021D18\n\ - .4byte _08021DAC\n\ - .4byte _08021E30\n\ - .4byte _08021E70\n\ - .4byte _08022068\n\ - .4byte _080221C0\n\ - .4byte _0802224E\n\ -_08021958:\n\ - ldr r5, _08021A08 @ =gBattleMons\n\ - ldr r2, _08021A0C @ =gBankTarget\n\ - ldrb r4, [r2]\n\ - movs r6, 0x58\n\ - adds r3, r4, 0\n\ - muls r3, r6\n\ - adds r0, r5, 0\n\ - adds r0, 0x50\n\ - adds r0, r3, r0\n\ - ldr r1, [r0]\n\ - movs r0, 0x80\n\ - lsls r0, 16\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - beq _080219FE\n\ - adds r0, r3, r5\n\ - ldrh r0, [r0, 0x28]\n\ - cmp r0, 0\n\ - beq _080219FE\n\ - ldr r0, _08021A10 @ =gBankAttacker\n\ - ldrb r1, [r0]\n\ - cmp r1, r4\n\ - beq _080219FE\n\ - adds r0, r1, 0\n\ - bl GetBattlerSide\n\ - adds r4, r0, 0\n\ - ldr r1, _08021A0C @ =gBankTarget\n\ - ldrb r0, [r1]\n\ - bl GetBattlerSide\n\ - lsls r4, 24\n\ - lsls r0, 24\n\ - cmp r4, r0\n\ - beq _080219FE\n\ - ldr r0, _08021A14 @ =gMoveResultFlags\n\ - ldrb r1, [r0]\n\ - movs r0, 0x29\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _080219FE\n\ - ldr r2, _08021A18 @ =gProtectStructs\n\ - ldr r4, _08021A0C @ =gBankTarget\n\ - ldrb r3, [r4]\n\ - lsls r1, r3, 4\n\ - adds r0, r2, 0x4\n\ - adds r0, r1, r0\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - bne _080219C8\n\ - adds r0, r2, 0\n\ - adds r0, 0x8\n\ - adds r0, r1, r0\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - beq _080219FE\n\ -_080219C8:\n\ - ldr r2, _08021A1C @ =gBattleMoves\n\ - ldr r0, _08021A20 @ =gCurrentMove\n\ - ldrh r1, [r0]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldrb r0, [r0, 0x1]\n\ - cmp r0, 0\n\ - beq _080219FE\n\ - adds r0, r3, 0\n\ - muls r0, r6\n\ - adds r1, r0, r5\n\ - ldrb r2, [r1, 0x19]\n\ - movs r0, 0x19\n\ - ldrsb r0, [r1, r0]\n\ - cmp r0, 0xB\n\ - bgt _080219FE\n\ - adds r0, r2, 0x1\n\ - strb r0, [r1, 0x19]\n\ - bl BattleScriptPushCursor\n\ - ldr r1, _08021A24 @ =gBattlescriptCurrInstr\n\ - ldr r0, _08021A28 @ =BattleScript_RageIsBuilding\n\ - str r0, [r1]\n\ - movs r5, 0x1\n\ - mov r10, r5\n\ -_080219FE:\n\ - ldr r2, _08021A2C @ =gSharedMem\n\ - ldr r0, _08021A30 @ =0x0001600c\n\ - adds r1, r2, r0\n\ - b _08021E00\n\ - .align 2, 0\n\ -_08021A08: .4byte gBattleMons\n\ -_08021A0C: .4byte gBankTarget\n\ -_08021A10: .4byte gBankAttacker\n\ -_08021A14: .4byte gMoveResultFlags\n\ -_08021A18: .4byte gProtectStructs\n\ -_08021A1C: .4byte gBattleMoves\n\ -_08021A20: .4byte gCurrentMove\n\ -_08021A24: .4byte gBattlescriptCurrInstr\n\ -_08021A28: .4byte BattleScript_RageIsBuilding\n\ -_08021A2C: .4byte gSharedMem\n\ -_08021A30: .4byte 0x0001600c\n\ -_08021A34:\n\ - ldr r2, _08021AD0 @ =gBattleMons\n\ - ldr r1, _08021AD4 @ =gBankTarget\n\ - ldrb r4, [r1]\n\ - movs r3, 0x58\n\ - mov r12, r3\n\ - mov r3, r12\n\ - muls r3, r4\n\ - adds r7, r2, 0\n\ - adds r7, 0x4C\n\ - adds r6, r3, r7\n\ - ldr r5, [r6]\n\ - movs r0, 0x20\n\ - ands r0, r5\n\ - cmp r0, 0\n\ - bne _08021A54\n\ - b _08021DFA\n\ -_08021A54:\n\ - adds r0, r3, r2\n\ - ldrh r0, [r0, 0x28]\n\ - cmp r0, 0\n\ - bne _08021A5E\n\ - b _08021DFA\n\ -_08021A5E:\n\ - ldr r0, _08021AD8 @ =gBankAttacker\n\ - ldrb r0, [r0]\n\ - cmp r0, r4\n\ - bne _08021A68\n\ - b _08021DFA\n\ -_08021A68:\n\ - ldr r0, _08021ADC @ =gSpecialStatuses\n\ - lsls r1, r4, 2\n\ - adds r1, r4\n\ - lsls r1, 2\n\ - adds r0, 0xC\n\ - adds r1, r0\n\ - ldr r0, [r1]\n\ - cmp r0, 0\n\ - bne _08021A7C\n\ - b _08021DFA\n\ -_08021A7C:\n\ - ldr r0, _08021AE0 @ =gMoveResultFlags\n\ - ldrb r1, [r0]\n\ - movs r0, 0x29\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08021A8A\n\ - b _08021DFA\n\ -_08021A8A:\n\ - ldr r4, [sp, 0x4]\n\ - cmp r4, 0xA\n\ - beq _08021A92\n\ - b _08021DFA\n\ -_08021A92:\n\ - movs r0, 0x21\n\ - negs r0, r0\n\ - ands r5, r0\n\ - str r5, [r6]\n\ - ldr r4, _08021AE4 @ =gActiveBattler\n\ - ldr r5, _08021AD4 @ =gBankTarget\n\ - ldrb r0, [r5]\n\ - strb r0, [r4]\n\ - ldrb r0, [r5]\n\ - mov r1, r12\n\ - muls r1, r0\n\ - adds r0, r1, 0\n\ - adds r0, r7\n\ - str r0, [sp]\n\ - movs r0, 0\n\ - movs r1, 0x28\n\ - movs r2, 0\n\ - movs r3, 0x4\n\ - bl EmitSetMonData\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - bl BattleScriptPushCursor\n\ - ldr r1, _08021AE8 @ =gBattlescriptCurrInstr\n\ - ldr r0, _08021AEC @ =BattleScript_DefrostedViaFireMove\n\ - str r0, [r1]\n\ - movs r2, 0x1\n\ - mov r10, r2\n\ - b _08021DFA\n\ - .align 2, 0\n\ -_08021AD0: .4byte gBattleMons\n\ -_08021AD4: .4byte gBankTarget\n\ -_08021AD8: .4byte gBankAttacker\n\ -_08021ADC: .4byte gSpecialStatuses\n\ -_08021AE0: .4byte gMoveResultFlags\n\ -_08021AE4: .4byte gActiveBattler\n\ -_08021AE8: .4byte gBattlescriptCurrInstr\n\ -_08021AEC: .4byte BattleScript_DefrostedViaFireMove\n\ -_08021AF0:\n\ - ldr r0, _08021B14 @ =gBankTarget\n\ - ldrb r1, [r0]\n\ - movs r0, 0\n\ - str r0, [sp]\n\ - movs r0, 0x7\n\ - movs r2, 0\n\ - movs r3, 0\n\ - bl AbilityBattleEffects\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08021B0C\n\ - movs r4, 0x1\n\ - mov r10, r4\n\ -_08021B0C:\n\ - ldr r2, _08021B18 @ =gSharedMem\n\ - ldr r5, _08021B1C @ =0x0001600c\n\ - adds r1, r2, r5\n\ - b _08021E00\n\ - .align 2, 0\n\ -_08021B14: .4byte gBankTarget\n\ -_08021B18: .4byte gSharedMem\n\ -_08021B1C: .4byte 0x0001600c\n\ -_08021B20:\n\ - ldr r0, _08021B40 @ =gBankTarget\n\ - ldrb r1, [r0]\n\ - movs r0, 0\n\ - str r0, [sp]\n\ - movs r0, 0x4\n\ - movs r2, 0\n\ - movs r3, 0\n\ - bl AbilityBattleEffects\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _08021B3A\n\ - b _08021DFA\n\ -_08021B3A:\n\ - movs r0, 0x1\n\ - mov r10, r0\n\ - b _08021DFA\n\ - .align 2, 0\n\ -_08021B40: .4byte gBankTarget\n\ -_08021B44:\n\ - movs r0, 0\n\ - str r0, [sp]\n\ - movs r0, 0x5\n\ - movs r1, 0\n\ - movs r2, 0\n\ - movs r3, 0\n\ - bl AbilityBattleEffects\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08021B68\n\ - movs r4, 0x1\n\ - mov r10, r4\n\ - ldr r5, _08021B64 @ =gSharedMem\n\ - mov r12, r5\n\ - b _0802224E\n\ - .align 2, 0\n\ -_08021B64: .4byte gSharedMem\n\ -_08021B68:\n\ - ldr r2, _08021B70 @ =gSharedMem\n\ - ldr r0, _08021B74 @ =0x0001600c\n\ - adds r1, r2, r0\n\ - b _08021E00\n\ - .align 2, 0\n\ -_08021B70: .4byte gSharedMem\n\ -_08021B74: .4byte 0x0001600c\n\ -_08021B78:\n\ - ldr r0, _08021B98 @ =gBankAttacker\n\ - ldrb r1, [r0]\n\ - movs r0, 0\n\ - str r0, [sp]\n\ - movs r0, 0x8\n\ - movs r2, 0\n\ - movs r3, 0\n\ - bl AbilityBattleEffects\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _08021B92\n\ - b _08021DFA\n\ -_08021B92:\n\ - movs r1, 0x1\n\ - mov r10, r1\n\ - b _08021DFA\n\ - .align 2, 0\n\ -_08021B98: .4byte gBankAttacker\n\ -_08021B9C:\n\ - ldr r0, _08021C28 @ =gHitMarker\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 18\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08021BE0\n\ - ldr r4, [sp, 0x8]\n\ - cmp r4, 0x1D\n\ - bne _08021BE0\n\ - ldr r0, _08021C2C @ =gChosenMove\n\ - ldrh r2, [r0]\n\ - adds r7, r0, 0\n\ - cmp r2, 0xA5\n\ - beq _08021BE0\n\ - ldr r5, [sp, 0xC]\n\ - ldrh r1, [r5]\n\ - cmp r1, 0\n\ - beq _08021BC8\n\ - ldr r0, _08021C30 @ =0x0000ffff\n\ - cmp r1, r0\n\ - bne _08021BE0\n\ -_08021BC8:\n\ - cmp r2, 0xE2\n\ - bne _08021BDA\n\ - ldr r0, _08021C34 @ =gMoveResultFlags\n\ - ldrb r1, [r0]\n\ - movs r0, 0x20\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _08021BDA\n\ - b _08022244\n\ -_08021BDA:\n\ - ldrh r0, [r7]\n\ - ldr r1, [sp, 0xC]\n\ - strh r0, [r1]\n\ -_08021BE0:\n\ - movs r4, 0\n\ - ldr r2, _08021C38 @ =gBattleMons\n\ - ldr r3, _08021C3C @ =gBankAttacker\n\ - ldrb r1, [r3]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r2, 0xC\n\ - adds r0, r2\n\ - ldrh r0, [r0]\n\ - ldr r5, [sp, 0xC]\n\ - ldrh r1, [r5]\n\ - mov r9, r3\n\ - cmp r0, r1\n\ - beq _08021C18\n\ - mov r6, r9\n\ - movs r3, 0x58\n\ - adds r5, r1, 0\n\ -_08021C02:\n\ - adds r4, 0x1\n\ - cmp r4, 0x3\n\ - bgt _08021C18\n\ - lsls r0, r4, 1\n\ - ldrb r1, [r6]\n\ - muls r1, r3\n\ - adds r0, r1\n\ - adds r0, r2\n\ - ldrh r0, [r0]\n\ - cmp r0, r5\n\ - bne _08021C02\n\ -_08021C18:\n\ - cmp r4, 0x4\n\ - beq _08021C1E\n\ - b _08022244\n\ -_08021C1E:\n\ - movs r0, 0\n\ - ldr r1, [sp, 0xC]\n\ -_08021C22:\n\ - strh r0, [r1]\n\ - b _08022244\n\ - .align 2, 0\n\ -_08021C28: .4byte gHitMarker\n\ -_08021C2C: .4byte gChosenMove\n\ -_08021C30: .4byte 0x0000ffff\n\ -_08021C34: .4byte gMoveResultFlags\n\ -_08021C38: .4byte gBattleMons\n\ -_08021C3C: .4byte gBankAttacker\n\ -_08021C40:\n\ - movs r4, 0\n\ - ldr r0, _08021C6C @ =gBattlersCount\n\ - ldrb r2, [r0]\n\ - cmp r4, r2\n\ - blt _08021C4C\n\ - b _08022244\n\ -_08021C4C:\n\ - movs r5, 0\n\ - ldr r2, _08021C70 @ =gSharedMem + 0x160F0\n\ - ldr r3, _08021C74 @ =gBattleMons\n\ -_08021C52:\n\ - ldrh r1, [r2]\n\ - cmp r1, 0\n\ - beq _08021C5C\n\ - strh r1, [r3, 0x2E]\n\ - strh r5, [r2]\n\ -_08021C5C:\n\ - adds r2, 0x2\n\ - adds r3, 0x58\n\ - adds r4, 0x1\n\ - ldrb r1, [r0]\n\ - cmp r4, r1\n\ - blt _08021C52\n\ - b _08022244\n\ - .align 2, 0\n\ -_08021C6C: .4byte gBattlersCount\n\ -_08021C70: .4byte gSharedMem + 0x160F0\n\ -_08021C74: .4byte gBattleMons\n\ -_08021C78:\n\ - movs r0, 0x3\n\ - movs r1, 0\n\ - movs r2, 0\n\ - bl ItemBattleEffects\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08021C98\n\ - movs r2, 0x1\n\ - mov r10, r2\n\ - ldr r3, _08021C94 @ =gSharedMem\n\ - mov r12, r3\n\ - b _0802224E\n\ - .align 2, 0\n\ -_08021C94: .4byte gSharedMem\n\ -_08021C98:\n\ - ldr r2, _08021CA0 @ =gSharedMem\n\ - ldr r4, _08021CA4 @ =0x0001600c\n\ - adds r1, r2, r4\n\ - b _08021E00\n\ - .align 2, 0\n\ -_08021CA0: .4byte gSharedMem\n\ -_08021CA4: .4byte 0x0001600c\n\ -_08021CA8:\n\ - movs r0, 0x4\n\ - movs r1, 0\n\ - movs r2, 0\n\ - bl ItemBattleEffects\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08021CBC\n\ - movs r5, 0x1\n\ - mov r10, r5\n\ -_08021CBC:\n\ - ldr r2, _08021CC4 @ =gSharedMem\n\ - ldr r0, _08021CC8 @ =0x0001600c\n\ - adds r1, r2, r0\n\ - b _08021E00\n\ - .align 2, 0\n\ -_08021CC4: .4byte gSharedMem\n\ -_08021CC8: .4byte 0x0001600c\n\ -_08021CCC:\n\ - ldr r1, _08021D04 @ =gStatuses3\n\ - ldr r0, _08021D08 @ =gBankAttacker\n\ - ldrb r2, [r0]\n\ - lsls r0, r2, 2\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - ldr r1, _08021D0C @ =0x000400c0\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _08021CE2\n\ - b _08021DFA\n\ -_08021CE2:\n\ - ldr r0, _08021D10 @ =gHitMarker\n\ - ldr r0, [r0]\n\ - movs r1, 0x80\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _08021CF0\n\ - b _08021DFA\n\ -_08021CF0:\n\ - ldr r4, _08021D14 @ =gActiveBattler\n\ - strb r2, [r4]\n\ - movs r0, 0\n\ - movs r1, 0x1\n\ - bl EmitSpriteInvisibility\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - b _08021DFA\n\ - .align 2, 0\n\ -_08021D04: .4byte gStatuses3\n\ -_08021D08: .4byte gBankAttacker\n\ -_08021D0C: .4byte 0x000400c0\n\ -_08021D10: .4byte gHitMarker\n\ -_08021D14: .4byte gActiveBattler\n\ -_08021D18:\n\ - ldr r0, _08021D88 @ =gMoveResultFlags\n\ - ldrb r1, [r0]\n\ - movs r0, 0x29\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _08021D44\n\ - ldr r1, _08021D8C @ =gStatuses3\n\ - ldr r0, _08021D90 @ =gBankAttacker\n\ - ldrb r2, [r0]\n\ - lsls r0, r2, 2\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - ldr r1, _08021D94 @ =0x000400c0\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08021D44\n\ - adds r0, r2, 0\n\ - bl WasUnableToUseMove\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08021D7E\n\ -_08021D44:\n\ - ldr r4, _08021D98 @ =gActiveBattler\n\ - ldr r5, _08021D90 @ =gBankAttacker\n\ - ldrb r0, [r5]\n\ - strb r0, [r4]\n\ - movs r0, 0\n\ - movs r1, 0\n\ - bl EmitSpriteInvisibility\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - ldr r0, _08021D8C @ =gStatuses3\n\ - ldrb r2, [r5]\n\ - lsls r2, 2\n\ - adds r2, r0\n\ - ldr r0, [r2]\n\ - ldr r1, _08021D9C @ =0xfffbff3f\n\ - ands r0, r1\n\ - str r0, [r2]\n\ - ldr r2, _08021DA0 @ =gSpecialStatuses\n\ - ldrb r1, [r5]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldrb r1, [r0]\n\ - movs r2, 0x4\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ -_08021D7E:\n\ - ldr r2, _08021DA4 @ =gSharedMem\n\ - ldr r4, _08021DA8 @ =0x0001600c\n\ - adds r1, r2, r4\n\ - b _08021E00\n\ - .align 2, 0\n\ -_08021D88: .4byte gMoveResultFlags\n\ -_08021D8C: .4byte gStatuses3\n\ -_08021D90: .4byte gBankAttacker\n\ -_08021D94: .4byte 0x000400c0\n\ -_08021D98: .4byte gActiveBattler\n\ -_08021D9C: .4byte 0xfffbff3f\n\ -_08021DA0: .4byte gSpecialStatuses\n\ -_08021DA4: .4byte gSharedMem\n\ -_08021DA8: .4byte 0x0001600c\n\ -_08021DAC:\n\ - ldr r2, _08021E0C @ =gSpecialStatuses\n\ - ldr r1, _08021E10 @ =gBankTarget\n\ - ldrb r3, [r1]\n\ - lsls r4, r3, 2\n\ - adds r0, r4, r3\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldrb r0, [r0]\n\ - lsls r0, 29\n\ - cmp r0, 0\n\ - blt _08021DFA\n\ - ldr r0, _08021E14 @ =gBattlersCount\n\ - ldrb r0, [r0]\n\ - cmp r3, r0\n\ - bcs _08021DFA\n\ - ldr r5, _08021E18 @ =gStatuses3\n\ - adds r0, r4, r5\n\ - ldr r0, [r0]\n\ - ldr r1, _08021E1C @ =0x000400c0\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _08021DFA\n\ - ldr r4, _08021E20 @ =gActiveBattler\n\ - strb r3, [r4]\n\ - movs r0, 0\n\ - movs r1, 0\n\ - bl EmitSpriteInvisibility\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - ldr r0, _08021E10 @ =gBankTarget\n\ - ldrb r2, [r0]\n\ - lsls r2, 2\n\ - adds r2, r5\n\ - ldr r0, [r2]\n\ - ldr r1, _08021E24 @ =0xfffbff3f\n\ - ands r0, r1\n\ - str r0, [r2]\n\ -_08021DFA:\n\ - ldr r2, _08021E28 @ =gSharedMem\n\ - ldr r3, _08021E2C @ =0x0001600c\n\ - adds r1, r2, r3\n\ -_08021E00:\n\ - ldrb r0, [r1]\n\ - adds r0, 0x1\n\ - strb r0, [r1]\n\ - mov r12, r2\n\ - b _0802224E\n\ - .align 2, 0\n\ -_08021E0C: .4byte gSpecialStatuses\n\ -_08021E10: .4byte gBankTarget\n\ -_08021E14: .4byte gBattlersCount\n\ -_08021E18: .4byte gStatuses3\n\ -_08021E1C: .4byte 0x000400c0\n\ -_08021E20: .4byte gActiveBattler\n\ -_08021E24: .4byte 0xfffbff3f\n\ -_08021E28: .4byte gSharedMem\n\ -_08021E2C: .4byte 0x0001600c\n\ -_08021E30:\n\ - movs r4, 0\n\ - ldr r0, _08021E60 @ =gBattlersCount\n\ - ldrb r5, [r0]\n\ - cmp r4, r5\n\ - blt _08021E3C\n\ - b _08022244\n\ -_08021E3C:\n\ - ldr r2, _08021E64 @ =gDisableStructs\n\ - ldr r5, _08021E68 @ =0xfeffffff\n\ - adds r3, r0, 0\n\ - ldr r1, _08021E6C @ =gBattleMons+0x50\n\ -_08021E44:\n\ - ldrb r0, [r2, 0xA]\n\ - cmp r0, 0\n\ - bne _08021E50\n\ - ldr r0, [r1]\n\ - ands r0, r5\n\ - str r0, [r1]\n\ -_08021E50:\n\ - adds r2, 0x1C\n\ - adds r1, 0x58\n\ - adds r4, 0x1\n\ - ldrb r0, [r3]\n\ - cmp r4, r0\n\ - blt _08021E44\n\ - b _08022244\n\ - .align 2, 0\n\ -_08021E60: .4byte gBattlersCount\n\ -_08021E64: .4byte gDisableStructs\n\ -_08021E68: .4byte 0xfeffffff\n\ -_08021E6C: .4byte gBattleMons+0x50\n\ -_08021E70:\n\ - ldr r1, _08021F2C @ =gHitMarker\n\ - ldr r3, [r1]\n\ - movs r0, 0x80\n\ - lsls r0, 5\n\ - ands r0, r3\n\ - ldr r2, _08021F30 @ =gBankAttacker\n\ - mov r9, r2\n\ - adds r5, r1, 0\n\ - cmp r0, 0\n\ - beq _08021E9A\n\ - ldr r0, _08021F34 @ =gActiveBattler\n\ - ldrb r2, [r2]\n\ - strb r2, [r0]\n\ - ldr r1, _08021F38 @ =gBankTarget\n\ - ldrb r0, [r1]\n\ - mov r4, r9\n\ - strb r0, [r4]\n\ - strb r2, [r1]\n\ - ldr r0, _08021F3C @ =0xffffefff\n\ - ands r3, r0\n\ - str r3, [r5]\n\ -_08021E9A:\n\ - ldr r1, _08021F40 @ =gBattleMoves\n\ - ldr r2, _08021F44 @ =gChosenMove\n\ - ldrh r3, [r2]\n\ - lsls r0, r3, 1\n\ - adds r0, r3\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldrb r0, [r0]\n\ - mov r8, r1\n\ - adds r7, r2, 0\n\ - cmp r0, 0x7F\n\ - bne _08021EBE\n\ - ldr r0, _08021F48 @ =gMoveResultFlags\n\ - ldrb r1, [r0]\n\ - movs r0, 0x29\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08021ECA\n\ -_08021EBE:\n\ - ldr r1, _08021F4C @ =gUnknown_02024C2C\n\ - mov r2, r9\n\ - ldrb r0, [r2]\n\ - lsls r0, 1\n\ - adds r0, r1\n\ - strh r3, [r0]\n\ -_08021ECA:\n\ - ldr r0, _08021F50 @ =gAbsentBattlerFlags\n\ - ldrb r1, [r0]\n\ - ldr r2, _08021F54 @ =gBitTable\n\ - mov r3, r9\n\ - ldrb r4, [r3]\n\ - lsls r0, r4, 2\n\ - adds r0, r2\n\ - ldr r3, [r0]\n\ - ands r1, r3\n\ - adds r6, r2, 0\n\ - cmp r1, 0\n\ - beq _08021EE4\n\ - b _08022244\n\ -_08021EE4:\n\ - ldr r0, _08021F58 @ =0x000160a6\n\ - add r0, r12\n\ - ldrb r0, [r0]\n\ - ands r0, r3\n\ - cmp r0, 0\n\ - beq _08021EF2\n\ - b _08022244\n\ -_08021EF2:\n\ - ldrh r2, [r7]\n\ - lsls r0, r2, 1\n\ - adds r0, r2\n\ - lsls r0, 2\n\ - add r0, r8\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x7F\n\ - bne _08021F04\n\ - b _08022244\n\ -_08021F04:\n\ - ldr r0, [r5]\n\ - movs r1, 0x80\n\ - lsls r1, 18\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08021F68\n\ - ldr r1, _08021F5C @ =gLastUsedMove\n\ - lsls r0, r4, 1\n\ - adds r0, r1\n\ - strh r2, [r0]\n\ - ldr r0, _08021F60 @ =gUnknown_02024C4C\n\ - mov r4, r9\n\ - ldrb r1, [r4]\n\ - lsls r1, 1\n\ - adds r1, r0\n\ - ldr r0, _08021F64 @ =gCurrentMove\n\ - ldrh r0, [r0]\n\ - strh r0, [r1]\n\ - b _08021F82\n\ - .align 2, 0\n\ -_08021F2C: .4byte gHitMarker\n\ -_08021F30: .4byte gBankAttacker\n\ -_08021F34: .4byte gActiveBattler\n\ -_08021F38: .4byte gBankTarget\n\ -_08021F3C: .4byte 0xffffefff\n\ -_08021F40: .4byte gBattleMoves\n\ -_08021F44: .4byte gChosenMove\n\ -_08021F48: .4byte gMoveResultFlags\n\ -_08021F4C: .4byte gUnknown_02024C2C\n\ -_08021F50: .4byte gAbsentBattlerFlags\n\ -_08021F54: .4byte gBitTable\n\ -_08021F58: .4byte 0x000160a6\n\ -_08021F5C: .4byte gLastUsedMove\n\ -_08021F60: .4byte gUnknown_02024C4C\n\ -_08021F64: .4byte gCurrentMove\n\ -_08021F68:\n\ - ldr r1, _08021FD0 @ =gLastUsedMove\n\ - lsls r0, r4, 1\n\ - adds r0, r1\n\ - ldr r1, _08021FD4 @ =0x0000ffff\n\ - strh r1, [r0]\n\ - ldr r1, _08021FD8 @ =gUnknown_02024C4C\n\ - mov r2, r9\n\ - ldrb r0, [r2]\n\ - lsls r0, 1\n\ - adds r0, r1\n\ - movs r1, 0x1\n\ - negs r1, r1\n\ - strh r1, [r0]\n\ -_08021F82:\n\ - ldr r2, _08021FDC @ =gBankTarget\n\ - ldrb r3, [r2]\n\ - lsls r0, r3, 2\n\ - adds r0, r6\n\ - ldr r0, [r0]\n\ - lsls r0, 28\n\ - ldr r1, [r5]\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - bne _08021FA0\n\ - ldr r0, _08021FE0 @ =gLastHitBy\n\ - adds r0, r3, r0\n\ - mov r3, r9\n\ - ldrb r1, [r3]\n\ - strb r1, [r0]\n\ -_08021FA0:\n\ - ldr r0, [r5]\n\ - movs r1, 0x80\n\ - lsls r1, 18\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0802204C\n\ - ldr r0, _08021FE4 @ =gMoveResultFlags\n\ - ldrb r1, [r0]\n\ - movs r0, 0x29\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _0802204C\n\ - ldrh r2, [r7]\n\ - ldr r0, _08021FD4 @ =0x0000ffff\n\ - cmp r2, r0\n\ - bne _08021FEC\n\ - ldr r1, _08021FE8 @ =gLastLandedMoves\n\ - ldr r4, _08021FDC @ =gBankTarget\n\ - ldrb r0, [r4]\n\ - lsls r0, 1\n\ - adds r0, r1\n\ - strh r2, [r0]\n\ - b _08022244\n\ - .align 2, 0\n\ -_08021FD0: .4byte gLastUsedMove\n\ -_08021FD4: .4byte 0x0000ffff\n\ -_08021FD8: .4byte gUnknown_02024C4C\n\ -_08021FDC: .4byte gBankTarget\n\ -_08021FE0: .4byte gLastHitBy\n\ -_08021FE4: .4byte gMoveResultFlags\n\ -_08021FE8: .4byte gLastLandedMoves\n\ -_08021FEC:\n\ - ldr r0, _08022014 @ =gLastLandedMoves\n\ - ldr r5, _08022018 @ =gBankTarget\n\ - ldrb r1, [r5]\n\ - lsls r1, 1\n\ - adds r1, r0\n\ - ldr r4, _0802201C @ =gCurrentMove\n\ - ldrh r0, [r4]\n\ - strh r0, [r1]\n\ - ldr r0, _08022020 @ =0x0001601c\n\ - add r0, r12\n\ - ldrb r3, [r0]\n\ - cmp r3, 0\n\ - beq _08022028\n\ - ldr r0, _08022024 @ =gLastHitByType\n\ - ldrb r1, [r5]\n\ - lsls r1, 1\n\ - adds r1, r0\n\ - movs r0, 0x3F\n\ - ands r0, r3\n\ - b _08021C22\n\ - .align 2, 0\n\ -_08022014: .4byte gLastLandedMoves\n\ -_08022018: .4byte gBankTarget\n\ -_0802201C: .4byte gCurrentMove\n\ -_08022020: .4byte 0x0001601c\n\ -_08022024: .4byte gLastHitByType\n\ -_08022028:\n\ - ldr r0, _08022044 @ =gLastHitByType\n\ - ldr r1, _08022048 @ =gBankTarget\n\ - ldrb r2, [r1]\n\ - lsls r2, 1\n\ - adds r2, r0\n\ - ldrh r1, [r4]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - add r0, r8\n\ - ldrb r0, [r0, 0x2]\n\ - strh r0, [r2]\n\ - b _08022244\n\ - .align 2, 0\n\ -_08022044: .4byte gLastHitByType\n\ -_08022048: .4byte gBankTarget\n\ -_0802204C:\n\ - ldr r0, _0802205C @ =gLastLandedMoves\n\ - ldr r2, _08022060 @ =gBankTarget\n\ - ldrb r1, [r2]\n\ - lsls r1, 1\n\ - adds r1, r0\n\ - ldr r0, _08022064 @ =0x0000ffff\n\ - b _08021C22\n\ - .align 2, 0\n\ -_0802205C: .4byte gLastLandedMoves\n\ -_08022060: .4byte gBankTarget\n\ -_08022064: .4byte 0x0000ffff\n\ -_08022068:\n\ - ldr r0, _0802212C @ =gAbsentBattlerFlags\n\ - ldrb r1, [r0]\n\ - ldr r6, _08022130 @ =gBitTable\n\ - ldr r2, _08022134 @ =gBankAttacker\n\ - ldrb r5, [r2]\n\ - lsls r0, r5, 2\n\ - adds r0, r6\n\ - ldr r4, [r0]\n\ - ands r1, r4\n\ - mov r9, r2\n\ - cmp r1, 0\n\ - beq _08022082\n\ - b _08022244\n\ -_08022082:\n\ - ldr r0, _08022138 @ =0x000160a6\n\ - add r0, r12\n\ - ldrb r0, [r0]\n\ - ands r0, r4\n\ - cmp r0, 0\n\ - beq _08022090\n\ - b _08022244\n\ -_08022090:\n\ - ldr r1, _0802213C @ =gBattleMoves\n\ - ldr r4, _08022140 @ =gChosenMove\n\ - ldrh r3, [r4]\n\ - lsls r0, r3, 1\n\ - adds r0, r3\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldrb r1, [r0, 0x8]\n\ - movs r0, 0x10\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0802215C\n\ - ldr r0, _08022144 @ =gHitMarker\n\ - ldr r1, [r0]\n\ - movs r0, 0x80\n\ - lsls r0, 18\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0802215C\n\ - ldr r2, _08022148 @ =gBankTarget\n\ - ldrb r0, [r2]\n\ - cmp r5, r0\n\ - bne _080220C0\n\ - b _08022244\n\ -_080220C0:\n\ - adds r2, r0, 0\n\ - lsls r0, r2, 2\n\ - adds r0, r6\n\ - ldr r0, [r0]\n\ - lsls r0, 28\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - bne _0802215C\n\ - ldr r0, _0802214C @ =gMoveResultFlags\n\ - ldrb r1, [r0]\n\ - movs r0, 0x29\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _0802215C\n\ - lsls r0, r2, 1\n\ - ldr r5, _08022150 @ =0x000160ac\n\ - adds r0, r5\n\ - add r0, r12\n\ - strb r3, [r0]\n\ - ldr r0, _08022148 @ =gBankTarget\n\ - ldrb r1, [r0]\n\ - lsls r1, 1\n\ - ldr r2, _08022154 @ =0x000160ad\n\ - adds r1, r2\n\ - add r1, r12\n\ - ldrh r0, [r4]\n\ - lsrs r0, 8\n\ - strb r0, [r1]\n\ - ldr r3, _08022148 @ =gBankTarget\n\ - ldrb r2, [r3]\n\ - lsls r2, 2\n\ - mov r5, r9\n\ - ldrb r0, [r5]\n\ - lsrs r0, 1\n\ - lsls r0, 1\n\ - ldr r1, _08022158 @ =0x00016100\n\ - adds r0, r1\n\ - adds r2, r0\n\ - add r2, r12\n\ - ldrh r0, [r4]\n\ - strb r0, [r2]\n\ - ldrb r2, [r3]\n\ - lsls r2, 2\n\ - ldrb r0, [r5]\n\ - lsrs r0, 1\n\ - lsls r0, 1\n\ - adds r1, 0x1\n\ - adds r0, r1\n\ - adds r2, r0\n\ - add r2, r12\n\ - ldrh r0, [r4]\n\ - lsrs r0, 8\n\ - strb r0, [r2]\n\ - b _08022244\n\ - .align 2, 0\n\ -_0802212C: .4byte gAbsentBattlerFlags\n\ -_08022130: .4byte gBitTable\n\ -_08022134: .4byte gBankAttacker\n\ -_08022138: .4byte 0x000160a6\n\ -_0802213C: .4byte gBattleMoves\n\ -_08022140: .4byte gChosenMove\n\ -_08022144: .4byte gHitMarker\n\ -_08022148: .4byte gBankTarget\n\ -_0802214C: .4byte gMoveResultFlags\n\ -_08022150: .4byte 0x000160ac\n\ -_08022154: .4byte 0x000160ad\n\ -_08022158: .4byte 0x00016100\n\ -_0802215C:\n\ - mov r1, r9\n\ - ldrb r0, [r1]\n\ - ldr r2, _080221B4 @ =gBankTarget\n\ - ldrb r2, [r2]\n\ - cmp r0, r2\n\ - beq _08022244\n\ - ldr r3, _080221B4 @ =gBankTarget\n\ - ldrb r0, [r3]\n\ - lsls r0, 1\n\ - ldr r4, _080221B8 @ =0x000160ac\n\ - adds r0, r4\n\ - add r0, r12\n\ - movs r3, 0\n\ - strb r3, [r0]\n\ - ldr r5, _080221B4 @ =gBankTarget\n\ - ldrb r0, [r5]\n\ - lsls r0, 1\n\ - ldr r1, _080221BC @ =0x000160ad\n\ - adds r0, r1\n\ - add r0, r12\n\ - strb r3, [r0]\n\ - ldrb r2, [r5]\n\ - lsls r2, 2\n\ - mov r4, r9\n\ - ldrb r0, [r4]\n\ - lsrs r0, 1\n\ - lsls r0, 1\n\ - adds r1, 0x53\n\ - adds r0, r1\n\ - adds r2, r0\n\ - add r2, r12\n\ - strb r3, [r2]\n\ - ldrb r2, [r5]\n\ - lsls r2, 2\n\ - ldrb r0, [r4]\n\ - lsrs r0, 1\n\ - lsls r0, 1\n\ - adds r1, 0x1\n\ - adds r0, r1\n\ - adds r2, r0\n\ - add r2, r12\n\ - strb r3, [r2]\n\ - b _08022244\n\ - .align 2, 0\n\ -_080221B4: .4byte gBankTarget\n\ -_080221B8: .4byte 0x000160ac\n\ -_080221BC: .4byte 0x000160ad\n\ -_080221C0:\n\ - ldr r5, _080222B0 @ =gHitMarker\n\ - ldr r2, [r5]\n\ - movs r0, 0x80\n\ - lsls r0, 12\n\ - ands r0, r2\n\ - cmp r0, 0\n\ - bne _08022244\n\ - ldr r0, _080222B4 @ =gBattleTypeFlags\n\ - ldrh r1, [r0]\n\ - movs r0, 0x1\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08022244\n\ - ldr r1, _080222B8 @ =gProtectStructs\n\ - ldr r0, _080222BC @ =gBankAttacker\n\ - ldrb r0, [r0]\n\ - lsls r0, 4\n\ - adds r0, r1\n\ - ldrb r0, [r0, 0x1]\n\ - lsls r0, 29\n\ - cmp r0, 0\n\ - blt _08022244\n\ - ldr r0, _080222C0 @ =gBattleMoves\n\ - mov r9, r0\n\ - ldr r1, _080222C4 @ =gCurrentMove\n\ - mov r8, r1\n\ - ldrh r0, [r1]\n\ - lsls r1, r0, 1\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - add r1, r9\n\ - ldrb r0, [r1, 0x6]\n\ - cmp r0, 0x8\n\ - bne _08022244\n\ - movs r6, 0x80\n\ - lsls r6, 2\n\ - adds r4, r6, 0\n\ - ands r4, r2\n\ - cmp r4, 0\n\ - bne _08022244\n\ - ldr r7, _080222C8 @ =gBankTarget\n\ - ldrb r0, [r7]\n\ - bl GetBattlerPosition\n\ - movs r1, 0x2\n\ - eors r0, r1\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - bl GetBattlerAtPosition\n\ - lsls r0, 24\n\ - lsrs r2, r0, 24\n\ - ldr r1, _080222CC @ =gBattleMons\n\ - movs r0, 0x58\n\ - muls r0, r2\n\ - adds r0, r1\n\ - ldrh r0, [r0, 0x28]\n\ - cmp r0, 0\n\ - beq _0802223A\n\ - bl _08021874\n\ -_0802223A:\n\ - ldr r0, [r5]\n\ - orrs r0, r6\n\ - str r0, [r5]\n\ - ldr r2, _080222D0 @ =gSharedMem\n\ - mov r12, r2\n\ -_08022244:\n\ - ldr r1, _080222D4 @ =0x0001600c\n\ - add r1, r12\n\ - ldrb r0, [r1]\n\ - adds r0, 0x1\n\ - strb r0, [r1]\n\ -_0802224E:\n\ - ldr r3, [sp, 0x10]\n\ - cmp r3, 0x1\n\ - bne _08022262\n\ - mov r4, r10\n\ - cmp r4, 0\n\ - bne _08022262\n\ - ldr r1, _080222D4 @ =0x0001600c\n\ - add r1, r12\n\ - movs r0, 0x11\n\ - strb r0, [r1]\n\ -_08022262:\n\ - ldr r5, [sp, 0x10]\n\ - cmp r5, 0x2\n\ - bne _08022278\n\ - ldr r1, _080222D4 @ =0x0001600c\n\ - add r1, r12\n\ - ldr r0, [sp, 0x14]\n\ - ldrb r2, [r1]\n\ - cmp r0, r2\n\ - bne _08022278\n\ - movs r0, 0x11\n\ - strb r0, [r1]\n\ -_08022278:\n\ - ldr r0, _080222D4 @ =0x0001600c\n\ - add r0, r12\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x11\n\ - beq _08022286\n\ - bl _080218E4\n\ -_08022286:\n\ - ldr r0, _080222D4 @ =0x0001600c\n\ - add r0, r12\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x11\n\ - bne _0802229E\n\ - mov r3, r10\n\ - cmp r3, 0\n\ - bne _0802229E\n\ - ldr r1, _080222D8 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x3\n\ -_0802229C:\n\ - str r0, [r1]\n\ -_0802229E:\n\ - add sp, 0x18\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_080222B0: .4byte gHitMarker\n\ -_080222B4: .4byte gBattleTypeFlags\n\ -_080222B8: .4byte gProtectStructs\n\ -_080222BC: .4byte gBankAttacker\n\ -_080222C0: .4byte gBattleMoves\n\ -_080222C4: .4byte gCurrentMove\n\ -_080222C8: .4byte gBankTarget\n\ -_080222CC: .4byte gBattleMons\n\ -_080222D0: .4byte gSharedMem\n\ -_080222D4: .4byte 0x0001600c\n\ -_080222D8: .4byte gBattlescriptCurrInstr\n\ - .syntax divided" - ); -} -#endif // NONMATCHING - -static void atk4A_typecalc2(void) -{ - u8 flags = 0; - int i = 0; - u8 move_type = gBattleMoves[gCurrentMove].type; - - if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && move_type == TYPE_GROUND) - { - gLastUsedAbility = gBattleMons[gBankTarget].ability; - gMoveResultFlags |= (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE); - gLastLandedMoves[gBankTarget] = 0; - gBattleCommunication[6] = move_type; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - else - { - while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) - { - if (gTypeEffectiveness[i] == TYPE_FORESIGHT) - { - if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) {break;} - else {i += 3; continue;} - } - - if (gTypeEffectiveness[i] == move_type) - { - //check type1 - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1) - { - if (gTypeEffectiveness[i + 2] == 0) - { - gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE; - break; - } - if (gTypeEffectiveness[i + 2] == 5) - flags |= MOVE_RESULT_NOT_VERY_EFFECTIVE; - if (gTypeEffectiveness[i + 2] == 20) - flags |= MOVE_RESULT_SUPER_EFFECTIVE; - } - //check type2 - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2) - { - if (gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 - && gTypeEffectiveness[i + 2] == 0) - { - gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE; - break; - } - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 && gTypeEffectiveness[i + 2] == 5) - flags |= MOVE_RESULT_NOT_VERY_EFFECTIVE; - if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 - && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 && gTypeEffectiveness[i + 2] == 20) - flags |= MOVE_RESULT_SUPER_EFFECTIVE; - } - } - i += 3; - } - } - - if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD && !(flags & MOVE_RESULT_NO_EFFECT) && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2 && - (!(flags & MOVE_RESULT_SUPER_EFFECTIVE) || ((flags & (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE)) == (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE))) && - gBattleMoves[gCurrentMove].power) - { - gLastUsedAbility = ABILITY_WONDER_GUARD; - gMoveResultFlags |= MOVE_RESULT_MISSED; - gLastLandedMoves[gBankTarget] = 0; - gBattleCommunication[6] = 3; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - if (gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) - gProtectStructs[gBankAttacker].notEffective = 1; - - gBattlescriptCurrInstr++; -} - -static void atk4B_returnatktoball(void) -{ - gActiveBattler = gBankAttacker; - if (!(gHitMarker & HITMARKER_FAINTED(gActiveBattler))) - { - EmitReturnPokeToBall(0, 0); - MarkBufferBankForExecution(gActiveBattler); - } - gBattlescriptCurrInstr++; -} - -static void atk4C_getswitchedmondata(void) -{ - if (gBattleExecBuffer) - return; - - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - - gBattlerPartyIndexes[gActiveBattler] = ewram16068arr(gActiveBattler); - - EmitGetAttributes(0, 0, gBitTable[gBattlerPartyIndexes[gActiveBattler]]); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 2; -} - -static void atk4D_switchindataupdate(void) -{ - struct BattlePokemon oldData; - s32 i; - u8 *monData; - - if (gBattleExecBuffer) - return; - - gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); - oldData = gBattleMons[gActiveBattler]; - monData = (u8*)(&gBattleMons[gActiveBattler]); - - for (i = 0; i < sizeof(struct BattlePokemon); i++) - { - monData[i] = gBattleBufferB[gActiveBattler][4 + i]; - } - - gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1; - gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2; - gBattleMons[gActiveBattler].ability = GetAbilityBySpecies(gBattleMons[gActiveBattler].species, gBattleMons[gActiveBattler].altAbility); - - // check knocked off item - i = GetBattlerSide(gActiveBattler); - if (gWishFutureKnock.knockedOffPokes[i] & gBitTable[gBattlerPartyIndexes[gActiveBattler]]) - { - gBattleMons[gActiveBattler].item = 0; - } - - if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS) - { - for (i = 0; i < 8; i++) - { - gBattleMons[gActiveBattler].statStages[i] = oldData.statStages[i]; - } - gBattleMons[gActiveBattler].status2 = oldData.status2; - } - - SwitchInClearSetData(); - - gBattleStruct->scriptingActive = gActiveBattler; - - PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gActiveBattler, gBattlerPartyIndexes[gActiveBattler]); - - gBattlescriptCurrInstr += 2; -} - -static void atk4E_switchinanim(void) -{ - if (gBattleExecBuffer) - return; - - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - if (GetBattlerSide(gActiveBattler) == 1 && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER))) - { - GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBattler].species), 2); - } - gAbsentBattlerFlags &= ~(gBitTable[gActiveBattler]); - EmitSendOutPoke(0, gBattlerPartyIndexes[gActiveBattler], T2_READ_8(gBattlescriptCurrInstr + 2)); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 3; -} - -static void atk4F_jumpifcantswitch(void) -{ - int val, to_cmp; - register struct Pokemon *party; - u8 r7; - //0x80 byte is used as a way of telling the function whether to not check status2/status3 - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1) & 0x7F); - if (!(T2_READ_8(gBattlescriptCurrInstr + 1) & 0x80) - && ((gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) - || (gStatuses3[gActiveBattler] & STATUS3_ROOTED))) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - return; - } - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (GetBattlerSide(gActiveBattler) == 1) - party = gEnemyParty; - else - party = gPlayerParty; - val = 0; - if (sub_803FBFC(sub_803FC34(gActiveBattler)) == 1) - val = 3; - for (to_cmp = val + 3; val < to_cmp; val++) - { - if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE - && !GetMonData(&party[val], MON_DATA_IS_EGG) - && GetMonData(&party[val], MON_DATA_HP) != 0 - && gBattlerPartyIndexes[gActiveBattler] != val) - break; - } - if (val == to_cmp) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; - } - else - { - if (GetBattlerSide(gActiveBattler) == 1) - { - r7 = GetBattlerAtPosition(1); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - to_cmp = GetBattlerAtPosition(3); - else - to_cmp = r7; - party = gEnemyParty; - } - else - { - r7 = GetBattlerAtPosition(0); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - to_cmp = GetBattlerAtPosition(2); - else - to_cmp = r7; - party = gPlayerParty; - } - for (val = 0; val < 6; val++) - { - if (GetMonData(&party[val], MON_DATA_HP) != 0 - && GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE - && !GetMonData(&party[val], MON_DATA_IS_EGG) - && val != gBattlerPartyIndexes[r7] && val != gBattlerPartyIndexes[to_cmp]) - break; - } - if (val == 6) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; - } -} - -void sub_8022A3C(u8 unkown) -{ - BATTLE_PARTY_ID(gActiveBattler) = gBattlerPartyIndexes[gActiveBattler]; - EmitChoosePokemon(0, 1, unkown, 0, gBattleStruct->unk1606C[gActiveBattler]); - MarkBufferBankForExecution(gActiveBattler); -} - -/* -static void atk50_openpartyscreen(void) -{ - int i = 0; - int r9 = 0; - u8* fail_loc = T1_READ_PTR(gBattlescriptCurrInstr + 2); - - if (T2_READ_8(gBattlescriptCurrInstr + 1) == 5) - { - if ((gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI)) != BATTLE_TYPE_DOUBLE) - { - for (gActiveBattler = i; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (!(gHitMarker & HITMARKER_FAINTED(gActiveBattler))) - { - EmitLinkStandbyMsg(0, 2); - MarkBufferBankForExecution(gActiveBattler); - } - else if (sub_8018018(gActiveBattler, 6, 6) == 0 - && !gSpecialStatuses[gActiveBattler].flag40) - { - sub_8022A3C(6); - gSpecialStatuses[gActiveBattler].flag40 = 1; - } - else - { - gAbsentBattlerFlags |= gBitTable[gActiveBattler]; - gHitMarker &= (~HITMARKER_FAINTED(gActiveBattler)); - EmitLinkStandbyMsg(0, 2); - MarkBufferBankForExecution(gActiveBattler); - } - } - } - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - if (!(gHitMarker >> 0x1C & gBitTable[0])) - { - - } - else if (sub_8018018(gActiveBattler, 6, 6) == 0 - && !gSpecialStatuses[gActiveBattler].flag40) - { - - } - else - { - - } - } - } -} -*/ - -NAKED -static void atk50_openpartyscreen(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r9\n\ - mov r6, r8\n\ - push {r6,r7}\n\ - sub sp, 0x4\n\ - movs r7, 0\n\ - movs r0, 0\n\ - mov r9, r0\n\ - ldr r6, _08022B44 @ =gBattlescriptCurrInstr\n\ - ldr r1, [r6]\n\ - ldrb r2, [r1, 0x2]\n\ - ldrb r0, [r1, 0x3]\n\ - lsls r0, 8\n\ - orrs r2, r0\n\ - ldrb r0, [r1, 0x4]\n\ - lsls r0, 16\n\ - orrs r2, r0\n\ - ldrb r0, [r1, 0x5]\n\ - lsls r0, 24\n\ - orrs r2, r0\n\ - mov r8, r2\n\ - ldrb r2, [r1, 0x1]\n\ - adds r0, r2, 0\n\ - mov r12, r6\n\ - cmp r0, 0x5\n\ - beq _08022ACE\n\ - b _08022F74\n\ -_08022ACE:\n\ - ldr r0, _08022B48 @ =gBattleTypeFlags\n\ - ldrh r0, [r0]\n\ - movs r1, 0x41\n\ - ands r1, r0\n\ - cmp r1, 0x1\n\ - beq _08022BBC\n\ - ldr r1, _08022B4C @ =gActiveBattler\n\ - strb r7, [r1]\n\ - ldr r0, _08022B50 @ =gBattlersCount\n\ - ldrb r0, [r0]\n\ - cmp r7, r0\n\ - bcc _08022AE8\n\ - b _08022F62\n\ -_08022AE8:\n\ - ldr r7, _08022B54 @ =gHitMarker\n\ - ldr r6, _08022B58 @ =gBitTable\n\ - adds r4, r1, 0\n\ - ldr r0, _08022B5C @ =gAbsentBattlerFlags\n\ - mov r8, r0\n\ -_08022AF2:\n\ - ldrb r2, [r4]\n\ - lsls r0, r2, 2\n\ - adds r0, r6\n\ - ldr r1, [r0]\n\ - lsls r1, 28\n\ - ldr r0, [r7]\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08022B94\n\ - adds r0, r2, 0\n\ - movs r1, 0x6\n\ - movs r2, 0x6\n\ - bl sub_8018018\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08022B60\n\ - ldrb r0, [r4]\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldr r0, [r0]\n\ - mov r2, r8\n\ - ldrb r1, [r2]\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ - ldrb r0, [r4]\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldr r1, [r0]\n\ - lsls r1, 28\n\ - ldr r0, [r7]\n\ - bics r0, r1\n\ - str r0, [r7]\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - bl EmitLinkStandbyMsg\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - b _08022BA2\n\ - .align 2, 0\n\ -_08022B44: .4byte gBattlescriptCurrInstr\n\ -_08022B48: .4byte gBattleTypeFlags\n\ -_08022B4C: .4byte gActiveBattler\n\ -_08022B50: .4byte gBattlersCount\n\ -_08022B54: .4byte gHitMarker\n\ -_08022B58: .4byte gBitTable\n\ -_08022B5C: .4byte gAbsentBattlerFlags\n\ -_08022B60:\n\ - ldr r5, _08022B90 @ =gSpecialStatuses\n\ - ldrb r0, [r4]\n\ - lsls r1, r0, 2\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - adds r1, r5\n\ - ldrb r0, [r1]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _08022BA2\n\ - movs r0, 0x6\n\ - bl sub_8022A3C\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r5\n\ - ldrb r1, [r0]\n\ - movs r2, 0x40\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ - b _08022BA2\n\ - .align 2, 0\n\ -_08022B90: .4byte gSpecialStatuses\n\ -_08022B94:\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - bl EmitLinkStandbyMsg\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ -_08022BA2:\n\ - ldrb r0, [r4]\n\ - adds r0, 0x1\n\ - strb r0, [r4]\n\ - ldr r1, _08022BB8 @ =gBattlersCount\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - ldrb r1, [r1]\n\ - cmp r0, r1\n\ - bcc _08022AF2\n\ - b _08022F62\n\ - .align 2, 0\n\ -_08022BB8: .4byte gBattlersCount\n\ -_08022BBC:\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - bne _08022BC4\n\ - b _08022F62\n\ -_08022BC4:\n\ - ldr r0, _08022C1C @ =gHitMarker\n\ - mov r8, r0\n\ - ldr r0, [r0]\n\ - lsrs r5, r0, 28\n\ - ldr r6, _08022C20 @ =gBitTable\n\ - ldr r0, [r6]\n\ - ands r0, r5\n\ - cmp r0, 0\n\ - beq _08022C7E\n\ - ldr r4, _08022C24 @ =gActiveBattler\n\ - strb r7, [r4]\n\ - movs r0, 0\n\ - movs r1, 0x6\n\ - movs r2, 0x6\n\ - bl sub_8018018\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08022C2C\n\ - ldr r2, _08022C28 @ =gAbsentBattlerFlags\n\ - ldrb r0, [r4]\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldr r0, [r0]\n\ - ldrb r1, [r2]\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ - ldrb r0, [r4]\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldr r1, [r0]\n\ - lsls r1, 28\n\ - mov r2, r8\n\ - ldr r0, [r2]\n\ - bics r0, r1\n\ - str r0, [r2]\n\ - movs r0, 0\n\ - bl Emitcmd42\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - b _08022C7E\n\ - .align 2, 0\n\ -_08022C1C: .4byte gHitMarker\n\ -_08022C20: .4byte gBitTable\n\ -_08022C24: .4byte gActiveBattler\n\ -_08022C28: .4byte gAbsentBattlerFlags\n\ -_08022C2C:\n\ - ldr r6, _08022C60 @ =gSpecialStatuses\n\ - ldrb r0, [r4]\n\ - lsls r1, r0, 2\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - adds r1, r6\n\ - ldrb r0, [r1]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _08022C6C\n\ - ldr r0, _08022C64 @ =gSharedMem\n\ - ldr r1, _08022C68 @ =0x0001606a\n\ - adds r0, r1\n\ - ldrb r0, [r0]\n\ - bl sub_8022A3C\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldrb r1, [r0]\n\ - movs r2, 0x40\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ - b _08022C7E\n\ - .align 2, 0\n\ -_08022C60: .4byte gSpecialStatuses\n\ -_08022C64: .4byte gSharedMem\n\ -_08022C68: .4byte 0x0001606a\n\ -_08022C6C:\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - bl EmitLinkStandbyMsg\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - movs r2, 0x1\n\ - mov r9, r2\n\ -_08022C7E:\n\ - ldr r6, _08022CD8 @ =gBitTable\n\ - ldr r0, [r6, 0x8]\n\ - ands r0, r5\n\ - cmp r0, 0\n\ - beq _08022D40\n\ - ldr r0, [r6]\n\ - ands r0, r5\n\ - cmp r0, 0\n\ - bne _08022D40\n\ - ldr r4, _08022CDC @ =gActiveBattler\n\ - movs r0, 0x2\n\ - strb r0, [r4]\n\ - movs r0, 0x2\n\ - movs r1, 0x6\n\ - movs r2, 0x6\n\ - bl sub_8018018\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08022CE8\n\ - ldr r2, _08022CE0 @ =gAbsentBattlerFlags\n\ - ldrb r0, [r4]\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldr r0, [r0]\n\ - ldrb r1, [r2]\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ - ldr r2, _08022CE4 @ =gHitMarker\n\ - ldrb r0, [r4]\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldr r1, [r0]\n\ - lsls r1, 28\n\ - ldr r0, [r2]\n\ - bics r0, r1\n\ - str r0, [r2]\n\ - movs r0, 0\n\ - bl Emitcmd42\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - b _08022D40\n\ - .align 2, 0\n\ -_08022CD8: .4byte gBitTable\n\ -_08022CDC: .4byte gActiveBattler\n\ -_08022CE0: .4byte gAbsentBattlerFlags\n\ -_08022CE4: .4byte gHitMarker\n\ -_08022CE8:\n\ - ldr r6, _08022D1C @ =gSpecialStatuses\n\ - ldrb r0, [r4]\n\ - lsls r1, r0, 2\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - adds r1, r6\n\ - ldrb r0, [r1]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _08022D28\n\ - ldr r0, _08022D20 @ =gSharedMem\n\ - ldr r1, _08022D24 @ =0x00016068\n\ - adds r0, r1\n\ - ldrb r0, [r0]\n\ - bl sub_8022A3C\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldrb r1, [r0]\n\ - movs r2, 0x40\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ - b _08022D40\n\ - .align 2, 0\n\ -_08022D1C: .4byte gSpecialStatuses\n\ -_08022D20: .4byte gSharedMem\n\ -_08022D24: .4byte 0x00016068\n\ -_08022D28:\n\ - movs r0, 0x1\n\ - mov r2, r9\n\ - ands r0, r2\n\ - cmp r0, 0\n\ - bne _08022D40\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - bl EmitLinkStandbyMsg\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ -_08022D40:\n\ - ldr r6, _08022D90 @ =gBitTable\n\ - ldr r0, [r6, 0x4]\n\ - ands r0, r5\n\ - cmp r0, 0\n\ - beq _08022DF6\n\ - ldr r4, _08022D94 @ =gActiveBattler\n\ - movs r0, 0x1\n\ - strb r0, [r4]\n\ - movs r0, 0x1\n\ - movs r1, 0x6\n\ - movs r2, 0x6\n\ - bl sub_8018018\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08022DA0\n\ - ldr r2, _08022D98 @ =gAbsentBattlerFlags\n\ - ldrb r0, [r4]\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldr r0, [r0]\n\ - ldrb r1, [r2]\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ - ldr r2, _08022D9C @ =gHitMarker\n\ - ldrb r0, [r4]\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldr r1, [r0]\n\ - lsls r1, 28\n\ - ldr r0, [r2]\n\ - bics r0, r1\n\ - str r0, [r2]\n\ - movs r0, 0\n\ - bl Emitcmd42\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - b _08022DF6\n\ - .align 2, 0\n\ -_08022D90: .4byte gBitTable\n\ -_08022D94: .4byte gActiveBattler\n\ -_08022D98: .4byte gAbsentBattlerFlags\n\ -_08022D9C: .4byte gHitMarker\n\ -_08022DA0:\n\ - ldr r6, _08022DD4 @ =gSpecialStatuses\n\ - ldrb r0, [r4]\n\ - lsls r1, r0, 2\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - adds r1, r6\n\ - ldrb r0, [r1]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _08022DE0\n\ - ldr r0, _08022DD8 @ =gSharedMem\n\ - ldr r1, _08022DDC @ =0x0001606b\n\ - adds r0, r1\n\ - ldrb r0, [r0]\n\ - bl sub_8022A3C\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldrb r1, [r0]\n\ - movs r2, 0x40\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ - b _08022DF6\n\ - .align 2, 0\n\ -_08022DD4: .4byte gSpecialStatuses\n\ -_08022DD8: .4byte gSharedMem\n\ -_08022DDC: .4byte 0x0001606b\n\ -_08022DE0:\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - bl EmitLinkStandbyMsg\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - movs r0, 0x2\n\ - mov r2, r9\n\ - orrs r2, r0\n\ - mov r9, r2\n\ -_08022DF6:\n\ - ldr r6, _08022E50 @ =gBitTable\n\ - ldr r0, [r6, 0xC]\n\ - ands r0, r5\n\ - cmp r0, 0\n\ - beq _08022EB8\n\ - ldr r0, [r6, 0x4]\n\ - ands r0, r5\n\ - cmp r0, 0\n\ - bne _08022EB8\n\ - ldr r4, _08022E54 @ =gActiveBattler\n\ - movs r0, 0x3\n\ - strb r0, [r4]\n\ - movs r0, 0x3\n\ - movs r1, 0x6\n\ - movs r2, 0x6\n\ - bl sub_8018018\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08022E60\n\ - ldr r2, _08022E58 @ =gAbsentBattlerFlags\n\ - ldrb r0, [r4]\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldr r0, [r0]\n\ - ldrb r1, [r2]\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ - ldr r2, _08022E5C @ =gHitMarker\n\ - ldrb r0, [r4]\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldr r1, [r0]\n\ - lsls r1, 28\n\ - ldr r0, [r2]\n\ - bics r0, r1\n\ - str r0, [r2]\n\ - movs r0, 0\n\ - bl Emitcmd42\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - b _08022EB8\n\ - .align 2, 0\n\ -_08022E50: .4byte gBitTable\n\ -_08022E54: .4byte gActiveBattler\n\ -_08022E58: .4byte gAbsentBattlerFlags\n\ -_08022E5C: .4byte gHitMarker\n\ -_08022E60:\n\ - ldr r6, _08022E94 @ =gSpecialStatuses\n\ - ldrb r0, [r4]\n\ - lsls r1, r0, 2\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - adds r1, r6\n\ - ldrb r0, [r1]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _08022EA0\n\ - ldr r0, _08022E98 @ =gSharedMem\n\ - ldr r1, _08022E9C @ =0x00016069\n\ - adds r0, r1\n\ - ldrb r0, [r0]\n\ - bl sub_8022A3C\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldrb r1, [r0]\n\ - movs r2, 0x40\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ - b _08022EB8\n\ - .align 2, 0\n\ -_08022E94: .4byte gSpecialStatuses\n\ -_08022E98: .4byte gSharedMem\n\ -_08022E9C: .4byte 0x00016069\n\ -_08022EA0:\n\ - movs r0, 0x2\n\ - mov r2, r9\n\ - ands r2, r0\n\ - cmp r2, 0\n\ - bne _08022EB8\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - bl EmitLinkStandbyMsg\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ -_08022EB8:\n\ - ldr r1, _08022EE8 @ =gSpecialStatuses\n\ - ldrb r0, [r1]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _08022F0C\n\ - adds r0, r1, 0\n\ - adds r0, 0x28\n\ - ldrb r0, [r0]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _08022F0C\n\ - cmp r5, 0\n\ - beq _08022F0C\n\ - ldr r0, _08022EEC @ =gAbsentBattlerFlags\n\ - ldrb r1, [r0]\n\ - ldr r0, _08022EF0 @ =gBitTable\n\ - ldr r0, [r0]\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - beq _08022EF8\n\ - ldr r1, _08022EF4 @ =gActiveBattler\n\ - movs r0, 0x2\n\ - strb r0, [r1]\n\ - b _08022EFC\n\ - .align 2, 0\n\ -_08022EE8: .4byte gSpecialStatuses\n\ -_08022EEC: .4byte gAbsentBattlerFlags\n\ -_08022EF0: .4byte gBitTable\n\ -_08022EF4: .4byte gActiveBattler\n\ -_08022EF8:\n\ - ldr r0, _08022F3C @ =gActiveBattler\n\ - strb r1, [r0]\n\ -_08022EFC:\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - bl EmitLinkStandbyMsg\n\ - ldr r0, _08022F3C @ =gActiveBattler\n\ - ldrb r0, [r0]\n\ - bl MarkBufferBankForExecution\n\ -_08022F0C:\n\ - ldr r1, _08022F40 @ =gSpecialStatuses\n\ - ldrb r0, [r1, 0x14]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _08022F62\n\ - adds r0, r1, 0\n\ - adds r0, 0x3C\n\ - ldrb r0, [r0]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _08022F62\n\ - cmp r5, 0\n\ - beq _08022F62\n\ - ldr r0, _08022F44 @ =gAbsentBattlerFlags\n\ - ldrb r0, [r0]\n\ - ldr r1, _08022F48 @ =gBitTable\n\ - ldr r1, [r1, 0x4]\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08022F4C\n\ - ldr r1, _08022F3C @ =gActiveBattler\n\ - movs r0, 0x3\n\ - b _08022F50\n\ - .align 2, 0\n\ -_08022F3C: .4byte gActiveBattler\n\ -_08022F40: .4byte gSpecialStatuses\n\ -_08022F44: .4byte gAbsentBattlerFlags\n\ -_08022F48: .4byte gBitTable\n\ -_08022F4C:\n\ - ldr r1, _08022F6C @ =gActiveBattler\n\ - movs r0, 0x1\n\ -_08022F50:\n\ - strb r0, [r1]\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - bl EmitLinkStandbyMsg\n\ - ldr r0, _08022F6C @ =gActiveBattler\n\ - ldrb r0, [r0]\n\ - bl MarkBufferBankForExecution\n\ -_08022F62:\n\ - ldr r1, _08022F70 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x6\n\ - str r0, [r1]\n\ - b _08023302\n\ - .align 2, 0\n\ -_08022F6C: .4byte gActiveBattler\n\ -_08022F70: .4byte gBattlescriptCurrInstr\n\ -_08022F74:\n\ - cmp r0, 0x6\n\ - beq _08022F7A\n\ - b _08023170\n\ -_08022F7A:\n\ - ldr r0, _08022FF0 @ =gBattleTypeFlags\n\ - ldrh r2, [r0]\n\ - movs r0, 0x40\n\ - ands r0, r2\n\ - cmp r0, 0\n\ - beq _08022F88\n\ - b _0802310C\n\ -_08022F88:\n\ - movs r0, 0x1\n\ - ands r0, r2\n\ - cmp r0, 0\n\ - bne _08022F92\n\ - b _0802310C\n\ -_08022F92:\n\ - ldr r7, _08022FF4 @ =gHitMarker\n\ - ldr r0, [r7]\n\ - lsrs r5, r0, 28\n\ - ldr r4, _08022FF8 @ =gBitTable\n\ - ldr r0, [r4, 0x8]\n\ - ands r0, r5\n\ - cmp r0, 0\n\ - beq _0802303A\n\ - ldr r0, [r4]\n\ - ands r0, r5\n\ - cmp r0, 0\n\ - beq _0802303A\n\ - ldr r6, _08022FFC @ =gActiveBattler\n\ - movs r0, 0x2\n\ - strb r0, [r6]\n\ - ldr r0, _08023000 @ =gBattleBufferB\n\ - ldrb r1, [r0, 0x1]\n\ - movs r0, 0x2\n\ - movs r2, 0x6\n\ - bl sub_8018018\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08023008\n\ - ldr r2, _08023004 @ =gAbsentBattlerFlags\n\ - ldrb r0, [r6]\n\ - lsls r0, 2\n\ - adds r0, r4\n\ - ldr r0, [r0]\n\ - ldrb r1, [r2]\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ - ldrb r0, [r6]\n\ - lsls r0, 2\n\ - adds r0, r4\n\ - ldr r1, [r0]\n\ - lsls r1, 28\n\ - ldr r0, [r7]\n\ - bics r0, r1\n\ - str r0, [r7]\n\ - movs r0, 0\n\ - bl Emitcmd42\n\ - ldrb r0, [r6]\n\ - bl MarkBufferBankForExecution\n\ - b _0802303A\n\ - .align 2, 0\n\ -_08022FF0: .4byte gBattleTypeFlags\n\ -_08022FF4: .4byte gHitMarker\n\ -_08022FF8: .4byte gBitTable\n\ -_08022FFC: .4byte gActiveBattler\n\ -_08023000: .4byte gBattleBufferB\n\ -_08023004: .4byte gAbsentBattlerFlags\n\ -_08023008:\n\ - ldr r4, _08023098 @ =gSpecialStatuses\n\ - ldrb r0, [r6]\n\ - lsls r1, r0, 2\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - adds r1, r4\n\ - ldrb r0, [r1]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _0802303A\n\ - ldr r0, _0802309C @ =gSharedMem\n\ - ldr r1, _080230A0 @ =0x00016068\n\ - adds r0, r1\n\ - ldrb r0, [r0]\n\ - bl sub_8022A3C\n\ - ldrb r1, [r6]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r4\n\ - ldrb r1, [r0]\n\ - movs r2, 0x40\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ -_0802303A:\n\ - ldr r4, _080230A4 @ =gBitTable\n\ - ldr r0, [r4, 0xC]\n\ - ands r0, r5\n\ - cmp r0, 0\n\ - beq _080230EE\n\ - ldr r0, [r4, 0x4]\n\ - ands r5, r0\n\ - cmp r5, 0\n\ - beq _080230EE\n\ - ldr r5, _080230A8 @ =gActiveBattler\n\ - movs r0, 0x3\n\ - strb r0, [r5]\n\ - ldr r0, _080230AC @ =gBattleBufferB\n\ - ldr r2, _080230B0 @ =0x00000201\n\ - adds r0, r2\n\ - ldrb r1, [r0]\n\ - movs r0, 0x3\n\ - movs r2, 0x6\n\ - bl sub_8018018\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _080230BC\n\ - ldr r2, _080230B4 @ =gAbsentBattlerFlags\n\ - ldrb r0, [r5]\n\ - lsls r0, 2\n\ - adds r0, r4\n\ - ldr r0, [r0]\n\ - ldrb r1, [r2]\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ - ldr r2, _080230B8 @ =gHitMarker\n\ - ldrb r0, [r5]\n\ - lsls r0, 2\n\ - adds r0, r4\n\ - ldr r1, [r0]\n\ - lsls r1, 28\n\ - ldr r0, [r2]\n\ - bics r0, r1\n\ - str r0, [r2]\n\ - movs r0, 0\n\ - bl Emitcmd42\n\ - ldrb r0, [r5]\n\ - bl MarkBufferBankForExecution\n\ - b _080230EE\n\ - .align 2, 0\n\ -_08023098: .4byte gSpecialStatuses\n\ -_0802309C: .4byte gSharedMem\n\ -_080230A0: .4byte 0x00016068\n\ -_080230A4: .4byte gBitTable\n\ -_080230A8: .4byte gActiveBattler\n\ -_080230AC: .4byte gBattleBufferB\n\ -_080230B0: .4byte 0x00000201\n\ -_080230B4: .4byte gAbsentBattlerFlags\n\ -_080230B8: .4byte gHitMarker\n\ -_080230BC:\n\ - ldr r4, _080230FC @ =gSpecialStatuses\n\ - ldrb r0, [r5]\n\ - lsls r1, r0, 2\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - adds r1, r4\n\ - ldrb r0, [r1]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - blt _080230EE\n\ - ldr r0, _08023100 @ =gSharedMem\n\ - ldr r1, _08023104 @ =0x00016069\n\ - adds r0, r1\n\ - ldrb r0, [r0]\n\ - bl sub_8022A3C\n\ - ldrb r1, [r5]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r4\n\ - ldrb r1, [r0]\n\ - movs r2, 0x40\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ -_080230EE:\n\ - ldr r1, _08023108 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x6\n\ - str r0, [r1]\n\ - mov r12, r1\n\ - b _08023110\n\ - .align 2, 0\n\ -_080230FC: .4byte gSpecialStatuses\n\ -_08023100: .4byte gSharedMem\n\ -_08023104: .4byte 0x00016069\n\ -_08023108: .4byte gBattlescriptCurrInstr\n\ -_0802310C:\n\ - adds r0, r1, 0x6\n\ - str r0, [r6]\n\ -_08023110:\n\ - ldr r0, _08023160 @ =gHitMarker\n\ - ldr r0, [r0]\n\ - lsrs r5, r0, 28\n\ - ldr r1, _08023164 @ =gBank1\n\ - movs r0, 0\n\ - strb r0, [r1]\n\ - ldr r4, _08023168 @ =gBitTable\n\ - ldr r2, [r4]\n\ - ands r2, r5\n\ - ldr r6, _0802316C @ =gBattlersCount\n\ - cmp r2, 0\n\ - bne _0802314C\n\ - adds r7, r6, 0\n\ - ldrb r0, [r6]\n\ - cmp r2, r0\n\ - bcs _0802314C\n\ - adds r3, r1, 0\n\ -_08023132:\n\ - ldrb r0, [r3]\n\ - adds r0, 0x1\n\ - strb r0, [r3]\n\ - ldrb r2, [r3]\n\ - lsls r0, r2, 2\n\ - adds r0, r4\n\ - ldr r0, [r0]\n\ - ands r0, r5\n\ - cmp r0, 0\n\ - bne _0802314C\n\ - ldrb r0, [r7]\n\ - cmp r2, r0\n\ - bcc _08023132\n\ -_0802314C:\n\ - ldrb r0, [r1]\n\ - ldrb r6, [r6]\n\ - cmp r0, r6\n\ - beq _08023156\n\ - b _08023302\n\ -_08023156:\n\ - mov r1, r8\n\ - mov r2, r12\n\ - str r1, [r2]\n\ - b _08023302\n\ - .align 2, 0\n\ -_08023160: .4byte gHitMarker\n\ -_08023164: .4byte gBank1\n\ -_08023168: .4byte gBitTable\n\ -_0802316C: .4byte gBattlersCount\n\ -_08023170:\n\ - movs r0, 0x80\n\ - ands r0, r2\n\ - movs r5, 0x1\n\ - cmp r0, 0\n\ - beq _0802317C\n\ - movs r5, 0\n\ -_0802317C:\n\ - movs r0, 0x7F\n\ - ands r0, r2\n\ - bl GetBattleBank\n\ - lsls r0, 24\n\ - lsrs r7, r0, 24\n\ - ldr r1, _080231A4 @ =gSpecialStatuses\n\ - lsls r0, r7, 2\n\ - adds r0, r7\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldrb r0, [r0]\n\ - lsls r0, 25\n\ - cmp r0, 0\n\ - bge _080231A8\n\ - ldr r0, [r6]\n\ - adds r0, 0x6\n\ - str r0, [r6]\n\ - b _08023302\n\ - .align 2, 0\n\ -_080231A4: .4byte gSpecialStatuses\n\ -_080231A8:\n\ - adds r0, r7, 0\n\ - movs r1, 0x6\n\ - movs r2, 0x6\n\ - bl sub_8018018\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _080231F8\n\ - ldr r2, _080231E8 @ =gActiveBattler\n\ - strb r7, [r2]\n\ - ldr r3, _080231EC @ =gAbsentBattlerFlags\n\ - ldr r4, _080231F0 @ =gBitTable\n\ - ldrb r0, [r2]\n\ - lsls r0, 2\n\ - adds r0, r4\n\ - ldr r0, [r0]\n\ - ldrb r1, [r3]\n\ - orrs r0, r1\n\ - strb r0, [r3]\n\ - ldr r3, _080231F4 @ =gHitMarker\n\ - ldrb r0, [r2]\n\ - lsls r0, 2\n\ - adds r0, r4\n\ - ldr r1, [r0]\n\ - lsls r1, 28\n\ - ldr r0, [r3]\n\ - bics r0, r1\n\ - str r0, [r3]\n\ - mov r0, r8\n\ - str r0, [r6]\n\ - b _08023302\n\ - .align 2, 0\n\ -_080231E8: .4byte gActiveBattler\n\ -_080231EC: .4byte gAbsentBattlerFlags\n\ -_080231F0: .4byte gBitTable\n\ -_080231F4: .4byte gHitMarker\n\ -_080231F8:\n\ - ldr r4, _080232A0 @ =gActiveBattler\n\ - strb r7, [r4]\n\ - ldr r3, _080232A4 @ =gSharedMem\n\ - ldrb r0, [r4]\n\ - ldr r2, _080232A8 @ =0x00016064\n\ - adds r1, r0, r2\n\ - adds r1, r3\n\ - ldr r2, _080232AC @ =gBattlerPartyIndexes\n\ - lsls r0, 1\n\ - adds r0, r2\n\ - ldrh r0, [r0]\n\ - strb r0, [r1]\n\ - ldrb r1, [r4]\n\ - movs r0, 0x2\n\ - eors r0, r1\n\ - ldr r1, _080232B0 @ =0x00016068\n\ - adds r0, r1\n\ - adds r0, r3\n\ - ldrb r2, [r0]\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - ldr r1, _080232B4 @ =0x0001606c\n\ - adds r3, r1\n\ - adds r0, r3\n\ - str r0, [sp]\n\ - movs r0, 0\n\ - adds r1, r5, 0\n\ - movs r3, 0\n\ - bl EmitChoosePokemon\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ - ldr r0, [r6]\n\ - adds r0, 0x6\n\ - str r0, [r6]\n\ - ldrb r0, [r4]\n\ - bl GetBattlerPosition\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _0802325A\n\ - ldr r1, _080232B8 @ =gBattleResults\n\ - ldrb r0, [r1, 0x2]\n\ - cmp r0, 0xFE\n\ - bhi _0802325A\n\ - adds r0, 0x1\n\ - strb r0, [r1, 0x2]\n\ -_0802325A:\n\ - ldr r0, _080232BC @ =gBattleTypeFlags\n\ - ldrh r1, [r0]\n\ - movs r0, 0x40\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _080232C4\n\ - ldr r1, _080232A0 @ =gActiveBattler\n\ - movs r0, 0\n\ - strb r0, [r1]\n\ - ldr r0, _080232C0 @ =gBattlersCount\n\ - ldrb r0, [r0]\n\ - cmp r0, 0\n\ - beq _08023302\n\ - adds r4, r1, 0\n\ -_08023276:\n\ - ldrb r0, [r4]\n\ - cmp r0, r7\n\ - beq _0802328A\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - bl EmitLinkStandbyMsg\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ -_0802328A:\n\ - ldrb r0, [r4]\n\ - adds r0, 0x1\n\ - strb r0, [r4]\n\ - ldr r1, _080232C0 @ =gBattlersCount\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - ldrb r1, [r1]\n\ - cmp r0, r1\n\ - bcc _08023276\n\ - b _08023302\n\ - .align 2, 0\n\ -_080232A0: .4byte gActiveBattler\n\ -_080232A4: .4byte gSharedMem\n\ -_080232A8: .4byte 0x00016064\n\ -_080232AC: .4byte gBattlerPartyIndexes\n\ -_080232B0: .4byte 0x00016068\n\ -_080232B4: .4byte 0x0001606c\n\ -_080232B8: .4byte gBattleResults\n\ -_080232BC: .4byte gBattleTypeFlags\n\ -_080232C0: .4byte gBattlersCount\n\ -_080232C4:\n\ - adds r0, r7, 0\n\ - bl GetBattlerPosition\n\ - movs r1, 0x1\n\ - eors r0, r1\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - bl GetBattlerAtPosition\n\ - ldr r4, _08023310 @ =gActiveBattler\n\ - strb r0, [r4]\n\ - ldr r0, _08023314 @ =gAbsentBattlerFlags\n\ - ldrb r1, [r0]\n\ - ldr r2, _08023318 @ =gBitTable\n\ - ldrb r3, [r4]\n\ - lsls r0, r3, 2\n\ - adds r0, r2\n\ - ldr r0, [r0]\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - beq _080232F4\n\ - movs r0, 0x2\n\ - eors r3, r0\n\ - strb r3, [r4]\n\ -_080232F4:\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - bl EmitLinkStandbyMsg\n\ - ldrb r0, [r4]\n\ - bl MarkBufferBankForExecution\n\ -_08023302:\n\ - add sp, 0x4\n\ - pop {r3,r4}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_08023310: .4byte gActiveBattler\n\ -_08023314: .4byte gAbsentBattlerFlags\n\ -_08023318: .4byte gBitTable\n\ - .syntax divided"); -} - -static void atk51_switchhandleorder(void) -{ - int i; - if (gBattleExecBuffer) - return; - - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - switch (T2_READ_8(gBattlescriptCurrInstr + 2)) - { - case 0: - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleBufferB[i][0] == 0x22) - ewram16068arr(i) = gBattleBufferB[i][1]; - } - break; - case 1: - if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - sub_8012258(gActiveBattler); - break; - case 2: - gBattleCommunication[0] = gBattleBufferB[gActiveBattler][1]; - ewram16068arr(gActiveBattler) = gBattleBufferB[gActiveBattler][1]; - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - ewram1606Carr(0, gActiveBattler) &= 0xF; - ewram1606Carr(0, gActiveBattler) |= (gBattleBufferB[gActiveBattler][2] & 0xF0); - ewram1606Carr(1, gActiveBattler) = gBattleBufferB[gActiveBattler][3]; - ewram1606Carr(0, (gActiveBattler ^ 2)) &= (0xF0); - ewram1606Carr(0, (gActiveBattler ^ 2)) |= (gBattleBufferB[gActiveBattler][2] & 0xF0) >> 4; - ewram1606Carr(2, (gActiveBattler ^ 2)) = gBattleBufferB[gActiveBattler][3]; - } - else - sub_8012258(gActiveBattler); - - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 6; - gBattleTextBuff1[2] = gBattleMons[gBankAttacker].species; - gBattleTextBuff1[3] = gBattleMons[gBankAttacker].species >> 8; - gBattleTextBuff1[4] = 0xFF; - - gBattleTextBuff2[0] = 0xFD; - gBattleTextBuff2[1] = 7; - gBattleTextBuff2[2] = gActiveBattler; - gBattleTextBuff2[3] = gBattleBufferB[gActiveBattler][1]; - gBattleTextBuff2[4] = 0xFF; - break; - } - gBattlescriptCurrInstr += 3; -} - -static void atk52_switchineffects(void) -{ - int i; - - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - sub_80157C4(gActiveBattler); - gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler)); - gSpecialStatuses[gActiveBattler].flag40 = 0; - - if (!(gSideAffecting[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED) && (gSideAffecting[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES) - && gBattleMons[gActiveBattler].type1 != TYPE_FLYING && gBattleMons[gActiveBattler].type2 != TYPE_FLYING && gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE) - { - u8 spikesDmg; - - gSideAffecting[GetBattlerSide(gActiveBattler)] |= SIDE_STATUS_SPIKES_DAMAGED; - - spikesDmg = (5 - gSideTimers[GetBattlerSide(gActiveBattler)].spikesAmount) * 2; - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / (spikesDmg); - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - - gBattleStruct->scriptingActive = gActiveBattler; - BattleScriptPushCursor(); - - if (T2_READ_8(gBattlescriptCurrInstr + 1) == 0) - gBattlescriptCurrInstr = BattleScript_SpikesOnTarget; - else if (T2_READ_8(gBattlescriptCurrInstr + 1) == 1) - gBattlescriptCurrInstr = BattleScript_SpikesOnAttacker; - else - gBattlescriptCurrInstr = BattleScript_SpikesOngBank1; - } - else - { - if (gBattleMons[gActiveBattler].ability == ABILITY_TRUANT) - { - gDisableStructs[gActiveBattler].truantCounter = 1; - } - - if (AbilityBattleEffects(0, gActiveBattler, 0, 0, 0) == 0 && ItemBattleEffects(0, gActiveBattler, 0) == 0) - { - gSideAffecting[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_SPIKES_DAMAGED); - - for (i = 0; i < gBattlersCount; i++) - { - if (gBanksByTurnOrder[i] == gActiveBattler) - gActionsByTurnOrder[i] = 0xC; - } - - for (i = 0; i < gBattlersCount; i++) - { - *(HP_ON_SWITCHOUT + GetBattlerSide(i)) = gBattleMons[i].hp; - } - - if (T2_READ_8(gBattlescriptCurrInstr + 1) == 5) - { - u32 hitmark = gHitMarker >> 0x1C; - gBank1++; - while (1) - { - if (hitmark & gBitTable[gBank1] && !(gAbsentBattlerFlags & gBitTable[gBank1])) - break; - if (gBank1 >= gBattlersCount) - break; - gBank1++; - } - } - gBattlescriptCurrInstr += 2; - } - } -} - -static void atk53_trainerslidein(void) -{ - if (!T2_READ_8(gBattlescriptCurrInstr + 1)) - gActiveBattler = GetBattlerAtPosition(0); - else - gActiveBattler = GetBattlerAtPosition(1); - - EmitTrainerSlide(0); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 2; -} - -static void atk54_playse(void) -{ - gActiveBattler = gBankAttacker; - EmitEffectivenessSound(0, T2_READ_16(gBattlescriptCurrInstr + 1)); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 3; -} - -static void atk55_fanfare(void) -{ - gActiveBattler = gBankAttacker; - Emitcmd44(0, T2_READ_16(gBattlescriptCurrInstr + 1)); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 3; -} - -static void atk56_playfaintcry(void) -{ - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - EmitFaintingCry(0); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 2; -} - -static void atk57(void) -{ - gActiveBattler = GetBattlerAtPosition(0); - Emitcmd55(0, gBattleOutcome); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 1; -} - -static void atk58_returntoball(void) -{ - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - EmitReturnPokeToBall(0, 1); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 2; -} - -void atk59_handlelearnnewmove(void) -{ - u8* loc1 = T1_READ_PTR(gBattlescriptCurrInstr + 1); - u8* loc2 = T1_READ_PTR(gBattlescriptCurrInstr + 5); - - u16 ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterID], T2_READ_8(gBattlescriptCurrInstr + 9)); - while (ret == 0xFFFE) - ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterID], 0); - - if (ret == 0) - { - gBattlescriptCurrInstr = loc2; - } - else if (ret == 0xFFFF) - { - gBattlescriptCurrInstr += 10; - } - else - { - gActiveBattler = GetBattlerAtPosition(0); - if (gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterID && !(gBattleMons[gActiveBattler].status2 & STATUS2_TRANSFORMED)) - GiveMoveToBattleMon(&gBattleMons[gActiveBattler], ret); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) //what is else if - { - gActiveBattler = GetBattlerAtPosition(2); - if (gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterID && !(gBattleMons[gActiveBattler].status2 & STATUS2_TRANSFORMED)) - GiveMoveToBattleMon(&gBattleMons[gActiveBattler], ret); - } - gBattlescriptCurrInstr = loc1; - } -} - -void sub_8023A80(void) -{ - sub_802BBD4(0x18, 8, 0x1D, 0xD, 0); - Text_InitWindow(&gUnknown_03004210, BattleText_YesNo, 0x100, 0x19, 0x9); - Text_PrintWindow8002F44(&gUnknown_03004210); - MenuCursor_Create814A5C0(0, 0xFFFF, 0xC, 0x2D9F, 0x20); -} - -void sub_8023AD8(void) -{ - sub_802BBD4(0x18, 8, 0x1D, 0xD, 1); - DestroyMenuCursor(); -} - -static void atk5A_yesnoboxlearnmove(void) -{ - gActiveBattler = 0; - switch (gBattleStruct->atk5A_StateTracker) - { - case 0: - sub_8023A80(); - gBattleStruct->atk5A_StateTracker++; - gBattleCommunication[1] = 0; - sub_802BC6C(); - break; - case 1: - if (gMain.newKeys & DPAD_UP && gBattleCommunication[1] != 0) - { - PlaySE(SE_SELECT); - nullsub_6(); - gBattleCommunication[1] = 0; - sub_802BC6C(); - } - if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[1] == 0) - { - PlaySE(SE_SELECT); - nullsub_6(); - gBattleCommunication[1] = 1; - sub_802BC6C(); - } - if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - if (gBattleCommunication[1] == 0) - { - sub_8023AD8(); - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); - gBattleStruct->atk5A_StateTracker++; - return; - } - goto state_tracker_4; - } - else if (gMain.newKeys & B_BUTTON) - { - PlaySE(SE_SELECT); - state_tracker_4: - gBattleStruct->atk5A_StateTracker = 4; - } - break; - case 2: - if (!gPaletteFade.active) - { - ShowSelectMovePokemonSummaryScreen(gPlayerParty, gBattleStruct->expGetterID, gPlayerPartyCount - 1, ReshowBattleScreenAfterMenu, gMoveToLearn); - gBattleStruct->atk5A_StateTracker++; - } - break; - case 3: - if (!gPaletteFade.active && gMain.callback2 == BattleMainCB2) - { - u8 move_pos = sub_809FA30(); - if (move_pos == 4) - { - gBattleStruct->atk5A_StateTracker = 4; - } - else - { - u16 move = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_MOVE1 + move_pos); - if (IsHMMove2(move)) - { - PrepareStringBattle(0x13F, gActiveBattler); - gBattleStruct->atk5A_StateTracker = 5; - } - else - { - u8 *ptr; - - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - ptr = gBattleTextBuff2; - { - ptr[0] = 0xFD; - ptr[1] = 2; - ptr[2] = move; - ptr[3] = ((move & 0xFF00) >> 8); - ptr += 4; - } - ptr[0] = 0xFF; - RemoveMonPPBonus(&gPlayerParty[gBattleStruct->expGetterID], move_pos); - SetMonMoveSlot(&gPlayerParty[gBattleStruct->expGetterID], gMoveToLearn, move_pos); - if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterID && !(gBattleMons[0].status2 & STATUS2_TRANSFORMED) - && !(gDisableStructs[0].unk18_b & gBitTable[move_pos])) - { - RemoveBattleMonPPBonus(&gBattleMons[0], move_pos); - SetBattleMonMoveSlot(&gBattleMons[0], gMoveToLearn, move_pos); - } - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlerPartyIndexes[2] == gBattleStruct->expGetterID && !(gBattleMons[2].status2 & STATUS2_TRANSFORMED) - && !(gDisableStructs[2].unk18_b & gBitTable[move_pos])) - { - RemoveBattleMonPPBonus(&gBattleMons[2], move_pos); - SetBattleMonMoveSlot(&gBattleMons[2], gMoveToLearn, move_pos); - } - } - } - } - break; - case 4: - sub_8023AD8(); - gBattlescriptCurrInstr += 5; - break; - case 5: - if (gBattleExecBuffer == 0) - { - gBattleStruct->atk5A_StateTracker = 2; - } - break; - } -} - -static void atk5B_yesnoboxstoplearningmove(void) -{ - switch (gBattleStruct->atk5A_StateTracker) - { - case 0: - sub_8023A80(); - gBattleStruct->atk5A_StateTracker++; - gBattleCommunication[1] = 0; - sub_802BC6C(); - break; - case 1: - if (gMain.newKeys & DPAD_UP && gBattleCommunication[1] != 0) - { - PlaySE(SE_SELECT); - nullsub_6(); - gBattleCommunication[1] = 0; - sub_802BC6C(); - } - if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[1] == 0) - { - PlaySE(SE_SELECT); - nullsub_6(); - gBattleCommunication[1] = 1; - sub_802BC6C(); - } - if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - if (gBattleCommunication[1] != 0) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr += 5; - sub_8023AD8(); - } - else if (gMain.newKeys & B_BUTTON) - { - PlaySE(SE_SELECT); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - sub_8023AD8(); - } - } -} - -static void atk5C_hitanimation(void) -{ - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - gBattlescriptCurrInstr += 2; - else if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE) || !(gBattleMons[gActiveBattler].status2 & STATUS2_SUBSTITUTE) || gDisableStructs[gActiveBattler].substituteHP == 0) - { - EmitHitAnimation(0); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 2; - } - else - gBattlescriptCurrInstr += 2; -} - -#define MONEY_UNKNOWN ((*(u8*)(ewram_addr + 0x17000 + 0x94))) - -#ifdef NONMATCHING -static void atk5D_getmoneyreward(void) -{ - int i = 0; - u8 r5 = 0; - u32 money_to_give; - if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) - { - money_to_give = 2 * gBattleStruct->moneyMultiplier * MONEY_UNKNOWN; - } - else - { - switch(gTrainers[gTrainerBattleOpponent].partyFlags) - { - case 0: - { - const struct PokeTrainerData1 *data = &gTrainers[gTrainerBattleOpponent].party->noItemNoMoves; - r5 = data[gTrainers[gTrainerBattleOpponent].partySize - 1].lvl; - } - break; - case 2: - { - const struct PokeTrainerData2 *data = &gTrainers[gTrainerBattleOpponent].party->itemNoMoves; - r5 = data[gTrainers[gTrainerBattleOpponent].partySize - 1].lvl; - } - break; - case 1: - case 3: - { - const struct PokeTrainerData3 *data = &gTrainers[gTrainerBattleOpponent].party->itemMoves; - r5 = data[gTrainers[gTrainerBattleOpponent].partySize - 1].lvl; - } - break; - } - for (; gTrainerMoney[i * 4] != 0xFF && gTrainerMoney[i * 4 + 1] != gTrainers[gTrainerBattleOpponent].trainerClass ; i++) {} - - money_to_give = (r5 << 2) * gBattleStruct->moneyMultiplier; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - money_to_give = 2 * gTrainerMoney[i * 4 + 1] * money_to_give; - else - money_to_give = 1 * gTrainerMoney[i * 4 + 1] * money_to_give; - } - - AddMoney(&gSaveBlock1.money, money_to_give); - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 1; - gBattleTextBuff1[2] = 4; - gBattleTextBuff1[3] = 5; - gBattleTextBuff1[4] = BYTE0(money_to_give); - gBattleTextBuff1[5] = BYTE1(money_to_give); - gBattleTextBuff1[6] = BYTE2(money_to_give); - gBattleTextBuff1[7] = BYTE3(money_to_give); - gBattleTextBuff1[8] = 0xFF; - - gBattlescriptCurrInstr += 1; -} -#else -NAKED -static void atk5D_getmoneyreward(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r8\n\ - push {r7}\n\ - movs r6, 0\n\ - movs r5, 0\n\ - ldr r0, _08024048 @ =gTrainerBattleOpponent\n\ - ldrh r2, [r0]\n\ - movs r1, 0x80\n\ - lsls r1, 3\n\ - cmp r2, r1\n\ - bne _08024058\n\ - ldr r0, _0802404C @ =gSharedMem + 0x17000\n\ - adds r1, r0, 0\n\ - adds r1, 0x94\n\ - ldrb r2, [r1]\n\ - ldr r1, _08024050 @ =0xfffff056\n\ - adds r0, r1\n\ - ldrb r1, [r0]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r4, r2, 0\n\ - muls r4, r0\n\ - ldr r0, _08024054 @ =gSaveBlock1 + 0x490\n\ - mov r8, r0\n\ - b _08024140\n\ - .align 2, 0\n\ -_08024048: .4byte gTrainerBattleOpponent\n\ -_0802404C: .4byte gSharedMem + 0x17000\n\ -_08024050: .4byte 0xfffff056\n\ -_08024054: .4byte gSaveBlock1 + 0x490\n\ -_08024058:\n\ - ldr r2, _08024074 @ =gTrainers\n\ - ldrh r1, [r0]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r3, r0, 3\n\ - adds r4, r3, r2\n\ - ldrb r1, [r4]\n\ - cmp r1, 0x1\n\ - beq _080240AE\n\ - cmp r1, 0x1\n\ - bgt _08024078\n\ - cmp r1, 0\n\ - beq _08024082\n\ - b _080240C4\n\ - .align 2, 0\n\ -_08024074: .4byte gTrainers\n\ -_08024078:\n\ - cmp r1, 0x2\n\ - beq _08024098\n\ - cmp r1, 0x3\n\ - beq _080240AE\n\ - b _080240C4\n\ -_08024082:\n\ - adds r0, r2, 0\n\ - adds r0, 0x24\n\ - adds r0, r3, r0\n\ - ldr r1, [r0]\n\ - adds r0, r4, 0\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - lsls r0, 3\n\ - adds r0, r1\n\ - subs r0, 0x8\n\ - b _080240C2\n\ -_08024098:\n\ - adds r0, r2, 0\n\ - adds r0, 0x24\n\ - adds r0, r3, r0\n\ - ldr r1, [r0]\n\ - adds r0, r4, 0\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - lsls r0, 3\n\ - adds r0, r1\n\ - subs r0, 0x8\n\ - b _080240C2\n\ -_080240AE:\n\ - adds r0, r2, 0\n\ - adds r0, 0x24\n\ - adds r0, r3, r0\n\ - ldr r1, [r0]\n\ - adds r0, r4, 0\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - lsls r0, 4\n\ - adds r0, r1\n\ - subs r0, 0x10\n\ -_080240C2:\n\ - ldrb r5, [r0, 0x2]\n\ -_080240C4:\n\ - ldr r0, _08024120 @ =gTrainerMoney\n\ - lsls r1, r6, 2\n\ - adds r3, r1, r0\n\ - ldrb r1, [r3]\n\ - mov r12, r0\n\ - lsls r4, r5, 2\n\ - ldr r5, _08024124 @ =gSharedMem\n\ - ldr r7, _08024128 @ =gBattleTypeFlags\n\ - ldr r0, _0802412C @ =gSaveBlock1 + 0x490\n\ - mov r8, r0\n\ - cmp r1, 0xFF\n\ - beq _080240FE\n\ - ldr r2, _08024130 @ =gTrainers\n\ - ldr r0, _08024134 @ =gTrainerBattleOpponent\n\ - ldrh r1, [r0]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r0, 3\n\ - adds r0, r2\n\ - ldrb r2, [r0, 0x1]\n\ - adds r1, r3, 0\n\ -_080240EE:\n\ - ldrb r0, [r1]\n\ - cmp r0, r2\n\ - beq _080240FE\n\ - adds r1, 0x4\n\ - adds r6, 0x1\n\ - ldrb r0, [r1]\n\ - cmp r0, 0xFF\n\ - bne _080240EE\n\ -_080240FE:\n\ - ldr r1, _08024138 @ =0x00016056\n\ - adds r0, r5, r1\n\ - ldrb r0, [r0]\n\ - adds r3, r4, 0\n\ - muls r3, r0\n\ - lsls r0, r6, 2\n\ - add r0, r12\n\ - ldrb r2, [r0, 0x1]\n\ - ldrh r1, [r7]\n\ - movs r0, 0x1\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0802413C\n\ - lsls r0, r2, 1\n\ - adds r4, r3, 0\n\ - muls r4, r0\n\ - b _08024140\n\ - .align 2, 0\n\ -_08024120: .4byte gTrainerMoney\n\ -_08024124: .4byte gSharedMem\n\ -_08024128: .4byte gBattleTypeFlags\n\ -_0802412C: .4byte gSaveBlock1 + 0x490\n\ -_08024130: .4byte gTrainers\n\ -_08024134: .4byte gTrainerBattleOpponent\n\ -_08024138: .4byte 0x00016056\n\ -_0802413C:\n\ - adds r4, r3, 0\n\ - muls r4, r2\n\ -_08024140:\n\ - mov r0, r8\n\ - adds r1, r4, 0\n\ - bl AddMoney\n\ - ldr r1, _0802418C @ =gBattleTextBuff1\n\ - movs r0, 0xFD\n\ - strb r0, [r1]\n\ - movs r0, 0x1\n\ - strb r0, [r1, 0x1]\n\ - movs r0, 0x4\n\ - strb r0, [r1, 0x2]\n\ - movs r0, 0x5\n\ - strb r0, [r1, 0x3]\n\ - strb r4, [r1, 0x4]\n\ - movs r0, 0xFF\n\ - lsls r0, 8\n\ - ands r0, r4\n\ - lsrs r0, 8\n\ - strb r0, [r1, 0x5]\n\ - movs r0, 0xFF\n\ - lsls r0, 16\n\ - ands r0, r4\n\ - lsrs r0, 16\n\ - strb r0, [r1, 0x6]\n\ - lsrs r0, r4, 24\n\ - strb r0, [r1, 0x7]\n\ - movs r0, 0xFF\n\ - strb r0, [r1, 0x8]\n\ - ldr r1, _08024190 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x1\n\ - str r0, [r1]\n\ - pop {r3}\n\ - mov r8, r3\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_0802418C: .4byte gBattleTextBuff1\n\ -_08024190: .4byte gBattlescriptCurrInstr\n\ - .syntax divided"); -} -#endif //NONMATCHING - -/* -static u32 GetTrainerMoneyToGive(u16 trainerId) -{ - u32 i = 0; - u32 lastMonLevel = 0; - u32 moneyReward = 0; - - if (trainerId == SECRET_BASE_OPPONENT) - { - moneyReward = 20 * eSecretBaseRecord->partyLevels[0] * gBattleStruct->moneyMultiplier; - } - else - { - switch (gTrainers[trainerId].partyFlags) - { - case 0: - { - const struct TrainerMonNoItemDefaultMoves *party = gTrainers[trainerId].party.NoItemDefaultMoves; - lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; - } - break; - case F_TRAINER_PARTY_CUSTOM_MOVESET: - { - const struct TrainerMonNoItemCustomMoves *party = gTrainers[trainerId].party.NoItemCustomMoves; - lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; - } - break; - case F_TRAINER_PARTY_HELD_ITEM: - { - const struct TrainerMonItemDefaultMoves *party = gTrainers[trainerId].party.ItemDefaultMoves; - lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; - } - break; - case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM: - { - const struct TrainerMonItemCustomMoves *party = gTrainers[trainerId].party.ItemCustomMoves; - lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; - } - break; - } - - for (; gTrainerMoneyTable[i].classId != 0xFF; i++) - { - if (gTrainerMoneyTable[i].classId == gTrainers[trainerId].trainerClass) - break; - } - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * 2 * gTrainerMoneyTable[i].value; - else - moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * gTrainerMoneyTable[i].value; - } - - return moneyReward; -} - -static void atk5D_getmoneyreward(void) -{ - u32 moneyReward = GetTrainerMoneyToGive(gTrainerBattleOpponent_A); - if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) - moneyReward += GetTrainerMoneyToGive(gTrainerBattleOpponent_B); - - AddMoney(&gSaveBlock1Ptr->money, moneyReward); - - PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff1, 5, moneyReward) - - gBattlescriptCurrInstr++; -} -*/ - -static void atk5E_8025A70(void) -{ - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - switch (gBattleCommunication[0]) - { - case 0: - EmitGetAttributes(0, REQUEST_ALL_BATTLE, 0); - MarkBufferBankForExecution(gActiveBattler); - gBattleCommunication[0]++; - break; - case 1: - if (gBattleExecBuffer == 0) - { - int i; - struct BattlePokemon* bufferPoke = (struct BattlePokemon*) &gBattleBufferB[gActiveBattler][4]; - for (i = 0; i < 4; i++) - { - gBattleMons[gActiveBattler].moves[i] = bufferPoke->moves[i]; - gBattleMons[gActiveBattler].pp[i] = bufferPoke->pp[i]; - } - gBattlescriptCurrInstr += 2; - } - break; - } -} - -static void atk5F_8025B24(void) -{ - gActiveBattler = gBankAttacker; - gBankAttacker = gBankTarget; - gBankTarget = gActiveBattler; - //what is xor... - if (gHitMarker & HITMARKER_PURSUIT_TRAP) - gHitMarker &= ~(HITMARKER_PURSUIT_TRAP); - else - gHitMarker |= HITMARKER_PURSUIT_TRAP; - gBattlescriptCurrInstr++; -} - -static void atk60_incrementgamestat(void) -{ - if (GetBattlerSide(gBankAttacker) == 0) - { - IncrementGameStat(T2_READ_8(gBattlescriptCurrInstr + 1)); - } - gBattlescriptCurrInstr += 2; -} - -static void atk61_drawpartystatussummary(void) -{ - int i; - struct Pokemon* party; - struct HpAndStatus hpStatus[6]; - if (gBattleExecBuffer) - return; - - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - if (GetBattlerSide(gActiveBattler) == 0) - party = gPlayerParty; - else - party = gEnemyParty; - - for (i = 0; i < 6; i++) - { - if (GetMonData(&party[i], MON_DATA_SPECIES2) == 0 || GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_EGG) - { - hpStatus[i].hp = 0xFFFF; - hpStatus[i].status = 0; - } - else - { - hpStatus[i].hp = GetMonData(&party[i], MON_DATA_HP); - hpStatus[i].status = GetMonData(&party[i], MON_DATA_STATUS); - } - } - EmitDrawPartyStatusSummary(0, hpStatus, 1); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 2; -} - -static void atk62_08025C6C(void) -{ - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - Emitcmd49(0); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 2; -} - -static void atk63_jumptorandomattack(void) -{ - if (T2_READ_8(gBattlescriptCurrInstr + 1)) - gCurrentMove = gRandomMove; - else - gChosenMove = gCurrentMove = gRandomMove; - gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; -} - -static void atk64_statusanimation(void) -{ - if (gBattleExecBuffer == 0) - { - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBattler].substituteHP == 0 && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) - { - EmitStatusAnimation(0, 0, gBattleMons[gActiveBattler].status1); - MarkBufferBankForExecution(gActiveBattler); - } - gBattlescriptCurrInstr += 2; - } -} - -static void atk65_status2animation(void) -{ - if (gBattleExecBuffer == 0) - { - u32 possible_to_anim; - gActiveBattler = GetBattleBank(T1_READ_8(gBattlescriptCurrInstr + 1)); - possible_to_anim = T1_READ_32(gBattlescriptCurrInstr + 2); - if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBattler].substituteHP == 0 && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) - { - EmitStatusAnimation(0, 1, gBattleMons[gActiveBattler].status2 & possible_to_anim); - MarkBufferBankForExecution(gActiveBattler); - } - gBattlescriptCurrInstr += 6; - } -} - -static void atk66_chosenstatusanimation(void) -{ - if (gBattleExecBuffer == 0) - { - u32 status; - gActiveBattler = GetBattleBank(T1_READ_8(gBattlescriptCurrInstr + 1)); - status = T1_READ_32(gBattlescriptCurrInstr + 3); - if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBattler].substituteHP == 0 && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) - { - EmitStatusAnimation(0, T1_READ_8(gBattlescriptCurrInstr + 2), status); - MarkBufferBankForExecution(gActiveBattler); - } - gBattlescriptCurrInstr += 7; - } -} - -static void atk67_yesnobox(void) -{ - switch (gBattleCommunication[0]) - { - case 0: - sub_8023A80(); - gBattleCommunication[0]++; - gBattleCommunication[1] = 0; - sub_802BC6C(); - break; - case 1: - if (gMain.newKeys & DPAD_UP && gBattleCommunication[1] != 0) - { - PlaySE(SE_SELECT); - nullsub_6(); - gBattleCommunication[1] = 0; - sub_802BC6C(); - } - if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[1] == 0) - { - PlaySE(SE_SELECT); - nullsub_6(); - gBattleCommunication[1] = 1; - sub_802BC6C(); - } - if (gMain.newKeys & B_BUTTON) - { - gBattleCommunication[1] = 1; - PlaySE(SE_SELECT); - sub_8023AD8(); - gBattlescriptCurrInstr++; - } - else if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - sub_8023AD8(); - gBattlescriptCurrInstr++; - } - break; - } -} - -static void atk68_cancelallactions(void) -{ - int i; - for (i = 0; i < gBattlersCount; i++) - { - gActionsByTurnOrder[i] = 0xC; - } - gBattlescriptCurrInstr++; -} - -static void atk69_adjustsetdamage(void) //literally a copy of atk07 except theres no rand dmg modifier... -{ - u8 hold_effect, quality; - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - hold_effect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; - else - { - hold_effect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); - } - - gStringBank = gBankTarget; - - if (hold_effect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) - { - RecordItemBattle(gBankTarget, hold_effect); - gSpecialStatuses[gBankTarget].focusBanded = 1; - } - if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) - goto END; - if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE && !gProtectStructs[gBankTarget].endured - && !gSpecialStatuses[gBankTarget].focusBanded) - goto END; - if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) - goto END; - - gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; - - if (gProtectStructs[gBankTarget].endured) - { - gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED; - goto END; - } - if (gSpecialStatuses[gBankTarget].focusBanded) - { - gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON; - gLastUsedItem = gBattleMons[gBankTarget].item; - } - - END: - gBattlescriptCurrInstr++; -} - -void atk6A_removeitem(void) -{ - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - USED_HELD_ITEMS(gActiveBattler) = gBattleMons[gActiveBattler].item; - - gBattleMons[gActiveBattler].item = 0; - EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBattler].item); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 2; -} - -static void atk6B_atknameinbuff1(void) -{ - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 7; - gBattleTextBuff1[2] = gBankAttacker; - gBattleTextBuff1[3] = gBattlerPartyIndexes[gBankAttacker]; - gBattleTextBuff1[4] = 0xFF; - gBattlescriptCurrInstr++; -} - -#ifdef NONMATCHING -static void atk6C_drawlvlupbox(void) -{ - u8 r1 = 0; - u8 r7 = 0; - switch (gBattleStruct->atk6C_statetracker) - { - case 0: - sub_802BBD4(0xB, 0, 0x1D, 0x7, r1); - StringCopy(gStringVar4, BattleText_Format2); - - } -} - -#else -NAKED -static void atk6C_drawlvlupbox(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x4\n\ - movs r1, 0\n\ - movs r7, 0\n\ - ldr r0, _08024928 @ =gSharedMem\n\ - mov r10, r0\n\ - ldr r4, _0802492C @ =0x0001609c\n\ - add r4, r10\n\ - ldrb r0, [r4]\n\ - cmp r0, 0x1\n\ - bne _0802491C\n\ - b _08024AF4\n\ -_0802491C:\n\ - cmp r0, 0x1\n\ - bgt _08024930\n\ - cmp r0, 0\n\ - beq _0802493E\n\ - b _08024C38\n\ - .align 2, 0\n\ -_08024928: .4byte gSharedMem\n\ -_0802492C: .4byte 0x0001609c\n\ -_08024930:\n\ - cmp r0, 0x2\n\ - bne _08024936\n\ - b _08024C04\n\ -_08024936:\n\ - cmp r0, 0x3\n\ - bne _0802493C\n\ - b _08024C30\n\ -_0802493C:\n\ - b _08024C38\n\ -_0802493E:\n\ - str r1, [sp]\n\ - movs r0, 0xB\n\ - movs r1, 0\n\ - movs r2, 0x1D\n\ - movs r3, 0x7\n\ - bl sub_802BBD4\n\ - ldr r0, _0802499C @ =gStringVar4\n\ - ldr r1, _080249A0 @ =BattleText_Format2\n\ - bl StringCopy\n\ - adds r5, r0, 0\n\ - movs r1, 0\n\ - mov r8, r1\n\ -_0802495A:\n\ - movs r2, 0\n\ - mov r9, r2\n\ - ldr r0, _080249A4 @ =gUnknown_0840165C\n\ - mov r1, r8\n\ - lsls r4, r1, 2\n\ - adds r0, r4, r0\n\ - ldr r1, [r0]\n\ - adds r0, r5, 0\n\ - bl StringAppend\n\ - adds r5, r0, 0\n\ - ldr r0, _080249A8 @ =gSharedMem\n\ - ldr r2, _080249AC @ =0x00016018\n\ - adds r0, r2\n\ - ldrb r1, [r0]\n\ - movs r0, 0x64\n\ - muls r0, r1\n\ - ldr r1, _080249B0 @ =gPlayerParty\n\ - adds r0, r1\n\ - ldr r1, _080249B4 @ =gLevelUpStatBoxStats\n\ - add r1, r8\n\ - ldrb r1, [r1]\n\ - bl GetMonData\n\ - lsls r0, 16\n\ - lsrs r1, r0, 16\n\ - mov r0, r8\n\ - cmp r0, 0x5\n\ - bhi _08024A1A\n\ - ldr r0, _080249B8 @ =_080249BC\n\ - adds r0, r4, r0\n\ - ldr r0, [r0]\n\ - mov pc, r0\n\ - .align 2, 0\n\ -_0802499C: .4byte gStringVar4\n\ -_080249A0: .4byte BattleText_Format2\n\ -_080249A4: .4byte gUnknown_0840165C\n\ -_080249A8: .4byte gSharedMem\n\ -_080249AC: .4byte 0x00016018\n\ -_080249B0: .4byte gPlayerParty\n\ -_080249B4: .4byte gLevelUpStatBoxStats\n\ -_080249B8: .4byte _080249BC\n\ - .align 2, 0\n\ -_080249BC:\n\ - .4byte _080249D4\n\ - .4byte _080249E0\n\ - .4byte _080249EC\n\ - .4byte _080249F8\n\ - .4byte _08024A04\n\ - .4byte _08024A10\n\ -_080249D4:\n\ - ldr r0, _080249DC @ =gSharedMem + 0x17180\n\ - ldrh r0, [r0]\n\ - b _08024A14\n\ - .align 2, 0\n\ -_080249DC: .4byte gSharedMem + 0x17180\n\ -_080249E0:\n\ - ldr r0, _080249E8 @ =gSharedMem + 0x17180\n\ - ldrh r0, [r0, 0x8]\n\ - b _08024A14\n\ - .align 2, 0\n\ -_080249E8: .4byte gSharedMem + 0x17180\n\ -_080249EC:\n\ - ldr r0, _080249F4 @ =gSharedMem + 0x17180\n\ - ldrh r0, [r0, 0x2]\n\ - b _08024A14\n\ - .align 2, 0\n\ -_080249F4: .4byte gSharedMem + 0x17180\n\ -_080249F8:\n\ - ldr r0, _08024A00 @ =gSharedMem + 0x17180\n\ - ldrh r0, [r0, 0xA]\n\ - b _08024A14\n\ - .align 2, 0\n\ -_08024A00: .4byte gSharedMem + 0x17180\n\ -_08024A04:\n\ - ldr r0, _08024A0C @ =gSharedMem + 0x17180\n\ - ldrh r0, [r0, 0x4]\n\ - b _08024A14\n\ - .align 2, 0\n\ -_08024A0C: .4byte gSharedMem + 0x17180\n\ -_08024A10:\n\ - ldr r0, _08024A54 @ =gSharedMem + 0x17180\n\ - ldrh r0, [r0, 0x6]\n\ -_08024A14:\n\ - subs r0, r1, r0\n\ - lsls r0, 16\n\ - lsrs r7, r0, 16\n\ -_08024A1A:\n\ - lsls r0, r7, 16\n\ - asrs r0, 16\n\ - cmp r0, 0\n\ - bge _08024A2C\n\ - negs r0, r0\n\ - lsls r0, 16\n\ - lsrs r7, r0, 16\n\ - movs r1, 0x1\n\ - add r9, r1\n\ -_08024A2C:\n\ - movs r0, 0xFC\n\ - strb r0, [r5]\n\ - movs r0, 0x13\n\ - strb r0, [r5, 0x1]\n\ - movs r1, 0x1\n\ - mov r2, r8\n\ - ands r1, r2\n\ - lsls r0, r1, 3\n\ - adds r0, r1\n\ - adds r0, 0x5\n\ - lsls r0, 3\n\ - adds r0, 0x6\n\ - strb r0, [r5, 0x2]\n\ - adds r5, 0x3\n\ - mov r0, r9\n\ - cmp r0, 0\n\ - beq _08024A5C\n\ - ldr r1, _08024A58 @ =BattleText_Dash\n\ - b _08024A5E\n\ - .align 2, 0\n\ -_08024A54: .4byte gSharedMem + 0x17180\n\ -_08024A58: .4byte BattleText_Dash\n\ -_08024A5C:\n\ - ldr r1, _08024AA4 @ =BattleText_Plus\n\ -_08024A5E:\n\ - adds r0, r5, 0\n\ - bl StringCopy\n\ - adds r5, r0, 0\n\ - movs r6, 0xFC\n\ - strb r6, [r5]\n\ - movs r4, 0x14\n\ - strb r4, [r5, 0x1]\n\ - movs r0, 0x6\n\ - strb r0, [r5, 0x2]\n\ - adds r5, 0x3\n\ - lsls r1, r7, 16\n\ - asrs r1, 16\n\ - adds r0, r5, 0\n\ - movs r2, 0x1\n\ - movs r3, 0x2\n\ - bl ConvertIntToDecimalStringN\n\ - adds r5, r0, 0\n\ - strb r6, [r5]\n\ - strb r4, [r5, 0x1]\n\ - movs r0, 0\n\ - strb r0, [r5, 0x2]\n\ - adds r5, 0x3\n\ - movs r0, 0x1\n\ - mov r1, r8\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08024AA8\n\ - movs r0, 0xFE\n\ - strb r0, [r5]\n\ - movs r0, 0xFF\n\ - strb r0, [r5, 0x1]\n\ - adds r5, 0x1\n\ - b _08024AB8\n\ - .align 2, 0\n\ -_08024AA4: .4byte BattleText_Plus\n\ -_08024AA8:\n\ - strb r6, [r5]\n\ - movs r0, 0x11\n\ - strb r0, [r5, 0x1]\n\ - movs r0, 0x8\n\ - strb r0, [r5, 0x2]\n\ - adds r5, 0x3\n\ - movs r0, 0xFF\n\ - strb r0, [r5]\n\ -_08024AB8:\n\ - movs r2, 0x1\n\ - add r8, r2\n\ - mov r0, r8\n\ - cmp r0, 0x5\n\ - bgt _08024AC4\n\ - b _0802495A\n\ -_08024AC4:\n\ - ldr r4, _08024AE4 @ =gUnknown_03004210\n\ - ldr r1, _08024AE8 @ =gStringVar4\n\ - adds r2, 0xFF\n\ - movs r0, 0x1\n\ - str r0, [sp]\n\ - adds r0, r4, 0\n\ - movs r3, 0xC\n\ - bl Text_InitWindow\n\ - adds r0, r4, 0\n\ - bl Text_PrintWindow8002F44\n\ - ldr r1, _08024AEC @ =gSharedMem\n\ - ldr r2, _08024AF0 @ =0x0001609c\n\ - adds r1, r2\n\ - b _08024BEA\n\ - .align 2, 0\n\ -_08024AE4: .4byte gUnknown_03004210\n\ -_08024AE8: .4byte gStringVar4\n\ -_08024AEC: .4byte gSharedMem\n\ -_08024AF0: .4byte 0x0001609c\n\ -_08024AF4:\n\ - ldr r0, _08024B94 @ =gMain\n\ - ldrh r0, [r0, 0x2E]\n\ - cmp r0, 0\n\ - bne _08024AFE\n\ - b _08024C38\n\ -_08024AFE:\n\ - movs r0, 0x5\n\ - bl PlaySE\n\ - ldr r0, _08024B98 @ =gStringVar4\n\ - ldr r1, _08024B9C @ =BattleText_Format2\n\ - bl StringCopy\n\ - adds r5, r0, 0\n\ - movs r0, 0\n\ - mov r8, r0\n\ - mov r9, r0\n\ - movs r6, 0xFC\n\ - movs r7, 0x14\n\ - ldr r1, _08024BA0 @ =0x00016018\n\ - add r10, r1\n\ -_08024B1C:\n\ - ldr r1, _08024BA4 @ =gUnknown_0840165C\n\ - mov r2, r8\n\ - lsls r0, r2, 2\n\ - adds r0, r1\n\ - ldr r1, [r0]\n\ - adds r0, r5, 0\n\ - bl StringAppend\n\ - adds r5, r0, 0\n\ - mov r0, r10\n\ - ldrb r1, [r0]\n\ - movs r0, 0x64\n\ - muls r0, r1\n\ - ldr r1, _08024BA8 @ =gPlayerParty\n\ - adds r0, r1\n\ - ldr r1, _08024BAC @ =gLevelUpStatBoxStats\n\ - add r1, r8\n\ - ldrb r1, [r1]\n\ - bl GetMonData\n\ - adds r1, r0, 0\n\ - strb r6, [r5]\n\ - movs r0, 0x13\n\ - strb r0, [r5, 0x1]\n\ - movs r4, 0x1\n\ - mov r2, r8\n\ - ands r4, r2\n\ - lsls r0, r4, 3\n\ - adds r0, r4\n\ - adds r0, 0x5\n\ - lsls r0, 3\n\ - adds r0, 0x6\n\ - strb r0, [r5, 0x2]\n\ - adds r5, 0x3\n\ - strb r6, [r5]\n\ - strb r7, [r5, 0x1]\n\ - movs r0, 0x6\n\ - strb r0, [r5, 0x2]\n\ - adds r5, 0x3\n\ - lsls r1, 16\n\ - asrs r1, 16\n\ - adds r0, r5, 0\n\ - movs r2, 0x1\n\ - movs r3, 0x3\n\ - bl ConvertIntToDecimalStringN\n\ - adds r5, r0, 0\n\ - strb r6, [r5]\n\ - strb r7, [r5, 0x1]\n\ - mov r0, r9\n\ - strb r0, [r5, 0x2]\n\ - adds r5, 0x3\n\ - cmp r4, 0\n\ - beq _08024BB0\n\ - movs r0, 0xFE\n\ - strb r0, [r5]\n\ - movs r0, 0xFF\n\ - strb r0, [r5, 0x1]\n\ - adds r5, 0x1\n\ - b _08024BC0\n\ - .align 2, 0\n\ -_08024B94: .4byte gMain\n\ -_08024B98: .4byte gStringVar4\n\ -_08024B9C: .4byte BattleText_Format2\n\ -_08024BA0: .4byte 0x00016018\n\ -_08024BA4: .4byte gUnknown_0840165C\n\ -_08024BA8: .4byte gPlayerParty\n\ -_08024BAC: .4byte gLevelUpStatBoxStats\n\ -_08024BB0:\n\ - strb r6, [r5]\n\ - movs r0, 0x11\n\ - strb r0, [r5, 0x1]\n\ - movs r0, 0x8\n\ - strb r0, [r5, 0x2]\n\ - adds r5, 0x3\n\ - movs r0, 0xFF\n\ - strb r0, [r5]\n\ -_08024BC0:\n\ - movs r1, 0x1\n\ - add r8, r1\n\ - mov r2, r8\n\ - cmp r2, 0x5\n\ - ble _08024B1C\n\ - ldr r4, _08024BF4 @ =gUnknown_03004210\n\ - ldr r1, _08024BF8 @ =gStringVar4\n\ - movs r2, 0x80\n\ - lsls r2, 1\n\ - movs r0, 0x1\n\ - str r0, [sp]\n\ - adds r0, r4, 0\n\ - movs r3, 0xC\n\ - bl Text_InitWindow\n\ - adds r0, r4, 0\n\ - bl Text_PrintWindow8002F44\n\ - ldr r1, _08024BFC @ =gSharedMem\n\ - ldr r0, _08024C00 @ =0x0001609c\n\ - adds r1, r0\n\ -_08024BEA:\n\ - ldrb r0, [r1]\n\ - adds r0, 0x1\n\ - strb r0, [r1]\n\ - b _08024C38\n\ - .align 2, 0\n\ -_08024BF4: .4byte gUnknown_03004210\n\ -_08024BF8: .4byte gStringVar4\n\ -_08024BFC: .4byte gSharedMem\n\ -_08024C00: .4byte 0x0001609c\n\ -_08024C04:\n\ - ldr r0, _08024C2C @ =gMain\n\ - ldrh r0, [r0, 0x2E]\n\ - cmp r0, 0\n\ - beq _08024C38\n\ - movs r0, 0x5\n\ - bl PlaySE\n\ - movs r0, 0x1\n\ - str r0, [sp]\n\ - movs r0, 0xB\n\ - movs r1, 0\n\ - movs r2, 0x1D\n\ - movs r3, 0x7\n\ - bl sub_802BBD4\n\ - ldrb r0, [r4]\n\ - adds r0, 0x1\n\ - strb r0, [r4]\n\ - b _08024C38\n\ - .align 2, 0\n\ -_08024C2C: .4byte gMain\n\ -_08024C30:\n\ - ldr r1, _08024C48 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x1\n\ - str r0, [r1]\n\ -_08024C38:\n\ - add sp, 0x4\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_08024C48: .4byte gBattlescriptCurrInstr\n\ - .syntax divided"); -} - -#endif - -static void atk6D_resetsentmonsvalue(void) -{ - ResetSentPokesToOpponentValue(); - gBattlescriptCurrInstr++; -} - -static void atk6E_setatktoplayer0(void) -{ - gBankAttacker = GetBattlerAtPosition(0); - gBattlescriptCurrInstr++; -} - -static void atk6F_makevisible(void) -{ - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - EmitSpriteInvisibility(0, 0); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 2; -} - -static void atk70_recordlastability(void) -{ - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - RecordAbilityBattle(gActiveBattler, gLastUsedAbility); - gBattlescriptCurrInstr += 1; //buggy, should be += 2, one byte for command, one byte for argument... -} - -void sub_8024CEC(void) -{ - gBattleTextBuff2[0] = 0xFD; - gBattleTextBuff2[1] = 2; - gBattleTextBuff2[2] = (gMoveToLearn); - gBattleTextBuff2[3] = uBYTE1_16(gMoveToLearn); - gBattleTextBuff2[4] = 0xFF; -} - -static void atk71_buffermovetolearn(void) -{ - sub_8024CEC(); - gBattlescriptCurrInstr++; -} - -static void atk72_jumpifplayerran(void) -{ - if (TryRunFromBattle(gBank1)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr += 5; -} - -static void atk73_hpthresholds(void) -{ - u8 opposing_bank; - s32 result; - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - opposing_bank = gActiveBattler ^ 1; - - result = gBattleMons[opposing_bank].hp * 100 / gBattleMons[opposing_bank].maxHP; - if (result == 0) - result = 1; - - if (result >= 70 || !gBattleMons[opposing_bank].hp) - gBattleStruct->hpScale = 0; - else if (result >= 40) - gBattleStruct->hpScale = 1; - else if (result >= 10) - gBattleStruct->hpScale = 2; - else - gBattleStruct->hpScale = 3; - } - - gBattlescriptCurrInstr += 2; -} - -static void atk74_hpthresholds2(void) -{ - u8 opposing_bank; - u8 hp_switchout; - s32 result; - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - opposing_bank = gActiveBattler ^ 1; - hp_switchout = ewram160BCarr(GetBattlerSide(opposing_bank)); //gBattleStruct->HP_OnSwitchout[GetBattlerSide(opposing_bank)]; - result = (hp_switchout - gBattleMons[opposing_bank].hp) * 100 / hp_switchout; - - if (gBattleMons[opposing_bank].hp >= hp_switchout) - gBattleStruct->hpScale = 0; - else if (result <= 29) - gBattleStruct->hpScale = 1; - else if (result <= 69) - gBattleStruct->hpScale = 2; - else - gBattleStruct->hpScale = 3; - } - - gBattlescriptCurrInstr += 2; -} - -static void atk75_useitemonopponent(void) -{ - gBankInMenu = gBankAttacker; - PokemonUseItemEffects(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker]], gLastUsedItem, gBattlerPartyIndexes[gBankAttacker], 0, 1); - gBattlescriptCurrInstr += 1; -} - -static void atk76_various(void) -{ - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - switch (T2_READ_8(gBattlescriptCurrInstr + 2)) - { - case 0: - CancelMultiTurnMoves(gActiveBattler); - break; - case 1: - { - u8 side; - gBankAttacker = gBankTarget; - side = GetBattlerSide(gBankAttacker) ^ 1; - if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp) - gBankTarget = gSideTimers[side].followmeTarget; - else - gBankTarget = gActiveBattler; - } - break; - case 2: - gBattleCommunication[0] = CanRunFromBattle(); - break; - case 3: - gBankTarget = GetMoveTarget(gCurrentMove, 0); - break; - case 4: - if (gHitMarker & HITMARKER_FAINTED(gActiveBattler)) - gBattleCommunication[0] = 1; - else - gBattleCommunication[0] = 0; - break; - case 5: - gSpecialStatuses[gActiveBattler].intimidatedPoke = 0; - gSpecialStatuses[gActiveBattler].traced = 0; - break; - case 6: - { - int i; - u16* choiced_move; - if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterID) - goto ACTIVE_0; - if (gBattlerPartyIndexes[2] != gBattleStruct->expGetterID) - break; - if (gBattlerPartyIndexes[0] == gBattlerPartyIndexes[2]) - { - ACTIVE_0: - gActiveBattler = 0; - } - else - gActiveBattler = 2; - - choiced_move = CHOICED_MOVE(gActiveBattler); - for (i = 0; i < 4; i++) - { - if (gBattleMons[gActiveBattler].moves[i] == *choiced_move) - break; - } - if (i == 4) - *choiced_move = 0; - } - break; - } - - gBattlescriptCurrInstr += 3; -} - -static void atk77_setprotectlike(void) //protect and endure -{ - bool8 not_last_turn = 1; - u16 last_move = gUnknown_02024C4C[gBankAttacker]; - - if (last_move != MOVE_PROTECT && last_move != MOVE_DETECT && last_move != MOVE_ENDURE) - gDisableStructs[gBankAttacker].protectUses = 0; - if (gCurrentTurnActionNumber == (gBattlersCount - 1)) - not_last_turn = 0; - - if (sProtectSuccessRates[gDisableStructs[gBankAttacker].protectUses] > Random() && not_last_turn) - { - if (gBattleMoves[gCurrentMove].effect == EFFECT_PROTECT) - { - gProtectStructs[gBankAttacker].protected = 1; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - if (gBattleMoves[gCurrentMove].effect == EFFECT_ENDURE) //what is else if - { - gProtectStructs[gBankAttacker].endured = 1; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - gDisableStructs[gBankAttacker].protectUses++; - } - else - { - gDisableStructs[gBankAttacker].protectUses = 0; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - gMoveResultFlags |= MOVE_RESULT_MISSED; - } - - gBattlescriptCurrInstr++; -} - -static void atk78_faintifabilitynotdamp(void) -{ - if (gBattleExecBuffer) - return; - - for (gBankTarget = 0; gBankTarget < gBattlersCount; gBankTarget++) - { - if (gBattleMons[gBankTarget].ability == ABILITY_DAMP) - break; - } - - if (gBankTarget == gBattlersCount) - { - gActiveBattler = gBankAttacker; - gBattleMoveDamage = gBattleMons[gActiveBattler].hp; - EmitHealthBarUpdate(0, 0x7FFF); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr++; - - for (gBankTarget = 0; gBankTarget < gBattlersCount; gBankTarget++) - { - if (gBankTarget == gBankAttacker) - continue; - if (!(gAbsentBattlerFlags & gBitTable[gBankTarget])) - break; - } - } - else - { - gLastUsedAbility = ABILITY_DAMP; - RecordAbilityBattle(gBankTarget, gBattleMons[gBankTarget].ability); - gBattlescriptCurrInstr = BattleScript_DampStopsExplosion; - } -} - -static void atk79_setatkhptozero(void) -{ - if (gBattleExecBuffer) - return; - - gActiveBattler = gBankAttacker; - gBattleMons[gActiveBattler].hp = 0; - EmitSetMonData(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBattler].hp); - MarkBufferBankForExecution(gActiveBattler); - - gBattlescriptCurrInstr++; -} - -static void atk7A_jumpifnexttargetvalid(void) //used by intimidate to loop through all targets -{ - u8* jump_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - for (gBankTarget++; ; gBankTarget++) - { - if (gBankTarget == gBankAttacker) - continue; - if (!(gAbsentBattlerFlags & gBitTable[gBankTarget])) - break; - } - - if (gBankTarget >= gBattlersCount) - gBattlescriptCurrInstr += 5; - else - gBattlescriptCurrInstr = jump_loc; - } - else - gBattlescriptCurrInstr += 5; -} - -static void atk7B_tryhealhalfhealth(void) -{ - u8* fail_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); - - if (T2_READ_8(gBattlescriptCurrInstr + 5) == 1) - gBankTarget = gBankAttacker; - - gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - - if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) - gBattlescriptCurrInstr = fail_loc; - else - gBattlescriptCurrInstr += 6; -} - -static void atk7C_trymirrormove(void) -{ - u16 r7 = ewram160ACarr2(0, gBankAttacker) | (ewram160ACarr2(1, gBankAttacker) << 8); - u16 r6 = ewram16100arr2(0, gBankAttacker) | (ewram16100arr2(1, gBankAttacker) << 8); - u16 r5 = ewram16100arr2(2, gBankAttacker) | (ewram16100arr2(3, gBankAttacker) << 8); - - if (r7 != 0 && r7 != 0xFFFF) - { - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gCurrentMove = r7; - gBankTarget = GetMoveTarget(gCurrentMove, 0); - gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; - } - else if (r6 != 0 && r5 != 0 && r6 != 0xFFFF && r5 != 0xFFFF) - { - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - if (Random() & 1) - gCurrentMove = r6; - else - gCurrentMove = r5; - gBankTarget = GetMoveTarget(gCurrentMove, 0); - gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; - } - else if (r6 != 0 && r6 != 0xFFFF) - { - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gCurrentMove = r6; - gBankTarget = GetMoveTarget(gCurrentMove, 0); - gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; - } - else if (r5 != 0 && r5 != 0xFFFF) - { - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gCurrentMove = r5; - gBankTarget = GetMoveTarget(gCurrentMove, 0); - gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; - } - else - { - gSpecialStatuses[gBankAttacker].flag20 = 1; - gBattlescriptCurrInstr++; - } -} - -static void atk7D_setrain(void) -{ - if (gBattleWeather & WEATHER_RAIN_ANY) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - } - else - { - gBattleWeather = WEATHER_RAIN_TEMPORARY; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - gWishFutureKnock.weatherDuration = 5; - } - gBattlescriptCurrInstr++; -} - -static void atk7E_setreflect(void) -{ - if (gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] & SIDE_STATUS_REFLECT) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - else - { - gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] |= SIDE_STATUS_REFLECT; - gSideTimers[GetBattlerPosition(gBankAttacker) & 1].reflectTimer = 5; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMons(1) == 2) - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - gBattlescriptCurrInstr++; -} - -static void atk7F_setseeded(void) -{ - if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT || gStatuses3[gBankTarget] & STATUS3_LEECHSEED) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else if (gBattleMons[gBankTarget].type1 == TYPE_GRASS || gBattleMons[gBankTarget].type2 == TYPE_GRASS) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - } - else - { - gStatuses3[gBankTarget] |= gBankAttacker; - gStatuses3[gBankTarget] |= STATUS3_LEECHSEED; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - - gBattlescriptCurrInstr++; -} - -static void atk80_manipulatedamage(void) -{ - switch (T2_READ_8(gBattlescriptCurrInstr + 1)) - { - case 0: - gBattleMoveDamage *= -1; - break; - case 1: - gBattleMoveDamage /= 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - if ((gBattleMons[gBankTarget].maxHP / 2) < gBattleMoveDamage) - gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; - break; - case 2: - gBattleMoveDamage *= 2; - break; - } - - gBattlescriptCurrInstr += 2; -} - -static void atk81_trysetrest(void) -{ - u8* fail_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); - gActiveBattler = gBankTarget = gBankAttacker; - gBattleMoveDamage = gBattleMons[gBankTarget].maxHP * (-1); - if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) - gBattlescriptCurrInstr = fail_loc; - else - { - if (gBattleMons[gBankTarget].status1 & ((u8)(~STATUS_SLEEP))) - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - - gBattleMons[gBankTarget].status1 = 3; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 5; - } -} - -static void atk82_jumpifnotfirstturn(void) -{ - u8* jump_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); - - if (gDisableStructs[gBankAttacker].isFirstTurn) - gBattlescriptCurrInstr += 5; - else - gBattlescriptCurrInstr = jump_loc; -} - -static void atk83_nop(void) -{ - gBattlescriptCurrInstr++; -} - -bool8 UproarWakeUpCheck(u8 bank) -{ - int i; - for (i = 0; i < gBattlersCount; i++) - { - if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || gBattleMons[bank].ability == ABILITY_SOUNDPROOF) //wtf gamefreak, you should check this only once, not every time in a loop... - continue; - gBattleStruct->scriptingActive = i; - if (gBankTarget == 0xFF) - gBankTarget = i; - else if (gBankTarget == i) - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - break; - } - if (i == gBattlersCount) - return 0; - else - return 1; -} - -static void atk84_jumpifcantmakeasleep(void) -{ - u8* jump_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); - if (UproarWakeUpCheck(gBankTarget)) - gBattlescriptCurrInstr = jump_loc; - else if (gBattleMons[gBankTarget].ability == ABILITY_INSOMNIA || gBattleMons[gBankTarget].ability == ABILITY_VITAL_SPIRIT) - { - gLastUsedAbility = gBattleMons[gBankTarget].ability; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - gBattlescriptCurrInstr = jump_loc; - RecordAbilityBattle(gBankTarget, gLastUsedAbility); - } - else - { - gBattlescriptCurrInstr += 5; - } -} - -static void atk85_stockpile(void) -{ - if (gDisableStructs[gBankAttacker].stockpileCounter == 3) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else - { - gDisableStructs[gBankAttacker].stockpileCounter++; - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 1; - gBattleTextBuff1[2] = 1; - gBattleTextBuff1[3] = 1; - gBattleTextBuff1[4] = gDisableStructs[gBankAttacker].stockpileCounter; - gBattleTextBuff1[5] = 0xFF; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - gBattlescriptCurrInstr++; -} - -static void atk86_stockpiletobasedamage(void) -{ - u8* jump_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); - if (gDisableStructs[gBankAttacker].stockpileCounter == 0) - { - gBattlescriptCurrInstr = jump_loc; - } - else - { - if (gBattleCommunication[6] != 1) - { - gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, - gSideAffecting[GetBattlerPosition(gBankTarget) & 1], 0, - 0, gBankAttacker, gBankTarget) - * gDisableStructs[gBankAttacker].stockpileCounter; - gBattleStruct->animTurn = gDisableStructs[gBankAttacker].stockpileCounter; - - if (gProtectStructs[gBankAttacker].helpingHand) - gBattleMoveDamage = gBattleMoveDamage * 15 / 10; - } - gDisableStructs[gBankAttacker].stockpileCounter = 0; - gBattlescriptCurrInstr += 5; - } -} - -static void atk87_stockpiletohpheal(void) -{ - u8* jump_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); - if (gDisableStructs[gBankAttacker].stockpileCounter == 0) - { - gBattlescriptCurrInstr = jump_loc; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - else if (gBattleMons[gBankAttacker].maxHP == gBattleMons[gBankAttacker].hp) - { - gDisableStructs[gBankAttacker].stockpileCounter = 0; - gBattlescriptCurrInstr = jump_loc; - gBankTarget = gBankAttacker; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else - { - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / (1 << (3 - gDisableStructs[gBankAttacker].stockpileCounter)); - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - gBattleStruct->animTurn = gDisableStructs[gBankAttacker].stockpileCounter; - gDisableStructs[gBankAttacker].stockpileCounter = 0; - gBattlescriptCurrInstr += 5; - gBankTarget = gBankAttacker; - } -} - -static void atk88_negativedamage(void) -{ - gBattleMoveDamage = -(gHpDealt / 2); - if (gBattleMoveDamage == 0) - gBattleMoveDamage = -1; - gBattlescriptCurrInstr++; -} - -static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8 *BS_ptr) -{ - bool8 certain = FALSE; - bool8 notProtectAffected = FALSE; - u32 index; - - if (flags & MOVE_EFFECT_AFFECTS_USER) - gActiveBattler = gBankAttacker; - else - gActiveBattler = gBankTarget; - - flags &= ~(MOVE_EFFECT_AFFECTS_USER); - - if (flags & MOVE_EFFECT_CERTAIN) - certain++; - flags &= ~(MOVE_EFFECT_CERTAIN); - - if (flags & STAT_CHANGE_NOT_PROTECT_AFFECTED) - notProtectAffected++; - flags &= ~(STAT_CHANGE_NOT_PROTECT_AFFECTED); - - PREPARE_STAT_BUFFER(gBattleTextBuff1, statId) - - if ((statValue << 0x18) < 0) // stat decrease - { - if (gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].mistTimer - && !certain && gCurrentMove != MOVE_CURSE) - { - if (flags == STAT_CHANGE_BS_PTR) - { - if (gSpecialStatuses[gActiveBattler].statLowered) - { - gBattlescriptCurrInstr = BS_ptr; - } - else - { - BattleScriptPush(BS_ptr); - gBattleStruct->scriptingActive = gActiveBattler; - gBattlescriptCurrInstr = BattleScript_MistProtected; - gSpecialStatuses[gActiveBattler].statLowered = 1; - } - } - return STAT_CHANGE_DIDNT_WORK; - } - else if (gCurrentMove != MOVE_CURSE - && notProtectAffected != TRUE && JumpIfMoveAffectedByProtect(0)) - { - gBattlescriptCurrInstr = BattleScript_ButItFailed; - return STAT_CHANGE_DIDNT_WORK; - } - else if ((gBattleMons[gActiveBattler].ability == ABILITY_CLEAR_BODY - || gBattleMons[gActiveBattler].ability == ABILITY_WHITE_SMOKE) - && !certain && gCurrentMove != MOVE_CURSE) - { - if (flags == STAT_CHANGE_BS_PTR) - { - if (gSpecialStatuses[gActiveBattler].statLowered) - { - gBattlescriptCurrInstr = BS_ptr; - } - else - { - BattleScriptPush(BS_ptr); - gBattleStruct->scriptingActive = gActiveBattler; - gBattlescriptCurrInstr = BattleScript_AbilityNoStatLoss; - gLastUsedAbility = gBattleMons[gActiveBattler].ability; - RecordAbilityBattle(gActiveBattler, gLastUsedAbility); - gSpecialStatuses[gActiveBattler].statLowered = 1; - } - } - return STAT_CHANGE_DIDNT_WORK; - } - else if (gBattleMons[gActiveBattler].ability == ABILITY_KEEN_EYE - && !certain && statId == STAT_STAGE_ACC) - { - if (flags == STAT_CHANGE_BS_PTR) - { - BattleScriptPush(BS_ptr); - gBattleStruct->scriptingActive = gActiveBattler; - gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss; - gLastUsedAbility = gBattleMons[gActiveBattler].ability; - RecordAbilityBattle(gActiveBattler, gLastUsedAbility); - } - return STAT_CHANGE_DIDNT_WORK; - } - else if (gBattleMons[gActiveBattler].ability == ABILITY_HYPER_CUTTER - && !certain && statId == STAT_STAGE_ATK) - { - if (flags == STAT_CHANGE_BS_PTR) - { - BattleScriptPush(BS_ptr); - gBattleStruct->scriptingActive = gActiveBattler; - gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss; - gLastUsedAbility = gBattleMons[gActiveBattler].ability; - RecordAbilityBattle(gActiveBattler, gLastUsedAbility); - } - return STAT_CHANGE_DIDNT_WORK; - } - else if (gBattleMons[gActiveBattler].ability == ABILITY_SHIELD_DUST && flags == 0) - { - return STAT_CHANGE_DIDNT_WORK; - } - else // try to decrease - { - statValue = -GET_STAT_BUFF_VALUE(statValue); - gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; - index = 1; - if (statValue == -2) - { - gBattleTextBuff2[1] = B_BUFF_STRING; - gBattleTextBuff2[2] = STRINGID_STATHARSHLY; - gBattleTextBuff2[3] = STRINGID_STATHARSHLY >> 8; - index = 4; - } - gBattleTextBuff2[index] = B_BUFF_STRING; - index++; - gBattleTextBuff2[index] = STRINGID_STATFELL; - index++; - gBattleTextBuff2[index] = STRINGID_STATFELL >> 8; - index++; - gBattleTextBuff2[index] = B_BUFF_EOS; - - if (gBattleMons[gActiveBattler].statStages[statId] == 0) - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - else - gBattleCommunication[MULTISTRING_CHOOSER] = (gBankTarget == gActiveBattler); - - } - } - else // stat increase - { - statValue = GET_STAT_BUFF_VALUE(statValue); - gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; - index = 1; - if (statValue == 2) - { - gBattleTextBuff2[1] = B_BUFF_STRING; - gBattleTextBuff2[2] = STRINGID_STATSHARPLY; - gBattleTextBuff2[3] = STRINGID_STATSHARPLY >> 8; - index = 4; - } - gBattleTextBuff2[index] = B_BUFF_STRING; - index++; - gBattleTextBuff2[index] = STRINGID_STATROSE; - index++; - gBattleTextBuff2[index] = STRINGID_STATROSE >> 8; - index++; - gBattleTextBuff2[index] = B_BUFF_EOS; - - if (gBattleMons[gActiveBattler].statStages[statId] == 0xC) - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - else - gBattleCommunication[MULTISTRING_CHOOSER] = (gBankTarget == gActiveBattler); - } - - gBattleMons[gActiveBattler].statStages[statId] += statValue; - if (gBattleMons[gActiveBattler].statStages[statId] < 0) - gBattleMons[gActiveBattler].statStages[statId] = 0; - if (gBattleMons[gActiveBattler].statStages[statId] > 0xC) - gBattleMons[gActiveBattler].statStages[statId] = 0xC; - - if (gBattleCommunication[MULTISTRING_CHOOSER] == 2 && flags & STAT_CHANGE_BS_PTR) - gMoveResultFlags |= MOVE_RESULT_MISSED; - - if (gBattleCommunication[MULTISTRING_CHOOSER] == 2 && !(flags & STAT_CHANGE_BS_PTR)) - return STAT_CHANGE_DIDNT_WORK; - - return STAT_CHANGE_WORKED; -} - -static void atk89_statbuffchange(void) -{ - u8* jump_loc = T1_READ_PTR(gBattlescriptCurrInstr + 2); - if (ChangeStatBuffs(gBattleStruct->statChanger & 0xF0, gBattleStruct->statChanger & 0xF, T2_READ_8(gBattlescriptCurrInstr + 1), jump_loc) == 0) - gBattlescriptCurrInstr += 6; -} - -static void atk8A_normalisebuffs(void) //haze -{ - int i, j; - for (i = 0; i < gBattlersCount; i++) - { - for (j = 0; j < 8; j++) - { - gBattleMons[i].statStages[j] = 6; - } - } - gBattlescriptCurrInstr++; -} - -static void atk8B_setbide(void) -{ - gBattleMons[gBankAttacker].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gBankAttacker] = gCurrentMove; - gTakenDmg[gBankAttacker] = 0; - gBattleMons[gBankAttacker].status2 |= (STATUS2_BIDE - 0x100); //2 turns - gBattlescriptCurrInstr++; -} - -static void atk8C_confuseifrepeatingattackends(void) -{ - if (!(gBattleMons[gBankAttacker].status2 & STATUS2_LOCK_CONFUSE)) - gBattleCommunication[MOVE_EFFECT_BYTE] = 0x75; - gBattlescriptCurrInstr++; -} - -static void atk8D_setmultihitcounter(void) -{ - if (T2_READ_8(gBattlescriptCurrInstr + 1)) - gMultiHitCounter = T2_READ_8(gBattlescriptCurrInstr + 1); - else - { - gMultiHitCounter = Random() & 3; - if (gMultiHitCounter > 1) - gMultiHitCounter = (Random() & 3) + 2; - else - gMultiHitCounter += 2; - } - gBattlescriptCurrInstr += 2; -} - -static void atk8E_initmultihitstring(void) -{ - ewram160E0(0) = 0xFD; - ewram160E0(1) = 1; - ewram160E0(2) = 1; - ewram160E0(3) = 1; - ewram160E0(4) = 0; - ewram160E0(5) = 0xFF; - gBattlescriptCurrInstr++; -} - -static bool8 sub_80264C0(void) -{ - if (gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) - { - ewram16064arr(gBankTarget) = gBattlerPartyIndexes[gBankTarget]; - } - else - { - u16 random = Random() & 0xFF; - if ((u32)((random * (gBattleMons[gBankAttacker].level + gBattleMons[gBankTarget].level) >> 8) + 1) <= (gBattleMons[gBankTarget].level / 4)) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - return 0; - } - ewram16064arr(gBankTarget) = gBattlerPartyIndexes[gBankTarget]; - } - gBattlescriptCurrInstr = BattleScript_SuccessForceOut; - return 1; -} - -static void atk8F_forcerandomswitch(void) -{ - if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER)) - { - u8 i; - struct Pokemon* party; - u8 valid; - u8 val; - if (!GetBattlerSide(gBankTarget)) - party = gPlayerParty; - else - party = gEnemyParty; - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - valid = 0; - val = 0; - if (sub_803FBFC(sub_803FC34(gBankTarget)) == 1) - val = 3; - for (i = val; i < val + 3; i++) - { - if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE - && !GetMonData(&party[i], MON_DATA_IS_EGG) - && GetMonData(&party[i], MON_DATA_HP) != 0) - valid++; - } - } - else - { - valid = 0; - for (i = 0; i < 6; i++) - { - if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE - && !GetMonData(&party[i], MON_DATA_IS_EGG) - && GetMonData(&party[i], MON_DATA_HP) != 0) - valid++; - } - } - - if ((valid < 2 && (gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI)) != BATTLE_TYPE_DOUBLE) - || (valid < 3 && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } - else if (sub_80264C0()) - { -#define MON_CAN_BATTLE(mon) (((GetMonData(mon, MON_DATA_SPECIES) && GetMonData(mon, MON_DATA_IS_EGG) != 1 && GetMonData(mon, MON_DATA_HP)))) - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - do - { - val = Random() % 3; - if (sub_803FBFC(sub_803FC34(gBankTarget)) == 1) - i = val + 3; - else - i = val; - } while (i == gBattlerPartyIndexes[gBankTarget] || i == gBattlerPartyIndexes[gBankTarget ^ 2] || !MON_CAN_BATTLE(&party[i])); - } - else - { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - do - { - i = Random() % 6; - } while (i == gBattlerPartyIndexes[gBankTarget] || i == gBattlerPartyIndexes[gBankTarget ^ 2] || !MON_CAN_BATTLE(&party[i])); - } - else - { - do - { - i = Random() % 6; - } while (i == gBattlerPartyIndexes[gBankTarget] || !MON_CAN_BATTLE(&party[i])); - } - } - ewram16068arr(gBankTarget) = i; - if (!IsLinkDoubleBattle()) - sub_8012258(gBankTarget); - sub_8094B6C(gBankTarget, i, 0); - sub_8094B6C(gBankTarget ^ 2, i, 1); -#undef MON_CAN_BATTLE - } - } - else - { - sub_80264C0(); - } -} - -static void atk90_tryconversiontypechange(void) -{ - //randomly changes user's type to one of its moves' type - u8 valid_moves = 0; - u8 checked_move; - u8 move_type; - while (valid_moves < 4) - { - if (gBattleMons[gBankAttacker].moves[valid_moves] == 0) - break; - valid_moves++; - } - - for (checked_move = 0; checked_move < valid_moves; checked_move++) - { - move_type = gBattleMoves[gBattleMons[gBankAttacker].moves[checked_move]].type; - if (move_type == TYPE_MYSTERY) - { - if (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST) - move_type = TYPE_GHOST; - else - move_type = TYPE_NORMAL; - } - if (move_type != gBattleMons[gBankAttacker].type1 && move_type != gBattleMons[gBankAttacker].type2) - break; - } - - if (checked_move == valid_moves) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } - else - { - do - { - - while ((checked_move = Random() & 3) >= valid_moves); - - move_type = gBattleMoves[gBattleMons[gBankAttacker].moves[checked_move]].type; - if (move_type == TYPE_MYSTERY) - { - if (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST) - move_type = TYPE_GHOST; - else - move_type = TYPE_NORMAL; - } - } while (move_type == gBattleMons[gBankAttacker].type1 || move_type == gBattleMons[gBankAttacker].type2); - - gBattleMons[gBankAttacker].type1 = move_type; - gBattleMons[gBankAttacker].type2 = move_type; - - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 3; - gBattleTextBuff1[2] = move_type; - gBattleTextBuff1[3] = 0xFF; - - gBattlescriptCurrInstr += 5; - } -} - -static void atk91_givepaydaymoney(void) -{ - if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && gPaydayMoney) - { - AddMoney(&gSaveBlock1.money, gPaydayMoney * gBattleStruct->moneyMultiplier); - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 1; - gBattleTextBuff1[2] = 2; - gBattleTextBuff1[3] = 5; - gBattleTextBuff1[4] = gPaydayMoney; - gBattleTextBuff1[5] = uBYTE1_16(gPaydayMoney); - gBattleTextBuff1[6] = 0xFF; - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_PrintPayDayMoneyString; - } - else - gBattlescriptCurrInstr++; -} - -static void atk92_setlightscreen(void) -{ - if (gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] & SIDE_STATUS_LIGHTSCREEN) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - else - { - gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] |= SIDE_STATUS_LIGHTSCREEN; - gSideTimers[GetBattlerPosition(gBankAttacker) & 1].lightscreenTimer = 5; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMons(1) == 2) - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 3; - } - gBattlescriptCurrInstr++; -} - -#ifdef NOTMATCHING -static void atk93_tryKO(void) -{ - if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) - hold_effect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; - else - { - hold_effect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); - quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); - } - - gStringBank = gBankTarget; - - if (hold_effect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) - { - RecordItemBattle(gBankTarget, hold_effect); - gSpecialStatuses[gBankTarget].focusBanded = 1; - } - - if (gBattleMons[gBankTarget].ability == ABILITY_STURDY) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - gLastUsedAbility = ABILITY_STURDY; - gBattlescriptCurrInstr = x; - RecordAbilityBattle(gBankTarget, ABILITY_STURDY); - return; - } - - if (!(gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS)) - { - u16 to_cmp = gBattleMons[gBankAttacker].level - gBattleMons[gBankTarget].level + gBattleMoves[gCurrentMove].accuracy; - if (Random() % 0x64 + 1 < to_cmp || gBattleMons[gBankAttacker].level < gBattleMons[gBankTarget].level) - { - goto MOVE_RESULT_MISSED_LABEL; - } - } - else - { - if (gDisableStructs[gBankTarget].bankWithSureHit != gBankAttacker || gBattleMons[gBankAttacker].level < gBattleMons[gBankTarget].level) - { - - } - } - -MOVE_RESULT_MISSED_LABEL: - gBattleTypeFlags |= MOVE_RESULT_MISSED; - if (gBattleMons[gBankAttacker].level < gBattleMons[gBankTarget].level) - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -#else -__attribute((naked)) -static void atk93_tryKO(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - ldr r7, _08026BA8 @ =gBattleMons\n\ - ldr r6, _08026BAC @ =gBankTarget\n\ - ldrb r2, [r6]\n\ - movs r5, 0x58\n\ - adds r0, r2, 0\n\ - muls r0, r5\n\ - adds r1, r0, r7\n\ - ldrh r0, [r1, 0x2E]\n\ - cmp r0, 0xAF\n\ - bne _08026BB4\n\ - ldr r1, _08026BB0 @ =gEnigmaBerries\n\ - lsls r0, r2, 3\n\ - subs r0, r2\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldrb r4, [r0, 0x7]\n\ - ldrb r6, [r0, 0x1A]\n\ - b _08026BCE\n\ - .align 2, 0\n\ -_08026BA8: .4byte gBattleMons\n\ -_08026BAC: .4byte gBankTarget\n\ -_08026BB0: .4byte gEnigmaBerries\n\ -_08026BB4:\n\ - ldrh r0, [r1, 0x2E]\n\ - bl ItemId_GetHoldEffect\n\ - lsls r0, 24\n\ - lsrs r4, r0, 24\n\ - ldrb r0, [r6]\n\ - muls r0, r5\n\ - adds r0, r7\n\ - ldrh r0, [r0, 0x2E]\n\ - bl ItemId_GetHoldEffectParam\n\ - lsls r0, 24\n\ - lsrs r6, r0, 24\n\ -_08026BCE:\n\ - ldr r1, _08026C4C @ =gStringBank\n\ - ldr r5, _08026C50 @ =gBankTarget\n\ - ldrb r0, [r5]\n\ - strb r0, [r1]\n\ - cmp r4, 0x27\n\ - bne _08026C0C\n\ - bl Random\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - movs r1, 0x64\n\ - bl __umodsi3\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - cmp r0, r6\n\ - bcs _08026C0C\n\ - ldrb r0, [r5]\n\ - movs r1, 0x27\n\ - bl RecordItemBattle\n\ - ldr r2, _08026C54 @ =gSpecialStatuses\n\ - ldrb r1, [r5]\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldrb r1, [r0]\n\ - movs r2, 0x80\n\ - orrs r1, r2\n\ - strb r1, [r0]\n\ -_08026C0C:\n\ - ldr r0, _08026C58 @ =gBattleMons\n\ - mov r8, r0\n\ - ldr r1, _08026C50 @ =gBankTarget\n\ - ldrb r2, [r1]\n\ - movs r6, 0x58\n\ - adds r0, r2, 0\n\ - muls r0, r6\n\ - mov r3, r8\n\ - adds r5, r0, r3\n\ - adds r0, r5, 0\n\ - adds r0, 0x20\n\ - ldrb r3, [r0]\n\ - mov r10, r8\n\ - cmp r3, 0x5\n\ - bne _08026C6C\n\ - ldr r2, _08026C5C @ =gMoveResultFlags\n\ - ldrb r0, [r2]\n\ - movs r1, 0x1\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ - ldr r0, _08026C60 @ =gLastUsedAbility\n\ - strb r3, [r0]\n\ - ldr r1, _08026C64 @ =gBattlescriptCurrInstr\n\ - ldr r0, _08026C68 @ =BattleScript_SturdyPreventsOHKO\n\ - str r0, [r1]\n\ - ldr r1, _08026C50 @ =gBankTarget\n\ - ldrb r0, [r1]\n\ - movs r1, 0x5\n\ - bl RecordAbilityBattle\n\ - b _08026E40\n\ - .align 2, 0\n\ -_08026C4C: .4byte gStringBank\n\ -_08026C50: .4byte gBankTarget\n\ -_08026C54: .4byte gSpecialStatuses\n\ -_08026C58: .4byte gBattleMons\n\ -_08026C5C: .4byte gMoveResultFlags\n\ -_08026C60: .4byte gLastUsedAbility\n\ -_08026C64: .4byte gBattlescriptCurrInstr\n\ -_08026C68: .4byte BattleScript_SturdyPreventsOHKO\n\ -_08026C6C:\n\ - ldr r1, _08026CE0 @ =gStatuses3\n\ - lsls r0, r2, 2\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - movs r1, 0x18\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _08026CF4\n\ - ldr r1, _08026CE4 @ =gBattleMoves\n\ - ldr r0, _08026CE8 @ =gCurrentMove\n\ - ldrh r0, [r0]\n\ - lsls r2, r0, 1\n\ - adds r2, r0\n\ - lsls r2, 2\n\ - adds r2, r1\n\ - ldr r7, _08026CEC @ =gBankAttacker\n\ - ldrb r0, [r7]\n\ - muls r0, r6\n\ - add r0, r10\n\ - adds r0, 0x2A\n\ - ldrb r0, [r0]\n\ - adds r1, r5, 0\n\ - adds r1, 0x2A\n\ - ldrb r1, [r1]\n\ - subs r0, r1\n\ - ldrb r2, [r2, 0x3]\n\ - adds r0, r2\n\ - lsls r0, 16\n\ - lsrs r4, r0, 16\n\ - bl Random\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - movs r1, 0x64\n\ - bl __umodsi3\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - adds r0, 0x1\n\ - cmp r0, r4\n\ - bge _08026CDC\n\ - ldrb r0, [r7]\n\ - adds r1, r0, 0\n\ - muls r1, r6\n\ - add r1, r10\n\ - adds r1, 0x2A\n\ - ldr r2, _08026CF0 @ =gBankTarget\n\ - ldrb r0, [r2]\n\ - muls r0, r6\n\ - add r0, r10\n\ - adds r0, 0x2A\n\ - ldrb r1, [r1]\n\ - movs r4, 0x1\n\ - ldrb r0, [r0]\n\ - cmp r1, r0\n\ - bcs _08026D20\n\ -_08026CDC:\n\ - mov r10, r8\n\ - b _08026DE0\n\ - .align 2, 0\n\ -_08026CE0: .4byte gStatuses3\n\ -_08026CE4: .4byte gBattleMoves\n\ -_08026CE8: .4byte gCurrentMove\n\ -_08026CEC: .4byte gBankAttacker\n\ -_08026CF0: .4byte gBankTarget\n\ -_08026CF4:\n\ - ldr r0, _08026D4C @ =gDisableStructs\n\ - lsls r1, r2, 3\n\ - subs r1, r2\n\ - lsls r1, 2\n\ - adds r1, r0\n\ - ldr r2, _08026D50 @ =gBankAttacker\n\ - ldrb r0, [r1, 0x15]\n\ - movs r4, 0\n\ - ldrb r3, [r2]\n\ - cmp r0, r3\n\ - bne _08026D20\n\ - ldrb r0, [r2]\n\ - muls r0, r6\n\ - add r0, r10\n\ - adds r0, 0x2A\n\ - adds r1, r5, 0\n\ - adds r1, 0x2A\n\ - ldrb r0, [r0]\n\ - ldrb r1, [r1]\n\ - cmp r0, r1\n\ - bcc _08026D20\n\ - movs r4, 0x1\n\ -_08026D20:\n\ - cmp r4, 0\n\ - beq _08026DE0\n\ - ldr r0, _08026D54 @ =gProtectStructs\n\ - ldr r1, _08026D58 @ =gBankTarget\n\ - ldrb r2, [r1]\n\ - lsls r1, r2, 4\n\ - adds r1, r0\n\ - ldrb r0, [r1]\n\ - lsls r0, 30\n\ - cmp r0, 0\n\ - bge _08026D64\n\ - ldr r1, _08026D5C @ =gBattleMoveDamage\n\ - movs r0, 0x58\n\ - muls r0, r2\n\ - add r0, r10\n\ - ldrh r0, [r0, 0x28]\n\ - subs r0, 0x1\n\ - str r0, [r1]\n\ - ldr r2, _08026D60 @ =gMoveResultFlags\n\ - ldrb r0, [r2]\n\ - movs r1, 0x40\n\ - b _08026DC6\n\ - .align 2, 0\n\ -_08026D4C: .4byte gDisableStructs\n\ -_08026D50: .4byte gBankAttacker\n\ -_08026D54: .4byte gProtectStructs\n\ -_08026D58: .4byte gBankTarget\n\ -_08026D5C: .4byte gBattleMoveDamage\n\ -_08026D60: .4byte gMoveResultFlags\n\ -_08026D64:\n\ - ldr r0, _08026DA0 @ =gSpecialStatuses\n\ - lsls r1, r2, 2\n\ - adds r1, r2\n\ - lsls r1, 2\n\ - adds r1, r0\n\ - ldrb r0, [r1]\n\ - lsrs r0, 7\n\ - cmp r0, 0\n\ - beq _08026DB4\n\ - ldr r1, _08026DA4 @ =gBattleMoveDamage\n\ - movs r3, 0x58\n\ - adds r0, r2, 0\n\ - muls r0, r3\n\ - add r0, r10\n\ - ldrh r0, [r0, 0x28]\n\ - subs r0, 0x1\n\ - str r0, [r1]\n\ - ldr r2, _08026DA8 @ =gMoveResultFlags\n\ - ldrb r0, [r2]\n\ - movs r1, 0x80\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ - ldr r1, _08026DAC @ =gLastUsedItem\n\ - ldr r2, _08026DB0 @ =gBankTarget\n\ - ldrb r0, [r2]\n\ - muls r0, r3\n\ - add r0, r10\n\ - ldrh r0, [r0, 0x2E]\n\ - strh r0, [r1]\n\ - b _08026DCA\n\ - .align 2, 0\n\ -_08026DA0: .4byte gSpecialStatuses\n\ -_08026DA4: .4byte gBattleMoveDamage\n\ -_08026DA8: .4byte gMoveResultFlags\n\ -_08026DAC: .4byte gLastUsedItem\n\ -_08026DB0: .4byte gBankTarget\n\ -_08026DB4:\n\ - ldr r1, _08026DD4 @ =gBattleMoveDamage\n\ - movs r0, 0x58\n\ - muls r0, r2\n\ - add r0, r10\n\ - ldrh r0, [r0, 0x28]\n\ - str r0, [r1]\n\ - ldr r2, _08026DD8 @ =gMoveResultFlags\n\ - ldrb r0, [r2]\n\ - movs r1, 0x10\n\ -_08026DC6:\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ -_08026DCA:\n\ - ldr r1, _08026DDC @ =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x5\n\ - str r0, [r1]\n\ - b _08026E40\n\ - .align 2, 0\n\ -_08026DD4: .4byte gBattleMoveDamage\n\ -_08026DD8: .4byte gMoveResultFlags\n\ -_08026DDC: .4byte gBattlescriptCurrInstr\n\ -_08026DE0:\n\ - ldr r2, _08026E10 @ =gMoveResultFlags\n\ - ldrb r0, [r2]\n\ - movs r1, 0x1\n\ - orrs r0, r1\n\ - strb r0, [r2]\n\ - ldr r0, _08026E14 @ =gBankAttacker\n\ - ldrb r0, [r0]\n\ - movs r2, 0x58\n\ - adds r1, r0, 0\n\ - muls r1, r2\n\ - add r1, r10\n\ - adds r1, 0x2A\n\ - ldr r3, _08026E18 @ =gBankTarget\n\ - ldrb r0, [r3]\n\ - muls r0, r2\n\ - add r0, r10\n\ - adds r0, 0x2A\n\ - ldrb r1, [r1]\n\ - ldrb r0, [r0]\n\ - cmp r1, r0\n\ - bcc _08026E20\n\ - ldr r1, _08026E1C @ =gBattleCommunication\n\ - movs r0, 0\n\ - b _08026E24\n\ - .align 2, 0\n\ -_08026E10: .4byte gMoveResultFlags\n\ -_08026E14: .4byte gBankAttacker\n\ -_08026E18: .4byte gBankTarget\n\ -_08026E1C: .4byte gBattleCommunication\n\ -_08026E20:\n\ - ldr r1, _08026E50 @ =gBattleCommunication\n\ - movs r0, 0x1\n\ -_08026E24:\n\ - strb r0, [r1, 0x5]\n\ - ldr r3, _08026E54 @ =gBattlescriptCurrInstr\n\ - ldr r2, [r3]\n\ - ldrb r1, [r2, 0x1]\n\ - ldrb r0, [r2, 0x2]\n\ - lsls r0, 8\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 16\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x4]\n\ - lsls r0, 24\n\ - orrs r1, r0\n\ - str r1, [r3]\n\ -_08026E40:\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_08026E50: .4byte gBattleCommunication\n\ -_08026E54: .4byte gBattlescriptCurrInstr\n\ - .syntax divided"); -} -#endif // NOTMATCHING - -static void atk94_damagetohalftargethp(void) //super fang -{ - gBattleMoveDamage = gBattleMons[gBankTarget].hp / 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattlescriptCurrInstr++; -} - -static void atk95_setsandstorm(void) -{ - if (gBattleWeather & WEATHER_SANDSTORM_ANY) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - } - else - { - gBattleWeather = WEATHER_SANDSTORM_TEMPORARY; - gBattleCommunication[MULTISTRING_CHOOSER] = 3; - gWishFutureKnock.weatherDuration = 5; - } - gBattlescriptCurrInstr++; -} - -static void atk96_weatherdamage(void) -{ - if (WEATHER_HAS_EFFECT) - { - if (gBattleWeather & WEATHER_SANDSTORM_ANY) - { - if (gBattleMons[gBankAttacker].type1 != TYPE_ROCK && gBattleMons[gBankAttacker].type1 != TYPE_STEEL && gBattleMons[gBankAttacker].type1 != TYPE_GROUND - && gBattleMons[gBankAttacker].type2 != TYPE_ROCK && gBattleMons[gBankAttacker].type2 != TYPE_STEEL && gBattleMons[gBankAttacker].type2 != TYPE_GROUND - && gBattleMons[gBankAttacker].ability != ABILITY_SAND_VEIL && !(gStatuses3[gBankAttacker] & STATUS3_UNDERGROUND) && !(gStatuses3[gBankAttacker] & STATUS3_UNDERWATER)) - { - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - } - else - { - gBattleMoveDamage = 0; - } - } - if (gBattleWeather & WEATHER_HAIL) - { - if (gBattleMons[gBankAttacker].type1 != TYPE_ICE && gBattleMons[gBankAttacker].type2 != TYPE_ICE && !(gStatuses3[gBankAttacker] & STATUS3_UNDERGROUND) && !(gStatuses3[gBankAttacker] & STATUS3_UNDERWATER)) - { - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - } - else - { - gBattleMoveDamage = 0; - } - } - } - else - gBattleMoveDamage = 0; - - if (gAbsentBattlerFlags & gBitTable[gBankAttacker]) - gBattleMoveDamage = 0; - - gBattlescriptCurrInstr++; -} - -static void atk97_tryinfatuating(void) -{ - struct Pokemon *attacker, *target; - u16 atk_species, def_species; - u32 atk_pid, def_pid; - if (!GetBattlerSide(gBankAttacker)) - attacker = &gPlayerParty[gBattlerPartyIndexes[gBankAttacker]]; - else - attacker = &gEnemyParty[gBattlerPartyIndexes[gBankAttacker]]; - - if (!GetBattlerSide(gBankTarget)) - target = &gPlayerParty[gBattlerPartyIndexes[gBankTarget]]; - else - target = &gEnemyParty[gBattlerPartyIndexes[gBankTarget]]; - - atk_species = GetMonData(attacker, MON_DATA_SPECIES); - atk_pid = GetMonData(attacker, MON_DATA_PERSONALITY); - - def_species = GetMonData(target, MON_DATA_SPECIES); - def_pid = GetMonData(target, MON_DATA_PERSONALITY); - - if (gBattleMons[gBankTarget].ability == ABILITY_OBLIVIOUS) - { - gBattlescriptCurrInstr = BattleScript_ObliviousPreventsAttraction; - gLastUsedAbility = ABILITY_OBLIVIOUS; - RecordAbilityBattle(gBankTarget, ABILITY_OBLIVIOUS); - } - else - { - if (GetGenderFromSpeciesAndPersonality(atk_species, atk_pid) == GetGenderFromSpeciesAndPersonality(def_species, def_pid) - || gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE || gBattleMons[gBankTarget].status2 & STATUS2_INFATUATION || GetGenderFromSpeciesAndPersonality(atk_species, atk_pid) == 0xFF - || GetGenderFromSpeciesAndPersonality(def_species, def_pid) == 0xFF) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } - else - { - gBattleMons[gBankTarget].status2 |= (gBitTable[gBankAttacker] << 16); - gBattlescriptCurrInstr += 5; - } - } -} - -static void atk98_updatestatusicon(void) -{ - if (gBattleExecBuffer) - return; - - if (T2_READ_8(gBattlescriptCurrInstr + 1) != 4) - { - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - EmitStatusIconUpdate(0, gBattleMons[gActiveBattler].status1, gBattleMons[gActiveBattler].status2); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 2; - } - else - { - gActiveBattler = gBankAttacker; - if (!(gAbsentBattlerFlags & gBitTable[gActiveBattler])) - { - EmitStatusIconUpdate(0, gBattleMons[gActiveBattler].status1, gBattleMons[gActiveBattler].status2); - MarkBufferBankForExecution(gActiveBattler); - } - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - gActiveBattler = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ 2); - if (!(gAbsentBattlerFlags & gBitTable[gActiveBattler])) - { - EmitStatusIconUpdate(0, gBattleMons[gActiveBattler].status1, gBattleMons[gActiveBattler].status2); - MarkBufferBankForExecution(gActiveBattler); - } - } - gBattlescriptCurrInstr += 2; - } -} - -static void atk99_setmist(void) -{ - if (gSideTimers[GetBattlerPosition(gBankAttacker) & 1].mistTimer) - { - gMoveResultFlags |= MOVE_RESULT_FAILED; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else - { - gSideTimers[GetBattlerPosition(gBankAttacker) & 1].mistTimer = 5; - gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] |= SIDE_STATUS_MIST; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - gBattlescriptCurrInstr++; -} - -static void atk9A_setfocusenergy(void) -{ - if (gBattleMons[gBankAttacker].status2 & STATUS2_FOCUS_ENERGY) - { - gMoveResultFlags |= MOVE_RESULT_FAILED; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else - { - gBattleMons[gBankAttacker].status2 |= STATUS2_FOCUS_ENERGY; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - gBattlescriptCurrInstr++; -} - -static void atk9B_transformdataexecution(void) -{ - gChosenMove = 0xFFFF; - gBattlescriptCurrInstr++; - if (gBattleMons[gBankTarget].status2 & STATUS2_TRANSFORMED || gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE) - { - gMoveResultFlags |= MOVE_RESULT_FAILED; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else - { - u32 i; s32 j; - u8 *atk_data, *def_data; - gBattleMons[gBankAttacker].status2 |= STATUS2_TRANSFORMED; - gDisableStructs[gBankAttacker].disabledMove = 0; - gDisableStructs[gBankAttacker].disableTimer1 = 0; - gDisableStructs[gBankAttacker].transformedMonPersonality = gBattleMons[gBankTarget].personality; - gDisableStructs[gBankAttacker].unk18_b = 0; - - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 6; - gBattleTextBuff1[2] = (gBattleMons[gBankTarget].species); - gBattleTextBuff1[3] = uBYTE1_16(gBattleMons[gBankTarget].species); - gBattleTextBuff1[4] = 0xFF; - - atk_data = (u8*)(&gBattleMons[gBankAttacker]); - def_data = (u8*)(&gBattleMons[gBankTarget]); - - for (i = 0; i < 0x24; i++) - atk_data[i] = def_data[i]; - - for (j = 0; j < 4; j++) - { - if (gBattleMoves[gBattleMons[gBankAttacker].moves[j]].pp < 5) - gBattleMons[gBankAttacker].pp[j] = gBattleMoves[gBattleMons[gBankAttacker].moves[j]].pp; - else - gBattleMons[gBankAttacker].pp[j] = 5; - } - - gActiveBattler = gBankAttacker; - EmitResetActionMoveSelection(0, 2); - MarkBufferBankForExecution(gActiveBattler); - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } -} - -static void atk9C_setsubstitute(void) -{ - u32 hp = gBattleMons[gBankAttacker].maxHP / 4; - if (gBattleMons[gBankAttacker].maxHP / 4 == 0) - hp = 1; - if (gBattleMons[gBankAttacker].hp <= hp) - { - gBattleMoveDamage = 0; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else - { - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 4; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMons[gBankAttacker].status2 |= STATUS2_SUBSTITUTE; - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_WRAPPED); - gDisableStructs[gBankAttacker].substituteHP = gBattleMoveDamage; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE; - } - gBattlescriptCurrInstr++; -} - -static bool8 IsMoveUncopyable(u16 move) -{ - int i; - for (i = 0; sMovesForbiddenToCopy[i] != 0xFFFE && sMovesForbiddenToCopy[i] != move; i++) {} - return (sMovesForbiddenToCopy[i] != 0xFFFE); -} - -static void atk9D_mimicattackcopy(void) -{ - gChosenMove = 0xFFFF; - if (IsMoveUncopyable(gLastUsedMove[gBankTarget]) || gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED - || gLastUsedMove[gBankTarget] == 0 || gLastUsedMove[gBankTarget] == 0xFFFF) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } - else - { - int i; - for (i = 0; i < 4; i++) - { - if (gBattleMons[gBankAttacker].moves[i] == gLastUsedMove[gBankTarget]) - break; - } - if (i == 4) - { - gBattleMons[gBankAttacker].moves[gCurrMovePos] = gLastUsedMove[gBankTarget]; - if (gBattleMoves[gLastUsedMove[gBankTarget]].pp < 5) - gBattleMons[gBankAttacker].pp[gCurrMovePos] = gBattleMoves[gLastUsedMove[gBankTarget]].pp; - else - gBattleMons[gBankAttacker].pp[gCurrMovePos] = 5; - - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = gLastUsedMove[gBankTarget]; - gBattleTextBuff1[3] = uBYTE1_16(gLastUsedMove[gBankTarget]); - gBattleTextBuff1[4] = 0xFF; - - gDisableStructs[gBankAttacker].unk18_b |= gBitTable[gCurrMovePos]; - gBattlescriptCurrInstr += 5; - } - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } -} - -#if DEBUG -NAKED -static void atk9E_metronome(void) -{ - asm("\ - push {r4, r5, r6, r7, lr}\n\ - mov r7, r8\n\ - push {r7}\n\ - ldr r6, ._3076 @ gBankAttacker\n\ - ldrb r2, [r6]\n\ - lsl r1, r2, #0x1\n\ - ldr r0, ._3076 + 4 @ \n\ - add r3, r1, r0\n\ - ldr r5, ._3076 + 8 @ \n\ - mov r4, #0x58\n\ - add r0, r2, #0\n\ - mul r0, r0, r4\n\ - add r1, r0, r5\n\ - ldrh r0, [r1, #0xe]\n\ - cmp r0, #0\n\ - bne ._3071 @cond_branch\n\ - ldrh r2, [r1, #0x10]\n\ - cmp r2, #0\n\ - beq ._3071 @cond_branch\n\ - ldrh r0, [r1, #0x12]\n\ - cmp r0, #0\n\ - beq ._3071 @cond_branch\n\ - ldrh r0, [r3]\n\ - cmp r0, #0\n\ - bne ._3072 @cond_branch\n\ - strh r2, [r3]\n\ -._3072:\n\ - ldr r1, ._3076 + 12 @ \n\ - ldrh r0, [r3]\n\ - strh r0, [r1]\n\ - ldrb r0, [r6]\n\ - mul r0, r0, r4\n\ - add r0, r0, r5\n\ - ldrh r5, [r0, #0x10]\n\ - ldrh r2, [r0, #0x12]\n\ - add r7, r1, #0\n\ - cmp r5, r2\n\ - bcs ._3073 @cond_branch\n\ - ldrh r0, [r3]\n\ - cmp r0, r2\n\ - beq ._3074 @cond_branch\n\ - add r0, r0, #0x1\n\ - b ._3079\n\ -._3077:\n\ - .align 2, 0\n\ -._3076:\n\ - .word gBankAttacker\n\ - .word +0x20160b4\n\ - .word gBattleMons\n\ - .word gCurrentMove\n\ -._3073:\n\ - ldrh r4, [r3]\n\ - add r1, r4, #0\n\ - mov r0, #0xb1\n\ - lsl r0, r0, #0x1\n\ - cmp r1, r0\n\ - bne ._3078 @cond_branch\n\ - mov r0, #0x1\n\ - b ._3079\n\ -._3078:\n\ - cmp r1, r2\n\ - bne ._3080 @cond_branch\n\ -._3074:\n\ - strh r5, [r3]\n\ - b ._3081\n\ -._3080:\n\ - add r0, r4, #1\n\ -._3079:\n\ - strh r0, [r3]\n\ -._3081:\n\ - ldr r4, ._3083 @ gHitMarker\n\ - ldr r2, [r4]\n\ - ldr r0, ._3083 + 4 @ 0xfffffbff\n\ - and r2, r2, r0\n\ - str r2, [r4]\n\ - ldr r6, ._3083 + 8 @ gBattlescriptCurrInstr\n\ - ldr r5, ._3083 + 12 @ gBattleScriptsForMoveEffects\n\ - ldr r3, ._3083 + 16 @ gBattleMoves\n\ - ldrh r1, [r7]\n\ - lsl r0, r1, #0x1\n\ - add r0, r0, r1\n\ - lsl r0, r0, #0x2\n\ - add r0, r0, r3\n\ - ldrb r0, [r0]\n\ - lsl r0, r0, #0x2\n\ - add r0, r0, r5\n\ - ldr r0, [r0]\n\ - str r0, [r6]\n\ - mov r0, #0x80\n\ - lsl r0, r0, #0x4\n\ - orr r2, r2, r0\n\ - str r2, [r4]\n\ - ldrh r0, [r7]\n\ - b ._3082\n\ -._3084:\n\ - .align 2, 0\n\ -._3083:\n\ - .word gHitMarker\n\ - .word 0xfffffbff\n\ - .word gBattlescriptCurrInstr\n\ - .word gBattleScriptsForMoveEffects\n\ - .word gBattleMoves\n\ -._3071:\n\ - ldr r7, ._3090 @ gCurrentMove\n\ - mov r6, #0xb1\n\ - lsl r6, r6, #0x1\n\ - ldr r5, ._3090 + 4 @ sMovesForbiddenToCopy\n\ - ldr r0, ._3090 + 8 @ gBattlescriptCurrInstr\n\ - mov r8, r0\n\ -._3089:\n\ - bl Random\n\ - ldr r2, ._3090 + 12 @ 0x1ff\n\ - add r1, r2, #0\n\ - and r0, r0, r1\n\ - add r0, r0, #0x1\n\ - strh r0, [r7]\n\ - cmp r0, r6\n\ - bhi ._3089 @cond_branch\n\ - mov r0, #0x3\n\ -._3086:\n\ - sub r0, r0, #0x1\n\ - cmp r0, #0\n\ - bge ._3086 @cond_branch\n\ - ldr r4, ._3090 @ gCurrentMove\n\ - ldrh r2, [r4]\n\ - ldr r3, ._3090 + 16 @ 0xffff\n\ - sub r0, r5, #2\n\ -._3088:\n\ - add r0, r0, #0x2\n\ - ldrh r1, [r0]\n\ - cmp r1, r2\n\ - beq ._3087 @cond_branch\n\ - cmp r1, r3\n\ - bne ._3088 @cond_branch\n\ -._3087:\n\ - ldr r0, ._3090 + 16 @ 0xffff\n\ - cmp r1, r0\n\ - bne ._3089 @cond_branch\n\ - ldr r2, ._3090 + 20 @ gHitMarker\n\ - ldr r0, [r2]\n\ - ldr r1, ._3090 + 24 @ 0xfffffbff\n\ - and r0, r0, r1\n\ - str r0, [r2]\n\ - ldr r3, ._3090 + 28 @ gBattleScriptsForMoveEffects\n\ - ldr r2, ._3090 + 32 @ gBattleMoves\n\ - ldrh r1, [r4]\n\ - lsl r0, r1, #0x1\n\ - add r0, r0, r1\n\ - lsl r0, r0, #0x2\n\ - add r0, r0, r2\n\ - ldrb r0, [r0]\n\ - lsl r0, r0, #0x2\n\ - add r0, r0, r3\n\ - ldr r0, [r0]\n\ - mov r1, r8\n\ - str r0, [r1]\n\ - ldrh r0, [r4]\n\ -._3082:\n\ - mov r1, #0x0\n\ - bl GetMoveTarget\n\ - ldr r1, ._3090 + 36 @ gBankTarget\n\ - strb r0, [r1]\n\ - pop {r3}\n\ - mov r8, r3\n\ - pop {r4, r5, r6, r7}\n\ - pop {r0}\n\ - bx r0\n\ -._3091:\n\ - .align 2, 0\n\ -._3090:\n\ - .word gCurrentMove\n\ - .word sMovesForbiddenToCopy\n\ - .word gBattlescriptCurrInstr\n\ - .word 0x1ff\n\ - .word 0xffff\n\ - .word gHitMarker\n\ - .word 0xfffffbff\n\ - .word gBattleScriptsForMoveEffects\n\ - .word gBattleMoves\n\ - .word gBankTarget"); -} -#else -#ifdef NONMATCHING -static void atk9E_metronome(void) -{ - // sMovesForbiddenToCopy - int i; - do - { - while ((gCurrentMove = (Random() & 0x1FF) + 1) > 0x162); - for (i = 0; sMovesForbiddenToCopy[i] != gCurrentMove && sMovesForbiddenToCopy[i] != 0xFFFF; i++); - } while (sMovesForbiddenToCopy[i] != 0xFFFF); - - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; - gBankTarget = GetMoveTarget(gCurrentMove, 0); -} - -#else -NAKED -static void atk9E_metronome(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r8\n\ - push {r7}\n\ - ldr r7, _08027938 @ =gCurrentMove\n\ - movs r6, 0xB1\n\ - lsls r6, 1\n\ - ldr r5, _0802793C @ =sMovesForbiddenToCopy\n\ - ldr r0, _08027940 @ =gBattlescriptCurrInstr\n\ - mov r8, r0\n\ -_080278CA:\n\ - bl Random\n\ - ldr r2, _08027944 @ =0x000001ff\n\ - adds r1, r2, 0\n\ - ands r0, r1\n\ - adds r0, 0x1\n\ - strh r0, [r7]\n\ - cmp r0, r6\n\ - bhi _080278CA\n\ - movs r0, 0x3\n\ -_080278DE:\n\ - subs r0, 0x1\n\ - cmp r0, 0\n\ - bge _080278DE\n\ - ldr r4, _08027938 @ =gCurrentMove\n\ - ldrh r2, [r4]\n\ - ldr r3, _08027948 @ =0x0000ffff\n\ - subs r0, r5, 0x2\n\ -_080278EC:\n\ - adds r0, 0x2\n\ - ldrh r1, [r0]\n\ - cmp r1, r2\n\ - beq _080278F8\n\ - cmp r1, r3\n\ - bne _080278EC\n\ -_080278F8:\n\ - ldr r0, _08027948 @ =0x0000ffff\n\ - cmp r1, r0\n\ - bne _080278CA\n\ - ldr r2, _0802794C @ =gHitMarker\n\ - ldr r0, [r2]\n\ - ldr r1, _08027950 @ =0xfffffbff\n\ - ands r0, r1\n\ - str r0, [r2]\n\ - ldr r3, _08027954 @ =gBattleScriptsForMoveEffects\n\ - ldr r2, _08027958 @ =gBattleMoves\n\ - ldrh r1, [r4]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldrb r0, [r0]\n\ - lsls r0, 2\n\ - adds r0, r3\n\ - ldr r0, [r0]\n\ - mov r1, r8\n\ - str r0, [r1]\n\ - ldrh r0, [r4]\n\ - movs r1, 0\n\ - bl GetMoveTarget\n\ - ldr r1, _0802795C @ =gBankTarget\n\ - strb r0, [r1]\n\ - pop {r3}\n\ - mov r8, r3\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_08027938: .4byte gCurrentMove\n\ -_0802793C: .4byte sMovesForbiddenToCopy\n\ -_08027940: .4byte gBattlescriptCurrInstr\n\ -_08027944: .4byte 0x000001ff\n\ -_08027948: .4byte 0x0000ffff\n\ -_0802794C: .4byte gHitMarker\n\ -_08027950: .4byte 0xfffffbff\n\ -_08027954: .4byte gBattleScriptsForMoveEffects\n\ -_08027958: .4byte gBattleMoves\n\ -_0802795C: .4byte gBankTarget\n\ - .syntax divided"); -} -#endif // NONMATCHING -#endif - -static void atk9F_dmgtolevel(void) -{ - gBattleMoveDamage = gBattleMons[gBankAttacker].level; - gBattlescriptCurrInstr++; -} - -static void atkA0_psywavedamageeffect(void) -{ - s32 rand_dmg; - while ((rand_dmg = (Random() & 0xF)) > 0xA); - rand_dmg *= 10; - gBattleMoveDamage = gBattleMons[gBankAttacker].level * (rand_dmg + 50) / 100; - gBattlescriptCurrInstr++; -} - -static void atkA1_counterdamagecalculator(void) -{ - u8 atk_side = GetBattlerSide(gBankAttacker); - u8 def_side = GetBattlerSide(gProtectStructs[gBankAttacker].physicalBank); - if (gProtectStructs[gBankAttacker].physicalDmg && atk_side != def_side && gBattleMons[gProtectStructs[gBankAttacker].physicalBank].hp) - { - gBattleMoveDamage = gProtectStructs[gBankAttacker].physicalDmg * 2; - if (gSideTimers[def_side].followmeTimer && gBattleMons[gSideTimers[def_side].followmeTarget].hp) - gBankTarget = gSideTimers[def_side].followmeTarget; - else - gBankTarget = gProtectStructs[gBankAttacker].physicalBank; - gBattlescriptCurrInstr += 5; - } - else - { - gSpecialStatuses[gBankAttacker].flag20 = 1; - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } -} - -static void atkA2_mirrorcoatdamagecalculator(void) //a copy of atkA1 with the physical -> special field changes -{ - u8 atk_side = GetBattlerSide(gBankAttacker); - u8 def_side = GetBattlerSide(gProtectStructs[gBankAttacker].specialBank); - if (gProtectStructs[gBankAttacker].specialDmg && atk_side != def_side && gBattleMons[gProtectStructs[gBankAttacker].specialBank].hp) - { - gBattleMoveDamage = gProtectStructs[gBankAttacker].specialDmg * 2; - if (gSideTimers[def_side].followmeTimer && gBattleMons[gSideTimers[def_side].followmeTarget].hp) - gBankTarget = gSideTimers[def_side].followmeTarget; - else - gBankTarget = gProtectStructs[gBankAttacker].specialBank; - gBattlescriptCurrInstr += 5; - } - else - { - gSpecialStatuses[gBankAttacker].flag20 = 1; - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } -} - -static void atkA3_disablelastusedattack(void) -{ - int i; - for (i = 0; i < 4; i++) - { - if (gBattleMons[gBankTarget].moves[i] == gLastUsedMove[gBankTarget]) - break; - } - if (gDisableStructs[gBankTarget].disabledMove == 0 && i != 4 && gBattleMons[gBankTarget].pp[i] != 0) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = gBattleMons[gBankTarget].moves[i]; - gBattleTextBuff1[3] = uBYTE1_16(gBattleMons[gBankTarget].moves[i]); - gBattleTextBuff1[4] = 0xFF; - - gDisableStructs[gBankTarget].disabledMove = gBattleMons[gBankTarget].moves[i]; - gDisableStructs[gBankTarget].disableTimer1 = (Random() & 3) + 2; - gDisableStructs[gBankTarget].disableTimer2 = gDisableStructs[gBankTarget].disableTimer1; //that's interesting - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } -} - -static void atkA4_trysetencore(void) -{ - int i; - for (i = 0; i < 4; i++) - { - if (gBattleMons[gBankTarget].moves[i] == gLastUsedMove[gBankTarget]) - break; - } - if (gLastUsedMove[gBankTarget] == MOVE_STRUGGLE || gLastUsedMove[gBankTarget] == MOVE_ENCORE || gLastUsedMove[gBankTarget] == MOVE_MIRROR_MOVE) - i = 4; - if (gDisableStructs[gBankTarget].encoredMove == 0 && i != 4 && gBattleMons[gBankTarget].pp[i] != 0) - { - gDisableStructs[gBankTarget].encoredMove = gBattleMons[gBankTarget].moves[i]; - gDisableStructs[gBankTarget].encoredMovePos = i; - gDisableStructs[gBankTarget].encoreTimer1 = (Random() & 3) + 3; - gDisableStructs[gBankTarget].encoreTimer2 = gDisableStructs[gBankTarget].encoreTimer1; - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } -} - -static void atkA5_painsplitdmgcalc(void) -{ - if (!(gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE)) - { - s32 hp_diff = (gBattleMons[gBankAttacker].hp + gBattleMons[gBankTarget].hp) / 2; - s32 to_store = gBattleMoveDamage = gBattleMons[gBankTarget].hp - hp_diff; - gBattleStruct->unk16014 = sBYTE0_32(to_store); - gBattleStruct->unk16015 = sBYTE1_32(to_store); - gBattleStruct->unk16016 = sBYTE2_32(to_store); - gBattleStruct->unk16017 = sBYTE3_32(to_store); - - gBattleMoveDamage = gBattleMons[gBankAttacker].hp - hp_diff; - gSpecialStatuses[gBankTarget].moveturnLostHP = 0xFFFF; - - gBattlescriptCurrInstr += 5; - } - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -#ifdef NONMATCHING -static void atkA6_settypetorandomresistance(void) -{ - if (gLastLandedMoves[gBankAttacker] == 0 || gLastLandedMoves[gBankAttacker] == 0xFFFF || (IsTwoTurnsMove(gLastLandedMoves[gBankAttacker]) && !gProtectStructs[gBankAttacker].physicalDmg && !gProtectStructs[gBankAttacker].specialDmg)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - { - int type = 0, rands = 0; - do - { - while (((type = (Random() & 0x7F)) > 0x70)); - type *= 3; - if (gTypeEffectiveness[type] == gLastHitByType[gBankAttacker] && gTypeEffectiveness[type + 2] <= 5 && gBattleMons[gBankAttacker].type1 != gTypeEffectiveness[type + 1] && gBattleMons[gBankAttacker].type2 != gTypeEffectiveness[type + 1]) - { - gBattleMons[gBankAttacker].type1 = type; - gBattleMons[gBankAttacker].type2 = type; - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 3; - gBattleTextBuff1[2] = type; - gBattleTextBuff1[3] = 0xFF; - gBattlescriptCurrInstr += 5; - return; - } - rands++; - } while (rands <= 999); - - type = 0, rands = 0; - do - { - if (gTypeEffectiveness[type] == 0xFE || gTypeEffectiveness[type] != 0xFF) - { - if (gTypeEffectiveness[type] == gLastHitByType[gBankAttacker] && gTypeEffectiveness[type + 2] <= 5 && gBattleMons[gBankAttacker].type1 != gTypeEffectiveness[type + 1] && gBattleMons[gBankAttacker].type2 != gTypeEffectiveness[type + 1]) - { - gBattleMons[gBankAttacker].type1 = gTypeEffectiveness[rands + 1]; - gBattleMons[gBankAttacker].type2 = gTypeEffectiveness[rands + 1]; - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 3; - gBattleTextBuff1[2] = gTypeEffectiveness[rands + 1]; - gBattleTextBuff1[3] = 0xFF; - gBattlescriptCurrInstr += 5; - return; - } - } - type += 3, rands += 3; - } while (rands < 336); - - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } -} - -#else -NAKED -static void atkA6_settypetorandomresistance(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - ldr r1, _08027FA8 @ =gLastLandedMoves\n\ - ldr r4, _08027FAC @ =gBankAttacker\n\ - ldrb r0, [r4]\n\ - lsls r0, 1\n\ - adds r2, r0, r1\n\ - ldrh r1, [r2]\n\ - cmp r1, 0\n\ - beq _08027F8C\n\ - ldr r0, _08027FB0 @ =0x0000ffff\n\ - cmp r1, r0\n\ - beq _08027F8C\n\ - ldrh r0, [r2]\n\ - bl IsTwoTurnsMove\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08028024\n\ - ldr r2, _08027FB4 @ =gProtectStructs\n\ - ldrb r0, [r4]\n\ - lsls r1, r0, 4\n\ - adds r0, r2, 0x4\n\ - adds r0, r1, r0\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - bne _08028024\n\ - adds r0, r2, 0\n\ - adds r0, 0x8\n\ - adds r0, r1, r0\n\ - ldr r0, [r0]\n\ - cmp r0, 0\n\ - bne _08028024\n\ -_08027F8C:\n\ - ldr r3, _08027FB8 @ =gBattlescriptCurrInstr\n\ - ldr r2, [r3]\n\ - ldrb r1, [r2, 0x1]\n\ - ldrb r0, [r2, 0x2]\n\ - lsls r0, 8\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 16\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x4]\n\ - lsls r0, 24\n\ - orrs r1, r0\n\ - str r1, [r3]\n\ - b _08028110\n\ - .align 2, 0\n\ -_08027FA8: .4byte gLastLandedMoves\n\ -_08027FAC: .4byte gBankAttacker\n\ -_08027FB0: .4byte 0x0000ffff\n\ -_08027FB4: .4byte gProtectStructs\n\ -_08027FB8: .4byte gBattlescriptCurrInstr\n\ -_08027FBC:\n\ - mov r0, r12\n\ - strb r5, [r0]\n\ - mov r1, r10\n\ - ldrb r0, [r1]\n\ - muls r0, r2\n\ - adds r0, r7\n\ - adds r0, 0x22\n\ - strb r5, [r0]\n\ - ldr r1, _08027FE0 @ =gBattleTextBuff1\n\ - movs r0, 0xFD\n\ - strb r0, [r1]\n\ - movs r0, 0x3\n\ - strb r0, [r1, 0x1]\n\ - strb r5, [r1, 0x2]\n\ - movs r0, 0xFF\n\ - strb r0, [r1, 0x3]\n\ - ldr r1, _08027FE4 @ =gBattlescriptCurrInstr\n\ - b _08028012\n\ - .align 2, 0\n\ -_08027FE0: .4byte gBattleTextBuff1\n\ -_08027FE4: .4byte gBattlescriptCurrInstr\n\ -_08027FE8:\n\ - mov r0, r8\n\ - adds r0, 0x1\n\ - adds r0, r3\n\ - ldrb r2, [r0]\n\ - strb r2, [r4]\n\ - mov r4, r10\n\ - ldrb r0, [r4]\n\ - muls r0, r6\n\ - ldr r7, _0802801C @ =gBattleMons\n\ - adds r0, r7\n\ - adds r0, 0x22\n\ - strb r2, [r0]\n\ - ldr r1, _08028020 @ =gBattleTextBuff1\n\ - movs r0, 0xFD\n\ - strb r0, [r1]\n\ - movs r0, 0x3\n\ - strb r0, [r1, 0x1]\n\ - strb r2, [r1, 0x2]\n\ - movs r0, 0xFF\n\ - strb r0, [r1, 0x3]\n\ - mov r1, r12\n\ -_08028012:\n\ - ldr r0, [r1]\n\ - adds r0, 0x5\n\ - str r0, [r1]\n\ - b _08028110\n\ - .align 2, 0\n\ -_0802801C: .4byte gBattleMons\n\ -_08028020: .4byte gBattleTextBuff1\n\ -_08028024:\n\ - movs r4, 0\n\ - mov r8, r4\n\ - movs r7, 0x7F\n\ - mov r9, r7\n\ -_0802802C:\n\ - bl Random\n\ - mov r4, r9\n\ - ands r4, r0\n\ - cmp r4, 0x70\n\ - bhi _0802802C\n\ - lsls r0, r4, 1\n\ - adds r4, r0, r4\n\ - ldr r6, _08028120 @ =gTypeEffectiveness\n\ - adds r3, r4, r6\n\ - ldr r1, _08028124 @ =gLastHitByType\n\ - ldr r2, _08028128 @ =gBankAttacker\n\ - ldrb r5, [r2]\n\ - lsls r0, r5, 1\n\ - adds r0, r1\n\ - ldrb r1, [r3]\n\ - mov r10, r2\n\ - ldrh r0, [r0]\n\ - cmp r1, r0\n\ - bne _08028088\n\ - adds r0, r4, 0x2\n\ - adds r0, r6\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x5\n\ - bhi _08028088\n\ - ldr r7, _0802812C @ =gBattleMons\n\ - movs r2, 0x58\n\ - adds r0, r5, 0\n\ - muls r0, r2\n\ - adds r3, r0, r7\n\ - movs r0, 0x21\n\ - adds r0, r3\n\ - mov r12, r0\n\ - adds r0, r4, 0x1\n\ - adds r0, r6\n\ - ldrb r5, [r0]\n\ - mov r1, r12\n\ - ldrb r0, [r1]\n\ - adds r1, r5, 0\n\ - cmp r0, r1\n\ - beq _08028088\n\ - adds r0, r3, 0\n\ - adds r0, 0x22\n\ - ldrb r0, [r0]\n\ - cmp r0, r1\n\ - bne _08027FBC\n\ -_08028088:\n\ - movs r7, 0x1\n\ - add r8, r7\n\ - ldr r0, _08028130 @ =0x000003e7\n\ - cmp r8, r0\n\ - ble _0802802C\n\ - movs r0, 0\n\ - mov r8, r0\n\ - ldr r1, _08028134 @ =gBattlescriptCurrInstr\n\ - mov r12, r1\n\ - ldr r3, _08028120 @ =gTypeEffectiveness\n\ - adds r0, r4, 0x1\n\ - adds r0, r3\n\ - mov r9, r0\n\ - adds r5, r3, 0\n\ -_080280A4:\n\ - ldrb r1, [r5]\n\ - cmp r1, 0xFF\n\ - bgt _080280AE\n\ - cmp r1, 0xFE\n\ - bge _080280E8\n\ -_080280AE:\n\ - mov r4, r10\n\ - ldrb r2, [r4]\n\ - lsls r0, r2, 1\n\ - ldr r7, _08028124 @ =gLastHitByType\n\ - adds r0, r7\n\ - ldrh r0, [r0]\n\ - cmp r1, r0\n\ - bne _080280E8\n\ - ldrb r0, [r5, 0x2]\n\ - cmp r0, 0x5\n\ - bhi _080280E8\n\ - movs r6, 0x58\n\ - adds r0, r2, 0\n\ - muls r0, r6\n\ - ldr r1, _0802812C @ =gBattleMons\n\ - adds r2, r0, r1\n\ - adds r4, r2, 0\n\ - adds r4, 0x21\n\ - ldrb r0, [r4]\n\ - mov r7, r9\n\ - ldrb r1, [r7]\n\ - cmp r0, r1\n\ - beq _080280E8\n\ - adds r0, r2, 0\n\ - adds r0, 0x22\n\ - ldrb r0, [r0]\n\ - cmp r0, r1\n\ - beq _080280E8\n\ - b _08027FE8\n\ -_080280E8:\n\ - adds r5, 0x3\n\ - movs r0, 0x3\n\ - add r8, r0\n\ - ldr r0, _08028138 @ =0x0000014f\n\ - cmp r8, r0\n\ - bls _080280A4\n\ - mov r1, r12\n\ - ldr r2, [r1]\n\ - ldrb r1, [r2, 0x1]\n\ - ldrb r0, [r2, 0x2]\n\ - lsls r0, 8\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 16\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x4]\n\ - lsls r0, 24\n\ - orrs r1, r0\n\ - mov r4, r12\n\ - str r1, [r4]\n\ -_08028110:\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_08028120: .4byte gTypeEffectiveness\n\ -_08028124: .4byte gLastHitByType\n\ -_08028128: .4byte gBankAttacker\n\ -_0802812C: .4byte gBattleMons\n\ -_08028130: .4byte 0x000003e7\n\ -_08028134: .4byte gBattlescriptCurrInstr\n\ -_08028138: .4byte 0x0000014f\n\ - .syntax divided"); -} -#endif // NONMATCHING - -static void atkA7_setalwayshitflag(void) -{ - gStatuses3[gBankTarget] &= ~(STATUS3_ALWAYS_HITS); - gStatuses3[gBankTarget] |= 0x10; - gDisableStructs[gBankTarget].bankWithSureHit = gBankAttacker; - gBattlescriptCurrInstr++; -} - -struct move_pp -{ - u16 move[4]; - u8 pp[4]; - u8 ppBonuses; -}; - -static void atkA8_copymovepermanently(void) -{ - gChosenMove = 0xFFFF; - if (!(gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED) && gUnknown_02024C2C[gBankTarget] != MOVE_STRUGGLE && gUnknown_02024C2C[gBankTarget] != 0 && gUnknown_02024C2C[gBankTarget] != 0xFFFF && gUnknown_02024C2C[gBankTarget] != MOVE_SKETCH) - { - int i; - for (i = 0; i < 4; i++) - { - if (gBattleMons[gBankAttacker].moves[i] == MOVE_SKETCH) - continue; - if (gBattleMons[gBankAttacker].moves[i] == gUnknown_02024C2C[gBankTarget]) - break; - } - if (i != 4) //sketch fail - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else //sketch worked - { - struct move_pp moves_data; - gBattleMons[gBankAttacker].moves[gCurrMovePos] = gUnknown_02024C2C[gBankTarget]; - gBattleMons[gBankAttacker].pp[gCurrMovePos] = gBattleMoves[gUnknown_02024C2C[gBankTarget]].pp; - gActiveBattler = gBankAttacker; - for (i = 0; i < 4; i++) - { - moves_data.move[i] = gBattleMons[gBankAttacker].moves[i]; - moves_data.pp[i] = gBattleMons[gBankAttacker].pp[i]; - } - moves_data.ppBonuses = gBattleMons[gBankAttacker].ppBonuses; - EmitSetMonData(0, REQUEST_MOVES_PP_BATTLE, 0, sizeof(struct move_pp), &moves_data); - MarkBufferBankForExecution(gActiveBattler); - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = gUnknown_02024C2C[gBankTarget]; - gBattleTextBuff1[3] = gUnknown_02024C2C[gBankTarget] >> 8; - gBattleTextBuff1[4] = 0xFF; - gBattlescriptCurrInstr += 5; - } - } - else //sketch fail - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static bool8 IsTwoTurnsMove(u16 move) -{ - u8 effect = gBattleMoves[move].effect; - if (effect == EFFECT_SKULL_BASH || effect == EFFECT_RAZOR_WIND || effect == EFFECT_SKY_ATTACK || effect == EFFECT_SOLARBEAM || effect == EFFECT_FLY || effect == EFFECT_BIDE) - return 1; - else - return 0; -} - -static bool8 IsMoveUnchoosable(u16 move) -{ - if (move == 0 || move == MOVE_SLEEP_TALK || move == MOVE_ASSIST || move == MOVE_MIRROR_MOVE || move == MOVE_METRONOME) - return 1; - else - return 0; -} - -static u8 AttacksThisTurn(u8 bank, u16 move) //Note: returns 1 if it's a charging turn, otherwise 2 -{ - //first argument is unused - u8 effect; - if (gBattleMoves[move].effect == EFFECT_SOLARBEAM && (gBattleWeather & WEATHER_SUN_ANY)) - return 2; - effect = gBattleMoves[move].effect; - if (effect == EFFECT_SKULL_BASH || effect == EFFECT_RAZOR_WIND || effect == EFFECT_SKY_ATTACK || effect == EFFECT_SOLARBEAM || effect == EFFECT_FLY || effect == EFFECT_BIDE) - { - if ((gHitMarker & HITMARKER_x8000000)) - return 1; - } - return 2; -} - -static void atkA9_trychoosesleeptalkmove(void) -{ - u8 unusable_moves = 0; - int i; - - for (i = 0; i < 4; i++) - { - if (IsMoveUnchoosable(gBattleMons[gBankAttacker].moves[i]) || gBattleMons[gBankAttacker].moves[i] == MOVE_FOCUS_PUNCH - || gBattleMons[gBankAttacker].moves[i] == MOVE_UPROAR || IsTwoTurnsMove(gBattleMons[gBankAttacker].moves[i])) - unusable_moves |= gBitTable[i]; - } - unusable_moves = CheckMoveLimitations(gBankAttacker, unusable_moves, 0xFD); - if (unusable_moves == 0xF) //all 4 moves cannot be chosen - gBattlescriptCurrInstr += 5; - else //at least one move can be chosen - { - u32 random_pos; - do - { - random_pos = Random() & 3; - } while ((gBitTable[random_pos] & unusable_moves)); - - gRandomMove = gBattleMons[gBankAttacker].moves[random_pos]; - gCurrMovePos = random_pos; - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gBankTarget = GetMoveTarget(gRandomMove, 0); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } -} - -static void atkAA_setdestinybond(void) -{ - gBattleMons[gBankAttacker].status2 |= STATUS2_DESTINY_BOND; - gBattlescriptCurrInstr++; -} - -static void TrySetDestinyBondToHappen(void) -{ - u8 atk_side = GetBattlerSide(gBankAttacker); - u8 def_side = GetBattlerSide(gBankTarget); - if (gBattleMons[gBankTarget].status2 & STATUS2_DESTINY_BOND && atk_side != def_side && !(gHitMarker & HITMARKER_GRUDGE)) - gHitMarker |= HITMARKER_DESTINYBOND; -} - -static void atkAB_trysetdestinybondtohappen(void) -{ - TrySetDestinyBondToHappen(); - gBattlescriptCurrInstr++; -} - -static void atkAC_remaininghptopower(void) -{ - s32 hp_fraction = GetScaledHPFraction(gBattleMons[gBankAttacker].hp, gBattleMons[gBankAttacker].maxHP, 48); - int i; - for (i = 0; i < 12; i += 2) - { - if (hp_fraction <= sFlailHpScaleToPowerTable[i]) - break; - } - gDynamicBasePower = sFlailHpScaleToPowerTable[i + 1]; - gBattlescriptCurrInstr++; -} - -static void atkAD_tryspiteppreduce(void) -{ - if (gLastUsedMove[gBankTarget] != 0 && gLastUsedMove[gBankTarget] != 0xFFFF && !(gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE)) - { - int i; - for (i = 0; i < 4; i++) - { - if (gLastUsedMove[gBankTarget] == gBattleMons[gBankTarget].moves[i]) - break; - } - if (i != 4 && gBattleMons[gBankTarget].pp[i] > 1) - { - s32 lost_pp = (Random() & 3) + 2; - if (gBattleMons[gBankTarget].pp[i] < lost_pp) - lost_pp = gBattleMons[gBankTarget].pp[i]; - - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = gLastUsedMove[gBankTarget]; - gBattleTextBuff1[3] = gLastUsedMove[gBankTarget] >> 8; - gBattleTextBuff1[4] = 0xFF; - ConvertIntToDecimalStringN(gBattleTextBuff2, lost_pp, 0, 1); - gBattleTextBuff2[0] = 0xFD; - gBattleTextBuff2[1] = 1; - gBattleTextBuff2[2] = 1; - gBattleTextBuff2[3] = 1; - gBattleTextBuff2[4] = lost_pp; - gBattleTextBuff2[5] = 0xFF; - - gBattleMons[gBankTarget].pp[i] -= lost_pp; - gActiveBattler = gBankTarget; - if (!(gDisableStructs[gActiveBattler].unk18_b & gBitTable[i]) - && !(gBattleMons[gActiveBattler].status2 & STATUS2_TRANSFORMED)) - { - EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + i, 0, 1, &gBattleMons[gActiveBattler].pp[i]); - MarkBufferBankForExecution(gActiveBattler); - } - gBattlescriptCurrInstr += 5; - if (gBattleMons[gBankTarget].pp[i] == 0) - CancelMultiTurnMoves(gBankTarget); - return; - } - } - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atkAE_healpartystatus(void) -{ - register u32 zero2 asm("r4") = 0; - u32 zero = zero2; - u8 to_heal = 0; - if (gCurrentMove == MOVE_HEAL_BELL) - { - struct Pokemon* party; - int i; - - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - if (GetBattlerSide(gBankAttacker) == 0) - party = gPlayerParty; - else - party = gEnemyParty; - - if (gBattleMons[gBankAttacker].ability != ABILITY_SOUNDPROOF) - { - gBattleMons[gBankAttacker].status1 = 0; - } - else - { - RecordAbilityBattle(gBankAttacker, gBattleMons[gBankAttacker].ability); - gBattleCommunication[MULTISTRING_CHOOSER] |= 1; - } - - gActiveBattler = gBattleStruct->scriptingActive = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ 2); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gAbsentBattlerFlags & gBitTable[gActiveBattler])) - { - if (gBattleMons[gActiveBattler].ability != ABILITY_SOUNDPROOF) - { - gBattleMons[gActiveBattler].status1 = 0; - } - else - { - RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability); - gBattleCommunication[MULTISTRING_CHOOSER] |= 2; - } - } - - for (i = 0; i < 6; i++) - { - u16 species = GetMonData(&party[i], MON_DATA_SPECIES2); - u8 abilityBit = GetMonData(&party[i], MON_DATA_ALT_ABILITY); - if (species != 0 && species != SPECIES_EGG) - { - u8 ability; - if (gBattlerPartyIndexes[gBankAttacker] == i) - ability = gBattleMons[gBankAttacker].ability; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlerPartyIndexes[gActiveBattler] == i && !(gAbsentBattlerFlags & gBitTable[gActiveBattler])) - ability = gBattleMons[gActiveBattler].ability; - else - ability = GetAbilityBySpecies(species, abilityBit); - if (ability != ABILITY_SOUNDPROOF) - to_heal |= (1 << i); - } - } - } - else //Aromatherapy - { - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - to_heal = 0x3F; - gBattleMons[gBankAttacker].status1 = zero2; - - gActiveBattler = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ 2); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gAbsentBattlerFlags & gBitTable[gActiveBattler])) - gBattleMons[gActiveBattler].status1 = 0; - - } - //missing check? - gActiveBattler = gBankAttacker; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, to_heal, 4, &zero); - MarkBufferBankForExecution(gActiveBattler); - - gBattlescriptCurrInstr++; -} - -static void atkAF_cursetarget(void) -{ - if (gBattleMons[gBankTarget].status2 & STATUS2_CURSED || gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } - else - { - gBattleMons[gBankTarget].status2 |= STATUS2_CURSED; - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattlescriptCurrInstr += 5; - } -} - -static void atkB0_trysetspikes(void) -{ - u8 side = GetBattlerSide(gBankAttacker) ^ 1; - if (gSideTimers[side].spikesAmount == 3) - { - gSpecialStatuses[gBankAttacker].flag20 = 1; - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } - else - { - gSideAffecting[side] |= SIDE_STATUS_SPIKES; - gSideTimers[side].spikesAmount++; - gBattlescriptCurrInstr += 5; - } -} - -static void atkB1_setforesight(void) -{ - gBattleMons[gBankTarget].status2 |= STATUS2_FORESIGHT; - gBattlescriptCurrInstr++; -} - -static void atkB2_trysetperishsong(void) -{ - int not_affected_pokes = 0, i; - - for (i = 0; i < gBattlersCount; i++) - { - if (gStatuses3[i] & STATUS3_PERISH_SONG || gBattleMons[i].ability == ABILITY_SOUNDPROOF) - not_affected_pokes++; - else - { - gStatuses3[i] |= STATUS3_PERISH_SONG; - gDisableStructs[i].perishSongTimer1 = 3; - gDisableStructs[i].perishSongTimer2 = 3; - } - } - - PressurePPLoseOnUsingPerishSong(gBankAttacker); - if (not_affected_pokes == gBattlersCount) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr += 5; -} - -static void atkB3_rolloutdamagecalculation(void) -{ - if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - { - CancelMultiTurnMoves(gBankAttacker); - gBattlescriptCurrInstr = BattleScript_MoveMissedPause; - } - else - { - int i; - if (!(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) //first hit - { - gDisableStructs[gBankAttacker].rolloutTimer1 = 5; - gDisableStructs[gBankAttacker].rolloutTimer2 = 5; - gBattleMons[gBankAttacker].status2 |= STATUS2_MULTIPLETURNS; - gLockedMoves[gBankAttacker] = gCurrentMove; - } - if (--gDisableStructs[gBankAttacker].rolloutTimer1 == 0) - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_MULTIPLETURNS); - - gDynamicBasePower = gBattleMoves[gCurrentMove].power; - for (i = 1; i < (5 - gDisableStructs[gBankAttacker].rolloutTimer1); i++) - gDynamicBasePower *= 2; - - if (gBattleMons[gBankAttacker].status2 & STATUS2_DEFENSE_CURL) - gDynamicBasePower *= 2; - - gBattlescriptCurrInstr++; - } -} - -static void atkB4_jumpifconfusedandstatmaxed(void) -{ - if (gBattleMons[gBankTarget].status2 & STATUS2_CONFUSION && gBattleMons[gBankTarget].statStages[T2_READ_8(gBattlescriptCurrInstr + 1)] == 0xC) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; -} - -static void atkB5_furycuttercalc(void) -{ - if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - { - gDisableStructs[gBankAttacker].furyCutterCounter = 0; - gBattlescriptCurrInstr = BattleScript_MoveMissedPause; - } - else - { - int i; - - if (gDisableStructs[gBankAttacker].furyCutterCounter != 5) - gDisableStructs[gBankAttacker].furyCutterCounter++; - - gDynamicBasePower = gBattleMoves[gCurrentMove].power; - for (i = 1; i < gDisableStructs[gBankAttacker].furyCutterCounter; i++) - gDynamicBasePower *= 2; - - gBattlescriptCurrInstr++; - } -} - -static void atkB6_happinesstodamagecalculation(void) -{ - if (gBattleMoves[gCurrentMove].effect == EFFECT_RETURN) - gDynamicBasePower = 10 * (gBattleMons[gBankAttacker].friendship) / 25; - else //EFFECT_FRUSTRATION - gDynamicBasePower = 10 * (255 - gBattleMons[gBankAttacker].friendship) / 25; - gBattlescriptCurrInstr++; -} - -static void atkB7_presentdamagecalculation(void) -{ - s32 rand = Random() & 0xFF; - if (rand < 102) - gDynamicBasePower = 40; - else if (rand < 178) - gDynamicBasePower = 80; - else if (rand < 204) - gDynamicBasePower = 120; - else - { - gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 4; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - } - if (rand < 204) - gBattlescriptCurrInstr = BattleScript_HitFromCritCalc; - else if (gBattleMons[gBankTarget].maxHP == gBattleMons[gBankTarget].hp) - gBattlescriptCurrInstr = BattleScript_AlreadyAtFullHp; - else - { - //gMoveResultFlags &= ~(MOVE_RESULT_DOESNT_AFFECT_FOE); only in Emerald - gBattlescriptCurrInstr = BattleScript_PresentHealTarget; - } -} - -static void atkB8_setsafeguard(void) -{ - if (gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] & SIDE_STATUS_SAFEGUARD) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - else - { - gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] |= SIDE_STATUS_SAFEGUARD; - gSideTimers[GetBattlerPosition(gBankAttacker) & 1].safeguardTimer = 5; - gBattleCommunication[MULTISTRING_CHOOSER] = 5; - } - gBattlescriptCurrInstr++; -} - -static void atkB9_magnitudedamagecalculation(void) -{ - s32 magnitude = Random() % 100; - if (magnitude < 5) - { - gDynamicBasePower = 10; - magnitude = 4; - } - else if (magnitude < 15) - { - gDynamicBasePower = 30; - magnitude = 5; - } - else if (magnitude < 35) - { - gDynamicBasePower = 50; - magnitude = 6; - } - else if (magnitude < 65) - { - gDynamicBasePower = 70; - magnitude = 7; - } - else if (magnitude < 85) - { - gDynamicBasePower = 90; - magnitude = 8; - } - else if (magnitude < 95) - { - gDynamicBasePower = 110; - magnitude = 9; - } - else - { - gDynamicBasePower = 150; - magnitude = 10; - } - - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 1; - gBattleTextBuff1[2] = 1; - gBattleTextBuff1[3] = 2; - gBattleTextBuff1[4] = magnitude; - gBattleTextBuff1[5] = 0xFF; - - for (gBankTarget = 0; gBankTarget < gBattlersCount; gBankTarget++) - { - if (gBankTarget == gBankAttacker) - continue; - if (!(gAbsentBattlerFlags & gBitTable[gBankTarget])) //a valid target was found - break; - } - gBattlescriptCurrInstr++; -} - -static void atkBA_jumpifnopursuitswitchdmg(void) -{ - if (gMultiHitCounter == 1) - { - if (GetBattlerSide(gBankAttacker) == 0) - gBankTarget = GetBattlerAtPosition(1); - else - gBankTarget = GetBattlerAtPosition(0); - } - else - { - if (GetBattlerSide(gBankAttacker) == 0) - gBankTarget = GetBattlerAtPosition(3); - else - gBankTarget = GetBattlerAtPosition(2); - } - - if (gActionForBanks[gBankTarget] == 0 && gBankAttacker == ewram16010arr(gBankTarget) && !(gBattleMons[gBankTarget].status1 & (STATUS_SLEEP | STATUS_FREEZE)) - && gBattleMons[gBankAttacker].hp && !gDisableStructs[gBankTarget].truantCounter && gChosenMovesByBanks[gBankTarget] == MOVE_PURSUIT) - { - int i; - for (i = 0; i < gBattlersCount; i++) - { - if (gBanksByTurnOrder[i] == gBankTarget) - gActionsByTurnOrder[i] = 11; - } - gCurrentMove = MOVE_PURSUIT; - gBattlescriptCurrInstr += 5; - gBattleStruct->animTurn = 1; - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - } - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atkBB_setsunny(void) -{ - if (gBattleWeather & WEATHER_SUN_ANY) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - } - else - { - gBattleWeather = WEATHER_SUN_TEMPORARY; - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - gWishFutureKnock.weatherDuration = 5; - } - gBattlescriptCurrInstr++; -} - -static void atkBC_maxattackhalvehp(void) //belly drum -{ - u32 half_hp = gBattleMons[gBankAttacker].maxHP / 2; - if (!(gBattleMons[gBankAttacker].maxHP / 2)) - half_hp = 1; - - if (gBattleMons[gBankAttacker].statStages[STAT_STAGE_ATK] < 12 && gBattleMons[gBankAttacker].hp > half_hp) - { - gBattleMons[gBankAttacker].statStages[STAT_STAGE_ATK] = 12; - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } -} - -static void atkBD_copyfoestats(void) //psych up -{ - int i; - for (i = 0; i < 8; i++) - { - gBattleMons[gBankAttacker].statStages[i] = gBattleMons[gBankTarget].statStages[i]; - } - gBattlescriptCurrInstr += 5; //why not 1? possible unused fail possibility? -} - -static void atkBE_rapidspinfree(void) //rapid spin -{ - if (gBattleMons[gBankAttacker].status2 & STATUS2_WRAPPED) - { - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_WRAPPED); - gBankTarget = ewram16020arr(gBankAttacker); - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = ewram16004arr(0, gBankAttacker); - gBattleTextBuff1[3] = ewram16004arr(1, gBankAttacker); - gBattleTextBuff1[4] = 0xFF; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_WrapFree; - } - else if (gStatuses3[gBankAttacker] & STATUS3_LEECHSEED) - { - gStatuses3[gBankAttacker] &= ~(STATUS3_LEECHSEED); - gStatuses3[gBankAttacker] &= ~(STATUS3_LEECHSEED_BANK); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_LeechSeedFree; - } - else if (gSideAffecting[GetBattlerSide(gBankAttacker)] & SIDE_STATUS_SPIKES) - { - gSideAffecting[GetBattlerSide(gBankAttacker)] &= ~(SIDE_STATUS_SPIKES); - gSideTimers[GetBattlerSide(gBankAttacker)].spikesAmount = 0; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_SpikesFree; - } - else - gBattlescriptCurrInstr++; -} - -static void atkBF_setdefensecurlbit(void) -{ - gBattleMons[gBankAttacker].status2 |= STATUS2_DEFENSE_CURL; - gBattlescriptCurrInstr++; -} - -static void atkC0_recoverbasedonsunlight(void) -{ - gBankTarget = gBankAttacker; - if (gBattleMons[gBankAttacker].hp != gBattleMons[gBankAttacker].maxHP) - { - if (!gBattleWeather || !WEATHER_HAS_EFFECT) - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; - else if (gBattleWeather & WEATHER_SUN_ANY) - gBattleMoveDamage = 20 * gBattleMons[gBankAttacker].maxHP / 30; - else //not sunny weather - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 4; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - gBattlescriptCurrInstr += 5; - } - else - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } -} - -static void atkC1_hiddenpowercalc(void) -{ - u8 power = ((gBattleMons[gBankAttacker].hpIV & 2) >> 1) | - ((gBattleMons[gBankAttacker].attackIV & 2)) | - ((gBattleMons[gBankAttacker].defenseIV & 2) << 1) | - ((gBattleMons[gBankAttacker].speedIV & 2) << 2) | - ((gBattleMons[gBankAttacker].spAttackIV & 2) << 3) | - ((gBattleMons[gBankAttacker].spDefenseIV & 2) << 4); - u8 type = ((gBattleMons[gBankAttacker].hpIV & 1)) | - ((gBattleMons[gBankAttacker].attackIV & 1) << 1) | - ((gBattleMons[gBankAttacker].defenseIV & 1) << 2) | - ((gBattleMons[gBankAttacker].speedIV & 1) << 3) | - ((gBattleMons[gBankAttacker].spAttackIV & 1) << 4) | - ((gBattleMons[gBankAttacker].spDefenseIV & 1) << 5); - - gDynamicBasePower = 30 + (power * 40 / 63); - - gBattleStruct->dynamicMoveType = ((type * 15) / 63) + 1; - if (gBattleStruct->dynamicMoveType >= TYPE_MYSTERY) - gBattleStruct->dynamicMoveType++; - - gBattleStruct->dynamicMoveType |= 0xC0; - - gBattlescriptCurrInstr++; -} - -static void atkC2_selectfirstvalidtarget(void) -{ - for (gBankTarget = 0; gBankTarget < gBattlersCount; gBankTarget++) - { - if (gBankTarget == gBankAttacker) - continue; - if (!(gAbsentBattlerFlags & gBitTable[gBankTarget])) - break; - } - gBattlescriptCurrInstr++; -} - -static void atkC3_trysetfutureattack(void) -{ - if (gWishFutureKnock.futureSightCounter[gBankTarget] != 0) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } - else - { - gWishFutureKnock.futureSightMove[gBankTarget] = gCurrentMove; - gWishFutureKnock.futureSightAttacker[gBankTarget] = gBankAttacker; - gWishFutureKnock.futureSightCounter[gBankTarget] = 3; - gWishFutureKnock.futureSightDmg[gBankTarget] = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, - gSideAffecting[GetBattlerPosition(gBankTarget) & 1], 0, - 0, gBankAttacker, gBankTarget); - - if (gProtectStructs[gBankAttacker].helpingHand) - gWishFutureKnock.futureSightDmg[gBankTarget] = gWishFutureKnock.futureSightDmg[gBankTarget] * 15 / 10; - - if (gCurrentMove == MOVE_DOOM_DESIRE) - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - - gBattlescriptCurrInstr += 5; - } -} - -#ifdef NONMATCHING -static void atkC4_trydobeatup(void) -{ - register struct Pokemon* party asm("r7"); - if (GetBattlerSide(gBankAttacker) == 0) - party = gPlayerParty; - else - party = gEnemyParty; - - if (gBattleMons[gBankTarget].hp == 0) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - { - while (gBattleCommunication[0] < 6) - { - if (GetMonData(&party[gBattleCommunication[0]], MON_DATA_HP) && GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2) - && GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2) != SPECIES_EGG && !GetMonData(&party[gBattleCommunication[0]], MON_DATA_STATUS)) - break; - gBattleCommunication[0]++; - } - if (gBattleCommunication[0] < 6) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 4; - gBattleTextBuff1[2] = gBankAttacker; - gBattleTextBuff1[3] = gBattleCommunication[0]; - gBattleTextBuff1[4] = 0xFF; - gBattlescriptCurrInstr += 9; - - gBattleMoveDamage = gBaseStats[GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES)].baseAttack; - gBattleMoveDamage *= gBattleMoves[gCurrentMove].power; - gBattleMoveDamage *= (GetMonData(&party[gBattleCommunication[0]], MON_DATA_LEVEL) * 2 / 5 + 2); - gBattleMoveDamage /= gBaseStats[gBattleMons[gBankTarget].species].baseDefense; - gBattleMoveDamage = (gBattleMoveDamage / 50) + 2; - if (gProtectStructs[gBankAttacker].helpingHand) - gBattleMoveDamage = gBattleMoveDamage * 15 / 10; - - gBattleCommunication[0]++; - } - else if (gBattleCommunication[0] != 0) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 5); - } -} -#else -NAKED -static void atkC4_trydobeatup(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r9\n\ - mov r6, r8\n\ - push {r6,r7}\n\ - ldr r0, _08029A8C @ =gBankAttacker\n\ - ldrb r0, [r0]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - ldr r7, _08029A90 @ =gEnemyParty\n\ - cmp r0, 0\n\ - bne _08029A62\n\ - ldr r7, _08029A94 @ =gPlayerParty\n\ -_08029A62:\n\ - ldr r2, _08029A98 @ =gBattleMons\n\ - ldr r0, _08029A9C @ =gBankTarget\n\ - ldrb r1, [r0]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r2\n\ - ldrh r0, [r0, 0x28]\n\ - cmp r0, 0\n\ - bne _08029AA4\n\ - ldr r3, _08029AA0 @ =gBattlescriptCurrInstr\n\ - ldr r2, [r3]\n\ - ldrb r1, [r2, 0x1]\n\ - ldrb r0, [r2, 0x2]\n\ - lsls r0, 8\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 16\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x4]\n\ - b _08029C40\n\ - .align 2, 0\n\ -_08029A8C: .4byte gBankAttacker\n\ -_08029A90: .4byte gEnemyParty\n\ -_08029A94: .4byte gPlayerParty\n\ -_08029A98: .4byte gBattleMons\n\ -_08029A9C: .4byte gBankTarget\n\ -_08029AA0: .4byte gBattlescriptCurrInstr\n\ -_08029AA4:\n\ - ldr r6, _08029BE0 @ =gBattleCommunication\n\ - ldrb r0, [r6]\n\ - mov r8, r0\n\ - cmp r0, 0x5\n\ - bls _08029AB0\n\ - b _08029C0C\n\ -_08029AB0:\n\ - adds r4, r6, 0\n\ - movs r5, 0x64\n\ -_08029AB4:\n\ - ldrb r0, [r4]\n\ - muls r0, r5\n\ - adds r0, r7, r0\n\ - movs r1, 0x39\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _08029AF8\n\ - ldrb r0, [r6]\n\ - muls r0, r5\n\ - adds r0, r7, r0\n\ - movs r1, 0x41\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _08029AF8\n\ - ldrb r0, [r4]\n\ - muls r0, r5\n\ - adds r0, r7, r0\n\ - movs r1, 0x41\n\ - bl GetMonData\n\ - movs r1, 0xCE\n\ - lsls r1, 1\n\ - cmp r0, r1\n\ - beq _08029AF8\n\ - ldrb r0, [r4]\n\ - muls r0, r5\n\ - adds r0, r7, r0\n\ - movs r1, 0x37\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _08029B08\n\ -_08029AF8:\n\ - ldrb r0, [r4]\n\ - adds r0, 0x1\n\ - strb r0, [r4]\n\ - adds r6, r4, 0\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0x5\n\ - bls _08029AB4\n\ -_08029B08:\n\ - ldr r1, _08029BE0 @ =gBattleCommunication\n\ - mov r9, r1\n\ - ldrb r2, [r1]\n\ - cmp r2, 0x5\n\ - bhi _08029C0C\n\ - ldr r1, _08029BE4 @ =gBattleTextBuff1\n\ - movs r0, 0xFD\n\ - strb r0, [r1]\n\ - movs r0, 0x4\n\ - strb r0, [r1, 0x1]\n\ - ldr r6, _08029BE8 @ =gBankAttacker\n\ - ldrb r0, [r6]\n\ - strb r0, [r1, 0x2]\n\ - strb r2, [r1, 0x3]\n\ - movs r0, 0xFF\n\ - strb r0, [r1, 0x4]\n\ - ldr r1, _08029BEC @ =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x9\n\ - str r0, [r1]\n\ - ldr r2, _08029BF0 @ =gBattleMoveDamage\n\ - mov r8, r2\n\ - ldr r5, _08029BF4 @ =gBaseStats\n\ - mov r1, r9\n\ - ldrb r0, [r1]\n\ - movs r4, 0x64\n\ - muls r0, r4\n\ - adds r0, r7, r0\n\ - movs r1, 0xB\n\ - bl GetMonData\n\ - lsls r1, r0, 3\n\ - subs r1, r0\n\ - lsls r1, 2\n\ - adds r1, r5\n\ - ldrb r3, [r1, 0x1]\n\ - mov r2, r8\n\ - str r3, [r2]\n\ - ldr r2, _08029BF8 @ =gBattleMoves\n\ - ldr r0, _08029BFC @ =gCurrentMove\n\ - ldrh r1, [r0]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldrb r0, [r0, 0x1]\n\ - muls r0, r3\n\ - mov r1, r8\n\ - str r0, [r1]\n\ - mov r2, r9\n\ - ldrb r0, [r2]\n\ - muls r0, r4\n\ - adds r0, r7, r0\n\ - movs r1, 0x38\n\ - bl GetMonData\n\ - lsls r0, 1\n\ - movs r1, 0x5\n\ - bl __udivsi3\n\ - adds r0, 0x2\n\ - mov r2, r8\n\ - ldr r1, [r2]\n\ - muls r0, r1\n\ - str r0, [r2]\n\ - ldr r3, _08029C00 @ =gBattleMons\n\ - ldr r1, _08029C04 @ =gBankTarget\n\ - ldrb r2, [r1]\n\ - movs r1, 0x58\n\ - muls r1, r2\n\ - adds r1, r3\n\ - ldrh r2, [r1]\n\ - lsls r1, r2, 3\n\ - subs r1, r2\n\ - lsls r1, 2\n\ - adds r1, r5\n\ - ldrb r1, [r1, 0x2]\n\ - bl __divsi3\n\ - mov r1, r8\n\ - str r0, [r1]\n\ - movs r1, 0x32\n\ - bl __divsi3\n\ - adds r2, r0, 0x2\n\ - mov r0, r8\n\ - str r2, [r0]\n\ - ldr r1, _08029C08 @ =gProtectStructs\n\ - ldrb r0, [r6]\n\ - lsls r0, 4\n\ - adds r0, r1\n\ - ldrb r0, [r0]\n\ - lsls r0, 28\n\ - cmp r0, 0\n\ - bge _08029BD4\n\ - lsls r0, r2, 4\n\ - subs r0, r2\n\ - movs r1, 0xA\n\ - bl __divsi3\n\ - mov r1, r8\n\ - str r0, [r1]\n\ -_08029BD4:\n\ - mov r2, r9\n\ - ldrb r0, [r2]\n\ - adds r0, 0x1\n\ - strb r0, [r2]\n\ - b _08029C46\n\ - .align 2, 0\n\ -_08029BE0: .4byte gBattleCommunication\n\ -_08029BE4: .4byte gBattleTextBuff1\n\ -_08029BE8: .4byte gBankAttacker\n\ -_08029BEC: .4byte gBattlescriptCurrInstr\n\ -_08029BF0: .4byte gBattleMoveDamage\n\ -_08029BF4: .4byte gBaseStats\n\ -_08029BF8: .4byte gBattleMoves\n\ -_08029BFC: .4byte gCurrentMove\n\ -_08029C00: .4byte gBattleMons\n\ -_08029C04: .4byte gBankTarget\n\ -_08029C08: .4byte gProtectStructs\n\ -_08029C0C:\n\ - mov r0, r8\n\ - cmp r0, 0\n\ - beq _08029C2C\n\ - ldr r3, _08029C28 @ =gBattlescriptCurrInstr\n\ - ldr r2, [r3]\n\ - ldrb r1, [r2, 0x1]\n\ - ldrb r0, [r2, 0x2]\n\ - lsls r0, 8\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 16\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x4]\n\ - b _08029C40\n\ - .align 2, 0\n\ -_08029C28: .4byte gBattlescriptCurrInstr\n\ -_08029C2C:\n\ - ldr r3, _08029C54 @ =gBattlescriptCurrInstr\n\ - ldr r2, [r3]\n\ - ldrb r1, [r2, 0x5]\n\ - ldrb r0, [r2, 0x6]\n\ - lsls r0, 8\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x7]\n\ - lsls r0, 16\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x8]\n\ -_08029C40:\n\ - lsls r0, 24\n\ - orrs r1, r0\n\ - str r1, [r3]\n\ -_08029C46:\n\ - pop {r3,r4}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_08029C54: .4byte gBattlescriptCurrInstr\n\ - .syntax divided"); -} -#endif // NONMATCHING - -static void atkC5_setsemiinvulnerablebit(void) -{ - switch (gCurrentMove) - { - case MOVE_FLY: - case MOVE_BOUNCE: - gStatuses3[gBankAttacker] |= STATUS3_ON_AIR; - break; - case MOVE_DIG: - gStatuses3[gBankAttacker] |= STATUS3_UNDERGROUND; - break; - case MOVE_DIVE: - gStatuses3[gBankAttacker] |= STATUS3_UNDERWATER; - break; - } - gBattlescriptCurrInstr++; -} - -static void atkC6_clearsemiinvulnerablebit(void) -{ - switch (gCurrentMove) - { - case MOVE_FLY: - case MOVE_BOUNCE: - gStatuses3[gBankAttacker] &= ~STATUS3_ON_AIR; - break; - case MOVE_DIG: - gStatuses3[gBankAttacker] &= ~STATUS3_UNDERGROUND; - break; - case MOVE_DIVE: - gStatuses3[gBankAttacker] &= ~STATUS3_UNDERWATER; - break; - } - gBattlescriptCurrInstr++; -} - -static void atkC7_setminimize(void) -{ - if (gHitMarker & HITMARKER_OBEYS) - gStatuses3[gBankAttacker] |= STATUS3_MINIMIZED; - gBattlescriptCurrInstr++; -} - -static void atkC8_sethail(void) -{ - if (gBattleWeather & WEATHER_HAIL) - { - gMoveResultFlags |= MOVE_RESULT_MISSED; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - } - else - { - gBattleWeather = WEATHER_HAIL; - gBattleCommunication[MULTISTRING_CHOOSER] = 5; - gWishFutureKnock.weatherDuration = 5; - } - gBattlescriptCurrInstr++; -} - -static void atkC9_jumpifattackandspecialattackcannotfall(void) //memento -{ - if (gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] == 0 - && gBattleMons[gBankTarget].statStages[STAT_STAGE_SPATK] == 0 - && gBattleCommunication[6] != 1) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - { - gActiveBattler = gBankAttacker; - gBattleMoveDamage = gBattleMons[gActiveBattler].hp; - EmitHealthBarUpdate(0, 0x7FFF); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 5; - } -} - -static void atkCA_setforcedtarget(void) //follow me -{ - gSideTimers[GetBattlerSide(gBankAttacker)].followmeTimer = 1; - gSideTimers[GetBattlerSide(gBankAttacker)].followmeTarget = gBankAttacker; - gBattlescriptCurrInstr++; -} - -static void atkCB_setcharge(void) -{ - gStatuses3[gBankAttacker] |= STATUS3_CHARGED_UP; - gDisableStructs[gBankAttacker].chargeTimer1 = 2; - gDisableStructs[gBankAttacker].chargeTimer2 = 2; - gBattlescriptCurrInstr++; -} - -static void atkCC_callterrainattack(void) //nature power -{ - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gCurrentMove = sNaturePowerMoves[gBattleTerrain]; - gBankTarget = GetMoveTarget(gCurrentMove, 0); - BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]); - gBattlescriptCurrInstr++; -} - -static void atkCD_cureifburnedparalysedorpoisoned(void) //refresh -{ - if (gBattleMons[gBankAttacker].status1 & (STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS | STATUS_TOXIC_POISON)) - { - gBattleMons[gBankAttacker].status1 = 0; - gBattlescriptCurrInstr += 5; - gActiveBattler = gBankAttacker; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); - MarkBufferBankForExecution(gActiveBattler); - } - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atkCE_settorment(void) -{ - if (gBattleMons[gBankTarget].status2 & STATUS2_TORMENT) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - { - gBattleMons[gBankTarget].status2 |= STATUS2_TORMENT; - gBattlescriptCurrInstr += 5; - } -} - -static void atkCF_jumpifnodamage(void) -{ - if (gProtectStructs[gBankAttacker].physicalDmg || gProtectStructs[gBankAttacker].specialDmg) - gBattlescriptCurrInstr += 5; - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atkD0_settaunt(void) -{ - if (gDisableStructs[gBankTarget].tauntTimer1 == 0) - { - gDisableStructs[gBankTarget].tauntTimer1 = 2; - gDisableStructs[gBankTarget].tauntTimer2 = 2; - gBattlescriptCurrInstr += 5; - } - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atkD1_trysethelpinghand(void) -{ - gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ 2); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gAbsentBattlerFlags & gBitTable[gBankTarget]) - && !gProtectStructs[gBankAttacker].helpingHand && !gProtectStructs[gBankTarget].helpingHand) - { - gProtectStructs[gBankTarget].helpingHand = 1; - gBattlescriptCurrInstr += 5; - } - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -#ifdef NONMATCHING -static void atkD2_tryswapitems(void) -{ - if ((GetBattlerSide(gBankAttacker) != 1 || gBattleTypeFlags & (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER) || gTrainerBattleOpponent == SECRET_BASE_OPPONENT)) - { - u8 side = GetBattlerSide(gBankAttacker); - if (gBattleTypeFlags) - } - - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -#else -NAKED -static void atkD2_tryswapitems(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x4\n\ - ldr r0, _0802A30C @ =gBankAttacker\n\ - ldrb r0, [r0]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0x1\n\ - bne _0802A24C\n\ - ldr r0, _0802A310 @ =gBattleTypeFlags\n\ - ldrh r1, [r0]\n\ - ldr r0, _0802A314 @ =0x00000902\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _0802A24C\n\ - ldr r0, _0802A318 @ =gTrainerBattleOpponent\n\ - ldrh r1, [r0]\n\ - movs r0, 0x80\n\ - lsls r0, 3\n\ - cmp r1, r0\n\ - bne _0802A2EE\n\ -_0802A24C:\n\ - ldr r4, _0802A30C @ =gBankAttacker\n\ - ldrb r0, [r4]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - lsrs r2, r0, 24\n\ - ldr r0, _0802A310 @ =gBattleTypeFlags\n\ - ldrh r1, [r0]\n\ - ldr r0, _0802A314 @ =0x00000902\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - bne _0802A290\n\ - ldr r0, _0802A318 @ =gTrainerBattleOpponent\n\ - ldrh r1, [r0]\n\ - movs r0, 0x80\n\ - lsls r0, 3\n\ - cmp r1, r0\n\ - beq _0802A290\n\ - ldr r0, _0802A31C @ =gWishFutureKnock\n\ - adds r0, 0x29\n\ - adds r0, r2, r0\n\ - ldrb r1, [r0]\n\ - ldr r3, _0802A320 @ =gBitTable\n\ - ldr r2, _0802A324 @ =gBattlerPartyIndexes\n\ - ldrb r0, [r4]\n\ - lsls r0, 1\n\ - adds r0, r2\n\ - ldrh r0, [r0]\n\ - lsls r0, 2\n\ - adds r0, r3\n\ - ldr r0, [r0]\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - bne _0802A2EE\n\ -_0802A290:\n\ - ldr r0, _0802A328 @ =gBattleMons\n\ - mov r9, r0\n\ - ldr r1, _0802A30C @ =gBankAttacker\n\ - ldrb r4, [r1]\n\ - movs r2, 0x58\n\ - mov r8, r2\n\ - mov r0, r8\n\ - muls r0, r4\n\ - mov r3, r9\n\ - adds r5, r0, r3\n\ - ldrh r3, [r5, 0x2E]\n\ - adds r1, r3, 0\n\ - cmp r1, 0\n\ - bne _0802A2BE\n\ - ldr r0, _0802A32C @ =gBankTarget\n\ - ldrb r0, [r0]\n\ - mov r2, r8\n\ - muls r2, r0\n\ - adds r0, r2, 0\n\ - add r0, r9\n\ - ldrh r0, [r0, 0x2E]\n\ - cmp r0, 0\n\ - beq _0802A2EE\n\ -_0802A2BE:\n\ - cmp r1, 0xAF\n\ - beq _0802A2EE\n\ - ldr r7, _0802A32C @ =gBankTarget\n\ - ldrb r0, [r7]\n\ - mov r1, r8\n\ - muls r1, r0\n\ - adds r0, r1, 0\n\ - mov r1, r9\n\ - adds r2, r0, r1\n\ - ldrh r1, [r2, 0x2E]\n\ - cmp r1, 0xAF\n\ - beq _0802A2EE\n\ - adds r0, r3, 0\n\ - subs r0, 0x79\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - cmp r0, 0xB\n\ - bls _0802A2EE\n\ - adds r0, r1, 0\n\ - subs r0, 0x79\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - cmp r0, 0xB\n\ - bhi _0802A334\n\ -_0802A2EE:\n\ - ldr r3, _0802A330 @ =gBattlescriptCurrInstr\n\ - ldr r2, [r3]\n\ - ldrb r1, [r2, 0x1]\n\ - ldrb r0, [r2, 0x2]\n\ - lsls r0, 8\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 16\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x4]\n\ - lsls r0, 24\n\ - orrs r1, r0\n\ - str r1, [r3]\n\ - b _0802A49A\n\ - .align 2, 0\n\ -_0802A30C: .4byte gBankAttacker\n\ -_0802A310: .4byte gBattleTypeFlags\n\ -_0802A314: .4byte 0x00000902\n\ -_0802A318: .4byte gTrainerBattleOpponent\n\ -_0802A31C: .4byte gWishFutureKnock\n\ -_0802A320: .4byte gBitTable\n\ -_0802A324: .4byte gBattlerPartyIndexes\n\ -_0802A328: .4byte gBattleMons\n\ -_0802A32C: .4byte gBankTarget\n\ -_0802A330: .4byte gBattlescriptCurrInstr\n\ -_0802A334:\n\ - adds r0, r2, 0\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x3C\n\ - bne _0802A36C\n\ - ldr r1, _0802A360 @ =gBattlescriptCurrInstr\n\ - ldr r0, _0802A364 @ =BattleScript_NoItemSteal\n\ - str r0, [r1]\n\ - ldr r1, _0802A368 @ =gLastUsedAbility\n\ - ldrb r0, [r7]\n\ - mov r2, r8\n\ - muls r2, r0\n\ - adds r0, r2, 0\n\ - add r0, r9\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - strb r0, [r1]\n\ - ldrb r0, [r7]\n\ - ldrb r1, [r1]\n\ - bl RecordAbilityBattle\n\ - b _0802A49A\n\ - .align 2, 0\n\ -_0802A360: .4byte gBattlescriptCurrInstr\n\ -_0802A364: .4byte BattleScript_NoItemSteal\n\ -_0802A368: .4byte gLastUsedAbility\n\ -_0802A36C:\n\ - lsls r0, r4, 1\n\ - ldr r4, _0802A458 @ =gSharedMem + 0x160F0\n\ - adds r6, r0, r4\n\ - ldrh r5, [r5, 0x2E]\n\ - mov r10, r5\n\ - strh r1, [r6]\n\ - ldr r3, _0802A45C @ =gBankAttacker\n\ - ldrb r0, [r3]\n\ - mov r1, r8\n\ - muls r1, r0\n\ - adds r0, r1, 0\n\ - add r0, r9\n\ - movs r1, 0\n\ - strh r1, [r0, 0x2E]\n\ - ldrb r0, [r7]\n\ - mov r2, r8\n\ - muls r2, r0\n\ - adds r0, r2, 0\n\ - add r0, r9\n\ - mov r3, r10\n\ - strh r3, [r0, 0x2E]\n\ - ldr r5, _0802A460 @ =gActiveBattler\n\ - ldr r1, _0802A45C @ =gBankAttacker\n\ - ldrb r0, [r1]\n\ - strb r0, [r5]\n\ - str r6, [sp]\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - movs r2, 0\n\ - movs r3, 0x2\n\ - bl EmitSetMonData\n\ - ldr r2, _0802A45C @ =gBankAttacker\n\ - ldrb r0, [r2]\n\ - bl MarkBufferBankForExecution\n\ - ldrb r0, [r7]\n\ - strb r0, [r5]\n\ - ldrb r0, [r7]\n\ - mov r3, r8\n\ - muls r3, r0\n\ - adds r0, r3, 0\n\ - mov r1, r9\n\ - adds r1, 0x2E\n\ - adds r0, r1\n\ - str r0, [sp]\n\ - movs r0, 0\n\ - movs r1, 0x2\n\ - movs r2, 0\n\ - movs r3, 0x2\n\ - bl EmitSetMonData\n\ - ldrb r0, [r7]\n\ - bl MarkBufferBankForExecution\n\ - ldr r0, _0802A464 @ =0xfffe9f10\n\ - adds r4, r0\n\ - ldrb r0, [r7]\n\ - lsls r0, 1\n\ - ldr r2, _0802A468 @ =0x000160e8\n\ - adds r0, r2\n\ - adds r0, r4\n\ - movs r1, 0\n\ - strb r1, [r0]\n\ - ldrb r0, [r7]\n\ - lsls r0, 1\n\ - ldr r1, _0802A46C @ =0x000160e9\n\ - adds r0, r1\n\ - adds r0, r4\n\ - movs r3, 0\n\ - strb r3, [r0]\n\ - ldr r3, _0802A45C @ =gBankAttacker\n\ - ldrb r0, [r3]\n\ - lsls r0, 1\n\ - adds r0, r2\n\ - adds r0, r4\n\ - movs r2, 0\n\ - strb r2, [r0]\n\ - ldrb r0, [r3]\n\ - lsls r0, 1\n\ - adds r0, r1\n\ - adds r0, r4\n\ - strb r2, [r0]\n\ - ldr r1, _0802A470 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x5\n\ - str r0, [r1]\n\ - ldr r1, _0802A474 @ =gBattleTextBuff1\n\ - movs r3, 0xFD\n\ - strb r3, [r1]\n\ - movs r2, 0xA\n\ - strb r2, [r1, 0x1]\n\ - ldrh r0, [r6]\n\ - strb r0, [r1, 0x2]\n\ - ldrh r0, [r6]\n\ - lsrs r0, 8\n\ - strb r0, [r1, 0x3]\n\ - movs r0, 0xFF\n\ - strb r0, [r1, 0x4]\n\ - ldr r1, _0802A478 @ =gBattleTextBuff2\n\ - strb r3, [r1]\n\ - strb r2, [r1, 0x1]\n\ - mov r3, r10\n\ - strb r3, [r1, 0x2]\n\ - mov r2, r10\n\ - lsrs r0, r2, 8\n\ - strb r0, [r1, 0x3]\n\ - movs r0, 0x1\n\ - negs r0, r0\n\ - strb r0, [r1, 0x4]\n\ - cmp r2, 0\n\ - beq _0802A480\n\ - ldrh r0, [r6]\n\ - cmp r0, 0\n\ - beq _0802A494\n\ - ldr r1, _0802A47C @ =gBattleCommunication\n\ - movs r0, 0x2\n\ - b _0802A498\n\ - .align 2, 0\n\ -_0802A458: .4byte gSharedMem + 0x160F0\n\ -_0802A45C: .4byte gBankAttacker\n\ -_0802A460: .4byte gActiveBattler\n\ -_0802A464: .4byte 0xfffe9f10\n\ -_0802A468: .4byte 0x000160e8\n\ -_0802A46C: .4byte 0x000160e9\n\ -_0802A470: .4byte gBattlescriptCurrInstr\n\ -_0802A474: .4byte gBattleTextBuff1\n\ -_0802A478: .4byte gBattleTextBuff2\n\ -_0802A47C: .4byte gBattleCommunication\n\ -_0802A480:\n\ - ldrh r0, [r6]\n\ - cmp r0, 0\n\ - beq _0802A494\n\ - ldr r0, _0802A490 @ =gBattleCommunication\n\ - movs r3, 0\n\ - strb r3, [r0, 0x5]\n\ - b _0802A49A\n\ - .align 2, 0\n\ -_0802A490: .4byte gBattleCommunication\n\ -_0802A494:\n\ - ldr r1, _0802A4AC @ =gBattleCommunication\n\ - movs r0, 0x1\n\ -_0802A498:\n\ - strb r0, [r1, 0x5]\n\ -_0802A49A:\n\ - add sp, 0x4\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_0802A4AC: .4byte gBattleCommunication\n\ - .syntax divided"); -} -#endif // NONMATCHING - -static void atkD3_trycopyability(void) //role play -{ - if (gBattleMons[gBankTarget].ability != 0 && gBattleMons[gBankTarget].ability != ABILITY_WONDER_GUARD) - { - gBattleMons[gBankAttacker].ability = gBattleMons[gBankTarget].ability; - gLastUsedAbility = gBattleMons[gBankTarget].ability; - gBattlescriptCurrInstr += 5; - } - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atkD4_trywish(void) -{ - switch (T2_READ_8(gBattlescriptCurrInstr + 1)) - { - case 0: //use wish - if (gWishFutureKnock.wishCounter[gBankAttacker] == 0) - { - gWishFutureKnock.wishCounter[gBankAttacker] = 2; - gWishFutureKnock.wishUserID[gBankAttacker] = gBattlerPartyIndexes[gBankAttacker]; - gBattlescriptCurrInstr += 6; - } - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - break; - case 1: //heal effect - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 4; - gBattleTextBuff1[2] = gBankTarget; - gBattleTextBuff1[3] = gWishFutureKnock.wishUserID[gBankTarget]; - gBattleTextBuff1[4] = 0xFF; - gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; - break; - } -} - -static void atkD5_trysetroots(void) //ingrain -{ - if (gStatuses3[gBankAttacker] & STATUS3_ROOTED) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - { - gStatuses3[gBankAttacker] |= STATUS3_ROOTED; - gBattlescriptCurrInstr += 5; - } -} - -static void atkD6_doubledamagedealtifdamaged(void) -{ - if ((gProtectStructs[gBankAttacker].physicalDmg && gProtectStructs[gBankAttacker].physicalBank == gBankTarget) - || (gProtectStructs[gBankAttacker].specialDmg && gProtectStructs[gBankAttacker].specialBank == gBankTarget)) - gBattleStruct->dmgMultiplier = 2; - gBattlescriptCurrInstr++; -} - -static void atkD7_setyawn(void) -{ - if (gStatuses3[gBankTarget] & STATUS3_YAWN || (u8) gBattleMons[gBankTarget].status1) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - { - gStatuses3[gBankTarget] |= 0x1000; - gBattlescriptCurrInstr += 5; - } -} - -static void atkD8_setdamagetohealthdifference(void) -{ - if (gBattleMons[gBankTarget].hp <= gBattleMons[gBankAttacker].hp) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } - else - { - gBattleMoveDamage = gBattleMons[gBankTarget].hp - gBattleMons[gBankAttacker].hp; - gBattlescriptCurrInstr += 5; - } -} - -static void atkD9_scaledamagebyhealthratio(void) -{ - if (gDynamicBasePower == 0) - { - u8 power = gBattleMoves[gCurrentMove].power; - gDynamicBasePower = gBattleMons[gBankAttacker].hp * power / gBattleMons[gBankAttacker].maxHP; - if (gDynamicBasePower == 0) - gDynamicBasePower = 1; - } - gBattlescriptCurrInstr++; -} - -static void atkDA_tryswapabilities(void) -{ - if ((gBattleMons[gBankAttacker].ability == 0 && gBattleMons[gBankTarget].ability == 0) - || gBattleMons[gBankAttacker].ability == ABILITY_WONDER_GUARD || gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD - || gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - { - u8 atk_ability = gBattleMons[gBankAttacker].ability; - gBattleMons[gBankAttacker].ability = gBattleMons[gBankTarget].ability; - gBattleMons[gBankTarget].ability = atk_ability; - gBattlescriptCurrInstr += 5; - } -} - -static void atkDB_tryimprision(void) -{ - u8 r8 = 0; - if ((gStatuses3[gBankAttacker] & STATUS3_IMPRISIONED)) - { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } - else - { - u8 bank; - PressurePPLoseOnUsingImprision(gBankAttacker); - for (bank = 0; bank < gBattlersCount; bank++) - { - if (r8 != GetBattlerSide(bank)) - { - int j; - for (j = 0; j < 4; j++) - { - int k; - for (k = 0; k < 4; k++) - { - if (gBattleMons[gBankAttacker].moves[j] == gBattleMons[bank].moves[k] && gBattleMons[gBankAttacker].moves[j]) - break; - } - if (k != 4) - break; - } - if (j != 4) - { - gStatuses3[gBankAttacker] |= STATUS3_IMPRISIONED; - gBattlescriptCurrInstr += 5; - break; - } - } - } - if (bank == gBattlersCount) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } -} - -static void atkDC_trysetgrudge(void) -{ - if (gStatuses3[gBankAttacker] & STATUS3_GRUDGE) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - { - gStatuses3[gBankAttacker] |= STATUS3_GRUDGE; - gBattlescriptCurrInstr += 5; - } -} - -static void atkDD_weightdamagecalculation(void) -{ - int i; - for (i = 0; sWeightToDamageTable[i] != 0xFFFF; i += 2) - { - if (sWeightToDamageTable[i] > GetPokedexHeightWeight(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), 1)) - break; - } - if (sWeightToDamageTable[i] != 0xFFFF) - gDynamicBasePower = sWeightToDamageTable[i + 1]; - else - gDynamicBasePower = 120; - gBattlescriptCurrInstr++; -} - -#ifdef NONMATCHING -static void atkDE_asistattackselect(void) -{ - u32 chooseable_moves_no = 0; - struct Pokemon* party; - int i, j; - u16* chooseable_moves; - if (GetBattlerPosition(gBankAttacker) & 1) - party = gEnemyParty; - else - party = gPlayerParty; - - for (i = 0; i < 6; i++) - { - if (i == gBattlerPartyIndexes[gBankAttacker]) - break; - if (!GetMonData(&party[i], MON_DATA_SPECIES2) || GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_EGG) - break; - chooseable_moves = &gBattleStruct->assistMove[chooseable_moves_no]; - for (j = 0; j < 4; j++) - { - int k; - u16 move = GetMonData(&party[i], MON_DATA_MOVE1 + i); - if (IsMoveUnchoosable(move)) - break; - //sMovesForbiddenToCopy[k] - for (k = 0; ;k++) - { - if (sMovesForbiddenToCopy[k] == 0xFFFF) - { - if (move) - { - *chooseable_moves = move; - chooseable_moves++; - chooseable_moves_no++; - } - break; - } - if (sMovesForbiddenToCopy[k] == move) - break; - } - } - } - if (chooseable_moves_no) - { - gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); - gRandomMove = gBattleStruct->assistMove[Random() % chooseable_moves_no]; - gBankTarget = GetMoveTarget(gRandomMove, 0); - gBattlescriptCurrInstr += 5; - } - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -#else -NAKED -static void atkDE_asistattackselect(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x8\n\ - movs r0, 0\n\ - mov r10, r0\n\ - ldr r0, _0802AB9C @ =gBankAttacker\n\ - ldrb r0, [r0]\n\ - bl GetBattlerPosition\n\ - movs r1, 0x1\n\ - ands r1, r0\n\ - ldr r0, _0802ABA0 @ =gPlayerParty\n\ - str r0, [sp]\n\ - cmp r1, 0\n\ - beq _0802AAAC\n\ - ldr r1, _0802ABA4 @ =gEnemyParty\n\ - str r1, [sp]\n\ -_0802AAAC:\n\ - movs r2, 0\n\ -_0802AAAE:\n\ - ldr r1, _0802ABA8 @ =gBattlerPartyIndexes\n\ - ldr r0, _0802AB9C @ =gBankAttacker\n\ - ldrb r0, [r0]\n\ - lsls r0, 1\n\ - adds r0, r1\n\ - adds r1, r2, 0x1\n\ - str r1, [sp, 0x4]\n\ - ldrh r0, [r0]\n\ - cmp r2, r0\n\ - beq _0802AB54\n\ - movs r0, 0x64\n\ - adds r6, r2, 0\n\ - muls r6, r0\n\ - ldr r0, [sp]\n\ - adds r4, r0, r6\n\ - adds r0, r4, 0\n\ - movs r1, 0x41\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _0802AB54\n\ - adds r0, r4, 0\n\ - movs r1, 0x41\n\ - bl GetMonData\n\ - movs r1, 0xCE\n\ - lsls r1, 1\n\ - cmp r0, r1\n\ - beq _0802AB54\n\ - movs r5, 0\n\ - ldr r1, _0802ABAC @ =0x0000ffff\n\ - mov r8, r1\n\ - mov r9, r6\n\ - mov r1, r10\n\ - lsls r0, r1, 1\n\ - ldr r1, _0802ABB0 @ =gSharedMem + 0x16024\n\ - adds r6, r0, r1\n\ -_0802AAF8:\n\ - movs r7, 0\n\ - adds r1, r5, 0\n\ - adds r1, 0xD\n\ - ldr r0, [sp]\n\ - add r0, r9\n\ - bl GetMonData\n\ - lsls r0, 16\n\ - lsrs r4, r0, 16\n\ - adds r0, r4, 0\n\ - bl IsMoveUnchoosable\n\ - lsls r0, 24\n\ - adds r1, r5, 0x1\n\ - cmp r0, 0\n\ - bne _0802AB4E\n\ - ldr r0, _0802ABB4 @ =sMovesForbiddenToCopy\n\ - ldrh r2, [r0]\n\ - adds r3, r0, 0\n\ - cmp r2, r8\n\ - beq _0802AB42\n\ - cmp r4, r2\n\ - beq _0802AB38\n\ - ldr r5, _0802ABAC @ =0x0000ffff\n\ - adds r2, r3, 0\n\ -_0802AB2A:\n\ - adds r2, 0x2\n\ - adds r7, 0x1\n\ - ldrh r0, [r2]\n\ - cmp r0, r5\n\ - beq _0802AB42\n\ - cmp r4, r0\n\ - bne _0802AB2A\n\ -_0802AB38:\n\ - lsls r0, r7, 1\n\ - adds r0, r3\n\ - ldrh r0, [r0]\n\ - cmp r0, r8\n\ - bne _0802AB4E\n\ -_0802AB42:\n\ - cmp r4, 0\n\ - beq _0802AB4E\n\ - strh r4, [r6]\n\ - adds r6, 0x2\n\ - movs r0, 0x1\n\ - add r10, r0\n\ -_0802AB4E:\n\ - adds r5, r1, 0\n\ - cmp r5, 0x3\n\ - ble _0802AAF8\n\ -_0802AB54:\n\ - ldr r2, [sp, 0x4]\n\ - cmp r2, 0x5\n\ - ble _0802AAAE\n\ - mov r1, r10\n\ - cmp r1, 0\n\ - beq _0802ABCC\n\ - ldr r2, _0802ABB8 @ =gHitMarker\n\ - ldr r0, [r2]\n\ - ldr r1, _0802ABBC @ =0xfffffbff\n\ - ands r0, r1\n\ - str r0, [r2]\n\ - ldr r4, _0802ABC0 @ =gRandomMove\n\ - bl Random\n\ - movs r1, 0xFF\n\ - ands r1, r0\n\ - mov r0, r10\n\ - muls r0, r1\n\ - asrs r0, 8\n\ - lsls r0, 1\n\ - ldr r1, _0802ABB0 @ =gSharedMem + 0x16024\n\ - adds r0, r1\n\ - ldrh r0, [r0]\n\ - strh r0, [r4]\n\ - ldrh r0, [r4]\n\ - movs r1, 0\n\ - bl GetMoveTarget\n\ - ldr r1, _0802ABC4 @ =gBankTarget\n\ - strb r0, [r1]\n\ - ldr r1, _0802ABC8 @ =gBattlescriptCurrInstr\n\ - ldr r0, [r1]\n\ - adds r0, 0x5\n\ - str r0, [r1]\n\ - b _0802ABE6\n\ - .align 2, 0\n\ -_0802AB9C: .4byte gBankAttacker\n\ -_0802ABA0: .4byte gPlayerParty\n\ -_0802ABA4: .4byte gEnemyParty\n\ -_0802ABA8: .4byte gBattlerPartyIndexes\n\ -_0802ABAC: .4byte 0x0000ffff\n\ -_0802ABB0: .4byte gSharedMem + 0x16024\n\ -_0802ABB4: .4byte sMovesForbiddenToCopy\n\ -_0802ABB8: .4byte gHitMarker\n\ -_0802ABBC: .4byte 0xfffffbff\n\ -_0802ABC0: .4byte gRandomMove\n\ -_0802ABC4: .4byte gBankTarget\n\ -_0802ABC8: .4byte gBattlescriptCurrInstr\n\ -_0802ABCC:\n\ - ldr r3, _0802ABF8 @ =gBattlescriptCurrInstr\n\ - ldr r2, [r3]\n\ - ldrb r1, [r2, 0x1]\n\ - ldrb r0, [r2, 0x2]\n\ - lsls r0, 8\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x3]\n\ - lsls r0, 16\n\ - orrs r1, r0\n\ - ldrb r0, [r2, 0x4]\n\ - lsls r0, 24\n\ - orrs r1, r0\n\ - str r1, [r3]\n\ -_0802ABE6:\n\ - add sp, 0x8\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_0802ABF8: .4byte gBattlescriptCurrInstr\n\ - .syntax divided"); -} - -#endif // NONMATCHING - -static void atkDF_trysetmagiccoat(void) -{ - gBankTarget = gBankAttacker; - gSpecialStatuses[gBankAttacker].flag20 = 1; - if (gCurrentTurnActionNumber == gBattlersCount - 1) //last turn - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - { - gProtectStructs[gBankAttacker].bounceMove = 1; - gBattlescriptCurrInstr += 5; - } -} - -static void atkE0_trysetsnatch(void) -{ - gSpecialStatuses[gBankAttacker].flag20 = 1; - if (gCurrentTurnActionNumber == gBattlersCount - 1) //last turn - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - { - gProtectStructs[gBankAttacker].stealMove = 1; - gBattlescriptCurrInstr += 5; - } -} - -static void atkE1_trygetintimidatetarget(void) -{ - u8 side; - - gBattleStruct->scriptingActive = ewram160DD; - side = GetBattlerSide(gBattleStruct->scriptingActive); - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 9; - gBattleTextBuff1[2] = gBattleMons[gBattleStruct->scriptingActive].ability; - gBattleTextBuff1[3] = 0xFF; - - for (;gBankTarget < gBattlersCount; gBankTarget++) - { - if (GetBattlerSide(gBankTarget) == side) - continue; - if (!(gAbsentBattlerFlags & gBitTable[gBankTarget])) - break; - } - - if (gBankTarget >= gBattlersCount) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - gBattlescriptCurrInstr += 5; -} - -static void atkE2_switchoutabilities(void) -{ - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - switch (gBattleMons[gActiveBattler].ability) - { - case ABILITY_NATURAL_CURE: - gBattleMons[gActiveBattler].status1 = 0; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, gBitTable[ewram16064arr(gActiveBattler)], 4, &gBattleMons[gActiveBattler].status1); - MarkBufferBankForExecution(gActiveBattler); - break; - } - gBattlescriptCurrInstr += 2; -} - -static void atkE3_jumpifhasnohp(void) -{ - gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); - if (gBattleMons[gActiveBattler].hp == 0) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); - else - gBattlescriptCurrInstr += 6; -} - -static void atkE4_getsecretpowereffect(void) -{ - switch (gBattleTerrain) - { - case BATTLE_TERRAIN_GRASS: - gBattleCommunication[MOVE_EFFECT_BYTE] = 2; - break; - case BATTLE_TERRAIN_LONG_GRASS: - gBattleCommunication[MOVE_EFFECT_BYTE] = 1; - break; - case BATTLE_TERRAIN_SAND: - gBattleCommunication[MOVE_EFFECT_BYTE] = 27; - break; - case BATTLE_TERRAIN_UNDERWATER: - gBattleCommunication[MOVE_EFFECT_BYTE] = 23; - break; - case BATTLE_TERRAIN_WATER: - gBattleCommunication[MOVE_EFFECT_BYTE] = 22; - break; - case BATTLE_TERRAIN_POND: - gBattleCommunication[MOVE_EFFECT_BYTE] = 24; - break; - case BATTLE_TERRAIN_MOUNTAIN: - gBattleCommunication[MOVE_EFFECT_BYTE] = 7; - break; - case BATTLE_TERRAIN_CAVE: - gBattleCommunication[MOVE_EFFECT_BYTE] = 8; - break; - default: - gBattleCommunication[MOVE_EFFECT_BYTE] = 5; - break; - } - gBattlescriptCurrInstr++; -} - -static void atkE5_pickup(void) -{ - int i; - for (i = 0; i < 6; i++) - { - u16 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); - u16 held_item = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); - u8 ability; - if (GetMonData(&gPlayerParty[i], MON_DATA_ALT_ABILITY)) - ability = gBaseStats[species].ability2; - else - ability = gBaseStats[species].ability1; - - if (ability == ABILITY_PICKUP && species != 0 && species != SPECIES_EGG && held_item == 0 && (Random() % 10) == 0) - { - s32 chance = Random() % 100; - s32 j; - for (j = 0; j < 18; j += 2) - { - if (sPickupItems[j + 1] > chance) - break; - } - SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, (const void*) &sPickupItems[j]); - } - } - gBattlescriptCurrInstr++; -} - -static void atkE6_docastformchangeanimation(void) -{ - gActiveBattler = gBattleStruct->scriptingActive; - if (gBattleMons[gActiveBattler].status2 & STATUS2_SUBSTITUTE) - gBattleStruct->castformToChangeInto |= 0x80; - EmitBattleAnimation(0, B_ANIM_CASTFORM_CHANGE, gBattleStruct->castformToChangeInto); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr++; -} - -static void atkE7_trycastformdatachange(void) -{ - u8 form; - gBattlescriptCurrInstr++; - form = CastformDataTypeChange(gBattleStruct->scriptingActive); - if (form) - { - BattleScriptPushCursorAndCallback(BattleScript_CastformChange); - gBattleStruct->castformToChangeInto = form - 1; - } -} - -static void atkE8_settypebasedhalvers(void) //water/mud sport -{ - bool8 worked = FALSE; - if (gBattleMoves[gCurrentMove].effect == EFFECT_MUD_SPORT) - { - if (!(gStatuses3[gBankAttacker] & STATUS3_MUDSPORT)) - { - gStatuses3[gBankAttacker] |= STATUS3_MUDSPORT; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - worked = TRUE; - } - } - else //water sport - { - if (!(gStatuses3[gBankAttacker] & STATUS3_WATERSPORT)) - { - gStatuses3[gBankAttacker] |= STATUS3_WATERSPORT; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - worked = TRUE; - } - } - if (worked) - gBattlescriptCurrInstr += 5; - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atkE9_setweatherballtype(void) -{ - if (WEATHER_HAS_EFFECT) - { - if ((u8)(gBattleWeather)) - gBattleStruct->dmgMultiplier = 2; - if (gBattleWeather & WEATHER_RAIN_ANY) - gBattleStruct->dynamicMoveType = TYPE_WATER | 0x80; - else if (gBattleWeather & WEATHER_SANDSTORM_ANY) - gBattleStruct->dynamicMoveType = TYPE_ROCK | 0x80; - else if (gBattleWeather & WEATHER_SUN_ANY) - gBattleStruct->dynamicMoveType = TYPE_FIRE | 0x80; - else if (gBattleWeather & WEATHER_HAIL) - gBattleStruct->dynamicMoveType = TYPE_ICE | 0x80; - else - gBattleStruct->dynamicMoveType = TYPE_NORMAL | 0x80; - } - gBattlescriptCurrInstr++; -} - -static void atkEA_tryrecycleitem(void) -{ - u16* used_item; - gActiveBattler = gBankAttacker; - used_item = USED_HELD_ITEM(gActiveBattler); - if (*used_item && gBattleMons[gActiveBattler].item == 0) - { - gLastUsedItem = *used_item; - *used_item = 0; - gBattleMons[gActiveBattler].item = gLastUsedItem; - EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBattler].item); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr += 5; - } - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atkEB_settypetoterrain(void) -{ - if (gBattleMons[gBankAttacker].type1 != sTerrainToType[gBattleTerrain] && gBattleMons[gBankAttacker].type2 != sTerrainToType[gBattleTerrain]) - { - gBattleMons[gBankAttacker].type1 = sTerrainToType[gBattleTerrain]; - gBattleMons[gBankAttacker].type2 = sTerrainToType[gBattleTerrain]; - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 3; - gBattleTextBuff1[2] = sTerrainToType[gBattleTerrain]; - gBattleTextBuff1[3] = 0xFF; - gBattlescriptCurrInstr += 5; - } - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atkEC_pursuitrelated(void) -{ - gActiveBattler = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ 2); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gAbsentBattlerFlags & gBitTable[gActiveBattler]) && gActionForBanks[gActiveBattler] == 0 && gChosenMovesByBanks[gActiveBattler] == MOVE_PURSUIT) - { - gActionsByTurnOrder[gActiveBattler] = 11; - gCurrentMove = MOVE_PURSUIT; - gBattlescriptCurrInstr += 5; - gBattleStruct->animTurn = 1; - gBattleStruct->unk160A7 = gBankAttacker; - gBankAttacker = gActiveBattler; - } - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); -} - -static void atkED_snatchsetbanks(void) -{ - gEffectBank = gBankAttacker; - if (gBankAttacker == gBankTarget) - gBankAttacker = gBankTarget = gBattleStruct->scriptingActive; - else - gBankTarget = gBattleStruct->scriptingActive; - gBattleStruct->scriptingActive = gEffectBank; - gBattlescriptCurrInstr++; -} - -static void atkEE_removelightscreenreflect(void) //brick break -{ - u8 side = GetBattlerSide(gBankAttacker) ^ 1; - if (gSideTimers[side].reflectTimer || gSideTimers[side].lightscreenTimer) - { - gSideAffecting[side] &= ~(SIDE_STATUS_REFLECT); - gSideAffecting[side] &= ~(SIDE_STATUS_LIGHTSCREEN); - gSideTimers[side].reflectTimer = 0; - gSideTimers[side].lightscreenTimer = 0; - gBattleStruct->animTurn = 1; - gBattleStruct->animTargetsHit = 1; - } - else - { - gBattleStruct->animTurn = 0; - gBattleStruct->animTargetsHit = 0; - } - gBattlescriptCurrInstr++; -} - -void atkEF_handleballthrow(void) -{ - u8 ball_multiplier = 0; - if (gBattleExecBuffer) - return; - - gActiveBattler = gBankAttacker; - gBankTarget = gBankAttacker ^ 1; - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - { - EmitBallThrow(0, 5); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr = BattleScript_TrainerBallBlock; - } - else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) - { - EmitBallThrow(0, 4); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr = BattleScript_WallyBallThrow; - } - else - { - u32 odds; - u8 catch_rate; - if (gLastUsedItem == ITEM_SAFARI_BALL) - catch_rate = gBattleStruct->unk16089 * 1275 / 100; //correct the name to safariFleeRate - else - catch_rate = gBaseStats[gBattleMons[gBankTarget].species].catchRate; - if (gLastUsedItem > 5) - { - switch (gLastUsedItem) - { - case ITEM_NET_BALL: - if (gBattleMons[gBankTarget].type1 == TYPE_WATER || gBattleMons[gBankTarget].type2 == TYPE_WATER || gBattleMons[gBankTarget].type1 == TYPE_BUG || gBattleMons[gBankTarget].type2 == TYPE_BUG) - ball_multiplier = 30; - else - ball_multiplier = 10; - break; - case ITEM_DIVE_BALL: - if (Overworld_GetMapTypeOfSaveblockLocation() == 5) - ball_multiplier = 35; - else - ball_multiplier = 10; - break; - case ITEM_NEST_BALL: - if (gBattleMons[gBankTarget].level <= 39) - { - ball_multiplier = 40 - gBattleMons[gBankTarget].level; - if (ball_multiplier <= 9) - ball_multiplier = 10; - } - else - ball_multiplier = 10; - break; - case ITEM_REPEAT_BALL: - if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), 1)) - ball_multiplier = 30; - else - ball_multiplier = 10; - break; - case ITEM_TIMER_BALL: - ball_multiplier = gBattleResults.battleTurnCounter + 10; - if (ball_multiplier > 40) - ball_multiplier = 40; - break; - case ITEM_LUXURY_BALL: - case ITEM_PREMIER_BALL: - ball_multiplier = 10; - break; - } - } - else - ball_multiplier = sBallCatchBonuses[gLastUsedItem - 2]; - - odds = (catch_rate * ball_multiplier / 10) * (gBattleMons[gBankTarget].maxHP * 3 - gBattleMons[gBankTarget].hp * 2) / (3 * gBattleMons[gBankTarget].maxHP); - if (gBattleMons[gBankTarget].status1 & (STATUS_SLEEP | STATUS_FREEZE)) - odds *= 2; - if (gBattleMons[gBankTarget].status1 & (STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS /*| STATUS_TOXIC_POISON */)) //nice one gf - odds = (odds * 15) / 10; - - if (gLastUsedItem != ITEM_SAFARI_BALL) - { - if (gLastUsedItem == ITEM_MASTER_BALL) - { - gBattleResults.unk5_1 = 1; - } - else - { - if (gBattleResults.usedBalls[gLastUsedItem - ITEM_ULTRA_BALL] < 0xFF) - gBattleResults.usedBalls[gLastUsedItem - ITEM_ULTRA_BALL]++; - } - } - if (odds > 254) //poke caught - { - EmitBallThrow(0, 4); - MarkBufferBankForExecution(gActiveBattler); - gBattlescriptCurrInstr = BattleScript_SuccessBallThrow; - SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankTarget]], MON_DATA_POKEBALL, (const void*) &gLastUsedItem); - if (CalculatePlayerPartyCount() == 6) - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else //poke may be caught, calculate shakes - { - u8 shakes; - odds = Sqrt(Sqrt(16711680 / odds)); - odds = 1048560 / odds; - for (shakes = 0; shakes < 4 && Random() < odds; shakes++) {} - if (gLastUsedItem == ITEM_MASTER_BALL) - shakes = 4; //why calculate the shakes before that check? - EmitBallThrow(0, shakes); - MarkBufferBankForExecution(gActiveBattler); - if (shakes == 4) //poke caught, copy of the code above - { - gBattlescriptCurrInstr = BattleScript_SuccessBallThrow; - SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankTarget]], MON_DATA_POKEBALL, (const void*) &gLastUsedItem); - if (CalculatePlayerPartyCount() == 6) - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else //rip - { - gBattleCommunication[MULTISTRING_CHOOSER] = shakes; - gBattlescriptCurrInstr = BattleScript_ShakeBallThrow; - } - } - } -} - -static void atkF0_givecaughtmon(void) -{ - GiveMonToPlayer(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]]); - gBattleResults.caughtPoke = gBattleMons[gBankAttacker ^ 1].species; - GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]], MON_DATA_NICKNAME, gBattleResults.caughtNick); - gBattlescriptCurrInstr++; -} - -static void atkF1_trysetcaughtmondexflags(void) -{ - if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), 1)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - else - { - GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), 3); - if (gBattleMons[gBankTarget].species == SPECIES_UNOWN) - gSaveBlock2.pokedex.unownPersonality = gBattleMons[gBankTarget].personality; - if (gBattleMons[gBankTarget].species == SPECIES_SPINDA) //else if - gSaveBlock2.pokedex.spindaPersonality = gBattleMons[gBankTarget].personality; - gBattlescriptCurrInstr += 5; - } -} - -extern const u32 gBattleTerrainTiles_Building[]; -extern const u32 gBattleTerrainTilemap_Building[]; -extern const u32 gBattleTerrainPalette_BattleTower[]; - -static void atkF2_displaydexinfo(void) -{ - switch (gBattleCommunication[0]) - { - case 0: - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); - gBattleCommunication[0]++; - break; - case 1: - if (!gPaletteFade.active) - { - gBattleCommunication[1] = sub_809070C(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), gBattleMons[gBankTarget].otId, gBattleMons[gBankTarget].personality); - gBattleCommunication[0]++; - } - break; - case 2: - if (!gPaletteFade.active && gMain.callback2 == BattleMainCB2 && !gTasks[gBattleCommunication[1]].isActive) - { - LZDecompressVram(gBattleTerrainTiles_Building, (void*)(0x06008000)); - LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(0x0600d000)); - LoadCompressedPalette(gBattleTerrainPalette_BattleTower, 0x20, 0x60); - REG_BG3CNT = 0x5a0b; - gBattle_BG3_X = 0x100; - BeginNormalPaletteFade(0xFFFC, 0, 16, 0, RGB(0, 0, 0)); - gBattleCommunication[0]++; - } - break; - case 3: - if (!gPaletteFade.active) - gBattlescriptCurrInstr++; - break; - } -} - -NAKED -void sub_802BBD4(u8 r0, u8 r1, u8 r2, u8 r3, u8 sp0) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - ldr r4, [sp, 0x20]\n\ - lsls r0, 24\n\ - lsrs r6, r0, 24\n\ - lsls r1, 24\n\ - lsrs r1, 24\n\ - mov r12, r1\n\ - lsls r2, 24\n\ - lsrs r5, r2, 24\n\ - lsls r3, 24\n\ - lsrs r7, r3, 24\n\ - lsls r4, 24\n\ - lsrs r4, 24\n\ - mov r8, r4\n\ - mov r2, r12\n\ - cmp r2, r7\n\ - bgt _0802BC5A\n\ - lsls r1, r6, 1\n\ - ldr r0, _0802BC20 @ =0x0600c000\n\ - adds r1, r0\n\ - mov r9, r1\n\ -_0802BC06:\n\ - adds r1, r6, 0\n\ - adds r0, r2, 0x1\n\ - mov r10, r0\n\ - cmp r1, r5\n\ - bgt _0802BC54\n\ - lsls r0, r2, 6\n\ - mov r4, r9\n\ - adds r3, r4, r0\n\ -_0802BC16:\n\ - cmp r2, r12\n\ - bne _0802BC28\n\ - ldr r0, _0802BC24 @ =0x00001022\n\ - b _0802BC36\n\ - .align 2, 0\n\ -_0802BC20: .4byte 0x0600c000\n\ -_0802BC24: .4byte 0x00001022\n\ -_0802BC28:\n\ - cmp r2, r7\n\ - bne _0802BC34\n\ - ldr r0, _0802BC30 @ =0x00001028\n\ - b _0802BC36\n\ - .align 2, 0\n\ -_0802BC30: .4byte 0x00001028\n\ -_0802BC34:\n\ - ldr r0, _0802BC68 @ =0x00001025\n\ -_0802BC36:\n\ - cmp r1, r6\n\ - beq _0802BC42\n\ - adds r0, 0x1\n\ - cmp r1, r5\n\ - bne _0802BC42\n\ - adds r0, 0x1\n\ -_0802BC42:\n\ - mov r4, r8\n\ - cmp r4, 0\n\ - beq _0802BC4A\n\ - movs r0, 0\n\ -_0802BC4A:\n\ - strh r0, [r3]\n\ - adds r3, 0x2\n\ - adds r1, 0x1\n\ - cmp r1, r5\n\ - ble _0802BC16\n\ -_0802BC54:\n\ - mov r2, r10\n\ - cmp r2, r7\n\ - ble _0802BC06\n\ -_0802BC5A:\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_0802BC68: .4byte 0x00001025\n\ - .syntax divided"); -} - -void sub_802BC6C(void) -{ - MenuCursor_SetPos814A880(0xC8, ((gBattleCommunication[1] << 28) + 1207959552) >> 24); //what could that be? -} - -void nullsub_6(void) -{ - return; -} - -static void atkF3_trygivecaughtmonnick(void) -{ - switch (gBattleCommunication[0]) - { - case 0: - sub_8023A80(); - gBattleCommunication[0]++; - gBattleCommunication[1] = 0; - sub_802BC6C(); - break; - case 1: - if (gMain.newKeys & DPAD_UP && gBattleCommunication[1] != 0) - { - PlaySE(SE_SELECT); - nullsub_6(); - gBattleCommunication[1] = 0; - sub_802BC6C(); - } - if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[1] == 0) - { - PlaySE(SE_SELECT); - nullsub_6(); - gBattleCommunication[1] = 1; - sub_802BC6C(); - } - if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - if (gBattleCommunication[1] == 0) - { - gBattleCommunication[0]++; - BeginFastPaletteFade(3); - } - else - gBattleCommunication[0] = 4; - } - else if (gMain.newKeys & B_BUTTON) - { - PlaySE(SE_SELECT); - gBattleCommunication[0] = 4; - } - break; - case 2: - if (!gPaletteFade.active) - { - GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]], MON_DATA_NICKNAME, gBattleStruct->caughtNick); - DoNamingScreen(2, gBattleStruct->caughtNick, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]], MON_DATA_SPECIES), GetMonGender(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]]), GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]], MON_DATA_PERSONALITY, 0), BattleMainCB2); - gBattleCommunication[0]++; - } - break; - case 3: - if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active ) - { - SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]], MON_DATA_NICKNAME, gBattleStruct->caughtNick); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - } - break; - case 4: - if (CalculatePlayerPartyCount() == 6) - gBattlescriptCurrInstr += 5; - else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - break; - } -} - -static void atkF4_subattackerhpbydmg(void) -{ - gBattleMons[gBankAttacker].hp -= gBattleMoveDamage; - gBattlescriptCurrInstr++; -} - -static void atkF5_removeattackerstatus1(void) -{ - gBattleMons[gBankAttacker].status1 = 0; - gBattlescriptCurrInstr++; -} - -static void atkF6_finishaction(void) -{ - gCurrentActionFuncId = 0xC; -} - -static void atkF7_finishturn(void) -{ - gCurrentActionFuncId = 0xC; - gCurrentTurnActionNumber = gBattlersCount; -} diff --git a/src/battle/battle_7.c b/src/battle/battle_7.c deleted file mode 100644 index 6e1ddceaf..000000000 --- a/src/battle/battle_7.c +++ /dev/null @@ -1,969 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_anim.h" -#include "battle_anim_813F0F4.h" -#include "battle_interface.h" -#include "blend_palette.h" -#include "contest.h" -#include "data2.h" -#include "decompress.h" -#include "main.h" -#include "m4a.h" -#include "palette.h" -#include "pokemon.h" -#include "rom_8077ABC.h" -#include "rom_8094928.h" -#include "constants/songs.h" -#include "sound.h" -#include "constants/species.h" -#include "sprite.h" -#include "task.h" -#include "text.h" -#include "gba/m4a_internal.h" -#include "ewram.h" -#include "graphics.h" - -extern u8 gBattleBufferA[][0x200]; -extern u8 gActiveBattler; -extern u8 gBattlersCount; -extern u16 gBattlerPartyIndexes[]; -extern u8 gBanksBySide[]; -extern u8 gBankSpriteIds[]; -extern u16 gUnknown_02024DE8; -extern u8 gDoingBattleAnim; -extern u32 gTransformedPersonalities[]; -extern struct Window gUnknown_03004210; -extern void (*gBattleBankFunc[])(void); -extern u8 gHealthboxIDs[]; -extern u8 gUnknown_0300434C[]; -extern struct MusicPlayerInfo gMPlay_SE1; -extern struct MusicPlayerInfo gMPlay_SE2; -extern struct MusicPlayerInfo gMPlay_BGM; -extern u32 gBitTable[]; -extern u16 gBattleTypeFlags; -extern u8 gBattleMonForms[]; -extern u8 gBattleAnimAttacker; -extern u8 gBattleAnimTarget; -extern void (*gAnimScriptCallback)(void); -extern u8 gAnimScriptActive; -extern const u8 *const gBattleAnims_General[]; -extern const u8 *const gBattleAnims_Special[]; -extern const struct CompressedSpriteSheet gTrainerFrontPicTable[]; -extern const struct MonCoords gTrainerFrontPicCoords[]; -extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; -extern const struct CompressedSpriteSheet gUnknown_081FAF24; -extern const struct SpriteTemplate gSpriteTemplate_81FAF34; -extern const u8 gSubstituteDollTilemap[]; // graphics.s -extern const u8 gSubstituteDollGfx[]; // graphics.s -extern const u8 gSubstituteDollPal[]; // graphics.s -extern const u8 gUnknown_08D09C48[]; // graphics.s - -const struct CompressedSpriteSheet gUnknown_0820A47C = -{ gBattleWindowLargeGfx, 4096, 0xd6ff }; - -const struct CompressedSpriteSheet gUnknown_0820A484 = -{ gBattleWindowSmallGfx, 4096, 0xd701 }; - -const struct CompressedSpriteSheet gUnknown_0820A48C[] = -{ - { gBattleWindowSmall2Gfx, 2048, 0xd6ff }, - { gBattleWindowSmall2Gfx, 2048, 0xd700 }, -}; - -const struct CompressedSpriteSheet gUnknown_0820A49C[] = -{ - { gBattleWindowSmall3Gfx, 2048, 0xd701 }, - { gBattleWindowSmall3Gfx, 2048, 0xd702 }, -}; - -const struct CompressedSpriteSheet gUnknown_0820A4AC = -{ gBattleWindowLarge2Gfx, 4096, 0xd70b }; - -const struct CompressedSpriteSheet gUnknown_0820A4B4[] = -{ - { gBlankGfxCompressed, 256, 0xd704 }, - { gBlankGfxCompressed, 288, 0xd705 }, - { gBlankGfxCompressed, 256, 0xd706 }, - { gBlankGfxCompressed, 288, 0xd707 }, -}; - -const struct SpritePalette gUnknown_0820A4D4[] = -{ - { gUnknown_08D1212C, 0xD6FF }, - { gUnknown_08D1214C, 0xD704 }, -}; - -extern void c3_0802FDF4(u8); -extern void sub_80440EC(); -extern void sub_804777C(); -extern u8 GetBattlerSpriteCoord(); -extern u8 IsBankSpritePresent(u8); -extern u8 sub_8077F68(u8); -extern u8 sub_8077F7C(u8); -extern void sub_8094958(void); -extern void sub_80105DC(struct Sprite *); -extern void move_anim_start_t2(); - -void sub_80315E8(u8); -u8 sub_803163C(u8); -void sub_80316CC(u8); -void sub_8031F0C(void); -void refresh_graphics_maybe(u8, u8, u8); -void sub_80324E0(u8 a); -void sub_80327CC(void); -void sub_8032978(struct Sprite *); -void sub_80328A4(struct Sprite *); - -void sub_80312F0(struct Sprite *sprite) -{ - u8 spriteId = sprite->data[1]; - - if (gSprites[spriteId].affineAnimEnded && !gSprites[spriteId].invisible) - { - if (gSprites[spriteId].animPaused) - gSprites[spriteId].animPaused = FALSE; - else if (gSprites[spriteId].animEnded) - { - gSprites[spriteId].callback = sub_80105DC; - StartSpriteAffineAnim(&gSprites[spriteId], 0); - sprite->callback = SpriteCallbackDummy; - } - } -} - -void unref_sub_8031364(struct Sprite *sprite, bool8 stupid) -{ - sprite->animPaused = TRUE; - sprite->callback = SpriteCallbackDummy; - if (!stupid) - StartSpriteAffineAnim(sprite, 1); - else - StartSpriteAffineAnim(sprite, 1); - AnimateSprite(sprite); -} - -void sub_80313A0(struct Sprite *sprite) -{ - if (!(gUnknown_02024DE8 & 1)) - { - sprite->pos2.x += sprite->data[0]; - if (sprite->pos2.x == 0) - sprite->callback = SpriteCallbackDummy; - } -} - -void move_anim_start_t2_for_situation(u8 a, u32 b) -{ - ewram17810[gActiveBattler].unk0_4 = 1; - if (a == 0) - { - if (b == 0x20) - move_anim_start_t2(gActiveBattler, 6); - else if (b == 8 || (b & 0x80)) - move_anim_start_t2(gActiveBattler, 0); - else if (b == 0x10) - move_anim_start_t2(gActiveBattler, 2); - else if (b & 7) - move_anim_start_t2(gActiveBattler, 4); - else if (b == 0x40) - move_anim_start_t2(gActiveBattler, 5); - else - ewram17810[gActiveBattler].unk0_4 = 0; - } - else - { - if (b & 0x000F0000) - move_anim_start_t2(gActiveBattler, 3); - else if (b & 7) - move_anim_start_t2(gActiveBattler, 1); - else if (b & 0x10000000) - move_anim_start_t2(gActiveBattler, 7); - else if (b & 0x08000000) - move_anim_start_t2(gActiveBattler, 8); - else if (b & 0x0000E000) - move_anim_start_t2(gActiveBattler, 9); - else - ewram17810[gActiveBattler].unk0_4 = 0; - } -} - -bool8 move_anim_start_t3(u8 a, u8 b, u8 c, u8 d, u16 e) -{ - u8 taskId; - - if (d == 0 && (e & 0x80)) - { - gBattleMonForms[a] = e & 0x7F; - return TRUE; - } - if (ewram17800[a].substituteSprite && sub_803163C(d) == 0) - return TRUE; - if (ewram17800[a].substituteSprite && d == 2 && gSprites[gBankSpriteIds[a]].invisible) - { - refresh_graphics_maybe(a, 1, gBankSpriteIds[a]); - sub_80324E0(a); - return TRUE; - } - gBattleAnimAttacker = b; - gBattleAnimTarget = c; - ewram17840.unk0 = e; - LaunchBattleAnimation(gBattleAnims_General, d, 0); - taskId = CreateTask(sub_80315E8, 10); - gTasks[taskId].data[0] = a; - ewram17810[gTasks[taskId].data[0]].unk0_5 = 1; - return FALSE; -} - -void sub_80315E8(u8 taskId) -{ - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - ewram17810[gTasks[taskId].data[0]].unk0_5 = 0; - DestroyTask(taskId); - } -} - -u8 sub_803163C(u8 a) -{ - switch (a) - { - case 2: - case 10: - case 11: - case 12: - case 13: - case 17: - return 1; - default: - return 0; - } -} - -void move_anim_start_t4(u8 a, u8 b, u8 c, u8 d) -{ - u8 taskId; - - gBattleAnimAttacker = b; - gBattleAnimTarget = c; - LaunchBattleAnimation(gBattleAnims_Special, d, 0); - taskId = CreateTask(sub_80316CC, 10); - gTasks[taskId].data[0] = a; - ewram17810[gTasks[taskId].data[0]].unk0_6 = 1; -} - -void sub_80316CC(u8 taskId) -{ - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - ewram17810[gTasks[taskId].data[0]].unk0_6 = 0; - DestroyTask(taskId); - } -} - -u8 sub_8031720(int unused1, int unused2) -{ - return 0; -} - -bool8 mplay_80342A4(u8 a) -{ - u8 zero = 0; - - if (IsSEPlaying()) - { - ewram17810[a].unk8++; - if (ewram17810[gActiveBattler].unk8 < 30) - return TRUE; - m4aMPlayStop(&gMPlay_SE1); - m4aMPlayStop(&gMPlay_SE2); - } - if (zero == 0) - { - ewram17810[a].unk8 = 0; - return FALSE; - } - return TRUE; -} - -void BattleLoadOpponentMonSprite(struct Pokemon *pkmn, u8 b) -{ - u32 personalityValue; - u16 species; - u32 r7; - u32 otId; - u8 var; - u16 paletteOffset; - const u8 *lzPaletteData; - - personalityValue = GetMonData(pkmn, MON_DATA_PERSONALITY); - if (ewram17800[b].transformedSpecies == 0) - { - species = GetMonData(pkmn, MON_DATA_SPECIES); - r7 = personalityValue; - } - else - { - species = ewram17800[b].transformedSpecies; - r7 = gTransformedPersonalities[b]; - } - otId = GetMonData(pkmn, MON_DATA_OT_ID); - var = GetBattlerPosition(b); - HandleLoadSpecialPokePic( - &gMonFrontPicTable[species], - gMonFrontPicCoords[species].coords, - gMonFrontPicCoords[species].y_offset, - eVoidSharedArr2, - gUnknown_081FAF4C[var], - species, - r7); - paletteOffset = 0x100 + b * 16; - if (ewram17800[b].transformedSpecies == 0) - lzPaletteData = GetMonSpritePal(pkmn); - else - lzPaletteData = GetMonSpritePalFromOtIdPersonality(species, otId, personalityValue); - LZDecompressWram(lzPaletteData, gSharedMem); - LoadPalette(gSharedMem, paletteOffset, 0x20); - LoadPalette(gSharedMem, 0x80 + b * 16, 0x20); - if (species == SPECIES_CASTFORM) - { - paletteOffset = 0x100 + b * 16; - LZDecompressWram(lzPaletteData, ewram16400); - LoadPalette(ewram16400 + gBattleMonForms[b] * 32, paletteOffset, 0x20); - } - if (ewram17800[b].transformedSpecies != 0) - { - BlendPalette(paletteOffset, 16, 6, RGB(31, 31, 31)); - CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); - } -} - -void BattleLoadPlayerMonSprite(struct Pokemon *pkmn, u8 b) -{ - u32 personalityValue; - u16 species; - u32 r7; - u32 otId; - u8 var; - u16 paletteOffset; - const u8 *lzPaletteData; - - personalityValue = GetMonData(pkmn, MON_DATA_PERSONALITY); - if (ewram17800[b].transformedSpecies == 0) - { - species = GetMonData(pkmn, MON_DATA_SPECIES); - r7 = personalityValue; - } - else - { - species = ewram17800[b].transformedSpecies; - r7 = gTransformedPersonalities[b]; - } - otId = GetMonData(pkmn, MON_DATA_OT_ID); - var = GetBattlerPosition(b); - HandleLoadSpecialPokePic( - &gMonBackPicTable[species], - gMonBackPicCoords[species].coords, - gMonBackPicCoords[species].y_offset, - eVoidSharedArr2, - gUnknown_081FAF4C[var], - species, - r7); - paletteOffset = 0x100 + b * 16; - if (ewram17800[b].transformedSpecies == 0) - lzPaletteData = GetMonSpritePal(pkmn); - else - lzPaletteData = GetMonSpritePalFromOtIdPersonality(species, otId, personalityValue); - LZDecompressWram(lzPaletteData, gSharedMem); - LoadPalette(gSharedMem, paletteOffset, 0x20); - LoadPalette(gSharedMem, 0x80 + b * 16, 0x20); - if (species == SPECIES_CASTFORM) - { - paletteOffset = 0x100 + b * 16; - LZDecompressWram(lzPaletteData, ewram16400); - LoadPalette(ewram16400 + gBattleMonForms[b] * 32, paletteOffset, 0x20); - } - if (ewram17800[b].transformedSpecies != 0) - { - BlendPalette(paletteOffset, 16, 6, RGB(31, 31, 31)); - CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); - } -} - -void unref_sub_8031A64(void) -{ -} - -void nullsub_9(u16 unused) -{ -} - -void sub_8031A6C(u16 a, u8 b) -{ - u8 status; - struct CompressedSpriteSheet spriteSheet; - - status = GetBattlerPosition(b); - DecompressPicFromTable_2( - &gTrainerFrontPicTable[a], - gTrainerFrontPicCoords[a].coords, - gTrainerFrontPicCoords[a].y_offset, - eVoidSharedArr, - gUnknown_081FAF4C[status], - 0); - spriteSheet.data = gUnknown_081FAF4C[status]; - spriteSheet.size = gTrainerFrontPicTable[a].size; - spriteSheet.tag = gTrainerFrontPicTable[a].tag; - LoadCompressedObjectPic(&spriteSheet); - LoadCompressedObjectPalette(&gTrainerFrontPicPaletteTable[a]); -} - -void LoadPlayerTrainerBankSprite(u16 a, u8 b) -{ - u8 status; - - status = GetBattlerPosition(b); - DecompressPicFromTable_2( - &gTrainerBackPicTable[a], - gTrainerBackPicCoords[a].coords, - gTrainerBackPicCoords[a].y_offset, - eVoidSharedArr, - gUnknown_081FAF4C[status], - 0); - LoadCompressedPalette(gTrainerBackPicPaletteTable[a].data, 0x100 + b * 16, 32); -} - -void nullsub_10(int unused) -{ -} - -void sub_8031B74(u16 a) -{ - FreeSpritePaletteByTag(gTrainerFrontPicPaletteTable[a].tag); - FreeSpriteTilesByTag(gTrainerFrontPicTable[a].tag); -} - -void unref_sub_8031BA0(void) -{ - u8 count; - u8 i; - - LoadSpritePalette(&gUnknown_0820A4D4[0]); - LoadSpritePalette(&gUnknown_0820A4D4[1]); - if (!IsDoubleBattle()) - { - LoadCompressedObjectPic(&gUnknown_0820A47C); - LoadCompressedObjectPic(&gUnknown_0820A484); - count = 2; - } - else - { - LoadCompressedObjectPic(&gUnknown_0820A48C[0]); - LoadCompressedObjectPic(&gUnknown_0820A48C[1]); - LoadCompressedObjectPic(&gUnknown_0820A49C[0]); - LoadCompressedObjectPic(&gUnknown_0820A49C[1]); - count = 4; - } - for (i = 0; i < count; i++) - LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[i]]); -} - -bool8 sub_8031C30(u8 a) -{ - bool8 retVal = FALSE; - - if (a != 0) - { - if (a == 1) - { - LoadSpritePalette(&gUnknown_0820A4D4[0]); - LoadSpritePalette(&gUnknown_0820A4D4[1]); - } - else if (!IsDoubleBattle()) - { - if (a == 2) - { - if (gBattleTypeFlags & 0x80) - LoadCompressedObjectPic(&gUnknown_0820A4AC); - else - LoadCompressedObjectPic(&gUnknown_0820A47C); - } - else if (a == 3) - LoadCompressedObjectPic(&gUnknown_0820A484); - else if (a == 4) - LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[0]]); - else if (a == 5) - LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[1]]); - else - retVal = TRUE; - } - else - { - if (a == 2) - LoadCompressedObjectPic(&gUnknown_0820A48C[0]); - else if (a == 3) - LoadCompressedObjectPic(&gUnknown_0820A48C[1]); - else if (a == 4) - LoadCompressedObjectPic(&gUnknown_0820A49C[0]); - else if (a == 5) - LoadCompressedObjectPic(&gUnknown_0820A49C[1]); - else if (a == 6) - LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[0]]); - else if (a == 7) - LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[1]]); - else if (a == 8) - LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[2]]); - else if (a == 9) - LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[3]]); - else - retVal = TRUE; - } - } - return retVal; -} - -void load_gfxc_health_bar(u8 a) -{ - LZDecompressWram(gUnknown_08D09C48, eVoidSharedArr); -} - -u8 battle_load_something(u8 *pState, u8 *b) -{ - bool8 retVal = FALSE; - - switch (*pState) - { - case 0: - sub_8031F0C(); - (*pState)++; - break; - case 1: - if (sub_8031C30(*b) == 0) - { - (*b)++; - } - else - { - *b = 0; - (*pState)++; - } - break; - case 2: - (*pState)++; - break; - case 3: - if ((gBattleTypeFlags & 0x80) && *b == 0) - gHealthboxIDs[*b] = battle_make_oam_safari_battle(); - else - gHealthboxIDs[*b] = battle_make_oam_normal_battle(*b); - (*b)++; - if (*b == gBattlersCount) - { - *b = 0; - (*pState)++; - } - break; - case 4: - sub_8043F44(*b); - if (gBanksBySide[*b] <= 1) - nullsub_11(gHealthboxIDs[*b], 0); - else - nullsub_11(gHealthboxIDs[*b], 1); - (*b)++; - if (*b == gBattlersCount) - { - *b = 0; - (*pState)++; - } - break; - case 5: - if (GetBattlerSide(*b) == 0) - { - if (!(gBattleTypeFlags & 0x80)) - sub_8045A5C(gHealthboxIDs[*b], &gPlayerParty[gBattlerPartyIndexes[*b]], 0); - } - else - { - sub_8045A5C(gHealthboxIDs[*b], &gEnemyParty[gBattlerPartyIndexes[*b]], 0); - } - sub_8043DB0(gHealthboxIDs[*b]); - (*b)++; - if (*b == gBattlersCount) - { - *b = 0; - (*pState)++; - } - break; - case 6: - sub_80327CC(); - sub_8094958(); - retVal = TRUE; - break; - } - return retVal; -} - -void sub_8031EE8(void) -{ - memset(ewram17810, 0, 0x30); - memset(&ewram17840, 0, 0x10); -} - -void sub_8031F0C(void) -{ - sub_8031EE8(); - memset(ewram17800, 0, 0x10); -} - -void sub_8031F24(void) -{ - s32 i; - - for (i = 0; i < gBattlersCount; i++) - ewram17800[i].invisible = gSprites[gBankSpriteIds[i]].invisible; -} - -void sub_8031F88(u8 a) -{ - ewram17800[a].invisible = gSprites[gBankSpriteIds[a]].invisible; -} - -void sub_8031FC4(u8 a, u8 b, bool8 c) -{ - u16 paletteOffset; - u16 species; - u32 personalityValue; - u32 otId; - u8 r10; - const u8 *lzPaletteData; - - if (c) - { - StartSpriteAnim(&gSprites[gBankSpriteIds[a]], ewram17840.unk0); - paletteOffset = 0x100 + a * 16; - LoadPalette(ewram16400 + ewram17840.unk0 * 32, paletteOffset, 32); - gBattleMonForms[a] = ewram17840.unk0; - if (ewram17800[a].transformedSpecies != 0) - { - BlendPalette(paletteOffset, 16, 6, RGB(31, 31, 31)); - CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); - } - gSprites[gBankSpriteIds[a]].pos1.y = sub_8077F68(a); - } - else - { - if (IsContest()) - { - r10 = 0; - species = shared19348.unk2; - personalityValue = shared19348.unk8; - otId = shared19348.unkC; - HandleLoadSpecialPokePic( - &gMonBackPicTable[species], - gMonBackPicCoords[species].coords, - gMonBackPicCoords[species].y_offset, - eVoidSharedArr2, - gUnknown_081FAF4C[0], - species, - shared19348.unk10); - } - else - { - r10 = GetBattlerPosition(a); - if (GetBattlerSide(b) == 1) - species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[b]], MON_DATA_SPECIES); - else - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[b]], MON_DATA_SPECIES); - if (GetBattlerSide(a) == 0) - { - personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[a]], MON_DATA_PERSONALITY); - otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[a]], MON_DATA_OT_ID); - HandleLoadSpecialPokePic( - &gMonBackPicTable[species], - gMonBackPicCoords[species].coords, - gMonBackPicCoords[species].y_offset, - eVoidSharedArr2, - gUnknown_081FAF4C[r10], - species, - gTransformedPersonalities[a]); - } - else - { - personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[a]], MON_DATA_PERSONALITY); - otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[a]], MON_DATA_OT_ID); - HandleLoadSpecialPokePic( - &gMonFrontPicTable[species], - gMonFrontPicCoords[species].coords, - gMonFrontPicCoords[species].y_offset, - eVoidSharedArr2, - gUnknown_081FAF4C[r10], - species, - gTransformedPersonalities[a]); - } - } - DmaCopy32Defvars(3, gUnknown_081FAF4C[r10], (void *)(VRAM + 0x10000 + gSprites[gBankSpriteIds[a]].oam.tileNum * 32), 0x800); - paletteOffset = 0x100 + a * 16; - lzPaletteData = GetMonSpritePalFromOtIdPersonality(species, otId, personalityValue); - LZDecompressWram(lzPaletteData, gSharedMem); - LoadPalette(gSharedMem, paletteOffset, 32); - if (species == SPECIES_CASTFORM) - { - u16 *paletteSrc = (u16 *)ewram16400; // TODO: avoid casting? - - LZDecompressWram(lzPaletteData, paletteSrc); - LoadPalette(paletteSrc + gBattleMonForms[b] * 16, paletteOffset, 32); - } - BlendPalette(paletteOffset, 16, 6, RGB(31, 31, 31)); - CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); - if (!IsContest()) - { - ewram17800[a].transformedSpecies = species; - gBattleMonForms[a] = gBattleMonForms[b]; - } - gSprites[gBankSpriteIds[a]].pos1.y = sub_8077F68(a); - StartSpriteAnim(&gSprites[gBankSpriteIds[a]], gBattleMonForms[a]); - } -} - -void BattleLoadSubstituteSprite(u8 a, u8 b) -{ - u8 r4; - u16 foo; - const u8 *gSubstituteDollPal_; - void *src; - s32 i; - - if (b == 0) - { - if (IsContest()) - r4 = 0; - else - r4 = GetBattlerPosition(a); - if (IsContest()) - LZDecompressVram(gSubstituteDollTilemap, gUnknown_081FAF4C[r4]); - else if (GetBattlerSide(a) != 0) - LZDecompressVram(gSubstituteDollGfx, gUnknown_081FAF4C[r4]); - else - LZDecompressVram(gSubstituteDollTilemap, gUnknown_081FAF4C[r4]); - // There is probably a way to do this without all the temp variables, but I couldn't figure it out. - foo = a * 16; - gSubstituteDollPal_ = gSubstituteDollPal; - src = gUnknown_081FAF4C[r4]; - for (i = 0; i < 3; i++) - DmaCopy32(3, src, src + i * 0x800 + 0x800, 0x800); - LoadCompressedPalette(gSubstituteDollPal_, 0x100 + foo, 32); - } - else - { - if (!IsContest()) - { - if (GetBattlerSide(a) != 0) - BattleLoadOpponentMonSprite(&gEnemyParty[gBattlerPartyIndexes[a]], a); - else - BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[a]], a); - } - } -} - -void refresh_graphics_maybe(u8 a, u8 b, u8 spriteId) -{ - BattleLoadSubstituteSprite(a, b); - StartSpriteAnim(&gSprites[spriteId], gBattleMonForms[a]); - if (b == 0) - gSprites[spriteId].pos1.y = sub_8077F7C(a); - else - gSprites[spriteId].pos1.y = sub_8077F68(a); -} - -void sub_80324BC(u8 a, u16 b) -{ - if (b == 0xA4) - ewram17800[a].substituteSprite = 1; -} - -void sub_80324E0(u8 a) -{ - ewram17800[a].substituteSprite = 0; -} - -void HandleLowHpMusicChange(struct Pokemon *pkmn, u8 b) -{ - u16 hp = GetMonData(pkmn, MON_DATA_HP); - u16 maxHP = GetMonData(pkmn, MON_DATA_MAX_HP); - - if (GetHPBarLevel(hp, maxHP) == 1) - { - if (!ewram17800[b].unk0_1) - { - if (!ewram17800[b ^ 2].unk0_1) - PlaySE(SE_HINSI); - ewram17800[b].unk0_1 = 1; - } - } - else - { - ewram17800[b].unk0_1 = 0; - if (!IsDoubleBattle()) - { - m4aSongNumStop(SE_HINSI); - return; - } - if (IsDoubleBattle() && !ewram17800[b ^ 2].unk0_1) - { - m4aSongNumStop(SE_HINSI); - return; - } - } -} - -void BattleStopLowHpSound(void) -{ - u8 r4 = GetBattlerAtPosition(0); - - ewram17800[r4].unk0_1 = 0; - if (IsDoubleBattle()) - ewram17800[r4 ^ 2].unk0_1 = 0; - m4aSongNumStop(SE_HINSI); -} - -u8 unref_sub_8032604(struct Pokemon *pkmn) -{ - u16 hp = GetMonData(pkmn, MON_DATA_HP); - u16 maxHP = GetMonData(pkmn, MON_DATA_MAX_HP); - - return GetHPBarLevel(hp, maxHP); -} - -void sub_8032638(void) -{ - if (gMain.inBattle) - { - u8 r8 = GetBattlerAtPosition(0); - u8 r9 = GetBattlerAtPosition(2); - u8 r4 = pokemon_order_func(gBattlerPartyIndexes[r8]); - u8 r5 = pokemon_order_func(gBattlerPartyIndexes[r9]); - - if (GetMonData(&gPlayerParty[r4], MON_DATA_HP) != 0) - HandleLowHpMusicChange(&gPlayerParty[r4], r8); - if (IsDoubleBattle()) - { - if (GetMonData(&gPlayerParty[r5], MON_DATA_HP) != 0) - HandleLowHpMusicChange(&gPlayerParty[r5], r9); - } - } -} - -void sub_80326EC(u8 a) -{ - s32 i; - - for (i = 0; i < gBattlersCount; i++) - { - if (IsBankSpritePresent(i) != 0) - { - gSprites[gBankSpriteIds[i]].oam.affineMode = a; - if (a == 0) - { - ewram17810[i].unk6 = gSprites[gBankSpriteIds[i]].oam.matrixNum; - gSprites[gBankSpriteIds[i]].oam.matrixNum = 0; - } - else - { - gSprites[gBankSpriteIds[i]].oam.matrixNum = ewram17810[i].unk6; - } - } - } -} - -void sub_80327CC(void) -{ - u8 r5; - - LoadCompressedObjectPic(&gUnknown_081FAF24); - r5 = GetBattlerAtPosition(1); - ewram17810[r5].unk7 = CreateSprite(&gSpriteTemplate_81FAF34, GetBattlerSpriteCoord(r5, 0), GetBattlerSpriteCoord(r5, 1) + 32, 0xC8); - gSprites[ewram17810[r5].unk7].data[0] = r5; - if (IsDoubleBattle()) - { - r5 = GetBattlerAtPosition(3); - ewram17810[r5].unk7 = CreateSprite(&gSpriteTemplate_81FAF34, GetBattlerSpriteCoord(r5, 0), GetBattlerSpriteCoord(r5, 1) + 32, 0xC8); - gSprites[ewram17810[r5].unk7].data[0] = r5; - } -} - -void sub_80328A4(struct Sprite *sprite) -{ - bool8 invisible = FALSE; - u8 r4 = sprite->data[0]; - struct Sprite *r7 = &gSprites[gBankSpriteIds[r4]]; - - if (!r7->inUse || IsBankSpritePresent(r4) == 0) - { - sprite->callback = sub_8032978; - return; - } - if (gAnimScriptActive || r7->invisible) - invisible = TRUE; - else if (ewram17800[r4].transformedSpecies != 0 && gEnemyMonElevation[ewram17800[r4].transformedSpecies] == 0) - invisible = TRUE; - if (ewram17800[r4].substituteSprite) - invisible = TRUE; - sprite->pos1.x = r7->pos1.x; - sprite->pos2.x = r7->pos2.x; - sprite->invisible = invisible; -} - -void sub_8032978(struct Sprite *sprite) -{ - sprite->invisible = TRUE; -} - -void sub_8032984(u8 a, u16 b) -{ - if (GetBattlerSide(a) != 0) - { - if (ewram17800[a].transformedSpecies != 0) - b = ewram17800[a].transformedSpecies; - if (gEnemyMonElevation[b] != 0) - gSprites[ewram17810[a].unk7].callback = sub_80328A4; - else - gSprites[ewram17810[a].unk7].callback = sub_8032978; - } -} - -void sub_8032A08(u8 a) -{ - gSprites[ewram17810[a].unk7].callback = sub_8032978; -} - -void sub_8032A38(void) -{ - u16 *ptr = (u16 *)(VRAM + 0x240); - s32 i; - s32 j; - - for (i = 0; i < 9; i++) - { - for (j = 0; j < 16; j++) - { - if (!(*ptr & 0xF000)) - *ptr |= 0xF000; - if (!(*ptr & 0x0F00)) - *ptr |= 0x0F00; - if (!(*ptr & 0x00F0)) - *ptr |= 0x00F0; - if (!(*ptr & 0x000F)) - *ptr |= 0x000F; - ptr++; - } - } -} - -void sub_8032AA8(u8 a, u8 b) -{ - ewram17800[a].transformedSpecies = 0; - gBattleMonForms[a] = 0; - if (b == 0) - sub_80324E0(a); -} diff --git a/src/battle/battle_ai.c b/src/battle/battle_ai.c deleted file mode 100644 index e192251d0..000000000 --- a/src/battle/battle_ai.c +++ /dev/null @@ -1,2157 +0,0 @@ -#include "global.h" -#include "battle_ai.h" -#include "constants/abilities.h" -#include "battle.h" -#include "constants/battle_move_effects.h" -#include "data2.h" -#include "item.h" -#include "constants/moves.h" -#include "pokemon.h" -#include "random.h" -#include "rom_8077ABC.h" -#include "constants/species.h" -#include "util.h" -#include "ewram.h" - -extern u8 gUnknown_02023A14_50; -extern u32 gUnknown_02023A14_4C; -extern u16 gBattleTypeFlags; -extern u16 gBattleWeather; -extern u8 gActiveBattler; -extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; -extern u16 gCurrentMove; -extern int gBattleMoveDamage; -extern u8 gBankAttacker; -extern u8 gBankTarget; -extern u8 gAbsentBattlerFlags; -extern u8 gMoveResultFlags; -extern u16 gDynamicBasePower; -extern u16 gLastUsedMove[MAX_BATTLERS_COUNT]; -extern u32 gStatuses3[MAX_BATTLERS_COUNT]; -extern u16 gSideAffecting[2]; -extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; -extern u8 gCritMultiplier; -extern u16 gTrainerBattleOpponent; -extern u8 *BattleAIs[]; - -enum -{ - WEATHER_TYPE_SUN, - WEATHER_TYPE_RAIN, - WEATHER_TYPE_SANDSTORM, - WEATHER_TYPE_HAIL, -}; - -/* -gAIScriptPtr is a pointer to the next battle AI cmd command to read. -when a command finishes processing, gAIScriptPtr is incremented by -the number of bytes that the current command had reserved for arguments -in order to read the next command correctly. refer to battle_ai_scripts.s for the -AI scripts. -*/ -EWRAM_DATA u8 *gAIScriptPtr = NULL; - -static void BattleAICmd_if_random_less_than(void); -static void BattleAICmd_if_random_greater_than(void); -static void BattleAICmd_if_random_equal(void); -static void BattleAICmd_if_random_not_equal(void); -static void BattleAICmd_score(void); -static void BattleAICmd_if_hp_less_than(void); -static void BattleAICmd_if_hp_more_than(void); -static void BattleAICmd_if_hp_equal(void); -static void BattleAICmd_if_hp_not_equal(void); -static void BattleAICmd_if_status(void); -static void BattleAICmd_if_not_status(void); -static void BattleAICmd_if_status2(void); -static void BattleAICmd_if_not_status2(void); -static void BattleAICmd_if_status3(void); -static void BattleAICmd_if_not_status3(void); -static void BattleAICmd_if_status4(void); -static void BattleAICmd_if_not_status4(void); -static void BattleAICmd_if_less_than(void); -static void BattleAICmd_if_more_than(void); -static void BattleAICmd_if_equal(void); -static void BattleAICmd_if_not_equal(void); -static void BattleAICmd_if_less_than_32(void); -static void BattleAICmd_if_more_than_32(void); -static void BattleAICmd_if_equal_32(void); -static void BattleAICmd_if_not_equal_32(void); -static void BattleAICmd_if_move(void); -static void BattleAICmd_if_not_move(void); -static void BattleAICmd_if_in_bytes(void); -static void BattleAICmd_if_not_in_bytes(void); -static void BattleAICmd_if_in_words(void); -static void BattleAICmd_if_not_in_words(void); -static void BattleAICmd_if_user_can_damage(void); -static void BattleAICmd_if_user_cant_damage(void); -static void BattleAICmd_get_turn_count(void); -static void BattleAICmd_get_type(void); -static void BattleAICmd_get_move_power(void); -static void BattleAICmd_is_most_powerful_move(void); -static void BattleAICmd_get_move(void); -static void BattleAICmd_if_arg_equal(void); -static void BattleAICmd_if_arg_not_equal(void); -static void BattleAICmd_if_would_go_first(void); -static void BattleAICmd_if_would_not_go_first(void); -static void BattleAICmd_nullsub_2A(void); -static void BattleAICmd_nullsub_2B(void); -static void BattleAICmd_count_alive_pokemon(void); -static void BattleAICmd_get_considered_move(void); -static void BattleAICmd_get_considered_move_effect(void); -static void BattleAICmd_get_ability(void); -static void BattleAICmd_get_highest_possible_damage(void); -static void BattleAICmd_if_damage_bonus(void); -static void BattleAICmd_nullsub_32(void); -static void BattleAICmd_nullsub_33(void); -static void BattleAICmd_if_status_in_party(void); -static void BattleAICmd_if_status_not_in_party(void); -static void BattleAICmd_get_weather(void); -static void BattleAICmd_if_effect(void); -static void BattleAICmd_if_not_effect(void); -static void BattleAICmd_if_stat_level_less_than(void); -static void BattleAICmd_if_stat_level_more_than(void); -static void BattleAICmd_if_stat_level_equal(void); -static void BattleAICmd_if_stat_level_not_equal(void); -static void BattleAICmd_if_can_faint(void); -static void BattleAICmd_if_cant_faint(void); -static void BattleAICmd_if_has_move(void); -static void BattleAICmd_if_dont_have_move(void); -static void BattleAICmd_if_move_effect(void); -static void BattleAICmd_if_not_move_effect(void); -static void BattleAICmd_if_last_move_did_damage(void); -static void BattleAICmd_if_encored(void); -static void BattleAICmd_flee(void); -static void BattleAICmd_if_random_100(void); -static void BattleAICmd_watch(void); -static void BattleAICmd_get_hold_effect(void); -static void BattleAICmd_get_gender(void); -static void BattleAICmd_is_first_turn(void); -static void BattleAICmd_get_stockpile_count(void); -static void BattleAICmd_is_double_battle(void); -static void BattleAICmd_get_used_item(void); -static void BattleAICmd_get_move_type_from_result(void); -static void BattleAICmd_get_move_power_from_result(void); -static void BattleAICmd_get_move_effect_from_result(void); -static void BattleAICmd_get_protect_count(void); -static void BattleAICmd_nullsub_52(void); -static void BattleAICmd_nullsub_53(void); -static void BattleAICmd_nullsub_54(void); -static void BattleAICmd_nullsub_55(void); -static void BattleAICmd_nullsub_56(void); -static void BattleAICmd_nullsub_57(void); -static void BattleAICmd_call(void); -static void BattleAICmd_jump(void); -static void BattleAICmd_end(void); -static void BattleAICmd_if_level_compare(void); -static void BattleAICmd_if_taunted(void); -static void BattleAICmd_if_not_taunted(void); - -typedef void (*BattleAICmdFunc)(void); - -static const BattleAICmdFunc sBattleAICmdTable[] = -{ - BattleAICmd_if_random_less_than, // 0x0 - BattleAICmd_if_random_greater_than, // 0x1 - BattleAICmd_if_random_equal, // 0x2 - BattleAICmd_if_random_not_equal, // 0x3 - BattleAICmd_score, // 0x4 - BattleAICmd_if_hp_less_than, // 0x5 - BattleAICmd_if_hp_more_than, // 0x6 - BattleAICmd_if_hp_equal, // 0x7 - BattleAICmd_if_hp_not_equal, // 0x8 - BattleAICmd_if_status, // 0x9 - BattleAICmd_if_not_status, // 0xA - BattleAICmd_if_status2, // 0xB - BattleAICmd_if_not_status2, // 0xC - BattleAICmd_if_status3, // 0xD - BattleAICmd_if_not_status3, // 0xE - BattleAICmd_if_status4, // 0xF - BattleAICmd_if_not_status4, // 0x10 - BattleAICmd_if_less_than, // 0x11 - BattleAICmd_if_more_than, // 0x12 - BattleAICmd_if_equal, // 0x13 - BattleAICmd_if_not_equal, // 0x14 - BattleAICmd_if_less_than_32, // 0x15 - BattleAICmd_if_more_than_32, // 0x16 - BattleAICmd_if_equal_32, // 0x17 - BattleAICmd_if_not_equal_32, // 0x18 - BattleAICmd_if_move, // 0x19 - BattleAICmd_if_not_move, // 0x1A - BattleAICmd_if_in_bytes, // 0x1B - BattleAICmd_if_not_in_bytes, // 0x1C - BattleAICmd_if_in_words, // 0x1D - BattleAICmd_if_not_in_words, // 0x1E - BattleAICmd_if_user_can_damage, // 0x1F - BattleAICmd_if_user_cant_damage, // 0x20 - BattleAICmd_get_turn_count, // 0x21 - BattleAICmd_get_type, // 0x22 - BattleAICmd_get_move_power, // 0x23 - BattleAICmd_is_most_powerful_move, // 0x24 - BattleAICmd_get_move, // 0x25 - BattleAICmd_if_arg_equal, // 0x26 - BattleAICmd_if_arg_not_equal, // 0x27 - BattleAICmd_if_would_go_first, // 0x28 - BattleAICmd_if_would_not_go_first, // 0x29 - BattleAICmd_nullsub_2A, // 0x2A - BattleAICmd_nullsub_2B, // 0x2B - BattleAICmd_count_alive_pokemon, // 0x2C - BattleAICmd_get_considered_move, // 0x2D - BattleAICmd_get_considered_move_effect, // 0x2E - BattleAICmd_get_ability, // 0x2F - BattleAICmd_get_highest_possible_damage, // 0x30 - BattleAICmd_if_damage_bonus, // 0x31 - BattleAICmd_nullsub_32, // 0x32 - BattleAICmd_nullsub_33, // 0x33 - BattleAICmd_if_status_in_party, // 0x34 - BattleAICmd_if_status_not_in_party, // 0x35 - BattleAICmd_get_weather, // 0x36 - BattleAICmd_if_effect, // 0x37 - BattleAICmd_if_not_effect, // 0x38 - BattleAICmd_if_stat_level_less_than, // 0x39 - BattleAICmd_if_stat_level_more_than, // 0x3A - BattleAICmd_if_stat_level_equal, // 0x3B - BattleAICmd_if_stat_level_not_equal, // 0x3C - BattleAICmd_if_can_faint, // 0x3D - BattleAICmd_if_cant_faint, // 0x3E - BattleAICmd_if_has_move, // 0x3F - BattleAICmd_if_dont_have_move, // 0x40 - BattleAICmd_if_move_effect, // 0x41 - BattleAICmd_if_not_move_effect, // 0x42 - BattleAICmd_if_last_move_did_damage, // 0x43 - BattleAICmd_if_encored, // 0x44 - BattleAICmd_flee, // 0x45 - BattleAICmd_if_random_100, // 0x46 - BattleAICmd_watch, // 0x47 - BattleAICmd_get_hold_effect, // 0x48 - BattleAICmd_get_gender, // 0x49 - BattleAICmd_is_first_turn, // 0x4A - BattleAICmd_get_stockpile_count, // 0x4B - BattleAICmd_is_double_battle, // 0x4C - BattleAICmd_get_used_item, // 0x4D - BattleAICmd_get_move_type_from_result, // 0x4E - BattleAICmd_get_move_power_from_result, // 0x4F - BattleAICmd_get_move_effect_from_result, // 0x50 - BattleAICmd_get_protect_count, // 0x51 - BattleAICmd_nullsub_52, // 0x52 - BattleAICmd_nullsub_53, // 0x53 - BattleAICmd_nullsub_54, // 0x54 - BattleAICmd_nullsub_55, // 0x55 - BattleAICmd_nullsub_56, // 0x56 - BattleAICmd_nullsub_57, // 0x57 - BattleAICmd_call, // 0x58 - BattleAICmd_jump, // 0x59 - BattleAICmd_end, // 0x5A - BattleAICmd_if_level_compare, // 0x5B - BattleAICmd_if_taunted, // 0x5C - BattleAICmd_if_not_taunted, // 0x5D -}; - -#ifdef NONMATCHING -static -#endif -const u16 sDiscouragedPowerfulMoveEffects[] = -{ - EFFECT_EXPLOSION, - EFFECT_DREAM_EATER, - EFFECT_RAZOR_WIND, - EFFECT_SKY_ATTACK, - EFFECT_RECHARGE, - EFFECT_SKULL_BASH, - EFFECT_SOLARBEAM, - EFFECT_SPIT_UP, - EFFECT_FOCUS_PUNCH, - EFFECT_SUPERPOWER, - EFFECT_ERUPTION, - EFFECT_OVERHEAT, - 0xFFFF -}; - -// if the AI is a Link battle, safari, battle tower, or ereader, it will ignore considering item uses. -void BattleAI_HandleItemUseBeforeAISetup(void) -{ - s32 i; - u8 *data; - - MEMSET_ALT(AI_BATTLE_HISTORY, 0, sizeof(struct BattleHistory), i, data); - - if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) - && gTrainerBattleOpponent != 0x400 - && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_SAFARI | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER))) - { - for (i = 0; i < MAX_TRAINER_ITEMS; i++) - { - if (gTrainers[gTrainerBattleOpponent].items[i] != 0) - { - AI_BATTLE_HISTORY->trainerItems[AI_BATTLE_HISTORY->numItems] = gTrainers[gTrainerBattleOpponent].items[i]; - AI_BATTLE_HISTORY->numItems++; - } - } - } - - BattleAI_SetupAIData(); -} - -void BattleAI_SetupAIData(void) -{ - s32 i; - u8 limitations; - u8 *data; - - // clear AI data and set default move score to 100. strange that they didn't use memset here. - MEMSET_ALT(AI_THINKING_STRUCT, 0, sizeof(struct AI_ThinkingStruct), i, data); - - for (i = 0; i < MAX_MON_MOVES; i++) - AI_THINKING_STRUCT->score[i] = 100; - - limitations = CheckMoveLimitations(gActiveBattler, 0, 0xFF); - - // do not consider moves the AI cannot select - // also, roll simulated RNG for moves that have a degree of - // randomness. - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBitTable[i] & limitations) - AI_THINKING_STRUCT->score[i] = 0; - - AI_THINKING_STRUCT->simulatedRNG[i] = 100 - (Random() % 16); - } - - // clear AI stack. - AI_STACK->size = 0; - gBankAttacker = gActiveBattler; - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - gBankTarget = Random() & 2; // just pick somebody to target. - - if (gAbsentBattlerFlags & gBitTable[gBankTarget]) - gBankTarget ^= 2; - } - else - gBankTarget = gActiveBattler ^ 1; - - // special AI flag cases. - if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) - AI_THINKING_STRUCT->aiFlags = 0x40000000; - else if (gBattleTypeFlags & BATTLE_TYPE_ROAMER) - AI_THINKING_STRUCT->aiFlags = 0x20000000; - else if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) - AI_THINKING_STRUCT->aiFlags = 0x80000000; -#ifdef GERMAN - else if (gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER) || gTrainerBattleOpponent == SECRET_BASE_OPPONENT) - AI_THINKING_STRUCT->aiFlags = 7; -#endif - else // otherwise, just set aiFlags to whatever flags the trainer has set in their data. - AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent].aiFlags; -#if DEBUG - if (gUnknown_02023A14_50 & 1) - AI_THINKING_STRUCT->aiFlags = gUnknown_02023A14_4C; -#endif -} - -u8 BattleAI_GetAIActionToUse(void) -{ - u8 currentMoveArray[MAX_MON_MOVES]; - u8 consideredMoveArray[MAX_MON_MOVES]; - u8 numOfBestMoves; - s32 i; - - sub_810745C(); - while (AI_THINKING_STRUCT->aiFlags != 0) - { - if (AI_THINKING_STRUCT->aiFlags & 1) - { - AI_THINKING_STRUCT->aiState = BATTLEAI_SETTING_UP; - BattleAI_DoAIProcessing(); - } - AI_THINKING_STRUCT->aiFlags >>= 1; - AI_THINKING_STRUCT->aiLogicId++; - AI_THINKING_STRUCT->movesetIndex = 0; - } - - // special flee or watch cases for safari. - if (AI_THINKING_STRUCT->aiAction & (AI_ACTION_FLEE)) // flee - return 4; - if (AI_THINKING_STRUCT->aiAction & (AI_ACTION_WATCH)) // watch - return 5; - - numOfBestMoves = 1; - currentMoveArray[0] = AI_THINKING_STRUCT->score[0]; - consideredMoveArray[0] = 0; - - for (i = 1; i < MAX_MON_MOVES; i++) - { - if (currentMoveArray[0] < AI_THINKING_STRUCT->score[i]) - { - numOfBestMoves = 1; - currentMoveArray[0] = AI_THINKING_STRUCT->score[i]; - consideredMoveArray[0] = i; - } - if (currentMoveArray[0] == AI_THINKING_STRUCT->score[i]) - { - currentMoveArray[numOfBestMoves] = AI_THINKING_STRUCT->score[i]; - consideredMoveArray[numOfBestMoves++] = i; - } - } - - return consideredMoveArray[Random() % numOfBestMoves]; // break any ties that exist. -} - -void BattleAI_DoAIProcessing(void) -{ - while (AI_THINKING_STRUCT->aiState != BATTLEAI_FINISHED) - { - switch (AI_THINKING_STRUCT->aiState) - { - case BATTLEAI_DO_NOT_PROCESS: //Needed to match. - break; - case BATTLEAI_SETTING_UP: - gAIScriptPtr = BattleAIs[AI_THINKING_STRUCT->aiLogicId]; // set the AI ptr. - if (gBattleMons[gBankAttacker].pp[AI_THINKING_STRUCT->movesetIndex] == 0) - { - AI_THINKING_STRUCT->moveConsidered = MOVE_NONE; // don't consider a move you have 0 PP for, idiot. - } - else - { - AI_THINKING_STRUCT->moveConsidered = gBattleMons[gBankAttacker].moves[AI_THINKING_STRUCT->movesetIndex]; - } - AI_THINKING_STRUCT->aiState++; - break; - case BATTLEAI_PROCESSING: - if (AI_THINKING_STRUCT->moveConsidered != MOVE_NONE) - sBattleAICmdTable[*gAIScriptPtr](); // run AI command. - else - { - AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = 0; // definitely do not consider any move that has 0 PP. - AI_THINKING_STRUCT->aiAction |= AI_ACTION_DONE; - } - if (AI_THINKING_STRUCT->aiAction & AI_ACTION_DONE) - { - AI_THINKING_STRUCT->movesetIndex++; - if (AI_THINKING_STRUCT->movesetIndex < MAX_MON_MOVES && (AI_THINKING_STRUCT->aiAction & AI_ACTION_DO_NOT_ATTACK) == 0) - AI_THINKING_STRUCT->aiState = BATTLEAI_SETTING_UP; // as long as their are more moves to process, keep setting this to setup state. - else - AI_THINKING_STRUCT->aiState++; // done processing. - AI_THINKING_STRUCT->aiAction &= (AI_ACTION_FLEE | AI_ACTION_WATCH | AI_ACTION_DO_NOT_ATTACK | - AI_ACTION_UNK5 | AI_ACTION_UNK6 | AI_ACTION_UNK7 | AI_ACTION_UNK8); // disable AI_ACTION_DONE. - } - break; - } - } -} - -void sub_810745C(void) -{ - s32 i; - - for (i = 0; i < 8; i++) - { - if (AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i] == 0) - { - AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i] = gLastUsedMove[gBankTarget]; - return; - } - } -} - -void unref_sub_81074A0(u8 a) -{ - s32 i; - - for (i = 0; i < 8; i++) - AI_BATTLE_HISTORY->usedMoves[a / 2][i] = 0; -} - -void RecordAbilityBattle(u8 a, u8 b) -{ - if (GetBattlerSide(a) == 0) - AI_BATTLE_HISTORY->abilities[GetBattlerPosition(a) & 1] = b; -} - -void RecordItemBattle(u8 a, u8 b) -{ - if (GetBattlerSide(a) == 0) - AI_BATTLE_HISTORY->itemEffects[GetBattlerPosition(a) & 1] = b; -} - -static void BattleAICmd_if_random_less_than(void) -{ - if (Random() % 256 < gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_random_greater_than(void) -{ - if (Random() % 256 > gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_random_equal(void) -{ - if (Random() % 256 == gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_random_not_equal(void) -{ - if (Random() % 256 != gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_score(void) -{ - AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] += gAIScriptPtr[1]; // add the result to the array of the move consider's score. - - if (AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] < 0) // if the score is negative, flatten it to 0. - AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = 0; - - gAIScriptPtr += 2; // AI return. -} - -static void BattleAICmd_if_hp_less_than(void) -{ - u16 index; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) < gAIScriptPtr[2]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_hp_more_than(void) -{ - u16 index; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) > gAIScriptPtr[2]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_hp_equal(void) -{ - u16 index; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) == gAIScriptPtr[2]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_hp_not_equal(void) -{ - u16 index; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) != gAIScriptPtr[2]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_status(void) -{ - u16 index; - u32 arg; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - arg = T1_READ_32(gAIScriptPtr + 2); - - if ((gBattleMons[index].status1 & arg) != 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_not_status(void) -{ - u16 index; - u32 arg; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - arg = T1_READ_32(gAIScriptPtr + 2); - - if ((gBattleMons[index].status1 & arg) == 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_status2(void) -{ - u16 index; - u32 arg; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - arg = T1_READ_32(gAIScriptPtr + 2); - - if ((gBattleMons[index].status2 & arg) != 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_not_status2(void) -{ - u16 index; - u32 arg; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - arg = T1_READ_32(gAIScriptPtr + 2); - - if ((gBattleMons[index].status2 & arg) == 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_status3(void) -{ - u16 index; - u32 arg; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - arg = T1_READ_32(gAIScriptPtr + 2); - - if ((gStatuses3[index] & arg) != 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_not_status3(void) -{ - u16 index; - u32 arg; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - arg = T1_READ_32(gAIScriptPtr + 2); - - if ((gStatuses3[index] & arg) == 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_status4(void) -{ - u16 index; - u32 arg1, arg2; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - arg1 = GetBattlerPosition(index) & 1; - arg2 = T1_READ_32(gAIScriptPtr + 2); - - if ((gSideAffecting[arg1] & arg2) != 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_not_status4(void) -{ - u16 index; - u32 arg1, arg2; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - arg1 = GetBattlerPosition(index) & 1; - arg2 = T1_READ_32(gAIScriptPtr + 2); - - if ((gSideAffecting[arg1] & arg2) == 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void BattleAICmd_if_less_than(void) -{ - if (AI_THINKING_STRUCT->funcResult < gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_more_than(void) -{ - if (AI_THINKING_STRUCT->funcResult > gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_equal(void) -{ - if (AI_THINKING_STRUCT->funcResult == gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_not_equal(void) -{ - if (AI_THINKING_STRUCT->funcResult != gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_less_than_32(void) -{ - u8 *temp = T1_READ_PTR(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->funcResult < *temp) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void BattleAICmd_if_more_than_32(void) -{ - u8 *temp = T1_READ_PTR(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->funcResult > *temp) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void BattleAICmd_if_equal_32(void) -{ - u8 *temp = T1_READ_PTR(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->funcResult == *temp) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void BattleAICmd_if_not_equal_32(void) -{ - u8 *temp = T1_READ_PTR(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->funcResult != *temp) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void BattleAICmd_if_move(void) -{ - u16 move = T1_READ_16(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->moveConsidered == move) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_not_move(void) -{ - u16 move = T1_READ_16(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->moveConsidered != move) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_in_bytes(void) -{ - u8 *ptr = T1_READ_PTR(gAIScriptPtr + 1); - - while (*ptr != 0xFF) - { - if (AI_THINKING_STRUCT->funcResult == *ptr) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - return; - } - ptr++; - } - gAIScriptPtr += 9; -} - -static void BattleAICmd_if_not_in_bytes(void) -{ - u8 *ptr = T1_READ_PTR(gAIScriptPtr + 1); - - while (*ptr != 0xFF) - { - if (AI_THINKING_STRUCT->funcResult == *ptr) - { - gAIScriptPtr += 9; - return; - } - ptr++; - } - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); -} - -static void BattleAICmd_if_in_words(void) -{ - u16 *ptr = (u16 *)T1_READ_PTR(gAIScriptPtr + 1); - - while (*ptr != 0xFFFF) - { - if (AI_THINKING_STRUCT->funcResult == *ptr) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - return; - } - ptr++; - } - gAIScriptPtr += 9; -} - -static void BattleAICmd_if_not_in_words(void) -{ - u16 *ptr = (u16 *)T1_READ_PTR(gAIScriptPtr + 1); - - while (*ptr != 0xFFFF) - { - if (AI_THINKING_STRUCT->funcResult == *ptr) - { - gAIScriptPtr += 9; - return; - } - ptr++; - } - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); -} - -static void BattleAICmd_if_user_can_damage(void) -{ - s32 i; - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[gBankAttacker].moves[i] != 0 - && gBattleMoves[gBattleMons[gBankAttacker].moves[i]].power != 0) - break; - } - if (i == MAX_MON_MOVES) - gAIScriptPtr += 5; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); -} - -static void BattleAICmd_if_user_cant_damage(void) -{ - s32 i; - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[gBankAttacker].moves[i] != 0 - && gBattleMoves[gBattleMons[gBankAttacker].moves[i]].power != 0) - break; - } - if (i != MAX_MON_MOVES) - gAIScriptPtr += 5; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); -} - -static void BattleAICmd_get_turn_count(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleResults.battleTurnCounter; - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_type(void) -{ - switch (gAIScriptPtr[1]) - { - case 1: // player primary type - AI_THINKING_STRUCT->funcResult = gBattleMons[gBankAttacker].type1; - break; - case 0: // enemy primary type - AI_THINKING_STRUCT->funcResult = gBattleMons[gBankTarget].type1; - break; - case 3: // player secondary type - AI_THINKING_STRUCT->funcResult = gBattleMons[gBankAttacker].type2; - break; - case 2: // enemy secondary type - AI_THINKING_STRUCT->funcResult = gBattleMons[gBankTarget].type2; - break; - case 4: // type of move being pointed to - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].type; - break; - } - gAIScriptPtr += 2; -} - -static void BattleAICmd_get_move_power(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power; - gAIScriptPtr += 1; -} - -#ifdef NONMATCHING -static void BattleAICmd_is_most_powerful_move(void) -{ - int i, j; - s32 damages[MAX_MON_MOVES]; - - for (i = 0; sDiscouragedPowerfulMoveEffects[i] != 0xFFFF; i++) - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect == sDiscouragedPowerfulMoveEffects[i]) - break; - - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power > 1 - && sDiscouragedPowerfulMoveEffects[i] == 0xFFFF) - { - gDynamicBasePower = 0; - eDynamicMoveType = 0; - eDmgMultiplier = 1; - gMoveResultFlags = 0; - gCritMultiplier = 1; - - for (i = 0; i < MAX_MON_MOVES; i++) - { - for (j = 0; sDiscouragedPowerfulMoveEffects[j] != 0xFFFF; j++) - { // _08108276 - if (gBattleMoves[gBattleMons[gBankAttacker].moves[i]].effect == sDiscouragedPowerfulMoveEffects[j]) - break; - } - - // _081082BA - if (gBattleMons[gBankAttacker].moves[i] - && sDiscouragedPowerfulMoveEffects[j] == 0xFFFF - && gBattleMoves[gBattleMons[gBankAttacker].moves[i]].power > 1) - { - gCurrentMove = gBattleMons[gBankAttacker].moves[i]; - AI_CalcDmg(gBankAttacker, gBankTarget); - TypeCalc(gCurrentMove, gBankAttacker, gBankTarget); - damages[i] = (gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[i]) / 100; - - if (damages[i] == 0) // moves always do at least 1 damage. - damages[i] = 1; - } - else - { - damages[i] = 0; - } - } - - for (i = 0; i < MAX_MON_MOVES; i++) - if (damages[i] > damages[AI_THINKING_STRUCT->movesetIndex]) - break; - - if (i == MAX_MON_MOVES) - AI_THINKING_STRUCT->funcResult = 2; - else - AI_THINKING_STRUCT->funcResult = 1; - } - else - { - AI_THINKING_STRUCT->funcResult = 0; - } - - gAIScriptPtr += 1; -} -#else -NAKED -static void BattleAICmd_is_most_powerful_move(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x14\n\ - movs r3, 0\n\ - ldr r0, _08108328 @ =sDiscouragedPowerfulMoveEffects\n\ - ldrh r1, [r0]\n\ - ldr r4, _0810832C @ =0x0000ffff\n\ - ldr r6, _08108330 @ =gBattleMoves\n\ - ldr r5, _08108334 @ =gSharedMem + 0x16800\n\ - cmp r1, r4\n\ - beq _0810822E\n\ - ldrh r1, [r5, 0x2]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldrb r2, [r0]\n\ - ldr r1, _08108328 @ =sDiscouragedPowerfulMoveEffects\n\ -_0810821E:\n\ - ldrh r0, [r1]\n\ - cmp r2, r0\n\ - beq _0810822E\n\ - adds r1, 0x2\n\ - adds r3, 0x1\n\ - ldrh r0, [r1]\n\ - cmp r0, r4\n\ - bne _0810821E\n\ -_0810822E:\n\ - ldrh r0, [r5, 0x2]\n\ - lsls r1, r0, 1\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - adds r1, r6\n\ - ldrb r0, [r1, 0x1]\n\ - cmp r0, 0x1\n\ - bhi _08108240\n\ - b _081083B2\n\ -_08108240:\n\ - lsls r0, r3, 1\n\ - ldr r1, _08108328 @ =sDiscouragedPowerfulMoveEffects\n\ - adds r0, r1\n\ - ldrh r3, [r0]\n\ - ldr r0, _0810832C @ =0x0000ffff\n\ - cmp r3, r0\n\ - beq _08108250\n\ - b _081083B2\n\ -_08108250:\n\ - ldr r0, _08108338 @ =gDynamicBasePower\n\ - movs r1, 0\n\ - strh r1, [r0]\n\ - ldr r2, _0810833C @ =0xfffff81c\n\ - adds r0, r5, r2\n\ - strb r1, [r0]\n\ - adds r2, 0x3\n\ - adds r0, r5, r2\n\ - movs r2, 0x1\n\ - strb r2, [r0]\n\ - ldr r0, _08108340 @ =gMoveResultFlags\n\ - strb r1, [r0]\n\ - ldr r0, _08108344 @ =gCritMultiplier\n\ - strb r2, [r0]\n\ - movs r6, 0\n\ - mov r9, r3\n\ - ldr r0, _08108328 @ =sDiscouragedPowerfulMoveEffects\n\ - ldrh r0, [r0]\n\ - str r0, [sp, 0x10]\n\ -_08108276:\n\ - movs r3, 0\n\ - ldr r5, _08108348 @ =gBattleMons\n\ - lsls r4, r6, 1\n\ - ldr r7, _0810834C @ =gBankAttacker\n\ - lsls r1, r6, 2\n\ - mov r8, r1\n\ - adds r2, r6, 0x1\n\ - mov r10, r2\n\ - ldr r0, [sp, 0x10]\n\ - cmp r0, r9\n\ - beq _081082BA\n\ - ldr r2, _08108330 @ =gBattleMoves\n\ - ldrb r1, [r7]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r4, r0\n\ - adds r1, r5, 0\n\ - adds r1, 0xC\n\ - adds r0, r1\n\ - ldrh r1, [r0]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldrb r2, [r0]\n\ - ldr r1, _08108328 @ =sDiscouragedPowerfulMoveEffects\n\ -_081082AA:\n\ - ldrh r0, [r1]\n\ - cmp r2, r0\n\ - beq _081082BA\n\ - adds r1, 0x2\n\ - adds r3, 0x1\n\ - ldrh r0, [r1]\n\ - cmp r0, r9\n\ - bne _081082AA\n\ -_081082BA:\n\ - ldrb r1, [r7]\n\ - movs r0, 0x58\n\ - muls r0, r1\n\ - adds r0, r4, r0\n\ - adds r1, r5, 0\n\ - adds r1, 0xC\n\ - adds r1, r0, r1\n\ - ldrh r0, [r1]\n\ - cmp r0, 0\n\ - beq _0810835C\n\ - lsls r0, r3, 1\n\ - ldr r2, _08108328 @ =sDiscouragedPowerfulMoveEffects\n\ - adds r0, r2\n\ - ldrh r0, [r0]\n\ - cmp r0, r9\n\ - bne _0810835C\n\ - ldr r0, _08108330 @ =gBattleMoves\n\ - ldrh r2, [r1]\n\ - lsls r1, r2, 1\n\ - adds r1, r2\n\ - lsls r1, 2\n\ - adds r1, r0\n\ - ldrb r0, [r1, 0x1]\n\ - cmp r0, 0x1\n\ - bls _0810835C\n\ - ldr r5, _08108350 @ =gCurrentMove\n\ - strh r2, [r5]\n\ - ldrb r0, [r7]\n\ - ldr r4, _08108354 @ =gBankTarget\n\ - ldrb r1, [r4]\n\ - bl AI_CalcDmg\n\ - ldrh r0, [r5]\n\ - ldrb r1, [r7]\n\ - ldrb r2, [r4]\n\ - bl TypeCalc\n\ - mov r4, sp\n\ - add r4, r8\n\ - ldr r2, _08108358 @ =gBattleMoveDamage\n\ - ldr r0, _08108334 @ =gSharedMem + 0x16800\n\ - adds r0, 0x18\n\ - adds r0, r6, r0\n\ - ldrb r1, [r0]\n\ - ldr r0, [r2]\n\ - muls r0, r1\n\ - movs r1, 0x64\n\ - bl __divsi3\n\ - str r0, [r4]\n\ - cmp r0, 0\n\ - bne _08108364\n\ - movs r0, 0x1\n\ - str r0, [r4]\n\ - b _08108364\n\ - .align 2, 0\n\ -_08108328: .4byte sDiscouragedPowerfulMoveEffects\n\ -_0810832C: .4byte 0x0000ffff\n\ -_08108330: .4byte gBattleMoves\n\ -_08108334: .4byte gSharedMem + 0x16800\n\ -_08108338: .4byte gDynamicBasePower\n\ -_0810833C: .4byte 0xfffff81c\n\ -_08108340: .4byte gMoveResultFlags\n\ -_08108344: .4byte gCritMultiplier\n\ -_08108348: .4byte gBattleMons\n\ -_0810834C: .4byte gBankAttacker\n\ -_08108350: .4byte gCurrentMove\n\ -_08108354: .4byte gBankTarget\n\ -_08108358: .4byte gBattleMoveDamage\n\ -_0810835C:\n\ - mov r1, sp\n\ - add r1, r8\n\ - movs r0, 0\n\ - str r0, [r1]\n\ -_08108364:\n\ - mov r6, r10\n\ - cmp r6, 0x3\n\ - ble _08108276\n\ - movs r6, 0\n\ - ldr r1, _081083A4 @ =gSharedMem + 0x16800\n\ - ldrb r0, [r1, 0x1]\n\ - lsls r0, 2\n\ - add r0, sp\n\ - ldr r2, [sp]\n\ - ldr r0, [r0]\n\ - adds r5, r1, 0\n\ - ldr r4, _081083A8 @ =gAIScriptPtr\n\ - cmp r2, r0\n\ - bgt _0810839A\n\ - adds r3, r5, 0\n\ - mov r2, sp\n\ -_08108384:\n\ - adds r2, 0x4\n\ - adds r6, 0x1\n\ - cmp r6, 0x3\n\ - bgt _0810839A\n\ - ldrb r0, [r3, 0x1]\n\ - lsls r0, 2\n\ - add r0, sp\n\ - ldr r1, [r2]\n\ - ldr r0, [r0]\n\ - cmp r1, r0\n\ - ble _08108384\n\ -_0810839A:\n\ - cmp r6, 0x4\n\ - bne _081083AC\n\ - movs r0, 0x2\n\ - str r0, [r5, 0x8]\n\ - b _081083B8\n\ - .align 2, 0\n\ -_081083A4: .4byte gSharedMem + 0x16800\n\ -_081083A8: .4byte gAIScriptPtr\n\ -_081083AC:\n\ - movs r0, 0x1\n\ - str r0, [r5, 0x8]\n\ - b _081083B8\n\ -_081083B2:\n\ - movs r0, 0\n\ - str r0, [r5, 0x8]\n\ - ldr r4, _081083D0 @ =gAIScriptPtr\n\ -_081083B8:\n\ - ldr r0, [r4]\n\ - adds r0, 0x1\n\ - str r0, [r4]\n\ - add sp, 0x14\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_081083D0: .4byte gAIScriptPtr\n\ - .syntax divided\n"); -} -#endif // NONMATCHING - -static void BattleAICmd_get_move(void) -{ - if (gAIScriptPtr[1] == USER) - AI_THINKING_STRUCT->funcResult = gLastUsedMove[gBankAttacker]; - else - AI_THINKING_STRUCT->funcResult = gLastUsedMove[gBankTarget]; - - gAIScriptPtr += 2; -} - -static void BattleAICmd_if_arg_equal(void) -{ - if (gAIScriptPtr[1] == AI_THINKING_STRUCT->funcResult) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_arg_not_equal(void) -{ - if (gAIScriptPtr[1] != AI_THINKING_STRUCT->funcResult) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_would_go_first(void) -{ - if (GetWhoStrikesFirst(gBankAttacker, gBankTarget, TRUE) == gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_would_not_go_first(void) -{ - if (GetWhoStrikesFirst(gBankAttacker, gBankTarget, TRUE) != gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_nullsub_2A(void) -{ -} - -static void BattleAICmd_nullsub_2B(void) -{ -} - -static void BattleAICmd_count_alive_pokemon(void) -{ - struct Pokemon *party; - int i; - u8 index; - u8 var, var2; - - AI_THINKING_STRUCT->funcResult = 0; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - if (GetBattlerSide(index) == 0) - party = gPlayerParty; - else - party = gEnemyParty; - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - u32 status; - var = gBattlerPartyIndexes[index]; - status = GetBattlerPosition(index) ^ 2; - var2 = gBattlerPartyIndexes[GetBattlerAtPosition(status)]; - } - else - { - var = gBattlerPartyIndexes[index]; - var2 = gBattlerPartyIndexes[index]; - } - - for (i = 0; i < 6; i++) - { - if (i != var && i != var2 - && GetMonData(&party[i], MON_DATA_HP) != 0 - && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_NONE - && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG) - { - AI_THINKING_STRUCT->funcResult++; - } - } - - gAIScriptPtr += 2; -} - -static void BattleAICmd_get_considered_move(void) -{ - AI_THINKING_STRUCT->funcResult = AI_THINKING_STRUCT->moveConsidered; - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_considered_move_effect(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect; - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_ability(void) -{ - u8 index; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - if (GetBattlerSide(index) == TARGET) - { - u16 side = GetBattlerPosition(index) & 1; - - if (AI_BATTLE_HISTORY->abilities[side] != 0) - { - AI_THINKING_STRUCT->funcResult = AI_BATTLE_HISTORY->abilities[side]; - gAIScriptPtr += 2; - return; - } - - // abilities that prevent fleeing. - if (gBattleMons[index].ability == ABILITY_SHADOW_TAG - || gBattleMons[index].ability == ABILITY_MAGNET_PULL - || gBattleMons[index].ability == ABILITY_ARENA_TRAP) - { - AI_THINKING_STRUCT->funcResult = gBattleMons[index].ability; - gAIScriptPtr += 2; - return; - } - - if (gBaseStats[gBattleMons[index].species].ability1 != ABILITY_NONE) - { - if (gBaseStats[gBattleMons[index].species].ability2 != ABILITY_NONE) - { - // AI has no knowledge of opponent, so it guesses which ability. - if (Random() % 2) - { - AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability1; - } - else - { - AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability2; - } - } - else - { - AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability1; // it's definitely ability 1. - } - } - else - { - AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability. - } - } - else - { - // The AI knows its own ability. - AI_THINKING_STRUCT->funcResult = gBattleMons[index].ability; - } - gAIScriptPtr += 2; -} - -static void BattleAICmd_get_highest_possible_damage(void) -{ - s32 i; - - gDynamicBasePower = 0; - gBattleStruct->dynamicMoveType = 0; - gBattleStruct->dmgMultiplier = 1; - gMoveResultFlags = 0; - gCritMultiplier = 1; - AI_THINKING_STRUCT->funcResult = 0; - - for (i = 0; i < MAX_MON_MOVES; i++) - { - gBattleMoveDamage = 40; - gCurrentMove = gBattleMons[gBankAttacker].moves[i]; - - if (gCurrentMove) - { - TypeCalc(gCurrentMove, gBankAttacker, gBankTarget); - - // reduce by 1/3. - if (gBattleMoveDamage == 120) - gBattleMoveDamage = 80; - if (gBattleMoveDamage == 240) - gBattleMoveDamage = 160; - if (gBattleMoveDamage == 30) - gBattleMoveDamage = 20; - if (gBattleMoveDamage == 15) - gBattleMoveDamage = 10; - - if (gMoveResultFlags & 8) // if it's a status move, it wont do anything. - gBattleMoveDamage = 0; - - if (AI_THINKING_STRUCT->funcResult < gBattleMoveDamage) - AI_THINKING_STRUCT->funcResult = gBattleMoveDamage; - } - } - gAIScriptPtr += 1; -} - -static void BattleAICmd_if_damage_bonus(void) -{ - u8 damageVar; - - gDynamicBasePower = 0; - gBattleStruct->dynamicMoveType = 0; - gBattleStruct->dmgMultiplier = 1; - gMoveResultFlags = 0; - gCritMultiplier = 1; - - gBattleMoveDamage = 40; - gCurrentMove = AI_THINKING_STRUCT->moveConsidered; - - TypeCalc(gCurrentMove, gBankAttacker, gBankTarget); - - if (gBattleMoveDamage == 120) - gBattleMoveDamage = 80; - if (gBattleMoveDamage == 240) - gBattleMoveDamage = 160; - if (gBattleMoveDamage == 30) - gBattleMoveDamage = 20; - if (gBattleMoveDamage == 15) - gBattleMoveDamage = 10; - - if (gMoveResultFlags & 8) - gBattleMoveDamage = 0; - - // store gBattleMoveDamage in a u8 variable because gAIScriptPtr[1] is a u8. - damageVar = gBattleMoveDamage; - - if (damageVar == gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_nullsub_32(void) -{ -} - -static void BattleAICmd_nullsub_33(void) -{ -} - -static void BattleAICmd_if_status_in_party(void) -{ - struct Pokemon *party; - struct Pokemon *partyPtr; - int i; - u32 statusToCompareTo; - - // for whatever reason, game freak put the party pointer into 2 variables instead of 1. it's possible at some point the switch encompassed the whole function and used each respective variable creating largely duplicate code. - switch (gAIScriptPtr[1]) - { - case 1: - party = partyPtr = gEnemyParty; - break; - default: - party = partyPtr = gPlayerParty; - break; - } - - statusToCompareTo = T1_READ_32(gAIScriptPtr + 2); - - for (i = 0; i < 6; i++) - { - u16 species = GetMonData(&party[i], MON_DATA_SPECIES); - u16 hp = GetMonData(&party[i], MON_DATA_HP); - u32 status = GetMonData(&party[i], MON_DATA_STATUS); - - if (species != SPECIES_NONE && species != SPECIES_EGG && hp != 0 && status == statusToCompareTo) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); // WHAT. why is this being merged into the above switch - return; - } - } - - gAIScriptPtr += 10; -} - -// bugged, doesnt return properly. also unused -static void BattleAICmd_if_status_not_in_party(void) -{ - struct Pokemon *party; - struct Pokemon *partyPtr; - int i; - u32 statusToCompareTo; - - switch (gAIScriptPtr[1]) - { - case 1: - party = partyPtr = gEnemyParty; - break; - default: - party = partyPtr = gPlayerParty; - break; - } - - statusToCompareTo = T1_READ_32(gAIScriptPtr + 2); - - for (i = 0; i < 6; i++) - { - u16 species = GetMonData(&party[i], MON_DATA_SPECIES); - u16 hp = GetMonData(&party[i], MON_DATA_HP); - u32 status = GetMonData(&party[i], MON_DATA_STATUS); - - // everytime the status is found, the AI's logic jumps further and further past its intended destination. this results in a broken AI macro and is probably why it is unused. - if (species != SPECIES_NONE && species != SPECIES_EGG && hp != 0 && status == statusToCompareTo) - gAIScriptPtr += 10; // doesnt return? - } - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); -} - -static void BattleAICmd_get_weather(void) -{ - if (gBattleWeather & WEATHER_RAIN_ANY) - AI_THINKING_STRUCT->funcResult = WEATHER_TYPE_RAIN; - if (gBattleWeather & WEATHER_SANDSTORM_ANY) - AI_THINKING_STRUCT->funcResult = WEATHER_TYPE_SANDSTORM; - if (gBattleWeather & WEATHER_SUN_ANY) - AI_THINKING_STRUCT->funcResult = WEATHER_TYPE_SUN; - if (gBattleWeather & WEATHER_HAIL) - AI_THINKING_STRUCT->funcResult = WEATHER_TYPE_HAIL; - - gAIScriptPtr += 1; -} - -static void BattleAICmd_if_effect(void) -{ - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect == gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_not_effect(void) -{ - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect != gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void BattleAICmd_if_stat_level_less_than(void) -{ - u32 party; - - if (gAIScriptPtr[1] == USER) - party = gBankAttacker; - else - party = gBankTarget; - - if (gBattleMons[party].statStages[gAIScriptPtr[2]] < gAIScriptPtr[3]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void BattleAICmd_if_stat_level_more_than(void) -{ - u32 party; - - if (gAIScriptPtr[1] == USER) - party = gBankAttacker; - else - party = gBankTarget; - - if (gBattleMons[party].statStages[gAIScriptPtr[2]] > gAIScriptPtr[3]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void BattleAICmd_if_stat_level_equal(void) -{ - u32 party; - - if (gAIScriptPtr[1] == USER) - party = gBankAttacker; - else - party = gBankTarget; - - if (gBattleMons[party].statStages[gAIScriptPtr[2]] == gAIScriptPtr[3]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void BattleAICmd_if_stat_level_not_equal(void) -{ - u32 party; - - if (gAIScriptPtr[1] == USER) - party = gBankAttacker; - else - party = gBankTarget; - - if (gBattleMons[party].statStages[gAIScriptPtr[2]] != gAIScriptPtr[3]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void BattleAICmd_if_can_faint(void) -{ - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power < 2) - { - gAIScriptPtr += 5; - return; - } - - gDynamicBasePower = 0; - gBattleStruct->dynamicMoveType = 0; - gBattleStruct->dmgMultiplier = 1; - gMoveResultFlags = 0; - gCritMultiplier = 1; - gCurrentMove = AI_THINKING_STRUCT->moveConsidered; - AI_CalcDmg(gBankAttacker, gBankTarget); - TypeCalc(gCurrentMove, gBankAttacker, gBankTarget); - - gBattleMoveDamage = gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[AI_THINKING_STRUCT->movesetIndex] / 100; - - // moves always do at least 1 damage. - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - - if (gBattleMons[gBankTarget].hp <= gBattleMoveDamage) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void BattleAICmd_if_cant_faint(void) -{ - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power < 2) - { - gAIScriptPtr += 5; - return; - } - - gDynamicBasePower = 0; - gBattleStruct->dynamicMoveType = 0; - gBattleStruct->dmgMultiplier = 1; - gMoveResultFlags = 0; - gCritMultiplier = 1; - gCurrentMove = AI_THINKING_STRUCT->moveConsidered; - AI_CalcDmg(gBankAttacker, gBankTarget); - TypeCalc(gCurrentMove, gBankAttacker, gBankTarget); - - gBattleMoveDamage = gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[AI_THINKING_STRUCT->movesetIndex] / 100; - - // this macro is missing the damage 0 = 1 assumption. - - if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void BattleAICmd_if_has_move(void) -{ - int i; - u16 *temp_ptr = (u16 *)(gAIScriptPtr + 2); - - switch (gAIScriptPtr[1]) - { - case 1: - case 3: - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[gBankAttacker].moves[i] == *temp_ptr) - break; - } - if (i == MAX_MON_MOVES) - gAIScriptPtr += 8; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - break; - case 0: - case 2: - for (i = 0; i < 8; i++) - { - if (AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i] == *temp_ptr) - break; - } - if (i == 8) - gAIScriptPtr += 8; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - break; - } -} - -static void BattleAICmd_if_dont_have_move(void) -{ - int i; - u16 *temp_ptr = (u16 *)(gAIScriptPtr + 2); - - switch (gAIScriptPtr[1]) - { - case 1: - case 3: - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[gBankAttacker].moves[i] == *temp_ptr) - break; - } - if (i != MAX_MON_MOVES) - gAIScriptPtr += 8; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - break; - case 0: - case 2: - for (i = 0; i < 8; i++) - { - if (AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i] == *temp_ptr) - break; - } - if (i != 8) - gAIScriptPtr += 8; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - break; - } -} - -static void BattleAICmd_if_move_effect(void) -{ - int i; - - switch (gAIScriptPtr[1]) - { - case 1: - case 3: - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[gBankAttacker].moves[i] != 0 && gBattleMoves[gBattleMons[gBankAttacker].moves[i]].effect == gAIScriptPtr[2]) - break; - } - if (i != MAX_MON_MOVES) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; - break; - case 0: - case 2: - for (i = 0; i < 8; i++) - { - if (gBattleMons[gBankAttacker].moves[i] != 0 && gBattleMoves[AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i]].effect == gAIScriptPtr[2]) - break; - } - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - } -} - -static void BattleAICmd_if_not_move_effect(void) -{ - int i; - - switch (gAIScriptPtr[1]) - { - case 1: - case 3: - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[gBankAttacker].moves[i] != 0 && gBattleMoves[gBattleMons[gBankAttacker].moves[i]].effect == gAIScriptPtr[2]) - break; - } - if (i != MAX_MON_MOVES) - gAIScriptPtr += 7; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - break; - case 0: - case 2: - for (i = 0; i < 8; i++) - { - if (AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i] != 0 && gBattleMoves[AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i]].effect == gAIScriptPtr[2]) - break; - } - gAIScriptPtr += 7; - } -} - -static void BattleAICmd_if_last_move_did_damage(void) -{ - u8 index; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - if (gAIScriptPtr[2] == 0) - { - if (gDisableStructs[index].disabledMove == 0) - { - gAIScriptPtr += 7; - return; - } - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - return; - } - else if (gAIScriptPtr[2] != 1) // ignore the macro if its not 0 or 1. - { - gAIScriptPtr += 7; - return; - } - else if (gDisableStructs[index].encoredMove != 0) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - return; - } - gAIScriptPtr += 7; -} - -static void BattleAICmd_if_encored(void) -{ - switch (gAIScriptPtr[1]) - { - case 0: // _08109348 - if (gDisableStructs[gActiveBattler].disabledMove == AI_THINKING_STRUCT->moveConsidered) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - return; - } - gAIScriptPtr += 6; - return; - case 1: // _08109370 - if (gDisableStructs[gActiveBattler].encoredMove == AI_THINKING_STRUCT->moveConsidered) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - return; - } - gAIScriptPtr += 6; - return; - default: - gAIScriptPtr += 6; - return; - } -} - -static void BattleAICmd_flee(void) -{ - AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_FLEE | AI_ACTION_DO_NOT_ATTACK); // what matters is AI_ACTION_FLEE being enabled. -} - -static void BattleAICmd_if_random_100(void) -{ - u8 safariFleeRate = gBattleStruct->safariFleeRate * 5; // safari flee rate, from 0-20 - - if ((u8)(Random() % 100) < safariFleeRate) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void BattleAICmd_watch(void) -{ - AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_WATCH | AI_ACTION_DO_NOT_ATTACK); // what matters is AI_ACTION_WATCH being enabled. -} - -static void BattleAICmd_get_hold_effect(void) -{ - u8 index; - u16 side; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - if (GetBattlerSide(index) == 0) - { - side = (GetBattlerPosition(index) & 1); - AI_THINKING_STRUCT->funcResult = AI_BATTLE_HISTORY->itemEffects[side]; - } - else - AI_THINKING_STRUCT->funcResult = ItemId_GetHoldEffect(gBattleMons[index].item); - - gAIScriptPtr += 2; -} - -static void BattleAICmd_get_gender(void) -{ - u8 index; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - AI_THINKING_STRUCT->funcResult = GetGenderFromSpeciesAndPersonality(gBattleMons[index].species, gBattleMons[index].personality); - - gAIScriptPtr += 2; -} - -static void BattleAICmd_is_first_turn(void) -{ - u8 index; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - AI_THINKING_STRUCT->funcResult = gDisableStructs[index].isFirstTurn; - - gAIScriptPtr += 2; -} - -static void BattleAICmd_get_stockpile_count(void) -{ - u8 index; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - AI_THINKING_STRUCT->funcResult = gDisableStructs[index].stockpileCounter; - - gAIScriptPtr += 2; -} - -static void BattleAICmd_is_double_battle(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleTypeFlags & BATTLE_TYPE_DOUBLE; - - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_used_item(void) -{ - u8 index; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - AI_THINKING_STRUCT->funcResult = AI_ARRAY_160CC(index); - - gAIScriptPtr += 2; -} - -static void BattleAICmd_get_move_type_from_result(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].type; - - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_move_power_from_result(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].power; - - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_move_effect_from_result(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].effect; - - gAIScriptPtr += 1; -} - -static void BattleAICmd_get_protect_count(void) -{ - u8 index; - - if (gAIScriptPtr[1] == USER) - index = gBankAttacker; - else - index = gBankTarget; - - AI_THINKING_STRUCT->funcResult = gDisableStructs[index].protectUses; - - gAIScriptPtr += 2; -} - -static void BattleAICmd_nullsub_52(void) -{ -} - -static void BattleAICmd_nullsub_53(void) -{ -} - -static void BattleAICmd_nullsub_54(void) -{ -} - -static void BattleAICmd_nullsub_55(void) -{ -} - -static void BattleAICmd_nullsub_56(void) -{ -} - -static void BattleAICmd_nullsub_57(void) -{ -} - -static void BattleAICmd_call(void) -{ - AIStackPushVar(gAIScriptPtr + 5); - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); -} - -static void BattleAICmd_jump(void) -{ - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); -} - -static void BattleAICmd_end(void) -{ - if (AIStackPop() == FALSE) - AI_THINKING_STRUCT->aiAction |= AI_ACTION_DONE; -} - -static void BattleAICmd_if_level_compare(void) -{ - switch (gAIScriptPtr[1]) - { - case 0: // greater than - if (gBattleMons[gBankAttacker].level > gBattleMons[gBankTarget].level) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - return; - } - gAIScriptPtr += 6; - return; - case 1: // less than - if (gBattleMons[gBankAttacker].level < gBattleMons[gBankTarget].level) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - return; - } - gAIScriptPtr += 6; - return; - case 2: // equal - if (gBattleMons[gBankAttacker].level == gBattleMons[gBankTarget].level) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - return; - } - gAIScriptPtr += 6; - return; - } -} - -static void BattleAICmd_if_taunted(void) -{ - if (gDisableStructs[gBankTarget].tauntTimer1 != 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void BattleAICmd_if_not_taunted(void) -{ - if (gDisableStructs[gBankTarget].tauntTimer1 == 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -void AIStackPushVar(u8 *var) -{ - AI_STACK->ptr[AI_STACK->size++] = var; -} - -// unused -void AIStackPushAIPtr(void) -{ - AI_STACK->ptr[AI_STACK->size++] = gAIScriptPtr; -} - -bool8 AIStackPop(void) -{ - if (AI_STACK->size != 0) - { - --AI_STACK->size; - gAIScriptPtr = AI_STACK->ptr[AI_STACK->size]; - return TRUE; - } - else - return FALSE; -} diff --git a/src/battle/battle_ai_switch_items.c b/src/battle/battle_ai_switch_items.c deleted file mode 100644 index 4dd7614bf..000000000 --- a/src/battle/battle_ai_switch_items.c +++ /dev/null @@ -1,1008 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_ai_switch_items.h" -#include "battle_script_commands.h" -#include "data2.h" -#include "ewram.h" -#include "pokemon.h" -#include "random.h" -#include "rom_8077ABC.h" -#include "rom3.h" -#include "util.h" -#include "constants/abilities.h" -#include "constants/items.h" -#include "constants/moves.h" -#include "constants/species.h" - -extern u8 gUnknown_02023A14_50; - -extern u8 gLastHitBy[]; -extern u8 gActiveBattler; -extern u16 gBattleTypeFlags; -extern u8 gAbsentBattlerFlags; -extern s32 gBattleMoveDamage; -extern u8 gMoveResultFlags; -extern u16 gDynamicBasePower; -extern u8 gCritMultiplier; -extern u16 gBattlerPartyIndexes[]; -extern u16 gLastLandedMoves[]; -extern const u8 gTypeEffectiveness[]; -extern struct BattlePokemon gBattleMons[]; -extern u32 gStatuses3[MAX_BATTLERS_COUNT]; - -static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng); -static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent); -static bool8 ShouldUseItem(void); - - -static bool8 ShouldSwitchIfPerishSong(void) -{ - if (gStatuses3[gActiveBattler] & STATUS3_PERISH_SONG - && gDisableStructs[gActiveBattler].perishSongTimer1 == 0) - { - ewram160C8arr(GetBattlerPosition(gActiveBattler)) = 6; // gBattleStruct->AI_monToSwitchIntoId[GetBattlerPosition(gActiveBattler)] = 6; - Emitcmd33(1, 2, 0); - return TRUE; - } - - return FALSE; -} - -#ifdef NONMATCHING -static bool8 ShouldSwitchIfWonderGuard(void) -{ - u8 opposingBattler; - u8 moveFlags; - s32 i, j; - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - return FALSE; - - if (gBattleMons[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)].ability != ABILITY_WONDER_GUARD) - return FALSE; - - // check if pokemon has a super effective move - opposingBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - for (i = 0; i < 4; i++) - { - u16 move = gBattleMons[gActiveBattler].moves[i]; - if (move == MOVE_NONE) - continue; - - moveFlags = AI_TypeCalc(move, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability); - if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE) - return FALSE; - } - - // find a pokemon in the party that has a super effective move - for (i = 0; i < 6; i++) - { - if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0 - || GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE - || GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG - || i == gBattlerPartyIndexes[gActiveBattler]) - continue; - - GetMonData(&gEnemyParty[i], MON_DATA_SPECIES); // unused return value - GetMonData(&gEnemyParty[i], MON_DATA_ALT_ABILITY); // unused return value - - opposingBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - for (j = 0; j < 4; j++) - { - u16 move = GetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j); - if (move == MOVE_NONE) - continue; - - moveFlags = AI_TypeCalc(move, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability); - if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE && (Random() % 3) < 2) - { - // we found a mon - ewram160C8arr(GetBattlerPosition(gActiveBattler)) = i; // gBattleStruct->AI_monToSwitchIntoId[GetBattlerPosition(gActiveBattler)] = i; - Emitcmd33(1, B_ACTION_SWITCH, 0); - return TRUE; - } - } - } - - return FALSE; // at this point there is not a single pokemon in the party that has a super effective move against a pokemon with wonder guard -} -#else -NAKED -static bool8 ShouldSwitchIfWonderGuard(void) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r9\n\ - mov r6, r8\n\ - push {r6,r7}\n\ - ldr r0, _0803606C @ =gBattleTypeFlags\n\ - ldrh r1, [r0]\n\ - movs r0, 0x1\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _080360A0\n\ - b _080361C8\n\ - .align 2, 0\n\ -_0803606C: .4byte gBattleTypeFlags\n\ -_08036070:\n\ - ldr r0, _08036094 @ =gActiveBattler\n\ - ldrb r0, [r0]\n\ - bl GetBattlerPosition\n\ - ldr r1, _08036098 @ =gSharedMem\n\ - lsls r0, 24\n\ - lsrs r0, 25\n\ - ldr r2, _0803609C @ =0x000160c8\n\ - adds r0, r2\n\ - adds r0, r1\n\ - strb r6, [r0]\n\ - movs r0, 0x1\n\ - movs r1, 0x2\n\ - movs r2, 0\n\ - bl Emitcmd33\n\ - movs r0, 0x1\n\ - b _080361CA\n\ - .align 2, 0\n\ -_08036094: .4byte gActiveBattler\n\ -_08036098: .4byte gSharedMem\n\ -_0803609C: .4byte 0x000160c8\n\ -_080360A0:\n\ - ldr r4, _080361D8 @ =gBattleMons\n\ - movs r0, 0\n\ - bl GetBattlerAtPosition\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - movs r1, 0x58\n\ - muls r0, r1\n\ - adds r0, r4\n\ - adds r0, 0x20\n\ - ldrb r0, [r0]\n\ - cmp r0, 0x19\n\ - beq _080360BC\n\ - b _080361C8\n\ -_080360BC:\n\ - movs r0, 0\n\ - bl GetBattlerAtPosition\n\ - lsls r0, 24\n\ - lsrs r2, r0, 24\n\ - movs r6, 0\n\ - adds r7, r4, 0\n\ - movs r5, 0x58\n\ - adds r0, r2, 0\n\ - muls r0, r5\n\ - adds r4, r0, r7\n\ - movs r3, 0x20\n\ - adds r3, r4\n\ - mov r8, r3\n\ -_080360D8:\n\ - lsls r1, r6, 1\n\ - ldr r0, _080361DC @ =gActiveBattler\n\ - ldrb r0, [r0]\n\ - muls r0, r5\n\ - adds r1, r0\n\ - adds r0, r7, 0\n\ - adds r0, 0xC\n\ - adds r1, r0\n\ - ldrh r0, [r1]\n\ - cmp r0, 0\n\ - beq _08036104\n\ - ldrh r1, [r4]\n\ - mov r3, r8\n\ - ldrb r2, [r3]\n\ - bl AI_TypeCalc\n\ - lsls r0, 24\n\ - lsrs r1, r0, 24\n\ - movs r0, 0x2\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - bne _080361C8\n\ -_08036104:\n\ - adds r6, 0x1\n\ - cmp r6, 0x3\n\ - ble _080360D8\n\ - movs r6, 0\n\ - ldr r0, _080361E0 @ =gEnemyParty\n\ - mov r9, r0\n\ -_08036110:\n\ - movs r0, 0x64\n\ - adds r5, r6, 0\n\ - muls r5, r0\n\ - mov r2, r9\n\ - adds r4, r5, r2\n\ - adds r0, r4, 0\n\ - movs r1, 0x39\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _080361C2\n\ - adds r0, r4, 0\n\ - movs r1, 0x41\n\ - bl GetMonData\n\ - cmp r0, 0\n\ - beq _080361C2\n\ - adds r0, r4, 0\n\ - movs r1, 0x41\n\ - bl GetMonData\n\ - movs r1, 0xCE\n\ - lsls r1, 1\n\ - cmp r0, r1\n\ - beq _080361C2\n\ - ldr r1, _080361E4 @ =gBattlerPartyIndexes\n\ - ldr r0, _080361DC @ =gActiveBattler\n\ - ldrb r0, [r0]\n\ - lsls r0, 1\n\ - adds r0, r1\n\ - ldrh r0, [r0]\n\ - cmp r6, r0\n\ - beq _080361C2\n\ - adds r0, r4, 0\n\ - movs r1, 0xB\n\ - bl GetMonData\n\ - adds r0, r4, 0\n\ - movs r1, 0x2E\n\ - bl GetMonData\n\ - movs r0, 0\n\ - bl GetBattlerAtPosition\n\ - lsls r0, 24\n\ - lsrs r2, r0, 24\n\ - movs r4, 0\n\ - mov r8, r5\n\ - ldr r1, _080361D8 @ =gBattleMons\n\ - movs r0, 0x58\n\ - muls r0, r2\n\ - adds r5, r0, r1\n\ - adds r7, r5, 0\n\ - adds r7, 0x20\n\ -_0803617C:\n\ - adds r1, r4, 0\n\ - adds r1, 0xD\n\ - mov r0, r8\n\ - add r0, r9\n\ - bl GetMonData\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - cmp r0, 0\n\ - beq _080361BC\n\ - ldrh r1, [r5]\n\ - ldrb r2, [r7]\n\ - bl AI_TypeCalc\n\ - lsls r0, 24\n\ - lsrs r1, r0, 24\n\ - movs r0, 0x2\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - beq _080361BC\n\ - bl Random\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - movs r1, 0x3\n\ - bl __umodsi3\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - cmp r0, 0x1\n\ - bhi _080361BC\n\ - b _08036070\n\ -_080361BC:\n\ - adds r4, 0x1\n\ - cmp r4, 0x3\n\ - ble _0803617C\n\ -_080361C2:\n\ - adds r6, 0x1\n\ - cmp r6, 0x5\n\ - ble _08036110\n\ -_080361C8:\n\ - movs r0, 0\n\ -_080361CA:\n\ - pop {r3,r4}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - pop {r4-r7}\n\ - pop {r1}\n\ - bx r1\n\ - .align 2, 0\n\ -_080361D8: .4byte gBattleMons\n\ -_080361DC: .4byte gActiveBattler\n\ -_080361E0: .4byte gEnemyParty\n\ -_080361E4: .4byte gBattlerPartyIndexes\n\ - .syntax divided\n"); -} -#endif // NONMATCHING - -static bool8 FindMonThatAbsorbsOpponentsMove(void) -{ - u8 battlerIn1, battlerIn2; - u8 absorbingTypeAbility; - s32 i; - - if (HasSuperEffectiveMoveAgainstOpponents(TRUE) && Random() % 3 != 0) - return FALSE; - if (gLastLandedMoves[gActiveBattler] == 0) - return FALSE; - if (gLastLandedMoves[gActiveBattler] == 0xFFFF) - return FALSE; - if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0) - return FALSE; - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - battlerIn1 = gActiveBattler; - if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))]) - battlerIn2 = gActiveBattler; - else - battlerIn2 = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))); - } - else - { - battlerIn1 = gActiveBattler; - battlerIn2 = gActiveBattler; - } - - if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_FIRE) - absorbingTypeAbility = ABILITY_FLASH_FIRE; - else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_WATER) - absorbingTypeAbility = ABILITY_WATER_ABSORB; - else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_ELECTRIC) - absorbingTypeAbility = ABILITY_VOLT_ABSORB; - else - return FALSE; - - if (gBattleMons[gActiveBattler].ability == absorbingTypeAbility) - return FALSE; - - for (i = 0; i < 6; i++) - { - u16 species; - u8 monAbility; - - if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0) - continue; - if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE) - continue; - if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG) - continue; - if (i == gBattlerPartyIndexes[battlerIn1]) - continue; - if (i == gBattlerPartyIndexes[battlerIn2]) - continue; - if (i == ewram16068arr(battlerIn1)) - continue; - if (i == ewram16068arr(battlerIn2)) - continue; - - species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES); - if (GetMonData(&gEnemyParty[i], MON_DATA_ALT_ABILITY) != 0) - monAbility = gBaseStats[species].ability2; - else - monAbility = gBaseStats[species].ability1; - - if (absorbingTypeAbility == monAbility && Random() & 1) - { - // we found a mon - ewram160C8arr(GetBattlerPosition(gActiveBattler)) = i; - Emitcmd33(1, B_ACTION_SWITCH, 0); - return TRUE; - } - } - - return FALSE; -} - -static bool8 ShouldSwitchIfNaturalCure(void) -{ - if (!(gBattleMons[gActiveBattler].status1 & STATUS_SLEEP)) - return FALSE; - if (gBattleMons[gActiveBattler].ability != ABILITY_NATURAL_CURE) - return FALSE; - if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 2) - return FALSE; - - if ((gLastLandedMoves[gActiveBattler] == 0 || gLastLandedMoves[gActiveBattler] == 0xFFFF) && Random() & 1) - { - ewram160C8arr(GetBattlerPosition(gActiveBattler)) = 6; - Emitcmd33(1, B_ACTION_SWITCH, 0); - return TRUE; - } - else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0 && Random() & 1) - { - ewram160C8arr(GetBattlerPosition(gActiveBattler)) = 6; - Emitcmd33(1, B_ACTION_SWITCH, 0); - return TRUE; - } - - if (FindMonWithFlagsAndSuperEffective(MOVE_RESULT_DOESNT_AFFECT_FOE, 1)) - return TRUE; - if (FindMonWithFlagsAndSuperEffective(MOVE_RESULT_NOT_VERY_EFFECTIVE, 1)) - return TRUE; - if (Random() & 1) - { - ewram160C8arr(GetBattlerPosition(gActiveBattler)) = 6; - Emitcmd33(1, B_ACTION_SWITCH, 0); - return TRUE; - } - - return FALSE; -} - -static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng) -{ - u8 opposingBattler; - s32 i; - u8 moveFlags; - u16 move; - - opposingBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - if (!(gAbsentBattlerFlags & gBitTable[opposingBattler])) - { - for (i = 0; i < 4; i++) - { - move = gBattleMons[gActiveBattler].moves[i]; - if (move == MOVE_NONE) - continue; - - moveFlags = AI_TypeCalc(move, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability); - if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE) - { - if (noRng) - return TRUE; - if (Random() % 10 != 0) - return TRUE; - } - } - } - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - return FALSE; - - opposingBattler = GetBattlerAtPosition(BATTLE_PARTNER(B_POSITION_PLAYER_LEFT)); - if (!(gAbsentBattlerFlags & gBitTable[opposingBattler])) - { - for (i = 0; i < 4; i++) - { - move = gBattleMons[gActiveBattler].moves[i]; - if (move == MOVE_NONE) - continue; - - moveFlags = AI_TypeCalc(move, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability); - if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE) - { - if (noRng) - return TRUE; - if (Random() % 10 != 0) - return TRUE; - } - } - } - - return FALSE; -} - -static bool8 AreStatsRaised(void) -{ - u8 buffedStatsValue = 0; - s32 i; - - for (i = 0; i < BATTLE_STATS_NO; i++) - { - if (gBattleMons[gActiveBattler].statStages[i] > 6) - buffedStatsValue += gBattleMons[gActiveBattler].statStages[i] - 6; - } - - return (buffedStatsValue > 3); -} - -static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent) -{ - u8 battlerIn1, battlerIn2; - s32 i, j; - u16 move; - u8 moveFlags; - - if (gLastLandedMoves[gActiveBattler] == 0) - return FALSE; - if (gLastLandedMoves[gActiveBattler] == 0xFFFF) - return FALSE; - if (gLastHitBy[gActiveBattler] == 0xFF) - return FALSE; - if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0) - return FALSE; - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - battlerIn1 = gActiveBattler; - if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))]) - battlerIn2 = gActiveBattler; - else - battlerIn2 = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))); - } - else - { - battlerIn1 = gActiveBattler; - battlerIn2 = gActiveBattler; - } - - for (i = 0; i < 6; i++) - { - u16 species; - u8 monAbility; - - if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0) - continue; - if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE) - continue; - if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG) - continue; - if (i == gBattlerPartyIndexes[battlerIn1]) - continue; - if (i == gBattlerPartyIndexes[battlerIn2]) - continue; - if (i == ewram16068arr(battlerIn1)) - continue; - if (i == ewram16068arr(battlerIn2)) - continue; - - species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES); - if (GetMonData(&gEnemyParty[i], MON_DATA_ALT_ABILITY) != 0) - monAbility = gBaseStats[species].ability2; - else - monAbility = gBaseStats[species].ability1; - - moveFlags = AI_TypeCalc(gLastLandedMoves[gActiveBattler], species, monAbility); - if (moveFlags & flags) - { - battlerIn1 = gLastHitBy[gActiveBattler]; - - for (j = 0; j < 4; j++) - { - move = GetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j); - if (move == 0) - continue; - - moveFlags = AI_TypeCalc(move, gBattleMons[battlerIn1].species, gBattleMons[battlerIn1].ability); - if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE && Random() % moduloPercent == 0) - { - ewram160C8arr(GetBattlerPosition(gActiveBattler)) = i; - Emitcmd33(1, B_ACTION_SWITCH, 0); - return TRUE; - } - } - } - } - - return FALSE; -} - -static bool8 ShouldSwitch(void) -{ - u8 battlerIn1, battlerIn2; - s32 i; - s32 availableToSwitch; - - if (gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) - return FALSE; - if (gStatuses3[gActiveBattler] & STATUS3_ROOTED) - return FALSE; - if (AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBattler, ABILITY_SHADOW_TAG, 0, 0)) - return FALSE; - if (AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBattler, ABILITY_ARENA_TRAP, 0, 0)) - return FALSE; // misses the flying or levitate check - if (AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MAGNET_PULL, 0, 0)) - { - if (gBattleMons[gActiveBattler].type1 == TYPE_STEEL) - return FALSE; - if (gBattleMons[gActiveBattler].type2 == TYPE_STEEL) - return FALSE; - } - - availableToSwitch = 0; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - battlerIn1 = gActiveBattler; - if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ BIT_FLANK)]) - battlerIn2 = gActiveBattler; - else - battlerIn2 = GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ BIT_FLANK); - } - else - { - battlerIn1 = gActiveBattler; - battlerIn2 = gActiveBattler; - } - - for (i = 0; i < 6; i++) - { - if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0) - continue; - if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE) - continue; - if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG) - continue; - if (i == gBattlerPartyIndexes[battlerIn1]) - continue; - if (i == gBattlerPartyIndexes[battlerIn2]) - continue; - if (i == ewram16068arr(battlerIn1)) - continue; - if (i == ewram16068arr(battlerIn2)) - continue; - - availableToSwitch++; - } - - if (availableToSwitch == 0) - return FALSE; - if (ShouldSwitchIfPerishSong()) - return TRUE; - if (ShouldSwitchIfWonderGuard()) - return TRUE; - if (FindMonThatAbsorbsOpponentsMove()) - return TRUE; - if (ShouldSwitchIfNaturalCure()) - return TRUE; - if (HasSuperEffectiveMoveAgainstOpponents(FALSE)) - return FALSE; - if (AreStatsRaised()) - return FALSE; - if (FindMonWithFlagsAndSuperEffective(MOVE_RESULT_DOESNT_AFFECT_FOE, 2) - || FindMonWithFlagsAndSuperEffective(MOVE_RESULT_NOT_VERY_EFFECTIVE, 3)) - return TRUE; - - return FALSE; -} - -void AI_TrySwitchOrUseItem(void) -{ - u8 battlerIn1, battlerIn2; - - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - { - if (ShouldSwitch()) - { - if (ewram160C8arr(GetBattlerPosition(gActiveBattler)) == 6) - { - s32 monToSwitchId = GetMostSuitableMonToSwitchInto(); - if (monToSwitchId == 6) - { - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - battlerIn2 = battlerIn1; - } - else - { - battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - battlerIn2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); - } - - for (monToSwitchId = 0; monToSwitchId < 6; monToSwitchId++) - { - if (GetMonData(&gEnemyParty[monToSwitchId], MON_DATA_HP) == 0) - continue; - if (monToSwitchId == gBattlerPartyIndexes[battlerIn1]) - continue; - if (monToSwitchId == gBattlerPartyIndexes[battlerIn2]) - continue; - if (monToSwitchId == ewram16068arr(battlerIn1)) - continue; - if (monToSwitchId == ewram16068arr(battlerIn2)) - continue; - - break; - } - } - - ewram160C8arr(GetBattlerPosition(gActiveBattler)) = monToSwitchId; - } - - ewram16068arr(gActiveBattler) = ewram160C8arr(GetBattlerPosition(gActiveBattler)); - return; - } - else - { - #if DEBUG - if (!(gUnknown_02023A14_50 & 0x20) && ShouldUseItem()) - return; - #else - if (ShouldUseItem()) - return; - #endif - } - } - - Emitcmd33(1, B_ACTION_USE_MOVE, (gActiveBattler ^ BIT_SIDE) << 8); -} - -static void ModulateByTypeEffectiveness(u8 attackType, u8 defenseType1, u8 defenseType2, u8 *var) -{ - s32 i = 0; - - while (TYPE_EFFECT_ATK_TYPE(i) != TYPE_ENDTABLE) - { - if (TYPE_EFFECT_ATK_TYPE(i) == TYPE_FORESIGHT) - { - i += 3; - continue; - } - else if (TYPE_EFFECT_ATK_TYPE(i) == attackType) - { - // check type1 - if (TYPE_EFFECT_DEF_TYPE(i) == defenseType1) - *var = (*var * TYPE_EFFECT_MULTIPLIER(i)) / 10; - // check type2 - if (TYPE_EFFECT_DEF_TYPE(i) == defenseType2 && defenseType1 != defenseType2) - *var = (*var * TYPE_EFFECT_MULTIPLIER(i)) / 10; - } - i += 3; - } -} - -u8 GetMostSuitableMonToSwitchInto(void) -{ - u8 opposingBattler; - u8 bestDmg; // note : should be changed to s32 - u8 bestMonId; - u8 battlerIn1, battlerIn2; - s32 i, j; - u8 invalidMons; - u16 move; - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - battlerIn1 = gActiveBattler; - if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ BIT_FLANK)]) - battlerIn2 = gActiveBattler; - else - battlerIn2 = GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ BIT_FLANK); - - // UB: It considers the opponent only player's side even though it can battle alongside player; - opposingBattler = Random() & BIT_FLANK; - if (gAbsentBattlerFlags & gBitTable[opposingBattler]) - opposingBattler ^= BIT_FLANK; - } - else - { - opposingBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - battlerIn1 = gActiveBattler; - battlerIn2 = gActiveBattler; - } - - invalidMons = 0; - - while (invalidMons != 0x3F) // all mons are invalid - { - bestDmg = 0; - bestMonId = 6; - // find the mon which type is the most suitable offensively - for (i = 0; i < 6; i++) - { - u16 species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES); - if (species != SPECIES_NONE - && GetMonData(&gEnemyParty[i], MON_DATA_HP) != 0 - && !(gBitTable[i] & invalidMons) - && gBattlerPartyIndexes[battlerIn1] != i - && gBattlerPartyIndexes[battlerIn2] != i - && i != ewram16068arr(battlerIn1) - && i != ewram16068arr(battlerIn2)) - { - u8 type1 = gBaseStats[species].type1; - u8 type2 = gBaseStats[species].type2; - u8 typeDmg = 10; - ModulateByTypeEffectiveness(gBattleMons[opposingBattler].type1, type1, type2, &typeDmg); - ModulateByTypeEffectiveness(gBattleMons[opposingBattler].type2, type1, type2, &typeDmg); - if (bestDmg < typeDmg) - { - bestDmg = typeDmg; - bestMonId = i; - } - } - else - { - invalidMons |= gBitTable[i]; - } - } - - // ok, we know the mon has the right typing but does it have at least one super effective move? - if (bestMonId != 6) - { - for (i = 0; i < 4; i++) - { - move = GetMonData(&gEnemyParty[bestMonId], MON_DATA_MOVE1 + i); - if (move != MOVE_NONE && TypeCalc(move, gActiveBattler, opposingBattler) & MOVE_RESULT_SUPER_EFFECTIVE) - break; - } - - if (i != 4) - return bestMonId; // has both the typing and at least one super effective move - - invalidMons |= gBitTable[bestMonId]; // sorry buddy, we want something better - } - else - { - invalidMons = 0x3F; // no viable mon to switch - } - } - - gDynamicBasePower = 0; - gBattleStruct->dynamicMoveType = 0; - gBattleStruct->dmgMultiplier = 1; - gMoveResultFlags = 0; - gCritMultiplier = 1; - bestDmg = 0; - bestMonId = 6; - - // if we couldn't find the best mon in terms of typing, find the one that deals most damage - for (i = 0; i < 6; i++) - { - if ((u16)(GetMonData(&gEnemyParty[i], MON_DATA_SPECIES)) == SPECIES_NONE) - continue; - if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0) - continue; - if (gBattlerPartyIndexes[battlerIn1] == i) - continue; - if (gBattlerPartyIndexes[battlerIn2] == i) - continue; - if (i == ewram16068arr(battlerIn1)) - continue; - if (i == ewram16068arr(battlerIn2)) - continue; - - for (j = 0; j < 4; j++) - { - move = GetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j); - gBattleMoveDamage = 0; - if (move != MOVE_NONE && gBattleMoves[move].power != 1) - { - AI_CalcDmg(gActiveBattler, opposingBattler); - TypeCalc(move, gActiveBattler, opposingBattler); - } - if (bestDmg < gBattleMoveDamage) - { - bestDmg = gBattleMoveDamage; - bestMonId = i; - } - } - } - - return bestMonId; -} - -// TODO: use PokemonItemEffect struct instead of u8 once it's documented -static u8 GetAI_ItemType(u8 itemId, const u8 *itemEffect) // NOTE: should take u16 as item Id argument -{ - if (itemId == ITEM_FULL_RESTORE) - return AI_ITEM_FULL_RESTORE; - if (itemEffect[4] & 4) - return AI_ITEM_HEAL_HP; - if (itemEffect[3] & 0x3F) - return AI_ITEM_CURE_CONDITION; - if (itemEffect[0] & 0x3F || itemEffect[1] != 0 || itemEffect[2] != 0) - return AI_ITEM_X_STAT; - if (itemEffect[3] & 0x80) - return AI_ITEM_GUARD_SPECS; - - return AI_ITEM_NOT_RECOGNIZABLE; -} - -static bool8 ShouldUseItem(void) -{ - s32 i; - u8 validMons = 0; - bool8 shouldUse = FALSE; - - for (i = 0; i < 6; i++) - { - if (GetMonData(&gEnemyParty[i], MON_DATA_HP) != 0 - && GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) != SPECIES_NONE - && GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) != SPECIES_EGG) - { - validMons++; - } - } - - for (i = 0; i < 4; i++) - { - u16 item; - const u8 *itemEffects; - u8 paramOffset; - u8 battlerSide; - - if (i != 0 && validMons > (AI_BATTLE_HISTORY->numItems - i) + 1) - continue; - item = AI_BATTLE_HISTORY->trainerItems[i]; - if (item == ITEM_NONE) - continue; - if (gItemEffectTable[item - 13] == NULL) - continue; - - if (item == ITEM_ENIGMA_BERRY) - itemEffects = gSaveBlock1.enigmaBerry.itemEffect; - else - itemEffects = gItemEffectTable[item - 13]; - - ewram160D8(gActiveBattler) = GetAI_ItemType(item, itemEffects); - - switch (ewram160D8(gActiveBattler)) - { - case AI_ITEM_FULL_RESTORE: - if (gBattleMons[gActiveBattler].hp >= gBattleMons[gActiveBattler].maxHP / 4) - break; - if (gBattleMons[gActiveBattler].hp == 0) - break; - shouldUse = TRUE; - break; - case AI_ITEM_HEAL_HP: - paramOffset = GetItemEffectParamOffset(item, 4, 4); - if (paramOffset == 0) - break; - if (gBattleMons[gActiveBattler].hp == 0) - break; - if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 4 || gBattleMons[gActiveBattler].maxHP - gBattleMons[gActiveBattler].hp > itemEffects[paramOffset]) - shouldUse = TRUE; - break; - case AI_ITEM_CURE_CONDITION: - ewram160DA(gActiveBattler) = 0; - if (itemEffects[3] & 0x20 && gBattleMons[gActiveBattler].status1 & STATUS_SLEEP) - { - ewram160DA(gActiveBattler) |= 0x20; - shouldUse = TRUE; - } - if (itemEffects[3] & 0x10 && (gBattleMons[gActiveBattler].status1 & STATUS_POISON || gBattleMons[gActiveBattler].status1 & STATUS_TOXIC_POISON)) - { - ewram160DA(gActiveBattler) |= 0x10; - shouldUse = TRUE; - } - if (itemEffects[3] & 0x8 && gBattleMons[gActiveBattler].status1 & STATUS_BURN) - { - ewram160DA(gActiveBattler) |= 0x8; - shouldUse = TRUE; - } - if (itemEffects[3] & 0x4 && gBattleMons[gActiveBattler].status1 & STATUS_FREEZE) - { - ewram160DA(gActiveBattler) |= 0x4; - shouldUse = TRUE; - } - if (itemEffects[3] & 0x2 && gBattleMons[gActiveBattler].status1 & STATUS_PARALYSIS) - { - ewram160DA(gActiveBattler) |= 0x2; - shouldUse = TRUE; - } - if (itemEffects[3] & 0x1 && gBattleMons[gActiveBattler].status2 & STATUS2_CONFUSION) - { - ewram160DA(gActiveBattler) |= 0x1; - shouldUse = TRUE; - } - break; - case AI_ITEM_X_STAT: - ewram160DA(gActiveBattler) = 0; - if (gDisableStructs[gActiveBattler].isFirstTurn == 0) - break; - if (itemEffects[0] & 0xF) - ewram160DA(gActiveBattler) |= 0x1; - if (itemEffects[1] & 0xF0) - ewram160DA(gActiveBattler) |= 0x2; - if (itemEffects[1] & 0xF) - ewram160DA(gActiveBattler) |= 0x4; - if (itemEffects[2] & 0xF) - ewram160DA(gActiveBattler) |= 0x8; - if (itemEffects[2] & 0xF0) - ewram160DA(gActiveBattler) |= 0x20; - if (itemEffects[0] & 0x30) - ewram160DA(gActiveBattler) |= 0x80; - shouldUse = TRUE; - break; - case AI_ITEM_GUARD_SPECS: - battlerSide = GetBattlerSide(gActiveBattler); - if (gDisableStructs[gActiveBattler].isFirstTurn != 0 && gSideTimers[battlerSide].mistTimer == 0) - shouldUse = TRUE; - break; - case AI_ITEM_NOT_RECOGNIZABLE: - return FALSE; - } - - if (shouldUse) - { - Emitcmd33(1, B_ACTION_USE_ITEM, 0); - ewram160D4(gActiveBattler) = item; - AI_BATTLE_HISTORY->trainerItems[i] = 0; - return shouldUse; - } - } - - return FALSE; -} diff --git a/src/battle/battle_anim.c b/src/battle/battle_anim.c deleted file mode 100644 index 287d80ab1..000000000 --- a/src/battle/battle_anim.c +++ /dev/null @@ -1,3236 +0,0 @@ -#include "global.h" -#include "battle_anim.h" -#include "battle.h" -#include "battle_anim_80CA710.h" -#include "battle_interface.h" -#include "contest.h" -#include "decompress.h" -#include "m4a.h" -#include "main.h" -#include "palette.h" -#include "rom_8077ABC.h" -#include "sound.h" -#include "sprite.h" -#include "task.h" -#include "ewram.h" -#include "graphics.h" -#include "constants/battle_anim.h" -#include "constants/songs.h" - -const struct OamData gOamData_837DF24 = -{ - .affineMode = 0, - .objMode = 0, - .shape = 0, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837DF2C = -{ - .affineMode = 0, - .objMode = 0, - .shape = 0, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837DF34 = -{ - .affineMode = 0, - .objMode = 0, - .shape = 0, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837DF3C = -{ - .affineMode = 0, - .objMode = 0, - .shape = 0, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837DF44 = -{ - .affineMode = 0, - .objMode = 0, - .shape = 1, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837DF4C = -{ - .affineMode = 0, - .objMode = 0, - .shape = 1, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837DF54 = -{ - .affineMode = 0, - .objMode = 0, - .shape = 1, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837DF5C = -{ - .affineMode = 0, - .objMode = 0, - .shape = 1, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837DF64 = -{ - .affineMode = 0, - .objMode = 0, - .shape = 2, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837DF6C = -{ - .affineMode = 0, - .objMode = 0, - .shape = 2, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837DF74 = -{ - .affineMode = 0, - .objMode = 0, - .shape = 2, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837DF7C = -{ - .affineMode = 0, - .objMode = 0, - .shape = 2, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837DF84 = -{ - .affineMode = 1, - .objMode = 0, - .shape = 0, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837DF8C = -{ - .affineMode = 1, - .objMode = 0, - .shape = 0, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837DF94 = -{ - .affineMode = 1, - .objMode = 0, - .shape = 0, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837DF9C = -{ - .affineMode = 1, - .objMode = 0, - .shape = 0, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837DFA4 = -{ - .affineMode = 1, - .objMode = 0, - .shape = 1, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837DFAC = -{ - .affineMode = 1, - .objMode = 0, - .shape = 1, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837DFB4 = -{ - .affineMode = 1, - .objMode = 0, - .shape = 1, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837DFBC = -{ - .affineMode = 1, - .objMode = 0, - .shape = 1, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837DFC4 = -{ - .affineMode = 1, - .objMode = 0, - .shape = 2, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837DFCC = -{ - .affineMode = 1, - .objMode = 0, - .shape = 2, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837DFD4 = -{ - .affineMode = 1, - .objMode = 0, - .shape = 2, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837DFDC = -{ - .affineMode = 1, - .objMode = 0, - .shape = 2, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837DFE4 = -{ - .affineMode = 3, - .objMode = 0, - .shape = 0, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837DFEC = -{ - .affineMode = 3, - .objMode = 0, - .shape = 0, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837DFF4 = -{ - .affineMode = 3, - .objMode = 0, - .shape = 0, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837DFFC = -{ - .affineMode = 3, - .objMode = 0, - .shape = 0, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837D004 = -{ - .affineMode = 3, - .objMode = 0, - .shape = 1, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837D00C = -{ - .affineMode = 3, - .objMode = 0, - .shape = 1, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837E014 = -{ - .affineMode = 3, - .objMode = 0, - .shape = 1, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837E01C = -{ - .affineMode = 3, - .objMode = 0, - .shape = 1, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837E024 = -{ - .affineMode = 3, - .objMode = 0, - .shape = 2, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837E02C = -{ - .affineMode = 3, - .objMode = 0, - .shape = 2, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837E034 = -{ - .affineMode = 3, - .objMode = 0, - .shape = 2, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837E03C = -{ - .affineMode = 3, - .objMode = 0, - .shape = 2, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837E044 = -{ - .affineMode = 0, - .objMode = 1, - .shape = 0, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837E04C = -{ - .affineMode = 0, - .objMode = 1, - .shape = 0, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837E054 = -{ - .affineMode = 0, - .objMode = 1, - .shape = 0, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837E05C = -{ - .affineMode = 0, - .objMode = 1, - .shape = 0, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837E064 = -{ - .affineMode = 0, - .objMode = 1, - .shape = 1, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837E06C = -{ - .affineMode = 0, - .objMode = 1, - .shape = 1, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837E074 = -{ - .affineMode = 0, - .objMode = 1, - .shape = 1, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837E07C = -{ - .affineMode = 0, - .objMode = 1, - .shape = 1, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837E084 = -{ - .affineMode = 0, - .objMode = 1, - .shape = 2, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837E08C = -{ - .affineMode = 0, - .objMode = 1, - .shape = 2, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837E094 = -{ - .affineMode = 0, - .objMode = 1, - .shape = 2, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837E09C = -{ - .affineMode = 0, - .objMode = 1, - .shape = 2, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837E0A4 = -{ - .affineMode = 1, - .objMode = 1, - .shape = 0, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837E0AC = -{ - .affineMode = 1, - .objMode = 1, - .shape = 0, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837E0B4 = -{ - .affineMode = 1, - .objMode = 1, - .shape = 0, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837E0BC = -{ - .affineMode = 1, - .objMode = 1, - .shape = 0, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837E0C4 = -{ - .affineMode = 1, - .objMode = 1, - .shape = 1, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837E0CC = -{ - .affineMode = 1, - .objMode = 1, - .shape = 1, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837E0D4 = -{ - .affineMode = 1, - .objMode = 1, - .shape = 1, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837E0DC = -{ - .affineMode = 1, - .objMode = 1, - .shape = 1, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837E0E4 = -{ - .affineMode = 1, - .objMode = 1, - .shape = 2, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837E0EC = -{ - .affineMode = 1, - .objMode = 1, - .shape = 2, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837E0F4 = -{ - .affineMode = 1, - .objMode = 1, - .shape = 2, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837E0FC = -{ - .affineMode = 1, - .objMode = 1, - .shape = 2, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837E104 = -{ - .affineMode = 3, - .objMode = 1, - .shape = 0, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837E10C = -{ - .affineMode = 3, - .objMode = 1, - .shape = 0, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837E114 = -{ - .affineMode = 3, - .objMode = 1, - .shape = 0, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837E11C = -{ - .affineMode = 3, - .objMode = 1, - .shape = 0, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837E124 = -{ - .affineMode = 3, - .objMode = 1, - .shape = 1, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837E12C = -{ - .affineMode = 3, - .objMode = 1, - .shape = 1, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837E134 = -{ - .affineMode = 3, - .objMode = 1, - .shape = 1, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837E13C = -{ - .affineMode = 3, - .objMode = 1, - .shape = 1, - .size = 3, - .priority = 2, -}; - -const struct OamData gOamData_837E144 = -{ - .affineMode = 3, - .objMode = 1, - .shape = 2, - .size = 0, - .priority = 2, -}; - -const struct OamData gOamData_837E14C = -{ - .affineMode = 3, - .objMode = 1, - .shape = 2, - .size = 1, - .priority = 2, -}; - -const struct OamData gOamData_837E154 = -{ - .affineMode = 3, - .objMode = 1, - .shape = 2, - .size = 2, - .priority = 2, -}; - -const struct OamData gOamData_837E15C = -{ - .affineMode = 3, - .objMode = 1, - .shape = 2, - .size = 3, - .priority = 2, -}; - -const struct CompressedSpriteSheet gBattleAnimPicTable[] = -{ - { gBattleAnimSpriteSheet_000, 0x200, ANIM_TAG_BONE }, - { gBattleAnimSpriteSheet_001, 0x300, ANIM_TAG_SPARK }, - { gBattleAnimSpriteSheet_002, 0x200, ANIM_TAG_PENCIL }, - { gBattleAnimSpriteSheet_003, 0x100, ANIM_TAG_AIR_WAVE }, - { gBattleAnimSpriteSheet_004, 0x200, ANIM_TAG_UNUSED_ORB }, - { gBattleAnimSpriteSheet_005, 0x400, ANIM_TAG_SWORD }, - { gBattleAnimSpriteSheet_006, 0x180, ANIM_TAG_SEED }, - { gBattleAnimSpriteSheet_007, 0x800, ANIM_TAG_UNUSED_EXPLOSION }, - { gBattleAnimSpriteSheet_008, 0x20, ANIM_TAG_UNUSED_PINK_ORB }, - { gBattleAnimSpriteSheet_009, 0x400, ANIM_TAG_GUST }, - { gBattleAnimSpriteSheet_010, 0x1200, ANIM_TAG_ICE_CUBE }, - { gBattleAnimSpriteSheet_011, 0x180, ANIM_TAG_SPARK_2 }, - { gBattleAnimSpriteSheet_012, 0x80, ANIM_TAG_UNUSED_ORANGE }, - { gBattleAnimSpriteSheet_013, 0x80, ANIM_TAG_YELLOW_BALL }, - { gBattleAnimSpriteSheet_014, 0x280, ANIM_TAG_LOCK_ON }, - { gBattleAnimSpriteSheet_015, 0x80, ANIM_TAG_TIED_BAG }, - { gBattleAnimSpriteSheet_016, 0x100, ANIM_TAG_BLACK_SMOKE }, - { gBattleAnimSpriteSheet_017, 0x20, ANIM_TAG_BLACK_BALL }, - { gBattleAnimSpriteSheet_018, 0x80, ANIM_TAG_CONVERSION }, - { gBattleAnimSpriteSheet_019, 0x400, ANIM_TAG_UNUSED_GLASS }, - { gBattleAnimSpriteSheet_020, 0x200, ANIM_TAG_HORN_HIT }, - { gBattleAnimSpriteSheet_021, 0xA00, ANIM_TAG_UNUSED_HIT }, - { gBattleAnimSpriteSheet_021, 0xA00, ANIM_TAG_UNUSED_HIT_2 }, - { gBattleAnimSpriteSheet_023, 0x380, ANIM_TAG_UNUSED_BLUE_SHARDS }, - { gBattleAnimSpriteSheet_024, 0x300, ANIM_TAG_UNUSED_CLOSING_EYE }, - { gBattleAnimSpriteSheet_025, 0xA00, ANIM_TAG_UNUSED_WAVING_HAND }, - { gBattleAnimSpriteSheet_026, 0xA00, ANIM_TAG_UNUSED_HIT_DUPLICATE }, - { gBattleAnimSpriteSheet_027, 0xA00, ANIM_TAG_LEER }, - { gBattleAnimSpriteSheet_028, 0xA00, ANIM_TAG_UNUSED_BLUE_BURST }, - { gBattleAnimSpriteSheet_029, 0xA00, ANIM_TAG_SMALL_EMBER }, - { gBattleAnimSpriteSheet_030, 0xA00, ANIM_TAG_GRAY_SMOKE }, - { gBattleAnimSpriteSheet_031, 0xE00, ANIM_TAG_BLUE_STAR }, - { gBattleAnimSpriteSheet_032, 0x380, ANIM_TAG_UNUSED_BUBBLE_BURST }, - { gBattleAnimSpriteSheet_033, 0x1000, ANIM_TAG_FIRE }, - { gBattleAnimSpriteSheet_034, 0x800, ANIM_TAG_UNUSED_SPINNING_FIRE }, - { gBattleAnimSpriteSheet_035, 0xA00, ANIM_TAG_FIRE_PLUME }, - { gBattleAnimSpriteSheet_036, 0x800, ANIM_TAG_UNUSED_LIGHTNING }, - { gBattleAnimSpriteSheet_037, 0xA00, ANIM_TAG_LIGHTNING }, - { gBattleAnimSpriteSheet_038, 0xA00, ANIM_TAG_UNUSED_CLAW_SLASH }, - { gBattleAnimSpriteSheet_039, 0xA00, ANIM_TAG_CLAW_SLASH }, - { gBattleAnimSpriteSheet_040, 0xA00, ANIM_TAG_UNUSED_SCRATCH }, - { gBattleAnimSpriteSheet_041, 0xA00, ANIM_TAG_UNUSED_SCRATCH_2 }, - { gBattleAnimSpriteSheet_042, 0xA00, ANIM_TAG_UNUSED_BUBBLE_BURST_2 }, - { gBattleAnimSpriteSheet_043, 0xA00, ANIM_TAG_ICE_CHUNK }, - { gBattleAnimSpriteSheet_044, 0xA00, ANIM_TAG_UNUSED_GLASS_2 }, - { gBattleAnimSpriteSheet_045, 0xA00, ANIM_TAG_UNUSED_PINK_HEART }, - { gBattleAnimSpriteSheet_046, 0x1000, ANIM_TAG_UNUSED_SAP_DRIP }, - { gBattleAnimSpriteSheet_046, 0x1000, ANIM_TAG_UNUSED_SAP_DRIP_2 }, - { gBattleAnimSpriteSheet_048, 0x1000, ANIM_TAG_SPARKLE_1 }, - { gBattleAnimSpriteSheet_048, 0x1000, ANIM_TAG_SPARKLE_2 }, - { gBattleAnimSpriteSheet_050, 0x200, ANIM_TAG_HUMANOID_FOOT }, - { gBattleAnimSpriteSheet_051, 0x200, ANIM_TAG_UNUSED_MONSTER_FOOT }, - { gBattleAnimSpriteSheet_052, 0x200, ANIM_TAG_UNUSED_HUMANOID_HAND }, - { gBattleAnimSpriteSheet_053, 0x800, ANIM_TAG_NOISE_LINE }, - { gBattleAnimSpriteSheet_054, 0x80, ANIM_TAG_UNUSED_YELLOW_UNK }, - { gBattleAnimSpriteSheet_055, 0x200, ANIM_TAG_UNUSED_RED_FIST }, - { gBattleAnimSpriteSheet_056, 0x1000, ANIM_TAG_SLAM_HIT }, - { gBattleAnimSpriteSheet_057, 0x180, ANIM_TAG_UNUSED_RING }, - { gBattleAnimSpriteSheet_058, 0xC00, ANIM_TAG_ROCKS }, - { gBattleAnimSpriteSheet_059, 0x100, ANIM_TAG_UNUSED_Z }, - { gBattleAnimSpriteSheet_060, 0x40, ANIM_TAG_UNUSED_YELLOW_UNK_2 }, - { gBattleAnimSpriteSheet_061, 0x180, ANIM_TAG_UNUSED_AIR_SLASH }, - { gBattleAnimSpriteSheet_062, 0x800, ANIM_TAG_UNUSED_SPINNING_GREEN_ORBS }, - { gBattleAnimSpriteSheet_063, 0x480, ANIM_TAG_LEAF }, - { gBattleAnimSpriteSheet_064, 0x200, ANIM_TAG_FINGER }, - { gBattleAnimSpriteSheet_065, 0x200, ANIM_TAG_POISON_POWDER }, - { gBattleAnimSpriteSheet_066, 0x100, ANIM_TAG_UNUSED_BROWN_TRIANGLE }, - { gBattleAnimSpriteSheet_065, 0x200, ANIM_TAG_SLEEP_POWDER }, - { gBattleAnimSpriteSheet_065, 0x200, ANIM_TAG_STUN_SPORE }, - { gBattleAnimSpriteSheet_065, 0x200, ANIM_TAG_UNUSED_POWDER }, - { gBattleAnimSpriteSheet_070, 0x200, ANIM_TAG_SPARKLE_3 }, - { gBattleAnimSpriteSheet_071, 0xA00, ANIM_TAG_SPARKLE_4 }, - { gBattleAnimSpriteSheet_072, 0x300, ANIM_TAG_MUSIC_NOTES }, - { gBattleAnimSpriteSheet_073, 0x180, ANIM_TAG_DUCK }, - { gBattleAnimSpriteSheet_074, 0xA0, ANIM_TAG_MUD_SAND }, - { gBattleAnimSpriteSheet_075, 0x700, ANIM_TAG_ALERT }, - { gBattleAnimSpriteSheet_076, 0x400, ANIM_TAG_UNUSED_BLUE_FLAMES }, - { gBattleAnimSpriteSheet_077, 0x200, ANIM_TAG_UNUSED_BLUE_FLAMES_2 }, - { gBattleAnimSpriteSheet_078, 0x300, ANIM_TAG_UNUSED_SHOCK }, - { gBattleAnimSpriteSheet_079, 0xC00, ANIM_TAG_SHOCK }, - { gBattleAnimSpriteSheet_080, 0xA00, ANIM_TAG_UNUSED_BELL }, - { gBattleAnimSpriteSheet_081, 0x80, ANIM_TAG_UNUSED_PINK_GLOVE }, - { gBattleAnimSpriteSheet_082, 0x40, ANIM_TAG_UNUSED_BLUE_LINES }, - { gBattleAnimSpriteSheet_083, 0xE00, ANIM_TAG_UNUSED_IMPACT }, - { gBattleAnimSpriteSheet_084, 0xE00, ANIM_TAG_UNUSED_IMPACT_2 }, - { gBattleAnimSpriteSheet_085, 0x280, ANIM_TAG_UNUSED_RETICLE }, - { gBattleAnimSpriteSheet_086, 0x200, ANIM_TAG_BREATH }, - { gBattleAnimSpriteSheet_087, 0x80, ANIM_TAG_ANGER }, - { gBattleAnimSpriteSheet_088, 0xC0, ANIM_TAG_UNUSED_SNOWBALL }, - { gBattleAnimSpriteSheet_089, 0xA00, ANIM_TAG_UNUSED_VINE }, - { gBattleAnimSpriteSheet_090, 0x200, ANIM_TAG_UNUSED_SWORD }, - { gBattleAnimSpriteSheet_091, 0x180, ANIM_TAG_UNUSED_CLAPPING }, - { gBattleAnimSpriteSheet_092, 0x80, ANIM_TAG_UNUSED_RED_TUBE }, - { gBattleAnimSpriteSheet_093, 0x1000, ANIM_TAG_AMNESIA }, - { gBattleAnimSpriteSheet_094, 0xA00, ANIM_TAG_UNUSED_STRING }, - { gBattleAnimSpriteSheet_095, 0x180, ANIM_TAG_UNUSED_PENCIL }, - { gBattleAnimSpriteSheet_096, 0x380, ANIM_TAG_UNUSED_PETAL }, - { gBattleAnimSpriteSheet_097, 0xC00, ANIM_TAG_BENT_SPOON }, - { gBattleAnimSpriteSheet_098, 0x200, ANIM_TAG_UNUSED_WEB }, - { gBattleAnimSpriteSheet_099, 0x200, ANIM_TAG_MILK_BOTTLE }, - { gBattleAnimSpriteSheet_100, 0x200, ANIM_TAG_COIN }, - { gBattleAnimSpriteSheet_101, 0x200, ANIM_TAG_UNUSED_CRACKED_EGG }, - { gBattleAnimSpriteSheet_102, 0x400, ANIM_TAG_UNUSED_HATCHED_EGG }, - { gBattleAnimSpriteSheet_103, 0x80, ANIM_TAG_UNUSED_FRESH_EGG }, - { gBattleAnimSpriteSheet_104, 0x400, ANIM_TAG_UNUSED_FANGS }, - { gBattleAnimSpriteSheet_105, 0xC00, ANIM_TAG_UNUSED_EXPLOSION_2 }, - { gBattleAnimSpriteSheet_106, 0x200, ANIM_TAG_UNUSED_EXPLOSION_3 }, - { gBattleAnimSpriteSheet_107, 0x1000, ANIM_TAG_UNUSED_WATER_DROPLET }, - { gBattleAnimSpriteSheet_108, 0xA00, ANIM_TAG_UNUSED_WATER_DROPLET_2 }, - { gBattleAnimSpriteSheet_109, 0x20, ANIM_TAG_UNUSED_SEED }, - { gBattleAnimSpriteSheet_110, 0xE00, ANIM_TAG_UNUSED_SPROUT }, - { gBattleAnimSpriteSheet_111, 0x80, ANIM_TAG_UNUSED_RED_WAND }, - { gBattleAnimSpriteSheet_112, 0xA00, ANIM_TAG_UNUSED_PURPLE_GREEN_UNK }, - { gBattleAnimSpriteSheet_113, 0x400, ANIM_TAG_UNUSED_WATER_COLUMN }, - { gBattleAnimSpriteSheet_114, 0x200, ANIM_TAG_UNUSED_MUD_UNK }, - { gBattleAnimSpriteSheet_115, 0x700, ANIM_TAG_RAIN_DROPS }, - { gBattleAnimSpriteSheet_116, 0x800, ANIM_TAG_UNUSED_FURY_SWIPES }, - { gBattleAnimSpriteSheet_117, 0xA00, ANIM_TAG_UNUSED_VINE_2 }, - { gBattleAnimSpriteSheet_118, 0x600, ANIM_TAG_UNUSED_TEETH }, - { gBattleAnimSpriteSheet_119, 0x800, ANIM_TAG_UNUSED_BONE }, - { gBattleAnimSpriteSheet_120, 0x200, ANIM_TAG_UNUSED_WHITE_BAG }, - { gBattleAnimSpriteSheet_121, 0x40, ANIM_TAG_UNUSED_UNKNOWN }, - { gBattleAnimSpriteSheet_122, 0x180, ANIM_TAG_UNUSED_PURPLE_CORAL }, - { gBattleAnimSpriteSheet_123, 0x600, ANIM_TAG_UNUSED_PURPLE_DROPLET }, - { gBattleAnimSpriteSheet_124, 0x600, ANIM_TAG_UNUSED_SHOCK_2 }, - { gBattleAnimSpriteSheet_125, 0x200, ANIM_TAG_UNUSED_CLOSING_EYE_2 }, - { gBattleAnimSpriteSheet_126, 0x80, ANIM_TAG_UNUSED_METAL_BALL }, - { gBattleAnimSpriteSheet_127, 0x200, ANIM_TAG_UNUSED_MONSTER_DOLL }, - { gBattleAnimSpriteSheet_128, 0x800, ANIM_TAG_UNUSED_WHIRLWIND }, - { gBattleAnimSpriteSheet_129, 0x80, ANIM_TAG_UNUSED_WHIRLWIND_2 }, - { gBattleAnimSpriteSheet_130, 0xA00, ANIM_TAG_UNUSED_EXPLOSION_4 }, - { gBattleAnimSpriteSheet_131, 0x280, ANIM_TAG_UNUSED_EXPLOSION_5 }, - { gBattleAnimSpriteSheet_132, 0x280, ANIM_TAG_UNUSED_TONGUE }, - { gBattleAnimSpriteSheet_133, 0x100, ANIM_TAG_UNUSED_SMOKE }, - { gBattleAnimSpriteSheet_134, 0x200, ANIM_TAG_UNUSED_SMOKE_2 }, - { gBattleAnimSpriteSheet_135, 0x200, ANIM_TAG_IMPACT }, - { gBattleAnimSpriteSheet_136, 0x20, ANIM_TAG_CIRCLE_IMPACT }, - { gBattleAnimSpriteSheet_137, 0xA00, ANIM_TAG_SCRATCH }, - { gBattleAnimSpriteSheet_138, 0x800, ANIM_TAG_CUT }, - { gBattleAnimSpriteSheet_139, 0x800, ANIM_TAG_SHARP_TEETH }, - { gBattleAnimSpriteSheet_140, 0xC0, ANIM_TAG_RAINBOW_RINGS }, - { gBattleAnimSpriteSheet_141, 0x1C0, ANIM_TAG_ICE_CRYSTALS }, - { gBattleAnimSpriteSheet_142, 0x100, ANIM_TAG_ICE_SPIKES }, - { gBattleAnimSpriteSheet_143, 0x800, ANIM_TAG_HANDS_AND_FEET }, - { gBattleAnimSpriteSheet_144, 0x200, ANIM_TAG_MIST_CLOUD }, - { gBattleAnimSpriteSheet_145, 0x800, ANIM_TAG_CLAMP }, - { gBattleAnimSpriteSheet_146, 0x180, ANIM_TAG_BUBBLE }, - { gBattleAnimSpriteSheet_147, 0x180, ANIM_TAG_ORBS }, - { gBattleAnimSpriteSheet_148, 0x200, ANIM_TAG_WATER_IMPACT }, - { gBattleAnimSpriteSheet_149, 0x200, ANIM_TAG_WATER_ORB }, - { gBattleAnimSpriteSheet_150, 0x180, ANIM_TAG_POISON_BUBBLE }, - { gBattleAnimSpriteSheet_151, 0x400, ANIM_TAG_TOXIC_BUBBLE }, - { gBattleAnimSpriteSheet_152, 0x80, ANIM_TAG_SPIKES }, - { gBattleAnimSpriteSheet_153, 0x100, ANIM_TAG_HORN_HIT_2 }, - { gBattleAnimSpriteSheet_154, 0x100, ANIM_TAG_AIR_WAVE_2 }, - { gBattleAnimSpriteSheet_155, 0x140, ANIM_TAG_SMALL_BUBBLES }, - { gBattleAnimSpriteSheet_156, 0x800, ANIM_TAG_ROUND_SHADOW }, - { gBattleAnimSpriteSheet_157, 0x200, ANIM_TAG_SUNLIGHT }, - { gBattleAnimSpriteSheet_158, 0x100, ANIM_TAG_SPORE }, - { gBattleAnimSpriteSheet_159, 0xA0, ANIM_TAG_FLOWER }, - { gBattleAnimSpriteSheet_160, 0x100, ANIM_TAG_RAZOR_LEAF }, - { gBattleAnimSpriteSheet_161, 0x80, ANIM_TAG_NEEDLE }, - { gBattleAnimSpriteSheet_162, 0x300, ANIM_TAG_WHIRLWIND_LINES }, - { gBattleAnimSpriteSheet_163, 0x100, ANIM_TAG_GOLD_RING }, - { gBattleAnimSpriteSheet_163, 0x100, ANIM_TAG_PURPLE_RING }, - { gBattleAnimSpriteSheet_163, 0x100, ANIM_TAG_BLUE_RING }, - { gBattleAnimSpriteSheet_166, 0x800, ANIM_TAG_GREEN_LIGHT_WALL }, - { gBattleAnimSpriteSheet_166, 0x800, ANIM_TAG_BLUE_LIGHT_WALL }, - { gBattleAnimSpriteSheet_166, 0x800, ANIM_TAG_RED_LIGHT_WALL }, - { gBattleAnimSpriteSheet_166, 0x800, ANIM_TAG_GRAY_LIGHT_WALL }, - { gBattleAnimSpriteSheet_166, 0x800, ANIM_TAG_ORANGE_LIGHT_WALL }, - { gBattleAnimSpriteSheet_171, 0x80, ANIM_TAG_BLACK_BALL_2 }, - { gBattleAnimSpriteSheet_144, 0x200, ANIM_TAG_PURPLE_GAS_CLOUD }, - { gBattleAnimSpriteSheet_173, 0x200, ANIM_TAG_SPARK_H }, - { gBattleAnimSpriteSheet_174, 0x200, ANIM_TAG_YELLOW_STAR }, - { gBattleAnimSpriteSheet_175, 0x80, ANIM_TAG_LARGE_FRESH_EGG }, - { gBattleAnimSpriteSheet_176, 0x200, ANIM_TAG_SHADOW_BALL }, - { gBattleAnimSpriteSheet_177, 0x500, ANIM_TAG_LICK }, - { gBattleAnimSpriteSheet_178, 0x800, ANIM_TAG_UNUSED_VOID_LINES }, - { gBattleAnimSpriteSheet_179, 0x400, ANIM_TAG_STRING }, - { gBattleAnimSpriteSheet_180, 0x20, ANIM_TAG_STRING_DOT }, - { gBattleAnimSpriteSheet_181, 0x800, ANIM_TAG_WEB }, - { gBattleAnimSpriteSheet_182, 0x100, ANIM_TAG_UNUSED_LIGHTBULB }, - { gBattleAnimSpriteSheet_183, 0x800, ANIM_TAG_SLASH }, - { gBattleAnimSpriteSheet_184, 0x400, ANIM_TAG_FOCUS_ENERGY }, - { gBattleAnimSpriteSheet_185, 0xA00, ANIM_TAG_SPHERE_TO_CUBE }, - { gBattleAnimSpriteSheet_186, 0x1000, ANIM_TAG_TENDRILS }, - { gBattleAnimSpriteSheet_187, 0x800, ANIM_TAG_EYE }, - { gBattleAnimSpriteSheet_188, 0x400, ANIM_TAG_WHITE_SHADOW }, - { gBattleAnimSpriteSheet_189, 0x200, ANIM_TAG_TEAL_ALERT }, - { gBattleAnimSpriteSheet_190, 0x800, ANIM_TAG_OPENING_EYE }, - { gBattleAnimSpriteSheet_191, 0x800, ANIM_TAG_ROUND_WHITE_HALO }, - { gBattleAnimSpriteSheet_192, 0x800, ANIM_TAG_FANG_ATTACK }, - { gBattleAnimSpriteSheet_193, 0x200, ANIM_TAG_PURPLE_HAND_OUTLINE }, - { gBattleAnimSpriteSheet_194, 0x800, ANIM_TAG_MOON }, - { gBattleAnimSpriteSheet_195, 0x200, ANIM_TAG_SPARKLE_5 }, - { gBattleAnimSpriteSheet_196, 0x800, ANIM_TAG_SPIRAL }, - { gBattleAnimSpriteSheet_197, 0x200, ANIM_TAG_SNORE_Z }, - { gBattleAnimSpriteSheet_198, 0x800, ANIM_TAG_EXPLOSION }, - { gBattleAnimSpriteSheet_199, 0x400, ANIM_TAG_NAIL }, - { gBattleAnimSpriteSheet_200, 0x200, ANIM_TAG_GHOSTLY_SPIRIT }, - { gBattleAnimSpriteSheet_201, 0xA80, ANIM_TAG_WARM_ROCK }, - { gBattleAnimSpriteSheet_202, 0x600, ANIM_TAG_BREAKING_EGG }, - { gBattleAnimSpriteSheet_203, 0x800, ANIM_TAG_THIN_RING }, - { gBattleAnimSpriteSheet_204, 0x200, ANIM_TAG_UNUSED_PUNCH_IMPACT }, - { gBattleAnimSpriteSheet_205, 0x600, ANIM_TAG_BELL }, - { gBattleAnimSpriteSheet_206, 0x800, ANIM_TAG_MUSIC_NOTES_2 }, - { gBattleAnimSpriteSheet_207, 0x180, ANIM_TAG_SPEED_DUST }, - { gBattleAnimSpriteSheet_208, 0x800, ANIM_TAG_TORN_METAL }, - { gBattleAnimSpriteSheet_209, 0x800, ANIM_TAG_THOUGHT_BUBBLE }, - { gBattleAnimSpriteSheet_210, 0x80, ANIM_TAG_MAGENTA_HEART }, - { gBattleAnimSpriteSheet_211, 0x80, ANIM_TAG_ELECTRIC_ORBS }, - { gBattleAnimSpriteSheet_212, 0x800, ANIM_TAG_CIRCLE_OF_LIGHT }, - { gBattleAnimSpriteSheet_213, 0x800, ANIM_TAG_ELECTRICITY }, - { gBattleAnimSpriteSheet_214, 0x600, ANIM_TAG_FINGER_2 }, - { gBattleAnimSpriteSheet_215, 0x600, ANIM_TAG_MOVEMENT_WAVES }, - { gBattleAnimSpriteSheet_210, 0x80, ANIM_TAG_RED_HEART }, - { gBattleAnimSpriteSheet_217, 0x80, ANIM_TAG_RED_ORB }, - { gBattleAnimSpriteSheet_218, 0x180, ANIM_TAG_EYE_SPARKLE }, - { gBattleAnimSpriteSheet_210, 0x80, ANIM_TAG_PINK_HEART }, - { gBattleAnimSpriteSheet_220, 0x200, ANIM_TAG_ANGEL }, - { gBattleAnimSpriteSheet_221, 0x400, ANIM_TAG_DEVIL }, - { gBattleAnimSpriteSheet_222, 0xA00, ANIM_TAG_SWIPE }, - { gBattleAnimSpriteSheet_223, 0x800, ANIM_TAG_ROOTS }, - { gBattleAnimSpriteSheet_224, 0x200, ANIM_TAG_ITEM_BAG }, - { gBattleAnimSpriteSheet_225, 0x400, ANIM_TAG_JAGGED_MUSIC_NOTE }, - { gBattleAnimSpriteSheet_226, 0x80, ANIM_TAG_POKEBALL }, - { gBattleAnimSpriteSheet_227, 0x800, ANIM_TAG_SPOTLIGHT }, - { gBattleAnimSpriteSheet_228, 0x200, ANIM_TAG_LETTER_Z }, - { gBattleAnimSpriteSheet_229, 0x300, ANIM_TAG_RAPID_SPIN }, - { gBattleAnimSpriteSheet_230, 0x800, ANIM_TAG_TRI_FORCE_TRIANGLE }, - { gBattleAnimSpriteSheet_231, 0x380, ANIM_TAG_WISP_ORB }, - { gBattleAnimSpriteSheet_232, 0x800, ANIM_TAG_WISP_FIRE }, - { gBattleAnimSpriteSheet_233, 0xC0, ANIM_TAG_GOLD_STARS }, - { gBattleAnimSpriteSheet_234, 0x800, ANIM_TAG_ECLIPSING_ORB }, - { gBattleAnimSpriteSheet_235, 0x60, ANIM_TAG_GRAY_ORB }, - { gBattleAnimSpriteSheet_235, 0x60, ANIM_TAG_BLUE_ORB }, - { gBattleAnimSpriteSheet_235, 0x60, ANIM_TAG_RED_ORB_2 }, - { gBattleAnimSpriteSheet_238, 0x80, ANIM_TAG_PINK_PETAL }, - { gBattleAnimSpriteSheet_239, 0x180, ANIM_TAG_PAIN_SPLIT }, - { gBattleAnimSpriteSheet_240, 0x180, ANIM_TAG_CONFETTI }, - { gBattleAnimSpriteSheet_241, 0x200, ANIM_TAG_GREEN_STAR }, - { gBattleAnimSpriteSheet_242, 0x200, ANIM_TAG_PINK_CLOUD }, - { gBattleAnimSpriteSheet_243, 0x20, ANIM_TAG_SWEAT_DROP }, - { gBattleAnimSpriteSheet_244, 0x400, ANIM_TAG_GUARD_RING }, - { gBattleAnimSpriteSheet_245, 0x600, ANIM_TAG_PURPLE_SCRATCH }, - { gBattleAnimSpriteSheet_246, 0x1000, ANIM_TAG_PURPLE_SWIPE }, - { gBattleAnimSpriteSheet_247, 0x400, ANIM_TAG_TAG_HAND }, - { gBattleAnimSpriteSheet_248, 0x20, ANIM_TAG_SMALL_RED_EYE }, - { gBattleAnimSpriteSheet_249, 0x80, ANIM_TAG_HOLLOW_ORB }, - { gBattleAnimSpriteSheet_250, 0x800, ANIM_TAG_X_SIGN }, - { gBattleAnimSpriteSheet_251, 0x80, ANIM_TAG_BLUEGREEN_ORB }, - { gBattleAnimSpriteSheet_252, 0x200, ANIM_TAG_PAW_PRINT }, - { gBattleAnimSpriteSheet_253, 0x400, ANIM_TAG_PURPLE_FLAME }, - { gBattleAnimSpriteSheet_254, 0x200, ANIM_TAG_RED_BALL }, - { gBattleAnimSpriteSheet_255, 0x200, ANIM_TAG_SMELLINGSALT_EFFECT }, - { gBattleAnimSpriteSheet_256, 0x800, ANIM_TAG_METEOR }, - { gBattleAnimSpriteSheet_257, 0x280, ANIM_TAG_FLAT_ROCK }, - { gBattleAnimSpriteSheet_258, 0x200, ANIM_TAG_MAGNIFYING_GLASS }, - { gBattleAnimSpriteSheet_149, 0x200, ANIM_TAG_BROWN_ORB }, - { gBattleAnimSpriteSheet_260, 0x400, ANIM_TAG_METAL_SOUND_WAVES }, - { gBattleAnimSpriteSheet_261, 0x200, ANIM_TAG_FLYING_DIRT }, - { gBattleAnimSpriteSheet_262, 0x200, ANIM_TAG_ICICLE_SPEAR }, - { gBattleAnimSpriteSheet_263, 0x80, ANIM_TAG_HAIL }, - { gBattleAnimSpriteSheet_264, 0x20, ANIM_TAG_GLOWY_RED_ORB }, - { gBattleAnimSpriteSheet_264, 0x20, ANIM_TAG_GLOWY_GREEN_ORB }, - { gBattleAnimSpriteSheet_266, 0x80, ANIM_TAG_GREEN_SPIKE }, - { gBattleAnimSpriteSheet_212, 0x800, ANIM_TAG_WHITE_CIRCLE_OF_LIGHT }, - { gBattleAnimSpriteSheet_264, 0x20, ANIM_TAG_GLOWY_BLUE_ORB }, - { gBattleAnimSpriteSheet_269, 0x80, ANIM_TAG_UNUSED_RED_BRICK }, - { gBattleAnimSpriteSheet_270, 0x400, ANIM_TAG_WHITE_FEATHER }, - { gBattleAnimSpriteSheet_271, 0x80, ANIM_TAG_SPARKLE_6 }, - { gBattleAnimSpriteSheet_272, 0x800, ANIM_TAG_SPLASH }, - { gBattleAnimSpriteSheet_273, 0x20, ANIM_TAG_SWEAT_BEAD }, - { gBattleAnimSpriteSheet_274, 0x800, ANIM_TAG_UNUSED_GEM_1 }, - { gBattleAnimSpriteSheet_275, 0x800, ANIM_TAG_UNUSED_GEM_2 }, - { gBattleAnimSpriteSheet_276, 0x800, ANIM_TAG_UNUSED_GEM_3 }, - { gBattleAnimSpriteSheet_277, 0x1000, ANIM_TAG_SLAM_HIT_2 }, - { gBattleAnimSpriteSheet_278, 0x800, ANIM_TAG_RECYCLE }, - { gBattleAnimSpriteSheet_279, 0xA0, ANIM_TAG_UNUSED_RED_PARTICLES }, - { gBattleAnimSpriteSheet_280, 0x800, ANIM_TAG_PROTECT }, - { gBattleAnimSpriteSheet_281, 0x200, ANIM_TAG_DIRT_MOUND }, - { gBattleAnimSpriteSheet_282, 0x600, ANIM_TAG_SHOCK_3 }, - { gBattleAnimSpriteSheet_283, 0x200, ANIM_TAG_WEATHER_BALL }, - { gBattleAnimSpriteSheet_284, 0x800, ANIM_TAG_BIRD }, - { gBattleAnimSpriteSheet_285, 0x200, ANIM_TAG_CROSS_IMPACT }, - { gBattleAnimSpriteSheet_183, 0x800, ANIM_TAG_SLASH_2 }, - { gBattleAnimSpriteSheet_056, 0x1000, ANIM_TAG_WHIP_HIT }, - { gBattleAnimSpriteSheet_163, 0x100, ANIM_TAG_BLUE_RING_2 }, -}; - -const struct CompressedSpritePalette gBattleAnimPaletteTable[] = -{ - { gBattleAnimSpritePalette_000, ANIM_TAG_BONE }, - { gBattleAnimSpritePalette_001, ANIM_TAG_SPARK }, - { gBattleAnimSpritePalette_002, ANIM_TAG_PENCIL }, - { gBattleAnimSpritePalette_003, ANIM_TAG_AIR_WAVE }, - { gBattleAnimSpritePalette_004, ANIM_TAG_UNUSED_ORB }, - { gBattleAnimSpritePalette_005, ANIM_TAG_SWORD }, - { gBattleAnimSpritePalette_006, ANIM_TAG_SEED }, - { gBattleAnimSpritePalette_007, ANIM_TAG_UNUSED_EXPLOSION }, - { gBattleAnimSpritePalette_008, ANIM_TAG_UNUSED_PINK_ORB }, - { gBattleAnimSpritePalette_009, ANIM_TAG_GUST }, - { gBattleAnimSpritePalette_010, ANIM_TAG_ICE_CUBE }, - { gBattleAnimSpritePalette_011, ANIM_TAG_SPARK_2 }, - { gBattleAnimSpritePalette_012, ANIM_TAG_UNUSED_ORANGE }, - { gBattleAnimSpritePalette_013, ANIM_TAG_YELLOW_BALL }, - { gBattleAnimSpritePalette_014, ANIM_TAG_LOCK_ON }, - { gBattleAnimSpritePalette_015, ANIM_TAG_TIED_BAG }, - { gBattleAnimSpritePalette_016, ANIM_TAG_BLACK_SMOKE }, - { gBattleAnimSpritePalette_016, ANIM_TAG_BLACK_BALL }, - { gBattleAnimSpritePalette_018, ANIM_TAG_CONVERSION }, - { gBattleAnimSpritePalette_019, ANIM_TAG_UNUSED_GLASS }, - { gBattleAnimSpritePalette_020, ANIM_TAG_HORN_HIT }, - { gBattleAnimSpritePalette_021, ANIM_TAG_UNUSED_HIT }, - { gBattleAnimSpritePalette_022, ANIM_TAG_UNUSED_HIT_2 }, - { gBattleAnimSpritePalette_023, ANIM_TAG_UNUSED_BLUE_SHARDS }, - { gBattleAnimSpritePalette_024, ANIM_TAG_UNUSED_CLOSING_EYE }, - { gBattleAnimSpritePalette_025, ANIM_TAG_UNUSED_WAVING_HAND }, - { gBattleAnimSpritePalette_026, ANIM_TAG_UNUSED_HIT_DUPLICATE }, - { gBattleAnimSpritePalette_027, ANIM_TAG_LEER }, - { gBattleAnimSpritePalette_028, ANIM_TAG_UNUSED_BLUE_BURST }, - { gBattleAnimSpritePalette_029, ANIM_TAG_SMALL_EMBER }, - { gBattleAnimSpritePalette_030, ANIM_TAG_GRAY_SMOKE }, - { gBattleAnimSpritePalette_031, ANIM_TAG_BLUE_STAR }, - { gBattleAnimSpritePalette_032, ANIM_TAG_UNUSED_BUBBLE_BURST }, - { gBattleAnimSpritePalette_033, ANIM_TAG_FIRE }, - { gBattleAnimSpritePalette_033, ANIM_TAG_UNUSED_SPINNING_FIRE }, - { gBattleAnimSpritePalette_033, ANIM_TAG_FIRE_PLUME }, - { gBattleAnimSpritePalette_036, ANIM_TAG_UNUSED_LIGHTNING }, - { gBattleAnimSpritePalette_036, ANIM_TAG_LIGHTNING }, - { gBattleAnimSpritePalette_038, ANIM_TAG_UNUSED_CLAW_SLASH }, - { gBattleAnimSpritePalette_039, ANIM_TAG_CLAW_SLASH }, - { gBattleAnimSpritePalette_038, ANIM_TAG_UNUSED_SCRATCH }, - { gBattleAnimSpritePalette_038, ANIM_TAG_UNUSED_SCRATCH_2 }, - { gBattleAnimSpritePalette_042, ANIM_TAG_UNUSED_BUBBLE_BURST_2 }, - { gBattleAnimSpritePalette_043, ANIM_TAG_ICE_CHUNK }, - { gBattleAnimSpritePalette_044, ANIM_TAG_UNUSED_GLASS_2 }, - { gBattleAnimSpritePalette_045, ANIM_TAG_UNUSED_PINK_HEART }, - { gBattleAnimSpritePalette_046, ANIM_TAG_UNUSED_SAP_DRIP }, - { gBattleAnimSpritePalette_047, ANIM_TAG_UNUSED_SAP_DRIP }, - { gBattleAnimSpritePalette_048, ANIM_TAG_SPARKLE_1 }, - { gBattleAnimSpritePalette_049, ANIM_TAG_SPARKLE_2 }, - { gBattleAnimSpritePalette_050, ANIM_TAG_HUMANOID_FOOT }, - { gBattleAnimSpritePalette_050, ANIM_TAG_UNUSED_MONSTER_FOOT }, - { gBattleAnimSpritePalette_050, ANIM_TAG_UNUSED_HUMANOID_HAND }, - { gBattleAnimSpritePalette_026, ANIM_TAG_NOISE_LINE }, - { gBattleAnimSpritePalette_054, ANIM_TAG_UNUSED_YELLOW_UNK }, - { gBattleAnimSpritePalette_050, ANIM_TAG_UNUSED_RED_FIST }, - { gBattleAnimSpritePalette_056, ANIM_TAG_SLAM_HIT }, - { gBattleAnimSpritePalette_057, ANIM_TAG_UNUSED_RING }, - { gBattleAnimSpritePalette_058, ANIM_TAG_ROCKS }, - { gBattleAnimSpritePalette_059, ANIM_TAG_UNUSED_Z }, - { gBattleAnimSpritePalette_060, ANIM_TAG_UNUSED_YELLOW_UNK_2 }, - { gBattleAnimSpritePalette_061, ANIM_TAG_UNUSED_AIR_SLASH }, - { gBattleAnimSpritePalette_062, ANIM_TAG_UNUSED_SPINNING_GREEN_ORBS }, - { gBattleAnimSpritePalette_063, ANIM_TAG_LEAF }, - { gBattleAnimSpritePalette_064, ANIM_TAG_FINGER }, - { gBattleAnimSpritePalette_065, ANIM_TAG_POISON_POWDER }, - { gBattleAnimSpritePalette_066, ANIM_TAG_UNUSED_BROWN_TRIANGLE }, - { gBattleAnimSpritePalette_067, ANIM_TAG_SLEEP_POWDER }, - { gBattleAnimSpritePalette_068, ANIM_TAG_STUN_SPORE }, - { gBattleAnimSpritePalette_065, ANIM_TAG_UNUSED_POWDER }, - { gBattleAnimSpritePalette_070, ANIM_TAG_SPARKLE_3 }, - { gBattleAnimSpritePalette_070, ANIM_TAG_SPARKLE_4 }, - { gBattleAnimSpritePalette_072, ANIM_TAG_MUSIC_NOTES }, - { gBattleAnimSpritePalette_073, ANIM_TAG_DUCK }, - { gBattleAnimSpritePalette_074, ANIM_TAG_MUD_SAND }, - { gBattleAnimSpritePalette_075, ANIM_TAG_ALERT }, - { gBattleAnimSpritePalette_076, ANIM_TAG_UNUSED_BLUE_FLAMES }, - { gBattleAnimSpritePalette_076, ANIM_TAG_UNUSED_BLUE_FLAMES_2 }, - { gBattleAnimSpritePalette_078, ANIM_TAG_UNUSED_SHOCK }, - { gBattleAnimSpritePalette_078, ANIM_TAG_SHOCK }, - { gBattleAnimSpritePalette_080, ANIM_TAG_UNUSED_BELL }, - { gBattleAnimSpritePalette_081, ANIM_TAG_UNUSED_PINK_GLOVE }, - { gBattleAnimSpritePalette_082, ANIM_TAG_UNUSED_BLUE_LINES }, - { gBattleAnimSpritePalette_083, ANIM_TAG_UNUSED_IMPACT }, - { gBattleAnimSpritePalette_084, ANIM_TAG_UNUSED_IMPACT_2 }, - { gBattleAnimSpritePalette_085, ANIM_TAG_UNUSED_RETICLE }, - { gBattleAnimSpritePalette_086, ANIM_TAG_BREATH }, - { gBattleAnimSpritePalette_087, ANIM_TAG_ANGER }, - { gBattleAnimSpritePalette_088, ANIM_TAG_UNUSED_SNOWBALL }, - { gBattleAnimSpritePalette_089, ANIM_TAG_UNUSED_VINE }, - { gBattleAnimSpritePalette_090, ANIM_TAG_UNUSED_SWORD }, - { gBattleAnimSpritePalette_091, ANIM_TAG_UNUSED_CLAPPING }, - { gBattleAnimSpritePalette_092, ANIM_TAG_UNUSED_RED_TUBE }, - { gBattleAnimSpritePalette_093, ANIM_TAG_AMNESIA }, - { gBattleAnimSpritePalette_094, ANIM_TAG_UNUSED_STRING }, - { gBattleAnimSpritePalette_095, ANIM_TAG_UNUSED_PENCIL }, - { gBattleAnimSpritePalette_096, ANIM_TAG_UNUSED_PETAL }, - { gBattleAnimSpritePalette_097, ANIM_TAG_BENT_SPOON }, - { gBattleAnimSpritePalette_094, ANIM_TAG_UNUSED_WEB }, - { gBattleAnimSpritePalette_099, ANIM_TAG_MILK_BOTTLE }, - { gBattleAnimSpritePalette_100, ANIM_TAG_COIN }, - { gBattleAnimSpritePalette_101, ANIM_TAG_UNUSED_CRACKED_EGG }, - { gBattleAnimSpritePalette_101, ANIM_TAG_UNUSED_HATCHED_EGG }, - { gBattleAnimSpritePalette_103, ANIM_TAG_UNUSED_FRESH_EGG }, - { gBattleAnimSpritePalette_104, ANIM_TAG_UNUSED_FANGS }, - { gBattleAnimSpritePalette_105, ANIM_TAG_UNUSED_EXPLOSION_2 }, - { gBattleAnimSpritePalette_105, ANIM_TAG_UNUSED_EXPLOSION_3 }, - { gBattleAnimSpritePalette_107, ANIM_TAG_UNUSED_WATER_DROPLET }, - { gBattleAnimSpritePalette_107, ANIM_TAG_UNUSED_WATER_DROPLET_2 }, - { gBattleAnimSpritePalette_109, ANIM_TAG_UNUSED_SEED }, - { gBattleAnimSpritePalette_109, ANIM_TAG_UNUSED_SPROUT }, - { gBattleAnimSpritePalette_111, ANIM_TAG_UNUSED_RED_WAND }, - { gBattleAnimSpritePalette_112, ANIM_TAG_UNUSED_PURPLE_GREEN_UNK }, - { gBattleAnimSpritePalette_113, ANIM_TAG_UNUSED_WATER_COLUMN }, - { gBattleAnimSpritePalette_114, ANIM_TAG_UNUSED_MUD_UNK }, - { gBattleAnimSpritePalette_115, ANIM_TAG_RAIN_DROPS }, - { gBattleAnimSpritePalette_116, ANIM_TAG_UNUSED_FURY_SWIPES }, - { gBattleAnimSpritePalette_117, ANIM_TAG_UNUSED_VINE_2 }, - { gBattleAnimSpritePalette_118, ANIM_TAG_UNUSED_TEETH }, - { gBattleAnimSpritePalette_119, ANIM_TAG_UNUSED_BONE }, - { gBattleAnimSpritePalette_120, ANIM_TAG_UNUSED_WHITE_BAG }, - { gBattleAnimSpritePalette_121, ANIM_TAG_UNUSED_UNKNOWN }, - { gBattleAnimSpritePalette_122, ANIM_TAG_UNUSED_PURPLE_CORAL }, - { gBattleAnimSpritePalette_122, ANIM_TAG_UNUSED_PURPLE_DROPLET }, - { gBattleAnimSpritePalette_124, ANIM_TAG_UNUSED_SHOCK_2 }, - { gBattleAnimSpritePalette_125, ANIM_TAG_UNUSED_CLOSING_EYE_2 }, - { gBattleAnimSpritePalette_126, ANIM_TAG_UNUSED_METAL_BALL }, - { gBattleAnimSpritePalette_127, ANIM_TAG_UNUSED_MONSTER_DOLL }, - { gBattleAnimSpritePalette_128, ANIM_TAG_UNUSED_WHIRLWIND }, - { gBattleAnimSpritePalette_128, ANIM_TAG_UNUSED_WHIRLWIND_2 }, - { gBattleAnimSpritePalette_130, ANIM_TAG_UNUSED_EXPLOSION_4 }, - { gBattleAnimSpritePalette_130, ANIM_TAG_UNUSED_EXPLOSION_5 }, - { gBattleAnimSpritePalette_132, ANIM_TAG_UNUSED_TONGUE }, - { gBattleAnimSpritePalette_133, ANIM_TAG_UNUSED_SMOKE }, - { gBattleAnimSpritePalette_133, ANIM_TAG_UNUSED_SMOKE_2 }, - { gBattleAnimSpritePalette_135, ANIM_TAG_IMPACT }, - { gBattleAnimSpritePalette_136, ANIM_TAG_CIRCLE_IMPACT }, - { gBattleAnimSpritePalette_135, ANIM_TAG_SCRATCH }, - { gBattleAnimSpritePalette_135, ANIM_TAG_CUT }, - { gBattleAnimSpritePalette_139, ANIM_TAG_SHARP_TEETH }, - { gBattleAnimSpritePalette_140, ANIM_TAG_RAINBOW_RINGS }, - { gBattleAnimSpritePalette_141, ANIM_TAG_ICE_CRYSTALS }, - { gBattleAnimSpritePalette_141, ANIM_TAG_ICE_SPIKES }, - { gBattleAnimSpritePalette_143, ANIM_TAG_HANDS_AND_FEET }, - { gBattleAnimSpritePalette_144, ANIM_TAG_MIST_CLOUD }, - { gBattleAnimSpritePalette_139, ANIM_TAG_CLAMP }, - { gBattleAnimSpritePalette_115, ANIM_TAG_BUBBLE }, - { gBattleAnimSpritePalette_147, ANIM_TAG_ORBS }, - { gBattleAnimSpritePalette_148, ANIM_TAG_WATER_IMPACT }, - { gBattleAnimSpritePalette_148, ANIM_TAG_WATER_ORB }, - { gBattleAnimSpritePalette_150, ANIM_TAG_POISON_BUBBLE }, - { gBattleAnimSpritePalette_150, ANIM_TAG_TOXIC_BUBBLE }, - { gBattleAnimSpritePalette_152, ANIM_TAG_SPIKES }, - { gBattleAnimSpritePalette_153, ANIM_TAG_HORN_HIT_2 }, - { gBattleAnimSpritePalette_154, ANIM_TAG_AIR_WAVE_2 }, - { gBattleAnimSpritePalette_155, ANIM_TAG_SMALL_BUBBLES }, - { gBattleAnimSpritePalette_156, ANIM_TAG_ROUND_SHADOW }, - { gBattleAnimSpritePalette_157, ANIM_TAG_SUNLIGHT }, - { gBattleAnimSpritePalette_158, ANIM_TAG_SPORE }, - { gBattleAnimSpritePalette_159, ANIM_TAG_FLOWER }, - { gBattleAnimSpritePalette_160, ANIM_TAG_RAZOR_LEAF }, - { gBattleAnimSpritePalette_161, ANIM_TAG_NEEDLE }, - { gBattleAnimSpritePalette_162, ANIM_TAG_WHIRLWIND_LINES }, - { gBattleAnimSpritePalette_163, ANIM_TAG_GOLD_RING }, - { gBattleAnimSpritePalette_164, ANIM_TAG_PURPLE_RING }, - { gBattleAnimSpritePalette_165, ANIM_TAG_BLUE_RING }, - { gBattleAnimSpritePalette_166, ANIM_TAG_GREEN_LIGHT_WALL }, - { gBattleAnimSpritePalette_167, ANIM_TAG_BLUE_LIGHT_WALL }, - { gBattleAnimSpritePalette_168, ANIM_TAG_RED_LIGHT_WALL }, - { gBattleAnimSpritePalette_169, ANIM_TAG_GRAY_LIGHT_WALL }, - { gBattleAnimSpritePalette_170, ANIM_TAG_ORANGE_LIGHT_WALL }, - { gBattleAnimSpritePalette_171, ANIM_TAG_BLACK_BALL_2 }, - { gBattleAnimSpritePalette_172, ANIM_TAG_PURPLE_GAS_CLOUD }, - { gBattleAnimSpritePalette_001, ANIM_TAG_SPARK_H }, - { gBattleAnimSpritePalette_174, ANIM_TAG_YELLOW_STAR }, - { gBattleAnimSpritePalette_175, ANIM_TAG_LARGE_FRESH_EGG }, - { gBattleAnimSpritePalette_176, ANIM_TAG_SHADOW_BALL }, - { gBattleAnimSpritePalette_177, ANIM_TAG_LICK }, - { gBattleAnimSpritePalette_178, ANIM_TAG_UNUSED_VOID_LINES }, - { gBattleAnimSpritePalette_179, ANIM_TAG_STRING }, - { gBattleAnimSpritePalette_179, ANIM_TAG_STRING_DOT }, - { gBattleAnimSpritePalette_179, ANIM_TAG_WEB }, - { gBattleAnimSpritePalette_182, ANIM_TAG_UNUSED_LIGHTBULB }, - { gBattleAnimSpritePalette_183, ANIM_TAG_SLASH }, - { gBattleAnimSpritePalette_184, ANIM_TAG_FOCUS_ENERGY }, - { gBattleAnimSpritePalette_185, ANIM_TAG_SPHERE_TO_CUBE }, - { gBattleAnimSpritePalette_186, ANIM_TAG_TENDRILS }, - { gBattleAnimSpritePalette_187, ANIM_TAG_EYE }, - { gBattleAnimSpritePalette_188, ANIM_TAG_WHITE_SHADOW }, - { gBattleAnimSpritePalette_189, ANIM_TAG_TEAL_ALERT }, - { gBattleAnimSpritePalette_190, ANIM_TAG_OPENING_EYE }, - { gBattleAnimSpritePalette_191, ANIM_TAG_ROUND_WHITE_HALO }, - { gBattleAnimSpritePalette_192, ANIM_TAG_FANG_ATTACK }, - { gBattleAnimSpritePalette_193, ANIM_TAG_PURPLE_HAND_OUTLINE }, - { gBattleAnimSpritePalette_194, ANIM_TAG_MOON }, - { gBattleAnimSpritePalette_195, ANIM_TAG_SPARKLE_5 }, - { gBattleAnimSpritePalette_196, ANIM_TAG_SPIRAL }, - { gBattleAnimSpritePalette_197, ANIM_TAG_SNORE_Z }, - { gBattleAnimSpritePalette_198, ANIM_TAG_EXPLOSION }, - { gBattleAnimSpritePalette_199, ANIM_TAG_NAIL }, - { gBattleAnimSpritePalette_200, ANIM_TAG_GHOSTLY_SPIRIT }, - { gBattleAnimSpritePalette_201, ANIM_TAG_WARM_ROCK }, - { gBattleAnimSpritePalette_202, ANIM_TAG_BREAKING_EGG }, - { gBattleAnimSpritePalette_203, ANIM_TAG_THIN_RING }, - { gBattleAnimSpritePalette_204, ANIM_TAG_UNUSED_PUNCH_IMPACT }, - { gBattleAnimSpritePalette_205, ANIM_TAG_BELL }, - { gBattleAnimSpritePalette_206, ANIM_TAG_MUSIC_NOTES_2 }, - { gBattleAnimSpritePalette_207, ANIM_TAG_SPEED_DUST }, - { gBattleAnimSpritePalette_167, ANIM_TAG_TORN_METAL }, - { gBattleAnimSpritePalette_209, ANIM_TAG_THOUGHT_BUBBLE }, - { gBattleAnimSpritePalette_210, ANIM_TAG_MAGENTA_HEART }, - { gBattleAnimSpritePalette_211, ANIM_TAG_ELECTRIC_ORBS }, - { gBattleAnimSpritePalette_211, ANIM_TAG_CIRCLE_OF_LIGHT }, - { gBattleAnimSpritePalette_211, ANIM_TAG_ELECTRICITY }, - { gBattleAnimSpritePalette_064, ANIM_TAG_FINGER_2 }, - { gBattleAnimSpritePalette_215, ANIM_TAG_MOVEMENT_WAVES }, - { gBattleAnimSpritePalette_216, ANIM_TAG_RED_HEART }, - { gBattleAnimSpritePalette_217, ANIM_TAG_RED_ORB }, - { gBattleAnimSpritePalette_218, ANIM_TAG_EYE_SPARKLE }, - { gBattleAnimSpritePalette_219, ANIM_TAG_PINK_HEART }, - { gBattleAnimSpritePalette_220, ANIM_TAG_ANGEL }, - { gBattleAnimSpritePalette_221, ANIM_TAG_DEVIL }, - { gBattleAnimSpritePalette_222, ANIM_TAG_SWIPE }, - { gBattleAnimSpritePalette_223, ANIM_TAG_ROOTS }, - { gBattleAnimSpritePalette_224, ANIM_TAG_ITEM_BAG }, - { gBattleAnimSpritePalette_225, ANIM_TAG_JAGGED_MUSIC_NOTE }, - { gBattleAnimSpritePalette_226, ANIM_TAG_POKEBALL }, - { gBattleAnimSpritePalette_226, ANIM_TAG_SPOTLIGHT }, - { gBattleAnimSpritePalette_228, ANIM_TAG_LETTER_Z }, - { gBattleAnimSpritePalette_229, ANIM_TAG_RAPID_SPIN }, - { gBattleAnimSpritePalette_230, ANIM_TAG_TRI_FORCE_TRIANGLE }, - { gBattleAnimSpritePalette_231, ANIM_TAG_WISP_ORB }, - { gBattleAnimSpritePalette_231, ANIM_TAG_WISP_FIRE }, - { gBattleAnimSpritePalette_233, ANIM_TAG_GOLD_STARS }, - { gBattleAnimSpritePalette_234, ANIM_TAG_ECLIPSING_ORB }, - { gBattleAnimSpritePalette_235, ANIM_TAG_GRAY_ORB }, - { gBattleAnimSpritePalette_236, ANIM_TAG_BLUE_ORB }, - { gBattleAnimSpritePalette_237, ANIM_TAG_RED_ORB_2 }, - { gBattleAnimSpritePalette_238, ANIM_TAG_PINK_PETAL }, - { gBattleAnimSpritePalette_239, ANIM_TAG_PAIN_SPLIT }, - { gBattleAnimSpritePalette_240, ANIM_TAG_CONFETTI }, - { gBattleAnimSpritePalette_241, ANIM_TAG_GREEN_STAR }, - { gBattleAnimSpritePalette_242, ANIM_TAG_PINK_CLOUD }, - { gBattleAnimSpritePalette_243, ANIM_TAG_SWEAT_DROP }, - { gBattleAnimSpritePalette_244, ANIM_TAG_GUARD_RING }, - { gBattleAnimSpritePalette_245, ANIM_TAG_PURPLE_SCRATCH }, - { gBattleAnimSpritePalette_245, ANIM_TAG_PURPLE_SWIPE }, - { gBattleAnimSpritePalette_064, ANIM_TAG_TAG_HAND }, - { gBattleAnimSpritePalette_248, ANIM_TAG_SMALL_RED_EYE }, - { gBattleAnimSpritePalette_249, ANIM_TAG_HOLLOW_ORB }, - { gBattleAnimSpritePalette_249, ANIM_TAG_X_SIGN }, - { gBattleAnimSpritePalette_251, ANIM_TAG_BLUEGREEN_ORB }, - { gBattleAnimSpritePalette_252, ANIM_TAG_PAW_PRINT }, - { gBattleAnimSpritePalette_253, ANIM_TAG_PURPLE_FLAME }, - { gBattleAnimSpritePalette_254, ANIM_TAG_RED_BALL }, - { gBattleAnimSpritePalette_255, ANIM_TAG_SMELLINGSALT_EFFECT }, - { gBattleAnimSpritePalette_256, ANIM_TAG_METEOR }, - { gBattleAnimSpritePalette_257, ANIM_TAG_FLAT_ROCK }, - { gBattleAnimSpritePalette_258, ANIM_TAG_MAGNIFYING_GLASS }, - { gBattleAnimSpritePalette_259, ANIM_TAG_BROWN_ORB }, - { gBattleAnimSpritePalette_260, ANIM_TAG_METAL_SOUND_WAVES }, - { gBattleAnimSpritePalette_261, ANIM_TAG_FLYING_DIRT }, - { gBattleAnimSpritePalette_262, ANIM_TAG_ICICLE_SPEAR }, - { gBattleAnimSpritePalette_263, ANIM_TAG_HAIL }, - { gBattleAnimSpritePalette_264, ANIM_TAG_GLOWY_RED_ORB }, - { gBattleAnimSpritePalette_265, ANIM_TAG_GLOWY_GREEN_ORB }, - { gBattleAnimSpritePalette_266, ANIM_TAG_GREEN_SPIKE }, - { gBattleAnimSpritePalette_267, ANIM_TAG_WHITE_CIRCLE_OF_LIGHT }, - { gBattleAnimSpritePalette_268, ANIM_TAG_GLOWY_BLUE_ORB }, - { gBattleAnimSpritePalette_269, ANIM_TAG_UNUSED_RED_BRICK }, - { gBattleAnimSpritePalette_270, ANIM_TAG_WHITE_FEATHER }, - { gBattleAnimSpritePalette_271, ANIM_TAG_SPARKLE_6 }, - { gBattleAnimSpritePalette_272, ANIM_TAG_SPLASH }, - { gBattleAnimSpritePalette_272, ANIM_TAG_SWEAT_BEAD }, - { gBattleAnimSpritePalette_274, ANIM_TAG_UNUSED_GEM_1 }, - { gBattleAnimSpritePalette_274, ANIM_TAG_UNUSED_GEM_2 }, - { gBattleAnimSpritePalette_274, ANIM_TAG_UNUSED_GEM_3 }, - { gBattleAnimSpritePalette_277, ANIM_TAG_SLAM_HIT_2 }, - { gBattleAnimSpritePalette_278, ANIM_TAG_RECYCLE }, - { gBattleAnimSpritePalette_279, ANIM_TAG_UNUSED_RED_PARTICLES }, - { gBattleAnimSpritePalette_280, ANIM_TAG_PROTECT }, - { gBattleAnimSpritePalette_281, ANIM_TAG_DIRT_MOUND }, - { gBattleAnimSpritePalette_282, ANIM_TAG_SHOCK_3 }, - { gBattleAnimSpritePalette_283, ANIM_TAG_WEATHER_BALL }, - { gBattleAnimSpritePalette_284, ANIM_TAG_BIRD }, - { gBattleAnimSpritePalette_285, ANIM_TAG_CROSS_IMPACT }, - { gBattleAnimSpritePalette_286, ANIM_TAG_SLASH_2 }, - { gBattleAnimSpritePalette_287, ANIM_TAG_WHIP_HIT }, - { gBattleAnimSpritePalette_288, ANIM_TAG_BLUE_RING_2 }, -}; - -const struct BattleAnimBackground gBattleAnimBackgroundTable[] = -{ - &gBattleAnimBackgroundImage_00, &gBattleAnimBackgroundPalette_00, &gBattleAnimBackgroundTilemap_00, - &gBattleAnimBackgroundImage_00, &gBattleAnimBackgroundPalette_00, &gBattleAnimBackgroundTilemap_00, - &gBattleAnimBackgroundImage_02, &gBattleAnimBackgroundPalette_02, &gBattleAnimBackgroundTilemap_02, - &gBattleAnimBackgroundImage_03, &gBattleAnimBackgroundPalette_03, &gBattleAnimBackgroundTilemap_03, - &gBattleAnimBackgroundImage_04, &gBattleAnimBackgroundPalette_04, &gBattleAnimBackgroundTilemap_04, - &gBattleAnimBackgroundImage_04, &gBattleAnimBackgroundPalette_04, &gBattleAnimBackgroundTilemap_05, - &gBattleAnimBackgroundImage_04, &gBattleAnimBackgroundPalette_04, &gBattleAnimBackgroundTilemap_06, - &gBattleAnimBackgroundImage_07, &gBattleAnimBackgroundPalette_07, &gBattleAnimBackgroundTilemap_07, - &gBattleAnimBackgroundImage_07, &gBattleAnimBackgroundPalette_07, &gBattleAnimBackgroundTilemap_08, - &gBattleAnimBackgroundImage_09, &gBattleAnimBackgroundPalette_09, &gBattleAnimBackgroundTilemap_09, - &gBattleAnimBackgroundImage_09, &gBattleAnimBackgroundPalette_09, &gBattleAnimBackgroundTilemap_10, - &gBattleAnimBackgroundImage_11, &gBattleAnimBackgroundPalette_11, &gBattleAnimBackgroundTilemap_11, - &gBattleAnimBackgroundImage_12, &gBattleAnimBackgroundPalette_12, &gBattleAnimBackgroundTilemap_12, - &gBattleAnimBackgroundImage_12, &gBattleAnimBackgroundPalette_12, &gBattleAnimBackgroundTilemap_13, - &gBattleAnimBackgroundImage_12, &gBattleAnimBackgroundPalette_12, &gBattleAnimBackgroundTilemap_14, - &gBattleAnimBackgroundImage_15, &gBattleAnimBackgroundPalette_15, &gBattleAnimBackgroundTilemap_15, - &gBattleAnimBackgroundImage_16, &gBattleAnimBackgroundPalette_16, &gBattleAnimBackgroundTilemap_16, - &gBattleAnimBackgroundImage_17, &gBattleAnimBackgroundPalette_17, &gBattleAnimBackgroundTilemap_17, - &gBattleAnimBackgroundImage_07, &gBattleAnimBackgroundPalette_18, &gBattleAnimBackgroundTilemap_07, - &gBattleAnimBackgroundImage_07, &gBattleAnimBackgroundPalette_18, &gBattleAnimBackgroundTilemap_08, - &gBattleAnimBackgroundImage_20, &gBattleAnimBackgroundPalette_20, &gBattleAnimBackgroundTilemap_20, - &gBattleAnimBackgroundImage_21, &gBattleAnimBackgroundPalette_21, &gBattleAnimBackgroundTilemap_21, - &gBattleAnimBackgroundImage_09, &gBattleAnimBackgroundPalette_22, &gBattleAnimBackgroundTilemap_09, - &gBattleAnimBackgroundImage_09, &gBattleAnimBackgroundPalette_22, &gBattleAnimBackgroundTilemap_10, - &gBattleAnimBackgroundImage_04, &gBattleAnimBackgroundPalette_24, &gBattleAnimBackgroundTilemap_04, - &gBattleAnimBackgroundImage_04, &gBattleAnimBackgroundPalette_24, &gBattleAnimBackgroundTilemap_05, - &gBattleAnimBackgroundImage_04, &gBattleAnimBackgroundPalette_24, &gBattleAnimBackgroundTilemap_06, -}; - -extern u16 gBattlerPartyIndexes[4]; -extern u8 gBankSpriteIds[]; -extern u8 gBankAttacker; -extern u8 gBankTarget; - -// sBattleAnimScriptPtr is a pointer to the next set of battle script commands. -EWRAM_DATA const u8 *sBattleAnimScriptPtr = NULL; -EWRAM_DATA const u8 *gBattleAnimScriptRetAddr = NULL; -EWRAM_DATA void (*gAnimScriptCallback)(void) = NULL; -EWRAM_DATA s8 gAnimFramesToWait = 0; -EWRAM_DATA u8 gAnimScriptActive = FALSE; -EWRAM_DATA u8 gAnimVisualTaskCount = 0; -EWRAM_DATA u8 gAnimSoundTaskCount = 0; -EWRAM_DATA struct DisableStruct *gAnimDisableStructPtr = NULL; -EWRAM_DATA s32 gAnimMoveDmg = 0; -EWRAM_DATA u16 gAnimMovePower = 0; -EWRAM_DATA u8 gAnimFriendship = 0; -EWRAM_DATA u16 gWeatherMoveAnim = 0; -EWRAM_DATA u8 gMonAnimTaskIdArray[2] = {0}; -EWRAM_DATA u8 gAnimMoveTurn = 0; -EWRAM_DATA u8 sAnimBackgroundFadeState = 0; -EWRAM_DATA u16 sAnimMoveIndex = 0; // set but unused. -EWRAM_DATA u8 gBattleAnimAttacker = 0; -EWRAM_DATA u8 gBattleAnimTarget = 0; -EWRAM_DATA u16 gAnimSpeciesByBanks[4] = {0}; -EWRAM_DATA u8 gUnknown_0202F7D2 = 0; // some global pan variable - -u16 gSoundAnimFramesToWait; -s16 gBattleAnimArgs[ANIM_ARGS_COUNT]; -u16 gAnimSpriteIndexArray[ANIM_SPRITE_INDEX_COUNT]; - -extern struct MusicPlayerInfo gMPlay_BGM; -extern struct MusicPlayerInfo gMPlay_SE1; -extern struct MusicPlayerInfo gMPlay_SE2; - -extern const u16 gSingingMoves[]; -extern const u8 *const gBattleAnims_Moves[]; - -static void RunAnimScriptCommand(void); -static void ScriptCmd_loadspritegfx(void); -static void ScriptCmd_unloadspritegfx(void); -static void ScriptCmd_createsprite(void); -static void ScriptCmd_createvisualtask(void); -static void ScriptCmd_delay(void); -static void ScriptCmd_waitforvisualfinish(void); -static void ScriptCmd_hang1(void); -static void ScriptCmd_hang2(void); -static void ScriptCmd_end(void); -static void ScriptCmd_playse(void); -static void ScriptCmd_monbg(void); -static void sub_8076380(void); -static void task_pA_ma0A_obj_to_bg_pal(u8); -static void ScriptCmd_clearmonbg(void); -static void sub_807672C(u8); -static void ScriptCmd_monbg_22(void); -static void ScriptCmd_clearmonbg_23(void); -static void sub_80769A4(u8); -static void ScriptCmd_setalpha(void); -static void ScriptCmd_setbldcnt(void); -static void ScriptCmd_blendoff(void); -static void ScriptCmd_call(void); -static void ScriptCmd_return(void); -static void ScriptCmd_setarg(void); -static void ScriptCmd_choosetwoturnanim(void); -static void ScriptCmd_jumpifmoveturn(void); -static void ScriptCmd_jump(void); -static void ScriptCmd_fadetobg(void); -static void ScriptCmd_fadetobgfromset(void); -static void Task_FadeToBg(u8); -static void LoadMoveBg(u16); -static void LoadDefaultBg(void); -static void ScriptCmd_restorebg(void); -static void ScriptCmd_waitbgfadeout(void); -static void ScriptCmd_waitbgfadein(void); -static void ScriptCmd_changebg(void); -static void ScriptCmd_playsewithpan(void); -static void ScriptCmd_setpan(void); -static void ScriptCmd_panse_1B(void); -static void Task_PanFromInitialToTarget(u8); -static void ScriptCmd_panse_26(void); -static void ScriptCmd_panse_27(void); -static void ScriptCmd_loopsewithpan(void); -static void Task_LoopAndPlaySE(u8); -static void ScriptCmd_waitplaysewithpan(void); -static void Task_WaitAndPlaySE(u8); -static void ScriptCmd_createsoundtask(void); -static void ScriptCmd_waitsound(void); -static void ScriptCmd_jumpargeq(void); -static void ScriptCmd_jumpifcontest(void); -static void ScriptCmd_monbgprio_28(void); -static void ScriptCmd_monbgprio_29(void); -static void ScriptCmd_monbgprio_2A(void); -static void ScriptCmd_invisible(void); -static void ScriptCmd_visible(void); -static void ScriptCmd_doublebattle_2D(void); -static void ScriptCmd_doublebattle_2E(void); -static void ScriptCmd_stopsound(void); - -static void (*const sScriptCmdTable[])(void) = { - ScriptCmd_loadspritegfx, - ScriptCmd_unloadspritegfx, - ScriptCmd_createsprite, - ScriptCmd_createvisualtask, - ScriptCmd_delay, - ScriptCmd_waitforvisualfinish, - ScriptCmd_hang1, - ScriptCmd_hang2, - ScriptCmd_end, - ScriptCmd_playse, - ScriptCmd_monbg, - ScriptCmd_clearmonbg, - ScriptCmd_setalpha, - ScriptCmd_blendoff, - ScriptCmd_call, - ScriptCmd_return, - ScriptCmd_setarg, - ScriptCmd_choosetwoturnanim, - ScriptCmd_jumpifmoveturn, - ScriptCmd_jump, - ScriptCmd_fadetobg, - ScriptCmd_restorebg, - ScriptCmd_waitbgfadeout, - ScriptCmd_waitbgfadein, - ScriptCmd_changebg, - ScriptCmd_playsewithpan, - ScriptCmd_setpan, - ScriptCmd_panse_1B, - ScriptCmd_loopsewithpan, - ScriptCmd_waitplaysewithpan, - ScriptCmd_setbldcnt, - ScriptCmd_createsoundtask, - ScriptCmd_waitsound, - ScriptCmd_jumpargeq, - ScriptCmd_monbg_22, - ScriptCmd_clearmonbg_23, - ScriptCmd_jumpifcontest, - ScriptCmd_fadetobgfromset, - ScriptCmd_panse_26, - ScriptCmd_panse_27, - ScriptCmd_monbgprio_28, - ScriptCmd_monbgprio_29, - ScriptCmd_monbgprio_2A, - ScriptCmd_invisible, - ScriptCmd_visible, - ScriptCmd_doublebattle_2D, - ScriptCmd_doublebattle_2E, - ScriptCmd_stopsound, -}; - -void ClearBattleAnimationVars(void) -{ - s32 i; - - gAnimFramesToWait = 0; - gAnimScriptActive = FALSE; - gAnimVisualTaskCount = 0; - gAnimSoundTaskCount = 0; - gAnimDisableStructPtr = NULL; - gAnimMoveDmg = 0; - gAnimMovePower = 0; - gAnimFriendship = 0; - - // clear index array. - for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++) - gAnimSpriteIndexArray[i] |= 0xFFFF; - - // clear anim args. - for (i = 0; i < ANIM_ARGS_COUNT; i++) - gBattleAnimArgs[i] = 0; - - gMonAnimTaskIdArray[0] = 0xFF; - gMonAnimTaskIdArray[1] = 0xFF; - gAnimMoveTurn = 0; - sAnimBackgroundFadeState = 0; - sAnimMoveIndex = 0; - gBattleAnimAttacker = 0; - gBattleAnimTarget = 0; - gUnknown_0202F7D2 = 0; -} - -void DoMoveAnim(u16 move) -{ - gBattleAnimAttacker = gBankAttacker; - gBattleAnimTarget = gBankTarget; - LaunchBattleAnimation(gBattleAnims_Moves, move, TRUE); -} - -void LaunchBattleAnimation(const u8 *const moveAnims[], u16 move, u8 isMoveAnim) -{ - s32 i; - - if (!IsContest()) - { - UpdateBattlerSpritePriorities(); - UpdateOamPriorityInAllHealthboxes(0); - for (i = 0; i < 4; i++) - { - if (GetBattlerSide(i) != 0) - gAnimSpeciesByBanks[i] = GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES); - else - gAnimSpeciesByBanks[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES); - } - } - else - { - for (i = 0; i < 4; i++) - gAnimSpeciesByBanks[i] = EWRAM_19348[0]; - } - - if (isMoveAnim == 0) - sAnimMoveIndex = 0; - else - sAnimMoveIndex = move; - - for (i = 0; i < ANIM_ARGS_COUNT; i++) - gBattleAnimArgs[i] = 0; - - gMonAnimTaskIdArray[0] = 0xFF; - gMonAnimTaskIdArray[1] = 0xFF; - sBattleAnimScriptPtr = moveAnims[move]; - gAnimScriptActive = TRUE; - gAnimFramesToWait = 0; - gAnimScriptCallback = RunAnimScriptCommand; - - for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++) - gAnimSpriteIndexArray[i] |= 0xFFFF; - - if (isMoveAnim) - { - for (i = 0; gSingingMoves[i] != 0xFFFF; i++) - { - if (move == gSingingMoves[i]) - { - // Lower the volume for the short song that gets played. - m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 128); - break; - } - } - } - - gBattle_WIN0H = 0; - gBattle_WIN0V = 0; - gBattle_WIN1H = 0; - gBattle_WIN1V = 0; -} - -void DestroyAnimSprite(struct Sprite *sprite) -{ - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); - gAnimVisualTaskCount--; -} - -void DestroyAnimVisualTask(u8 taskId) -{ - DestroyTask(taskId); - gAnimVisualTaskCount--; -} - -void DestroyAnimSoundTask(u8 taskId) -{ - DestroyTask(taskId); - gAnimSoundTaskCount--; -} - -static void AddSpriteIndex(u16 index) -{ - s32 i; - - for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++) - { - if (gAnimSpriteIndexArray[i] == 0xFFFF) - { - gAnimSpriteIndexArray[i] = index; - return; - } - } -} - -static void ClearSpriteIndex(u16 index) -{ - s32 i; - - for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++) - { - if (gAnimSpriteIndexArray[i] == index) - { - gAnimSpriteIndexArray[i] |= 0xFFFF; - return; - } - } -} - -static void WaitAnimFrameCount(void) -{ - if (gAnimFramesToWait <= 0) - { - gAnimScriptCallback = RunAnimScriptCommand; - gAnimFramesToWait = 0; - } - else - { - gAnimFramesToWait--; - } -} - -static void RunAnimScriptCommand(void) -{ - do - { - sScriptCmdTable[T1_READ_8(sBattleAnimScriptPtr)](); - } while (gAnimFramesToWait == 0 && gAnimScriptActive); -} - -// Loads sprite graphics used in a move into memory. -// arg 0: gfx ANIM_TAG -static void ScriptCmd_loadspritegfx(void) -{ - u16 tag; - - sBattleAnimScriptPtr++; - tag = T1_READ_16(sBattleAnimScriptPtr); - LoadCompressedObjectPic(&gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(tag)]); - LoadCompressedObjectPalette(&gBattleAnimPaletteTable[GET_TRUE_SPRITE_INDEX(tag)]); - sBattleAnimScriptPtr += 2; - AddSpriteIndex(GET_TRUE_SPRITE_INDEX(tag)); - gAnimFramesToWait = 1; - gAnimScriptCallback = WaitAnimFrameCount; -} - -// Frees sprite graphics from memory when move animation no longer needs them. -// arg0: gfx ANIM_TAG -static void ScriptCmd_unloadspritegfx(void) -{ - u16 tag; - - sBattleAnimScriptPtr++; - tag = T1_READ_16(sBattleAnimScriptPtr); - FreeSpriteTilesByTag(gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(tag)].tag); - FreeSpritePaletteByTag(gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(tag)].tag); - sBattleAnimScriptPtr += 2; - ClearSpriteIndex(GET_TRUE_SPRITE_INDEX(tag)); -} - -// Creates a sprite from the given sprite template. -// arg0: SpriteTemplate -// arg1: s16[] gBattleAnimArgs -static void ScriptCmd_createsprite(void) -{ - s32 i; - const struct SpriteTemplate *template; - u8 argVar; - u8 argsCount; - s16 subpriority; - - sBattleAnimScriptPtr++; - template = (const struct SpriteTemplate *)(T2_READ_32(sBattleAnimScriptPtr)); - sBattleAnimScriptPtr += 4; - - argVar = T1_READ_8(sBattleAnimScriptPtr); - sBattleAnimScriptPtr++; - - argsCount = T1_READ_8(sBattleAnimScriptPtr); - sBattleAnimScriptPtr++; - for (i = 0; i < argsCount; i++) - { - gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr); - sBattleAnimScriptPtr += 2; - } - - if (argVar & 0x80) - { - argVar ^= 0x80; - if (argVar >= 0x40) - argVar -= 0x40; - else - argVar *= -1; - - subpriority = GetBattlerSubpriority(gBattleAnimTarget) + (s8)(argVar); - } - else - { - if (argVar >= 0x40) - argVar -= 0x40; - else - argVar *= -1; - - subpriority = GetBattlerSubpriority(gBattleAnimAttacker) + (s8)(argVar); - } - - if (subpriority < 3) - subpriority = 3; - - CreateSpriteAndAnimate(template, GetBattlerSpriteCoord(gBattleAnimTarget, 2), GetBattlerSpriteCoord(gBattleAnimTarget, 3), subpriority); - gAnimVisualTaskCount++; -} - -// Initializes an animation task. -// arg0: AnimTask function -// arg1: s16[] arguments -static void ScriptCmd_createvisualtask(void) -{ - TaskFunc taskFunc; - u8 taskPriority; - u8 taskId; - u8 numArgs; - s32 i; - - sBattleAnimScriptPtr++; - - taskFunc = (TaskFunc)T2_READ_32(sBattleAnimScriptPtr); - sBattleAnimScriptPtr += 4; - - taskPriority = T1_READ_8(sBattleAnimScriptPtr); - sBattleAnimScriptPtr++; - - numArgs = T1_READ_8(sBattleAnimScriptPtr); - sBattleAnimScriptPtr++; - - for (i = 0; i < numArgs; i++) - { - gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr); - sBattleAnimScriptPtr += 2; - } - - taskId = CreateTask(taskFunc, taskPriority); - taskFunc(taskId); - gAnimVisualTaskCount++; -} - -// Creates a visual delay. -// arg0: number of frames to wait. -static void ScriptCmd_delay(void) -{ - sBattleAnimScriptPtr++; - gAnimFramesToWait = T1_READ_8(sBattleAnimScriptPtr); - if (gAnimFramesToWait == 0) - gAnimFramesToWait = -1; - sBattleAnimScriptPtr++; - gAnimScriptCallback = WaitAnimFrameCount; -} - -// Wait for visual tasks to finish. -static void ScriptCmd_waitforvisualfinish(void) -{ - if (gAnimVisualTaskCount == 0) - { - sBattleAnimScriptPtr++; - gAnimFramesToWait = 0; - } - else - { - gAnimFramesToWait = 1; - } -} - -static void ScriptCmd_hang1(void) -{ -} - -static void ScriptCmd_hang2(void) -{ -} - -// Marks the end of an animation. Finishes the anims, tasks, and sound effects. -// started during an animaiton. -static void ScriptCmd_end(void) -{ - s32 i; - bool32 continuousAnim = FALSE; - - // keep waiting as long as there is animations to be done. - if (gAnimVisualTaskCount != 0 || gAnimSoundTaskCount != 0 - || gMonAnimTaskIdArray[0] != 0xFF || gMonAnimTaskIdArray[1] != 0xFF) - { - gSoundAnimFramesToWait = 0; - gAnimFramesToWait = 1; - return; - } - - // finish the sound effects. - if (IsSEPlaying()) - { - if (++gSoundAnimFramesToWait <= 90) // wait 90 frames, then halt the sound effect. - { - gAnimFramesToWait = 1; - return; - } - else - { - m4aMPlayStop(&gMPlay_SE1); - m4aMPlayStop(&gMPlay_SE2); - } - } - - // the SE has halted, so set the SE Frame Counter to 0 and continue. - gSoundAnimFramesToWait = 0; - - for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++) - { - if (gAnimSpriteIndexArray[i] != 0xFFFF) - { - FreeSpriteTilesByTag(gBattleAnimPicTable[gAnimSpriteIndexArray[i]].tag); - FreeSpritePaletteByTag(gBattleAnimPicTable[gAnimSpriteIndexArray[i]].tag); - gAnimSpriteIndexArray[i] |= 0xFFFF; // set terminator. - } - } - - if (!continuousAnim) // may have been used for debug? - { - m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 256); - if (IsContest() == 0) - { - UpdateBattlerSpritePriorities(); - UpdateOamPriorityInAllHealthboxes(1); - } - gAnimScriptActive = FALSE; - } -} - -// Plays a sound effect. -// arg0: sound effect ID -static void ScriptCmd_playse(void) -{ - sBattleAnimScriptPtr++; - PlaySE(T1_READ_16(sBattleAnimScriptPtr)); - sBattleAnimScriptPtr += 2; -} - -// -// arg0: battler -static void ScriptCmd_monbg(void) -{ - u8 animBank; - u8 bank; - u8 identity; - bool8 toBG_2; - u16 spriteId; - u8 taskId; - - sBattleAnimScriptPtr++; - animBank = T1_READ_8(sBattleAnimScriptPtr); - if (animBank == ANIM_BATTLER_ATTACKER) - animBank = ANIM_BATTLER_ATK_PARTNER; - else if (animBank == ANIM_BATTLER_TARGET) - animBank = ANIM_BATTLER_DEF_PARTNER; - - if (animBank == ANIM_BATTLER_ATTACKER || animBank == ANIM_BATTLER_ATK_PARTNER) - bank = gBattleAnimAttacker; - else - bank = gBattleAnimTarget; - - if (IsAnimBankSpriteVisible(bank)) - { - identity = GetBattlerPosition(bank); - identity += 0xFF; - if (identity <= 1 || IsContest() != 0) - toBG_2 = 0; - else - toBG_2 = 1; - - MoveBattlerSpriteToBG(bank, toBG_2); - spriteId = gBankSpriteIds[bank]; - taskId = CreateTask(task_pA_ma0A_obj_to_bg_pal, 10); - gTasks[taskId].data[0] = spriteId; - gTasks[taskId].data[1] = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x; - gTasks[taskId].data[2] = gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y; - if (toBG_2 == 0) - { - gTasks[taskId].data[3] = gBattle_BG1_X; - gTasks[taskId].data[4] = gBattle_BG1_Y; - } - else - { - gTasks[taskId].data[3] = gBattle_BG2_X; - gTasks[taskId].data[4] = gBattle_BG2_Y; - } - gTasks[taskId].data[5] = toBG_2; - gTasks[taskId].data[6] = bank; - gMonAnimTaskIdArray[0] = taskId; - - } - - bank ^= 2; - if (animBank >= ANIM_BATTLER_ATK_PARTNER && IsAnimBankSpriteVisible(bank)) - { - identity = GetBattlerPosition(bank); - identity += 0xFF; - if (identity <= 1 || IsContest() != 0) - toBG_2 = 0; - else - toBG_2 = 1; - MoveBattlerSpriteToBG(bank, toBG_2); - spriteId = gBankSpriteIds[bank]; - taskId = CreateTask(task_pA_ma0A_obj_to_bg_pal, 10); - gTasks[taskId].data[0] = spriteId; - gTasks[taskId].data[1] = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x; - gTasks[taskId].data[2] = gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y; - if (toBG_2 == 0) - { - gTasks[taskId].data[3] = gBattle_BG1_X; - gTasks[taskId].data[4] = gBattle_BG1_Y; - } - else - { - gTasks[taskId].data[3] = gBattle_BG2_X; - gTasks[taskId].data[4] = gBattle_BG2_Y; - } - - gTasks[taskId].data[5] = toBG_2; - gTasks[taskId].data[6] = bank; - gMonAnimTaskIdArray[1] = taskId; - } - - sBattleAnimScriptPtr++; -} - -bool8 IsAnimBankSpriteVisible(u8 bank) -{ - if (IsContest()) - { - if (bank == gBattleAnimAttacker) - return TRUE; - else - return FALSE; - } - if (!IsBankSpritePresent(bank)) - return FALSE; - if (IsContest()) - return TRUE; // this line wont ever be reached. - if (!(EWRAM_17800[bank].unk0 & 1) || !gSprites[gBankSpriteIds[bank]].invisible) - return TRUE; - - return FALSE; -} - -void MoveBattlerSpriteToBG(u8 bank, u8 toBG_2) -{ - u8 spriteId; - - if (toBG_2 == 0) - { - volatile u8 pointlessZero; - struct UnknownStruct2 s; - u8 r2; - - sub_8078914(&s); - DmaFill32Large(3, 0, s.unk0, 0x2000, 0x1000); - pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? - pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? - DmaFill16Defvars(3, 0xFF, (void *)s.unk4, 0x1000); - - REG_BG1CNT_BITFIELD.priority = 2; - REG_BG1CNT_BITFIELD.screenSize = 1; - REG_BG1CNT_BITFIELD.areaOverflowMode = 0; - - spriteId = gBankSpriteIds[bank]; - gBattle_BG1_X = -(gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x) + 32; - if (IsContest() != 0 && IsSpeciesNotUnown(EWRAM_19348[0]) != 0) - gBattle_BG1_X--; - gBattle_BG1_Y = -(gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y) + 32; - gSprites[gBankSpriteIds[bank]].invisible = TRUE; - - REG_BG1HOFS = gBattle_BG1_X; - REG_BG1VOFS = gBattle_BG1_Y; - - LoadPalette(gPlttBufferUnfaded + 0x100 + bank * 16, s.unk8 * 16, 32); - DmaCopy32Defvars(3, gPlttBufferUnfaded + 0x100 + bank * 16, (u16 *)PLTT + s.unk8 * 16, 32); - - if (IsContest() != 0) - r2 = 0; - else - r2 = GetBattlerPosition(bank); - sub_80E4EF8(0, 0, r2, s.unk8, (u32)s.unk0, (((s32)s.unk4 - VRAM) / 2048), REG_BG1CNT_BITFIELD.charBaseBlock); - if (IsContest() != 0) - sub_8076380(); - } - else - { - volatile u8 pointlessZero; - - DmaFill32Large(3, 0, (void *)(VRAM + 0x6000), 0x2000, 0x1000); - pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? - pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? - DmaFill32Defvars(3, 0, (void *)(VRAM + 0xF000), 0x800); - - REG_BG2CNT_BITFIELD.priority = 2; - REG_BG2CNT_BITFIELD.screenSize = 1; - REG_BG2CNT_BITFIELD.areaOverflowMode = 0; - - spriteId = gBankSpriteIds[bank]; - gBattle_BG2_X = -(gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x) + 32; - gBattle_BG2_Y = -(gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y) + 32; - gSprites[gBankSpriteIds[bank]].invisible = TRUE; - - REG_BG2HOFS = gBattle_BG2_X; - REG_BG2VOFS = gBattle_BG2_Y; - - LoadPalette(gPlttBufferUnfaded + 0x100 + bank * 16, 0x90, 32); - DmaCopy32Defvars(3, gPlttBufferUnfaded + 0x100 + bank * 16, (void *)(PLTT + 0x120), 32); - - sub_80E4EF8(0, 0, GetBattlerPosition(bank), 9, 0x6000, 0x1E, REG_BG2CNT_BITFIELD.charBaseBlock); - } -} - -static void sub_8076380(void) -{ - int i; - int j; - struct UnknownStruct2 s; - u16 *ptr; - - if (IsSpeciesNotUnown(EWRAM_19348[0])) - { - sub_8078914(&s); - ptr = s.unk4; - for (i = 0; i < 8; i++) - { - for (j = 0; j < 4; j++) - { - u16 temp = ptr[j + i * 32]; - - ptr[j + i * 32] = ptr[7 - j + i * 32]; - ptr[7 - j + i * 32] = temp; - } - } - for (i = 0; i < 8; i++) - { - for (j = 0; j < 8; j++) - ptr[j + i * 32] ^= 0x400; - } - } -} - -void sub_80763FC(u16 a, u16 *b, u32 c, u8 d) -{ - u8 i; - u8 j; - u32 r9; - - if (d == 0) - r9 = 32; - else - r9 = 64; - a <<= 12; - for (i = 0; i < r9; i++) - { - for (j = 0; j < 32; j++) - b[j + i * 32] = ((b[j + i * 32] & 0xFFF) | a) + c; - } -} - -void sub_8076464(u8 a) -{ - volatile u8 pointlessZero; - struct UnknownStruct2 s; - - sub_8078914(&s); - if (a == 0 || IsContest() != 0) - { - DmaFill32Large(3, 0, s.unk0, 0x2000, 0x1000); - pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? - pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? - DmaFill32Defvars(3, 0, s.unk4, 0x800); - gBattle_BG1_X = 0; - gBattle_BG1_Y = 0; - } - else - { - DmaFill32Large(3, 0, (void *)(VRAM + 0x6000), 0x2000, 0x1000); - pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? - pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? - DmaFill32Defvars(3, 0, (void *)(VRAM + 0xF000), 0x800); - gBattle_BG2_X = 0; - gBattle_BG2_Y = 0; - } -} - -static void task_pA_ma0A_obj_to_bg_pal(u8 taskId) -{ - u8 spriteId, palIndex; - s16 x, y; - struct UnknownStruct2 s; - - spriteId = gTasks[taskId].data[0]; - palIndex = gTasks[taskId].data[6]; - sub_8078914(&s); - x = gTasks[taskId].data[1] - (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x); - y = gTasks[taskId].data[2] - (gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y); - - if (gTasks[taskId].data[5] == 0) - { - gBattle_BG1_X = x + gTasks[taskId].data[3]; - gBattle_BG1_Y = y + gTasks[taskId].data[4]; - DmaCopy32Defvars(3, gPlttBufferFaded + 0x100 + palIndex * 16, gPlttBufferFaded + 0x100 + s.unk8 * 16 - 256, 32); - } - else - { - gBattle_BG2_X = x + gTasks[taskId].data[3]; - gBattle_BG2_Y = y + gTasks[taskId].data[4]; - DmaCopy32Defvars(3, gPlttBufferFaded + 0x100 + palIndex * 16, gPlttBufferFaded + 0x100 - 112, 32); - } -} - -static void ScriptCmd_clearmonbg(void) -{ - u8 animBankId; - u8 bank; - u8 taskId; - - sBattleAnimScriptPtr++; - animBankId = T1_READ_8(sBattleAnimScriptPtr); - - if (animBankId == ANIM_BATTLER_ATTACKER) - animBankId = ANIM_BATTLER_ATK_PARTNER; - else if (animBankId == ANIM_BATTLER_TARGET) - animBankId = ANIM_BATTLER_DEF_PARTNER; - - if (animBankId == ANIM_BATTLER_ATTACKER || animBankId == ANIM_BATTLER_ATK_PARTNER) - bank = gBattleAnimAttacker; - else - bank = gBattleAnimTarget; - - if (gMonAnimTaskIdArray[0] != 0xFF) - gSprites[gBankSpriteIds[bank]].invisible = FALSE; - if (animBankId > 1 && gMonAnimTaskIdArray[1] != 0xFF) - gSprites[gBankSpriteIds[bank ^ 2]].invisible = FALSE; - else - animBankId = 0; - - taskId = CreateTask(sub_807672C, 5); - gTasks[taskId].data[0] = animBankId; - gTasks[taskId].data[2] = bank; - sBattleAnimScriptPtr++; -} - -static void sub_807672C(u8 taskId) -{ - u8 identity; - u8 to_BG2; - - gTasks[taskId].data[1]++; - if (gTasks[taskId].data[1] != 1) - { - identity = GetBattlerPosition(gTasks[taskId].data[2]); - identity += 0xFF; - if (identity <= 1 || IsContest() != 0) - to_BG2 = 0; - else - to_BG2 = 1; - if (gMonAnimTaskIdArray[0] != 0xFF) - { - sub_8076464(to_BG2); - DestroyTask(gMonAnimTaskIdArray[0]); - gMonAnimTaskIdArray[0] = 0xFF; - } - if (gTasks[taskId].data[0] > 1) - { - sub_8076464(to_BG2 ^ 1); - DestroyTask(gMonAnimTaskIdArray[1]); - gMonAnimTaskIdArray[1] = 0xFF; - } - DestroyTask(taskId); - } -} - -static void ScriptCmd_monbg_22(void) -{ - u8 animBankId; - u8 bank; - u8 identity; - u8 r1; - - sBattleAnimScriptPtr++; - animBankId = T1_READ_8(sBattleAnimScriptPtr); - - if (animBankId == ANIM_BATTLER_ATTACKER) - animBankId = ANIM_BATTLER_ATK_PARTNER; - else if (animBankId == ANIM_BATTLER_TARGET) - animBankId = ANIM_BATTLER_DEF_PARTNER; - - if (animBankId == ANIM_BATTLER_ATTACKER || animBankId == ANIM_BATTLER_ATK_PARTNER) - bank = gBattleAnimAttacker; - else - bank = gBattleAnimTarget; - - if (IsAnimBankSpriteVisible(bank)) - { - identity = GetBattlerPosition(bank); - identity += 0xFF; - if (identity <= 1 || IsContest() != 0) - r1 = 0; - else - r1 = 1; - MoveBattlerSpriteToBG(bank, r1); - gSprites[gBankSpriteIds[bank]].invisible = FALSE; - } - - bank ^= 2; - if (animBankId > ANIM_BATTLER_TARGET && IsAnimBankSpriteVisible(bank)) - { - identity = GetBattlerPosition(bank); - identity += 0xFF; - if (identity <= 1 || IsContest() != 0) - r1 = 0; - else - r1 = 1; - MoveBattlerSpriteToBG(bank, r1); - gSprites[gBankSpriteIds[bank]].invisible = FALSE; - } - sBattleAnimScriptPtr++; -} - -static void ScriptCmd_clearmonbg_23(void) -{ - u8 animBankId; - u8 bank; - u8 taskId; - - sBattleAnimScriptPtr++; - animBankId = T1_READ_8(sBattleAnimScriptPtr); - - if (animBankId == ANIM_BATTLER_ATTACKER) - animBankId = ANIM_BATTLER_ATK_PARTNER; - else if (animBankId == ANIM_BATTLER_TARGET) - animBankId = ANIM_BATTLER_DEF_PARTNER; - - if (animBankId == ANIM_BATTLER_ATTACKER || animBankId == ANIM_BATTLER_ATK_PARTNER) - bank = gBattleAnimAttacker; - else - bank = gBattleAnimTarget; - - if (IsAnimBankSpriteVisible(bank)) - gSprites[gBankSpriteIds[bank]].invisible = FALSE; - if (animBankId > 1 && IsAnimBankSpriteVisible(bank ^ 2)) - gSprites[gBankSpriteIds[bank ^ 2]].invisible = FALSE; - else - animBankId = 0; - - taskId = CreateTask(sub_80769A4, 5); - gTasks[taskId].data[0] = animBankId; - gTasks[taskId].data[2] = bank; - - sBattleAnimScriptPtr++; -} - -static void sub_80769A4(u8 taskId) -{ - u8 identity; - u8 bank; - u8 toBG_2; - - gTasks[taskId].data[1]++; - if (gTasks[taskId].data[1] != 1) - { - bank = gTasks[taskId].data[2]; - identity = GetBattlerPosition(bank); - identity += 0xFF; - if (identity <= 1 || IsContest() != 0) - toBG_2 = 0; - else - toBG_2 = 1; - if (IsAnimBankSpriteVisible(bank)) - sub_8076464(toBG_2); - if (gTasks[taskId].data[0] > 1 && IsAnimBankSpriteVisible(bank ^ 2)) - sub_8076464(toBG_2 ^ 1); - DestroyTask(taskId); - } -} - -// Sets transparency of sprite. -// arg0: sprite alpha value -// arg1: background alpha value -static void ScriptCmd_setalpha(void) -{ - u16 spriteAlpha, bgAlpha; - - sBattleAnimScriptPtr++; - spriteAlpha = *(sBattleAnimScriptPtr++); - bgAlpha = *(sBattleAnimScriptPtr++) << 8; - REG_BLDCNT = BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_EFFECT_BLEND; - REG_BLDALPHA = spriteAlpha | bgAlpha; -} - -static void ScriptCmd_setbldcnt(void) -{ - u16 half1, half2; - - sBattleAnimScriptPtr++; - half1 = *(sBattleAnimScriptPtr++); - half2 = *(sBattleAnimScriptPtr++) << 8; - REG_BLDCNT = half1 | half2; -} - -// Turns off alpha blending / semi transparency. -static void ScriptCmd_blendoff(void) -{ - sBattleAnimScriptPtr++; - REG_BLDCNT = 0; - REG_BLDALPHA = 0; -} - -// Calls another animation by resetting sBattleAnimScriptPtr. -// arg0: Function -static void ScriptCmd_call(void) -{ - sBattleAnimScriptPtr++; - gBattleAnimScriptRetAddr = sBattleAnimScriptPtr + 4; - sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr); -} - -// Returns to the function that called this. -static void ScriptCmd_return(void) -{ - sBattleAnimScriptPtr = gBattleAnimScriptRetAddr; -} - -// Sets a value into gBattleAnimArgs[8] -// arg0: index / arg number -// arg1: value to set -static void ScriptCmd_setarg(void) -{ - const u8 *addr = sBattleAnimScriptPtr; - u16 value; - u8 argId; - - sBattleAnimScriptPtr++; - argId = T1_READ_8(sBattleAnimScriptPtr); - sBattleAnimScriptPtr++; - value = T1_READ_16(sBattleAnimScriptPtr); - sBattleAnimScriptPtr = addr + 4; - gBattleAnimArgs[argId] = value; -} - -// Flips between the first and second step of a move with two turns. -// arg0: first turn animation -// arg1: second turn animation -static void ScriptCmd_choosetwoturnanim(void) -{ - sBattleAnimScriptPtr++; - if (gAnimMoveTurn & 1) - sBattleAnimScriptPtr += 4; - sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr); -} - -// Jump to specified step of multi turn moves. -// arg0: move turn -// arg1: turn animation -static void ScriptCmd_jumpifmoveturn(void) -{ - u8 toCheck; - - sBattleAnimScriptPtr++; - toCheck = T1_READ_8(sBattleAnimScriptPtr); - sBattleAnimScriptPtr++; - - if (toCheck == gAnimMoveTurn) - { - sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr); - } - else - { - sBattleAnimScriptPtr += 4; - } -} - -// Jump to another animation. -// arg0: new animation -static void ScriptCmd_jump(void) -{ - sBattleAnimScriptPtr++; - sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr); -} - -bool8 IsContest(void) -{ - if (!gMain.inBattle) - return TRUE; - else - return FALSE; -} - -#define tBackgroundId data[0] -#define tState data[10] - -// Fades the screen and sets new background image. -// arg0: background ID -static void ScriptCmd_fadetobg(void) -{ - u8 backgroundId; - u8 taskId; - - sBattleAnimScriptPtr++; - backgroundId = T1_READ_8(sBattleAnimScriptPtr); - sBattleAnimScriptPtr++; - taskId = CreateTask(Task_FadeToBg, 5); - gTasks[taskId].tBackgroundId = backgroundId; - sAnimBackgroundFadeState = 1; -} - -// Fades to background image based on context of move (contest, battle) -// arg0: opponent background image ID -// arg1: player background image ID -// arg2: contest background image ID -static void ScriptCmd_fadetobgfromset(void) -{ - u8 bg1, bg2, bg3; - u8 taskId; - - sBattleAnimScriptPtr++; - bg1 = sBattleAnimScriptPtr[0]; - bg2 = sBattleAnimScriptPtr[1]; - bg3 = sBattleAnimScriptPtr[2]; - sBattleAnimScriptPtr += 3; - taskId = CreateTask(Task_FadeToBg, 5); - - if (IsContest()) - gTasks[taskId].tBackgroundId = bg3; - else if (GetBattlerSide(gBattleAnimTarget) == 0) - gTasks[taskId].tBackgroundId = bg2; - else - gTasks[taskId].tBackgroundId = bg1; - - sAnimBackgroundFadeState = 1; -} - -static void Task_FadeToBg(u8 taskId) -{ - if (gTasks[taskId].tState == 0) - { - BeginHardwarePaletteFade(0xE8, 0, 0, 16, 0); - gTasks[taskId].tState++; - return; - } - if (gPaletteFade.active) - return; - if (gTasks[taskId].tState == 1) - { - gTasks[taskId].tState++; - sAnimBackgroundFadeState = 2; - } - else if (gTasks[taskId].tState == 2) - { - s16 bgId = (u16)gTasks[taskId].tBackgroundId; - - if (bgId == -1) - LoadDefaultBg(); - else - LoadMoveBg(bgId); - - BeginHardwarePaletteFade(0xE8, 0, 16, 0, 1); - gTasks[taskId].tState++; - return; - } - if (gPaletteFade.active) - return; - if (gTasks[taskId].tState == 3) - { - DestroyTask(taskId); - sAnimBackgroundFadeState = 0; - } -} - -static void LoadMoveBg(u16 bgId) -{ - if (IsContest()) - { - void *tilemap = gBattleAnimBackgroundTable[bgId].tilemap; - - LZDecompressWram(tilemap, IsContest() ? EWRAM_14800 : EWRAM_18000); - sub_80763FC(sub_80789BC(), IsContest() ? EWRAM_14800 : EWRAM_18000, 0x100, 0); - DmaCopy32Defvars(3, IsContest() ? EWRAM_14800 : EWRAM_18000, (void *)(VRAM + 0xD000), 0x800); - LZDecompressVram(gBattleAnimBackgroundTable[bgId].image, (void *)(VRAM + 0x2000)); - LoadCompressedPalette(gBattleAnimBackgroundTable[bgId].palette, sub_80789BC() * 16, 32); - } - else - { - LZDecompressVram(gBattleAnimBackgroundTable[bgId].tilemap, (void *)(VRAM + 0xD000)); - LZDecompressVram(gBattleAnimBackgroundTable[bgId].image, (void *)(VRAM + 0x8000)); - LoadCompressedPalette(gBattleAnimBackgroundTable[bgId].palette, 32, 32); - } -} - -static void LoadDefaultBg(void) -{ - if (IsContest()) - LoadContestBgAfterMoveAnim(); - else - DrawMainBattleBackground(); -} - -// Restores default background image. -static void ScriptCmd_restorebg(void) -{ - u8 taskId; - - sBattleAnimScriptPtr++; - taskId = CreateTask(Task_FadeToBg, 5); - gTasks[taskId].tBackgroundId = 0xFFFF; - sAnimBackgroundFadeState = 1; -} - -#undef tBackgroundId -#undef tState - -// Wait for background image fade out to compete. -static void ScriptCmd_waitbgfadeout(void) -{ - if (sAnimBackgroundFadeState == 2) - { - sBattleAnimScriptPtr++; - gAnimFramesToWait = 0; - } - else - { - gAnimFramesToWait = 1; - } -} - -// Wait for background image fade in to compete. -static void ScriptCmd_waitbgfadein(void) -{ - if (sAnimBackgroundFadeState == 0) - { - sBattleAnimScriptPtr++; - gAnimFramesToWait = 0; - } - else - { - gAnimFramesToWait = 1; - } -} - -// Change background. -// arg0: background image ID -static void ScriptCmd_changebg(void) -{ - sBattleAnimScriptPtr++; - LoadMoveBg(T1_READ_8(sBattleAnimScriptPtr)); - sBattleAnimScriptPtr++; -} - -//Weird control flow -/* -s8 BattleAnimAdjustPanning(s8 a) -{ - if (!IsContest() && (EWRAM_17810[gBattleAnimAttacker].unk0 & 0x10)) - { - a = GetBattlerSide(gBattleAnimAttacker) ? SOUND_PAN_ATTACKER : SOUND_PAN_TARGET; - } - //_08076FDC - else - { - if (IsContest()) - { - if (gBattleAnimAttacker == gBattleAnimTarget && gBattleAnimAttacker == 2 - && a == SOUND_PAN_TARGET) - { - //jump to _0807707A - if (a < SOUND_PAN_ATTACKER_NEG) - a = SOUND_PAN_ATTACKER; - return a; - } - } - //_08077004 - else - { - if (GetBattlerSide(gBattleAnimAttacker) == 0) - { - if (GetBattlerSide(gBattleAnimTarget) == 0) - } - //_08077042 - else - { - - } - //_0807706C - } - } - //_0807706E -} -*/ -NAKED -s8 BattleAnimAdjustPanning(s8 a) -{ - asm(".syntax unified\n\ - push {r4,lr}\n\ - lsls r0, 24\n\ - lsrs r4, r0, 24\n\ - bl IsContest\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _08076FDC\n\ - ldr r0, _08076FD4 @ =gBattleAnimAttacker\n\ - ldrb r2, [r0]\n\ - lsls r0, r2, 1\n\ - adds r0, r2\n\ - lsls r0, 2\n\ - ldr r1, _08076FD8 @ =gSharedMem + 0x17810\n\ - adds r0, r1\n\ - ldrb r1, [r0]\n\ - movs r0, 0x10\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08076FDC\n\ - adds r0, r2, 0\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - movs r4, 0xC0\n\ - cmp r0, 0\n\ - beq _0807706E\n\ - movs r4, 0x3F\n\ - b _0807706E\n\ - .align 2, 0\n\ -_08076FD4: .4byte gBattleAnimAttacker\n\ -_08076FD8: .4byte gSharedMem + 0x17810\n\ -_08076FDC:\n\ - bl IsContest\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08077004\n\ - ldr r0, _08076FFC @ =gBattleAnimAttacker\n\ - ldr r1, _08077000 @ =gBattleAnimTarget\n\ - ldrb r0, [r0]\n\ - ldrb r1, [r1]\n\ - cmp r0, r1\n\ - bne _08077068\n\ - cmp r0, 0x2\n\ - bne _08077068\n\ - cmp r4, 0x3F\n\ - beq _0807707A\n\ - b _08077068\n\ - .align 2, 0\n\ -_08076FFC: .4byte gBattleAnimAttacker\n\ -_08077000: .4byte gBattleAnimTarget\n\ -_08077004:\n\ - ldr r0, _0807702C @ =gBattleAnimAttacker\n\ - ldrb r0, [r0]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _08077042\n\ - ldr r0, _08077030 @ =gBattleAnimTarget\n\ - ldrb r0, [r0]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _0807706E\n\ - lsls r0, r4, 24\n\ - asrs r1, r0, 24\n\ - cmp r1, 0x3F\n\ - bne _08077034\n\ - movs r4, 0xC0\n\ - b _0807706E\n\ - .align 2, 0\n\ -_0807702C: .4byte gBattleAnimAttacker\n\ -_08077030: .4byte gBattleAnimTarget\n\ -_08077034:\n\ - movs r0, 0x40\n\ - negs r0, r0\n\ - cmp r1, r0\n\ - beq _0807706E\n\ - negs r0, r1\n\ - lsls r0, 24\n\ - b _0807706C\n\ -_08077042:\n\ - ldr r0, _08077064 @ =gBattleAnimTarget\n\ - ldrb r0, [r0]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0x1\n\ - bne _08077068\n\ - lsls r0, r4, 24\n\ - asrs r0, 24\n\ - movs r1, 0x40\n\ - negs r1, r1\n\ - cmp r0, r1\n\ - bne _0807706E\n\ - movs r4, 0x3F\n\ - b _0807706E\n\ - .align 2, 0\n\ -_08077064: .4byte gBattleAnimTarget\n\ -_08077068:\n\ - lsls r0, r4, 24\n\ - negs r0, r0\n\ -_0807706C:\n\ - lsrs r4, r0, 24\n\ -_0807706E:\n\ - lsls r0, r4, 24\n\ - asrs r0, 24\n\ - cmp r0, 0x3F\n\ - ble _0807707A\n\ - movs r4, 0x3F\n\ - b _08077088\n\ -_0807707A:\n\ - lsls r0, r4, 24\n\ - asrs r0, 24\n\ - movs r1, 0x40\n\ - negs r1, r1\n\ - cmp r0, r1\n\ - bge _08077088\n\ - movs r4, 0xC0\n\ -_08077088:\n\ - lsls r0, r4, 24\n\ - asrs r0, 24\n\ - pop {r4}\n\ - pop {r1}\n\ - bx r1\n\ - .syntax divided\n"); -} - -s8 BattleAnimAdjustPanning2(s8 pan) -{ - if (!IsContest() && (EWRAM_17810[gBattleAnimAttacker].unk0 & 0x10)) - { - if (GetBattlerSide(gBattleAnimAttacker) != 0) - pan = SOUND_PAN_TARGET; - else - pan = SOUND_PAN_ATTACKER; - } - else - { - if (GetBattlerSide(gBattleAnimAttacker) != 0 || IsContest() != 0) - pan = -pan; - } - return pan; -} - -s16 sub_8077104(s16 newPan, int oldPan) -{ - s16 var = newPan; - - if (var > SOUND_PAN_TARGET) - var = SOUND_PAN_TARGET; - else if (var < SOUND_PAN_ATTACKER_NEG) - var = SOUND_PAN_ATTACKER_NEG; - return var; -} - -s16 CalculatePanIncrement(s16 sourcePan, s16 targetPan, s16 incrementPan) -{ - u16 ret; - - if (sourcePan < targetPan) - ret = ((incrementPan < 0) ? -incrementPan : incrementPan); - else if (sourcePan > targetPan) - ret = -((incrementPan < 0) ? -incrementPan : incrementPan); - else - ret = 0; - - return ret; -} - -static void ScriptCmd_playsewithpan(void) -{ - u16 soundId; - s8 pan; - - sBattleAnimScriptPtr++; - soundId = T1_READ_16(sBattleAnimScriptPtr); - pan = T1_READ_8(sBattleAnimScriptPtr + 2); - PlaySE12WithPanning(soundId, BattleAnimAdjustPanning(pan)); - sBattleAnimScriptPtr += 3; -} - -static void ScriptCmd_setpan(void) -{ - s8 pan; - - sBattleAnimScriptPtr++; - pan = T1_READ_8(sBattleAnimScriptPtr); - SE12PanpotControl(BattleAnimAdjustPanning(pan)); - sBattleAnimScriptPtr++; -} - -#define tInitialPan data[0] -#define tTargetPan data[1] -#define tIncrementPan data[2] -#define tFramesToWait data[3] -#define tCurrentPan data[4] -#define tFrameCounter data[8] - -static void ScriptCmd_panse_1B(void) -{ - u16 songNum; - s8 currentPanArg, incrementPan, incrementPanArg, currentPan, targetPan; - u8 framesToWait; - u8 taskId; - - sBattleAnimScriptPtr++; - songNum = T1_READ_16(sBattleAnimScriptPtr); - currentPanArg = T1_READ_8(sBattleAnimScriptPtr + 2); - incrementPan = T1_READ_8(sBattleAnimScriptPtr + 3); - incrementPanArg = T1_READ_8(sBattleAnimScriptPtr + 4); - framesToWait = T1_READ_8(sBattleAnimScriptPtr + 5); - - currentPan = BattleAnimAdjustPanning(currentPanArg); - targetPan = BattleAnimAdjustPanning(incrementPan); - incrementPan = CalculatePanIncrement(currentPan, targetPan, incrementPanArg); - taskId = CreateTask(Task_PanFromInitialToTarget, 1); - gTasks[taskId].tInitialPan = currentPan; - gTasks[taskId].tTargetPan = targetPan; - gTasks[taskId].tIncrementPan = incrementPan; - gTasks[taskId].tFramesToWait = framesToWait; - gTasks[taskId].tCurrentPan = currentPan; - - PlaySE12WithPanning(songNum, currentPan); - - gAnimSoundTaskCount++; - sBattleAnimScriptPtr += 6; -} - -void Task_PanFromInitialToTarget(u8 taskId) -{ - bool32 destroyTask = FALSE; - if (gTasks[taskId].tFrameCounter++ >= gTasks[taskId].tFramesToWait) - { - s16 pan; - s16 initialPanning, targetPanning, currentPan, incrementPan; - - gTasks[taskId].tFrameCounter = 0; - initialPanning = gTasks[taskId].tInitialPan; - targetPanning = gTasks[taskId].tTargetPan; - currentPan = gTasks[taskId].tCurrentPan; - incrementPan = gTasks[taskId].tIncrementPan; - pan = currentPan + incrementPan; - gTasks[taskId].tCurrentPan = pan; - - if (incrementPan == 0) // If we're not incrementing, just cancel the task immediately - { - destroyTask = TRUE; - } - else if (initialPanning < targetPanning) // Panning increasing - { - if (pan >= targetPanning) // Target reached - destroyTask = TRUE; - } - else // Panning decreasing - { - if (pan <= targetPanning) // Target reached - destroyTask = TRUE; - } - - if (destroyTask) - { - pan = targetPanning; - DestroyTask(taskId); - gAnimSoundTaskCount--; - } - - SE12PanpotControl(pan); - } -} - -static void ScriptCmd_panse_26(void) -{ - u16 songId; - s8 currentPan, targetPan, incrementPan; - u8 framesToWait; - u8 taskId; - - sBattleAnimScriptPtr++; - songId = T1_READ_16(sBattleAnimScriptPtr); - currentPan = T1_READ_8(sBattleAnimScriptPtr + 2); - targetPan = T1_READ_8(sBattleAnimScriptPtr + 3); - incrementPan = T1_READ_8(sBattleAnimScriptPtr + 4); - framesToWait = T1_READ_8(sBattleAnimScriptPtr + 5); - - taskId = CreateTask(Task_PanFromInitialToTarget, 1); - gTasks[taskId].tInitialPan = currentPan; - gTasks[taskId].tTargetPan = targetPan; - gTasks[taskId].tIncrementPan = incrementPan; - gTasks[taskId].tFramesToWait = framesToWait; - gTasks[taskId].tCurrentPan = currentPan; - - PlaySE12WithPanning(songId, currentPan); - - gAnimSoundTaskCount++; - sBattleAnimScriptPtr += 6; -} - -static void ScriptCmd_panse_27(void) -{ - u16 songId; - u8 targetPanArg, incrementPanArg, currentPan, currentPanArg; - s8 targetPan, incrementPan, framesToWait; - u8 taskId; - - sBattleAnimScriptPtr++; - songId = T1_READ_16(sBattleAnimScriptPtr); - currentPanArg = T1_READ_8(sBattleAnimScriptPtr + 2); - targetPanArg = T1_READ_8(sBattleAnimScriptPtr + 3); - incrementPanArg = T1_READ_8(sBattleAnimScriptPtr + 4); - currentPan = T1_READ_8(sBattleAnimScriptPtr + 5); - - targetPan = BattleAnimAdjustPanning2(currentPanArg); - incrementPan = BattleAnimAdjustPanning2(targetPanArg); - framesToWait = BattleAnimAdjustPanning2(incrementPanArg); - - taskId = CreateTask(Task_PanFromInitialToTarget, 1); - gTasks[taskId].data[0] = targetPan; - gTasks[taskId].data[1] = incrementPan; - gTasks[taskId].data[2] = framesToWait; - gTasks[taskId].data[3] = currentPan; - gTasks[taskId].data[4] = targetPan; - - PlaySE12WithPanning(songId, targetPan); - - gAnimSoundTaskCount++; - sBattleAnimScriptPtr += 6; -} - -#undef tInitialPan -#undef tTargetPan -#undef tIncrementPan -#undef tFramesToWait -#undef tCurrentPan -#undef tFrameCounter - -#define tSongId data[0] -#define tPanning data[1] -#define tFramesToWait data[2] -#define tNumberOfPlays data[3] -#define tFrameCounter data[8] - -static void ScriptCmd_loopsewithpan(void) -{ - u16 songId; - s8 panningArg, panning; - u8 framesToWait, numberOfPlays; - u8 taskId; - - sBattleAnimScriptPtr++; - songId = T1_READ_16(sBattleAnimScriptPtr); - panningArg = T1_READ_8(sBattleAnimScriptPtr + 2); - framesToWait = T1_READ_8(sBattleAnimScriptPtr + 3); - numberOfPlays = T1_READ_8(sBattleAnimScriptPtr + 4); - panning = BattleAnimAdjustPanning(panningArg); - - taskId = CreateTask(Task_LoopAndPlaySE, 1); - gTasks[taskId].tSongId = songId; - gTasks[taskId].tPanning = panning; - gTasks[taskId].tFramesToWait = framesToWait; - gTasks[taskId].tNumberOfPlays = numberOfPlays; - gTasks[taskId].tFrameCounter = framesToWait; - gTasks[taskId].func(taskId); - - gAnimSoundTaskCount++; - sBattleAnimScriptPtr += 5; -} - -static void Task_LoopAndPlaySE(u8 taskId) -{ - if (gTasks[taskId].tFrameCounter++ >= gTasks[taskId].tFramesToWait) - { - u16 songId; - s8 panning; - u8 numberOfPlays; - - gTasks[taskId].tFrameCounter = 0; - songId = gTasks[taskId].tSongId; - panning = gTasks[taskId].tPanning; - numberOfPlays = --gTasks[taskId].tNumberOfPlays; - PlaySE12WithPanning(songId, panning); - if (numberOfPlays == 0) - { - DestroyTask(taskId); - gAnimSoundTaskCount--; - } - } -} - -#undef tSongId -#undef tPanning -#undef tFramesToWait -#undef tNumberOfPlays -#undef tFrameCounter - -#define tSongId data[0] -#define tPanning data[1] -#define tFramesToWait data[2] - -static void ScriptCmd_waitplaysewithpan(void) -{ - u16 songId; - s8 panningArg, panning; - u8 framesToWait; - u8 taskId; - - sBattleAnimScriptPtr++; - songId = T1_READ_16(sBattleAnimScriptPtr); - panningArg = T1_READ_8(sBattleAnimScriptPtr + 2); - framesToWait = T1_READ_8(sBattleAnimScriptPtr + 3); - panning = BattleAnimAdjustPanning(panningArg); - - taskId = CreateTask(Task_WaitAndPlaySE, 1); - gTasks[taskId].tSongId = songId; - gTasks[taskId].tPanning = panning; - gTasks[taskId].tFramesToWait = framesToWait; - - gAnimSoundTaskCount++; - sBattleAnimScriptPtr += 4; -} - -static void Task_WaitAndPlaySE(u8 taskId) -{ - if (gTasks[taskId].tFramesToWait-- <= 0) - { - PlaySE12WithPanning(gTasks[taskId].tSongId, gTasks[taskId].tPanning); - DestroyTask(taskId); - gAnimSoundTaskCount--; - } -} - -#undef tSongId -#undef tPanning -#undef tFramesToWait - -// Creates a sound task. -// arg0: sound task function -// arg1: s16[] gBattleAnimArgs -static void ScriptCmd_createsoundtask(void) -{ - TaskFunc func; - u8 numArgs, taskId; - s32 i; - - sBattleAnimScriptPtr++; - func = (TaskFunc)T2_READ_32(sBattleAnimScriptPtr); - sBattleAnimScriptPtr += 4; - numArgs = T1_READ_8(sBattleAnimScriptPtr); - sBattleAnimScriptPtr++; - for (i = 0; i < numArgs; i++) - { - gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr); - sBattleAnimScriptPtr += 2; - } - taskId = CreateTask(func, 1); - func(taskId); - gAnimSoundTaskCount++; -} - -// Wait for sound effect to end. -static void ScriptCmd_waitsound(void) -{ - if (gAnimSoundTaskCount != 0) - { - gSoundAnimFramesToWait = 0; - gAnimFramesToWait = 1; - } - else if (IsSEPlaying()) - { - if (++gSoundAnimFramesToWait > 90) - { - m4aMPlayStop(&gMPlay_SE1); - m4aMPlayStop(&gMPlay_SE2); - gSoundAnimFramesToWait = 0; - } - else - { - gAnimFramesToWait = 1; - } - } - else - { - gSoundAnimFramesToWait = 0; - sBattleAnimScriptPtr++; - gAnimFramesToWait = 0; - } -} - -// Jump to animation based on gBattleAnimArgs[index] value. -// arg0: gBattleAnimArgs[] argument index -// arg1: value -// arg2: animation script -static void ScriptCmd_jumpargeq(void) -{ - u8 argId; - s16 valueToCheck; - - sBattleAnimScriptPtr++; - argId = T1_READ_8(sBattleAnimScriptPtr); - valueToCheck = T1_READ_16(sBattleAnimScriptPtr + 1); - - if (valueToCheck == gBattleAnimArgs[argId]) - sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr + 3); - else - sBattleAnimScriptPtr += 7; -} - -// If using move in contest, go to specific animation script. -// arg0: animation script -static void ScriptCmd_jumpifcontest(void) -{ - sBattleAnimScriptPtr++; - if (IsContest()) - sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr); - else - sBattleAnimScriptPtr += 4; -} - -static void ScriptCmd_monbgprio_28(void) -{ - u8 wantedBank; - u8 bank; - u8 bankIdentity; - - wantedBank = T1_READ_8(sBattleAnimScriptPtr + 1); - sBattleAnimScriptPtr += 2; - - if (wantedBank != 0) - bank = gBattleAnimTarget; - else - bank = gBattleAnimAttacker; - - bankIdentity = GetBattlerPosition(bank); - if (!IsContest() && (bankIdentity == 0 || bankIdentity == 3)) - { - REG_BG1CNT_BITFIELD.priority = 1; - REG_BG2CNT_BITFIELD.priority = 2; - } -} - -static void ScriptCmd_monbgprio_29(void) -{ - sBattleAnimScriptPtr++; - if (!IsContest()) - { - REG_BG1CNT_BITFIELD.priority = 1; - REG_BG2CNT_BITFIELD.priority = 2; - } -} - -static void ScriptCmd_monbgprio_2A(void) -{ - u8 wantedBank; - u8 bankIdentity; - u8 bank; - - wantedBank = T1_READ_8(sBattleAnimScriptPtr + 1); - sBattleAnimScriptPtr += 2; - if (GetBattlerSide(gBattleAnimAttacker) != GetBattlerSide(gBattleAnimTarget)) - { - if (wantedBank != 0) - bank = gBattleAnimTarget; - else - bank = gBattleAnimAttacker; - bankIdentity = GetBattlerPosition(bank); - if (!IsContest() && (bankIdentity == 0 || bankIdentity == 3)) - { - REG_BG1CNT_BITFIELD.priority = 1; - REG_BG2CNT_BITFIELD.priority = 2; - } - } -} - -// Sets sprite to be invisible. -// arg0: battler sprite ID -static void ScriptCmd_invisible(void) -{ - u8 spriteId; - - spriteId = GetAnimBattlerSpriteId(T1_READ_8(sBattleAnimScriptPtr + 1)); - if (spriteId != 0xFF) - gSprites[spriteId].invisible = TRUE; - - sBattleAnimScriptPtr += 2; -} - -// Sets aprite to be visible. -// arg0: battler sprite ID -static void ScriptCmd_visible(void) -{ - u8 spriteId; - - spriteId = GetAnimBattlerSpriteId(T1_READ_8(sBattleAnimScriptPtr + 1)); - if (spriteId != 0xFF) - gSprites[spriteId].invisible = FALSE; - - sBattleAnimScriptPtr += 2; -} - -static void ScriptCmd_doublebattle_2D(void) -{ - u8 wantedBank; - u8 r4; - u8 spriteId; - - wantedBank = T1_READ_8(sBattleAnimScriptPtr + 1); - sBattleAnimScriptPtr += 2; - if (!IsContest() && IsDoubleBattle() - && GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget)) - { - if (wantedBank == 0) - { - r4 = GetBattlerPosition_permutated(gBattleAnimAttacker); - spriteId = GetAnimBattlerSpriteId(0); - } - else - { - r4 = GetBattlerPosition_permutated(gBattleAnimTarget); - spriteId = GetAnimBattlerSpriteId(1); - } - if (spriteId != 0xFF) - { - gSprites[spriteId].invisible = FALSE; - if (r4 == 2) - gSprites[spriteId].oam.priority = 3; - if (r4 == 1) - sub_8076464(0); - else - sub_8076464(1); - } - } -} - -static void ScriptCmd_doublebattle_2E(void) -{ - u8 wantedBank; - u8 r4; - u8 spriteId; - - wantedBank = T1_READ_8(sBattleAnimScriptPtr + 1); - sBattleAnimScriptPtr += 2; - if (!IsContest() && IsDoubleBattle() - && GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget)) - { - if (wantedBank == 0) - { - r4 = GetBattlerPosition_permutated(gBattleAnimAttacker); - spriteId = GetAnimBattlerSpriteId(0); - } - else - { - r4 = GetBattlerPosition_permutated(gBattleAnimTarget); - spriteId = GetAnimBattlerSpriteId(1); - } - if (spriteId != 0xFF && r4 == 2) - { - gSprites[spriteId].oam.priority = 2; - } - } -} - -// Cease playing sounds. -static void ScriptCmd_stopsound(void) -{ - m4aMPlayStop(&gMPlay_SE1); - m4aMPlayStop(&gMPlay_SE2); - sBattleAnimScriptPtr++; -} diff --git a/src/battle/battle_anim_807B69C.c b/src/battle/battle_anim_807B69C.c deleted file mode 100644 index 90e6ce38c..000000000 --- a/src/battle/battle_anim_807B69C.c +++ /dev/null @@ -1,354 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_anim.h" -#include "blend_palette.h" -#include "decompress.h" -#include "palette.h" -#include "sprite.h" -#include "task.h" -#include "trig.h" -#include "ewram.h" - -extern u8 gBattleAnimAttacker; -extern u8 gBattleAnimTarget; -extern bool8 gAnimScriptActive; -extern void (*gAnimScriptCallback)(void); -extern s16 gBattleAnimArgs[]; -extern u8 gBattleAnimTarget; -extern u8 gBankSpriteIds[]; -extern const struct CompressedSpriteSheet gBattleAnimPicTable[]; -extern const struct CompressedSpritePalette gBattleAnimPaletteTable[]; -extern const u8 *const gBattleAnims_StatusConditions[]; -extern const struct OamData gOamData_837E05C; -extern const struct OamData gOamData_837DF24; - -extern u8 GetBattlerSpriteCoord(u8, u8); -extern void sub_80E32E0(u8); - - -static const struct Subsprite gSubspriteTable_83931B8[] = -{ - {.x = -16, .y = -16, .shape = ST_OAM_SQUARE, .size = 3, .tileOffset = 0, .priority = 2}, - {.x = -16, .y = 48, .shape = ST_OAM_H_RECTANGLE, .size = 3, .tileOffset = 64, .priority = 2}, - {.x = 48, .y = -16, .shape = ST_OAM_V_RECTANGLE, .size = 3, .tileOffset = 96, .priority = 2}, - {.x = 48, .y = 48, .shape = ST_OAM_SQUARE, .size = 2, .tileOffset = 128, .priority = 2}, -}; - -static const struct SubspriteTable gSubspriteTables_83931D8[] = -{ - {ARRAY_COUNT(gSubspriteTable_83931B8), gSubspriteTable_83931B8}, -}; - -static const struct SpriteTemplate gSpriteTemplate_83931E0 = -{ - .tileTag = ANIM_TAG_ICE_CUBE, - .paletteTag = ANIM_TAG_ICE_CUBE, - .oam = &gOamData_837E05C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, -}; - -static void sub_807B870(struct Sprite *); -static const struct SpriteTemplate gSpriteTemplate_83931F8 = -{ - .tileTag = ANIM_TAG_CIRCLE_IMPACT, - .paletteTag = ANIM_TAG_CIRCLE_IMPACT, - .oam = &gOamData_837DF24, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_807B870, -}; - -static void sub_807B7E0(u8); -static void sub_807B8A4(struct Sprite *); -static void sub_807B9D8(u8); -static void sub_807BA24(u8); -static void sub_807BAD4(u8); -static void sub_807BB24(u8); -static void sub_807BDAC(u8); - -u8 unref_sub_807B69C(u8 a, u8 b) -{ - u8 spriteId1 = gBankSpriteIds[a]; - u8 taskId = CreateTask(sub_807B7E0, 10); - u8 spriteId2; - u8 i; - - LoadCompressedObjectPic(&gBattleAnimPicTable[136]); - LoadCompressedObjectPalette(&gBattleAnimPaletteTable[136]); - gTasks[taskId].data[0] = a; - if (b != 0) - { - gTasks[taskId].data[1] = 0x1F; - for (i = 0; i < 10; i++) - { - spriteId2 = CreateSprite(&gSpriteTemplate_83931F8, gSprites[spriteId1].pos1.x, gSprites[spriteId1].pos1.y + 32, 0); - gSprites[spriteId2].data[0] = i * 51; - gSprites[spriteId2].data[1] = -256; - gSprites[spriteId2].invisible = TRUE; - if (i > 4) - gSprites[spriteId2].data[6] = 21; - } - } - else - { - gTasks[taskId].data[1] = 0x7C00; - for (i = 0; i < 10; i++) - { - spriteId2 = CreateSprite(&gSpriteTemplate_83931F8, gSprites[spriteId1].pos1.x, gSprites[spriteId1].pos1.y - 32, 0); - gSprites[spriteId2].data[0] = i * 51; - gSprites[spriteId2].data[1] = 256; - gSprites[spriteId2].invisible = TRUE; - if (i > 4) - gSprites[spriteId2].data[6] = 21; - } - } - gSprites[spriteId2].data[7] = 1; - return taskId; -} - -static void sub_807B7E0(u8 taskId) -{ - if (gTasks[taskId].data[2] == 2) - { - gTasks[taskId].data[2] = 0; - BlendPalette(0x100 + gTasks[taskId].data[0] * 16, 16, gTasks[taskId].data[4], gTasks[taskId].data[1]); - if (gTasks[taskId].data[5] == 0) - { - gTasks[taskId].data[4]++; - if (gTasks[taskId].data[4] > 8) - gTasks[taskId].data[5] ^= 1; - } - else - { - u16 var = gTasks[taskId].data[4]; - - gTasks[taskId].data[4]--; - if (gTasks[taskId].data[4] < 0) - { - gTasks[taskId].data[4] = var; - gTasks[taskId].data[5] ^= 1; - gTasks[taskId].data[3]++; - if (gTasks[taskId].data[3] == 2) - DestroyTask(taskId); - } - } - } - else - { - gTasks[taskId].data[2]++; - } -} - -static void sub_807B870(struct Sprite *sprite) -{ - if (sprite->data[6] == 0) - { - sprite->invisible = FALSE; - sprite->callback = sub_807B8A4; - sub_807B8A4(sprite); - } - else - { - sprite->data[6] --; - } -} - -static void sub_807B8A4(struct Sprite *sprite) -{ - sprite->pos2.x = Cos(sprite->data[0], 32); - sprite->pos2.y = Sin(sprite->data[0], 8); - if (sprite->data[0] < 128) - sprite->subpriority = 29; - else - sprite->subpriority = 31; - sprite->data[0] = (sprite->data[0] + 8) & 0xFF; - sprite->data[5] += sprite->data[1]; - sprite->pos2.y += sprite->data[5] >> 8; - sprite->data[2]++; - if (sprite->data[2] == 52) - { - if (sprite->data[7] != 0) - DestroySpriteAndFreeResources(sprite); - else - DestroySprite(sprite); - } -} - -void sub_807B920(u8 taskId) -{ - s16 x = GetBattlerSpriteCoord(gBattleAnimTarget, 2) - 32; - s16 y = GetBattlerSpriteCoord(gBattleAnimTarget, 3) - 36; - u8 spriteId; - - if (IsContest()) - x -= 6; - REG_BLDCNT = 0x3F40; - REG_BLDALPHA = 0x1000; - spriteId = CreateSprite(&gSpriteTemplate_83931E0, x, y, 4); - SetSubspriteTables(&gSprites[spriteId], gSubspriteTables_83931D8); - gTasks[taskId].data[15] = spriteId; - gTasks[taskId].func = sub_807B9D8; -} - -static void sub_807B9D8(u8 taskId) -{ - gTasks[taskId].data[1]++; - if (gTasks[taskId].data[1] == 10) - { - gTasks[taskId].func = sub_807BA24; - gTasks[taskId].data[1] = 0; - } - else - { - u8 var = gTasks[taskId].data[1]; - - REG_BLDALPHA = ((16 - var) << 8) | var; - } -} - -static void sub_807BA24(u8 taskId) -{ - u8 r2 = IndexOfSpritePaletteTag(0x271A); - - if (gTasks[taskId].data[1]++ > 13) - { - gTasks[taskId].data[2]++; - if (gTasks[taskId].data[2] == 3) - { - u16 temp; - - temp = gPlttBufferFaded[0x100 + r2 * 16 + 13]; - gPlttBufferFaded[0x100 + r2 * 16 + 13] = gPlttBufferFaded[0x100 + r2 * 16 + 14]; - gPlttBufferFaded[0x100 + r2 * 16 + 14] = gPlttBufferFaded[0x100 + r2 * 16 + 15]; - gPlttBufferFaded[0x100 + r2 * 16 + 15] = temp; - - gTasks[taskId].data[2] = 0; - gTasks[taskId].data[3]++; - if (gTasks[taskId].data[3] == 3) - { - gTasks[taskId].data[3] = 0; - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[4]++; - if (gTasks[taskId].data[4] == 2) - { - gTasks[taskId].data[1] = 9; - gTasks[taskId].func = sub_807BAD4; - } - } - } - } -} - -static void sub_807BAD4(u8 taskId) -{ - gTasks[taskId].data[1]--; - if (gTasks[taskId].data[1] == -1) - { - gTasks[taskId].func = sub_807BB24; - gTasks[taskId].data[1] = 0; - } - else - { - u8 var = gTasks[taskId].data[1]; - - REG_BLDALPHA = ((16 - var) << 8) | var; - } -} - -static void sub_807BB24(u8 taskId) -{ - gTasks[taskId].data[1]++; - if (gTasks[taskId].data[1] == 37) - { - u8 spriteId = gTasks[taskId].data[15]; - - FreeSpriteOamMatrix(&gSprites[spriteId]); - DestroySprite(&gSprites[spriteId]); - } - else if (gTasks[taskId].data[1] == 39) - { - REG_BLDCNT = 0; - REG_BLDALPHA = 0; - DestroyAnimVisualTask(taskId); - } -} - -void sub_807BB88(u8 taskId) -{ - s16 r5; - s16 r2; - s16 r3 = 0; - - switch (ewram17840.unk0) - { - case 15: r5 = 0; r2 = 0; break; - case 16: r5 = 0; r2 = 1; break; - case 17: r5 = 0; r2 = 3; break; - case 18: r5 = 0; r2 = 5; break; - case 19: r5 = 0; r2 = 6; break; - case 20: r5 = 0; r2 = 2; break; - case 21: r5 = 0; r2 = 4; break; - case 22: r5 = 1; r2 = 0; break; - case 23: r5 = 1; r2 = 1; break; - case 24: r5 = 1; r2 = 3; break; - case 25: r5 = 1; r2 = 5; break; - case 26: r5 = 1; r2 = 6; break; - case 27: r5 = 1; r2 = 2; break; - case 28: r5 = 1; r2 = 4; break; - case 39: r5 = 0; r2 = 0; r3 = 1; break; - case 40: r5 = 0; r2 = 1; r3 = 1; break; - case 41: r5 = 0; r2 = 3; r3 = 1; break; - case 42: r5 = 0; r2 = 5; r3 = 1; break; - case 43: r5 = 0; r2 = 6; r3 = 1; break; - case 44: r5 = 0; r2 = 2; r3 = 1; break; - case 45: r5 = 0; r2 = 4; r3 = 1; break; - case 46: r5 = 1; r2 = 0; r3 = 1; break; - case 47: r5 = 1; r2 = 1; r3 = 1; break; - case 48: r5 = 1; r2 = 3; r3 = 1; break; - case 49: r5 = 1; r2 = 5; r3 = 1; break; - case 50: r5 = 1; r2 = 6; r3 = 1; break; - case 51: r5 = 1; r2 = 2; r3 = 1; break; - case 52: r5 = 1; r2 = 4; r3 = 1; break; - case 55: r5 = 0; r2 = 0xFF; r3 = 0; break; - case 56: r5 = 0; r2 = 0xFF; r3 = 1; break; - case 57: r5 = 1; r2 = 0xFF; r3 = 0; break; - case 58: r5 = 1; r2 = 0xFF; r3 = 1; break; - - default: - DestroyAnimVisualTask(taskId); - return; - } - - gBattleAnimArgs[0] = r5; - gBattleAnimArgs[1] = r2; - gBattleAnimArgs[2] = 0; - gBattleAnimArgs[3] = 0; - gBattleAnimArgs[4] = r3; - gTasks[taskId].func = sub_80E32E0; - sub_80E32E0(taskId); -} - -void move_anim_start_t2(u8 a, u8 b) -{ - u8 taskId; - - gBattleAnimAttacker = a; - gBattleAnimTarget = a; - LaunchBattleAnimation(gBattleAnims_StatusConditions, b, 0); - taskId = CreateTask(sub_807BDAC, 10); - gTasks[taskId].data[0] = a; -} - -static void sub_807BDAC(u8 taskId) -{ - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - ewram17810[gTasks[taskId].data[0]].unk0_4 = 0; - DestroyTask(taskId); - } -} diff --git a/src/battle/battle_anim_80A7E7C.c b/src/battle/battle_anim_80A7E7C.c deleted file mode 100644 index 5e713a3a7..000000000 --- a/src/battle/battle_anim_80A7E7C.c +++ /dev/null @@ -1,1072 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_anim.h" -#include "rom_8077ABC.h" -#include "sprite.h" -#include "task.h" -#include "trig.h" - -#define SPRITE gSprites[TASK.data[0]] - -extern s16 gBattleAnimArgs[8]; - -extern u8 gBankSpriteIds[]; -extern s32 gAnimMoveDmg; -extern u16 gAnimMovePower; -extern u8 gBattleAnimAttacker; -extern u8 gBattleAnimTarget; - -static void AnimTask_ShakeMonStep(u8 taskId); -static void AnimTask_ShakeMon2Step(u8 taskId); -static void AnimTask_ShakeMonInPlaceStep(u8 taskId); -static void AnimTask_ShakeAndSinkMonStep(u8 taskId); -static void sub_80A8488(u8 taskId); -static void DoHorizontalLunge(struct Sprite *sprite); -static void ReverseHorizontalLungeDirection(struct Sprite *sprite); -static void DoVerticalDip(struct Sprite *sprite); -static void ReverseVerticalDipDirection(struct Sprite* sprite); -static void SlideMonToOriginalPos(struct Sprite *sprite); -static void SlideMonToOriginalPosStep(struct Sprite *sprite); -static void SlideMonToOffset(struct Sprite *sprite); -static void sub_80A8818(struct Sprite *sprite); -static void sub_80A88F0(struct Sprite *sprite); -static void AnimTask_WindUpLungePart1(u8 taskId); -static void AnimTask_WindUpLungePart2(u8 taskId); -static void AnimTask_SwayMonStep(u8 taskId); -static void AnimTask_ScaleMonAndRestoreStep(u8 taskId); -static void sub_80A8FD8(u8 taskId); -static void sub_80A913C(u8 taskId); - -const struct SpriteTemplate gHorizontalLungeSpriteTemplate = -{ - .tileTag = 0, - .paletteTag = 0, - .oam = &gDummyOamData, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = DoHorizontalLunge, -}; - -const struct SpriteTemplate gVerticalDipSpriteTemplate = -{ - .tileTag = 0, - .paletteTag = 0, - .oam = &gDummyOamData, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = DoVerticalDip, -}; - -const struct SpriteTemplate gSlideMonToOriginalPosSpriteTemplate = -{ - .tileTag = 0, - .paletteTag = 0, - .oam = &gDummyOamData, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SlideMonToOriginalPos, -}; - -const struct SpriteTemplate gSlideMonToOffsetSpriteTemplate = -{ - .tileTag = 0, - .paletteTag = 0, - .oam = &gDummyOamData, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SlideMonToOffset, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_83C2010 = -{ - .tileTag = 0, - .paletteTag = 0, - .oam = &gDummyOamData, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_80A8818, -}; - -// Task to facilitate simple shaking of a pokemon's picture in battle. -// The shaking alternates between the original position and the target position. -// arg 0: anim battler -// arg 1: x pixel offset -// arg 2: y pixel offset -// arg 3: num times to shake -// arg 4: frame delay -void AnimTask_ShakeMon(u8 taskId) -{ - u8 spriteId; - spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - if (spriteId == 0xff) - { - DestroyAnimVisualTask(taskId); - return; - } - gSprites[spriteId].pos2.x = gBattleAnimArgs[1]; - gSprites[spriteId].pos2.y = gBattleAnimArgs[2]; - TASK.data[0] = spriteId; - TASK.data[1] = gBattleAnimArgs[3]; - TASK.data[2] = gBattleAnimArgs[4]; - TASK.data[3] = gBattleAnimArgs[4]; - TASK.data[4] = gBattleAnimArgs[1]; - TASK.data[5] = gBattleAnimArgs[2]; - TASK.func = AnimTask_ShakeMonStep; - AnimTask_ShakeMonStep(taskId); -} - -static void AnimTask_ShakeMonStep(u8 taskId) -{ - if (TASK.data[3] == 0) - { - if (SPRITE.pos2.x == 0) - { - SPRITE.pos2.x = TASK.data[4]; - } - else - { - SPRITE.pos2.x = 0; - } - if (SPRITE.pos2.y == 0) - { - SPRITE.pos2.y = TASK.data[5]; - } - else - { - SPRITE.pos2.y = 0; - } - TASK.data[3] = TASK.data[2]; - if (--TASK.data[1] == 0) - { - SPRITE.pos2.x = 0; - SPRITE.pos2.y = 0; - DestroyAnimVisualTask(taskId); - return; - } - } - else - { - TASK.data[3]--; - } -} - -// Task to facilitate simple shaking of a pokemon's picture in battle. -// The shaking alternates between the positive and negative versions of the specified pixel offsets. -// arg 0: anim battler -// arg 1: x pixel offset -// arg 2: y pixel offset -// arg 3: num times to shake -// arg 4: frame delay -void AnimTask_ShakeMon2(u8 taskId) -{ - u8 sprite; - bool8 destroy; - u8 side; - destroy = FALSE; - if (gBattleAnimArgs[0] < 4) - { - sprite = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - if (sprite == 0xff) - { - DestroyAnimVisualTask(taskId); - return; - } - } - else if (gBattleAnimArgs[0] != 8) - { - switch (gBattleAnimArgs[0]) - { - case 4: - side = GetBattlerAtPosition(0); - break; - case 5: - side = GetBattlerAtPosition(2); - break; - case 6: - side = GetBattlerAtPosition(1); - break; - case 7: - default: - side = GetBattlerAtPosition(3); - break; - } - - if (IsAnimBankSpriteVisible(side) == FALSE) - destroy = TRUE; - - sprite = gBankSpriteIds[side]; - } - else - { - sprite = gBankSpriteIds[gBattleAnimAttacker]; - } - - if (destroy) - { - DestroyAnimVisualTask(taskId); - return; - } - - gSprites[sprite].pos2.x = gBattleAnimArgs[1]; - gSprites[sprite].pos2.y = gBattleAnimArgs[2]; - TASK.data[0] = sprite; - TASK.data[1] = gBattleAnimArgs[3]; - TASK.data[2] = gBattleAnimArgs[4]; - TASK.data[3] = gBattleAnimArgs[4]; - TASK.data[4] = gBattleAnimArgs[1]; - TASK.data[5] = gBattleAnimArgs[2]; - TASK.func = AnimTask_ShakeMon2Step; - TASK.func(taskId); -} - -static void AnimTask_ShakeMon2Step(u8 taskId) -{ - if (TASK.data[3] == 0) - { - if (SPRITE.pos2.x == TASK.data[4]) - SPRITE.pos2.x = -TASK.data[4]; - else - SPRITE.pos2.x = TASK.data[4]; - - if (SPRITE.pos2.y == TASK.data[5]) - SPRITE.pos2.y = -TASK.data[5]; - else - SPRITE.pos2.y = TASK.data[5]; - - TASK.data[3] = TASK.data[2]; - if (--TASK.data[1] == 0) - { - SPRITE.pos2.x = 0; - SPRITE.pos2.y = 0; - DestroyAnimVisualTask(taskId); - return; - } - } - else - { - TASK.data[3]--; - } -} - -// Task to facilitate simple shaking of a pokemon's picture in battle. -// The shaking alternates between the positive and negative versions of the specified pixel offsets -// with respect to the current location of the mon's picture. -// arg 0: battler -// arg 1: x offset -// arg 2: y offset -// arg 3: num shakes -// arg 4: delay -void AnimTask_ShakeMonInPlace(u8 taskId) -{ - u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - if (spriteId == 0xff) - { - DestroyAnimVisualTask(taskId); - return; - } - - gSprites[spriteId].pos2.x += gBattleAnimArgs[1]; - gSprites[spriteId].pos2.y += gBattleAnimArgs[2]; - TASK.data[0] = spriteId; - TASK.data[1] = 0; - TASK.data[2] = gBattleAnimArgs[3]; - TASK.data[3] = 0; - TASK.data[4] = gBattleAnimArgs[4]; - TASK.data[5] = gBattleAnimArgs[1] * 2; - TASK.data[6] = gBattleAnimArgs[2] * 2; - TASK.func = AnimTask_ShakeMonInPlaceStep; - TASK.func(taskId); -} - -static void AnimTask_ShakeMonInPlaceStep(u8 taskId) -{ - if (TASK.data[3] == 0) - { - if (TASK.data[1] & 1) - { - SPRITE.pos2.x += TASK.data[5]; - SPRITE.pos2.y += TASK.data[6]; - } - else - { - SPRITE.pos2.x -= TASK.data[5]; - SPRITE.pos2.y -= TASK.data[6]; - } - TASK.data[3] = TASK.data[4]; - if (++TASK.data[1] >= TASK.data[2]) - { - if (TASK.data[1] & 1) - { - SPRITE.pos2.x += TASK.data[5] / 2; - SPRITE.pos2.y += TASK.data[6] / 2; - } - else - { - SPRITE.pos2.x -= TASK.data[5] / 2; - SPRITE.pos2.y -= TASK.data[6] / 2; - } - DestroyAnimVisualTask(taskId); - return; - } - } - else - { - TASK.data[3]--; - } -} - -// Shakes a mon bg horizontally and moves it downward linearly. -// arg 0: battler -// arg 1: x offset -// arg 2: frame delay between each movement -// arg 3: downward speed (subpixel) -// arg 4: duration -void AnimTask_ShakeAndSinkMon(u8 taskId) -{ - u8 sprite = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - gSprites[sprite].pos2.x = gBattleAnimArgs[1]; - TASK.data[0] = sprite; - TASK.data[1] = gBattleAnimArgs[1]; - TASK.data[2] = gBattleAnimArgs[2]; - TASK.data[3] = gBattleAnimArgs[3]; - TASK.data[4] = gBattleAnimArgs[4]; - TASK.func = AnimTask_ShakeAndSinkMonStep; - TASK.func(taskId); -} - -static void AnimTask_ShakeAndSinkMonStep(u8 taskId) -{ - s16 x; - u8 sprite; - sprite = TASK.data[0]; - x = TASK.data[1]; - if (TASK.data[2] == TASK.data[8]++) - { - TASK.data[8] = 0; - if (gSprites[sprite].pos2.x == x) - x = -x; - - gSprites[sprite].pos2.x += x; - } - - TASK.data[1] = x; - TASK.data[9] += TASK.data[3]; - gSprites[sprite].pos2.y = TASK.data[9] >> 8; - if (--TASK.data[4] == 0) - { - DestroyAnimVisualTask(taskId); - return; - } -} - -// Moves a mon bg picture along an elliptical path that begins -// and ends at the mon's origin location. -// arg 0: battler -// arg 1: ellipse width -// arg 2: ellipse height -// arg 3: num loops -// arg 4: speed (valid values are 0-5) -void AnimTask_TranslateMonElliptical(u8 taskId) -{ - u8 i; - u8 spriteId; - u8 wavePeriod; - - wavePeriod = 1; - spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - if (gBattleAnimArgs[4] > 5) - gBattleAnimArgs[4] = 5; - - for (i = 0; i < gBattleAnimArgs[4]; i++) - { - wavePeriod <<= 1; - } - - TASK.data[0] = spriteId; - TASK.data[1] = gBattleAnimArgs[1]; - TASK.data[2] = gBattleAnimArgs[2]; - TASK.data[3] = gBattleAnimArgs[3]; - TASK.data[4] = wavePeriod; - TASK.func = sub_80A8488; - TASK.func(taskId); -} - -static void sub_80A8488(u8 taskId) -{ - u8 spriteId = TASK.data[0]; - gSprites[spriteId].pos2.x = Sin(TASK.data[5], TASK.data[1]); - gSprites[spriteId].pos2.y = -Cos(TASK.data[5], TASK.data[2]); - gSprites[spriteId].pos2.y += TASK.data[2]; - TASK.data[5] += TASK.data[4]; - TASK.data[5] &= 0xff; - - if (TASK.data[5] == 0) - TASK.data[3]--; - - if (TASK.data[3] == 0) - { - gSprites[spriteId].pos2.x = 0; - gSprites[spriteId].pos2.y = 0; - DestroyAnimVisualTask(taskId); - return; - } -} - -// Moves a mon bg picture along an elliptical path that begins -// and ends at the mon's origin location. Reverses the direction -// of the path if it's not on the player's side of the battle. -// arg 0: battler -// arg 1: ellipse width -// arg 2: ellipse height -// arg 3: num loops -// arg 4: speed (valid values are 0-5) -void AnimTask_TranslateMonEllipticalRespectSide(u8 taskId) -{ - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - gBattleAnimArgs[1] = -gBattleAnimArgs[1]; - - AnimTask_TranslateMonElliptical(taskId); -} - -// Performs a simple horizontal lunge, where the mon moves -// horizontally, and then moves back in the opposite direction. -// arg 0: duration of single lunge direction -// arg 1: x pixel delta that is applied each frame -static void DoHorizontalLunge(struct Sprite *sprite) -{ - sprite->invisible = TRUE; - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - sprite->data[1] = -gBattleAnimArgs[1]; - else - sprite->data[1] = gBattleAnimArgs[1]; - - sprite->data[0] = gBattleAnimArgs[0]; - sprite->data[2] = 0; - sprite->data[3] = gBankSpriteIds[gBattleAnimAttacker]; - sprite->data[4] = gBattleAnimArgs[0]; - StoreSpriteCallbackInData(sprite, ReverseHorizontalLungeDirection); - sprite->callback = TranslateMonBGUntil; -} - -static void ReverseHorizontalLungeDirection(struct Sprite *sprite) -{ - sprite->data[0] = sprite->data[4]; - sprite->data[1] = -sprite->data[1]; - sprite->callback = TranslateMonBGUntil; - StoreSpriteCallbackInData(sprite, DestroyAnimSprite); -} - -// Performs a simple vertical dipping motion, where moves vertically, and then -// moves back in the opposite direction. -// arg 0: duration of single dip direction -// arg 1: y pixel delta that is applied each frame -// arg 2: battler -static void DoVerticalDip(struct Sprite *sprite) -{ - u8 spriteId; - sprite->invisible = TRUE; - spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]); - sprite->data[0] = gBattleAnimArgs[0]; - sprite->data[1] = 0; - sprite->data[2] = gBattleAnimArgs[1]; - sprite->data[3] = spriteId; - sprite->data[4] = gBattleAnimArgs[0]; - StoreSpriteCallbackInData(sprite, ReverseVerticalDipDirection); - sprite->callback = TranslateMonBGUntil; -} - -static void ReverseVerticalDipDirection(struct Sprite *sprite) -{ - sprite->data[0] = sprite->data[4]; - sprite->data[2] = -sprite->data[2]; - sprite->callback = TranslateMonBGUntil; - StoreSpriteCallbackInData(sprite, DestroyAnimSprite); -} - -// Linearly slides a mon's bg picture back to its original sprite position. -// The sprite parameter is a dummy sprite used for facilitating the movement with its callback. -// arg 0: 1 = target or 0 = attacker -// arg 1: direction (0 = horizontal and vertical, 1 = horizontal only, 2 = vertical only) -// arg 2: duration -static void SlideMonToOriginalPos(struct Sprite *sprite) -{ - int something; - int monSpriteId; - if (!gBattleAnimArgs[0]) - monSpriteId = gBankSpriteIds[gBattleAnimAttacker]; - else - monSpriteId = gBankSpriteIds[gBattleAnimTarget]; - - sprite->data[0] = gBattleAnimArgs[2]; - sprite->data[1] = gSprites[monSpriteId].pos1.x + gSprites[monSpriteId].pos2.x; - sprite->data[2] = gSprites[monSpriteId].pos1.x; - sprite->data[3] = gSprites[monSpriteId].pos1.y + gSprites[monSpriteId].pos2.y; - sprite->data[4] = gSprites[monSpriteId].pos1.y; - something = 0; - InitSpriteDataForLinearTranslation(sprite); - sprite->data[3] = something; - sprite->data[4] = something; - sprite->data[5] = gSprites[monSpriteId].pos2.x; - sprite->data[6] = gSprites[monSpriteId].pos2.y; - sprite->invisible = TRUE; - - if (gBattleAnimArgs[1] == 1) - sprite->data[2] = something; - else if (gBattleAnimArgs[1] == 2) - sprite->data[1] = something; - - sprite->data[7] = gBattleAnimArgs[1]; - sprite->data[7] |= monSpriteId << 8; - sprite->callback = SlideMonToOriginalPosStep; -} - -static void SlideMonToOriginalPosStep(struct Sprite *sprite) -{ - s8 monSpriteId; - u8 lo; - struct Sprite *monSprite; - - lo = sprite->data[7] & 0xff; - monSpriteId = sprite->data[7] >> 8; - monSprite = &gSprites[monSpriteId]; - if (sprite->data[0] == 0) - { - if (lo < 2) - monSprite->pos2.x = 0; - - if (lo == 2 || lo == 0) - monSprite->pos2.y = 0; - - DestroyAnimSprite(sprite); - } - else - { - sprite->data[0]--; - sprite->data[3] += sprite->data[1]; - sprite->data[4] += sprite->data[2]; - monSprite->pos2.x = (s8)(sprite->data[3] >> 8) + sprite->data[5]; - monSprite->pos2.y = (s8)(sprite->data[4] >> 8) + sprite->data[6]; - } -} - -// Linearly translates a mon to a target offset. The horizontal offset -// is mirrored for the opponent's pokemon, and the vertical offset -// is only mirrored if arg 3 is set to 1. -// arg 0: 0 = attacker, 1 = target -// arg 1: target x pixel offset -// arg 2: target y pixel offset -// arg 3: mirror vertical translation for opposite battle side -// arg 4: duration -static void SlideMonToOffset(struct Sprite *sprite) -{ - u8 battler; - u8 monSpriteId; - if (!gBattleAnimArgs[0]) - battler = gBattleAnimAttacker; - else - battler = gBattleAnimTarget; - - monSpriteId = gBankSpriteIds[battler]; - if (GetBattlerSide(battler) != B_SIDE_PLAYER) - { - gBattleAnimArgs[1] = -gBattleAnimArgs[1]; - if (gBattleAnimArgs[3] == 1) - { - gBattleAnimArgs[2] = -gBattleAnimArgs[2]; - } - } - - sprite->data[0] = gBattleAnimArgs[4]; - sprite->data[1] = gSprites[monSpriteId].pos1.x; - sprite->data[2] = gSprites[monSpriteId].pos1.x + gBattleAnimArgs[1]; - sprite->data[3] = gSprites[monSpriteId].pos1.y; - sprite->data[4] = gSprites[monSpriteId].pos1.y + gBattleAnimArgs[2]; - InitSpriteDataForLinearTranslation(sprite); - sprite->data[3] = 0; - sprite->data[4] = 0; - sprite->data[5] = monSpriteId; - sprite->invisible = TRUE; - StoreSpriteCallbackInData(sprite, DestroyAnimSprite); - sprite->callback = TranslateMonBGSubPixelUntil; -} - -static void sub_80A8818(struct Sprite *sprite) -{ - u8 spriteId; - u8 v1; - sprite->invisible = TRUE; - if (!gBattleAnimArgs[0]) - { - v1 = gBattleAnimAttacker; - } - else - { - v1 = gBattleAnimTarget; - } - spriteId = gBankSpriteIds[v1]; - if (GetBattlerSide(v1)) - { - gBattleAnimArgs[1] = -gBattleAnimArgs[1]; - if (gBattleAnimArgs[3] == 1) - { - gBattleAnimArgs[2] = -gBattleAnimArgs[2]; - } - } - sprite->data[0] = gBattleAnimArgs[4]; - sprite->data[1] = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x; - sprite->data[2] = sprite->data[1] + gBattleAnimArgs[1]; - sprite->data[3] = gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y; - sprite->data[4] = sprite->data[3] + gBattleAnimArgs[2]; - InitSpriteDataForLinearTranslation(sprite); - sprite->data[3] = gSprites[spriteId].pos2.x << 8; - sprite->data[4] = gSprites[spriteId].pos2.y << 8; - sprite->data[5] = spriteId; - sprite->data[6] = gBattleAnimArgs[5]; - if (!gBattleAnimArgs[5]) - { - StoreSpriteCallbackInData(sprite, DestroyAnimSprite); - } - else - { - StoreSpriteCallbackInData(sprite, sub_80A88F0); - } - sprite->callback = TranslateMonBGSubPixelUntil; -} - - -static void sub_80A88F0(struct Sprite *sprite) -{ - gSprites[sprite->data[5]].pos2.x = 0; - gSprites[sprite->data[5]].pos2.y = 0; - DestroyAnimSprite(sprite); -} - -// Task to facilitate a two-part translation animation, in which the sprite -// is first translated in an arc to one position. Then, it "lunges" to a target -// x offset. Used in TAKE_DOWN, for example. -// arg 0: anim bank -// arg 1: horizontal speed (subpixel) -// arg 2: wave amplitude -// arg 3: first duration -// arg 4: delay before starting lunge -// arg 5: target x offset for lunge -// arg 6: lunge duration -void AnimTask_WindUpLunge(u8 taskId) -{ - s16 wavePeriod = 0x8000 / gBattleAnimArgs[3]; - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - { - gBattleAnimArgs[1] = -gBattleAnimArgs[1]; - gBattleAnimArgs[5] = -gBattleAnimArgs[5]; - } - TASK.data[0] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - TASK.data[1] = (gBattleAnimArgs[1] << 8) / gBattleAnimArgs[3]; - TASK.data[2] = gBattleAnimArgs[2]; - TASK.data[3] = gBattleAnimArgs[3]; - TASK.data[4] = gBattleAnimArgs[4]; - TASK.data[5] = (gBattleAnimArgs[5] << 8) / gBattleAnimArgs[6]; - TASK.data[6] = gBattleAnimArgs[6]; - TASK.data[7] = wavePeriod; - TASK.func = AnimTask_WindUpLungePart1; -} - -static void AnimTask_WindUpLungePart1(u8 taskId) -{ - u8 spriteId; - spriteId = TASK.data[0]; - TASK.data[11] += TASK.data[1]; - gSprites[spriteId].pos2.x = TASK.data[11] >> 8; - gSprites[spriteId].pos2.y = Sin((u8)(TASK.data[10] >> 8), TASK.data[2]); - TASK.data[10] += TASK.data[7]; - if (--TASK.data[3] == 0) - { - TASK.func = AnimTask_WindUpLungePart2; - } -} - -static void AnimTask_WindUpLungePart2(u8 taskId) -{ - u8 spriteId; - if (TASK.data[4] > 0) - { - TASK.data[4]--; - } - else - { - spriteId = TASK.data[0]; - TASK.data[12] += TASK.data[5]; - gSprites[spriteId].pos2.x = (TASK.data[12] >> 8) + (TASK.data[11] >> 8); - if (--TASK.data[6] == 0) - { - DestroyAnimVisualTask(taskId); - return; - } - } -} - -static void sub_80A8B3C(u8 taskId); - -void sub_80A8A80(u8 taskId) -{ - u8 spriteId; - switch (gBattleAnimArgs[0]) - { - case 0: - case 1: - spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - break; - case 2: - if (!IsAnimBankSpriteVisible(gBattleAnimAttacker ^ 2)) - { - DestroyAnimVisualTask(taskId); - return; - } - spriteId = gBankSpriteIds[gBattleAnimAttacker ^ 2]; - break; - case 3: - if (!IsAnimBankSpriteVisible(gBattleAnimTarget ^ 2)) - { - DestroyAnimVisualTask(taskId); - return; - } - spriteId = gBankSpriteIds[gBattleAnimTarget ^ 2]; - break; - default: - DestroyAnimVisualTask(taskId); - return; - } - TASK.data[0] = spriteId; - if (GetBattlerSide(gBattleAnimTarget)) - { - TASK.data[1] = gBattleAnimArgs[1]; - } - else - { - TASK.data[1] = -gBattleAnimArgs[1]; - } - TASK.func = sub_80A8B3C; -} - -static void sub_80A8B3C(u8 taskId) -{ - u8 spriteId = TASK.data[0]; - gSprites[spriteId].pos2.x += TASK.data[1]; - if (gSprites[spriteId].pos2.x + gSprites[spriteId].pos1.x + 0x20 > 0x130u) - { - DestroyAnimVisualTask(taskId); - return; - } -} - -// Task that facilitates translating the mon bg picture back and forth -// in a swaying motion (uses Sine wave). It can sway either horizontally -// or vertically, but not both. -// arg 0: direction (0 = horizontal, 1 = vertical) -// arg 1: wave amplitude -// arg 2: wave period -// arg 3: num sways -// arg 4: which mon (0 = attacker, 1`= target) -void AnimTask_SwayMon(u8 taskId) -{ - u8 spriteId; - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - gBattleAnimArgs[1] = -gBattleAnimArgs[1]; - - spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[4]); - TASK.data[0] = gBattleAnimArgs[0]; - TASK.data[1] = gBattleAnimArgs[1]; - TASK.data[2] = gBattleAnimArgs[2]; - TASK.data[3] = gBattleAnimArgs[3]; - TASK.data[4] = spriteId; - - if (gBattleAnimArgs[4] == 0) - TASK.data[5] = gBattleAnimAttacker; - else - TASK.data[5] = gBattleAnimTarget; - - TASK.data[12] = 1; - TASK.func = AnimTask_SwayMonStep; -} - -static void AnimTask_SwayMonStep(u8 taskId) -{ - s16 sineValue; - u8 spriteId; - int waveIndex; - u16 sineIndex; - - spriteId = TASK.data[4]; - sineIndex = TASK.data[10] + TASK.data[2]; - TASK.data[10] = sineIndex; - waveIndex = sineIndex >> 8; - sineValue = Sin(waveIndex, TASK.data[1]); - - if (TASK.data[0] == 0) - { - gSprites[spriteId].pos2.x = sineValue; - } - else - { - if (GetBattlerSide(TASK.data[5]) == B_SIDE_PLAYER) - { - gSprites[spriteId].pos2.y = (sineValue >= 0) ? sineValue : -sineValue; - } - else - { - gSprites[spriteId].pos2.y = (sineValue >= 0) ? -sineValue : sineValue; - } - } - - if (((waveIndex >= 0x80u) && (TASK.data[11] == 0) && (TASK.data[12] == 1)) - || ((waveIndex < 0x7fu) && (TASK.data[11] == 1) && (TASK.data[12] == 0))) - { - TASK.data[11] ^= 1; - TASK.data[12] ^= 1; - if (--TASK.data[3] == 0) - { - gSprites[spriteId].pos2.x = 0; - gSprites[spriteId].pos2.y = 0; - DestroyAnimVisualTask(taskId); - return; - } - } -} - -// Scales a mon's sprite, and then scales back to its original dimensions. -// arg 0: x scale delta -// arg 1: y scale delta -// arg 2: duration -// arg 3: anim bank -// arg 4: sprite object mode -void AnimTask_ScaleMonAndRestore(u8 taskId) -{ - u8 spriteId; - spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[3]); - PrepareBattlerSpriteForRotScale(spriteId, gBattleAnimArgs[4]); - TASK.data[0] = gBattleAnimArgs[0]; - TASK.data[1] = gBattleAnimArgs[1]; - TASK.data[2] = gBattleAnimArgs[2]; - TASK.data[3] = gBattleAnimArgs[2]; - TASK.data[4] = spriteId; - TASK.data[10] = 0x100; - TASK.data[11] = 0x100; - TASK.func = AnimTask_ScaleMonAndRestoreStep; -} - -static void AnimTask_ScaleMonAndRestoreStep(u8 taskId) -{ - u8 spriteId; - TASK.data[10] += TASK.data[0]; - TASK.data[11] += TASK.data[1]; - spriteId = TASK.data[4]; - obj_id_set_rotscale(spriteId, TASK.data[10], TASK.data[11], 0); - if (--TASK.data[2] == 0) - { - if (TASK.data[3] > 0) - { - TASK.data[0] = -TASK.data[0]; - TASK.data[1] = -TASK.data[1]; - TASK.data[2] = TASK.data[3]; - TASK.data[3] = 0; - } - else - { - sub_8078F40(spriteId); - DestroyAnimVisualTask(taskId); - return; - } - } -} - -void sub_80A8E04(u8 taskId) -{ - u8 spriteId; - spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]); - PrepareBattlerSpriteForRotScale(spriteId, 0); - TASK.data[1] = 0; - TASK.data[2] = gBattleAnimArgs[0]; - if (gBattleAnimArgs[3] != 1) - { - TASK.data[3] = 0; - } - else - { - TASK.data[3] = gBattleAnimArgs[0] * gBattleAnimArgs[1]; - } - TASK.data[4] = gBattleAnimArgs[1]; - TASK.data[5] = spriteId; - TASK.data[6] = gBattleAnimArgs[3]; - if (IsContest()) - { - TASK.data[7] = 1; - } - else - { - if (gBattleAnimArgs[2] == 0) - { - TASK.data[7] = !GetBattlerSide(gBattleAnimAttacker); - } - else - { - TASK.data[7] = !GetBattlerSide(gBattleAnimTarget); - } - } - if (TASK.data[7]) - { - if (!IsContest()) - { - TASK.data[3] *= -1; - TASK.data[4] *= -1; - } - } - TASK.func = sub_80A8FD8; -} - -void sub_80A8EFC(u8 taskId) -{ - u8 spriteId; - spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]); - PrepareBattlerSpriteForRotScale(spriteId, 0); - TASK.data[1] = 0; - TASK.data[2] = gBattleAnimArgs[0]; - if (gBattleAnimArgs[2] == 0) - { - if (GetBattlerSide(gBattleAnimAttacker)) - { - gBattleAnimArgs[1] = -gBattleAnimArgs[1]; - } - } - else - { - if (GetBattlerSide(gBattleAnimTarget)) - { - gBattleAnimArgs[1] = -gBattleAnimArgs[1]; - } - } - if (gBattleAnimArgs[3] != 1) - { - TASK.data[3] = 0; - } - else - { - TASK.data[3] = gBattleAnimArgs[0] * gBattleAnimArgs[1]; - } - TASK.data[4] = gBattleAnimArgs[1]; - TASK.data[5] = spriteId; - TASK.data[6] = gBattleAnimArgs[3]; - TASK.data[7] = 1; - TASK.data[3] *= -1; - TASK.data[4] *= -1; - TASK.func = sub_80A8FD8; -} - -static void sub_80A8FD8(u8 taskId) -{ - TASK.data[3] += TASK.data[4]; - obj_id_set_rotscale(TASK.data[5], 0x100, 0x100, TASK.data[3]); - if (TASK.data[7]) - { - sub_8078F9C(TASK.data[5]); - } - if (++TASK.data[1] >= TASK.data[2]) - { - switch (TASK.data[6]) - { - case 1: - sub_8078F40(TASK.data[5]); - case 0: - default: - DestroyAnimVisualTask(taskId); - return; - case 2: - TASK.data[1] = 0; - TASK.data[4] *= -1; - TASK.data[6] = 1; - break; - } - } -} - -void sub_80A9058(u8 taskId) -{ - if (!gBattleAnimArgs[0]) - { - TASK.data[15] = gAnimMovePower / 12; - if (TASK.data[15] < 1) - { - TASK.data[15] = 1; - } - if (TASK.data[15] > 16) - { - TASK.data[15] = 16; - } - } - else - { - TASK.data[15] = gAnimMoveDmg / 12; - if (TASK.data[15] < 1) - { - TASK.data[15] = 1; - } - if (TASK.data[15] > 16) - { - TASK.data[15] = 16; - } - } - TASK.data[14] = TASK.data[15] / 2; - TASK.data[13] = TASK.data[14] + (TASK.data[15] & 1); - TASK.data[12] = 0; - TASK.data[10] = gBattleAnimArgs[3]; - TASK.data[11] = gBattleAnimArgs[4]; - TASK.data[7] = GetAnimBattlerSpriteId(1); - TASK.data[8] = gSprites[TASK.data[7]].pos2.x; - TASK.data[9] = gSprites[TASK.data[7]].pos2.y; - TASK.data[0] = 0; - TASK.data[1] = gBattleAnimArgs[1]; - TASK.data[2] = gBattleAnimArgs[2]; - TASK.func = sub_80A913C; -} - -static void sub_80A913C(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - if (++task->data[0] > task->data[1]) - { - task->data[0] = 0; - task->data[12] = (task->data[12] + 1) & 1; - if (task->data[10]) - { - if (task->data[12]) - { - gSprites[task->data[7]].pos2.x = task->data[8] + task->data[13]; - } - else - { - gSprites[task->data[7]].pos2.x = task->data[8] - task->data[14]; - } - } - if (task->data[11]) - { - if (task->data[12]) - { - gSprites[task->data[7]].pos2.y = task->data[15]; - } - else - { - gSprites[task->data[7]].pos2.y = 0; - } - } - if (!--task->data[2]) - { - gSprites[task->data[7]].pos2.x = 0; - gSprites[task->data[7]].pos2.y = 0; - DestroyAnimVisualTask(taskId); - return; - } - } -} diff --git a/src/battle/battle_anim_80CA710.c b/src/battle/battle_anim_80CA710.c deleted file mode 100644 index 65ccd7c21..000000000 --- a/src/battle/battle_anim_80CA710.c +++ /dev/null @@ -1,18 +0,0 @@ - -// Includes -#include "global.h" - -// Static type declarations - -// Static RAM declarations - -IWRAM_DATA u32 filler_03000724; -IWRAM_DATA u16 gUnknown_03000728[4]; -IWRAM_DATA u16 gUnknown_03000730[6]; -IWRAM_DATA u32 filler_0300073c; - -// Static ROM declarations - -// .rodata - -// .text diff --git a/src/battle/battle_anim_812C144.c b/src/battle/battle_anim_812C144.c deleted file mode 100644 index 90e7d8e2c..000000000 --- a/src/battle/battle_anim_812C144.c +++ /dev/null @@ -1,6065 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_anim.h" -#include "blend_palette.h" -#include "contest.h" -#include "data2.h" -#include "decompress.h" -#include "ewram.h" -#include "palette.h" -#include "random.h" -#include "rom_8077ABC.h" -#include "scanline_effect.h" -#include "sound.h" -#include "trig.h" -#include "constants/songs.h" -#include "constants/species.h" - -extern s16 gBattleAnimArgs[]; -extern u8 gBattleAnimAttacker; -extern u8 gBattleAnimTarget; -extern u8 gAnimVisualTaskCount; -extern u8 gAnimFriendship; -extern s32 gAnimMoveDmg; -extern u16 gBattle_WIN0H; -extern u16 gBattle_WIN0V; -extern u16 gBattle_WIN1H; -extern u16 gBattle_WIN1V; -extern u16 gBattle_BG1_X; -extern u16 gBattle_BG1_Y; -extern u16 gBattle_BG2_X; -extern u16 gBattle_BG2_Y; -extern u16 gWeatherMoveAnim; - -extern const struct SpriteTemplate gBattleAnimSpriteTemplate_83D7220; -extern const union AffineAnimCmd *const gSpriteAffineAnimTable_81E7C18[]; -extern const union AffineAnimCmd *const gSpriteAffineAnimTable_81E7BEC[]; -extern const u32 gUnknown_08D2AA98[]; -extern const u32 gUnknown_08D2A9E0[]; -extern const u16 gUnknown_08D2AA80[]; -extern const u8 gUnknown_08D2E014[]; -extern const u8 gUnknown_08D2E170[]; -extern const u16 gUnknown_08D2E150[]; -extern u8 gBattleMonForms[]; -extern u8 gBankSpriteIds[]; -extern u16 gBattlerPartyIndexes[]; - -extern u8 sub_8046234(s16 x, s16 y, u8 a3); -extern void sub_80DA48C(struct Sprite *); -extern void sub_80E3C4C(u8 taskId, int unused, u16 arg2, u8 battler1, u8 arg4, u8 arg5, u8 arg6, u8 arg7, const u8 *arg8, const u8 *arg9, const u16 *palette); - -static void sub_812C184(struct Sprite *sprite); -static void sub_812C268(struct Sprite *sprite); -static void sub_812C2A4(struct Sprite *sprite); -static void sub_812C380(struct Sprite *sprite); -static void sub_812C40C(struct Sprite *sprite); -static void sub_812C450(struct Sprite *sprite); -static void sub_812C4FC(struct Sprite *sprite); -static void sub_812C588(u8 taskId); -static void sub_812C64C(u8 taskId); -static void sub_812C798(struct Sprite *sprite); -static void sub_812C7C8(struct Sprite *sprite); -static void sub_812CA04(struct Sprite *sprite); -static void sub_812CAD0(struct Sprite *sprite); -static void sub_812CBB4(struct Sprite *sprite); -static void sub_812CD64(struct Sprite *sprite); -static void sub_812CEF0(u8 taskId); -static void sub_812D06C(u8 taskId); -static void sub_812D254(struct Sprite *sprite); -static void sub_812D4EC(struct Sprite *sprite); -static void sub_812D5E8(struct Sprite *sprite); -static void sub_812DFEC(struct Sprite *sprite); -static void sub_812E09C(struct Sprite *sprite); -static void sub_812E0F8(struct Sprite *sprite); -static void sub_812E638(u8 taskId); -static void sub_812E7F0(struct Sprite *sprite); -static void sub_812E8B4(u8 taskId); -static void sub_812ED24(struct Sprite *sprite); -static void sub_812EE00(struct Sprite *sprite); -static void sub_812EEEC(struct Sprite *sprite); -static void AnimTask_RolePlaySilhouetteStep1(u8 taskId); -static void sub_812F290(u8 taskId); -static void sub_812F474(u8 taskId); -static void sub_812F76C(u8 taskId); -static void sub_812F8DC(struct Sprite *sprite); -static void sub_812FE20(u8 taskId); -static void sub_812FEB8(u8, bool8); -static void sub_813003C(u8 taskId); -static void sub_81301B4(struct Sprite *sprite); -static void sub_81302E4(u8 taskId); -static void sub_8130424(s16, s16, s16, s16, u8, u8, s16*, s16*); -static void sub_81306A4(u8 taskId); -static void sub_813085C(struct Sprite *sprite); -static void sub_8130970(u8 taskId); -static void sub_8130A94(struct Sprite *sprite); -static void sub_8130B38(struct Sprite *sprite); -static void sub_8130DBC(u8 taskId); -static void sub_8130FE0(struct Sprite *sprite); -static void sub_8131408(u8 taskId); -static void sub_81315C8(struct Sprite *sprite); -static void sub_8131810(u8 taskId); -static void sub_8131838(struct Sprite *sprite); -static void sub_812C144(struct Sprite *sprite); -static void sub_812C220(struct Sprite *sprite); -static void sub_812C2BC(struct Sprite *sprite); -static void sub_812C358(struct Sprite *sprite); -static void sub_812C720(struct Sprite *sprite); -static void sub_812C80C(struct Sprite *sprite); -static void sub_812C848(struct Sprite *sprite); -static void sub_812C908(struct Sprite *sprite); -static void sub_812C990(struct Sprite *sprite); -static void sub_812CAFC(struct Sprite *sprite); -static void sub_812CC28(struct Sprite *sprite); -static void sub_812CCE8(struct Sprite *sprite); -static void sub_812D294(struct Sprite *sprite); -static void sub_812D3AC(struct Sprite *sprite); -static void sub_812D4B4(struct Sprite *sprite); -static void sub_812D588(struct Sprite *sprite); -static void sub_812DEAC(struct Sprite *sprite); -static void sub_812D724(struct Sprite *sprite); -static void sub_812E4F0(struct Sprite *sprite); -static void sub_812E7A0(struct Sprite *sprite); -static void sub_812EA4C(struct Sprite *sprite); -static void sub_812EC78(struct Sprite *sprite); -static void sub_812ED84(struct Sprite *sprite); -static void sub_812EEA4(struct Sprite *sprite); -static void sub_812F88C(struct Sprite *sprite); -static void sub_812F948(struct Sprite *sprite); -static void sub_812FF94(struct Sprite *sprite); -static void sub_81300F4(struct Sprite *sprite); -static void sub_81304DC(struct Sprite *sprite); -static void sub_813051C(struct Sprite *sprite); -static void sub_81307B0(struct Sprite *sprite); -static void sub_8130A2C(struct Sprite *sprite); -static void sub_8130AEC(struct Sprite *sprite); -static void sub_8130F5C(struct Sprite *sprite); -static void sub_8131264(struct Sprite *sprite); -extern void sub_80D1FDC(struct Sprite *sprite);// kiss_fountain.c -static void sub_8131564(struct Sprite *sprite); -static void AnimTask_TeeterDanceMovementStep(u8); - -/*static*/ void sub_8131EB8(struct Sprite *sprite);// rest not yet decompiled -void AnimKnockOffStrike(struct Sprite *sprite); -void AnimRecycle(struct Sprite *sprite); -static void AnimRecycleStep(struct Sprite *sprite); -static void AnimTask_SlackOffSquishStep(u8 taskId); - -const union AnimCmd gSpriteAnim_8402164[] = -{ - ANIMCMD_FRAME(0 , 4), - ANIMCMD_FRAME(16, 4), - ANIMCMD_FRAME(32, 4), - ANIMCMD_FRAME(48, 4), - ANIMCMD_FRAME(64, 4), - ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_840217C[] = -{ - gSpriteAnim_8402164, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402180 = -{ - .tileTag = ANIM_TAG_SCRATCH, - .paletteTag = ANIM_TAG_SCRATCH, - .oam = &gOamData_837E054, - .anims = gSpriteAnimTable_840217C, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_80793C4, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402198 = -{ - .tileTag = ANIM_TAG_BLACK_SMOKE, - .paletteTag = ANIM_TAG_BLACK_SMOKE, - .oam = &gOamData_837DF54, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812C144, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84021B0 = -{ - .tileTag = ANIM_TAG_BLACK_BALL, - .paletteTag = ANIM_TAG_BLACK_BALL, - .oam = &gOamData_837DF24, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_80794A8, -}; - -const union AnimCmd gSpriteAnim_84021C8[] = -{ - ANIMCMD_FRAME(0, 40), - ANIMCMD_FRAME(16, 8), - ANIMCMD_FRAME(32, 40), - ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_84021D8[] = -{ - gSpriteAnim_84021C8, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84021DC = -{ - .tileTag = ANIM_TAG_OPENING_EYE, - .paletteTag = ANIM_TAG_OPENING_EYE, - .oam = &gOamData_837DF34, - .anims = gSpriteAnimTable_84021D8, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_80793C4, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84021F4 = -{ - .tileTag = ANIM_TAG_ROUND_WHITE_HALO, - .paletteTag = ANIM_TAG_ROUND_WHITE_HALO, - .oam = &gOamData_837E05C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812C220, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_840220C = -{ - .tileTag = ANIM_TAG_TEAL_ALERT, - .paletteTag = ANIM_TAG_TEAL_ALERT, - .oam = &gOamData_837DF94, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812C2BC, -}; - -const union AffineAnimCmd gSpriteAffineAnim_8402224[] = -{ - AFFINEANIMCMD_FRAME(0x180, 0x180, 0, 0), - AFFINEANIMCMD_FRAME(0xFFE0, 0x18, 0, 5), - AFFINEANIMCMD_FRAME(0x18, 0xFFE0, 0, 5), - AFFINEANIMCMD_JUMP(1), -}; - -const union AffineAnimCmd gSpriteAffineAnim_8402244[] = -{ - AFFINEANIMCMD_FRAME(0x30, 0x30, 0, 0), - AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 6), - AFFINEANIMCMD_END, -}; - -const union AffineAnimCmd *const gSpriteAffineAnimTable_840225C[] = -{ - gSpriteAffineAnim_8402224, - gSpriteAffineAnim_8402244, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402264 = -{ - .tileTag = ANIM_TAG_EYE, - .paletteTag = ANIM_TAG_EYE, - .oam = &gOamData_837E11C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_840225C, - .callback = sub_812C358, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_840227C = -{ - .tileTag = ANIM_TAG_SPIKES, - .paletteTag = ANIM_TAG_SPIKES, - .oam = &gOamData_837DF2C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812C720, -}; - -const union AnimCmd gSpriteAnim_8402294[] = -{ - ANIMCMD_FRAME(0, 3), - ANIMCMD_FRAME(16, 3), - ANIMCMD_FRAME(32, 3), - ANIMCMD_FRAME(48, 3), - ANIMCMD_FRAME(64, 3), - ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_84022AC[] = -{ - gSpriteAnim_8402294, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84022B0 = -{ - .tileTag = ANIM_TAG_LEER, - .paletteTag = ANIM_TAG_LEER, - .oam = &gOamData_837DF34, - .anims = gSpriteAnimTable_84022AC, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812C80C, -}; - -const union AnimCmd gSpriteAnim_84022C8[] = -{ - ANIMCMD_FRAME(0, 3), - ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_84022D0[] = -{ - gSpriteAnim_84022C8, -}; - -const union AffineAnimCmd gSpriteAffineAnim_84022D4[] = -{ - AFFINEANIMCMD_FRAME(0xFFF9, 0xFFF9, -3, 16), - AFFINEANIMCMD_FRAME(0x7, 0x7, 3, 16), - AFFINEANIMCMD_JUMP(0), -}; - -const union AffineAnimCmd *const gSpriteAffineAnimTable_84022EC[] = -{ - gSpriteAffineAnim_84022D4, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84022F0 = -{ - .tileTag = ANIM_TAG_LETTER_Z, - .paletteTag = ANIM_TAG_LETTER_Z, - .oam = &gOamData_837DF94, - .anims = gSpriteAnimTable_84022D0, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_84022EC, - .callback = sub_812C848, -}; - -const union AnimCmd gSpriteAnim_8402308[] = -{ - ANIMCMD_FRAME(0, 8), - ANIMCMD_FRAME(16, 16), - ANIMCMD_FRAME(32, 4), - ANIMCMD_FRAME(48, 4), - ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_840231C[] = -{ - gSpriteAnim_8402308, -}; - -const union AffineAnimCmd gSpriteAffineAnim_8402320[] = -{ - AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0), - AFFINEANIMCMD_FRAME(0xFFE0, 0xFFE0, 0, 8), - AFFINEANIMCMD_END, -}; - -const union AffineAnimCmd *const gSpriteAffineAnimTable_8402338[] = -{ - gSpriteAffineAnim_8402320, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_840233C = -{ - .tileTag = ANIM_TAG_FANG_ATTACK, - .paletteTag = ANIM_TAG_FANG_ATTACK, - .oam = &gOamData_837DFF4, - .anims = gSpriteAnimTable_840231C, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_8402338, - .callback = sub_812C908, -}; - -const union AffineAnimCmd gSpriteAffineAnim_8402354[] = -{ - AFFINEANIMCMD_FRAME(0x0, 0x180, 0, 0), - AFFINEANIMCMD_FRAME(0x10, 0x0, 0, 20), - AFFINEANIMCMD_END, -}; - -const union AffineAnimCmd gSpriteAffineAnim_840236C[] = -{ - AFFINEANIMCMD_FRAME(0x140, 0x180, 0, 0), - AFFINEANIMCMD_FRAME(0xFFF0, 0x0, 0, 19), - AFFINEANIMCMD_END, -}; - -const union AffineAnimCmd *const gSpriteAffineAnimTable_8402384[] = -{ - gSpriteAffineAnim_8402354, - gSpriteAffineAnim_840236C, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_840238C = -{ - .tileTag = ANIM_TAG_SPOTLIGHT, - .paletteTag = ANIM_TAG_SPOTLIGHT, - .oam = &gOamData_837DFFC, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_8402384, - .callback = sub_812C990, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84023A4 = -{ - .tileTag = ANIM_TAG_TAG_HAND, - .paletteTag = ANIM_TAG_TAG_HAND, - .oam = &gOamData_837DF34, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812CAFC, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84023BC = -{ - .tileTag = ANIM_TAG_TAG_HAND, - .paletteTag = ANIM_TAG_TAG_HAND, - .oam = &gOamData_837DF34, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812CC28, -}; - -const union AnimCmd gSpriteAnim_84023D4[] = -{ - ANIMCMD_FRAME(0, 2), - ANIMCMD_FRAME(8, 2), - ANIMCMD_FRAME(16, 2), - ANIMCMD_JUMP(0), -}; - -const union AnimCmd *const gSpriteAnimTable_84023E4[] = -{ - gSpriteAnim_84023D4, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84023E8 = -{ - .tileTag = ANIM_TAG_RAPID_SPIN, - .paletteTag = ANIM_TAG_RAPID_SPIN, - .oam = &gOamData_837DF54, - .anims = gSpriteAnimTable_84023E4, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812CCE8, -}; - -const union AffineAnimCmd gUnknown_08402400[] = -{ - AFFINEANIMCMD_FRAME(-12, 8, 0, 4), - AFFINEANIMCMD_FRAME(20, -20, 0, 4), - AFFINEANIMCMD_FRAME(-8, 12, 0, 4), - AFFINEANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_8402420[] = -{ - ANIMCMD_FRAME(0, 8), - ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_8402428[] = -{ - gSpriteAnim_8402420, -}; - -const union AffineAnimCmd gSpriteAffineAnim_840242C[] = -{ - AFFINEANIMCMD_FRAME(0x0, 0x0, 5, 40), - AFFINEANIMCMD_FRAME(0x0, 0x0, 10, 10), - AFFINEANIMCMD_FRAME(0x0, 0x0, 15, 10), - AFFINEANIMCMD_FRAME(0x0, 0x0, 20, 40), - AFFINEANIMCMD_JUMP(0), -}; - -const union AffineAnimCmd *const gSpriteAffineAnimTable_8402454[] = -{ - gSpriteAffineAnim_840242C, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402458 = -{ - .tileTag = ANIM_TAG_TRI_FORCE_TRIANGLE, - .paletteTag = ANIM_TAG_TRI_FORCE_TRIANGLE, - .oam = &gOamData_837DFFC, - .anims = gSpriteAnimTable_8402428, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_8402454, - .callback = sub_812D294, -}; - -const union AnimCmd gSpriteAnim_8402470[] = -{ - ANIMCMD_FRAME(0, 3), - ANIMCMD_FRAME(16, 3), - ANIMCMD_FRAME(32, 3), - ANIMCMD_FRAME(48, 3), - ANIMCMD_FRAME(32, 3, .hFlip = TRUE), - ANIMCMD_FRAME(16, 3, .hFlip = TRUE), - ANIMCMD_FRAME(0, 3, .hFlip = TRUE), - ANIMCMD_LOOP(1), - ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_8402494[] = -{ - gSpriteAnim_8402470, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402498 = -{ - .tileTag = ANIM_TAG_ECLIPSING_ORB, - .paletteTag = ANIM_TAG_ECLIPSING_ORB, - .oam = &gOamData_837DF34, - .anims = gSpriteAnimTable_8402494, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_80793C4, -}; - -const union AffineAnimCmd gUnknown_084024B0[] = -{ - AFFINEANIMCMD_FRAME(-12, 20, 0, 8), - AFFINEANIMCMD_FRAME(12, -20, 0, 8), - AFFINEANIMCMD_LOOP(2), - AFFINEANIMCMD_END, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84024D0 = -{ - .tileTag = ANIM_TAG_POKEBALL, - .paletteTag = ANIM_TAG_POKEBALL, - .oam = &gOamData_837DF2C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812D3AC, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84024E8 = -{ - .tileTag = ANIM_TAG_GOLD_STARS, - .paletteTag = ANIM_TAG_GOLD_STARS, - .oam = &gOamData_837DF2C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812D4B4, -}; - -const struct SpriteTemplate gSpriteTemplate_8402500 = -{ - .tileTag = ANIM_TAG_GOLD_STARS, - .paletteTag = ANIM_TAG_GOLD_STARS, - .oam = &gOamData_837DF24, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812D588, -}; - -const union AffineAnimCmd gUnknown_08402518[] = -{ - AFFINEANIMCMD_FRAME(8, -8, 0, 12), - AFFINEANIMCMD_FRAME(-16, 16, 0, 12), - AFFINEANIMCMD_FRAME(8, -8, 0, 12), - AFFINEANIMCMD_LOOP(1), - AFFINEANIMCMD_END, -}; - -const union AffineAnimCmd gUnknown_08402540[] = -{ - AFFINEANIMCMD_FRAME(0, 6, 0, 20), - AFFINEANIMCMD_FRAME(0, 0, 0, 20), - AFFINEANIMCMD_FRAME(0, -18, 0, 6), - AFFINEANIMCMD_FRAME(-18, -18, 0, 3), - AFFINEANIMCMD_FRAME(0, 0, 0, 15), - AFFINEANIMCMD_FRAME(4, 4, 0, 13), - AFFINEANIMCMD_END, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402578 = -{ - .tileTag = ANIM_TAG_BLUE_ORB, - .paletteTag = ANIM_TAG_BLUE_ORB, - .oam = &gOamData_837DF24, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812D724, -}; - -const union AffineAnimCmd gUnknown_08402590[] = -{ - AFFINEANIMCMD_FRAME(0, 6, 0, 20), - AFFINEANIMCMD_FRAME(0, 0, 0, 20), - AFFINEANIMCMD_FRAME(7, -30, 0, 6), - AFFINEANIMCMD_FRAME(0, 0, 0, 20), - AFFINEANIMCMD_FRAME(-2, 3, 0, 20), - AFFINEANIMCMD_END, -}; - -const s8 gUnknown_084025C0[] = -{ - 0xE8, - 0x18, - 0xFC, - 0x00, -}; - -const union AnimCmd gSpriteAnim_84025C4[] = -{ - ANIMCMD_FRAME(0, 6), - ANIMCMD_FRAME(4, 6), - ANIMCMD_JUMP(0), -}; - -const union AnimCmd gSpriteAnim_84025D0[] = -{ - ANIMCMD_FRAME(8, 6), - ANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_84025D8[] = -{ - ANIMCMD_FRAME(12, 6), - ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_84025E0[] = -{ - gSpriteAnim_84025C4, - gSpriteAnim_84025D0, - gSpriteAnim_84025D8, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84025EC = -{ - .tileTag = ANIM_TAG_GREEN_STAR, - .paletteTag = ANIM_TAG_GREEN_STAR, - .oam = &gOamData_837DF2C, - .anims = gSpriteAnimTable_84025E0, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812DEAC, -}; - -const s8 gUnknown_08402604[] = -{ - 0x78, - 0x50, - 0x28, - 0x00, -}; - -const u8 gUnknown_08402608[] = -{ - 0, - 0, - 0, - 0, - 50, -}; - -const union AffineAnimCmd gUnknown_08402610[] = -{ - AFFINEANIMCMD_FRAME(0, -15, 0, 7), - AFFINEANIMCMD_FRAME(0, 15, 0, 7), - AFFINEANIMCMD_LOOP(2), - AFFINEANIMCMD_END, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402630 = -{ - .tileTag = ANIM_TAG_ANGER, - .paletteTag = ANIM_TAG_ANGER, - .oam = &gOamData_837DF2C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812E4F0, -}; - -const union AnimCmd gSpriteAnim_8402648[] = -{ - ANIMCMD_FRAME(0, 8), - ANIMCMD_FRAME(1, 8), - ANIMCMD_FRAME(2, 8), - ANIMCMD_FRAME(3, 8), - ANIMCMD_FRAME(3, 8, .vFlip = TRUE), - ANIMCMD_FRAME(2, 8, .vFlip = TRUE), - ANIMCMD_FRAME(0, 8, .vFlip = TRUE), - ANIMCMD_FRAME(1, 8, .vFlip = TRUE), - ANIMCMD_JUMP(0), -}; - -const union AnimCmd gSpriteAnim_840266C[] = -{ - ANIMCMD_FRAME(0, 8, .hFlip = TRUE), - ANIMCMD_FRAME(1, 8, .hFlip = TRUE), - ANIMCMD_FRAME(2, 8, .hFlip = TRUE), - ANIMCMD_FRAME(3, 8, .hFlip = TRUE), - ANIMCMD_FRAME(3, 8, .vFlip = TRUE, .hFlip = TRUE), - ANIMCMD_FRAME(2, 8, .vFlip = TRUE, .hFlip = TRUE), - ANIMCMD_FRAME(0, 8, .vFlip = TRUE, .hFlip = TRUE), - ANIMCMD_FRAME(1, 8, .vFlip = TRUE, .hFlip = TRUE), - ANIMCMD_JUMP(0), -}; - -const union AnimCmd gSpriteAnim_8402690[] = -{ - ANIMCMD_FRAME(0, 8), - ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_8402698[] = -{ - gSpriteAnim_8402648, - gSpriteAnim_840266C, - gSpriteAnim_8402690, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84026A4 = -{ - .tileTag = ANIM_TAG_PINK_PETAL, - .paletteTag = ANIM_TAG_PINK_PETAL, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_8402698, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812E7A0, -}; - -const u16 gUnknown_4026BC[] = INCBIN_U16("graphics/unknown/unknown_4026BC.gbapal"); - -const union AnimCmd gSpriteAnim_84026DC[] = -{ - ANIMCMD_FRAME(0, 5), - ANIMCMD_FRAME(4, 9), - ANIMCMD_FRAME(8, 5), - ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_84026EC[] = -{ - gSpriteAnim_84026DC, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84026F0 = -{ - .tileTag = ANIM_TAG_PAIN_SPLIT, - .paletteTag = ANIM_TAG_PAIN_SPLIT, - .oam = &gOamData_837DF2C, - .anims = gSpriteAnimTable_84026EC, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812EA4C, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402708 = -{ - .tileTag = ANIM_TAG_CONFETTI, - .paletteTag = ANIM_TAG_CONFETTI, - .oam = &gOamData_837DF24, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812EC78, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402720 = -{ - .tileTag = ANIM_TAG_SPOTLIGHT, - .paletteTag = ANIM_TAG_SPOTLIGHT, - .oam = &gOamData_837DFFC, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_8402384, - .callback = sub_812ED84, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402738 = -{ - .tileTag = ANIM_TAG_BLUE_ORB, - .paletteTag = ANIM_TAG_BLUE_ORB, - .oam = &gOamData_837DF24, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812EEA4, -}; - -const union AffineAnimCmd gUnknown_08402750[] = -{ - AFFINEANIMCMD_FRAME(16, 0, 0, 4), - AFFINEANIMCMD_FRAME(0, -3, 0, 16), - AFFINEANIMCMD_FRAME(4, 0, 0, 4), - AFFINEANIMCMD_FRAME(0, 0, 0, 24), - AFFINEANIMCMD_FRAME(-5, 3, 0, 16), - AFFINEANIMCMD_END, -}; - -const union AffineAnimCmd gSpriteAffineAnim_8402780[] = -{ - AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), - AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 8), - AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8), - AFFINEANIMCMD_JUMP(0), -}; - -const union AffineAnimCmd gSpriteAffineAnim_84027A0[] = -{ - AFFINEANIMCMD_FRAME(0xC0, 0xC0, 0, 0), - AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8), - AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 8), - AFFINEANIMCMD_JUMP(0), -}; - -const union AffineAnimCmd gSpriteAffineAnim_84027C0[] = -{ - AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), - AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8), - AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 8), - AFFINEANIMCMD_JUMP(0), -}; - -const union AffineAnimCmd *const gSpriteAffineAnimTable_84027E0[] = -{ - gSpriteAffineAnim_8402780, - gSpriteAffineAnim_84027A0, - gSpriteAffineAnim_84027C0, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84027EC = -{ - .tileTag = ANIM_TAG_PINK_CLOUD, - .paletteTag = ANIM_TAG_PINK_CLOUD, - .oam = &gOamData_837DF94, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_84027E0, - .callback = sub_812F88C, -}; - -const union AffineAnimCmd gSpriteAffineAnim_8402804[] = -{ - AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), - AFFINEANIMCMD_FRAME(0xFFFC, 0xFFFA, 0, 16), - AFFINEANIMCMD_FRAME(0x4, 0x6, 0, 16), - AFFINEANIMCMD_JUMP(0), -}; - -const union AffineAnimCmd gSpriteAffineAnim_8402824[] = -{ - AFFINEANIMCMD_FRAME(0xC0, 0xC0, 0, 0), - AFFINEANIMCMD_FRAME(0x4, 0x6, 0, 16), - AFFINEANIMCMD_FRAME(0xFFFC, 0xFFFA, 0, 16), - AFFINEANIMCMD_JUMP(0), -}; - -const union AffineAnimCmd gSpriteAffineAnim_8402844[] = -{ - AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), - AFFINEANIMCMD_FRAME(0x4, 0x6, 0, 16), - AFFINEANIMCMD_FRAME(0xFFFC, 0xFFFA, 0, 16), - AFFINEANIMCMD_JUMP(0), -}; - -const union AffineAnimCmd gSpriteAffineAnim_8402864[] = -{ - AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), - AFFINEANIMCMD_FRAME(0x8, 0xA, 0, 30), - AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF6, 0, 16), - AFFINEANIMCMD_JUMP(0), -}; - -const union AffineAnimCmd *const gSpriteAffineAnimTable_8402884[] = -{ - gSpriteAffineAnim_8402804, - gSpriteAffineAnim_8402824, - gSpriteAffineAnim_8402844, - gSpriteAffineAnim_8402864, -}; - -//arg[0]: frame (0-3) -//arg[1]: x -//arg[2]: y -//arg[3]: ??? (time on screen?) -const struct SpriteTemplate gPinkSmokeTemplate = -{ - .tileTag = ANIM_TAG_PINK_CLOUD, - .paletteTag = ANIM_TAG_PINK_CLOUD, - .oam = &gOamData_837DFF4, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_8402884, - .callback = sub_812F948, -}; - -const union AffineAnimCmd gUnknown_084028AC[] = -{ - AFFINEANIMCMD_FRAME(-16, 16, 0, 6), - AFFINEANIMCMD_FRAME(16, -16, 0, 12), - AFFINEANIMCMD_FRAME(-16, 16, 0, 6), - AFFINEANIMCMD_END, -}; - -const struct SpriteTemplate gSpriteTemplate_84028CC = -{ - .tileTag = ANIM_TAG_SWEAT_DROP, - .paletteTag = ANIM_TAG_SWEAT_DROP, - .oam = &gOamData_837DF24, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_812FF94, -}; - -const u16 gUnknown_084028E4[] = INCBIN_U16("graphics/battle_anims/sprites/effect.gbapal"); - -const union AnimCmd gSpriteAnim_8402914[] = -{ - ANIMCMD_FRAME(0, 3), - ANIMCMD_FRAME(16, 3), - ANIMCMD_JUMP(0), -}; - -const union AnimCmd gSpriteAnim_8402920[] = -{ - ANIMCMD_FRAME(32, 3), - ANIMCMD_FRAME(48, 3), - ANIMCMD_JUMP(0), -}; - -const union AnimCmd *const gSpriteAnimTable_840292C[] = -{ - gSpriteAnim_8402914, - gSpriteAnim_8402920, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402934 = -{ - .tileTag = ANIM_TAG_NOISE_LINE, - .paletteTag = ANIM_TAG_NOISE_LINE, - .oam = &gOamData_837DF34, - .anims = gSpriteAnimTable_840292C, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_81300F4, -}; - -const struct SpriteTemplate gSpriteTemplate_840294C = -{ - .tileTag = ANIM_TAG_SMALL_RED_EYE, - .paletteTag = ANIM_TAG_SMALL_RED_EYE, - .oam = &gOamData_837DF24, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_81304DC, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402964 = -{ - .tileTag = ANIM_TAG_PAW_PRINT, - .paletteTag = ANIM_TAG_PAW_PRINT, - .oam = &gOamData_837DF34, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_813051C, -}; - -const union AffineAnimCmd gSpriteAffineAnim_840297C[] = -{ - AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 24), - AFFINEANIMCMD_END, -}; - -const union AffineAnimCmd gSpriteAffineAnim_840298C[] = -{ - AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0), - AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 24), - AFFINEANIMCMD_END, -}; - -const union AffineAnimCmd *const gSpriteAffineAnimTable_84029A4[] = -{ - gSpriteAffineAnim_840297C, - gSpriteAffineAnim_840298C, -}; - -const struct SpriteTemplate gSpriteTemplate_84029AC = -{ - .tileTag = ANIM_TAG_RED_BALL, - .paletteTag = ANIM_TAG_RED_BALL, - .oam = &gOamData_837DF94, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_84029A4, - .callback = SpriteCallbackDummy, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84029C4 = -{ - .tileTag = ANIM_TAG_TAG_HAND, - .paletteTag = ANIM_TAG_TAG_HAND, - .oam = &gOamData_837DF34, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_81307B0, -}; - -const union AffineAnimCmd gUnknown_084029DC[] = -{ - AFFINEANIMCMD_FRAME(0, -16, 0, 6), - AFFINEANIMCMD_FRAME(0, 16, 0, 6), - AFFINEANIMCMD_END,//0 -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_84029F4 = -{ - .tileTag = ANIM_TAG_SMELLINGSALT_EFFECT, - .paletteTag = ANIM_TAG_SMELLINGSALT_EFFECT, - .oam = &gOamData_837DF34, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8130A2C, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402A0C = -{ - .tileTag = ANIM_TAG_TAG_HAND, - .paletteTag = ANIM_TAG_TAG_HAND, - .oam = &gOamData_837DF34, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8130AEC, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402A24 = -{ - .tileTag = ANIM_TAG_MAGNIFYING_GLASS, - .paletteTag = ANIM_TAG_MAGNIFYING_GLASS, - .oam = &gOamData_837E054, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8130F5C, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402A3C = -{ - .tileTag = ANIM_TAG_GOLD_STARS, - .paletteTag = ANIM_TAG_GOLD_STARS, - .oam = &gOamData_837DF2C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8131264, -}; - -const struct SpriteTemplate gSpriteTemplate_8402A54 = -{ - .tileTag = ANIM_TAG_GOLD_STARS, - .paletteTag = ANIM_TAG_GOLD_STARS, - .oam = &gOamData_837DF2C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_80D1FDC, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402A6C = -{ - .tileTag = ANIM_TAG_X_SIGN, - .paletteTag = ANIM_TAG_X_SIGN, - .oam = &gOamData_837DF3C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8131564, -}; - -const struct SpriteTemplate gSpriteTemplate_8402A84 = -{ - .tileTag = ANIM_TAG_ITEM_BAG, - .paletteTag = ANIM_TAG_ITEM_BAG, - .oam = &gOamData_837DF34, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8131EB8, -}; - -const union AnimCmd gSpriteAnim_8402A9C[] = -{ - ANIMCMD_FRAME(0, 4), - ANIMCMD_FRAME(64, 4), - ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_8402AA8[] = -{ - gSpriteAnim_8402A9C, -}; - -const union AffineAnimCmd gSpriteAffineAnim_8402AAC[] = -{ - AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), - AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 8), - AFFINEANIMCMD_END, -}; - -const union AffineAnimCmd gSpriteAffineAnim_8402AC4[] = -{ - AFFINEANIMCMD_FRAME(0xFF00, 0x100, 0, 0), - AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 8), - AFFINEANIMCMD_END, -}; - -const union AffineAnimCmd *const gSpriteAffineAnimTable_8402ADC[] = -{ - gSpriteAffineAnim_8402AAC, - gSpriteAffineAnim_8402AC4, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402AE4 = -{ - .tileTag = ANIM_TAG_SLAM_HIT_2, - .paletteTag = ANIM_TAG_SLAM_HIT_2, - .oam = &gOamData_837DF9C, - .anims = gSpriteAnimTable_8402AA8, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_8402ADC, - .callback = AnimKnockOffStrike, -}; - -const union AffineAnimCmd gSpriteAffineAnim_8402AFC[] = -{ - AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 64), - AFFINEANIMCMD_JUMP(0), -}; - -const union AffineAnimCmd *const gSpriteAffineAnimTable_8402B0C[] = -{ - gSpriteAffineAnim_8402AFC, -}; - -const struct SpriteTemplate gBattleAnimSpriteTemplate_8402B10 = -{ - .tileTag = ANIM_TAG_RECYCLE, - .paletteTag = ANIM_TAG_RECYCLE, - .oam = &gOamData_837E0BC, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_8402B0C, - .callback = AnimRecycle, -}; - -const union AffineAnimCmd gSlackOffSquishAffineAnimCmds[] = -{ - AFFINEANIMCMD_FRAME(0, 16, 0, 4), - AFFINEANIMCMD_FRAME(-2, 0, 0, 8), - AFFINEANIMCMD_FRAME(0, 4, 0, 4), - AFFINEANIMCMD_FRAME(0, 0, 0, 24), - AFFINEANIMCMD_FRAME(1, -5, 0, 16), - AFFINEANIMCMD_END, -}; - -static void sub_812C144(struct Sprite *sprite) -{ - sprite->pos1.x += gBattleAnimArgs[0]; - sprite->pos1.y += gBattleAnimArgs[1]; - - if (gBattleAnimArgs[3] == 0) - sprite->data[0] = gBattleAnimArgs[2]; - else - sprite->data[0] = -gBattleAnimArgs[2]; - - sprite->data[1] = gBattleAnimArgs[4]; - sprite->callback = sub_812C184; -} - -static void sub_812C184(struct Sprite *sprite) -{ - if (sprite->data[1] > 0) - { - sprite->pos2.x = sprite->data[2] >> 8; - sprite->data[2] += sprite->data[0]; - sprite->invisible ^= 1; - sprite->data[1]--; - } - else - { - DestroyAnimSprite(sprite); - } -} - -void sub_812C1D0(u8 taskId) -{ - sub_8046234( - GetBattlerSpriteCoord(gBattleAnimTarget, 2) + 8, - GetBattlerSpriteCoord(gBattleAnimTarget, 3) + 8, - 0); - DestroyAnimVisualTask(taskId); - -} - -static void sub_812C220(struct Sprite *sprite) -{ - sprite->data[0] = 90; - sprite->callback = WaitAnimForDuration; - sprite->data[1] = 7; - StoreSpriteCallbackInData(sprite, sub_812C268); - REG_BLDCNT = 0x3F40; - REG_BLDALPHA = ((16 - sprite->data[1]) << 8) | sprite->data[1]; -} - -static void sub_812C268(struct Sprite *sprite) -{ - REG_BLDALPHA = ((16 - sprite->data[1]) << 8) | sprite->data[1]; - if (--sprite->data[1] < 0) - { - sprite->invisible = 1; - sprite->callback = sub_812C2A4; - } -} - -static void sub_812C2A4(struct Sprite *sprite) -{ - REG_BLDCNT = 0; - REG_BLDALPHA = 0; - DestroyAnimSprite(sprite); -} - -static void sub_812C2BC(struct Sprite *sprite) -{ - u16 rotation; - u8 x = GetBattlerSpriteCoord(gBattleAnimTarget, 2); - u8 y = GetBattlerSpriteCoord(gBattleAnimTarget, 3); - - sub_8078764(sprite, TRUE); - - rotation = ArcTan2Neg(sprite->pos1.x - x, sprite->pos1.y - y); - rotation += 0x6000; - if (IsContest()) - rotation += 0x4000; - - sub_8078FDC(sprite, 0, 0x100, 0x100, rotation); - - sprite->data[0] = gBattleAnimArgs[2]; - sprite->data[2] = x; - sprite->data[4] = y; - sprite->callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData(sprite, DestroyAnimSprite); -} - -static void sub_812C358(struct Sprite *sprite) -{ - REG_BLDCNT = 0x3F40; - REG_BLDALPHA = 0x1000; - sprite->data[0] = 4; - sprite->callback = sub_812C380; -} - -static void sub_812C380(struct Sprite *sprite) -{ - REG_BLDALPHA = ((16 - sprite->data[0]) << 8) | sprite->data[0]; - - if (sprite->data[1]) - sprite->data[0]--; - else - sprite->data[0]++; - - if (sprite->data[0] == 15 || sprite->data[0] == 4) - sprite->data[1] ^= 1; - - if (sprite->data[2]++ > 70) - { - REG_BLDCNT = 0; - REG_BLDALPHA = 0; - StartSpriteAffineAnim(sprite, 1); - sprite->data[2] = 0; - sprite->invisible = 1; - sprite->affineAnimPaused = 1; - sprite->callback = sub_812C40C; - } -} - -static void sub_812C40C(struct Sprite *sprite) -{ - if (sprite->data[2]++ > 9) - { - sprite->invisible = 0; - sprite->affineAnimPaused = 0; - if (sprite->affineAnimEnded) - sprite->callback = sub_812C450; - } -} - -static void sub_812C450(struct Sprite *sprite) -{ - switch (sprite->data[3]) - { - case 0: - case 1: - sprite->pos2.x = 1; - sprite->pos2.y = 0; - break; - case 2: - case 3: - sprite->pos2.x = -1; - sprite->pos2.y = 0; - break; - case 4: - case 5: - sprite->pos2.x = 0; - sprite->pos2.y = 1; - break; - case 6: - default: - sprite->pos2.x = 0; - sprite->pos2.y = -1; - break; - } - - if (++sprite->data[3] > 7) - sprite->data[3] = 0; - - if (sprite->data[4]++ > 15) - { - sprite->data[0] = 16; - sprite->data[1] = 0; - REG_BLDCNT = 0x3F40; - REG_BLDALPHA = sprite->data[0]; - sprite->callback = sub_812C4FC; - } -} - -static void sub_812C4FC(struct Sprite *sprite) -{ - REG_BLDALPHA = ((16 - sprite->data[0]) << 8) | sprite->data[0]; - - if (sprite->data[1]++ > 1) - { - sprite->data[0]--; - sprite->data[1] = 0; - } - - if (sprite->data[0] == 0) - sprite->invisible = 1; - - if (sprite->data[0] < 0) - { - REG_BLDCNT = 0; - REG_BLDALPHA = 0; - DestroyAnimSprite(sprite); - } -} - -void sub_812C560(u8 taskId) -{ - gTasks[taskId].func = sub_812C588; - gAnimVisualTaskCount--; -} - -static void sub_812C588(u8 taskId) -{ - int i; - u16 lastColor; - u8 paletteIndex = sub_80789BC(); - - if (++gTasks[taskId].data[5] == 4) - { - lastColor = gPlttBufferFaded[paletteIndex * 16 + 11]; - for (i = 10; i > 0; i--) - gPlttBufferFaded[paletteIndex * 16 + i + 1] = gPlttBufferFaded[paletteIndex * 16 + i]; - - gPlttBufferFaded[paletteIndex * 16 + 1] = lastColor; - gTasks[taskId].data[5] = 0; - } - - if ((u16)gBattleAnimArgs[7] == 0xFFFF) - DestroyTask(taskId); -} - -void sub_812C624(u8 taskId) -{ - gTasks[taskId].func = sub_812C64C; - gAnimVisualTaskCount--; -} - -static void sub_812C64C(u8 taskId) -{ - int i; - u16 lastColor; - u8 paletteIndex = sub_80789BC(); - - if (++gTasks[taskId].data[5] == 4) - { - lastColor = gPlttBufferFaded[paletteIndex * 16 + 11]; - for (i = 10; i > 0; i--) - gPlttBufferFaded[paletteIndex * 16 + i + 1] = gPlttBufferFaded[paletteIndex * 16 + i]; - gPlttBufferFaded[paletteIndex * 16 + 1] = lastColor; - - lastColor = gPlttBufferUnfaded[paletteIndex * 16 + 11]; - for (i = 10; i > 0; i--) - gPlttBufferUnfaded[paletteIndex * 16 + i + 1] = gPlttBufferUnfaded[paletteIndex * 16 + i]; - gPlttBufferUnfaded[paletteIndex * 16 + 1] = lastColor; - - gTasks[taskId].data[5] = 0; - } - - if ((u16)gBattleAnimArgs[7] == 0xFFFF) - DestroyTask(taskId); -} - -static void sub_812C720(struct Sprite *sprite) -{ - u16 x; - u16 y; - - InitAnimSpritePos(sprite, 1); - SetAverageBattlerPositions(gBattleAnimTarget, 0, &x, &y); - - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - gBattleAnimArgs[2] = -gBattleAnimArgs[2]; - - sprite->data[0] = gBattleAnimArgs[4]; - sprite->data[2] = x + gBattleAnimArgs[2]; - sprite->data[4] = y + gBattleAnimArgs[3]; - sprite->data[5] = -50; - - InitAnimArcTranslation(sprite); - sprite->callback = sub_812C798; -} - -static void sub_812C798(struct Sprite *sprite) -{ - if (TranslateAnimArc(sprite)) - { - sprite->data[0] = 30; - sprite->data[1] = 0; - sprite->callback = WaitAnimForDuration; - StoreSpriteCallbackInData(sprite, sub_812C7C8); - } -} - -static void sub_812C7C8(struct Sprite *sprite) -{ - if (sprite->data[1] & 1) - sprite->invisible ^= 1; - - if (++sprite->data[1] == 16) - DestroyAnimSprite(sprite); -} - -static void sub_812C80C(struct Sprite *sprite) -{ - sub_8078650(sprite); - sub_807867C(sprite, gBattleAnimArgs[0]); - sprite->pos1.y += gBattleAnimArgs[1]; - sprite->callback = sub_8078600; - StoreSpriteCallbackInData(sprite, DestroyAnimSprite); -} - -// This is likely fakematching due to some strange type casting behavior. -static void sub_812C848(struct Sprite *sprite) -{ - int var0; - int var1; - if (sprite->data[0] == 0) - { - sub_8078650(sprite); - sub_807867C(sprite, gBattleAnimArgs[0]); - - if (!IsContest()) - { - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - { - sprite->data[1] = gBattleAnimArgs[2]; - sprite->data[2] = gBattleAnimArgs[3]; - } - else - { - var1 = -gBattleAnimArgs[2]; - sprite->data[1] = var1; - var1 = -gBattleAnimArgs[3]; - sprite->data[2] = var1; - } - } - else - { - var1 = -gBattleAnimArgs[2]; - sprite->data[1] = var1; - sprite->data[2] = gBattleAnimArgs[3]; - } - } - - sprite->data[0]++; - var0 = (sprite->data[0] * 20) & 0xFF; - sprite->data[3] += sprite->data[1]; - sprite->data[4] += sprite->data[2]; - sprite->pos2.x = (sprite->data[3] + (s32)((u32)sprite->data[3] >> 31)) >> 1; - sprite->pos2.y = Sin(var0 & 0xFF, 5) + ((s32)(sprite->data[4] + ((u32)sprite->data[4] >> 31)) >> 1); - - if ((u16)(sprite->pos1.x + sprite->pos2.x) > 240) - DestroyAnimSprite(sprite); -} - -static void sub_812C908(struct Sprite *sprite) -{ - if (sprite->animEnded) - DestroyAnimSprite(sprite); -} - -void sub_812C924(u8 taskId) -{ - if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT) - gBattleAnimArgs[7] = 0; - else - gBattleAnimArgs[7] = 1; - - DestroyAnimVisualTask(taskId); -} - -void sub_812C960(u8 taskId) -{ - if (gAnimMoveDmg > 0) - gBattleAnimArgs[7] = 0; - else - gBattleAnimArgs[7] = 1; - - DestroyAnimVisualTask(taskId); -} - -static void sub_812C990(struct Sprite *sprite) -{ - REG_WINOUT = 0x1F3F; - REG_DISPCNT |= DISPCNT_OBJWIN_ON; - gBattle_WIN0H = 0; - gBattle_WIN0V = 0; - REG_WIN0H = 0; - REG_WIN0V = 0; - - sub_8078764(sprite, FALSE); - - sprite->oam.objMode = ST_OAM_OBJ_WINDOW; - sprite->invisible = 1; - sprite->callback = sub_812CA04; -} - -static void sub_812CA04(struct Sprite *sprite) -{ - switch (sprite->data[0]) - { - case 0: - sprite->invisible = 0; - if (sprite->affineAnimEnded) - sprite->data[0]++; - break; - case 1: - case 3: - sprite->data[1] += 117; - sprite->pos2.x = sprite->data[1] >> 8; - if (++sprite->data[2] == 21) - { - sprite->data[2] = 0; - sprite->data[0]++; - } - break; - case 2: - sprite->data[1] -= 117; - sprite->pos2.x = sprite->data[1] >> 8; - if (++sprite->data[2] == 41) - { - sprite->data[2] = 0; - sprite->data[0]++; - } - break; - case 4: - ChangeSpriteAffineAnim(sprite, 1); - sprite->data[0]++; - break; - case 5: - if (sprite->affineAnimEnded) - { - sprite->invisible = 1; - sprite->callback = sub_812CAD0; - } - break; - } -} - -static void sub_812CAD0(struct Sprite *sprite) -{ - REG_WINOUT = 0x3F3F; - REG_DISPCNT ^= DISPCNT_OBJWIN_ON; - DestroyAnimSprite(sprite); -} - -static void sub_812CAFC(struct Sprite *sprite) -{ - if (gBattleAnimArgs[3] == 0) - { - sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); - sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); - } - - sprite->pos1.x += gBattleAnimArgs[0]; - sprite->pos1.y += gBattleAnimArgs[1]; - sprite->oam.tileNum += 16; - - if (gBattleAnimArgs[2] == 0) - { - sprite->oam.matrixNum = 8; - sprite->pos2.x = -12; - sprite->data[1] = 2; - } - else - { - sprite->pos2.x = 12; - sprite->data[1] = -2; - } - - sprite->data[0] = gBattleAnimArgs[4]; - - if (sprite->data[3] != 255) - sprite->data[3] = gBattleAnimArgs[2]; - - sprite->callback = sub_812CBB4; -} - -static void sub_812CBB4(struct Sprite *sprite) -{ - if (sprite->data[2] == 0) - { - sprite->pos2.x += sprite->data[1]; - if (sprite->pos2.x == 0) - { - sprite->data[2]++; - if (sprite->data[3] == 0) - { - PlaySE1WithPanning(222, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER_NEG)); - } - } - } - else - { - sprite->pos2.x -= sprite->data[1]; - if (abs(sprite->pos2.x) == 12) - { - sprite->data[0]--; - sprite->data[2]--; - } - - } - - if (sprite->data[0] == 0) - DestroyAnimSprite(sprite); -} - -static void sub_812CC28(struct Sprite *sprite) -{ - sprite->oam.objMode = ST_OAM_OBJ_WINDOW; - sprite->data[3] = 255; - sub_812CAFC(sprite); -} - -void sub_812CC44(u8 taskId) -{ - if (IsContest()) - { - REG_WININ = 0x1F3F; - gBattle_WIN1H = 0x98F0; - gBattle_WIN1V = 0x00A0; - REG_WIN1H = gBattle_WIN0H; - REG_WIN1V = gBattle_WIN0V; - } - - DestroyAnimVisualTask(taskId); -} - -void sub_812CCA8(u8 taskId) -{ - if (IsContest()) - { - REG_WININ = 0x3F3F; - gBattle_WIN1H = 0; - gBattle_WIN1V = 0; - } - - DestroyAnimVisualTask(taskId); -} - -static void sub_812CCE8(struct Sprite *sprite) -{ - int var0; - if (gBattleAnimArgs[0] == 0) - { - sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0) + gBattleAnimArgs[1]; - sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); - } - else - { - sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0) + gBattleAnimArgs[1]; - sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1); - } - - sprite->pos2.y = gBattleAnimArgs[2]; - var0 = 0; - if (sprite->pos2.y > gBattleAnimArgs[3]) - var0 = 1; - - sprite->data[0] = var0; - sprite->data[1] = 0; - sprite->data[2] = gBattleAnimArgs[4]; - sprite->data[3] = gBattleAnimArgs[5]; - sprite->data[4] = gBattleAnimArgs[3]; - sprite->callback = sub_812CD64; -} - -static void sub_812CD64(struct Sprite *sprite) -{ - sprite->data[1] = (sprite->data[1] + sprite->data[2]) & 0xFF; - sprite->pos2.x = gSineTable[sprite->data[1]] >> 4; - sprite->pos2.y += sprite->data[3]; - - if (sprite->data[0]) - { - if (sprite->pos2.y < sprite->data[4]) - DestroyAnimSprite(sprite); - } - else - { - if (sprite->pos2.y > sprite->data[4]) - DestroyAnimSprite(sprite); - } -} - -void sub_812CDC8(u8 taskId) -{ - s16 var0; - u8 toBG2; - s16 var2; - int var3; - int var4; - s16 i; - struct ScanlineEffectParams scanlineParams; - struct Task *task = &gTasks[taskId]; - - if (gBattleAnimArgs[0] == 0) - { - var0 = sub_8077FC0(gBattleAnimAttacker); - toBG2 = GetBattlerPosition_permutated(gBattleAnimAttacker); - } - else - { - var0 = sub_8077FC0(gBattleAnimTarget); - toBG2 = GetBattlerPosition_permutated(gBattleAnimTarget); - } - - task->data[0] = var0 + 36; - task->data[1] = task->data[0]; - task->data[2] = var0 - 33; - if (task->data[2] < 0) - task->data[2] = 0; - - task->data[3] = task->data[0]; - task->data[4] = 8; - task->data[5] = gBattleAnimArgs[1]; - task->data[6] = 0; - task->data[7] = 0; - - if (toBG2 == 1) - { - var3 = gBattle_BG1_X; - task->data[8] = var3; - var4 = var3 + 240; - } - else - { - var3 = gBattle_BG2_X; - task->data[8] = var3; - var4 = var3 + 240; - } - - task->data[9] = var4; - task->data[10] = gBattleAnimArgs[2]; - - if (gBattleAnimArgs[2] == 0) - { - task->data[11] = var4; - var2 = task->data[8]; - } - else - { - task->data[11] = var3; - var2 = task->data[9]; - } - - task->data[15] = 0; - - i = task->data[2]; - while (i <= task->data[3]) - { - gScanlineEffectRegBuffers[0][i] = var2; - gScanlineEffectRegBuffers[1][i] = var2; - i++; - } - - if (toBG2 == 1) - scanlineParams.dmaDest = ®_BG1HOFS; - else - scanlineParams.dmaDest = ®_BG2HOFS; - - scanlineParams.dmaControl = 0xA2600001; - scanlineParams.initState = 1; - scanlineParams.unused9 = 0; - ScanlineEffect_SetParams(scanlineParams); - - task->func = sub_812CEF0; -} - -static void sub_812CEF0(u8 taskId) -{ - s16 i; - struct Task *task = &gTasks[taskId]; - - task->data[0] -= task->data[5]; - if (task->data[0] < task->data[2]) - task->data[0] = task->data[2]; - - if (task->data[4] == 0) - { - task->data[1] -= task->data[5]; - if (task->data[1] < task->data[2]) - { - task->data[1] = task->data[2]; - task->data[15] = 1; - } - } - else - { - task->data[4]--; - } - - if (++task->data[6] > 1) - { - task->data[6] = 0; - task->data[7] = task->data[7] == 0 ? 1 : 0; - - if (task->data[7]) - task->data[12] = task->data[8]; - else - task->data[12] = task->data[9]; - } - - i = task->data[0]; - while (i < task->data[1]) - { - gScanlineEffectRegBuffers[0][i] = task->data[12]; - gScanlineEffectRegBuffers[1][i] = task->data[12]; - i++; - } - - i = task->data[1]; - while (i <= task->data[3]) - { - gScanlineEffectRegBuffers[0][i] = task->data[11]; - gScanlineEffectRegBuffers[1][i] = task->data[11]; - i++; - } - - if (task->data[15]) - { - if (task->data[10]) - gScanlineEffect.state = 3; - - DestroyAnimVisualTask(taskId); - } -} - -void sub_812D008(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - - task->data[0] = 0; - task->data[1] = 0; - task->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); - task->data[3] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); - task->data[4] = 32; - task->data[5] = -20; - task->data[6] = 0; - task->data[15] = GetAnimBattlerSpriteId(0); - task->func = sub_812D06C; -} - -static void sub_812D06C(u8 taskId) -{ - int var0, var1; - s16 x, y; - u16 i, j; - u8 spriteId; - struct Task *task = &gTasks[taskId]; - - switch (task->data[0]) - { - case 0: - var0 = task->data[2]; - if (task->data[1] & 1) - { - var1 = task->data[4]; - x = var0 - var1; - } - else - { - var1 = task->data[4]; - x = var0 + var1; - } - - y = task->data[3] + task->data[5]; - spriteId = CreateSprite(&gBattleAnimSpriteTemplate_83D7220, x, y, 6 - task->data[1]); - PlaySE12WithPanning(186, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER_NEG)); - - if (spriteId != MAX_SPRITES) - { - gSprites[spriteId].hFlip = task->data[1] & 1; - gSprites[spriteId].callback = SpriteCallbackDummy; - } - - if (task->data[1] & 1) - { - task->data[4] -= 6; - task->data[5] -= 6; - } - - PrepareAffineAnimInTaskData(task, task->data[15], gUnknown_08402400); - task->data[1]++; - task->data[0] = 1; - break; - case 1: - if (RunAffineAnimFromTaskData(task) == 0) - { - if (task->data[1] == 6) - { - task->data[6] = 8; - task->data[0] = 3; - } - else - { - if (task->data[1] <= 2) - task->data[6] = 10; - else - task->data[6] = 0; - - task->data[0] = 2; - } - } - break; - case 2: - if (task->data[6] != 0) - task->data[6]--; - else - task->data[0] = 0; - break; - case 3: - if (task->data[6] != 0) - task->data[6]--; - else - task->data[0] = 4; - break; - case 4: - for (i = 0, j = 0; i < MAX_SPRITES; i++) - { - if (gSprites[i].template == &gBattleAnimSpriteTemplate_83D7220) - { - gSprites[i].data[0] = taskId; - gSprites[i].data[1] = 6; - StartSpriteAnim(&gSprites[i], 2); - gSprites[i].callback = sub_812D254; - - if (++j == 6) - break; - } - } - - task->data[6] = j; - task->data[0] = 5; - break; - case 5: - if (task->data[6] == 0) - DestroyAnimVisualTask(taskId); - break; - } -} - -static void sub_812D254(struct Sprite *sprite) -{ - if (sprite->animEnded) - { - gTasks[sprite->data[0]].data[sprite->data[1]]--; - DestroySprite(sprite); - } -} - -static void sub_812D294(struct Sprite *sprite) -{ - if (sprite->data[0] == 0) - InitAnimSpritePos(sprite, 0); - - sprite->data[0]++; - if (sprite->data[0] < 40) - { - u16 var = sprite->data[0]; - if ((var & 1) == 0) - sprite->invisible = 1; - else - sprite->invisible = 0; - } - - if (sprite->data[0] > 30) - sprite->invisible = 0; - - if (sprite->data[0] == 61) - { - StoreSpriteCallbackInData(sprite, DestroyAnimSprite); - sprite->pos1.x += sprite->pos2.x; - sprite->pos1.y += sprite->pos2.y; - sprite->pos2.x = 0; - sprite->pos2.y = 0; - sprite->data[0] = 20; - sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); - sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); - sprite->callback = StartAnimLinearTranslation; - } -} - -void sub_812D350(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - case 0: - PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(0), &gUnknown_084024B0); - gTasks[taskId].data[0]++; - break; - case 1: - if (RunAffineAnimFromTaskData(&gTasks[taskId]) == 0) - DestroyAnimVisualTask(taskId); - break; - } -} - -static void sub_812D3AC(struct Sprite *sprite) -{ - u8 spriteId = GetAnimBattlerSpriteId(0); - - switch (sprite->data[0]) - { - case 0: - sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); - sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); - PrepareBattlerSpriteForRotScale(spriteId, 0); - sprite->data[1] = 256; - sprite->data[2] = 256; - sprite->data[0]++; - break; - case 1: - sprite->data[1] += 96; - sprite->data[2] -= 26; - obj_id_set_rotscale(spriteId, sprite->data[1], sprite->data[2], 0); - - if (++sprite->data[3] == 5) - sprite->data[0]++; - // fall through - case 2: - sprite->data[1] += 96; - sprite->data[2] += 48; - obj_id_set_rotscale(spriteId, sprite->data[1], sprite->data[2], 0); - - if (++sprite->data[3] == 9) - { - sprite->data[3] = 0; - gSprites[spriteId].invisible = 1; - sub_8078F40(spriteId); - sprite->data[0]++; - } - break; - case 3: - sprite->pos2.y -= 6; - if (sprite->pos1.y + sprite->pos2.y < -32) - DestroyAnimSprite(sprite); - break; - } -} - -static void sub_812D4B4(struct Sprite *sprite) -{ - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - sprite->pos1.x = -16; - else - sprite->pos1.x = 256; - - sprite->pos1.y = 0; - sprite->callback = sub_812D4EC; -} - -static void sub_812D4EC(struct Sprite *sprite) -{ - u32 newX; - - sprite->data[0] += 72; - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - sprite->pos2.x = sprite->data[0] >> 4; - else - sprite->pos2.x = -(sprite->data[0] >> 4); - - sprite->data[1] += 16; - sprite->pos2.y += sprite->data[1] >> 8; - - if (++sprite->data[2] % 3 == 0) - { - CreateSpriteAndAnimate( - &gSpriteTemplate_8402500, - sprite->pos1.x + sprite->pos2.x, - sprite->pos1.y + sprite->pos2.y, - sprite->subpriority + 1); - } - - newX = sprite->pos1.x + sprite->pos2.x + 32; - if (newX > 304) - DestroyAnimSprite(sprite); -} - -static void sub_812D588(struct Sprite *sprite) -{ - u8 rand; - s8 y; - - rand = Random() & 3; - if (rand == 0) - sprite->oam.tileNum += 4; - else - sprite->oam.tileNum += 5; - - y = Random() & 7; - if (y > 3) - y = -y; - - sprite->pos2.y = y; - sprite->callback = sub_812D5E8; -} - -static void sub_812D5E8(struct Sprite *sprite) -{ - if (++sprite->data[0] < 30) - { - if (++sprite->data[1] == 2) - { - sprite->invisible ^= 1; - sprite->data[1] = 0; - } - } - else - { - if (sprite->data[1] == 2) - sprite->invisible = 0; - - if (sprite->data[1] == 3) - { - sprite->invisible = 1; - sprite->data[1] = -1; - } - - sprite->data[1]++; - } - - if (sprite->data[0] > 60) - DestroySprite(sprite); -} - -void sub_812D674(u8 taskId) -{ - if (gTasks[taskId].data[0] == 0) - { - PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(0), &gUnknown_08402518); - gTasks[taskId].data[0]++; - } - else - { - if (RunAffineAnimFromTaskData(&gTasks[taskId]) == 0) - DestroyAnimVisualTask(taskId); - } -} - -void sub_812D6CC(u8 taskId) -{ - if (gTasks[taskId].data[0] == 0) - { - PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(0), &gUnknown_08402540); - gTasks[taskId].data[0]++; - } - else - { - if (RunAffineAnimFromTaskData(&gTasks[taskId]) == 0) - DestroyAnimVisualTask(taskId); - } -} - -static void sub_812D724(struct Sprite *sprite) -{ - switch (sprite->data[0]) - { - case 0: - InitAnimSpritePos(sprite, 0); - sprite->data[1] = 0x900; - sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); - sprite->data[0]++; - break; - case 1: - sprite->pos2.y -= sprite->data[1] >> 8; - sprite->data[1] -= 96; - if (sprite->pos1.y + sprite->pos2.y > sprite->data[2]) - DestroyAnimSprite(sprite); - break; - } -} - -void sub_812D790(u8 taskId) -{ - if (gTasks[taskId].data[0] == 0) - { - PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(0), &gUnknown_08402590); - gTasks[taskId].data[0]++; - } - else - { - if (RunAffineAnimFromTaskData(&gTasks[taskId]) == 0) - DestroyAnimVisualTask(taskId); - } -} - -void sub_812D7E8(u8 taskId) -{ - int i, j; - u8 position; - struct Struct_sub_8078914 subStruct; - u8 *dest; - u8 *src; - u16 *field_4; - u16 *ptr; - u16 stretch; - - switch (gTasks[taskId].data[0]) - { - case 0: - REG_MOSAIC = 0; - if (GetBattlerPosition_permutated(gBattleAnimAttacker) == 1) - REG_BG1CNT_BITFIELD.mosaic = 1; - else - REG_BG2CNT_BITFIELD.mosaic = 1; - - gTasks[taskId].data[10] = gBattleAnimArgs[0]; - gTasks[taskId].data[0]++; - break; - case 1: - if (gTasks[taskId].data[2]++ > 1) - { - gTasks[taskId].data[2] = 0; - gTasks[taskId].data[1]++; - stretch = gTasks[taskId].data[1]; - REG_MOSAIC = (stretch << 4) | stretch; - if (stretch == 15) - gTasks[taskId].data[0]++; - } - break; - case 2: - sub_8031FC4(gBattleAnimAttacker, gBattleAnimTarget, gTasks[taskId].data[10]); - sub_8078954(&subStruct, gBattleAnimAttacker); - - if (IsContest()) - position = 0; - else - position = GetBattlerPosition(gBattleAnimAttacker); - - dest = gUnknown_081FAF4C[position] + (gBattleMonForms[gBattleAnimAttacker] << 11); - src = subStruct.field_0; - DmaCopy32(3, dest, src, 0x800); - - if (IsContest()) - { - if (IsSpeciesNotUnown(EWRAM_19348[0]) != IsSpeciesNotUnown(EWRAM_19348[1])) - { - field_4 = (u16 *)subStruct.field_4; - for (i = 0; i < 8; i++) - { - for (j = 0; j < 4; j++) - { - u16 temp = field_4[j + i * 0x20]; - field_4[j + i * 0x20] = field_4[(7 - j) + i * 0x20]; - field_4[(7 - j) + i * 0x20] = temp; - } - } - - for (i = 0; i < 8; i++) - { - for (j = 0; j < 8; j++) - { - field_4[j + i * 0x20] ^= 0x400; - } - } - } - - ptr = EWRAM_19348; - if (IsSpeciesNotUnown(ptr[1])) - gSprites[gBankSpriteIds[gBattleAnimAttacker]].affineAnims = gSpriteAffineAnimTable_81E7C18; - else - gSprites[gBankSpriteIds[gBattleAnimAttacker]].affineAnims = gSpriteAffineAnimTable_81E7BEC; - - StartSpriteAffineAnim(&gSprites[gBankSpriteIds[gBattleAnimAttacker]], 0); - } - - gTasks[taskId].data[0]++; - break; - case 3: - if (gTasks[taskId].data[2]++ > 1) - { - gTasks[taskId].data[2] = 0; - gTasks[taskId].data[1]--; - stretch = gTasks[taskId].data[1]; - REG_MOSAIC = (stretch << 4) | stretch; - - if (stretch == 0) - gTasks[taskId].data[0]++; - } - break; - case 4: - REG_MOSAIC = 0; - if (GetBattlerPosition_permutated(gBattleAnimAttacker) == 1) - REG_BG1CNT_BITFIELD.mosaic = 0; - else - REG_BG2CNT_BITFIELD.mosaic = 0; - - if (!IsContest()) - { - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) - { - if (gTasks[taskId].data[10] == 0) - sub_8032984(gBattleAnimAttacker, eTransformStatuses[gBattleAnimAttacker].species); - } - } - - DestroyAnimVisualTask(taskId); - break; - } -} - -void c3_80DFBE4(u8 taskId) -{ - gBattleAnimArgs[7] = gSprites[gBankSpriteIds[gBattleAnimAttacker]].invisible; - DestroyAnimVisualTask(taskId); -} - -void sub_812DB58(u8 taskId) -{ - sub_8031FC4(gBattleAnimAttacker, gBattleAnimTarget, 1); - DestroyAnimVisualTask(taskId); -} - -void sub_812DB84(u8 taskId) -{ - struct Struct_sub_8078914 subStruct; - - switch (gTasks[taskId].data[0]) - { - case 0: - REG_BLDCNT = BLDCNT_TGT2_BD | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 - | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1; - REG_BLDALPHA = 0x1000; - REG_BG1CNT_BITFIELD.screenSize = 0; - REG_BG1CNT_BITFIELD.priority = 1; - if (!IsContest()) - REG_BG1CNT_BITFIELD.charBaseBlock = 1; - - sub_8078914(&subStruct); - DmaClear32(3, subStruct.field_4, 0x1000); - LZDecompressVram(gUnknown_08D2AA98, subStruct.field_4); - LZDecompressVram(gUnknown_08D2A9E0, subStruct.field_0); - LoadCompressedPalette(gUnknown_08D2AA80, subStruct.field_8 * 16, 32); - if (IsContest()) - { - sub_80763FC(subStruct.field_8, (u16 *)subStruct.field_4, 0, 0); - gBattle_BG1_X = -56; - gBattle_BG1_Y = 0; - } - else - { - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - gBattle_BG1_X = -135; - else - gBattle_BG1_X = -10; - - gBattle_BG1_Y = 0; - } - - gTasks[taskId].data[10] = gBattle_BG1_X; - gTasks[taskId].data[11] = gBattle_BG1_Y; - - gTasks[taskId].data[0]++; - PlaySE12WithPanning(SE_W234, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER_NEG)); - break; - case 1: - if (gTasks[taskId].data[4]++ > 0) - { - gTasks[taskId].data[4] = 0; - if (++gTasks[taskId].data[1] > 12) - gTasks[taskId].data[1] = 12; - - REG_BLDALPHA = ((16 - gTasks[taskId].data[1]) << 8) | gTasks[taskId].data[1]; - - if (gTasks[taskId].data[1] == 12) - gTasks[taskId].data[0]++; - } - break; - case 2: - if (--gTasks[taskId].data[1] < 0) - gTasks[taskId].data[1] = 0; - - REG_BLDALPHA = ((16 - gTasks[taskId].data[1]) << 8) | gTasks[taskId].data[1]; - - if (gTasks[taskId].data[1] == 0) - { - gBattle_BG1_X = gUnknown_084025C0[gTasks[taskId].data[2]] + gTasks[taskId].data[10]; - if (++gTasks[taskId].data[2] == 4) - gTasks[taskId].data[0] = 4; - else - gTasks[taskId].data[0] = 3; - } - break; - case 3: - if (++gTasks[taskId].data[3] == 4) - { - gTasks[taskId].data[3] = 0; - gTasks[taskId].data[0] = 1; - PlaySE12WithPanning(SE_W234, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER_NEG)); - } - break; - case 4: - sub_8078914(&subStruct); - DmaFill32Large(3, 0, subStruct.field_0, 0x2000, 0x1000); - DmaClear32(3, subStruct.field_4, 0x800); - - if (!IsContest()) - REG_BG1CNT_BITFIELD.charBaseBlock = 0; - - REG_BG1CNT_BITFIELD.priority = 1; - gBattle_BG1_X = 0; - gBattle_BG1_Y = 0; - REG_BLDCNT = 0; - REG_BLDALPHA = 0; - DestroyAnimVisualTask(taskId); - break; - } -} - -static void sub_812DEAC(struct Sprite *sprite) -{ - s16 var0; - u8 spriteId1; - u8 spriteId2; - - var0 = Random(); - var0 &= 0x3F; - if (var0 > 31) - var0 = 32 - var0; - - sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0) + var0; - sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 32; - sprite->data[1] = gBattleAnimArgs[0]; - sprite->data[2] = gBattleAnimArgs[1]; - - spriteId1 = CreateSprite(&gBattleAnimSpriteTemplate_84025EC, sprite->pos1.x, sprite->pos1.y, sprite->subpriority + 1); - spriteId2 = CreateSprite(&gBattleAnimSpriteTemplate_84025EC, sprite->pos1.x, sprite->pos1.y, sprite->subpriority + 1); - StartSpriteAnim(&gSprites[spriteId1], 1); - StartSpriteAnim(&gSprites[spriteId2], 2); - - gSprites[spriteId1].data[1] = gBattleAnimArgs[0]; - gSprites[spriteId1].data[2] = gBattleAnimArgs[1]; - gSprites[spriteId2].data[1] = gBattleAnimArgs[0]; - gSprites[spriteId2].data[2] = gBattleAnimArgs[1]; - gSprites[spriteId1].data[7] = -1; - gSprites[spriteId2].data[7] = -1; - gSprites[spriteId1].invisible = 1; - gSprites[spriteId2].invisible = 1; - gSprites[spriteId1].callback = sub_812E0F8; - gSprites[spriteId2].callback = sub_812E0F8; - - sprite->data[6] = spriteId1; - sprite->data[7] = spriteId2; - sprite->callback = sub_812DFEC; -} - -static void sub_812DFEC(struct Sprite *sprite) -{ - int var0; - s8 var1; - - var0 = (u16)sprite->data[2] + (u16)sprite->data[3]; - var1 = var0 >> 8; - sprite->pos2.y -= var1; - sprite->data[3] = var0 & 0xFF; - if (sprite->data[4] == 0 && sprite->pos2.y < -8) - { - gSprites[sprite->data[6]].invisible = 0; - sprite->data[4]++; - } - - if (sprite->data[4] == 1 && sprite->pos2.y < -16) - { - gSprites[sprite->data[7]].invisible = 0; - sprite->data[4]++; - } - - if (--sprite->data[1] == -1) - { - sprite->invisible = 1; - sprite->callback = sub_812E09C; - } -} - -static void sub_812E09C(struct Sprite *sprite) -{ - if (gSprites[sprite->data[6]].callback == SpriteCallbackDummy - && gSprites[sprite->data[7]].callback == SpriteCallbackDummy) - { - DestroySprite(&gSprites[sprite->data[6]]); - DestroySprite(&gSprites[sprite->data[7]]); - DestroyAnimSprite(sprite); - } -} - -static void sub_812E0F8(struct Sprite *sprite) -{ - u16 d2; - register u16 d3 asm("r1"); - int var0; - s8 var1; - - if (!sprite->invisible) - { - d2 = sprite->data[2]; - d3 = sprite->data[3]; - var0 = d2 + d3; - var1 = var0 >> 8; - sprite->pos2.y -= var1; - sprite->data[3] = var0 & 0xFF; - if (--sprite->data[1] == -1) - { - sprite->invisible = 1; - sprite->callback = SpriteCallbackDummy; - } - } -} - -void sub_812E14C(u8 taskId) -{ - struct Struct_sub_8078914 subStruct; - - switch (gTasks[taskId].data[0]) - { - case 0: - REG_BLDCNT = BLDCNT_TGT2_BD | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 - | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1; - REG_BLDALPHA = 0xD03; - REG_BG1CNT_BITFIELD.screenSize = 0; - REG_BG1CNT_BITFIELD.priority = 1; - - if (!IsContest()) - REG_BG1CNT_BITFIELD.charBaseBlock = 1; - - sub_8078914(&subStruct); - DmaClear32(3, subStruct.field_4, 0x1000); - LZDecompressVram(gUnknown_08D2AA98, subStruct.field_4); - LZDecompressVram(gUnknown_08D2A9E0, subStruct.field_0); - LoadCompressedPalette(gUnknown_08D2AA80, subStruct.field_8 * 16, 32); - - if (IsContest()) - { - sub_80763FC(subStruct.field_8, (u16 *)subStruct.field_4, 0, 0); - gBattle_BG1_X = -56; - gBattle_BG1_Y = 0; - } - else - { - u8 position = GetBattlerPosition(gBattleAnimTarget); - if (IsDoubleBattle() == TRUE) - { - if (position == B_POSITION_OPPONENT_LEFT) - gBattle_BG1_X = -155; - if (position == B_POSITION_OPPONENT_RIGHT) - gBattle_BG1_X = -115; - if (position == B_POSITION_PLAYER_LEFT) - gBattle_BG1_X = 14; - if (position == B_POSITION_PLAYER_RIGHT) - gBattle_BG1_X = -20; - } - else - { - if (position == B_POSITION_OPPONENT_LEFT) - gBattle_BG1_X = -135; - if (position == B_POSITION_PLAYER_LEFT) - gBattle_BG1_X = -10; - } - - gBattle_BG1_Y = 0; - } - - gTasks[taskId].data[10] = gBattle_BG1_X; - gTasks[taskId].data[11] = gBattle_BG1_Y; - gTasks[taskId].data[0]++; - break; - case 1: - gTasks[taskId].data[3] = 0; - if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT) - gBattle_BG1_X = gTasks[taskId].data[10] + gUnknown_08402604[gTasks[taskId].data[2]]; - else - gBattle_BG1_X = gTasks[taskId].data[10] - gUnknown_08402604[gTasks[taskId].data[2]]; - - if (++gTasks[taskId].data[2] == 5) - gTasks[taskId].data[0] = 5; - else - gTasks[taskId].data[0]++; - break; - case 2: - if (--gTasks[taskId].data[1] <= 4) - gTasks[taskId].data[1] = 5; - - REG_BLDALPHA = (gTasks[taskId].data[1] << 8) | 3; - if (gTasks[taskId].data[1] == 5) - gTasks[taskId].data[0]++; - break; - case 3: - if (++gTasks[taskId].data[3] > gUnknown_08402608[gTasks[taskId].data[2]]) - gTasks[taskId].data[0]++; - break; - case 4: - if (++gTasks[taskId].data[1] > 13) - gTasks[taskId].data[1] = 13; - - REG_BLDALPHA = (gTasks[taskId].data[1] << 8) | 3; - if (gTasks[taskId].data[1] == 13) - gTasks[taskId].data[0] = 1; - break; - case 5: - sub_8078914(&subStruct); - DmaClear32(3, subStruct.field_4, 0x800); - - if (!IsContest()) - REG_BG1CNT_BITFIELD.charBaseBlock = 0; - - REG_BG1CNT_BITFIELD.priority = 1; - gBattle_BG1_X = 0; - gBattle_BG1_Y = 0; - REG_BLDCNT = 0; - REG_BLDALPHA = 0; - DestroyAnimVisualTask(taskId); - break; - } -} - -void sub_812E498(u8 taskId) -{ - if (gTasks[taskId].data[0] == 0) - { - PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(0), &gUnknown_08402610); - gTasks[taskId].data[0]++; - } - else - { - if (!RunAffineAnimFromTaskData(&gTasks[taskId])) - { - DestroyAnimVisualTask(taskId); - } - } -} - -static void sub_812E4F0(struct Sprite *sprite) -{ - if (sprite->data[0] == 0) - { - InitAnimSpritePos(sprite, 0); - sprite->data[0]++; - } - else if (sprite->data[0]++ > 20) - { - sprite->data[1] += 160; - sprite->data[2] += 128; - - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - sprite->pos2.x = -(sprite->data[1] >> 8); - else - sprite->pos2.x = sprite->data[1] >> 8; - - sprite->pos2.y += sprite->data[2] >> 8; - if (sprite->pos2.y > 64) - DestroyAnimSprite(sprite); - } -} - -void sub_812E568(u8 taskId) -{ - u8 side; - struct Task *task = &gTasks[taskId]; - - if (gBattleAnimArgs[1] == 0) - { - DestroyAnimVisualTask(taskId); - return; - } - - if (gBattleAnimArgs[2] < 0) - gBattleAnimArgs[2] = 0; - if (gBattleAnimArgs[2] > 2) - gBattleAnimArgs[2] = 2; - - task->data[0] = 0; - task->data[1] = 0; - task->data[2] = 0; - task->data[3] = 8 - (2 * gBattleAnimArgs[2]); - task->data[4] = 0x100 + (gBattleAnimArgs[2] * 128); - task->data[5] = gBattleAnimArgs[2] + 2; - task->data[6] = gBattleAnimArgs[1] - 1; - task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - - if (gBattleAnimArgs[0] == 0) - side = GetBattlerSide(gBattleAnimAttacker); - else - side = GetBattlerSide(gBattleAnimTarget); - - if (side == B_SIDE_OPPONENT) - { - task->data[4] *= -1; - task->data[5] *= -1; - } - - PrepareBattlerSpriteForRotScale(task->data[15], 0); - task->func = sub_812E638; -} - -static void sub_812E638(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - - switch (task->data[0]) - { - case 0: - gSprites[task->data[15]].pos2.x += task->data[5]; - task->data[2] -= task->data[4]; - obj_id_set_rotscale(task->data[15], 0x100, 0x100, task->data[2]); - sub_8078F9C(task->data[15]); - if (++task->data[1] >= task->data[3]) - { - task->data[1] = 0; - task->data[0]++; - } - break; - case 1: - gSprites[task->data[15]].pos2.x -= task->data[5]; - task->data[2] += task->data[4]; - obj_id_set_rotscale(task->data[15], 0x100, 0x100, task->data[2]); - sub_8078F9C(task->data[15]); - if (++task->data[1] >= task->data[3] * 2) - { - task->data[1] = 0; - task->data[0]++; - } - break; - case 2: - gSprites[task->data[15]].pos2.x += task->data[5]; - task->data[2] -= task->data[4]; - obj_id_set_rotscale(task->data[15], 0x100, 0x100, task->data[2]); - sub_8078F9C(task->data[15]); - if (++task->data[1] >= task->data[3]) - { - if (task->data[6]) - { - task->data[6]--; - task->data[1] = 0; - task->data[0] = 0; - } - else - { - task->data[0]++; - } - } - break; - case 3: - sub_8078F40(task->data[15]); - DestroyAnimVisualTask(taskId); - break; - } -} - -static void sub_812E7A0(struct Sprite *sprite) -{ - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - { - sprite->pos1.x = 0; - sprite->pos1.y = gBattleAnimArgs[0]; - } - else - { - sprite->pos1.x = 240; - sprite->pos1.y = gBattleAnimArgs[0] - 30; - } - - sprite->data[2] = gBattleAnimArgs[2]; - StartSpriteAnim(sprite, gBattleAnimArgs[1]); - sprite->callback = sub_812E7F0; -} - -static void sub_812E7F0(struct Sprite *sprite) -{ - sprite->data[0] += 3; - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - { - sprite->pos1.x += 5; - sprite->pos1.y -= 1; - - if (sprite->pos1.x > 240) - DestroyAnimSprite(sprite); - - sprite->pos2.y = Sin(sprite->data[0] & 0xFF, 16); - } - else - { - sprite->pos1.x -= 5; - sprite->pos1.y += 1; - - if (sprite->pos1.x < 0) - DestroyAnimSprite(sprite); - - sprite->pos2.y = Cos(sprite->data[0] & 0xFF, 16); - } -} - -void sub_812E860(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - - task->data[0] = 0; - task->data[1] = 0; - task->data[2] = 0; - task->data[3] = 0; - task->data[12] = 0x20; - task->data[13] = 0x40; - task->data[14] = 0x800; - task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - - PrepareBattlerSpriteForRotScale(task->data[15], 0); - task->func = sub_812E8B4; -} - -static void sub_812E8B4(u8 taskId) -{ - int temp; - struct Task *task = &gTasks[taskId]; - - switch (task->data[0]) - { - case 0: - task->data[2] += 0x200; - if (task->data[2] >= task->data[14]) - { - s16 diff = task->data[14] - task->data[2]; - s16 div = diff / (task->data[14] * 2); - s16 mod = diff % (task->data[14] * 2); - - if ((div & 1) == 0) - { - task->data[2] = task->data[14] - mod; - task->data[0] = 1; - } - else - { - task->data[2] = mod - task->data[14]; - } - } - break; - case 1: - task->data[2] -= 0x200; - if (task->data[2] <= -task->data[14]) - { - s16 diff = task->data[14] - task->data[2]; - s16 div = diff / (task->data[14] * 2); - s16 mod = diff % (task->data[14] * 2); - - if ((1 & div) == 0) - { - task->data[2] = mod - task->data[14]; - task->data[0] = 0; - } - else - { - task->data[2] = task->data[14] - mod; - } - } - break; - case 2: - sub_8078F40(task->data[15]); - DestroyAnimVisualTask(taskId); - return; - } - - obj_id_set_rotscale(task->data[15], 0x100, 0x100, task->data[2]); - sub_8078F9C(task->data[15]); - gSprites[task->data[15]].pos2.x = -(((temp = task->data[2]) >= 0 ? task->data[2] : temp + 63) >> 6); - - if (++task->data[1] > 8) - { - if (task->data[12]) - { - task->data[12]--; - task->data[14] -= task->data[13]; - if (task->data[14] < 16) - task->data[14] = 16; - } - else - { - task->data[0] = 2; - } - } -} - -static void sub_812EA4C(struct Sprite *sprite) -{ - if (sprite->data[0] == 0) - { - if (gBattleAnimArgs[2] == 0) - { - sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); - sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); - } - - sprite->pos1.x += gBattleAnimArgs[0]; - sprite->pos1.y += gBattleAnimArgs[1]; - sprite->data[1] = 0x80; - sprite->data[2] = 0x300; - sprite->data[3] = gBattleAnimArgs[1]; - sprite->data[0]++; - } - else - { - sprite->pos2.x = sprite->data[1] >> 8; - sprite->pos2.y += sprite->data[2] >> 8; - if (sprite->data[4] == 0 && sprite->pos2.y > -sprite->data[3]) - { - sprite->data[4] = 1; - sprite->data[2] = (-sprite->data[2] / 3) * 2; - } - - sprite->data[1] += 192; - sprite->data[2] += 128; - if (sprite->animEnded) - DestroyAnimSprite(sprite); - } -} - -void sub_812EB10(u8 taskId) -{ - u8 spriteId; - - if (gTasks[taskId].data[0] == 0) - { - if (gBattleAnimArgs[0] == 0) - gTasks[taskId].data[11] = gBattleAnimAttacker; - else - gTasks[taskId].data[11] = gBattleAnimTarget; - - spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - gTasks[taskId].data[10] = spriteId; - PrepareBattlerSpriteForRotScale(spriteId, 0); - - switch (gBattleAnimArgs[1]) - { - case 0: - obj_id_set_rotscale(spriteId, 0xE0, 0x140, 0); - sub_8079A64(spriteId); - break; - case 1: - obj_id_set_rotscale(spriteId, 0xD0, 0x130, 0xF00); - sub_8079A64(spriteId); - if (IsContest() || GetBattlerSide(gTasks[taskId].data[11]) == B_SIDE_PLAYER) - gSprites[spriteId].pos2.y += 16; - break; - case 2: - obj_id_set_rotscale(spriteId, 0xD0, 0x130, 0xF100); - sub_8079A64(spriteId); - if (IsContest() || GetBattlerSide(gTasks[taskId].data[11]) == B_SIDE_PLAYER) - gSprites[spriteId].pos2.y += 16; - break; - } - - gSprites[spriteId].pos2.x = 2; - gTasks[taskId].data[0]++; - } - else - { - spriteId = gTasks[taskId].data[10]; - if (++gTasks[taskId].data[2] == 3) - { - gTasks[taskId].data[2] = 0; - gSprites[spriteId].pos2.x = -gSprites[spriteId].pos2.x; - } - - if (++gTasks[taskId].data[1] == 13) - { - sub_8078F40(spriteId); - gSprites[spriteId].pos2.x = 0; - gSprites[spriteId].pos2.y = 0; - DestroyAnimVisualTask(taskId); - } - } -} - -static void sub_812EC78(struct Sprite *sprite) -{ - u8 tileOffset; - int rand1; - int rand2; - - tileOffset = Random() % 12; - sprite->oam.tileNum += tileOffset; - rand1 = Random() & 0x1FF; - rand2 = Random() & 0xFF; - - if (rand1 & 1) - sprite->data[0] = 0x5E0 + rand1; - else - sprite->data[0] = 0x5E0 - rand1; - - if (rand2 & 1) - sprite->data[1] = 0x480 + rand2; - else - sprite->data[1] = 0x480 - rand2; - - sprite->data[2] = gBattleAnimArgs[0]; - if (sprite->data[2] == 0) - sprite->pos1.x = -8; - else - sprite->pos1.x = 248; - - sprite->pos1.y = 104; - sprite->callback = sub_812ED24; -} - -static void sub_812ED24(struct Sprite *sprite) -{ - if (sprite->data[2] == 0) - { - sprite->pos2.x += sprite->data[0] >> 8; - sprite->pos2.y -= sprite->data[1] >> 8; - } - else - { - sprite->pos2.x -= sprite->data[0] >> 8; - sprite->pos2.y -= sprite->data[1] >> 8; - } - - sprite->data[0] -= 22; - sprite->data[1] -= 48; - if (sprite->data[0] < 0) - sprite->data[0] = 0; - - if (++sprite->data[3] == 31) - DestroyAnimSprite(sprite); -} - -static void sub_812ED84(struct Sprite *sprite) -{ - REG_WINOUT = 0x1F3F; - REG_DISPCNT |= DISPCNT_OBJWIN_ON; - gBattle_WIN0H = 0; - gBattle_WIN0V = 0; - REG_WIN0H = 0; - REG_WIN0V = 0; - - sprite->data[0] = gBattleAnimArgs[2]; - sub_8078764(sprite, FALSE); - sprite->oam.objMode = ST_OAM_OBJ_WINDOW; - sprite->invisible = 1; - sprite->callback = sub_812EE00; -} - -static void sub_812EE00(struct Sprite *sprite) -{ - switch (sprite->data[1]) - { - case 0: - sprite->invisible = 0; - if (sprite->affineAnimEnded) - sprite->data[1]++; - break; - case 1: - if (--sprite->data[0] == 0) - { - ChangeSpriteAffineAnim(sprite, 1); - sprite->data[1]++; - } - break; - case 2: - if (sprite->affineAnimEnded) - { - sprite->invisible = 1; - sprite->data[1]++; - } - break; - case 3: - REG_WINOUT = 0x3F3F; - REG_DISPCNT ^= DISPCNT_OBJWIN_ON; - DestroyAnimSprite(sprite); - break; - } -} - -static void sub_812EEA4(struct Sprite *sprite) -{ - sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); - sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); - sprite->data[0] = gBattleAnimArgs[0]; - sprite->data[1] = gBattleAnimArgs[1]; - sprite->callback = sub_812EEEC; - sprite->callback(sprite); -} - -static void sub_812EEEC(struct Sprite *sprite) -{ - sprite->pos2.x = Sin(sprite->data[1], sprite->data[2] >> 8); - sprite->pos2.y = Cos(sprite->data[1], sprite->data[3] >> 8); - sprite->data[1] = (sprite->data[1] + 9) & 0xFF; - - if ((u16)sprite->data[1] < 64 || sprite->data[1] > 195) - sprite->subpriority = GetBattlerSubpriority(gBattleAnimAttacker) - 1; - else - sprite->subpriority = GetBattlerSubpriority(gBattleAnimAttacker) + 1; - - if (sprite->data[5] == 0) - { - sprite->data[2] += 0x400; - sprite->data[3] += 0x100; - sprite->data[4]++; - if (sprite->data[4] == sprite->data[0]) - { - sprite->data[4] = 0; - sprite->data[5] = 1; - } - } - else if (sprite->data[5] == 1) - { - sprite->data[2] -= 0x400; - sprite->data[3] -= 0x100; - sprite->data[4]++; - if (sprite->data[4] == sprite->data[0]) - DestroyAnimSprite(sprite); - } -} - -// Copies the target mon's sprite, and makes a white silhouette that shrinks away. -void AnimTask_RolePlaySilhouette(u8 taskId) -{ - u8 isBackPic; - u32 personality; - u32 otId; - u16 species; - s16 xOffset; - u32 priority; - u8 spriteId; - s16 coord1, coord2; - - GetAnimBattlerSpriteId(ANIM_BATTLER_ATTACKER); - if (IsContest()) - { - isBackPic = 1; - personality = eWRAM_19348Struct->personality; - otId = eWRAM_19348Struct->otId; - species = eWRAM_19348Struct->species; - xOffset = 20; - priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker); - } - else - { - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - { - isBackPic = 0; - personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY); - otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID); - if (eTransformStatuses[gBattleAnimTarget].species == SPECIES_NONE) - { - if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES); - else - species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES); - } - else - { - species = eTransformStatuses[gBattleAnimTarget].species; - } - - xOffset = 20; - priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker); - } - else - { - isBackPic = 1; - personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY); - otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID); - if (eTransformStatuses[gBattleAnimTarget].species == SPECIES_NONE) - { - if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES); - else - species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES); - } - else - { - species = eTransformStatuses[gBattleAnimTarget].species; - } - - xOffset = -20; - priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker); - } - } - - coord1 = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); - coord2 = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); - spriteId = sub_8079F44(species, isBackPic, 0, coord1 + xOffset, coord2, 5, personality, otId); - - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].oam.objMode = ST_OAM_OBJ_BLEND; - FillPalette(RGB_WHITE, (gSprites[spriteId].oam.paletteNum << 4) + 0x100, 32); - gSprites[spriteId].oam.priority = priority; - REG_BLDCNT = BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL; - REG_BLDALPHA = BLDALPHA_BLEND(gTasks[taskId].data[1], 16 - gTasks[taskId].data[1]); - - gTasks[taskId].data[0] = spriteId; - gTasks[taskId].func = AnimTask_RolePlaySilhouetteStep1; -} - -static void AnimTask_RolePlaySilhouetteStep1(u8 taskId) -{ - if (gTasks[taskId].data[10]++ > 1) - { - gTasks[taskId].data[10] = 0; - gTasks[taskId].data[1]++; - REG_BLDALPHA = ((16 - gTasks[taskId].data[1]) << 8) | gTasks[taskId].data[1]; - if (gTasks[taskId].data[1] == 10) - { - gTasks[taskId].data[10] = 256; - gTasks[taskId].data[11] = 256; - gTasks[taskId].func = sub_812F290; - } - } -} - -static void sub_812F290(u8 taskId) -{ - u8 spriteId = gTasks[taskId].data[0]; - gTasks[taskId].data[10] -= 16; - gTasks[taskId].data[11] += 128; - gSprites[spriteId].oam.affineMode |= 2; - sub_8078FDC(&gSprites[spriteId], 1, gTasks[taskId].data[10], gTasks[taskId].data[11], 0); - if (++gTasks[taskId].data[12] == 9) - { - sub_8079098(&gSprites[spriteId]); - DestroySpriteAndFreeResources_(&gSprites[spriteId]); - gTasks[taskId].func = sub_8078634; - } -} - -void sub_812F314(u8 taskId) -{ - u8 battler; - u16 bgX, bgY; - s16 y, i; - struct ScanlineEffectParams scanlineParams; - struct Task *task = &gTasks[taskId]; - - if (gBattleAnimArgs[0] == 0) - battler = gBattleAnimAttacker; - else - battler = gBattleAnimTarget; - - task->data[0] = 0; - task->data[1] = 0; - task->data[2] = 0; - task->data[3] = 16; - task->data[4] = 0; - task->data[5] = battler; - task->data[6] = 32; - task->data[7] = 0; - task->data[8] = 24; - - if (GetBattlerSide(battler) == B_SIDE_OPPONENT) - task->data[8] *= -1; - - task->data[13] = sub_8077FC0(battler) - 34; - if (task->data[13] < 0) - task->data[13] = 0; - - task->data[14] = task->data[13] + 66; - task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - if (GetBattlerPosition_permutated(battler) == 1) - { - scanlineParams.dmaDest = ®_BG1HOFS; - REG_BLDCNT = 0x3F42; - bgX = gBattle_BG1_X; - bgY = gBattle_BG1_Y; - } - else - { - scanlineParams.dmaDest = ®_BG2HOFS; - REG_BLDCNT = 0x3F44; - bgX = gBattle_BG2_X; - bgY = gBattle_BG2_Y; - } - - for (y = 0, i = 0; y < 160; y++, i += 2) - { - gScanlineEffectRegBuffers[0][i] = bgX; - gScanlineEffectRegBuffers[1][i] = bgX; - gScanlineEffectRegBuffers[0][i + 1] = bgY; - gScanlineEffectRegBuffers[1][i + 1] = bgY; - } - - scanlineParams.dmaControl = 0xA6600001; - scanlineParams.initState = 1; - scanlineParams.unused9 = 0; - ScanlineEffect_SetParams(scanlineParams); - task->func = sub_812F474; -} - -static void sub_812F474(u8 taskId) -{ - struct Task *task; - s16 var1; - s16 var2; - s16 bgX, bgY; - s16 offset; - s16 var0; - s16 i; - s16 sineIndex; - s16 var3; - - task = &gTasks[taskId]; - if (GetBattlerPosition_permutated(task->data[5]) == 1) - { - bgX = gBattle_BG1_X; - bgY = gBattle_BG1_Y; - } - else - { - bgX = gBattle_BG2_X; - bgY = gBattle_BG2_Y; - } - - switch (task->data[0]) - { - case 0: - offset = task->data[14] * 2; - var1 = 0; - var2 = 0; - i = 0; - task->data[1] = (task->data[1] + 2) & 0xFF; - sineIndex = task->data[1]; - task->data[9] = 0x7E0 / task->data[6]; - task->data[10] = -((task->data[7] * 2) / task->data[9]); - task->data[11] = task->data[7]; - var3 = task->data[11] >> 5; - task->data[12] = var3; - var0 = task->data[14]; - while (var0 > task->data[13]) - { - gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][offset + 1] = (i - var2) + bgY; - gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][offset] = bgX + var3 + (gSineTable[sineIndex] >> 5); - sineIndex = (sineIndex + 10) & 0xFF; - task->data[11] += task->data[10]; - var3 = task->data[11] >> 5; - task->data[12] = var3; - - i++; - offset -= 2; - var1 += task->data[6]; - var2 = var1 >> 5; - var0--; - } - - var0 *= 2; - while (var0 >= 0) - { - gScanlineEffectRegBuffers[0][var0] = bgX + 240; - gScanlineEffectRegBuffers[1][var0] = bgX + 240; - var0 -= 2; - } - - if (++task->data[6] > 63) - { - task->data[6] = 64; - task->data[2]++; - if (task->data[2] & 1) - task->data[3]--; - else - task->data[4]++; - - REG_BLDALPHA = (task->data[4] << 8) | task->data[3]; - if (task->data[3] == 0 && task->data[4] == 16) - { - task->data[2] = 0; - task->data[3] = 0; - task->data[0]++; - } - } - else - { - task->data[7] += task->data[8]; - } - break; - case 1: - if (++task->data[2] > 12) - { - gScanlineEffect.state = 3; - task->data[2] = 0; - task->data[0]++; - } - break; - case 2: - task->data[2]++; - if (task->data[2] & 1) - task->data[3]++; - else - task->data[4]--; - - REG_BLDALPHA = (task->data[4] << 8) | task->data[3]; - if (task->data[3] == 16 && task->data[4] == 0) - { - task->data[2] = 0; - task->data[3] = 0; - task->data[0]++; - } - break; - case 3: - DestroyAnimVisualTask(taskId); - break; - } -} - -void sub_812F724(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - task->data[0] = 0; - task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - PrepareAffineAnimInTaskData(&gTasks[taskId], task->data[15], &gUnknown_08402750); - task->func = sub_812F76C; -} - -static void sub_812F76C(u8 taskId) -{ - u16 var0; - - struct Task *task = &gTasks[taskId]; - var0 = task->data[0]; - task->data[0]++; - var0 -= 20; - if (var0 < 23) - { - if (++task->data[1] > 1) - { - task->data[1] = 0; - task->data[2]++; - if (task->data[2] & 1) - gSprites[task->data[15]].pos2.x = 1; - else - gSprites[task->data[15]].pos2.x = -1; - } - } - else - { - gSprites[task->data[15]].pos2.x = 0; - } - - if (!RunAffineAnimFromTaskData(&gTasks[taskId])) - DestroyAnimVisualTask(taskId); -} - -static void sub_812F804(struct Sprite *sprite, s16 b, s16 c, s16 d, s16 e, u16 f) -{ - sprite->pos1.x = b; - sprite->pos1.y = c; - sprite->data[4] = b << 4; - sprite->data[5] = c << 4; - sprite->data[6] = ((d - b) << 4) / f; - sprite->data[7] = ((e - c) << 4) / f; -} - -void sub_812F86C(struct Sprite *sprite) -{ - sprite->data[4] += sprite->data[6]; - sprite->data[5] += sprite->data[7]; - sprite->pos1.x = sprite->data[4] >> 4; - sprite->pos1.y = sprite->data[5] >> 4; -} - -static void sub_812F88C(struct Sprite *sprite) -{ - s16 x = sprite->pos1.x; - s16 y = sprite->pos1.y; - - sub_8078650(sprite); - StartSpriteAffineAnim(sprite, gBattleAnimArgs[0]); - sub_812F804(sprite, sprite->pos1.x, sprite->pos1.y, x, y, 64); - sprite->data[0] = 0; - sprite->callback = sub_812F8DC; -} - -static void sub_812F8DC(struct Sprite *sprite) -{ - int index; - - sprite->data[0]++; - index = (sprite->data[0] * 8) & 0xFF; - sub_812F86C(sprite); - sprite->pos2.y = Sin(index, 8); - if (sprite->data[0] > 58) - { - if (++sprite->data[1] > 1) - { - sprite->data[1] = 0; - sprite->data[2]++; - sprite->invisible = sprite->data[2] & 1; - if (sprite->data[2] > 3) - DestroySpriteAndMatrix(sprite); - } - } -} - -static void sub_812F948(struct Sprite *sprite) -{ - sprite->data[0] = gBattleAnimArgs[3]; - StartSpriteAffineAnim(sprite, gBattleAnimArgs[0]); - if (GetBattlerSide(gBattleAnimTarget) != B_SIDE_PLAYER) - gBattleAnimArgs[1] = -gBattleAnimArgs[1]; - - sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + gBattleAnimArgs[1]; - sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + gBattleAnimArgs[2]; - sprite->callback = sub_80DA48C; -} - -static void sub_812F9B0(u8 taskId) -{ - u16 var0 = 0; - u16 var1 = 0; - - gTasks[taskId].data[0]--; - if ((gTasks[taskId].data[6] & 0x8000) && (--gTasks[taskId].data[1] == -1)) - { - if (gTasks[taskId].data[9] == 0) - { - gTasks[taskId].data[9] = gTasks[taskId].data[4]; - gTasks[taskId].data[4] = -gTasks[taskId].data[4]; - } - else - { - gTasks[taskId].data[9] = 0; - } - - if (gTasks[taskId].data[10] == 0) - { - gTasks[taskId].data[10] = gTasks[taskId].data[5]; - gTasks[taskId].data[5] = -gTasks[taskId].data[5]; - } - else - { - gTasks[taskId].data[10] = 0; - } - - gTasks[taskId].data[1] = gTasks[taskId].data[13]; - } - - var0 = gTasks[taskId].data[7]; - var1 = gTasks[taskId].data[8]; - if (gTasks[taskId].data[2] & 0x8000) - gSprites[gTasks[taskId].data[15]].pos2.x = gTasks[taskId].data[9] - (var0 >> 8); - else - gSprites[gTasks[taskId].data[15]].pos2.x = gTasks[taskId].data[9] + (var0 >> 8); - - if (gTasks[taskId].data[3] & 0x8000) - gSprites[gTasks[taskId].data[15]].pos2.y = gTasks[taskId].data[10] - (var1 >> 8); - else - gSprites[gTasks[taskId].data[15]].pos2.y = gTasks[taskId].data[10] + (var1 >> 8); - - if (gTasks[taskId].data[0] < 1) - { - DestroyTask(taskId); - gAnimVisualTaskCount--; - } -} - -static void sub_812FAF8(u8 taskId) -{ - u16 var0 = 0; - u16 var1 = 0; - - gTasks[taskId].data[0]--; - if ((gTasks[taskId].data[6] & 0x8000) && (--gTasks[taskId].data[1] == -1)) - { - if (gTasks[taskId].data[9] == 0) - { - gTasks[taskId].data[9] = gTasks[taskId].data[4]; - gTasks[taskId].data[4] = -gTasks[taskId].data[4]; - } - else - { - gTasks[taskId].data[9] = var0; - } - - if (gTasks[taskId].data[10] == 0) - { - gTasks[taskId].data[10] = gTasks[taskId].data[5]; - gTasks[taskId].data[5] = -gTasks[taskId].data[5]; - } - else - { - gTasks[taskId].data[10] = 0; - } - - gTasks[taskId].data[1] = gTasks[taskId].data[13]; - } - - var0 = (gTasks[taskId].data[2] & 0x7FFF) + gTasks[taskId].data[7]; - var1 = (gTasks[taskId].data[3] & 0x7FFF) + gTasks[taskId].data[8]; - if (gTasks[taskId].data[2] & 0x8000) - gSprites[gTasks[taskId].data[15]].pos2.x = gTasks[taskId].data[9] - (var0 >> 8); - else - gSprites[gTasks[taskId].data[15]].pos2.x = gTasks[taskId].data[9] + (var0 >> 8); - - if (gTasks[taskId].data[3] & 0x8000) - gSprites[gTasks[taskId].data[15]].pos2.y = gTasks[taskId].data[10] - (var1 >> 8); - else - gSprites[gTasks[taskId].data[15]].pos2.y = gTasks[taskId].data[10] + (var1 >> 8); - - gTasks[taskId].data[7] = var0; - gTasks[taskId].data[8] = var1; - if (gTasks[taskId].data[0] < 1) - { - gTasks[taskId].data[0] = 30; - gTasks[taskId].data[13] = 0; - gTasks[taskId].func = sub_812F9B0; - } -} - -void sub_812FC68(u8 taskId) -{ - gTasks[taskId].data[15] = gBankSpriteIds[gBattleAnimAttacker]; - gTasks[taskId].data[14] = gBattleAnimArgs[0]; - gTasks[taskId].data[0] = gBattleAnimArgs[0]; - gTasks[taskId].data[13] = gBattleAnimArgs[6]; - if (gBattleAnimArgs[3]) - gTasks[taskId].data[6] = gTasks[taskId].data[6] | -0x8000; - - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - { - gTasks[taskId].data[2] = gBattleAnimArgs[1]; - gTasks[taskId].data[3] = gBattleAnimArgs[2]; - } - else - { - if (gBattleAnimArgs[1] & 0x8000) - gTasks[taskId].data[2] = gBattleAnimArgs[1] & 0x7FFF; - else - gTasks[taskId].data[2] = gBattleAnimArgs[1] | -0x8000; - - if (gBattleAnimArgs[2] & 0x8000) - gTasks[taskId].data[3] = gBattleAnimArgs[2] & 0x7FFF; - else - gTasks[taskId].data[3] = gBattleAnimArgs[2] | -0x8000; - } - - gTasks[taskId].data[8] = 0; - gTasks[taskId].data[7] = 0; - gTasks[taskId].data[4] = gBattleAnimArgs[4]; - gTasks[taskId].data[5] = gBattleAnimArgs[5]; - gTasks[taskId].func = sub_812FAF8; -} - -void sub_812FD7C(u8 taskId) -{ - u8 battler; - struct Task *task = &gTasks[taskId]; - - if (gBattleAnimArgs[1] == 0) - DestroyAnimVisualTask(taskId); - - task->data[0] = 0; - task->data[1] = 0; - task->data[2] = 0; - task->data[3] = gBattleAnimArgs[1]; - if (gBattleAnimArgs[0] == 0) - battler = gBattleAnimAttacker; - else - battler = gBattleAnimTarget; - - task->data[4] = GetBattlerSpriteCoord(battler, 0); - task->data[5] = GetBattlerSpriteCoord(battler, 1); - task->data[6] = GetBattlerSubpriority(battler); - task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - PrepareAffineAnimInTaskData(task, task->data[15], &gUnknown_084028AC); - task->func = sub_812FE20; -} - -static void sub_812FE20(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - - switch (task->data[0]) - { - case 0: - if (++task->data[1] == 6) - sub_812FEB8(taskId, TRUE); - - if (task->data[1] == 18) - sub_812FEB8(taskId, FALSE); - - if (!RunAffineAnimFromTaskData(task)) - { - if (--task->data[3] == 0) - { - task->data[0]++; - } - else - { - task->data[1] = 0; - PrepareAffineAnimInTaskData(task, task->data[15], &gUnknown_084028AC); - } - } - break; - case 1: - if (task->data[2] == 0) - DestroyAnimVisualTask(taskId); - break; - } -} - -static void sub_812FEB8(u8 taskId, bool8 arg1) -{ - u8 i; - s8 xOffset, yOffset; - struct Task *task; - s16 xCoords[4]; - s16 yCoords[2]; - - task = &gTasks[taskId]; - if (!arg1) - { - xOffset = 18; - yOffset = -20; - } - else - { - xOffset = 30; - yOffset = 20; - } - - xCoords[0] = task->data[4] - xOffset; - xCoords[1] = task->data[4] - xOffset - 4; - xCoords[2] = task->data[4] + xOffset; - xCoords[3] = task->data[4] + xOffset + 4; - yCoords[0] = task->data[5] + yOffset; - yCoords[1] = task->data[5] + yOffset + 6; - - for (i = 0; i < 4; i++) - { - u8 spriteId = CreateSprite(&gSpriteTemplate_84028CC, xCoords[i], yCoords[i & 1], task->data[6] - 5); - if (spriteId != MAX_SPRITES) - { - gSprites[spriteId].data[0] = 0; - gSprites[spriteId].data[1] = i < 2 ? -2 : 2; - gSprites[spriteId].data[2] = -1; - gSprites[spriteId].data[3] = taskId; - gSprites[spriteId].data[4] = 2; - task->data[2]++; - } - } -} - -static void sub_812FF94(struct Sprite *sprite) -{ - sprite->pos1.x += sprite->data[1]; - sprite->pos1.y += sprite->data[2]; - if (++sprite->data[0] > 6) - { - gTasks[sprite->data[3]].data[sprite->data[4]]--; - DestroySprite(sprite); - } -} - -void sub_812FFE4(u8 taskId) -{ - u8 spriteId; - - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[1] = gBattleAnimArgs[1]; - spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - gTasks[taskId].data[2] = 0x100 + gSprites[spriteId].oam.paletteNum * 16; - gTasks[taskId].func = sub_813003C; -} - -static void sub_813003C(u8 taskId) -{ - if (gTasks[taskId].data[1]) - { - BlendPalette(gTasks[taskId].data[2], 16, 8, gUnknown_084028E4[gTasks[taskId].data[0]]); - if (++gTasks[taskId].data[0] > 23) - gTasks[taskId].data[0] = 0; - - gTasks[taskId].data[1]--; - } - else - { - BlendPalette(gTasks[taskId].data[2], 16, 0, RGB(0, 0, 0)); - DestroyAnimVisualTask(taskId); - } -} - -void sub_81300A4(u8 taskId) -{ - sub_80E3C4C( - taskId, - 0, - 0x1A0, - gBattleAnimAttacker, - gBattleAnimArgs[0], - 10, - 2, - 30, - gUnknown_08D2E014, - gUnknown_08D2E170, - gUnknown_08D2E150); -} - -static void sub_81300F4(struct Sprite *sprite) -{ - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) - gBattleAnimArgs[0] = -gBattleAnimArgs[0]; - - sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0) + gBattleAnimArgs[0]; - sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + gBattleAnimArgs[1]; - if (gBattleAnimArgs[2] == 0) - { - sprite->data[0] = 640; - sprite->data[1] = -640; - } - else if (gBattleAnimArgs[2] == 1) - { - sprite->vFlip = 1; - sprite->data[0] = 640; - sprite->data[1] = 640; - } - else - { - StartSpriteAnim(sprite, 1); - sprite->data[0] = 640; - } - - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - { - sprite->data[0] = -sprite->data[0]; - sprite->hFlip = 1; - } - - sprite->callback = sub_81301B4; -} - -static void sub_81301B4(struct Sprite *sprite) -{ - sprite->data[6] += sprite->data[0]; - sprite->data[7] += sprite->data[1]; - sprite->pos2.x = sprite->data[6] >> 8; - sprite->pos2.y = sprite->data[7] >> 8; - if (++sprite->data[5] == 14) - DestroyAnimSprite(sprite); -} - -void sub_81301EC(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - - if (IsContest()) - { - task->data[5] = 8; - task->data[6] = 3; - task->data[7] = 1; - } - else - { - task->data[5] = 12; - task->data[6] = 3; - task->data[7] = 0; - } - - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - task->data[11] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + GetBattlerSpriteCoordAttr(gBattleAnimAttacker, 0) / 4; - else - task->data[11] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) - GetBattlerSpriteCoordAttr(gBattleAnimAttacker, 0) / 4; - - task->data[12] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) - GetBattlerSpriteCoordAttr(gBattleAnimAttacker, 0) / 4; - task->data[13] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); - task->data[14] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); - task->func = sub_81302E4; -} - -static void sub_81302E4(u8 taskId) -{ - u8 i; - s16 x, y; - struct Task *task = &gTasks[taskId]; - - switch (task->data[0]) - { - case 0: - if (++task->data[1] > 3) - { - task->data[1] = 0; - sub_8130424( - task->data[11], - task->data[12], - task->data[13], - task->data[14], - task->data[5], - task->data[2], - &x, - &y); - - for (i = 0; i < 2; i++) - { - u8 spriteId = CreateSprite(&gSpriteTemplate_840294C, x, y, 35); - if (spriteId != MAX_SPRITES) - { - if (task->data[7] == 0) - { - if (i == 0) - gSprites[spriteId].pos2.x = gSprites[spriteId].pos2.y = -task->data[6]; - else - gSprites[spriteId].pos2.x = gSprites[spriteId].pos2.y = task->data[6]; - } - else - { - if (i == 0) - { - gSprites[spriteId].pos2.x = -task->data[6]; - gSprites[spriteId].pos2.y = task->data[6]; - } - else - { - gSprites[spriteId].pos2.x = task->data[6]; - gSprites[spriteId].pos2.y = -task->data[6]; - } - } - - gSprites[spriteId].data[0] = 0; - gSprites[spriteId].data[1] = taskId; - gSprites[spriteId].data[2] = 10; - task->data[10]++; - } - } - - if (task->data[2] == task->data[5]) - task->data[0]++; - - task->data[2]++; - } - break; - case 1: - if (task->data[10] == 0) - DestroyAnimVisualTask(taskId); - break; - } -} - -static void sub_8130424(s16 arg0, s16 arg1, s16 arg2, s16 arg3, u8 arg4, u8 arg5, s16 *x, s16 *y) -{ - int x2; - int y2; - - if (arg5 == 0) - { - *x = arg0; - *y = arg1; - return; - } - - if (arg5 >= arg4) - { - *x = arg2; - *y = arg3; - return; - } - - arg4--; - x2 = (arg0 << 8) + arg5 * (((arg2 - arg0) << 8) / arg4); - y2 = (arg1 << 8) + arg5 * (((arg3 - arg1) << 8) / arg4); - *x = x2 >> 8; - *y = y2 >> 8; -} - -static void sub_81304DC(struct Sprite *sprite) -{ - if (++sprite->data[0] > 36) - { - gTasks[sprite->data[1]].data[sprite->data[2]]--; - DestroySprite(sprite); - } -} - -static void sub_813051C(struct Sprite *sprite) -{ - sprite->pos1.x = gBattleAnimArgs[0]; - sprite->pos1.y = gBattleAnimArgs[1]; - sprite->data[2] = gBattleAnimArgs[2]; - sprite->data[4] = gBattleAnimArgs[3]; - sprite->data[0] = gBattleAnimArgs[4]; - StoreSpriteCallbackInData(sprite, DestroyAnimSprite); - sprite->callback = sub_8078CC0; -} - -void sub_8130554(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - - task->data[11] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); - task->data[12] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); - task->data[13] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); - task->data[14] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + GetBattlerSpriteCoordAttr(gBattleAnimTarget, 0) / 4; - task->data[15] = CreateSprite(&gSpriteTemplate_84029AC, task->data[11], task->data[12], GetBattlerSubpriority(gBattleAnimTarget) - 5); - if (task->data[15] != MAX_SPRITES) - { - gSprites[task->data[15]].data[0] = 16; - gSprites[task->data[15]].data[2] = task->data[13]; - gSprites[task->data[15]].data[4] = task->data[14]; - gSprites[task->data[15]].data[5] = -32; - InitAnimArcTranslation(&gSprites[task->data[15]]); - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) - StartSpriteAffineAnim(&gSprites[task->data[15]], 1); - - task->func = sub_81306A4; - } - else - { - DestroyAnimVisualTask(taskId); - } -} - -static void sub_81306A4(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - - switch (task->data[0]) - { - case 0: - if (++task->data[1] > 1) - { - task->data[1] = 0; - TranslateAnimArc(&gSprites[task->data[15]]); - if (++task->data[2] > 7) - task->data[0]++; - } - break; - case 1: - if (TranslateAnimArc(&gSprites[task->data[15]])) - { - task->data[1] = 0; - task->data[2] = 0; - task->data[0]++; - } - break; - case 2: - if (++task->data[1] > 1) - { - task->data[1] = 0; - task->data[2]++; - gSprites[task->data[15]].invisible = task->data[2] & 1; - if (task->data[2] == 16) - { - FreeOamMatrix(gSprites[task->data[15]].oam.matrixNum); - DestroySprite(&gSprites[task->data[15]]); - task->data[0]++; - } - } - break; - case 3: - DestroyAnimVisualTask(taskId); - break; - } -} - -static void sub_81307B0(struct Sprite *sprite) -{ - u8 battler; - - if (gBattleAnimArgs[0] == 0) - battler = gBattleAnimAttacker; - else - battler = gBattleAnimTarget; - - sprite->oam.tileNum += 16; - sprite->data[6] = gBattleAnimArgs[2]; - sprite->data[7] = gBattleAnimArgs[1] == 0 ? -1 : 1; - sprite->pos1.y = GetBattlerSpriteCoord(battler, 3); - if (gBattleAnimArgs[1] == 0) - { - sprite->oam.matrixNum |= 0x8; - sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, 4) - 8; - } - else - { - sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, 5) + 8; - } - - sprite->callback = sub_813085C; -} - -static void sub_813085C(struct Sprite *sprite) -{ - switch (sprite->data[0]) - { - case 0: - if (++sprite->data[1] > 1) - { - sprite->data[1] = 0; - sprite->pos2.x += sprite->data[7]; - if (++sprite->data[2] == 12) - sprite->data[0]++; - } - break; - case 1: - if (++sprite->data[1] == 8) - { - sprite->data[1] = 0; - sprite->data[0]++; - } - break; - case 2: - sprite->pos2.x -= sprite->data[7] * 4; - if (++sprite->data[1] == 6) - { - sprite->data[1] = 0; - sprite->data[0]++; - } - break; - case 3: - sprite->pos2.x += sprite->data[7] * 3; - if (++sprite->data[1] == 8) - { - if (--sprite->data[6]) - { - sprite->data[1] = 0; - sprite->data[0]--; - } - else - { - DestroyAnimSprite(sprite); - } - } - break; - } -} - -void sub_8130918(u8 taskId) -{ - if (gBattleAnimArgs[0] == 0) - { - DestroyAnimVisualTask(taskId); - } - else - { - gTasks[taskId].data[0] = gBattleAnimArgs[1]; - gTasks[taskId].data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - PrepareAffineAnimInTaskData(&gTasks[taskId], gTasks[taskId].data[15], &gUnknown_084029DC); - gTasks[taskId].func = sub_8130970; - } -} - -static void sub_8130970(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - - if (++task->data[1] > 1) - { - task->data[1] = 0; - if (!(task->data[2] & 1)) - gSprites[task->data[15]].pos2.x = 2; - else - gSprites[task->data[15]].pos2.x = -2; - } - - if (!RunAffineAnimFromTaskData(task)) - { - gSprites[task->data[15]].pos2.x = 0; - if (--task->data[0]) - { - PrepareAffineAnimInTaskData(&gTasks[taskId], gTasks[taskId].data[15], &gUnknown_084029DC); - task->data[1] = 0; - task->data[2] = 0; - } - else - { - DestroyAnimVisualTask(taskId); - } - } -} - -static void sub_8130A2C(struct Sprite *sprite) -{ - if (gBattleAnimArgs[0] == 0) - { - sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); - sprite->pos1.y = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, 2); - } - else - { - sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2); - sprite->pos1.y = GetBattlerSpriteCoordAttr(gBattleAnimTarget, 2); - } - - if (sprite->pos1.y < 8) - sprite->pos1.y = 8; - - sprite->data[0] = 0; - sprite->data[1] = gBattleAnimArgs[1]; - sprite->data[2] = 0; - sprite->data[3] = gBattleAnimArgs[2]; - sprite->callback = sub_8130A94; -} - -static void sub_8130A94(struct Sprite *sprite) -{ - if (++sprite->data[0] >= sprite->data[1]) - { - sprite->data[0] = 0; - sprite->data[2] = (sprite->data[2] + 1) & 1; - sprite->invisible = sprite->data[2]; - if (sprite->data[2] && --sprite->data[3] == 0) - DestroyAnimSprite(sprite); - } -} - -static void sub_8130AEC(struct Sprite *sprite) -{ - if (gBattleAnimArgs[0] == 0) - { - sprite->oam.matrixNum |= 0x8; - sprite->pos1.x = 100; - sprite->data[7] = 1; - } - else - { - sprite->pos1.x = 140; - sprite->data[7] = -1; - } - - sprite->pos1.y = 56; - sprite->callback = sub_8130B38; -} - -static void sub_8130B38(struct Sprite *sprite) -{ - switch (sprite->data[0]) - { - case 0: - sprite->pos1.y -= sprite->data[7] * 2; - if (sprite->data[1] & 1) - sprite->pos1.x -= sprite->data[7] * 2; - - if (++sprite->data[1] == 9) - { - sprite->data[1] = 0; - sprite->data[0]++; - } - break; - case 1: - if (++sprite->data[1] == 4) - { - sprite->data[1] = 0; - sprite->data[0]++; - } - break; - case 2: - sprite->data[1]++; - sprite->pos1.y += sprite->data[7] * 3; - sprite->pos2.x = sprite->data[7] * (gSineTable[sprite->data[1] * 10] >> 3); - if (sprite->data[1] == 12) - { - sprite->data[1] = 0; - sprite->data[0]++; - } - break; - case 3: - if (++sprite->data[1] == 2) - { - sprite->data[1] = 0; - sprite->data[0]++; - } - break; - case 4: - sprite->data[1]++; - sprite->pos1.y -= sprite->data[7] * 3; - sprite->pos2.x = sprite->data[7] * (gSineTable[sprite->data[1] * 10] >> 3); - if (sprite->data[1] == 12) - sprite->data[0]++; - break; - case 5: - sprite->data[1]++; - sprite->pos1.y += sprite->data[7] * 3; - sprite->pos2.x = sprite->data[7] * (gSineTable[sprite->data[1] * 10] >> 3); - if (sprite->data[1] == 15) - sprite->oam.tileNum += 16; - - if (sprite->data[1] == 18) - { - sprite->data[1] = 0; - sprite->data[0]++; - } - break; - case 6: - sprite->pos1.x += sprite->data[7] * 6; - if (++sprite->data[1] == 9) - { - sprite->data[1] = 0; - sprite->data[0]++; - } - break; - case 7: - sprite->pos1.x += sprite->data[7] * 2; - if (++sprite->data[1] == 1) - { - sprite->data[1] = 0; - sprite->data[0]++; - } - break; - case 8: - sprite->pos1.x -= sprite->data[7] * 3; - if (++sprite->data[1] == 5) - DestroyAnimSprite(sprite); - break; - } -} - -void sub_8130D20(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - - task->data[15] = GetAnimBattlerSpriteId(0); - if (!IsContest()) - { - if (IsDoubleBattle() == TRUE) - { - int x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); - int y = GetBattlerSpriteCoord(gBattleAnimAttacker ^ 2, 0); - if (x > y) - task->data[14] = 1; - else - task->data[14] = -1; - } - else - { - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - task->data[14] = -1; - else - task->data[14] = 1; - } - } - else - { - task->data[14] = 1; - } - - task->func = sub_8130DBC; -} - -static void sub_8130DBC(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - - switch (task->data[0]) - { - case 0: - if (++task->data[1] == 13) - { - task->data[1] = 0; - task->data[0]++; - } - break; - case 1: - gSprites[task->data[15]].pos2.x -= task->data[14] * 3; - if (++task->data[1] == 6) - { - task->data[1] = 0; - task->data[0]++; - } - break; - case 2: - gSprites[task->data[15]].pos2.x += task->data[14] * 3; - if (++task->data[1] == 6) - { - task->data[1] = 0; - task->data[0]++; - } - break; - case 3: - if (++task->data[1] == 2) - { - task->data[1] = 0; - if (task->data[2] == 0) - { - task->data[2]++; - task->data[0] = 1; - } - else - { - task->data[0]++; - } - } - break; - case 4: - gSprites[task->data[15]].pos2.x += task->data[14]; - if (++task->data[1] == 3) - { - task->data[1] = 0; - task->data[0]++; - } - break; - case 5: - if (++task->data[1] == 6) - { - task->data[1] = 0; - task->data[0]++; - } - break; - case 6: - gSprites[task->data[15]].pos2.x -= task->data[14] * 4; - if (++task->data[1] == 5) - { - task->data[1] = 0; - task->data[0]++; - } - break; - case 7: - gSprites[task->data[15]].pos2.x += task->data[14] * 4; - if (++task->data[1] == 5) - { - task->data[1] = 0; - task->data[0]++; - } - break; - case 8: - gSprites[task->data[15]].pos2.x = 0; - DestroyAnimVisualTask(taskId); - break; - } -} - -static void sub_8130F5C(struct Sprite *sprite) -{ - if (gBattleAnimArgs[0] == 0) - { - InitAnimSpritePos(sprite, 1); - sprite->data[7] = gBattleAnimAttacker; - } - else - { - sprite->data[7] = gBattleAnimTarget; - } - - if (GetBattlerSide(sprite->data[7]) == B_SIDE_OPPONENT) - sprite->oam.matrixNum = 8; - - sprite->oam.priority = GetBattlerSpriteBGPriority(sprite->data[7]); - sprite->oam.objMode = ST_OAM_OBJ_BLEND; - sprite->callback = sub_8130FE0; -} - -static void sub_8130FE0(struct Sprite *sprite) -{ - u16 x, y; - - switch (sprite->data[5]) - { - case 0: - switch (sprite->data[6]) - { - default: - sprite->data[6] = 0; - case 0: - case 4: - x = GetBattlerSpriteCoordAttr(sprite->data[7], 5) - 4; - y = GetBattlerSpriteCoordAttr(sprite->data[7], 3) - 4; - break; - case 1: - x = GetBattlerSpriteCoordAttr(sprite->data[7], 5) - 4; - y = GetBattlerSpriteCoordAttr(sprite->data[7], 2) + 4; - break; - case 2: - x = GetBattlerSpriteCoordAttr(sprite->data[7], 4) + 4; - y = GetBattlerSpriteCoordAttr(sprite->data[7], 3) - 4; - break; - case 3: - x = GetBattlerSpriteCoordAttr(sprite->data[7], 4) + 4; - y = GetBattlerSpriteCoordAttr(sprite->data[7], 2) - 4; - break; - case 5: - x = GetBattlerSpriteCoord(sprite->data[7], 2); - y = GetBattlerSpriteCoord(sprite->data[7], 3); - break; - } - - if (sprite->data[6] == 4) - sprite->data[0] = 24; - else if (sprite->data[6] == 5) - sprite->data[0] = 6; - else - sprite->data[0] = 12; - - sprite->data[1] = sprite->pos1.x; - sprite->data[2] = x; - sprite->data[3] = sprite->pos1.y; - sprite->data[4] = y; - InitAnimLinearTranslation(sprite); - sprite->data[5]++; - break; - case 1: - if (TranslateAnimLinear(sprite)) - { - switch (sprite->data[6]) - { - default: - sprite->pos1.x += sprite->pos2.x; - sprite->pos1.y += sprite->pos2.y; - sprite->pos2.y = 0; - sprite->pos2.x = 0; - sprite->data[0] = 0; - sprite->data[5]++; - sprite->data[6]++; - break; - case 4: - sprite->pos1.x += sprite->pos2.x; - sprite->pos1.y += sprite->pos2.y; - sprite->pos2.y = 0; - sprite->pos2.x = 0; - sprite->data[5] = 0; - sprite->data[6]++; - break; - case 5: - sprite->data[0] = 0; - sprite->data[1] = 16; - sprite->data[2] = 0; - sprite->data[5] = 3; - break; - } - } - break; - case 2: - if (++sprite->data[0] == 4) - sprite->data[5] = 0; - break; - case 3: - if (!(sprite->data[0] & 1)) - sprite->data[1]--; - else - sprite->data[2]++; - - REG_BLDALPHA = (sprite->data[2] << 8) | sprite->data[1]; - if (++sprite->data[0] == 32) - { - sprite->invisible = 1; - sprite->data[5]++; - } - break; - case 4: - DestroyAnimSprite(sprite); - break; - } -} - -static void sub_81311E4(struct Sprite *sprite) -{ - sprite->pos2.x = ((sprite->data[2] - sprite->data[0]) * sprite->data[5]) / sprite->data[4]; - sprite->pos2.y = ((sprite->data[3] - sprite->data[1]) * sprite->data[5]) / sprite->data[4]; - if (!(sprite->data[5] & 1)) - { - CreateSprite( - &gSpriteTemplate_8402500, - sprite->pos1.x + sprite->pos2.x, - sprite->pos1.y + sprite->pos2.y, 5); - } - - if (sprite->data[5] == sprite->data[4]) - DestroyAnimSprite(sprite); - - sprite->data[5]++; -} - -static void sub_8131264(struct Sprite *sprite) -{ - GetBattlerSpriteCoord(gBattleAnimTarget, 2); // unused local variable - GetBattlerSpriteCoord(gBattleAnimTarget, 3); // unused local variable - - if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER || IsContest()) - { - sprite->data[0] = sprite->pos1.x - gBattleAnimArgs[0]; - sprite->data[2] = sprite->pos1.x - gBattleAnimArgs[2]; - } - else - { - sprite->data[0] = sprite->pos1.x + gBattleAnimArgs[0]; - sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2]; - } - - sprite->data[1] = sprite->pos1.y + gBattleAnimArgs[1]; - sprite->data[3] = sprite->pos1.y + gBattleAnimArgs[3]; - sprite->data[4] = gBattleAnimArgs[4]; - sprite->pos1.x = sprite->data[0]; - sprite->pos1.y = sprite->data[1]; - sprite->callback = sub_81311E4; -} - -void sub_81312E4(u8 taskId) -{ - int i; - u8 spriteId = GetAnimBattlerSpriteId(0); - - if (gTasks[taskId].data[0] == 0) - { - PrepareBattlerSpriteForRotScale(spriteId, 0); - gTasks[taskId].data[1] = 0x100; - gTasks[taskId].data[2] = 0x100; - gTasks[taskId].data[0]++; - } - else if (gTasks[taskId].data[0] == 1) - { - gTasks[taskId].data[1] += 0x60; - gTasks[taskId].data[2] -= 0xD; - obj_id_set_rotscale(spriteId, gTasks[taskId].data[1], gTasks[taskId].data[2], 0); - if (++gTasks[taskId].data[3] == 9) - { - gTasks[taskId].data[3] = 0; - sub_8078F40(spriteId); - gSprites[spriteId].invisible = 1; - gTasks[taskId].data[0]++; - } - } - else - { - refresh_graphics_maybe(gBattleAnimAttacker, 0, spriteId); - if (IsContest()) - { - gSprites[gBankSpriteIds[gBattleAnimAttacker]].affineAnims = gSpriteAffineAnimTable_81E7C18; - StartSpriteAffineAnim(&gSprites[gBankSpriteIds[gBattleAnimAttacker]], 0); - } - - for (i = 0; i < 16; i++) - gTasks[taskId].data[i] = 0; - - gTasks[taskId].func = sub_8131408; - } -} - -static void sub_8131408(u8 taskId) -{ - u8 spriteId = GetAnimBattlerSpriteId(0); - - switch (gTasks[taskId].data[0]) - { - case 0: - gSprites[spriteId].pos2.y = -200; - gSprites[spriteId].pos2.x = 200; - gSprites[spriteId].invisible = 0; - gTasks[taskId].data[10] = 0; - gTasks[taskId].data[0]++; - break; - case 1: - gTasks[taskId].data[10] += 112; - gSprites[spriteId].pos2.y += gTasks[taskId].data[10] >> 8; - if (gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y >= -32) - gSprites[spriteId].pos2.x = 0; - - if (gSprites[spriteId].pos2.y > 0) - gSprites[spriteId].pos2.y = 0; - - if (gSprites[spriteId].pos2.y == 0) - { - PlaySE12WithPanning(SE_W145B, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER_NEG)); - gTasks[taskId].data[10] -= 0x800; - gTasks[taskId].data[0]++; - } - break; - case 2: - gTasks[taskId].data[10] -= 112; - if (gTasks[taskId].data[10] < 0) - gTasks[taskId].data[10] = 0; - - gSprites[spriteId].pos2.y -= gTasks[taskId].data[10] >> 8; - if (gTasks[taskId].data[10] == 0) - gTasks[taskId].data[0]++; - break; - case 3: - gTasks[taskId].data[10] += 112; - gSprites[spriteId].pos2.y += gTasks[taskId].data[10] >> 8; - if (gSprites[spriteId].pos2.y > 0) - gSprites[spriteId].pos2.y = 0; - - if (gSprites[spriteId].pos2.y == 0) - { - PlaySE12WithPanning(SE_W145B, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER_NEG)); - DestroyAnimVisualTask(taskId); - } - break; - } -} - -static void sub_8131564(struct Sprite *sprite) -{ - s16 y2; - - if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) - { - sprite->subpriority = GetBattlerSubpriority(gBattleAnimTarget) - 2; - y2 = -144; - } - else - { - sprite->subpriority = GetBattlerSubpriority(gBattleAnimTarget) + 2; - y2 = -96; - } - - sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3); - sprite->pos2.y = y2; - sprite->callback = sub_81315C8; -} - -static void sub_81315C8(struct Sprite *sprite) -{ - switch (sprite->data[0]) - { - case 0: - sprite->pos2.y += 10; - if (sprite->pos2.y >= 0) - { - PlaySE12WithPanning(SE_W166, BattleAnimAdjustPanning(SOUND_PAN_TARGET)); - sprite->pos2.y = 0; - sprite->data[0]++; - } - break; - case 1: - sprite->data[1] += 4; - sprite->pos2.y = -(gSineTable[sprite->data[1]] >> 3); - if (sprite->data[1] > 127) - { - PlaySE12WithPanning(SE_W166, BattleAnimAdjustPanning(SOUND_PAN_TARGET)); - sprite->data[1] = 0; - sprite->pos2.y = 0; - sprite->data[0]++; - } - break; - case 2: - sprite->data[1] += 6; - sprite->pos2.y = -(gSineTable[sprite->data[1]] >> 4); - if (sprite->data[1] > 127) - { - sprite->data[1] = 0; - sprite->pos2.y = 0; - sprite->data[0]++; - } - break; - case 3: - if (++sprite->data[1] > 8) - { - PlaySE12WithPanning(SE_W043, BattleAnimAdjustPanning(SOUND_PAN_TARGET)); - sprite->data[1] = 0; - sprite->data[0]++; - } - break; - case 4: - if (++sprite->data[1] > 8) - { - sprite->data[1] = 0; - sprite->data[2]++; - sprite->invisible = sprite->data[2] & 1; - if (sprite->data[2] == 7) - DestroyAnimSprite(sprite); - } - break; - } -} - -void sub_81316F8(u8 taskId) -{ - s16 spriteId1, spriteId2; - - if (IsContest()) - { - DestroyAnimVisualTask(taskId); - return; - } - - spriteId1 = duplicate_obj_of_side_rel2move_in_transparent_mode(1); - if (spriteId1 < 0) - { - DestroyAnimVisualTask(taskId); - return; - } - - spriteId2 = duplicate_obj_of_side_rel2move_in_transparent_mode(1); - if (spriteId2 < 0) - { - obj_delete_but_dont_free_vram(&gSprites[spriteId1]); - DestroyAnimVisualTask(taskId); - return; - } - - gSprites[spriteId2].pos2.x += 24; - gSprites[spriteId1].pos2.x -= 24; - gSprites[spriteId2].data[0] = 0; - gSprites[spriteId1].data[0] = 0; - gSprites[spriteId2].data[1] = 0; - gSprites[spriteId1].data[1] = 0; - gSprites[spriteId2].data[2] = 0; - gSprites[spriteId1].data[2] = 0; - gSprites[spriteId2].data[3] = 16; - gSprites[spriteId1].data[3] = -16; - gSprites[spriteId2].data[4] = 0; - gSprites[spriteId1].data[4] = 128; - gSprites[spriteId2].data[5] = 24; - gSprites[spriteId1].data[5] = 24; - gSprites[spriteId2].data[6] = taskId; - gSprites[spriteId1].data[6] = taskId; - gSprites[spriteId2].data[7] = 0; - gSprites[spriteId1].data[7] = 0; - gTasks[taskId].data[0] = 2; - gSprites[spriteId2].invisible = 0; - gSprites[spriteId1].invisible = 1; - gSprites[spriteId2].oam.objMode = ST_OAM_OBJ_NORMAL; - gSprites[spriteId1].oam.objMode = ST_OAM_OBJ_NORMAL; - gSprites[spriteId2].callback = sub_8131838; - gSprites[spriteId1].callback = sub_8131838; - gTasks[taskId].func = sub_8131810; -} - -static void sub_8131810(u8 taskId) -{ - if (gTasks[taskId].data[0] == 0) - DestroyAnimVisualTask(taskId); -} - -static void sub_8131838(struct Sprite *sprite) -{ - if (++sprite->data[1] > 1) - { - sprite->data[1] = 0; - sprite->invisible ^= 1; - } - - sprite->data[4] = (sprite->data[4] + sprite->data[3]) & 0xFF; - sprite->pos2.x = Cos(sprite->data[4], sprite->data[5]); - switch (sprite->data[0]) - { - case 0: - if (++sprite->data[2] == 60) - { - sprite->data[2] = 0; - sprite->data[0]++; - } - break; - case 1: - if (++sprite->data[2] > 0) - { - sprite->data[2] = 0; - sprite->data[5] -= 2; - if (sprite->data[5] < 0) - { - gTasks[sprite->data[6]].data[sprite->data[7]]--; - obj_delete_but_dont_free_vram(sprite); - } - } - break; - } -} - -void AnimTask_GetReturnPowerLevel(u8 taskId) -{ - gBattleAnimArgs[7] = 0; - if (gAnimFriendship < 60) - gBattleAnimArgs[7] = 0; - if (gAnimFriendship > 60 && gAnimFriendship < 92) - gBattleAnimArgs[7] = 1; - if (gAnimFriendship > 91 && gAnimFriendship < 201) - gBattleAnimArgs[7] = 2; - if (gAnimFriendship > 200) - gBattleAnimArgs[7] = 3; - - DestroyAnimVisualTask(taskId); -} - -#ifdef NONMATCHING -// Makes the mon run out of screen, run past the opposing mon, and return to its original position. -// No args. -void AnimTask_SnatchOpposingMonMove(u8 taskId) -{ - u8 spriteId, spriteId2; - u32 personality; - u32 otId; - u16 species; - u8 subpriority; - u8 isBackPic; - s16 x; - - switch (gTasks[taskId].data[0]) - { - case 0: - spriteId = GetAnimBattlerSpriteId(ANIM_BATTLER_ATTACKER); - gTasks[taskId].data[1] += 0x800; - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - gSprites[spriteId].pos2.x += (gTasks[taskId].data[1] >> 8); - else - gSprites[spriteId].pos2.x -= (gTasks[taskId].data[1] >> 8); - - gTasks[taskId].data[1] &= 0xFF; - x = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x; - if ((u16)(x + 32) > 304) - { - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[0]++; - } - break; - case 1: - if (IsContest()) - { - personality = eWRAM_19348Struct->personality; - otId = eWRAM_19348Struct->otId; - species = eWRAM_19348Struct->species; - subpriority = GetBattlerSubpriority(gBattleAnimAttacker); - isBackPic = 0; - x = -32; - } - else - { - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - { - personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_PERSONALITY); - otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_OT_ID); - if (eTransformStatuses[gBattleAnimTarget].species == SPECIES_NONE) - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES); - else - species = eTransformStatuses[gBattleAnimTarget].species; - - subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_BATTLER_TARGET)].subpriority + 1; - isBackPic = 0; - x = 272; - } - else - { - personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_PERSONALITY); - otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_OT_ID); - if (eTransformStatuses[gBattleAnimTarget].species == SPECIES_NONE) - species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES); - else - species = eTransformStatuses[gBattleAnimTarget].species; - - subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_BATTLER_TARGET)].subpriority - 1; - isBackPic = 1; - x = -32; - } - } - - spriteId2 = sub_8079F44(species, isBackPic, 0, x, GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y), subpriority, personality, otId); - if (eTransformStatuses[gBattleAnimTarget].species != SPECIES_NONE) - BlendPalette((gSprites[spriteId2].oam.paletteNum * 16) | 0x100, 16, 6, RGB_WHITE); - - gTasks[taskId].data[15] = spriteId2; - gTasks[taskId].data[0]++; - break; - case 2: - spriteId2 = gTasks[taskId].data[15]; - gTasks[taskId].data[1] += 0x800; - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - gSprites[spriteId2].pos2.x -= (gTasks[taskId].data[1] >> 8); - else - gSprites[spriteId2].pos2.x += (gTasks[taskId].data[1] >> 8); - - gTasks[taskId].data[1] &= 0xFF; - x = gSprites[spriteId2].pos1.x + gSprites[spriteId2].pos2.x; - if (gTasks[taskId].data[14] == 0) - { - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - { - if (x < GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X)) - { - gTasks[taskId].data[14]++; - gBattleAnimArgs[7] = 0xFFFF; - } - } - else - { - if (x > GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X)) - { - gTasks[taskId].data[14]++; - gBattleAnimArgs[7] = 0xFFFF; - } - } - } - - if ((u16)(x + 32) > 304) - { - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[0]++; - } - break; - case 3: - spriteId = GetAnimBattlerSpriteId(ANIM_BATTLER_ATTACKER); - spriteId2 = gTasks[taskId].data[15]; - DestroySpriteAndFreeResources_(&gSprites[spriteId2]); - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - gSprites[spriteId].pos2.x = -gSprites[spriteId].pos1.x - 32; - else - gSprites[spriteId].pos2.x = 272 - gSprites[spriteId].pos1.x; - - gTasks[taskId].data[0]++; - break; - case 4: - spriteId = GetAnimBattlerSpriteId(ANIM_BATTLER_ATTACKER); - gTasks[taskId].data[1] += 0x800; - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - { - gSprites[spriteId].pos2.x += (gTasks[taskId].data[1] >> 8); - if (gSprites[spriteId].pos2.x + gSprites[spriteId].pos1.x >= GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X)) - gSprites[spriteId].pos2.x = 0; - } - else - { - gSprites[spriteId].pos2.x -= (gTasks[taskId].data[1] >> 8); - if (gSprites[spriteId].pos2.x + gSprites[spriteId].pos1.x <= GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X)) - gSprites[spriteId].pos2.x = 0; - } - - gTasks[taskId].data[1] = (u8)gTasks[taskId].data[1]; - if (gSprites[spriteId].pos2.x == 0) - DestroyAnimVisualTask(taskId); - break; - } -} -#else -NAKED -void AnimTask_SnatchOpposingMonMove(u8 taskId) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x14\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - mov r8, r0\n\ - ldr r1, _08131974 @ =gTasks\n\ - lsls r0, 2\n\ - add r0, r8\n\ - lsls r0, 3\n\ - adds r0, r1\n\ - movs r1, 0x8\n\ - ldrsh r0, [r0, r1]\n\ - cmp r0, 0x4\n\ - bls _0813196A\n\ - b _08131EA0\n\ -_0813196A:\n\ - lsls r0, 2\n\ - ldr r1, _08131978 @ =_0813197C\n\ - adds r0, r1\n\ - ldr r0, [r0]\n\ - mov pc, r0\n\ - .align 2, 0\n\ -_08131974: .4byte gTasks\n\ -_08131978: .4byte _0813197C\n\ - .align 2, 0\n\ -_0813197C:\n\ - .4byte _08131990\n\ - .4byte _08131A44\n\ - .4byte _08131C20\n\ - .4byte _08131D40\n\ - .4byte _08131DC4\n\ -_08131990:\n\ - movs r0, 0\n\ - bl GetAnimBattlerSpriteId\n\ - lsls r0, 24\n\ - lsrs r7, r0, 24\n\ - ldr r1, _081319DC @ =gTasks\n\ - mov r2, r8\n\ - lsls r4, r2, 2\n\ - adds r0, r4, r2\n\ - lsls r0, 3\n\ - adds r6, r0, r1\n\ - movs r3, 0x80\n\ - lsls r3, 4\n\ - adds r0, r3, 0\n\ - ldrh r1, [r6, 0xA]\n\ - adds r0, r1\n\ - strh r0, [r6, 0xA]\n\ - ldr r0, _081319E0 @ =gBattleAnimAttacker\n\ - ldrb r0, [r0]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - mov r9, r4\n\ - cmp r0, 0\n\ - bne _081319E8\n\ - ldr r2, _081319E4 @ =gSprites\n\ - lsls r3, r7, 4\n\ - adds r1, r3, r7\n\ - lsls r1, 2\n\ - adds r1, r2\n\ - ldrh r0, [r6, 0xA]\n\ - lsls r0, 16\n\ - asrs r0, 24\n\ - ldrh r4, [r1, 0x24]\n\ - adds r0, r4\n\ - strh r0, [r1, 0x24]\n\ - b _08131A02\n\ - .align 2, 0\n\ -_081319DC: .4byte gTasks\n\ -_081319E0: .4byte gBattleAnimAttacker\n\ -_081319E4: .4byte gSprites\n\ -_081319E8:\n\ - ldr r3, _08131A3C @ =gSprites\n\ - lsls r4, r7, 4\n\ - adds r2, r4, r7\n\ - lsls r2, 2\n\ - adds r2, r3\n\ - ldrh r1, [r6, 0xA]\n\ - lsls r1, 16\n\ - asrs r1, 24\n\ - ldrh r0, [r2, 0x24]\n\ - subs r0, r1\n\ - strh r0, [r2, 0x24]\n\ - adds r2, r3, 0\n\ - adds r3, r4, 0\n\ -_08131A02:\n\ - ldr r1, _08131A40 @ =gTasks\n\ - mov r0, r9\n\ - add r0, r8\n\ - lsls r0, 3\n\ - adds r4, r0, r1\n\ - ldrb r0, [r4, 0xA]\n\ - strh r0, [r4, 0xA]\n\ - adds r1, r3, r7\n\ - lsls r1, 2\n\ - adds r1, r2\n\ - ldrh r0, [r1, 0x24]\n\ - ldrh r1, [r1, 0x20]\n\ - adds r0, r1\n\ - lsls r0, 16\n\ - movs r1, 0x80\n\ - lsls r1, 14\n\ - adds r0, r1\n\ - movs r1, 0x98\n\ - lsls r1, 17\n\ - cmp r0, r1\n\ - bhi _08131A2E\n\ - b _08131EA0\n\ -_08131A2E:\n\ - movs r0, 0\n\ - strh r0, [r4, 0xA]\n\ - ldrh r0, [r4, 0x8]\n\ - adds r0, 0x1\n\ - strh r0, [r4, 0x8]\n\ - b _08131EA0\n\ - .align 2, 0\n\ -_08131A3C: .4byte gSprites\n\ -_08131A40: .4byte gTasks\n\ -_08131A44:\n\ - bl IsContest\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - beq _08131A74\n\ - ldr r0, _08131A6C @ =gSharedMem + 0x19348\n\ - ldr r2, [r0, 0x8]\n\ - mov r10, r2\n\ - ldr r3, [r0, 0xC]\n\ - mov r9, r3\n\ - ldrh r5, [r0]\n\ - ldr r0, _08131A70 @ =gBattleAnimAttacker\n\ - ldrb r0, [r0]\n\ - bl GetBattlerSubpriority\n\ - lsls r0, 24\n\ - lsrs r4, r0, 24\n\ - movs r7, 0\n\ - b _08131B92\n\ - .align 2, 0\n\ -_08131A6C: .4byte gSharedMem + 0x19348\n\ -_08131A70: .4byte gBattleAnimAttacker\n\ -_08131A74:\n\ - ldr r4, _08131AD4 @ =gBattleAnimAttacker\n\ - ldrb r0, [r4]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _08131B10\n\ - ldr r7, _08131AD8 @ =gBattlerPartyIndexes\n\ - ldrb r0, [r4]\n\ - lsls r0, 1\n\ - adds r0, r7\n\ - ldrh r0, [r0]\n\ - movs r6, 0x64\n\ - muls r0, r6\n\ - ldr r5, _08131ADC @ =gPlayerParty\n\ - adds r0, r5\n\ - movs r1, 0\n\ - bl GetMonData\n\ - mov r10, r0\n\ - ldrb r0, [r4]\n\ - lsls r0, 1\n\ - adds r0, r7\n\ - ldrh r0, [r0]\n\ - muls r0, r6\n\ - adds r0, r5\n\ - movs r1, 0x1\n\ - bl GetMonData\n\ - mov r9, r0\n\ - ldrb r2, [r4]\n\ - lsls r1, r2, 2\n\ - ldr r0, _08131AE0 @ =gSharedMem + 0x17800\n\ - adds r1, r0\n\ - ldrh r0, [r1, 0x2]\n\ - cmp r0, 0\n\ - bne _08131AE4\n\ - lsls r0, r2, 1\n\ - adds r0, r7\n\ - ldrh r0, [r0]\n\ - muls r0, r6\n\ - adds r0, r5\n\ - movs r1, 0xB\n\ - bl GetMonData\n\ - lsls r0, 16\n\ - lsrs r5, r0, 16\n\ - b _08131AE6\n\ - .align 2, 0\n\ -_08131AD4: .4byte gBattleAnimAttacker\n\ -_08131AD8: .4byte gBattlerPartyIndexes\n\ -_08131ADC: .4byte gPlayerParty\n\ -_08131AE0: .4byte gSharedMem + 0x17800\n\ -_08131AE4:\n\ - ldrh r5, [r1, 0x2]\n\ -_08131AE6:\n\ - movs r0, 0x1\n\ - bl GetAnimBattlerSpriteId\n\ - ldr r2, _08131B0C @ =gSprites\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - lsls r1, r0, 4\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - adds r1, r2\n\ - adds r1, 0x43\n\ - ldrb r0, [r1]\n\ - adds r0, 0x1\n\ - lsls r0, 24\n\ - lsrs r4, r0, 24\n\ - movs r7, 0\n\ - movs r6, 0x88\n\ - lsls r6, 1\n\ - b _08131B94\n\ - .align 2, 0\n\ -_08131B0C: .4byte gSprites\n\ -_08131B10:\n\ - ldr r7, _08131B64 @ =gBattlerPartyIndexes\n\ - ldrb r0, [r4]\n\ - lsls r0, 1\n\ - adds r0, r7\n\ - ldrh r0, [r0]\n\ - movs r6, 0x64\n\ - muls r0, r6\n\ - ldr r5, _08131B68 @ =gEnemyParty\n\ - adds r0, r5\n\ - movs r1, 0\n\ - bl GetMonData\n\ - mov r10, r0\n\ - ldrb r0, [r4]\n\ - lsls r0, 1\n\ - adds r0, r7\n\ - ldrh r0, [r0]\n\ - muls r0, r6\n\ - adds r0, r5\n\ - movs r1, 0x1\n\ - bl GetMonData\n\ - mov r9, r0\n\ - ldrb r2, [r4]\n\ - lsls r1, r2, 2\n\ - ldr r0, _08131B6C @ =gSharedMem + 0x17800\n\ - adds r1, r0\n\ - ldrh r0, [r1, 0x2]\n\ - cmp r0, 0\n\ - bne _08131B70\n\ - lsls r0, r2, 1\n\ - adds r0, r7\n\ - ldrh r0, [r0]\n\ - muls r0, r6\n\ - adds r0, r5\n\ - movs r1, 0xB\n\ - bl GetMonData\n\ - lsls r0, 16\n\ - lsrs r5, r0, 16\n\ - b _08131B72\n\ - .align 2, 0\n\ -_08131B64: .4byte gBattlerPartyIndexes\n\ -_08131B68: .4byte gEnemyParty\n\ -_08131B6C: .4byte gSharedMem + 0x17800\n\ -_08131B70:\n\ - ldrh r5, [r1, 0x2]\n\ -_08131B72:\n\ - movs r0, 0x1\n\ - bl GetAnimBattlerSpriteId\n\ - ldr r2, _08131C04 @ =gSprites\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - lsls r1, r0, 4\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - adds r1, r2\n\ - adds r1, 0x43\n\ - ldrb r0, [r1]\n\ - subs r0, 0x1\n\ - lsls r0, 24\n\ - lsrs r4, r0, 24\n\ - movs r7, 0x1\n\ -_08131B92:\n\ - ldr r6, _08131C08 @ =0x0000ffe0\n\ -_08131B94:\n\ - ldr r0, _08131C0C @ =gBattleAnimTarget\n\ - ldrb r0, [r0]\n\ - movs r1, 0x1\n\ - bl GetBattlerSpriteCoord\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - lsls r3, r6, 16\n\ - asrs r3, 16\n\ - str r0, [sp]\n\ - str r4, [sp, 0x4]\n\ - mov r4, r10\n\ - str r4, [sp, 0x8]\n\ - mov r0, r9\n\ - str r0, [sp, 0xC]\n\ - adds r0, r5, 0\n\ - adds r1, r7, 0\n\ - movs r2, 0\n\ - bl sub_8079F44\n\ - lsls r0, 24\n\ - lsrs r5, r0, 24\n\ - ldr r0, _08131C10 @ =gBattleAnimAttacker\n\ - ldrb r0, [r0]\n\ - lsls r0, 2\n\ - ldr r1, _08131C14 @ =gSharedMem + 0x17800\n\ - adds r0, r1\n\ - ldrh r0, [r0, 0x2]\n\ - cmp r0, 0\n\ - beq _08131BF2\n\ - ldr r1, _08131C04 @ =gSprites\n\ - lsls r0, r5, 4\n\ - adds r0, r5\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldrb r0, [r0, 0x5]\n\ - lsrs r0, 4\n\ - lsls r0, 4\n\ - movs r2, 0x80\n\ - lsls r2, 1\n\ - adds r1, r2, 0\n\ - orrs r0, r1\n\ - ldr r3, _08131C18 @ =0x00007fff\n\ - movs r1, 0x10\n\ - movs r2, 0x6\n\ - bl BlendPalette\n\ -_08131BF2:\n\ - ldr r0, _08131C1C @ =gTasks\n\ - mov r3, r8\n\ - lsls r1, r3, 2\n\ - add r1, r8\n\ - lsls r1, 3\n\ - adds r1, r0\n\ - strh r5, [r1, 0x26]\n\ - b _08131DB6\n\ - .align 2, 0\n\ -_08131C04: .4byte gSprites\n\ -_08131C08: .4byte 0x0000ffe0\n\ -_08131C0C: .4byte gBattleAnimTarget\n\ -_08131C10: .4byte gBattleAnimAttacker\n\ -_08131C14: .4byte gSharedMem + 0x17800\n\ -_08131C18: .4byte 0x00007fff\n\ -_08131C1C: .4byte gTasks\n\ -_08131C20:\n\ - ldr r1, _08131C6C @ =gTasks\n\ - mov r0, r8\n\ - lsls r4, r0, 2\n\ - adds r0, r4, r0\n\ - lsls r0, 3\n\ - adds r6, r0, r1\n\ - ldrh r0, [r6, 0x26]\n\ - lsls r0, 24\n\ - lsrs r5, r0, 24\n\ - movs r1, 0x80\n\ - lsls r1, 4\n\ - adds r0, r1, 0\n\ - ldrh r2, [r6, 0xA]\n\ - adds r0, r2\n\ - strh r0, [r6, 0xA]\n\ - ldr r0, _08131C70 @ =gBattleAnimAttacker\n\ - ldrb r0, [r0]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - mov r9, r4\n\ - cmp r0, 0\n\ - bne _08131C78\n\ - ldr r3, _08131C74 @ =gSprites\n\ - lsls r4, r5, 4\n\ - adds r2, r4, r5\n\ - lsls r2, 2\n\ - adds r2, r3\n\ - ldrh r1, [r6, 0xA]\n\ - lsls r1, 16\n\ - asrs r1, 24\n\ - ldrh r0, [r2, 0x24]\n\ - subs r0, r1\n\ - strh r0, [r2, 0x24]\n\ - adds r2, r3, 0\n\ - adds r3, r4, 0\n\ - b _08131C8E\n\ - .align 2, 0\n\ -_08131C6C: .4byte gTasks\n\ -_08131C70: .4byte gBattleAnimAttacker\n\ -_08131C74: .4byte gSprites\n\ -_08131C78:\n\ - ldr r2, _08131CDC @ =gSprites\n\ - lsls r3, r5, 4\n\ - adds r1, r3, r5\n\ - lsls r1, 2\n\ - adds r1, r2\n\ - ldrh r0, [r6, 0xA]\n\ - lsls r0, 16\n\ - asrs r0, 24\n\ - ldrh r4, [r1, 0x24]\n\ - adds r0, r4\n\ - strh r0, [r1, 0x24]\n\ -_08131C8E:\n\ - ldr r1, _08131CE0 @ =gTasks\n\ - mov r0, r9\n\ - add r0, r8\n\ - lsls r0, 3\n\ - adds r6, r0, r1\n\ - ldrb r0, [r6, 0xA]\n\ - strh r0, [r6, 0xA]\n\ - adds r1, r3, r5\n\ - lsls r1, 2\n\ - adds r1, r2\n\ - ldrh r0, [r1, 0x24]\n\ - ldrh r1, [r1, 0x20]\n\ - adds r0, r1\n\ - lsls r0, 16\n\ - lsrs r5, r0, 16\n\ - movs r1, 0x24\n\ - ldrsh r0, [r6, r1]\n\ - cmp r0, 0\n\ - bne _08131D0E\n\ - ldr r0, _08131CE4 @ =gBattleAnimAttacker\n\ - ldrb r0, [r0]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _08131CEC\n\ - lsls r4, r5, 16\n\ - asrs r4, 16\n\ - ldr r0, _08131CE8 @ =gBattleAnimTarget\n\ - ldrb r0, [r0]\n\ - movs r1, 0\n\ - bl GetBattlerSpriteCoord\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r4, r0\n\ - bge _08131D0E\n\ - b _08131D02\n\ - .align 2, 0\n\ -_08131CDC: .4byte gSprites\n\ -_08131CE0: .4byte gTasks\n\ -_08131CE4: .4byte gBattleAnimAttacker\n\ -_08131CE8: .4byte gBattleAnimTarget\n\ -_08131CEC:\n\ - lsls r4, r5, 16\n\ - asrs r4, 16\n\ - ldr r0, _08131D30 @ =gBattleAnimTarget\n\ - ldrb r0, [r0]\n\ - movs r1, 0\n\ - bl GetBattlerSpriteCoord\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r4, r0\n\ - ble _08131D0E\n\ -_08131D02:\n\ - ldrh r0, [r6, 0x24]\n\ - adds r0, 0x1\n\ - strh r0, [r6, 0x24]\n\ - ldr r1, _08131D34 @ =gBattleAnimArgs\n\ - ldr r0, _08131D38 @ =0x0000ffff\n\ - strh r0, [r1, 0xE]\n\ -_08131D0E:\n\ - lsls r0, r5, 16\n\ - movs r2, 0x80\n\ - lsls r2, 14\n\ - adds r0, r2\n\ - movs r1, 0x98\n\ - lsls r1, 17\n\ - cmp r0, r1\n\ - bhi _08131D20\n\ - b _08131EA0\n\ -_08131D20:\n\ - ldr r0, _08131D3C @ =gTasks\n\ - mov r1, r9\n\ - add r1, r8\n\ - lsls r1, 3\n\ - adds r1, r0\n\ - movs r0, 0\n\ - strh r0, [r1, 0xA]\n\ - b _08131DB6\n\ - .align 2, 0\n\ -_08131D30: .4byte gBattleAnimTarget\n\ -_08131D34: .4byte gBattleAnimArgs\n\ -_08131D38: .4byte 0x0000ffff\n\ -_08131D3C: .4byte gTasks\n\ -_08131D40:\n\ - movs r0, 0\n\ - bl GetAnimBattlerSpriteId\n\ - lsls r0, 24\n\ - lsrs r7, r0, 24\n\ - ldr r1, _08131D8C @ =gTasks\n\ - mov r3, r8\n\ - lsls r4, r3, 2\n\ - adds r0, r4, r3\n\ - lsls r0, 3\n\ - adds r0, r1\n\ - ldrh r0, [r0, 0x26]\n\ - lsls r0, 24\n\ - lsrs r5, r0, 24\n\ - lsls r0, r5, 4\n\ - adds r0, r5\n\ - lsls r0, 2\n\ - ldr r5, _08131D90 @ =gSprites\n\ - adds r0, r5\n\ - bl DestroySpriteAndFreeResources_\n\ - ldr r0, _08131D94 @ =gBattleAnimAttacker\n\ - ldrb r0, [r0]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - mov r9, r4\n\ - cmp r0, 0\n\ - bne _08131D98\n\ - lsls r1, r7, 4\n\ - adds r1, r7\n\ - lsls r1, 2\n\ - adds r1, r5\n\ - ldrh r0, [r1, 0x20]\n\ - negs r0, r0\n\ - subs r0, 0x20\n\ - strh r0, [r1, 0x24]\n\ - b _08131DAC\n\ - .align 2, 0\n\ -_08131D8C: .4byte gTasks\n\ -_08131D90: .4byte gSprites\n\ -_08131D94: .4byte gBattleAnimAttacker\n\ -_08131D98:\n\ - lsls r0, r7, 4\n\ - adds r0, r7\n\ - lsls r0, 2\n\ - adds r0, r5\n\ - ldrh r2, [r0, 0x20]\n\ - movs r4, 0x88\n\ - lsls r4, 1\n\ - adds r1, r4, 0\n\ - subs r1, r2\n\ - strh r1, [r0, 0x24]\n\ -_08131DAC:\n\ - ldr r0, _08131DC0 @ =gTasks\n\ - mov r1, r9\n\ - add r1, r8\n\ - lsls r1, 3\n\ - adds r1, r0\n\ -_08131DB6:\n\ - ldrh r0, [r1, 0x8]\n\ - adds r0, 0x1\n\ - strh r0, [r1, 0x8]\n\ - b _08131EA0\n\ - .align 2, 0\n\ -_08131DC0: .4byte gTasks\n\ -_08131DC4:\n\ - movs r0, 0\n\ - bl GetAnimBattlerSpriteId\n\ - lsls r0, 24\n\ - lsrs r7, r0, 24\n\ - ldr r1, _08131E38 @ =gTasks\n\ - mov r0, r8\n\ - lsls r4, r0, 2\n\ - adds r0, r4, r0\n\ - lsls r0, 3\n\ - adds r2, r0, r1\n\ - movs r1, 0x80\n\ - lsls r1, 4\n\ - adds r0, r1, 0\n\ - ldrh r3, [r2, 0xA]\n\ - adds r0, r3\n\ - strh r0, [r2, 0xA]\n\ - ldr r0, _08131E3C @ =gBattleAnimAttacker\n\ - mov r10, r0\n\ - ldrb r0, [r0]\n\ - str r2, [sp, 0x10]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - mov r9, r4\n\ - ldr r2, [sp, 0x10]\n\ - cmp r0, 0\n\ - bne _08131E44\n\ - ldr r1, _08131E40 @ =gSprites\n\ - lsls r5, r7, 4\n\ - adds r0, r5, r7\n\ - lsls r0, 2\n\ - adds r6, r0, r1\n\ - ldrh r0, [r2, 0xA]\n\ - lsls r0, 16\n\ - asrs r0, 24\n\ - ldrh r1, [r6, 0x24]\n\ - adds r0, r1\n\ - strh r0, [r6, 0x24]\n\ - movs r2, 0x24\n\ - ldrsh r4, [r6, r2]\n\ - movs r3, 0x20\n\ - ldrsh r0, [r6, r3]\n\ - adds r4, r0\n\ - mov r1, r10\n\ - ldrb r0, [r1]\n\ - movs r1, 0\n\ - bl GetBattlerSpriteCoord\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - adds r3, r5, 0\n\ - cmp r4, r0\n\ - blt _08131E7C\n\ - movs r2, 0\n\ - strh r2, [r6, 0x24]\n\ - b _08131E7C\n\ - .align 2, 0\n\ -_08131E38: .4byte gTasks\n\ -_08131E3C: .4byte gBattleAnimAttacker\n\ -_08131E40: .4byte gSprites\n\ -_08131E44:\n\ - ldr r1, _08131EB0 @ =gSprites\n\ - lsls r5, r7, 4\n\ - adds r0, r5, r7\n\ - lsls r0, 2\n\ - adds r6, r0, r1\n\ - ldrh r1, [r2, 0xA]\n\ - lsls r1, 16\n\ - asrs r1, 24\n\ - ldrh r0, [r6, 0x24]\n\ - subs r0, r1\n\ - strh r0, [r6, 0x24]\n\ - movs r3, 0x24\n\ - ldrsh r4, [r6, r3]\n\ - movs r1, 0x20\n\ - ldrsh r0, [r6, r1]\n\ - adds r4, r0\n\ - mov r2, r10\n\ - ldrb r0, [r2]\n\ - movs r1, 0\n\ - bl GetBattlerSpriteCoord\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - adds r3, r5, 0\n\ - cmp r4, r0\n\ - bgt _08131E7C\n\ - movs r4, 0\n\ - strh r4, [r6, 0x24]\n\ -_08131E7C:\n\ - ldr r1, _08131EB4 @ =gTasks\n\ - mov r0, r9\n\ - add r0, r8\n\ - lsls r0, 3\n\ - adds r0, r1\n\ - ldrb r1, [r0, 0xA]\n\ - strh r1, [r0, 0xA]\n\ - ldr r1, _08131EB0 @ =gSprites\n\ - adds r0, r3, r7\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - movs r1, 0x24\n\ - ldrsh r0, [r0, r1]\n\ - cmp r0, 0\n\ - bne _08131EA0\n\ - mov r0, r8\n\ - bl DestroyAnimVisualTask\n\ -_08131EA0:\n\ - add sp, 0x14\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_08131EB0: .4byte gSprites\n\ -_08131EB4: .4byte gTasks\n\ - .syntax divided"); -} -#endif // NONMATCHING - -void sub_8131EB8(struct Sprite *sprite) -{ - switch (sprite->data[7]) - { - case 0: - if (gBattleAnimArgs[7] == -1) - { - PlaySE12WithPanning(SE_W233, BattleAnimAdjustPanning(63)); - sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 16; - sprite->data[0] = -32; - sprite->data[7]++; - sprite->invisible = 0; - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT && !IsContest()) - sprite->subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_BATTLER_TARGET)].subpriority - 1; - } - else - { - sprite->invisible = 1; - } - break; - case 1: - sprite->pos2.y = Sin(sprite->data[1], sprite->data[0]); - sprite->data[1] += 5; - if (sprite->data[1] > 0x7F) - { - sprite->data[0] = sprite->data[0] / 2; - sprite->data[3]++; - sprite->data[1] -= 0x7F; - } - - sprite->data[2] += 0x100; - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - sprite->pos2.x -= (sprite->data[2] >> 8); - else - sprite->pos2.x += (sprite->data[2] >> 8); - - sprite->data[2] &= 0xFF; - if (sprite->data[3] == 2) - DestroyAnimSprite(sprite); - break; - } -} - -// Quickly moves the mon towards its partner and back. -// No args. -void AnimTask_SnatchPartnerMove(u8 taskId) -{ - s16 attackerX, targetX; - u8 spriteId; - - switch (gTasks[taskId].data[15]) - { - case 0: - attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X); - targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X); - gTasks[taskId].data[0] = 6; - if (attackerX > targetX) - gTasks[taskId].data[0] *= -1; - - gTasks[taskId].data[1] = attackerX; - gTasks[taskId].data[2] = targetX; - gTasks[taskId].data[15]++; - break; - case 1: - spriteId = gBankSpriteIds[gBattleAnimAttacker]; - gSprites[spriteId].pos2.x += gTasks[taskId].data[0]; - if (gTasks[taskId].data[0] > 0) - { - if (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x >= gTasks[taskId].data[2]) - gTasks[taskId].data[15]++; - } - else - { - if (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x <= gTasks[taskId].data[2]) - gTasks[taskId].data[15]++; - } - break; - case 2: - gTasks[taskId].data[0] *= -1; - gTasks[taskId].data[15]++; - break; - case 3: - spriteId = gBankSpriteIds[gBattleAnimAttacker]; - gSprites[spriteId].pos2.x += gTasks[taskId].data[0]; - if (gTasks[taskId].data[0] < 0) - { - if (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x <= gTasks[taskId].data[1]) - gTasks[taskId].data[15]++; - } - else - { - if (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x >= gTasks[taskId].data[1]) - gTasks[taskId].data[15]++; - } - break; - case 4: - default: - spriteId = gBankSpriteIds[gBattleAnimAttacker]; - gSprites[spriteId].pos2.x = 0; - DestroyAnimVisualTask(taskId); - break; - } -} - -// Moves the mon's sprite back and forth in an unpredictable swaying motion. -// No args. -void AnimTask_TeeterDanceMovement(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - task->data[3] = GetAnimBattlerSpriteId(ANIM_BATTLER_ATTACKER); - task->data[4] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER ? 1 : -1; - task->data[6] = gSprites[task->data[3]].pos1.y; - task->data[5] = gSprites[task->data[3]].pos1.x; - task->data[9] = 0; - task->data[11] = 0; - task->data[10] = 1; - task->data[12] = 0; - task->func = AnimTask_TeeterDanceMovementStep; -} - -static void AnimTask_TeeterDanceMovementStep(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - switch (task->data[0]) - { - case 0: - task->data[11] += 8; - task->data[11] &= 0xFF; - gSprites[task->data[3]].pos2.x = gSineTable[task->data[11]] >> 5; - task->data[9] += 2; - task->data[9] &= 0xFF; - gSprites[task->data[3]].pos1.x = (gSineTable[task->data[9]] >> 3) * task->data[4] + task->data[5]; - if (task->data[9] == 0) - { - gSprites[task->data[3]].pos1.x = task->data[5]; - task->data[0]++; - } - break; - case 1: - task->data[11] += 8; - task->data[11] &= 0xFF; - gSprites[task->data[3]].pos2.x = gSineTable[task->data[11]] >> 5; - if (task->data[11] == 0) - { - gSprites[task->data[3]].pos2.x = 0; - task->data[0]++; - } - break; - case 2: - DestroyAnimVisualTask(taskId); - break; - } -} - -static void AnimKnockOffStrikeStep(struct Sprite *sprite) -{ - // These two cases are identical. - if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) - { - sprite->data[1] += sprite->data[0]; - sprite->data[1] &= 0xFF; - } - else - { - sprite->data[1] += sprite->data[0]; - sprite->data[1] &= 0xFF; - } - - sprite->pos2.x = Cos(sprite->data[1], 20); - sprite->pos2.y = Sin(sprite->data[1], 20); - if (sprite->animEnded) - DestroyAnimSprite(sprite); - - sprite->data[2]++; -} - -// Animates a strike that swipes downard at the target mon. -// arg 0: initial x pixel offset -// arg 1: initial y pixel offset -void AnimKnockOffStrike(struct Sprite *sprite) -{ - if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) - { - sprite->pos1.x -= gBattleAnimArgs[0]; - sprite->pos1.y += gBattleAnimArgs[1]; - sprite->data[0] = -11; - sprite->data[1] = 192; - StartSpriteAffineAnim(sprite, 1); - } - else - { - sprite->data[0] = 11; - sprite->data[1] = 192; - sprite->pos1.x += gBattleAnimArgs[0]; - sprite->pos1.y += gBattleAnimArgs[1]; - } - - sprite->callback = AnimKnockOffStrikeStep; -} - -// Gradually fades a rotating recyle arrow sprite in and back out. -// No args. -void AnimRecycle(struct Sprite *sprite) -{ - sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); - sprite->pos1.y = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP); - if (sprite->pos1.y < 16) - sprite->pos1.y = 16; - - sprite->data[6] = 0; - sprite->data[7] = 16; - sprite->callback = AnimRecycleStep; - REG_BLDALPHA = BLDALPHA_BLEND(sprite->data[6], sprite->data[7]); -} - -static void AnimRecycleStep(struct Sprite *sprite) -{ - switch (sprite->data[2]) - { - case 0: - if (++sprite->data[0] > 1) - { - sprite->data[0] = 0; - if (!(sprite->data[1] & 1)) - { - if (sprite->data[6] < 16) - sprite->data[6]++; - } - else - { - if (sprite->data[7] != 0) - sprite->data[7]--; - } - - sprite->data[1]++; - REG_BLDALPHA = BLDALPHA_BLEND(sprite->data[6], sprite->data[7]); - if (sprite->data[7] == 0) - sprite->data[2]++; - } - break; - case 1: - if (++sprite->data[0] == 10) - { - sprite->data[0] = 0; - sprite->data[1] = 0; - sprite->data[2]++; - } - break; - case 2: - if (++sprite->data[0] > 1) - { - sprite->data[0] = 0; - if (!(sprite->data[1] & 1)) - { - if (sprite->data[6] != 0) - sprite->data[6]--; - } - else - { - if (sprite->data[7] < 16) - sprite->data[7]++; - } - - sprite->data[1]++; - REG_BLDALPHA = BLDALPHA_BLEND(sprite->data[6], sprite->data[7]); - if (sprite->data[7] == 16) - sprite->data[2]++; - } - break; - case 3: - DestroySpriteAndMatrix(sprite); - break; - } -} - -void AnimTask_GetWeather(u8 taskId) -{ - gBattleAnimArgs[7] = ANIM_WEATHER_NONE; - if (gWeatherMoveAnim & WEATHER_SUN_ANY) - gBattleAnimArgs[7] = ANIM_WEATHER_SUN; - else if (gWeatherMoveAnim & WEATHER_RAIN_ANY) - gBattleAnimArgs[7] = ANIM_WEATHER_RAIN; - else if (gWeatherMoveAnim & WEATHER_SANDSTORM_ANY) - gBattleAnimArgs[7] = ANIM_WEATHER_SANDSTORM; - else if (gWeatherMoveAnim & WEATHER_HAIL_ANY) - gBattleAnimArgs[7] = ANIM_WEATHER_HAIL; - - DestroyAnimVisualTask(taskId); -} - -// Squishes the mon sprite vertically, and shakes it back and forth. -// arg 0: which battler -void AnimTask_SlackOffSquish(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - task->data[0] = 0; - task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); - PrepareAffineAnimInTaskData(task, task->data[15], gSlackOffSquishAffineAnimCmds); - task->func = AnimTask_SlackOffSquishStep; -} - -static void AnimTask_SlackOffSquishStep(u8 taskId) -{ - struct Task *task = &gTasks[taskId]; - - gTasks[taskId].data[0]++; - if (gTasks[taskId].data[0] > 16 && gTasks[taskId].data[0] < 40) - { - if (++task->data[1] > 2) - { - task->data[1] = 0; - task->data[2]++; - if (!(task->data[2] & 1)) - gSprites[task->data[15]].pos2.x = -1; - else - gSprites[task->data[15]].pos2.x = 1; - } - } - else - { - gSprites[task->data[15]].pos2.x = 0; - } - - if (!RunAffineAnimFromTaskData(&gTasks[taskId])) - DestroyAnimVisualTask(taskId); -} \ No newline at end of file diff --git a/src/battle/battle_anim_813F0F4.c b/src/battle/battle_anim_813F0F4.c deleted file mode 100755 index 9ea0585d1..000000000 --- a/src/battle/battle_anim_813F0F4.c +++ /dev/null @@ -1,2170 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_anim.h" -#include "battle_anim_813F0F4.h" -#include "battle_interface.h" -#include "blend_palette.h" -#include "decompress.h" -#include "ewram.h" -#include "m4a.h" -#include "main.h" -#include "palette.h" -#include "pokeball.h" -#include "rom_8077ABC.h" -#include "sound.h" -#include "sprite.h" -#include "task.h" -#include "trig.h" -#include "util.h" -#include "constants/items.h" -#include "constants/songs.h" - -extern int gUnknown_03005F0C; -extern u16 gUnknown_03005F10; -extern u16 gUnknown_03005F14; - -extern s16 gBattleAnimArgs[]; -extern u8 gBattleAnimAttacker; -extern u8 gBattleAnimTarget; -extern u8 gHealthboxIDs[]; -extern u8 gBankSpriteIds[]; -extern u16 gBattlerPartyIndexes[]; -extern u16 gLastUsedItem; -extern u8 gDoingBattleAnim; -extern u8 gEffectBank; - -extern const u8 gUnknown_08D2EE48[]; -extern const u8 gUnknown_08D2EDFC[]; -extern const u16 gUnknown_08D2E150[]; -extern const struct SpriteTemplate gSpriteTemplates_840B3B4[]; -extern const struct SpriteTemplate gSpriteTemplate_8402500; -extern const struct SpriteTemplate gBattleAnimSpriteTemplate_84024E8; -extern const struct CompressedSpriteSheet gBattleAnimPicTable[]; -extern const struct CompressedSpritePalette gBattleAnimPaletteTable[]; - -static void sub_813F300(u8 taskId); -static void sub_813F6CC(u8 taskId); -static void sub_813FD34(u8 taskId); -static void sub_813FD90(struct Sprite *sprite); -static void sub_813FB7C(u8 taskId); -static void sub_813FCBC(u8 taskId); -static void sub_813FDC0(struct Sprite *sprite); -static void sub_813FE70(struct Sprite *sprite); -static void sub_81407B8(struct Sprite *sprite); -static void sub_813FEC8(struct Sprite *sprite); -static void sub_8140014(struct Sprite *sprite); -static void sub_8140058(struct Sprite *sprite); -static void sub_8140410(struct Sprite *sprite); -static void sub_8140158(struct Sprite *sprite); -static void sub_81401A0(struct Sprite *sprite); -static void sub_8140434(struct Sprite *sprite); -static void sub_81405F4(struct Sprite *sprite); -static void sub_8140454(struct Sprite *sprite); -static void sub_81404E4(struct Sprite *sprite); -static void sub_81405C8(struct Sprite *sprite); -static void sub_81406BC(struct Sprite *sprite); -static void sub_81407F4(struct Sprite *sprite); -static void PokeBallOpenParticleAnimation_Step1(struct Sprite *sprite); -static void PokeBallOpenParticleAnimation_Step2(struct Sprite *sprite); -static void DestroyBallOpenAnimationParticle(struct Sprite *sprite); -static void FanOutBallOpenParticles_Step1(struct Sprite *sprite); -static void RepeatBallOpenParticleAnimation_Step1(struct Sprite *sprite); -static void PremierBallOpenParticleAnimation_Step1(struct Sprite *sprite); -static void sub_81413DC(u8 taskId); -static void sub_814146C(u8 taskId); -static void sub_81414BC(u8 taskId); -static void sub_814191C(u8 taskId); -static void sub_8141B20(struct Sprite *sprite); -static void sub_8141B74(struct Sprite *sprite); -static void sub_8141AD8(u8 taskId); -static void sub_8141CBC(struct Sprite *sprite); -static void sub_8141CF4(struct Sprite *sprite); -static void sub_8141D20(struct Sprite *sprite); - -extern const u8 gBattleAnimSpriteSheet_Particles[]; -const struct CompressedSpriteSheet gBallOpenParticleSpritesheets[] = -{ - {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6EC}, - {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6ED}, - {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6EE}, - {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6EF}, - {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F0}, - {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F1}, - {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F2}, - {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F3}, - {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F4}, - {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F5}, - {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F6}, - {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F7}, -}; - -extern const u8 gBattleAnimSpritePalette_136[]; -const struct CompressedSpritePalette gBallOpenParticlePalettes[] = -{ - {gBattleAnimSpritePalette_136, 0xD6EC}, - {gBattleAnimSpritePalette_136, 0xD6ED}, - {gBattleAnimSpritePalette_136, 0xD6EE}, - {gBattleAnimSpritePalette_136, 0xD6EF}, - {gBattleAnimSpritePalette_136, 0xD6F0}, - {gBattleAnimSpritePalette_136, 0xD6F1}, - {gBattleAnimSpritePalette_136, 0xD6F2}, - {gBattleAnimSpritePalette_136, 0xD6F3}, - {gBattleAnimSpritePalette_136, 0xD6F4}, - {gBattleAnimSpritePalette_136, 0xD6F5}, - {gBattleAnimSpritePalette_136, 0xD6F6}, - {gBattleAnimSpritePalette_136, 0xD6F7}, -}; - -const union AnimCmd gSpriteAnim_840B318[] = -{ - ANIMCMD_FRAME(0, 1), - ANIMCMD_FRAME(1, 1), - ANIMCMD_FRAME(2, 1), - ANIMCMD_FRAME(0, 1, .hFlip = TRUE), - ANIMCMD_FRAME(2, 1), - ANIMCMD_FRAME(1, 1), - ANIMCMD_JUMP(0), -}; - -const union AnimCmd gSpriteAnim_840B334[] = -{ - ANIMCMD_FRAME(3, 1), - ANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_840B33C[] = -{ - ANIMCMD_FRAME(4, 1), - ANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_840B344[] = -{ - ANIMCMD_FRAME(5, 1), - ANIMCMD_END, -}; - -const union AnimCmd gSpriteAnim_840B34C[] = -{ - ANIMCMD_FRAME(6, 4), - ANIMCMD_FRAME(7, 4), - ANIMCMD_JUMP(0), -}; - -const union AnimCmd gSpriteAnim_840B358[] = -{ - ANIMCMD_FRAME(7, 4), - ANIMCMD_END, -}; - -const union AnimCmd *const gSpriteAnimTable_840B360[] = -{ - gSpriteAnim_840B318, - gSpriteAnim_840B334, - gSpriteAnim_840B33C, - gSpriteAnim_840B344, - gSpriteAnim_840B34C, - gSpriteAnim_840B358, -}; - -const u8 gBallOpenParticleAnimNums[] = -{ - 0, - 0, - 0, - 5, - 1, - 2, - 2, - 3, - 5, - 5, - 4, - 4, -}; - -void PokeBallOpenParticleAnimation(u8); -void GreatBallOpenParticleAnimation(u8); -void SafariBallOpenParticleAnimation(u8); -void UltraBallOpenParticleAnimation(u8); -void MasterBallOpenParticleAnimation(u8); -void SafariBallOpenParticleAnimation(u8); -void DiveBallOpenParticleAnimation(u8); -void UltraBallOpenParticleAnimation(u8); -void RepeatBallOpenParticleAnimation(u8); -void TimerBallOpenParticleAnimation(u8); -void GreatBallOpenParticleAnimation(u8); -void PremierBallOpenParticleAnimation(u8); - -const TaskFunc gBallOpenParticleAnimationFuncs[] = -{ - PokeBallOpenParticleAnimation, - GreatBallOpenParticleAnimation, - SafariBallOpenParticleAnimation, - UltraBallOpenParticleAnimation, - MasterBallOpenParticleAnimation, - SafariBallOpenParticleAnimation, - DiveBallOpenParticleAnimation, - UltraBallOpenParticleAnimation, - RepeatBallOpenParticleAnimation, - TimerBallOpenParticleAnimation, - GreatBallOpenParticleAnimation, - PremierBallOpenParticleAnimation, -}; - -const struct SpriteTemplate gSpriteTemplates_840B3B4[] = -{ - { - .tileTag = 55020, - .paletteTag = 55020, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_840B360, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55021, - .paletteTag = 55021, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_840B360, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55022, - .paletteTag = 55022, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_840B360, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55023, - .paletteTag = 55023, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_840B360, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55024, - .paletteTag = 55024, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_840B360, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55025, - .paletteTag = 55025, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_840B360, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55026, - .paletteTag = 55026, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_840B360, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55027, - .paletteTag = 55027, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_840B360, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55028, - .paletteTag = 55028, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_840B360, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55029, - .paletteTag = 55029, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_840B360, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55030, - .paletteTag = 55030, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_840B360, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55031, - .paletteTag = 55031, - .oam = &gOamData_837DF24, - .anims = gSpriteAnimTable_840B360, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, -}; - -const u16 gUnknown_0840B4D4[] = -{ - 0x7ADF, - 0x7AF0, - 0x53D7, - 0x3FFF, - 0x7297, - 0x67F5, - 0x7B2C, - 0x2B7E, - 0x431F, - 0x7BDD, - 0x2A3F, - 0x293F, - 0x0000, - 0x0201, - 0x0403, - 0x0101, - 0x0100, - 0x0503, - 0x0506, - 0x0004, -}; - -static void sub_8141C30(struct Sprite *sprite); -const struct SpriteTemplate gBattleAnimSpriteTemplate_840B4FC = -{ - .tileTag = ANIM_TAG_UNUSED_RED_BRICK, - .paletteTag = ANIM_TAG_UNUSED_RED_BRICK, - .oam = &gOamData_837DF2C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8141C30, -}; - -void unref_sub_813F0F4(u8 taskId) -{ - struct Struct_sub_8078914 subStruct; - u8 healthBoxSpriteId; - u8 battler; - u8 spriteId1, spriteId2, spriteId3, spriteId4; - - battler = gBattleAnimAttacker; - gBattle_WIN0H = 0; - gBattle_WIN0V = 0; - REG_WININ = 0x3F3F; - REG_WINOUT = 0x3F3D; - REG_DISPCNT |= DISPCNT_OBJWIN_ON; - REG_BLDCNT = 0x3F42; - REG_BLDALPHA = 0x1000; - REG_BG1CNT_BITFIELD.priority = 0; - REG_BG1CNT_BITFIELD.screenSize = 0; - REG_BG1CNT_BITFIELD.areaOverflowMode = 1; - REG_BG1CNT_BITFIELD.charBaseBlock = 1; - - healthBoxSpriteId = gHealthboxIDs[battler]; - spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam; - spriteId2 = gSprites[healthBoxSpriteId].data[5]; - spriteId3 = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy); - spriteId4 = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy); - gSprites[healthBoxSpriteId].oam.priority = 1; - gSprites[spriteId1].oam.priority = 1; - gSprites[spriteId2].oam.priority = 1; - gSprites[spriteId3] = gSprites[healthBoxSpriteId]; - gSprites[spriteId4] = gSprites[spriteId1]; - gSprites[spriteId3].oam.objMode = ST_OAM_OBJ_WINDOW; - gSprites[spriteId4].oam.objMode = ST_OAM_OBJ_WINDOW; - gSprites[spriteId3].callback = SpriteCallbackDummy; - gSprites[spriteId4].callback = SpriteCallbackDummy; - - sub_8078914(&subStruct); - DmaFill32Defvars(3, 0, subStruct.field_4, 0x1000); - LZDecompressVram(&gUnknown_08D2EE48, subStruct.field_4); - LZDecompressVram(&gUnknown_08D2EDFC, subStruct.field_0); - LoadCompressedPalette(gUnknown_08D2E150, subStruct.field_8 << 4, 32); - - gBattle_BG1_X = -gSprites[spriteId3].pos1.x + 32; - gBattle_BG1_Y = -gSprites[spriteId3].pos1.y - 32; - gTasks[taskId].data[1] = 640; - gTasks[taskId].data[0] = spriteId3; - gTasks[taskId].data[2] = spriteId4; - gTasks[taskId].func = sub_813F300; -} - -static void sub_813F300(u8 taskId) -{ - struct Struct_sub_8078914 subStruct; - u8 spriteId1, spriteId2; - u8 battler; - - battler = gBattleAnimAttacker; - gTasks[taskId].data[13] += gTasks[taskId].data[1]; - gBattle_BG1_Y += (u16)gTasks[taskId].data[13] >> 8; - gTasks[taskId].data[13] &= 0xFF; - - switch (gTasks[taskId].data[15]) - { - case 0: - if (gTasks[taskId].data[11]++ > 1) - { - gTasks[taskId].data[11] = 0; - gTasks[taskId].data[12]++; - REG_BLDALPHA = ((16 - gTasks[taskId].data[12]) << 8) | gTasks[taskId].data[12]; - if (gTasks[taskId].data[12] == 8) - gTasks[taskId].data[15]++; - } - break; - case 1: - if (++gTasks[taskId].data[10] == 30) - gTasks[taskId].data[15]++; - break; - case 2: - if (gTasks[taskId].data[11]++ > 1) - { - gTasks[taskId].data[11] = 0; - gTasks[taskId].data[12]--; - REG_BLDALPHA = ((16 - gTasks[taskId].data[12]) << 8) | gTasks[taskId].data[12]; - if (gTasks[taskId].data[12] == 0) - { - sub_8076464(0); - gBattle_WIN0H = 0; - gBattle_WIN0V = 0; - REG_WININ = 0x3F3F; - REG_WINOUT = 0x3F3F; - if (!IsContest()) - REG_BG1CNT_BITFIELD.charBaseBlock = 0; - - REG_DISPCNT ^= DISPCNT_OBJWIN_ON; - REG_BLDCNT = 0; - REG_BLDALPHA = 0; - DestroySprite(&gSprites[gTasks[taskId].data[0]]); - DestroySprite(&gSprites[gTasks[taskId].data[2]]); - sub_8078914(&subStruct); - DmaFill32Defvars(3, 0, subStruct.field_4, 0x800); - REG_BG1CNT_BITFIELD.areaOverflowMode = 0; - spriteId1 = gSprites[gHealthboxIDs[battler]].oam.affineParam; - spriteId2 = gSprites[gHealthboxIDs[battler]].data[5]; - gSprites[gHealthboxIDs[battler]].oam.priority = 1; - gSprites[spriteId1].oam.priority = 1; - gSprites[spriteId2].oam.priority = 1; - DestroyAnimVisualTask(taskId); - } - } - break; - } -} - -void sub_813F4EC(u8 taskId) -{ - u8 healthBoxSpriteId; - u8 spriteId1, spriteId2; - u8 paletteNum1, paletteNum2; - u16 offset1, offset2; - - healthBoxSpriteId = gHealthboxIDs[gBattleAnimAttacker]; - spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam; - spriteId2 = gSprites[healthBoxSpriteId].data[5]; - paletteNum1 = AllocSpritePalette(0xD709); - paletteNum2 = AllocSpritePalette(0xD70A); - - offset1 = (gSprites[healthBoxSpriteId].oam.paletteNum * 16) + 0x100; - offset2 = (gSprites[spriteId2].oam.paletteNum * 16) + 0x100; - LoadPalette(&gPlttBufferUnfaded[offset1], paletteNum1 * 16 + 0x100, 0x20); - LoadPalette(&gPlttBufferUnfaded[offset2], paletteNum2 * 16 + 0x100, 0x20); - - gSprites[healthBoxSpriteId].oam.paletteNum = paletteNum1; - gSprites[spriteId1].oam.paletteNum = paletteNum1; - gSprites[spriteId2].oam.paletteNum = paletteNum2; - DestroyAnimVisualTask(taskId); -} - -void sub_813F5E8(u8 taskId) -{ - u8 healthBoxSpriteId; - u8 spriteId1, spriteId2; - u8 paletteIndex1, paletteIndex2; - - healthBoxSpriteId = gHealthboxIDs[gBattleAnimAttacker]; - spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam; - spriteId2 = gSprites[healthBoxSpriteId].data[5]; - - FreeSpritePaletteByTag(0xD709); - FreeSpritePaletteByTag(0xD70A); - paletteIndex1 = IndexOfSpritePaletteTag(0xD6FF); - paletteIndex2 = IndexOfSpritePaletteTag(0xD704); - gSprites[healthBoxSpriteId].oam.paletteNum = paletteIndex1; - gSprites[spriteId1].oam.paletteNum = paletteIndex1; - gSprites[spriteId2].oam.paletteNum = paletteIndex2; - - DestroyAnimVisualTask(taskId); -} - -void sub_813F6A0(u8 taskId) -{ - gTasks[taskId].data[10] = gBattleAnimArgs[0]; - gTasks[taskId].data[11] = gBattleAnimArgs[1]; - gTasks[taskId].func = sub_813F6CC; -} - -static void sub_813F6CC(u8 taskId) -{ - u8 paletteNum; - int paletteOffset, colorOffset; - - gTasks[taskId].data[0]++; - if (gTasks[taskId].data[0]++ >= gTasks[taskId].data[11]) - { - gTasks[taskId].data[0] = 0; - paletteNum = IndexOfSpritePaletteTag(0xD709); - colorOffset = gTasks[taskId].data[10] == 0 ? 6 : 2; - switch (gTasks[taskId].data[1]) - { - case 0: - gTasks[taskId].data[2] += 2; - if (gTasks[taskId].data[2] > 16) - gTasks[taskId].data[2] = 16; - - paletteOffset = paletteNum * 16 + 0x100; - BlendPalette(paletteOffset + colorOffset, 1, gTasks[taskId].data[2], RGB(20, 27, 31)); - if (gTasks[taskId].data[2] == 16) - gTasks[taskId].data[1]++; - break; - case 1: - gTasks[taskId].data[2] -= 2; - if (gTasks[taskId].data[2] < 0) - gTasks[taskId].data[2] = 0; - - paletteOffset = paletteNum * 16 + 0x100; - BlendPalette(paletteOffset + colorOffset, 1, gTasks[taskId].data[2], RGB(20, 27, 31)); - if (gTasks[taskId].data[2] == 0) - DestroyAnimVisualTask(taskId); - break; - } - } -} - -void sub_813F798(u8 taskId) -{ - u8 spriteId; - - spriteId = gBankSpriteIds[gBattleAnimAttacker]; - switch (gTasks[taskId].data[0]) - { - case 0: - PrepareBattlerSpriteForRotScale(spriteId, 0); - gTasks[taskId].data[10] = 0x100; - gTasks[taskId].data[0]++; - break; - case 1: - gTasks[taskId].data[10] += 0x30; - obj_id_set_rotscale(spriteId, gTasks[taskId].data[10], gTasks[taskId].data[10], 0); - sub_8079A64(spriteId); - if (gTasks[taskId].data[10] >= 0x2D0) - gTasks[taskId].data[0]++; - break; - case 2: - sub_8078F40(spriteId); - gSprites[spriteId].invisible = 1; - DestroyAnimVisualTask(taskId); - break; - } -} - -void sub_813F844(u8 taskId) -{ - u8 spriteId; - u16 ball; - u8 ballIndex; - u8 x, y; - u8 priority, subpriority; - u32 selectedPalettes; - - spriteId = gBankSpriteIds[gBattleAnimAttacker]; - if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) - ball = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_POKEBALL); - else - ball = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_POKEBALL); - - ballIndex = ball_number_to_ball_processing_index(ball); - switch (gTasks[taskId].data[0]) - { - case 0: - x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); - y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); - priority = gSprites[spriteId].oam.priority; - subpriority = gSprites[spriteId].subpriority; - gTasks[taskId].data[10] = AnimateBallOpenParticles(x, y + 32, priority, subpriority, ballIndex); - selectedPalettes = sub_80791A8(1, 0, 0, 0, 0, 0, 0); - gTasks[taskId].data[11] = sub_8141314(0, gBattleAnimAttacker, selectedPalettes, ballIndex); - gTasks[taskId].data[0]++; - break; - case 1: - if (!gTasks[gTasks[taskId].data[10]].isActive && !gTasks[gTasks[taskId].data[11]].isActive) - DestroyAnimVisualTask(taskId); - break; - } -} - -void sub_813F990(u8 taskId) -{ - u8 ballIndex = ball_number_to_ball_processing_index(gLastUsedItem); - LoadBallGraphics(ballIndex); - DestroyAnimVisualTask(taskId); -} - -void sub_813F9B8(u8 taskId) -{ - u8 ballIndex = ball_number_to_ball_processing_index(gLastUsedItem); - FreeBallGraphics(ballIndex); - DestroyAnimVisualTask(taskId); -} - -void sub_813F9E0(u8 taskId) -{ - if (ewram17840.unk8 == 5) - gBattleAnimArgs[7] = -1; - else - gBattleAnimArgs[7] = 0; - - DestroyAnimVisualTask(taskId); -} - -u8 ball_number_to_ball_processing_index(u16 ballItem) -{ - switch (ballItem) - { - case ITEM_MASTER_BALL: - return 4; - case ITEM_ULTRA_BALL: - return 3; - case ITEM_GREAT_BALL: - return 1; - case ITEM_SAFARI_BALL: - return 2; - case ITEM_NET_BALL: - return 5; - case ITEM_DIVE_BALL: - return 6; - case ITEM_NEST_BALL: - return 7; - case ITEM_REPEAT_BALL: - return 8; - case ITEM_TIMER_BALL: - return 9; - case ITEM_LUXURY_BALL: - return 10; - case ITEM_PREMIER_BALL: - return 11; - case ITEM_POKE_BALL: - default: - return 0; - } -} - -void sub_813FA94(u8 taskId) -{ - u8 ballIndex; - u8 spriteId; - - ballIndex = ball_number_to_ball_processing_index(gLastUsedItem); - spriteId = CreateSprite(&gBallSpriteTemplates[ballIndex], 32, 80, 29); - gSprites[spriteId].data[0] = 34; - gSprites[spriteId].data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, 0); - gSprites[spriteId].data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 1) - 16; - gSprites[spriteId].callback = sub_813FD90; - ewram17840.unk9_1 = gSprites[gBankSpriteIds[gBattleAnimTarget]].invisible; - gTasks[taskId].data[0] = spriteId; - gTasks[taskId].func = sub_813FB7C; -} - -static void sub_813FB7C(u8 taskId) -{ - u8 spriteId = gTasks[taskId].data[0]; - if ((u16)gSprites[spriteId].data[0] == 0xFFFF) - DestroyAnimVisualTask(taskId); -} - -void sub_813FBB8(u8 taskId) -{ - int x, y; - u8 ballIndex; - u8 subpriority; - u8 spriteId; - - if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) - { - x = 32; - y = 11; - } - else - { - x = 23; - y = 5; - } - - ballIndex = ball_number_to_ball_processing_index(gLastUsedItem); - subpriority = GetBattlerSubpriority(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)) + 1; - spriteId = CreateSprite(&gBallSpriteTemplates[ballIndex], x + 32, y | 80, subpriority); - gSprites[spriteId].data[0] = 34; - gSprites[spriteId].data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, 0); - gSprites[spriteId].data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 1) - 16; - gSprites[spriteId].callback = SpriteCallbackDummy; - StartSpriteAnim(&gSprites[gBankSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]], 1); - gTasks[taskId].data[0] = spriteId; - gTasks[taskId].func = sub_813FCBC; -} - -static void sub_813FCBC(u8 taskId) -{ - if (gSprites[gBankSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]].animCmdIndex == 1) - { - PlaySE12WithPanning(SE_NAGERU, 0); - gSprites[gTasks[taskId].data[0]].callback = sub_813FD90; - CreateTask(sub_813FD34, 10); - gTasks[taskId].func = sub_813FB7C; - } -} - -static void sub_813FD34(u8 taskId) -{ - if (gSprites[gBankSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]].animEnded) - { - StartSpriteAnim(&gSprites[gBankSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]], 0); - DestroyTask(taskId); - } -} - -static void sub_813FD90(struct Sprite *sprite) -{ - u16 temp = sprite->data[1]; - u16 temp2 = sprite->data[2]; - sprite->data[1] = sprite->pos1.x; - sprite->data[2] = temp; - sprite->data[3] = sprite->pos1.y; - sprite->data[4] = temp2; - sprite->data[5] = -40; - InitAnimArcTranslation(sprite); - sprite->callback = sub_813FDC0; -} - -static void sub_813FDC0(struct Sprite *sprite) -{ - int i; - u8 ballIndex; - int ballIndex2; // extra var needed to match - - if (TranslateAnimArc(sprite)) - { - if (ewram17840.unk8 == 5) - { - sprite->callback = sub_81407B8; - } - else - { - StartSpriteAnim(sprite, 1); - sprite->pos1.x += sprite->pos2.x; - sprite->pos1.y += sprite->pos2.y; - sprite->pos2.x = 0; - sprite->pos2.y = 0; - - for (i = 0; i < 8; i++) - { - sprite->data[i] = 0; - } - - sprite->data[5] = 0; - sprite->callback = sub_813FE70; - ballIndex = ball_number_to_ball_processing_index(gLastUsedItem); - ballIndex2 = ballIndex; - if (ballIndex2 > 11) - return; - if (ballIndex2 < 0) - return; - - AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 28, ballIndex); - sub_8141314(0, gBattleAnimTarget, 14, ballIndex); - } - } -} - -static void sub_813FE70(struct Sprite *sprite) -{ - if (++sprite->data[5] == 10) - { - sprite->data[5] = CreateTask(TaskDummy, 50); - sprite->callback = sub_813FEC8; - gSprites[gBankSpriteIds[gBattleAnimTarget]].data[1] = 0; - } -} - -static void sub_813FEC8(struct Sprite *sprite) -{ - u8 spriteId; - u8 taskId; - - spriteId = gBankSpriteIds[gBattleAnimTarget]; - taskId = sprite->data[5]; - - if (++gTasks[taskId].data[1] == 11) - PlaySE(SE_SUIKOMU); - - switch (gTasks[taskId].data[0]) - { - case 0: - PrepareBattlerSpriteForRotScale(spriteId, 0); - gTasks[taskId].data[10] = 256; - gUnknown_03005F0C = 28; - gUnknown_03005F14 = (gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y) - (sprite->pos1.y + sprite->pos2.y); - gUnknown_03005F10 = (u32)(gUnknown_03005F14 * 256) / 28; - gTasks[taskId].data[2] = gUnknown_03005F10; - gTasks[taskId].data[0]++; - break; - case 1: - gTasks[taskId].data[10] += 0x20; - obj_id_set_rotscale(spriteId, gTasks[taskId].data[10], gTasks[taskId].data[10], 0); - gTasks[taskId].data[3] += gTasks[taskId].data[2]; - gSprites[spriteId].pos2.y = -gTasks[taskId].data[3] >> 8; - if (gTasks[taskId].data[10] >= 0x480) - gTasks[taskId].data[0]++; - break; - case 2: - sub_8078F40(spriteId); - gSprites[spriteId].invisible = 1; - gTasks[taskId].data[0]++; - break; - default: - if (gTasks[taskId].data[1] > 10) - { - DestroyTask(taskId); - StartSpriteAnim(sprite, 2); - sprite->data[5] = 0; - sprite->callback = sub_8140014; - } - break; - } -} - -static void sub_8140014(struct Sprite *sprite) -{ - int angle; - - if (sprite->animEnded) - { - sprite->data[3] = 0; - sprite->data[4] = 32; - sprite->data[5] = 0; - angle = 0; - sprite->pos1.y += Cos(angle, 32); - sprite->pos2.y = -Cos(angle, sprite->data[4]); - sprite->callback = sub_8140058; - } -} - -static void sub_8140058(struct Sprite *sprite) -{ - bool8 lastBounce; - int bounceCount; - - lastBounce = 0; - - switch (sprite->data[3] & 0xFF) - { - case 0: - sprite->pos2.y = -Cos(sprite->data[5], sprite->data[4]); - sprite->data[5] += (sprite->data[3] >> 8) + 4; - if (sprite->data[5] >= 64) - { - sprite->data[4] -= 10; - sprite->data[3] += 257; - - bounceCount = sprite->data[3] >> 8; - if (bounceCount == 4) - lastBounce = 1; - - // Play a different sound effect for each pokeball bounce. - switch (bounceCount) - { - case 1: - PlaySE(SE_KON); - break; - case 2: - PlaySE(SE_KON2); - break; - case 3: - PlaySE(SE_KON3); - break; - default: - PlaySE(SE_KON4); - break; - } - } - break; - case 1: - sprite->pos2.y = -Cos(sprite->data[5], sprite->data[4]); - sprite->data[5] -= (sprite->data[3] >> 8) + 4; - if (sprite->data[5] <= 0) - { - sprite->data[5] = 0; - sprite->data[3] &= -0x100; - } - break; - } - - if (lastBounce) - { - sprite->data[3] = 0; - sprite->pos1.y += Cos(64, 32); - sprite->pos2.y = 0; - if (ewram17840.unk8 == 0) - { - sprite->data[5] = 0; - sprite->callback = sub_8140410; - } - else - { - sprite->callback = sub_8140158; - sprite->data[4] = 1; - sprite->data[5] = 0; - } - } -} - -static void sub_8140158(struct Sprite *sprite) -{ - if (++sprite->data[3] == 31) - { - sprite->data[3] = 0; - sprite->affineAnimPaused = 1; - StartSpriteAffineAnim(sprite, 1); - ewram17840.unkC = 0; - sprite->callback = sub_81401A0; - PlaySE(SE_BOWA); - } -} - -static void sub_81401A0(struct Sprite *sprite) -{ - s8 state; - u16 var0; - - switch (sprite->data[3] & 0xFF) - { - case 0: - if ((s16)ewram17840.unkC > 0xFF) - { - sprite->pos2.x += sprite->data[4]; - ewram17840.unkC &= 0xFF; - } - else - { - ewram17840.unkC += 0xB0; - } - - sprite->data[5]++; - sprite->affineAnimPaused = 0; - var0 = sprite->data[5] + 7; - if (var0 > 14) - { - ewram17840.unkC = 0; - sprite->data[3]++; - sprite->data[5] = 0; - } - break; - case 1: - if (++sprite->data[5] == 1) - { - sprite->data[5] = 0; - sprite->data[4] = -sprite->data[4]; - sprite->data[3]++; - sprite->affineAnimPaused = 0; - if (sprite->data[4] < 0) - ChangeSpriteAffineAnim(sprite, 2); - else - ChangeSpriteAffineAnim(sprite, 1); - } - else - { - sprite->affineAnimPaused = 1; - } - break; - case 2: - if ((s16)ewram17840.unkC > 0xFF) - { - sprite->pos2.x += sprite->data[4]; - ewram17840.unkC &= 0xFF; - } - else - { - ewram17840.unkC += 0xB0; - } - - sprite->data[5]++; - sprite->affineAnimPaused = 0; - var0 = sprite->data[5] + 12; - if (var0 > 24) - { - ewram17840.unkC = 0; - sprite->data[3]++; - sprite->data[5] = 0; - } - break; - case 3: - if (sprite->data[5]++ < 0) - { - sprite->affineAnimPaused = 1; - break; - } - - sprite->data[5] = 0; - sprite->data[4] = -sprite->data[4]; - sprite->data[3]++; - sprite->affineAnimPaused = 0; - if (sprite->data[4] < 0) - ChangeSpriteAffineAnim(sprite, 2); - else - ChangeSpriteAffineAnim(sprite, 1); - // fall through - case 4: - if ((s16)ewram17840.unkC > 0xFF) - { - sprite->pos2.x += sprite->data[4]; - ewram17840.unkC &= 0xFF; - } - else - { - ewram17840.unkC += 0xB0; - } - - sprite->data[5]++; - sprite->affineAnimPaused = 0; - var0 = sprite->data[5] + 4; - if (var0 > 8) - { - ewram17840.unkC = 0; - sprite->data[3]++; - sprite->data[5] = 0; - sprite->data[4] = -sprite->data[4]; - } - break; - case 5: - sprite->data[3] += 0x100; - state = sprite->data[3] >> 8; - if (state == ewram17840.unk8) - { - sprite->affineAnimPaused = 1; - sprite->callback = sub_8140410; - } - else - { - if (ewram17840.unk8 == 4 && state == 3) - { - sprite->callback = sub_8140434; - sprite->affineAnimPaused = 1; - } - else - { - sprite->data[3]++; - sprite->affineAnimPaused = 1; - } - } - break; - case 6: - default: - if (++sprite->data[5] == 31) - { - sprite->data[5] = 0; - sprite->data[3] &= -0x100; - StartSpriteAffineAnim(sprite, 3); - if (sprite->data[4] < 0) - StartSpriteAffineAnim(sprite, 2); - else - StartSpriteAffineAnim(sprite, 1); - - PlaySE(SE_BOWA); - } - break; - } -} - -static void sub_8140410(struct Sprite *sprite) -{ - if (++sprite->data[5] == 31) - { - sprite->data[5] = 0; - sprite->callback = sub_81405F4; - } -} - -static void sub_8140434(struct Sprite *sprite) -{ - sprite->animPaused = 1; - sprite->callback = sub_8140454; - sprite->data[3] = 0; - sprite->data[4] = 0; - sprite->data[5] = 0; -} - -static void sub_8140454(struct Sprite *sprite) -{ - u8 *battler = &gBattleAnimTarget; - - sprite->data[4]++; - if (sprite->data[4] == 40) - return; - - if (sprite->data[4] == 95) - { - gDoingBattleAnim = 0; - UpdateOamPriorityInAllHealthboxes(1); - m4aMPlayAllStop(); - PlaySE(MUS_FANFA5); - } - else if (sprite->data[4] == 315) - { - FreeOamMatrix(gSprites[gBankSpriteIds[*battler]].oam.matrixNum); - DestroySprite(&gSprites[gBankSpriteIds[*battler]]); - sprite->data[0] = 0; - sprite->callback = sub_81404E4; - } -} - -static void sub_81404E4(struct Sprite *sprite) -{ - u8 paletteIndex; - - switch (sprite->data[0]) - { - case 0: - sprite->data[1] = 0; - sprite->data[2] = 0; - sprite->oam.objMode = ST_OAM_OBJ_BLEND; - REG_BLDCNT = 0x3F40; - REG_BLDALPHA = 0x0010; - paletteIndex = IndexOfSpritePaletteTag(sprite->template->paletteTag); - BeginNormalPaletteFade(1 << (paletteIndex + 0x10), 0, 0, 16, RGB(31, 31, 31)); - sprite->data[0]++; - break; - case 1: - if (sprite->data[1]++ > 0) - { - sprite->data[1] = 0; - sprite->data[2]++; - REG_BLDALPHA = (sprite->data[2] << 8) | (16 - sprite->data[2]); - if (sprite->data[2] == 16) - sprite->data[0]++; - } - break; - case 2: - sprite->invisible = 1; - sprite->data[0]++; - break; - default: - if (!gPaletteFade.active) - { - REG_BLDCNT = 0; - REG_BLDALPHA = 0; - sprite->data[0] = 0; - sprite->callback = sub_81405C8; - } - break; - } -} - -static void sub_81405C8(struct Sprite *sprite) -{ - if (sprite->data[0] == 0) - { - sprite->data[0] = -1; - } - else - { - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); - } -} - -// fakematching. I think the return type of ball_number_to_ball_processing_index() -// is wrong because of the weird required casting. -static void sub_81405F4(struct Sprite *sprite) -{ - u8 ballIndex; - int ballIndex2; // extra var needed to match - - StartSpriteAnim(sprite, 1); - StartSpriteAffineAnim(sprite, 0); - sprite->callback = sub_81406BC; - - ballIndex = ball_number_to_ball_processing_index(gLastUsedItem); - ballIndex2 = ballIndex; - if (ballIndex2 > 11) - goto LABEL; - if (ballIndex2 < 0) - goto LABEL; - - AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 28, ballIndex); - sub_8141314(1, gBattleAnimTarget, 14, ballIndex); - - LABEL: - gSprites[gBankSpriteIds[gBattleAnimTarget]].invisible = 0; - StartSpriteAffineAnim(&gSprites[gBankSpriteIds[gBattleAnimTarget]], 1); - AnimateSprite(&gSprites[gBankSpriteIds[gBattleAnimTarget]]); - gSprites[gBankSpriteIds[gBattleAnimTarget]].data[1] = 0x1000; -} - -static void sub_81406BC(struct Sprite *sprite) -{ - int next = FALSE; - - if (sprite->animEnded) - sprite->invisible = 1; - - if (gSprites[gBankSpriteIds[gBattleAnimTarget]].affineAnimEnded) - { - StartSpriteAffineAnim(&gSprites[gBankSpriteIds[gBattleAnimTarget]], 0); - next = TRUE; - } - else - { - gSprites[gBankSpriteIds[gBattleAnimTarget]].data[1] -= 288; - gSprites[gBankSpriteIds[gBattleAnimTarget]].pos2.y = gSprites[gBankSpriteIds[gBattleAnimTarget]].data[1] >> 8; - } - - if (sprite->animEnded && next) - { - gSprites[gBankSpriteIds[gBattleAnimTarget]].pos2.y = 0; - gSprites[gBankSpriteIds[gBattleAnimTarget]].invisible = ewram17840.unk9_1; - sprite->data[0] = 0; - sprite->callback = sub_81405C8; - gDoingBattleAnim = 0; - UpdateOamPriorityInAllHealthboxes(1); - } -} - -static void sub_81407B8(struct Sprite *sprite) -{ - int i; - - sprite->pos1.x += sprite->pos2.x; - sprite->pos1.y += sprite->pos2.y; - sprite->pos2.y = 0; - sprite->pos2.x = 0; - for (i = 0; i < 6; i++) - sprite->data[i] = 0; - - sprite->callback = sub_81407F4; -} - -#ifdef NONMATCHING -// there is some weird typing going on with var0 and var1. -static void sub_81407F4(struct Sprite *sprite) -{ - s16 var0, var1; - - var0 = sprite->data[0] + 0x800; - var1 = sprite->data[1] + 0x680; - sprite->pos2.x -= var1 >> 8; - sprite->pos2.y += var0 >> 8; - sprite->data[0] = var0 & 0xFF; - sprite->data[1] = var1 & 0xFF; - - if (sprite->pos1.y + sprite->pos2.y > 160 - || sprite->pos1.x + sprite->pos2.x < -8) - { - sprite->data[0] = 0; - sprite->callback = sub_81405C8; - gDoingBattleAnim = 0; - UpdateOamPriorityInAllHealthboxes(1); - } -} -#else -NAKED -static void sub_81407F4(struct Sprite *sprite) -{ - asm(".syntax unified\n\ - push {r4,lr}\n\ - adds r4, r0, 0\n\ - movs r0, 0x80\n\ - lsls r0, 4\n\ - adds r2, r0, 0\n\ - ldrh r1, [r4, 0x2E]\n\ - adds r2, r1\n\ - movs r0, 0xD0\n\ - lsls r0, 3\n\ - adds r3, r0, 0\n\ - ldrh r1, [r4, 0x30]\n\ - adds r3, r1\n\ - lsls r1, r3, 16\n\ - asrs r1, 24\n\ - ldrh r0, [r4, 0x24]\n\ - subs r0, r1\n\ - strh r0, [r4, 0x24]\n\ - lsls r0, r2, 16\n\ - asrs r0, 24\n\ - ldrh r1, [r4, 0x26]\n\ - adds r0, r1\n\ - strh r0, [r4, 0x26]\n\ - movs r0, 0xFF\n\ - ands r2, r0\n\ - strh r2, [r4, 0x2E]\n\ - ands r3, r0\n\ - strh r3, [r4, 0x30]\n\ - movs r2, 0x22\n\ - ldrsh r0, [r4, r2]\n\ - movs r2, 0x26\n\ - ldrsh r1, [r4, r2]\n\ - adds r0, r1\n\ - cmp r0, 0xA0\n\ - bgt _0814084A\n\ - movs r1, 0x20\n\ - ldrsh r0, [r4, r1]\n\ - movs r2, 0x24\n\ - ldrsh r1, [r4, r2]\n\ - adds r0, r1\n\ - movs r1, 0x8\n\ - negs r1, r1\n\ - cmp r0, r1\n\ - bge _0814085E\n\ -_0814084A:\n\ - movs r0, 0\n\ - strh r0, [r4, 0x2E]\n\ - ldr r0, _08140864 @ =sub_81405C8\n\ - str r0, [r4, 0x1C]\n\ - ldr r1, _08140868 @ =gDoingBattleAnim\n\ - movs r0, 0\n\ - strb r0, [r1]\n\ - movs r0, 0x1\n\ - bl UpdateOamPriorityInAllHealthboxes\n\ -_0814085E:\n\ - pop {r4}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_08140864: .4byte sub_81405C8\n\ -_08140868: .4byte gDoingBattleAnim\n\ - .syntax divided\n"); -} -#endif // NONMATCHING - -u8 AnimateBallOpenParticles(u8 x, u8 y, u8 priority, u8 subpriority, u8 ballIndex) -{ - u8 taskId; - - if (GetSpriteTileStartByTag(gBallOpenParticleSpritesheets[ballIndex].tag) == 0xFFFF) - { - LoadCompressedObjectPic(&gBallOpenParticleSpritesheets[ballIndex]); - LoadCompressedObjectPalette(&gBallOpenParticlePalettes[ballIndex]); - } - - taskId = CreateTask(gBallOpenParticleAnimationFuncs[ballIndex], 5); - gTasks[taskId].data[1] = x; - gTasks[taskId].data[2] = y; - gTasks[taskId].data[3] = priority; - gTasks[taskId].data[4] = subpriority; - gTasks[taskId].data[15] = ballIndex; - PlaySE(SE_BOWA2); - if (gMain.inBattle) - ewram17840.unkA++; - - return taskId; -} - -void PokeBallOpenParticleAnimation(u8 taskId) -{ - u8 spriteId; - u8 x, y; - u8 priority, subpriority; - u8 ballIndex; - u8 var0; - - ballIndex = gTasks[taskId].data[15]; - if (gTasks[taskId].data[0] < 16) - { - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); - StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); - gSprites[spriteId].callback = PokeBallOpenParticleAnimation_Step1; - gSprites[spriteId].oam.priority = priority; - - var0 = (u8)gTasks[taskId].data[0]; - if (var0 >= 8) - var0 -= 8; - - gSprites[spriteId].data[0] = var0 * 32; - if (gTasks[taskId].data[0] == 15) - { - gSprites[spriteId].data[7] = 1; - DestroyTask(taskId); - return; - } - } - - gTasks[taskId].data[0]++; -} - -static void PokeBallOpenParticleAnimation_Step1(struct Sprite *sprite) -{ - if (sprite->data[1] == 0) - sprite->callback = PokeBallOpenParticleAnimation_Step2; - else - sprite->data[1]--; -} - -static void PokeBallOpenParticleAnimation_Step2(struct Sprite *sprite) -{ - sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); - sprite->pos2.y = Cos(sprite->data[0], sprite->data[1]); - sprite->data[1] += 2; - if (sprite->data[1] == 50) - DestroyBallOpenAnimationParticle(sprite); -} - -void TimerBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballIndex; - u8 spriteId; - - ballIndex = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 8; i++) - { - spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); - StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); - gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 32; - gSprites[spriteId].data[4] = 10; - gSprites[spriteId].data[5] = 2; - gSprites[spriteId].data[6] = 1; - } - - gSprites[spriteId].data[7] = 1; - DestroyTask(taskId); -} - -void DiveBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballIndex; - u8 spriteId; - - ballIndex = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 8; i++) - { - spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); - StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); - gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 32; - gSprites[spriteId].data[4] = 10; - gSprites[spriteId].data[5] = 1; - gSprites[spriteId].data[6] = 2; - } - - gSprites[spriteId].data[7] = 1; - DestroyTask(taskId); -} - -void SafariBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballIndex; - u8 spriteId; - - ballIndex = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 8; i++) - { - spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); - StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); - gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 32; - gSprites[spriteId].data[4] = 4; - gSprites[spriteId].data[5] = 1; - gSprites[spriteId].data[6] = 1; - } - - gSprites[spriteId].data[7] = 1; - DestroyTask(taskId); -} - -void UltraBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballIndex; - u8 spriteId; - - ballIndex = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 10; i++) - { - spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); - StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); - gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 25; - gSprites[spriteId].data[4] = 5; - gSprites[spriteId].data[5] = 1; - gSprites[spriteId].data[6] = 1; - } - - gSprites[spriteId].data[7] = 1; - DestroyTask(taskId); -} - -void GreatBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballIndex; - u8 spriteId; - - if (gTasks[taskId].data[7]) - { - gTasks[taskId].data[7]--; - } - else - { - ballIndex = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 8; i++) - { - spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); - StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); - gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 32; - gSprites[spriteId].data[4] = 8; - gSprites[spriteId].data[5] = 2; - gSprites[spriteId].data[6] = 2; - } - - gTasks[taskId].data[7] = 8; - if (++gTasks[taskId].data[0] == 2) - { - gSprites[spriteId].data[7] = 1; - DestroyTask(taskId); - } - } -} - -static void FanOutBallOpenParticles_Step1(struct Sprite *sprite) -{ - sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); - sprite->pos2.y = Cos(sprite->data[0], sprite->data[2]); - sprite->data[0] = (sprite->data[0] + sprite->data[4]) & 0xFF; - sprite->data[1] += sprite->data[5]; - sprite->data[2] += sprite->data[6]; - if (++sprite->data[3] == 51) - DestroyBallOpenAnimationParticle(sprite); -} - -void RepeatBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballIndex; - u8 spriteId; - - ballIndex = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 12; i++) - { - spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); - StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); - gSprites[spriteId].callback = RepeatBallOpenParticleAnimation_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 21; - } - - gSprites[spriteId].data[7] = 1; - DestroyTask(taskId); -} - -static void RepeatBallOpenParticleAnimation_Step1(struct Sprite *sprite) -{ - sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); - sprite->pos2.y = Cos(sprite->data[0], Sin(sprite->data[0], sprite->data[2])); - sprite->data[0] = (sprite->data[0] + 6) & 0xFF; - sprite->data[1]++; - sprite->data[2]++; - if (++sprite->data[3] == 51) - DestroyBallOpenAnimationParticle(sprite); -} - -void MasterBallOpenParticleAnimation(u8 taskId) -{ - u8 i, j; - u8 x, y, priority, subpriority, ballIndex; - u8 spriteId; - - ballIndex = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (j = 0; j < 2; j++) - { - for (i = 0; i < 8; i++) - { - spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); - StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); - gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 32; - gSprites[spriteId].data[4] = 8; - - if (j == 0) - { - gSprites[spriteId].data[5] = 2; - gSprites[spriteId].data[6] = 1; - } - else - { - gSprites[spriteId].data[5] = 1; - gSprites[spriteId].data[6] = 2; - } - } - } - - gSprites[spriteId].data[7] = 1; - DestroyTask(taskId); -} - -void PremierBallOpenParticleAnimation(u8 taskId) -{ - u8 i; - u8 x, y, priority, subpriority, ballIndex; - u8 spriteId; - - ballIndex = gTasks[taskId].data[15]; - x = gTasks[taskId].data[1]; - y = gTasks[taskId].data[2]; - priority = gTasks[taskId].data[3]; - subpriority = gTasks[taskId].data[4]; - - for (i = 0; i < 8; i++) - { - spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); - StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); - gSprites[spriteId].callback = PremierBallOpenParticleAnimation_Step1; - gSprites[spriteId].oam.priority = priority; - gSprites[spriteId].data[0] = i * 32; - } - - gSprites[spriteId].data[7] = 1; - DestroyTask(taskId); -} - -static void PremierBallOpenParticleAnimation_Step1(struct Sprite *sprite) -{ - sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); - sprite->pos2.y = Cos(sprite->data[0], Sin(sprite->data[0] & 0x3F, sprite->data[2])); - sprite->data[0] = (sprite->data[0] + 10) & 0xFF; - sprite->data[1]++; - sprite->data[2]++; - if (++sprite->data[3] == 51) - DestroyBallOpenAnimationParticle(sprite); -} - -static void DestroyBallOpenAnimationParticle(struct Sprite *sprite) -{ - int i; - int temp; - - if (!gMain.inBattle) - { - temp = sprite->data[7]; // temp var needed to match - if (temp == 1) - DestroySpriteAndFreeResources(sprite); - else - DestroySprite(sprite); - } - else if (sprite->data[7] == 1) - { - if (--ewram17840.unkA == 0) - { - for (i = 0; i < 12; i++) - { - FreeSpriteTilesByTag(gBallOpenParticleSpritesheets[i].tag); - FreeSpritePaletteByTag(gBallOpenParticlePalettes[i].tag); - } - - DestroySprite(sprite); - } - else - DestroySprite(sprite); - } - else - DestroySprite(sprite); -} - -u8 sub_8141314(u8 arg0, u8 battler, u32 selectedPalettes, u8 ballIndex) -{ - u8 taskId; - - taskId = CreateTask(sub_81413DC, 5); - gTasks[taskId].data[15] = ballIndex; - gTasks[taskId].data[3] = battler; - gTasks[taskId].data[10] = selectedPalettes; - gTasks[taskId].data[11] = selectedPalettes >> 16; - - if (!arg0) - { - BlendPalette(battler * 16 + 0x100, 16, 0, gUnknown_0840B4D4[ballIndex]); - gTasks[taskId].data[1] = 1; - } - else - { - BlendPalette(battler * 16 + 0x100, 16, 16, gUnknown_0840B4D4[ballIndex]); - gTasks[taskId].data[0] = 16; - gTasks[taskId].data[1] = -1; - gTasks[taskId].func = sub_814146C; - } - - BeginNormalPaletteFade(selectedPalettes, 0, 0, 16, RGB(31, 31, 31)); - return taskId; -} - -static void sub_81413DC(u8 taskId) -{ - u8 ballIndex = gTasks[taskId].data[15]; - - if (gTasks[taskId].data[2] <= 16) - { - BlendPalette(gTasks[taskId].data[3] * 16 + 0x100, 16, gTasks[taskId].data[0], gUnknown_0840B4D4[ballIndex]); - gTasks[taskId].data[0] += gTasks[taskId].data[1]; - gTasks[taskId].data[2]++; - } - else if (!gPaletteFade.active) - { - u32 selectedPalettes = (u16)gTasks[taskId].data[10] | ((u16)gTasks[taskId].data[11] << 16); - BeginNormalPaletteFade(selectedPalettes, 0, 16, 0, RGB(31, 31, 31)); - DestroyTask(taskId); - } -} - -static void sub_814146C(u8 taskId) -{ - if (!gPaletteFade.active) - { - u32 selectedPalettes = (u16)gTasks[taskId].data[10] | ((u16)gTasks[taskId].data[11] << 16); - BeginNormalPaletteFade(selectedPalettes, 0, 16, 0, RGB(31, 31, 31)); - gTasks[taskId].func = sub_81414BC; - } -} - -static void sub_81414BC(u8 taskId) -{ - u8 ballIndex = gTasks[taskId].data[15]; - - if (gTasks[taskId].data[2] <= 16) - { - BlendPalette(gTasks[taskId].data[3] * 16 + 0x100, 16, gTasks[taskId].data[0], gUnknown_0840B4D4[ballIndex]); - gTasks[taskId].data[0] += gTasks[taskId].data[1]; - gTasks[taskId].data[2]++; - } - else - { - DestroyTask(taskId); - } -} - -void sub_814151C(u8 taskId) -{ - u8 spriteId; - u32 x; - u32 done; - - done = FALSE; - spriteId = gBankSpriteIds[gBattleAnimAttacker]; - switch (gTasks[taskId].data[10]) - { - case 0: - gTasks[taskId].data[11] = gBattleAnimArgs[0]; - gTasks[taskId].data[0] += 0x500; - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - gSprites[spriteId].pos2.x += gTasks[taskId].data[0] >> 8; - else - gSprites[spriteId].pos2.x -= gTasks[taskId].data[0] >> 8; - - gTasks[taskId].data[0] &= 0xFF; - x = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x + 32; - if (x > 304) - gTasks[taskId].data[10]++; - break; - case 1: - refresh_graphics_maybe(gBattleAnimAttacker, gTasks[taskId].data[11], spriteId); - gTasks[taskId].data[10]++; - break; - case 2: - gTasks[taskId].data[0] += 0x500; - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - gSprites[spriteId].pos2.x -= gTasks[taskId].data[0] >> 8; - else - gSprites[spriteId].pos2.x += gTasks[taskId].data[0] >> 8; - - gTasks[taskId].data[0] &= 0xFF; - if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) - { - if (gSprites[spriteId].pos2.x <= 0) - { - gSprites[spriteId].pos2.x = 0; - // done = FALSE; // fakematching--can't get the tail merge correct - goto DONE; - } - } - else - { - if (gSprites[spriteId].pos2.x >= 0) - { - gSprites[spriteId].pos2.x = 0; - done = TRUE; - } - } - - if (done) - { - DONE: - DestroyAnimVisualTask(taskId); - } - break; - } -} - -void sub_81416C4(u8 taskId) -{ - u8 spriteId; - - switch (gTasks[taskId].data[15]) - { - case 0: - if (GetBattlerPosition_permutated(gBattleAnimAttacker) == 1) - REG_BLDCNT = 0x3F42; - else - REG_BLDCNT = 0x3F44; - - REG_BLDALPHA = 0x0010; - gTasks[taskId].data[15]++; - break; - case 1: - if (gTasks[taskId].data[1]++ > 1) - { - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[0]++; - REG_BLDALPHA = (gTasks[taskId].data[0] << 8) | (16 - gTasks[taskId].data[0]); - if (gTasks[taskId].data[0] == 16) - gTasks[taskId].data[15]++; - } - break; - case 2: - spriteId = gBankSpriteIds[gBattleAnimAttacker]; - DmaClear32(3, (void *)OBJ_VRAM0 + gSprites[spriteId].oam.tileNum * TILE_SIZE_4BPP, 0x800); - sub_80324E0(gBattleAnimAttacker); - DestroyAnimVisualTask(taskId); - break; - } -} - -void sub_81417D8(u8 taskId) -{ - gBattleAnimArgs[7] = ewram17800[gBattleAnimAttacker].substituteSprite; - DestroyAnimVisualTask(taskId); -} - -void sub_8141808(u8 taskId) -{ - gBattleAnimTarget = gEffectBank; - DestroyAnimVisualTask(taskId); -} - -void sub_8141828(u8 battler, struct Pokemon *mon) -{ - int isShiny; - u32 otId, personality; - u32 shinyValue; - u8 taskId1, taskId2; - - isShiny = 0; - ewram17810[battler].unk0_7 = 1; - otId = GetMonData(mon, MON_DATA_OT_ID); - personality = GetMonData(mon, MON_DATA_PERSONALITY); - - if (IsAnimBankSpriteVisible(battler)) - { - shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality); - if (shinyValue < 8) - isShiny = TRUE; - - if (isShiny) - { - if (GetSpriteTileStartByTag(0x27F9) == 0xFFFF) - { - LoadCompressedObjectPic(&gBattleAnimPicTable[233]); - LoadCompressedObjectPalette(&gBattleAnimPaletteTable[233]); - } - - taskId1 = CreateTask(sub_814191C, 10); - taskId2 = CreateTask(sub_814191C, 10); - gTasks[taskId1].data[0] = battler; - gTasks[taskId2].data[0] = battler; - gTasks[taskId1].data[1] = 0; - gTasks[taskId2].data[1] = 1; - return; - } - } - - ewram17810[battler].unk1_0 = 1; -} - -static void sub_814191C(u8 taskId) -{ - u8 battler; - u8 x, y; - u8 spriteId; - u16 counter; - s16 state; - u8 pan; - - if (gTasks[taskId].data[13] < 60) - { - gTasks[taskId].data[13]++; - return; - } - - if (ewram17840.unkA) - return; - - counter = gTasks[taskId].data[10]++; - if (counter & 3) - return; - - battler = gTasks[taskId].data[0]; - x = GetBattlerSpriteCoord(battler, 0); - y = GetBattlerSpriteCoord(battler, 1); - state = gTasks[taskId].data[11]; - if (state == 0) - { - spriteId = CreateSprite(&gBattleAnimSpriteTemplate_84024E8, x, y, 5); - } - else if (state >= 0 && gTasks[taskId].data[11] < 4) - { - spriteId = CreateSprite(&gSpriteTemplate_8402500, x, y, 5); - gSprites[spriteId].oam.tileNum += 4; - } - else - { - spriteId = CreateSprite(&gSpriteTemplate_8402500, x, y, 5); - gSprites[spriteId].oam.tileNum += 5; - } - - if (gTasks[taskId].data[1] == 0) - { - gSprites[spriteId].callback = sub_8141B20; - } - else - { - gSprites[spriteId].callback = sub_8141B74; - gSprites[spriteId].pos2.x = -32; - gSprites[spriteId].pos2.y = 32; - gSprites[spriteId].invisible = 1; - if (gTasks[taskId].data[11] == 0) - { - if (GetBattlerSide(battler) == B_SIDE_PLAYER) - pan = 192; - else - pan = 63; - - PlaySE12WithPanning(SE_REAPOKE, pan); - } - } - - gSprites[spriteId].data[0] = taskId; - gTasks[taskId].data[11]++; - gTasks[taskId].data[12]++; - if (gTasks[taskId].data[11] == 5) - gTasks[taskId].func = sub_8141AD8; -} - -static void sub_8141AD8(u8 taskId) -{ - u8 battler; - - if (gTasks[taskId].data[12] == 0) - { - if (gTasks[taskId].data[1] == 1) - { - battler = gTasks[taskId].data[0]; - ewram17810[battler].unk1_0 = 1; - } - - DestroyTask(taskId); - } -} - -static void sub_8141B20(struct Sprite *sprite) -{ - sprite->pos2.x = Sin(sprite->data[1], 24); - sprite->pos2.y = Cos(sprite->data[1], 24); - sprite->data[1] += 12; - if (sprite->data[1] > 0xFF) - { - gTasks[sprite->data[0]].data[12]--; - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); - } -} - -static void sub_8141B74(struct Sprite *sprite) -{ - if (sprite->data[1] < 4) - { - sprite->data[1]++; - } - else - { - sprite->invisible = 0; - sprite->pos2.x += 5; - sprite->pos2.y -= 5; - if (sprite->pos2.x > 32) - { - gTasks[sprite->data[0]].data[12]--; - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); - } - } -} - -void sub_8141BD4(u8 taskId) -{ - u8 paletteIndex; - - LoadCompressedObjectPic(&gBattleAnimPicTable[269]); - LoadCompressedObjectPalette(&gBattleAnimPaletteTable[269]); - paletteIndex = IndexOfSpritePaletteTag(0x281D); // unused - DestroyAnimVisualTask(taskId); -} - -void sub_8141C08(u8 taskId) -{ - FreeSpriteTilesByTag(0x281D); - FreeSpritePaletteByTag(0x281D); - DestroyAnimVisualTask(taskId); -} - -static void sub_8141C30(struct Sprite *sprite) -{ - InitAnimSpritePos(sprite, 0); - sprite->data[0] = 30; - sprite->data[2] = GetBattlerSpriteCoord(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), 0) + gBattleAnimArgs[2]; - sprite->data[4] = GetBattlerSpriteCoord(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), 1) + gBattleAnimArgs[3]; - sprite->data[5] = -32; - InitAnimArcTranslation(sprite); - StartSpriteAnim(&gSprites[gBankSpriteIds[gBattleAnimAttacker]], 1); - sprite->callback = sub_8141CBC; -} - -static void sub_8141CBC(struct Sprite *sprite) -{ - if (gSprites[gBankSpriteIds[gBattleAnimAttacker]].animCmdIndex == 1) - sprite->callback = sub_8141CF4; -} - -static void sub_8141CF4(struct Sprite *sprite) -{ - if (TranslateAnimArc(sprite)) - { - sprite->data[0] = 0; - sprite->invisible = 1; - sprite->callback = sub_8141D20; - } -} - -static void sub_8141D20(struct Sprite *sprite) -{ - if (gSprites[gBankSpriteIds[gBattleAnimAttacker]].animEnded) - { - if (++sprite->data[0] > 0) - { - StartSpriteAnim(&gSprites[gBankSpriteIds[gBattleAnimAttacker]], 0); - DestroyAnimSprite(sprite); - } - } -} - -void sub_8141D7C(u8 taskId) -{ - gBattleAnimAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - gBattleAnimTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - DestroyAnimVisualTask(taskId); -} - -void sub_8141DAC(u8 taskId) -{ - if (ewram17840.unk0 == 83) - gBattleAnimArgs[0] = 1; - else if (ewram17840.unk0 == 250) - gBattleAnimArgs[0] = 2; - else if (ewram17840.unk0 == 128) - gBattleAnimArgs[0] = 3; - else if (ewram17840.unk0 == 328) - gBattleAnimArgs[0] = 4; - else - gBattleAnimArgs[0] = 0; - - DestroyAnimVisualTask(taskId); -} - -void sub_8141E10(u8 taskId) -{ - gBattleAnimAttacker = ewram17840.unk0; - gBattleAnimTarget = ewram17840.unk0 >> 8; - DestroyAnimVisualTask(taskId); -} diff --git a/src/battle/battle_bg.c b/src/battle/battle_bg.c deleted file mode 100644 index 4928708e0..000000000 --- a/src/battle/battle_bg.c +++ /dev/null @@ -1,864 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "decompress.h" -#include "ewram.h" -#include "graphics.h" -#include "link.h" -#include "main.h" -#include "palette.h" -#include "task.h" -#include "text.h" -#include "text_window.h" -#include "trainer.h" -#include "trig.h" -#include "sound.h" -#include "constants/map_types.h" -#include "constants/songs.h" - - -extern u16 gBattleTypeFlags; -extern u8 gBattleOutcome; - -extern struct Window gUnknown_03004210; - -extern u8 BattleText_Win[]; -extern u8 BattleText_Loss[]; -extern u8 BattleText_Tie[]; - -extern void sub_8032A38(void); - -#define GetCurrentMapBattleScene sav1_map_get_battletype -//extern u8 GetCurrentMapBattleScene(void); - -extern const u8 gGameVersion; -extern u16 gBattleTypeFlags; -extern struct Trainer gTrainers[]; -extern u16 gTrainerBattleOpponent; - -extern u8 gBattleTerrain; - -extern u16 gBattleTerrainPalette_Groudon[]; -extern u16 gBattleTerrainPalette_Kyogre[]; -extern u16 gBattleTerrainPalette_BuildingLeader[]; -extern u16 gBattleTerrainPalette_StadiumSteven[]; -extern u16 gBattleTerrainPalette_BuildingGym[]; -extern u16 gBattleTerrainPalette_StadiumMagma[]; -extern u16 gBattleTerrainPalette_StadiumAqua[]; -extern u16 gBattleTerrainPalette_StadiumSidney[]; -extern u16 gBattleTerrainPalette_StadiumPhoebe[]; -extern u16 gBattleTerrainPalette_StadiumGlacia[]; -extern u16 gBattleTerrainPalette_StadiumDrake[]; -extern u16 gBattleTerrainPalette_BattleTower[]; - -extern u8 gVersusFrameGfx[]; -extern u16 gVersusFrameTilemap[]; -extern u16 gVersusFramePal[]; - -extern u16 gBattle_BG1_X; -extern u16 gBattle_BG1_Y; -extern u16 gBattle_BG2_X; -extern u16 gBattle_BG2_Y; - -extern u8 sav1_map_get_battletype(void); - -struct LinkResultWindow { - struct Window *window; - u16 offset; - u8 left; - u8 top; - u8 *dest; -}; - -#define gLinkResultWindows gUnknown_081F9680 -extern const struct LinkResultWindow gLinkResultWindows[]; - -extern struct SpriteTemplate gSpriteTemplate_81F96D0; - -const struct OamData gOamData_81F952C = { - .affineMode = ST_OAM_AFFINE_DOUBLE, - .size = 3 -}; - -const struct OamData gOamData_81F9534 = { - .affineMode = ST_OAM_AFFINE_DOUBLE, - .size = 3, - .tileNum = 64 -}; - -const union AffineAnimCmd gSpriteAffineAnim_81F953C[] = { - AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), - AFFINEANIMCMD_END -}; - -const union AffineAnimCmd gSpriteAffineAnim_81F954C[] = { - AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), - AFFINEANIMCMD_FRAME(0x18, 0x18, 0, -128), - AFFINEANIMCMD_FRAME(0x18, 0x18, 0, -128), - AFFINEANIMCMD_END -}; - -const union AffineAnimCmd *const gSpriteAffineAnimTable_81F956C[] = { - gSpriteAffineAnim_81F953C, - gSpriteAffineAnim_81F954C -}; - -const struct SpriteTemplate gSpriteTemplate_81F9574 = { - .tileTag = 10000, - .paletteTag = 10000, - .oam = &gOamData_81F952C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_81F956C, - .callback = nullsub_36 -}; - -const struct SpriteTemplate gSpriteTemplate_81F958C = { - .tileTag = 10000, - .paletteTag = 10000, - .oam = &gOamData_81F9534, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gSpriteAffineAnimTable_81F956C, - .callback = nullsub_36 -}; - -extern const u8 gUnknown_08E5DC2C[]; - -const struct CompressedSpriteSheet gUnknown_081F95A4[] = { - {gUnknown_08E5DC2C, 4096, 0x2710}, -}; - -struct BattleBackground -{ - const void *tileset; - const void *tilemap; - const void *entryTileset; - const void *entryTilemap; - const void *palette; -}; - -const struct BattleBackground gBattleTerrainTable[] = { -{ - .tileset = gBattleTerrainTiles_TallGrass, - .tilemap = gBattleTerrainTilemap_TallGrass, - .entryTileset = gBattleTerrainAnimTiles_TallGrass, - .entryTilemap = gBattleTerrainAnimTilemap_TallGrass, - .palette = gBattleTerrainPalette_TallGrass -}, -{ - .tileset = gBattleTerrainTiles_LongGrass, - .tilemap = gBattleTerrainTilemap_LongGrass, - .entryTileset = gBattleTerrainAnimTiles_LongGrass, - .entryTilemap = gBattleTerrainAnimTilemap_LongGrass, - .palette = gBattleTerrainPalette_LongGrass -}, -{ - .tileset = gBattleTerrainTiles_Sand, - .tilemap = gBattleTerrainTilemap_Sand, - .entryTileset = gBattleTerrainAnimTiles_Sand, - .entryTilemap = gBattleTerrainAnimTilemap_Sand, - .palette = gBattleTerrainPalette_Sand -}, -{ - .tileset = gBattleTerrainTiles_Underwater, - .tilemap = gBattleTerrainTilemap_Underwater, - .entryTileset = gBattleTerrainAnimTiles_Underwater, - .entryTilemap = gBattleTerrainAnimTilemap_Underwater, - .palette = gBattleTerrainPalette_Underwater -}, -{ - .tileset = gBattleTerrainTiles_Water, - .tilemap = gBattleTerrainTilemap_Water, - .entryTileset = gBattleTerrainAnimTiles_Water, - .entryTilemap = gBattleTerrainAnimTilemap_Water, - .palette = gBattleTerrainPalette_Water -}, -{ - .tileset = gBattleTerrainTiles_PondWater, - .tilemap = gBattleTerrainTilemap_PondWater, - .entryTileset = gBattleTerrainAnimTiles_PondWater, - .entryTilemap = gBattleTerrainAnimTilemap_PondWater, - .palette = gBattleTerrainPalette_PondWater -}, -{ - .tileset = gBattleTerrainTiles_Rock, - .tilemap = gBattleTerrainTilemap_Rock, - .entryTileset = gBattleTerrainAnimTiles_Rock, - .entryTilemap = gBattleTerrainAnimTilemap_Rock, - .palette = gBattleTerrainPalette_Rock -}, -{ - .tileset = gBattleTerrainTiles_Cave, - .tilemap = gBattleTerrainTilemap_Cave, - .entryTileset = gBattleTerrainAnimTiles_Cave, - .entryTilemap = gBattleTerrainAnimTilemap_Cave, - .palette = gBattleTerrainPalette_Cave -}, -{ - .tileset = gBattleTerrainTiles_Building, - .tilemap = gBattleTerrainTilemap_Building, - .entryTileset = gBattleTerrainAnimTiles_Building, - .entryTilemap = gBattleTerrainAnimTilemap_Building, - .palette = gBattleTerrainPalette_Building -}, -{ - .tileset = gBattleTerrainTiles_Building, - .tilemap = gBattleTerrainTilemap_Building, - .entryTileset = gBattleTerrainAnimTiles_Building, - .entryTilemap = gBattleTerrainAnimTilemap_Building, - .palette = gBattleTerrainPalette_Plain - } -}; - -static void sub_800D6C4(void); - -void debug_sub_800D684(void) -{ - u8 spriteId; - ResetSpriteData(); - spriteId = CreateSprite(&gSpriteTemplate_81F96D0, 0, 0, 0); - gSprites[spriteId].invisible = TRUE; - SetMainCallback2(sub_800D6C4); -} - -static void sub_800D6C4(void) -{ - AnimateSprites(); - BuildOamBuffer(); -} - -void sub_800D6D4(void) -{ - u16 ime = REG_IME; - REG_IME = 0; - REG_IE |= INTR_FLAG_VBLANK; - REG_IME = ime; - REG_DISPSTAT = DISPSTAT_VBLANK_INTR; - REG_BG0CNT = 0x9800; - REG_BG1CNT = 0x9c04; - REG_BG2CNT = 0x5e05; - REG_BG3CNT = 0x5a0b; - REG_BLDCNT = 0; - REG_BLDALPHA = 0; - REG_BLDY = 0; - REG_DISPCNT = 0xbf40; -} - -void ApplyPlayerChosenFrameToBattleMenu(void) -{ - TextWindow_SetBaseTileNum(0x12); - TextWindow_LoadStdFrameGraphicsOverridePal(&gUnknown_03004210, 1); - TextWindow_SetBaseTileNum(0x22); - TextWindow_LoadStdFrameGraphicsOverridePal(&gUnknown_03004210, 1); - gPlttBufferUnfaded[92] = 0x7fe0; - gPlttBufferUnfaded[93] = 0x2529; - gPlttBufferUnfaded[94] = 0x7fff; - gPlttBufferUnfaded[95] = 0x675a; - CpuSet(&gPlttBufferUnfaded[92], &gPlttBufferFaded[92], 4); - sub_8032A38(); -} - -void DrawMainBattleBackground(void) -{ - if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER /*| BATTLE_TYPE_x2000000*/)) - { - LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_BattleTower, 0x20, 0x60); - } - else if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) - { - if (gGameVersion == VERSION_RUBY) - { - LZDecompressVram(gBattleTerrainTiles_Cave, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Cave, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_Groudon, 0x20, 0x60); - } - else - { - LZDecompressVram(gBattleTerrainTiles_Water, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Water, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_Kyogre, 0x20, 0x60); - } - } - else - { - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - { - u8 trainerClass = gTrainers[gTrainerBattleOpponent].trainerClass; - if (trainerClass == TRAINER_CLASS_LEADER) - { - LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_BuildingLeader, 0x20, 0x60); - return; - } - else if (trainerClass == TRAINER_CLASS_CHAMPION) - { - LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_StadiumSteven, 0x20, 0x60); - return; - } - } - - switch (GetCurrentMapBattleScene()) - { - case MAP_BATTLE_SCENE_NORMAL: - LZDecompressVram(gBattleTerrainTable[gBattleTerrain].tileset, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTable[gBattleTerrain].tilemap, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainTable[gBattleTerrain].palette, 0x20, 0x60); - break; - case MAP_BATTLE_SCENE_GYM: - LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_BuildingGym, 0x20, 0x60); - break; - case MAP_BATTLE_SCENE_MAGMA: - LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_StadiumMagma, 0x20, 0x60); - break; - case MAP_BATTLE_SCENE_AQUA: - LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_StadiumAqua, 0x20, 0x60); - break; - case MAP_BATTLE_SCENE_SIDNEY: - LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_StadiumSidney, 0x20, 0x60); - break; - case MAP_BATTLE_SCENE_PHOEBE: - LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_StadiumPhoebe, 0x20, 0x60); - break; - case MAP_BATTLE_SCENE_GLACIA: - LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_StadiumGlacia, 0x20, 0x60); - break; - case MAP_BATTLE_SCENE_DRAKE: - LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_StadiumDrake, 0x20, 0x60); - break; - case MAP_BATTLE_SCENE_BATTLE_TOWER: - LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000)); - LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000)); - LoadCompressedPalette(gBattleTerrainPalette_BattleTower, 0x20, 0x60); - break; - } - } -} - -void LoadBattleTextboxAndBackground(void) -{ - LZDecompressVram(gBattleTextboxTiles, (void*)(BG_VRAM)); - CpuSet(gBattleTextboxTilemap, (void *)(VRAM + 0xC000), 0x800); - LoadCompressedPalette(gBattleTextboxPalette, 0, 0x40); - ApplyPlayerChosenFrameToBattleMenu(); - DrawMainBattleBackground(); - - #if DEBUG - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - debug_sub_8008218((void*)(VRAM + 0x600), 0, (void*)(VRAM + 0xC000), 1); - debug_sub_8008264(257, 3, 1, 3, 1); - debug_sub_8008264(257, 3, 21, 3, 1); - debug_sub_8008264(257, 3, 41, 3, 1); - } - #endif -} - -static void sub_800DAF8(u8 taskId, u8 windowId, u8 *dest) -{ - int i; - u16 r4 = 0; - u16 src[6]; - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { - if (gTasks[taskId].data[5]) { - switch (windowId) { - case 0: - r4 = gTasks[taskId].data[3] & 0x3f; - break; - case 1: - r4 = (gTasks[taskId].data[4] & 0xfc0) >> 6; - break; - case 2: - r4 = (gTasks[taskId].data[3] & 0xfc0) >> 6; - break; - case 3: - r4 = gTasks[taskId].data[4] & 0x3f; - break; - } - } else { - switch (windowId) { - case 0: - r4 = gTasks[taskId].data[3] & 0x3f; - break; - case 1: - r4 = gTasks[taskId].data[4] & 0x3f; - break; - case 2: - r4 = (gTasks[taskId].data[3] & 0xfc0) >> 6; - break; - case 3: - r4 = (gTasks[taskId].data[4] & 0xfc0) >> 6; - break; - } - } - for (i = 0; i < 3; i++) { - src[i] = ((r4 & (3 << (i * 2))) >> (i * 2)) + 0x6001; - } - CpuSet(src, dest, 3); - } else { - if (windowId == gBattleStruct->linkPlayerIndex) { - r4 = gTasks[taskId].data[3]; - } else { - r4 = gTasks[taskId].data[4]; - } - for (i = 0; i < 6; i++) { - src[i] = ((r4 & (3 << (i * 2))) >> (i * 2)) + 0x6001; - } - CpuSet(src, dest, 6); - } -} - - -#if ENGLISH -#define LEFT_MESSAGE_X 6 -#define RIGHT_MESSAGE_X 21 -#define TILE_OFFSET_LOSS 168 -#elif GERMAN -#define LEFT_MESSAGE_X 5 -#define RIGHT_MESSAGE_X 20 -#define TILE_OFFSET_LOSS 172 -#endif -#define TILE_OFFSET_WIN 160 -#define CENTER_MESSAGE_X 13 -#define MESSAGE_Y 2 - -#define PRINT_MESSAGE(text, tileDataStartOffset, x) \ -{ \ - Text_InitWindow(&gUnknown_03004210, text, tileDataStartOffset, x, MESSAGE_Y); \ - Text_PrintWindow8002F44(&gUnknown_03004210); \ -} - -#define PRINT_MESSAGE_LEFT(text, tileDataStartOffset) PRINT_MESSAGE(text, tileDataStartOffset, LEFT_MESSAGE_X) -#define PRINT_MESSAGE_RIGHT(text, tileDataStartOffset) PRINT_MESSAGE(text, tileDataStartOffset, RIGHT_MESSAGE_X) - -static void PrintLinkBattleWinLossTie(void) -{ - - if (gBattleOutcome == 3) - { - PRINT_MESSAGE(BattleText_Tie, TILE_OFFSET_WIN, CENTER_MESSAGE_X); - return; - } - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - // Double battle? - - if (gBattleOutcome == 1) - { - - // lp_field_18 = player position? - switch (gLinkPlayers[gBattleStruct->linkPlayerIndex].lp_field_18) - { - case 0: - case 2: - PRINT_MESSAGE_LEFT(BattleText_Win, TILE_OFFSET_WIN); - PRINT_MESSAGE_RIGHT(BattleText_Loss, TILE_OFFSET_LOSS); - return; - - case 1: - case 3: - PRINT_MESSAGE_RIGHT(BattleText_Win, TILE_OFFSET_WIN) - PRINT_MESSAGE_LEFT(BattleText_Loss, TILE_OFFSET_LOSS) - return; - } - } - else - { - - switch (gLinkPlayers[gBattleStruct->linkPlayerIndex].lp_field_18) - { - case 1: - case 3: - PRINT_MESSAGE_LEFT(BattleText_Win, TILE_OFFSET_WIN); - PRINT_MESSAGE_RIGHT(BattleText_Loss, TILE_OFFSET_LOSS); - return; - - case 0: - case 2: - PRINT_MESSAGE_RIGHT(BattleText_Win, TILE_OFFSET_WIN); - PRINT_MESSAGE_LEFT(BattleText_Loss, TILE_OFFSET_LOSS); - return; - } - } - - return; - } - - - if (gBattleOutcome == 1) - { - if (gLinkPlayers[gBattleStruct->linkPlayerIndex].lp_field_18 != 0) - { - PRINT_MESSAGE_RIGHT(BattleText_Win, TILE_OFFSET_WIN); - PRINT_MESSAGE_LEFT(BattleText_Loss, TILE_OFFSET_LOSS); - } - else - { - PRINT_MESSAGE_LEFT(BattleText_Win, TILE_OFFSET_WIN); - PRINT_MESSAGE_RIGHT(BattleText_Loss, TILE_OFFSET_LOSS); - } - } - else - { - if (gLinkPlayers[gBattleStruct->linkPlayerIndex].lp_field_18 != 0) - { - PRINT_MESSAGE_LEFT(BattleText_Win, TILE_OFFSET_WIN); - PRINT_MESSAGE_RIGHT(BattleText_Loss, TILE_OFFSET_LOSS); - } - else - { - PRINT_MESSAGE_RIGHT(BattleText_Win, TILE_OFFSET_WIN); - PRINT_MESSAGE_LEFT(BattleText_Loss, TILE_OFFSET_LOSS); - } - } -} - - -void sub_800DE30(u8 taskId) -{ - u8 palette; - int i; - - switch (gTasks[taskId].data[0]) { - - case 0: - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { - for (i = 0; i < 4; i++) { - u8 windowId = (gLinkPlayers[i].lp_field_18 & 3); - Text_InitWindow8002E4C( - gLinkResultWindows[windowId].window, - gLinkPlayers[i].name, - gLinkResultWindows[windowId].offset, - gLinkResultWindows[windowId].left, - gLinkResultWindows[windowId].top, - 1); - Text_PrintWindow8002F44(gLinkResultWindows[windowId].window); - sub_800DAF8(taskId, windowId, gLinkResultWindows[windowId].dest); - } - } else { - u8 windowId = 4; - - u8 playerId = gBattleStruct->linkPlayerIndex; - u8 opponentId = gBattleStruct->linkPlayerIndex ^ 1; - if (gLinkPlayers[playerId].lp_field_18) { - opponentId = gBattleStruct->linkPlayerIndex; - playerId = gBattleStruct->linkPlayerIndex ^ 1; - } - - Text_InitWindow8002E4C( - gLinkResultWindows[windowId].window, - gLinkPlayers[playerId].name, - gLinkResultWindows[windowId].offset, - gLinkResultWindows[windowId].left, - gLinkResultWindows[windowId].top, - 1); - Text_PrintWindow8002F44(gLinkResultWindows[windowId].window); - sub_800DAF8(taskId, playerId, gLinkResultWindows[windowId].dest); - - Text_InitWindow8002E4C( - gLinkResultWindows[windowId + 1].window, - gLinkPlayers[opponentId].name, - gLinkResultWindows[windowId + 1].offset, - gLinkResultWindows[windowId + 1].left, - gLinkResultWindows[windowId + 1].top, - 1); - Text_PrintWindow8002F44(gLinkResultWindows[windowId + 1].window); - sub_800DAF8(taskId, opponentId, gLinkResultWindows[windowId + 1].dest); - } - gTasks[taskId].data[0]++; - break; - - case 1: - palette = AllocSpritePalette(10000); - gPlttBufferUnfaded[palette * 16 + 0x10f] = gPlttBufferFaded[palette * 16 + 0x10f] = 0x7fff; - gBattleStruct->unk1608A = CreateSprite(&gSpriteTemplate_81F9574, 108, 80, 0); - gBattleStruct->unk1608B = CreateSprite(&gSpriteTemplate_81F958C, 132, 80, 0); - gSprites[gBattleStruct->unk1608A].invisible = TRUE; - gSprites[gBattleStruct->unk1608B].invisible = TRUE; - gTasks[taskId].data[0]++; - break; - - case 2: - if (gTasks[taskId].data[5]) { - gBattle_BG1_X = (-20) - (Sin2(gTasks[taskId].data[1]) / 32); - gBattle_BG2_X = (-140) - (Sin2(gTasks[taskId].data[2]) / 32); - gBattle_BG1_Y = -36; - gBattle_BG2_Y = -36; - } else { - gBattle_BG1_X = (-20) - (Sin2(gTasks[taskId].data[1]) / 32); - gBattle_BG1_Y = (-164) + (Cos2(gTasks[taskId].data[1]) / 32); - gBattle_BG2_X = (-140) - (Sin2(gTasks[taskId].data[2]) / 32); - gBattle_BG2_Y = (-164) + (Cos2(gTasks[taskId].data[2]) / 32); - } - if (gTasks[taskId].data[2]) { - gTasks[taskId].data[2] -= 2; - gTasks[taskId].data[1] += 2; - } else { - if (gTasks[taskId].data[5]) { - PrintLinkBattleWinLossTie(); - } - PlaySE(SE_W231); - DestroyTask(taskId); - gSprites[gBattleStruct->unk1608A].invisible = FALSE; - gSprites[gBattleStruct->unk1608B].invisible = FALSE; - gSprites[gBattleStruct->unk1608B].oam.tileNum += 0x40; - gSprites[gBattleStruct->unk1608A].data[0] = 0; - gSprites[gBattleStruct->unk1608B].data[0] = 1; - gSprites[gBattleStruct->unk1608A].data[1] = gSprites[gBattleStruct->unk1608A].pos1.x; - gSprites[gBattleStruct->unk1608B].data[1] = gSprites[gBattleStruct->unk1608B].pos1.x; - gSprites[gBattleStruct->unk1608A].data[2] = 0; - gSprites[gBattleStruct->unk1608B].data[2] = 0; - } - break; - } -} - -void LoadBattleEntryBackground(void) { - if (gBattleTypeFlags & BATTLE_TYPE_LINK) { - LZDecompressVram(gVersusFrameGfx, (void *)0x6004000); - LZDecompressVram(gVersusFrameTilemap, (void *)0x600e000); - LZDecompressVram(gVersusFrameTilemap, (void *)0x600f000); - LZDecompressVram(gUnknown_08E5DC2C, (void *)0x6010000); - LoadCompressedPalette(gVersusFramePal, 0x60, 0x20); - REG_BG1CNT = 0x5c04; - REG_WININ = 0x36; - REG_WINOUT = 0x36; - gBattle_BG1_Y = 0xff5c; - gBattle_BG2_Y = 0xff5c; - LoadCompressedObjectPic(gUnknown_081F95A4); - return; - } else if (gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK)) { - LZDecompressVram(gBattleTerrainAnimTiles_Building, (void *)0x6004000); - LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void *)0x600e000); - return; - } else if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) { - if (gGameVersion == VERSION_RUBY) { - LZDecompressVram(gBattleTerrainAnimTiles_Cave, (void *)0x6004000); - LZDecompressVram(gBattleTerrainAnimTilemap_Cave, (void *)0x600e000); - return; - } else { - LZDecompressVram(gBattleTerrainAnimTiles_Underwater, (void *)0x6004000); - LZDecompressVram(gBattleTerrainAnimTilemap_Underwater, (void *)0x600e000); - return; - } - } else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) { - if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x19) { - LZDecompressVram(gBattleTerrainAnimTiles_Building, (void *)0x6004000); - LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void *)0x600e000); - return; - } else if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x20) { - LZDecompressVram(gBattleTerrainAnimTiles_Building, (void *)0x6004000); - LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void *)0x600e000); - return; - } - } - if (sav1_map_get_battletype() == 0) { - LZDecompressVram(gBattleTerrainTable[gBattleTerrain].entryTileset, (void *)0x6004000); - LZDecompressVram(gBattleTerrainTable[gBattleTerrain].entryTilemap, (void *)0x600e000); - return; - } - LZDecompressVram(gBattleTerrainAnimTiles_Building, (void *)0x6004000); - LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void *)0x600e000); -} - -int LoadChosenBattleElement(u8 type) { - int ret = 0; - switch (type) { - case 0: - LZDecompressVram(&gBattleTextboxTiles, (void *)0x6000000); - break; - case 1: - CpuCopy16(gBattleTextboxTilemap, (void *)0x600c000, 0x1000); - break; - case 2: - LoadCompressedPalette(gBattleTextboxPalette, 0, 0x40); - break; - case 3: // tiles - if (!(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK))) { - if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) { - if (gGameVersion == VERSION_RUBY) { - LZDecompressVram(gBattleTerrainTiles_Cave, (void *)0x6008000); - break; - } else { - LZDecompressVram(gBattleTerrainTiles_Water, (void *)0x6008000); - break; - } - } else { - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) { - if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x19) { - LZDecompressVram(gBattleTerrainTiles_Building, (void *)0x6008000); - break; - } else if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x20) { - LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); - break; - } - } - switch (sav1_map_get_battletype()) { - case 0: - LZDecompressVram(gBattleTerrainTable[gBattleTerrain].tileset, (void *)0x6008000); - break; - case 2: - LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); - break; - case 3: - LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); - break; - case 4: - LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); - break; - case 5: - LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); - break; - case 6: - LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); - break; - case 7: - LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); - break; - case 1: - case 8: - LZDecompressVram(gBattleTerrainTiles_Building, (void *)0x6008000); - break; - } - break; - } - } else { - LZDecompressVram(gBattleTerrainTiles_Building, (void *)0x6008000); - break; - } - case 4: // tilemap - if (!(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK))) { - if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) { - if (gGameVersion == 2) { - LZDecompressVram(gBattleTerrainTilemap_Cave, (void *)0x600d000); - break; - } else { - LZDecompressVram(gBattleTerrainTilemap_Water, (void *)0x600d000); - break; - } - } else { - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) { - if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x19) { - LZDecompressVram(gBattleTerrainTilemap_Building, (void *)0x600d000); - break; - } else if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x20) { - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); - break; - } - } - switch (sav1_map_get_battletype()) { - case 0: - LZDecompressVram(gBattleTerrainTable[gBattleTerrain].tilemap, (void *)0x600d000); - break; - case 2: - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); - break; - case 3: - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); - break; - case 4: - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); - break; - case 5: - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); - break; - case 6: - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); - break; - case 7: - LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); - break; - case 1: - case 8: - LZDecompressVram(gBattleTerrainTilemap_Building, (void *)0x600d000); - break; - } - break; - } - } else { - LZDecompressVram(gBattleTerrainTilemap_Building, (void *)0x600d000); - break; - } - case 5: // palette - if (!(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK))) { - if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) { - if (gGameVersion == 2) { - LoadCompressedPalette(gBattleTerrainPalette_Groudon, 0x20, 0x60); - break; - } else { - LoadCompressedPalette(gBattleTerrainPalette_Kyogre, 0x20, 0x60); - break; - } - } else { - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) { - if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x19) { - LoadCompressedPalette(gBattleTerrainPalette_BuildingLeader, 0x20, 0x60); - break; - } else if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x20) { - LoadCompressedPalette(gBattleTerrainPalette_StadiumSteven, 0x20, 0x60); - break; - } - } - switch (sav1_map_get_battletype()) { - case 0: - LoadCompressedPalette(gBattleTerrainTable[gBattleTerrain].palette, 0x20, 0x60); - break; - case 1: - LoadCompressedPalette(gBattleTerrainPalette_BuildingGym, 0x20, 0x60); - break; - case 2: - LoadCompressedPalette(gBattleTerrainPalette_StadiumMagma, 0x20, 0x60); - break; - case 3: - LoadCompressedPalette(gBattleTerrainPalette_StadiumAqua, 0x20, 0x60); - break; - case 4: - LoadCompressedPalette(gBattleTerrainPalette_StadiumSidney, 0x20, 0x60); - break; - case 5: - LoadCompressedPalette(gBattleTerrainPalette_StadiumPhoebe, 0x20, 0x60); - break; - case 6: - LoadCompressedPalette(gBattleTerrainPalette_StadiumGlacia, 0x20, 0x60); - break; - case 7: - LoadCompressedPalette(gBattleTerrainPalette_StadiumDrake, 0x20, 0x60); - break; - case 8: - LoadCompressedPalette(gBattleTerrainPalette_BattleTower, 0x20, 0x60); - break; - } - break; - } - } else { - LoadCompressedPalette(gBattleTerrainPalette_BattleTower, 0x20, 0x60); - break; - } - case 6: - ApplyPlayerChosenFrameToBattleMenu(); - break; - default: - ret = 1; - } - return ret; -} diff --git a/src/battle/battle_controller_linkopponent.c b/src/battle/battle_controller_linkopponent.c deleted file mode 100644 index 117aeb932..000000000 --- a/src/battle/battle_controller_linkopponent.c +++ /dev/null @@ -1,1778 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_anim.h" -#include "battle_anim_813F0F4.h" -#include "battle_interface.h" -#include "data2.h" -#include "link.h" -#include "m4a.h" -#include "main.h" -#include "palette.h" -#include "rom_8077ABC.h" -#include "rom3.h" -#include "constants/songs.h" -#include "sound.h" -#include "sprite.h" -#include "string_util.h" -#include "task.h" -#include "text.h" -#include "util.h" -#include "ewram.h" - -struct MovePpInfo -{ - u16 moves[4]; - u8 pp[4]; - u8 ppBonuses; -}; - -extern u8 gActiveBattler; -extern u8 gBattleBufferA[][0x200]; -extern u8 gBankSpriteIds[]; -extern u16 gBattlerPartyIndexes[]; -extern u8 gHealthboxIDs[]; -extern u16 gBattleTypeFlags; -extern u8 gBattleMonForms[]; -extern void (*gBattleBankFunc[])(void); -extern s32 gAnimMoveDmg; -extern u16 gAnimMovePower; -extern u8 gAnimFriendship; -extern u16 gWeatherMoveAnim; -extern u32 gTransformedPersonalities[]; -extern u8 gAnimScriptActive; -extern void (*gAnimScriptCallback)(void); -extern u8 gDisplayedStringBattle[]; -extern bool8 gDoingBattleAnim; -extern u8 gBattleOutcome; -extern u16 gUnknown_02024DE8; -extern u8 gUnknown_02024E68[]; -extern struct SpriteTemplate gUnknown_02024E8C; -extern u8 gAnimMoveTurn; -extern struct Window gUnknown_03004210; -extern u8 gUnknown_0300434C[]; -extern u32 gBattleExecBuffer; -extern MainCallback gPreBattleCallback1; -extern struct MusicPlayerInfo gMPlay_BGM; - -extern u8 sub_8077F68(); -extern u8 GetBattlerSubpriority(); -extern u8 GetBattlerPosition(u8); -extern void BattleLoadOpponentMonSprite(struct Pokemon *, u8); -extern void sub_8037A74(void); -extern void sub_8032984(u8, u16); -extern void sub_8037E30(void); -extern void sub_80312F0(struct Sprite *); -extern u8 StartSendOutMonAnimation(); -extern void sub_8032A08(); -extern void sub_8043DB0(); -extern void sub_8037BBC(void); -extern s32 sub_803FC34(u16); -extern void sub_8031A6C(u16, u8); -extern void sub_80313A0(struct Sprite *); -extern void sub_803757C(void); -extern void oamt_add_pos2_onto_pos1(); -extern void StoreSpriteCallbackInData(); -extern void StartAnimLinearTranslation(struct Sprite *); -extern void sub_80375B4(void); -extern void sub_8010384(struct Sprite *); -extern void sub_8037B78(void); -extern u8 sub_8031720(); -extern bool8 mplay_80342A4(u8); -extern void DoMoveAnim(); -extern void sub_80326EC(); -extern void sub_8031F24(void); -extern void sub_80324BC(); -extern void BufferStringBattle(); -extern void sub_8037C2C(void); -extern void sub_8043D84(); -extern void sub_8037B24(void); -extern void sub_8045A5C(); -extern void sub_8037FAC(void); -extern void move_anim_start_t2_for_situation(); -extern void dp01t_0F_4_move_anim(void); -extern void sub_8047858(); -extern u8 GetBattlerSide(u8); -extern void StartBattleIntroAnim(); -extern void sub_803A3A8(struct Sprite *); -extern void sub_8044CA0(u8); -extern void nullsub_47(void); -extern bool8 IsDoubleBattle(void); -extern void sub_8037840(void); -extern void sub_8031B74(); -extern u8 IsBankSpritePresent(); -extern u8 move_anim_start_t3(); -extern void sub_8037FD8(void); -extern void sub_8037F34(void); -extern void LinkOpponentBufferExecCompleted(void); -extern void sub_804777C(); - -// this file's functions - -u32 dp01_getattr_by_ch1_for_player_pokemon__(u8, u8 *); -void sub_803752C(void); -void sub_8037D2C(void); -void sub_8038900(u8); -void sub_8039430(u8, u8); -void sub_8039648(void); -void sub_8039B64(void); -void sub_803A2C4(u8); -void sub_803A4E0(void); - -void LinkOpponentHandleGetAttributes(void); -void LinkOpponentHandlecmd1(void); -void LinkOpponentHandleSetAttributes(void); -void LinkOpponentHandlecmd3(void); -void LinkOpponentHandleLoadPokeSprite(void); -void LinkOpponentHandleSendOutPoke(void); -void LinkOpponentHandleReturnPokeToBall(void); -void LinkOpponentHandleTrainerThrow(void); -void LinkOpponentHandleTrainerSlide(void); -void LinkOpponentHandleTrainerSlideBack(void); -void LinkOpponentHandlecmd10(void); -void LinkOpponentHandlecmd11(void); -void LinkOpponentHandlecmd12(void); -void LinkOpponentHandleBallThrow(void); -void LinkOpponentHandlePuase(void); -void LinkOpponentHandleMoveAnimation(void); -void LinkOpponentHandlePrintString(void); -void LinkOpponentHandlePrintStringPlayerOnly(void); -void LinkOpponentHandlecmd18(void); -void LinkOpponentHandlecmd19(void); -void LinkOpponentHandlecmd20(void); -void LinkOpponentHandleOpenBag(void); -void LinkOpponentHandlecmd22(void); -void LinkOpponentHandlecmd23(void); -void LinkOpponentHandleHealthBarUpdate(void); -void LinkOpponentHandleExpBarUpdate(void); -void LinkOpponentHandleStatusIconUpdate(void); -void LinkOpponentHandleStatusAnimation(void); -void LinkOpponentHandleStatusXor(void); -void LinkOpponentHandlecmd29(void); -void LinkOpponentHandleDMATransfer(void); -void LinkOpponentHandlecmd31(void); -void LinkOpponentHandlecmd32(void); -void LinkOpponentHandlecmd33(void); -void LinkOpponentHandlecmd34(void); -void LinkOpponentHandlecmd35(void); -void LinkOpponentHandlecmd36(void); -void LinkOpponentHandlecmd37(void); -void LinkOpponentHandlecmd38(void); -void LinkOpponentHandlecmd39(void); -void LinkOpponentHandlecmd40(void); -void LinkOpponentHandleHitAnimation(void); -void LinkOpponentHandlecmd42(void); -void LinkOpponentHandleEffectivenessSound(void); -void LinkOpponentHandlecmd44(void); -void LinkOpponentHandleFaintingCry(void); -void LinkOpponentHandleIntroSlide(void); -void LinkOpponentHandleTrainerBallThrow(void); -void LinkOpponentHandlecmd48(void); -void LinkOpponentHandlecmd49(void); -void LinkOpponentHandlecmd50(void); -void LinkOpponentHandleSpriteInvisibility(void); -void LinkOpponentHandleBattleAnimation(void); -void LinkOpponentHandleLinkStandbyMsg(void); -void LinkOpponentHandleResetActionMoveSelection(void); -void LinkOpponentHandlecmd55(void); -void LinkOpponentHandlecmd56(void); - -// const data - -typedef void (*BattleBufferCmd) (void); -const BattleBufferCmd gLinkOpponentBufferCommands[] = -{ - LinkOpponentHandleGetAttributes, - LinkOpponentHandlecmd1, - LinkOpponentHandleSetAttributes, - LinkOpponentHandlecmd3, - LinkOpponentHandleLoadPokeSprite, - LinkOpponentHandleSendOutPoke, - LinkOpponentHandleReturnPokeToBall, - LinkOpponentHandleTrainerThrow, - LinkOpponentHandleTrainerSlide, - LinkOpponentHandleTrainerSlideBack, - LinkOpponentHandlecmd10, - LinkOpponentHandlecmd11, - LinkOpponentHandlecmd12, - LinkOpponentHandleBallThrow, - LinkOpponentHandlePuase, - LinkOpponentHandleMoveAnimation, - LinkOpponentHandlePrintString, - LinkOpponentHandlePrintStringPlayerOnly, - LinkOpponentHandlecmd18, - LinkOpponentHandlecmd19, - LinkOpponentHandlecmd20, - LinkOpponentHandleOpenBag, - LinkOpponentHandlecmd22, - LinkOpponentHandlecmd23, - LinkOpponentHandleHealthBarUpdate, - LinkOpponentHandleExpBarUpdate, - LinkOpponentHandleStatusIconUpdate, - LinkOpponentHandleStatusAnimation, - LinkOpponentHandleStatusXor, - LinkOpponentHandlecmd29, - LinkOpponentHandleDMATransfer, - LinkOpponentHandlecmd31, - LinkOpponentHandlecmd32, - LinkOpponentHandlecmd33, - LinkOpponentHandlecmd34, - LinkOpponentHandlecmd35, - LinkOpponentHandlecmd36, - LinkOpponentHandlecmd37, - LinkOpponentHandlecmd38, - LinkOpponentHandlecmd39, - LinkOpponentHandlecmd40, - LinkOpponentHandleHitAnimation, - LinkOpponentHandlecmd42, - LinkOpponentHandleEffectivenessSound, - LinkOpponentHandlecmd44, - LinkOpponentHandleFaintingCry, - LinkOpponentHandleIntroSlide, - LinkOpponentHandleTrainerBallThrow, - LinkOpponentHandlecmd48, - LinkOpponentHandlecmd49, - LinkOpponentHandlecmd50, - LinkOpponentHandleSpriteInvisibility, - LinkOpponentHandleBattleAnimation, - LinkOpponentHandleLinkStandbyMsg, - LinkOpponentHandleResetActionMoveSelection, - LinkOpponentHandlecmd55, - LinkOpponentHandlecmd56 -}; - -// code - -void nullsub_47(void) -{ -} - -void SetBankFuncToLinkOpponentBufferRunCommand(void) -{ - gBattleBankFunc[gActiveBattler] = sub_803752C; -} - -void sub_803752C(void) -{ - if (gBattleExecBuffer & gBitTable[gActiveBattler]) - { - if (gBattleBufferA[gActiveBattler][0] <= 0x38) - gLinkOpponentBufferCommands[gBattleBufferA[gActiveBattler][0]](); - else - LinkOpponentBufferExecCompleted(); - } -} - -void sub_803757C(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - LinkOpponentBufferExecCompleted(); -} - -void sub_80375B4(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - sub_8031B74(gSprites[gBankSpriteIds[gActiveBattler]].oam.affineParam); - gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum = gSprites[gBankSpriteIds[gActiveBattler]].data[5]; - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - LinkOpponentBufferExecCompleted(); - } -} - -void sub_8037644(void) -{ - if ((--ewram17810[gActiveBattler].unk9) == 0xFF) - { - ewram17810[gActiveBattler].unk9 = 0; - LinkOpponentBufferExecCompleted(); - } -} - -void sub_8037680(void) -{ - bool8 r6 = FALSE; - - if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) - { - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) - r6 = TRUE; - } - else - { - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxIDs[gActiveBattler ^ 2]].callback == SpriteCallbackDummy) - r6 = TRUE; - } - if (IsCryPlayingOrClearCrySongs()) - r6 = FALSE; - - if (r6) - { - if (GetBattlerPosition(gActiveBattler) == 1) - { - if (!ewram17810[gActiveBattler].unk1_0 || !ewram17810[gActiveBattler ^ 2].unk1_0) - return; - ewram17810[gActiveBattler].unk0_7 = 0; - ewram17810[gActiveBattler].unk1_0 = 0; - ewram17810[gActiveBattler ^ 2].unk0_7 = 0; - ewram17810[gActiveBattler ^ 2].unk1_0 = 0; - FreeSpriteTilesByTag(0x27F9); - FreeSpritePaletteByTag(0x27F9); - } - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (GetBattlerPosition(gActiveBattler) == 1) - m4aMPlayContinue(&gMPlay_BGM); - } - else - { - m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 256); - } - ewram17810[gActiveBattler].unk9 = 3; - gBattleBankFunc[gActiveBattler] = sub_8037644; - } -} - -void sub_8037840(void) -{ - if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) - sub_8141828(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); - if (!ewram17810[gActiveBattler ^ 2].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_7) - sub_8141828(gActiveBattler ^ 2, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ 2]]); - if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_3) - { - if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) && GetBattlerPosition(gActiveBattler) == 3) - { - if (++ewram17810[gActiveBattler].unk9 == 1) - return; - ewram17810[gActiveBattler].unk9 = 0; - } - if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler ^ 2]]); - sub_8045A5C( - gHealthboxIDs[gActiveBattler ^ 2], - &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], - 0); - sub_804777C(gActiveBattler ^ 2); - sub_8043DFC(gHealthboxIDs[gActiveBattler ^ 2]); - sub_8032984( - gActiveBattler ^ 2, - GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], MON_DATA_SPECIES)); - } - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); - sub_8045A5C( - gHealthboxIDs[gActiveBattler], - &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], - 0); - sub_804777C(gActiveBattler); - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - sub_8032984( - gActiveBattler, - GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - - ewram17840.unk9_0 = 0; - gBattleBankFunc[gActiveBattler] = sub_8037680; - } -} - -void sub_8037A74(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].animEnded == TRUE - && gSprites[gBankSpriteIds[gActiveBattler]].pos2.x == 0) - { - if (!ewram17810[gActiveBattler].unk0_7) - { - sub_8141828(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); - return; - } - if (ewram17810[gActiveBattler].unk1_0) - { - ewram17810[gActiveBattler].unk0_7 = 0; - ewram17810[gActiveBattler].unk1_0 = 0; - FreeSpriteTilesByTag(0x27F9); - FreeSpritePaletteByTag(0x27F9); - LinkOpponentBufferExecCompleted(); - return; - } - } -} - -void sub_8037B24(void) -{ - s16 r4 = sub_8045C78(gActiveBattler, gHealthboxIDs[gActiveBattler], 0, 0); - - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - if (r4 != -1) - sub_80440EC(gHealthboxIDs[gActiveBattler], r4, 0); - else - LinkOpponentBufferExecCompleted(); -} - -void sub_8037B78(void) -{ - if (!gSprites[gBankSpriteIds[gActiveBattler]].inUse) - { - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - LinkOpponentBufferExecCompleted(); - } -} - -void sub_8037BBC(void) -{ - if (!ewram17810[gActiveBattler].unk0_6) - { - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - sub_8032A08(gActiveBattler); - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - LinkOpponentBufferExecCompleted(); - } -} - -void sub_8037C2C(void) -{ - if (gUnknown_03004210.state == 0) - LinkOpponentBufferExecCompleted(); -} - -void dp01t_0F_4_move_anim(void) -{ - u8 spriteId = gBankSpriteIds[gActiveBattler]; - - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = 0; - LinkOpponentBufferExecCompleted(); - } - else - { - if (((u16)gSprites[spriteId].data[1] % 4) == 0) - gSprites[spriteId].invisible ^= 1; - gSprites[spriteId].data[1]++; - } -} - -void sub_8037CC0(void) -{ - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) - { - if (ewram17800[gActiveBattler].substituteSprite) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); - gBattleBankFunc[gActiveBattler] = sub_8037D2C; - } -} - -void sub_8037D2C(void) -{ - if (!ewram17810[gActiveBattler].unk0_6) - { - CreateTask(c3_0802FDF4, 10); - LinkOpponentBufferExecCompleted(); - } -} - -void sub_8037D64(void) -{ - if (ewram17810[gActiveBattler].unk1_0) - { - ewram17810[gActiveBattler].unk0_7 = 0; - ewram17810[gActiveBattler].unk1_0 = 0; - FreeSpriteTilesByTag(0x27F9); - FreeSpritePaletteByTag(0x27F9); - StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 0); - sub_8045A5C( - gHealthboxIDs[gActiveBattler], - &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], - 0); - sub_804777C(gActiveBattler); - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - sub_8031F88(gActiveBattler); - gBattleBankFunc[gActiveBattler] = sub_8037CC0; - } -} - -void sub_8037E30(void) -{ - if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) - sub_8141828(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); - if (gSprites[gUnknown_0300434C[gActiveBattler]].callback == SpriteCallbackDummy - && !ewram17810[gActiveBattler].unk0_3) - { - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); - sub_8032984(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - gBattleBankFunc[gActiveBattler] = sub_8037D64; - } -} - -void sub_8037EF0(void) -{ - if (gReceivedRemoteLinkPlayers == 0) - { - m4aSongNumStop(SE_HINSI); - gMain.inBattle = FALSE; - gMain.callback1 = gPreBattleCallback1; - SetMainCallback2(c2_8011A1C); - } -} - -void sub_8037F34(void) -{ - if (!gPaletteFade.active) - { - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - sub_800832C(); - gBattleBankFunc[gActiveBattler] = sub_8037EF0; - } - else - { - m4aSongNumStop(SE_HINSI); - gMain.inBattle = FALSE; - gMain.callback1 = gPreBattleCallback1; - SetMainCallback2(gMain.savedCallback); - } - } -} - -void sub_8037FAC(void) -{ - if (!ewram17810[gActiveBattler].unk0_4) - LinkOpponentBufferExecCompleted(); -} - -void sub_8037FD8(void) -{ - if (!ewram17810[gActiveBattler].unk0_5) - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentBufferExecCompleted(void) -{ - gBattleBankFunc[gActiveBattler] = sub_803752C; - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - u8 playerId = GetMultiplayerId(); - - PrepareBufferDataTransferLink(2, 4, &playerId); - gBattleBufferA[gActiveBattler][0] = 0x38; - } - else - { - gBattleExecBuffer &= ~gBitTable[gActiveBattler]; - } -} - -void LinkOpponentHandleGetAttributes(void) -{ - u8 buffer[0x100]; - u32 r6 = 0; - u8 r4; - s32 i; - - if (gBattleBufferA[gActiveBattler][2] == 0) - { - r6 = dp01_getattr_by_ch1_for_player_pokemon__(gBattlerPartyIndexes[gActiveBattler], buffer); - } - else - { - r4 = gBattleBufferA[gActiveBattler][2]; - for (i = 0; i < 6; i++) - { - if (r4 & 1) - r6 += dp01_getattr_by_ch1_for_player_pokemon__(i, buffer + r6); - r4 >>= 1; - } - } - Emitcmd29(1, r6, buffer); - LinkOpponentBufferExecCompleted(); -} - -u32 dp01_getattr_by_ch1_for_player_pokemon__(u8 a, u8 *buffer) -{ - struct BattlePokemon battlePokemon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; - - switch (gBattleBufferA[gActiveBattler][1]) - { - case 0: - battlePokemon.species = GetMonData(&gEnemyParty[a], MON_DATA_SPECIES); - battlePokemon.item = GetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM); - for (size = 0; size < 4; size++) - { - battlePokemon.moves[size] = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + size); - battlePokemon.pp[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size); - } - battlePokemon.ppBonuses = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES); - battlePokemon.friendship = GetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP); - battlePokemon.experience = GetMonData(&gEnemyParty[a], MON_DATA_EXP); - battlePokemon.hpIV = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV); - battlePokemon.attackIV = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV); - battlePokemon.defenseIV = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV); - battlePokemon.speedIV = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV); - battlePokemon.spAttackIV = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV); - battlePokemon.spDefenseIV = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV); - battlePokemon.personality = GetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY); - battlePokemon.status1 = GetMonData(&gEnemyParty[a], MON_DATA_STATUS); - battlePokemon.level = GetMonData(&gEnemyParty[a], MON_DATA_LEVEL); - battlePokemon.hp = GetMonData(&gEnemyParty[a], MON_DATA_HP); - battlePokemon.maxHP = GetMonData(&gEnemyParty[a], MON_DATA_MAX_HP); - battlePokemon.attack = GetMonData(&gEnemyParty[a], MON_DATA_ATK); - battlePokemon.defense = GetMonData(&gEnemyParty[a], MON_DATA_DEF); - battlePokemon.speed = GetMonData(&gEnemyParty[a], MON_DATA_SPEED); - battlePokemon.spAttack = GetMonData(&gEnemyParty[a], MON_DATA_SPATK); - battlePokemon.spDefense = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF); - battlePokemon.isEgg = GetMonData(&gEnemyParty[a], MON_DATA_IS_EGG); - battlePokemon.altAbility = GetMonData(&gEnemyParty[a], MON_DATA_ALT_ABILITY); - battlePokemon.otId = GetMonData(&gEnemyParty[a], MON_DATA_OT_ID); - GetMonData(&gEnemyParty[a], MON_DATA_NICKNAME, nickname); - StringCopy10(battlePokemon.nickname, nickname); - GetMonData(&gEnemyParty[a], MON_DATA_OT_NAME, battlePokemon.otName); - - MEMCPY_ALT(&battlePokemon, buffer, sizeof(battlePokemon), size, src); - break; - case 1: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPECIES); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 2: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 3: - for (size = 0; size < 4; size++) - { - moveData.moves[size] = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES); - MEMCPY_ALT(&moveData, buffer, sizeof(moveData), size, src); - break; - case 4: - case 5: - case 6: - case 7: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 8: - for (size = 0; size < 4; size++) - buffer[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size); - buffer[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES); - size++; - break; - case 9: - case 10: - case 11: - case 12: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9); - size = 1; - break; - case 17: - data32 = GetMonData(&gEnemyParty[a], MON_DATA_OT_ID); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case 18: - data32 = GetMonData(&gEnemyParty[a], MON_DATA_EXP); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case 19: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_EV); - size = 1; - break; - case 20: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_EV); - size = 1; - break; - case 21: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_EV); - size = 1; - break; - case 22: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_EV); - size = 1; - break; - case 23: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_EV); - size = 1; - break; - case 24: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_EV); - size = 1; - break; - case 25: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP); - size = 1; - break; - case 26: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_POKERUS); - size = 1; - break; - case 27: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_LOCATION); - size = 1; - break; - case 28: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_LEVEL); - size = 1; - break; - case 29: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_GAME); - size = 1; - break; - case 30: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_POKEBALL); - size = 1; - break; - case 31: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV); - buffer[1] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV); - buffer[2] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV); - buffer[3] = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV); - buffer[4] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV); - buffer[5] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV); - size = 6; - break; - case 32: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV); - size = 1; - break; - case 33: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV); - size = 1; - break; - case 34: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV); - size = 1; - break; - case 35: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV); - size = 1; - break; - case 36: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV); - size = 1; - break; - case 37: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV); - size = 1; - break; - case 38: - data32 = GetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - buffer[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case 39: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_CHECKSUM); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 40: - data32 = GetMonData(&gEnemyParty[a], MON_DATA_STATUS); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - buffer[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case 41: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_LEVEL); - size = 1; - break; - case 42: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_HP); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 43: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_MAX_HP); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 44: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_ATK); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 45: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_DEF); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 46: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPEED); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 47: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPATK); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 48: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 49: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_COOL); - size = 1; - break; - case 50: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_BEAUTY); - size = 1; - break; - case 51: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_CUTE); - size = 1; - break; - case 52: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SMART); - size = 1; - break; - case 53: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_TOUGH); - size = 1; - break; - case 54: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SHEEN); - size = 1; - break; - case 55: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_COOL_RIBBON); - size = 1; - break; - case 56: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case 57: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case 58: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SMART_RIBBON); - size = 1; - break; - case 59: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - return size; -} - -void LinkOpponentHandlecmd1(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleSetAttributes(void) -{ - u8 i; - u8 r4; - - if (gBattleBufferA[gActiveBattler][2] == 0) - { - sub_8038900(gBattlerPartyIndexes[gActiveBattler]); - } - else - { - r4 = gBattleBufferA[gActiveBattler][2]; - for (i = 0; i < 6; i++) - { - if (r4 & 1) - sub_8038900(i); - r4 >>= 1; - } - } - LinkOpponentBufferExecCompleted(); -} - -void sub_8038900(u8 a) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleBufferA[gActiveBattler][1]) - { - case 0: - { - u8 iv; - - SetMonData(&gEnemyParty[a], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < 4; i++) - { - SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gEnemyParty[a], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gEnemyParty[a], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gEnemyParty[a], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gEnemyParty[a], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gEnemyParty[a], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gEnemyParty[a], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gEnemyParty[a], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gEnemyParty[a], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gEnemyParty[a], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gEnemyParty[a], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gEnemyParty[a], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case 1: - SetMonData(&gEnemyParty[a], MON_DATA_SPECIES, &gBattleBufferA[gActiveBattler][3]); - break; - case 2: - SetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]); - break; - case 3: - for (i = 0; i < 4; i++) - { - SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gEnemyParty[a], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case 4: - case 5: - case 6: - case 7: - SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4, &gBattleBufferA[gActiveBattler][3]); - break; - case 8: - SetMonData(&gEnemyParty[a], MON_DATA_PP1, &gBattleBufferA[gActiveBattler][3]); - SetMonData(&gEnemyParty[a], MON_DATA_PP2, &gBattleBufferA[gActiveBattler][4]); - SetMonData(&gEnemyParty[a], MON_DATA_PP3, &gBattleBufferA[gActiveBattler][5]); - SetMonData(&gEnemyParty[a], MON_DATA_PP4, &gBattleBufferA[gActiveBattler][6]); - SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBattler][7]); - break; - case 9: - case 10: - case 11: - case 12: - SetMonData(&gEnemyParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9, &gBattleBufferA[gActiveBattler][3]); - break; - case 17: - SetMonData(&gEnemyParty[a], MON_DATA_OT_ID, &gBattleBufferA[gActiveBattler][3]); - break; - case 18: - SetMonData(&gEnemyParty[a], MON_DATA_EXP, &gBattleBufferA[gActiveBattler][3]); - break; - case 19: - SetMonData(&gEnemyParty[a], MON_DATA_HP_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 20: - SetMonData(&gEnemyParty[a], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 21: - SetMonData(&gEnemyParty[a], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 22: - SetMonData(&gEnemyParty[a], MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 23: - SetMonData(&gEnemyParty[a], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 24: - SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 25: - SetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBattler][3]); - break; - case 26: - SetMonData(&gEnemyParty[a], MON_DATA_POKERUS, &gBattleBufferA[gActiveBattler][3]); - break; - case 27: - SetMonData(&gEnemyParty[a], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBattler][3]); - break; - case 28: - SetMonData(&gEnemyParty[a], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBattler][3]); - break; - case 29: - SetMonData(&gEnemyParty[a], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBattler][3]); - break; - case 30: - SetMonData(&gEnemyParty[a], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBattler][3]); - break; - case 31: - SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); - SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][4]); - SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][5]); - SetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][6]); - SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][7]); - SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][8]); - break; - case 32: - SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 33: - SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 34: - SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 35: - SetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 36: - SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 37: - SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 38: - SetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBattler][3]); - break; - case 39: - SetMonData(&gEnemyParty[a], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBattler][3]); - break; - case 40: - SetMonData(&gEnemyParty[a], MON_DATA_STATUS, &gBattleBufferA[gActiveBattler][3]); - break; - case 41: - SetMonData(&gEnemyParty[a], MON_DATA_LEVEL, &gBattleBufferA[gActiveBattler][3]); - break; - case 42: - SetMonData(&gEnemyParty[a], MON_DATA_HP, &gBattleBufferA[gActiveBattler][3]); - break; - case 43: - SetMonData(&gEnemyParty[a], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBattler][3]); - break; - case 44: - SetMonData(&gEnemyParty[a], MON_DATA_ATK, &gBattleBufferA[gActiveBattler][3]); - break; - case 45: - SetMonData(&gEnemyParty[a], MON_DATA_DEF, &gBattleBufferA[gActiveBattler][3]); - break; - case 46: - SetMonData(&gEnemyParty[a], MON_DATA_SPEED, &gBattleBufferA[gActiveBattler][3]); - break; - case 47: - SetMonData(&gEnemyParty[a], MON_DATA_SPATK, &gBattleBufferA[gActiveBattler][3]); - break; - case 48: - SetMonData(&gEnemyParty[a], MON_DATA_SPDEF, &gBattleBufferA[gActiveBattler][3]); - break; - case 49: - SetMonData(&gEnemyParty[a], MON_DATA_COOL, &gBattleBufferA[gActiveBattler][3]); - break; - case 50: - SetMonData(&gEnemyParty[a], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBattler][3]); - break; - case 51: - SetMonData(&gEnemyParty[a], MON_DATA_CUTE, &gBattleBufferA[gActiveBattler][3]); - break; - case 52: - SetMonData(&gEnemyParty[a], MON_DATA_SMART, &gBattleBufferA[gActiveBattler][3]); - break; - case 53: - SetMonData(&gEnemyParty[a], MON_DATA_TOUGH, &gBattleBufferA[gActiveBattler][3]); - break; - case 54: - SetMonData(&gEnemyParty[a], MON_DATA_SHEEN, &gBattleBufferA[gActiveBattler][3]); - break; - case 55: - SetMonData(&gEnemyParty[a], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 56: - SetMonData(&gEnemyParty[a], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 57: - SetMonData(&gEnemyParty[a], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 58: - SetMonData(&gEnemyParty[a], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 59: - SetMonData(&gEnemyParty[a], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - } -} - -void LinkOpponentHandlecmd3(void) -{ - u8 *dst; - u8 i; - - MEMSET_ALT(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1], - gBattleBufferA[gActiveBattler][3 + i], gBattleBufferA[gActiveBattler][2], i, dst); - - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleLoadPokeSprite(void) -{ - u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - BattleLoadOpponentMonSprite(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(gActiveBattler)); - gBankSpriteIds[gActiveBattler] = CreateSprite( - &gUnknown_02024E8C, - GetBattlerSpriteCoord(gActiveBattler, 2), - sub_8077F68(gActiveBattler), - GetBattlerSubpriority(gActiveBattler)); - gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -240; - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = gActiveBattler; - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], gBattleMonForms[gActiveBattler]); - sub_8032984(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - gBattleBankFunc[gActiveBattler] = sub_8037A74; -} - -void LinkOpponentHandleSendOutPoke(void) -{ - gBattlerPartyIndexes[gActiveBattler] = gBattleBufferA[gActiveBattler][1]; - sub_8039430(gActiveBattler, gBattleBufferA[gActiveBattler][2]); - gBattleBankFunc[gActiveBattler] = sub_8037E30; -} - -void sub_8039430(u8 a, u8 b) -{ - u16 species; - - sub_8032AA8(a, b); - gBattlerPartyIndexes[a] = gBattleBufferA[a][1]; - species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[a]], MON_DATA_SPECIES); - gUnknown_0300434C[a] = CreateInvisibleSpriteWithCallback(sub_80312F0); - BattleLoadOpponentMonSprite(&gEnemyParty[gBattlerPartyIndexes[a]], a); - GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(a)); - gBankSpriteIds[a] = CreateSprite( - &gUnknown_02024E8C, - GetBattlerSpriteCoord(a, 2), - sub_8077F68(a), - GetBattlerSubpriority(a)); - gSprites[gUnknown_0300434C[a]].data[1] = gBankSpriteIds[a]; - gSprites[gBankSpriteIds[a]].data[0] = a; - gSprites[gBankSpriteIds[a]].data[2] = species; - gSprites[gBankSpriteIds[a]].oam.paletteNum = a; - StartSpriteAnim(&gSprites[gBankSpriteIds[a]], gBattleMonForms[a]); - gSprites[gBankSpriteIds[a]].invisible = TRUE; - gSprites[gBankSpriteIds[a]].callback = SpriteCallbackDummy; - gSprites[gUnknown_0300434C[a]].data[0] = StartSendOutMonAnimation(0, 0xFE); -} - -void LinkOpponentHandleReturnPokeToBall(void) -{ - if (gBattleBufferA[gActiveBattler][1] == 0) - { - ewram17810[gActiveBattler].unk4 = 0; - gBattleBankFunc[gActiveBattler] = sub_8039648; - } - else - { - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - sub_8032A08(gActiveBattler); - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - LinkOpponentBufferExecCompleted(); - } -} - -void sub_8039648(void) -{ - switch (ewram17810[gActiveBattler].unk4) - { - case 0: - if (ewram17800[gActiveBattler].substituteSprite) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - ewram17810[gActiveBattler].unk4 = 1; - break; - case 1: - if (!ewram17810[gActiveBattler].unk0_6) - { - ewram17810[gActiveBattler].unk4 = 0; - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 2); - gBattleBankFunc[gActiveBattler] = sub_8037BBC; - } - break; - } -} - -void LinkOpponentHandleTrainerThrow(void) -{ - s16 xOffset; - u32 gender; - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (GetBattlerPosition(gActiveBattler) & 2) - xOffset = -16; - else - xOffset = 16; - gender = gLinkPlayers[sub_803FC34(gActiveBattler)].gender; - } - else - { - xOffset = 0; - gender = gLinkPlayers[GetMultiplayerId() ^ 1].gender; - } - sub_8031A6C(gender, gActiveBattler); - GetMonSpriteTemplate_803C5A0(gender, GetBattlerPosition(gActiveBattler)); - gBankSpriteIds[gActiveBattler] = CreateSprite( - &gUnknown_02024E8C, - 176 + xOffset, 40 + 4 * (8 - gTrainerFrontPicCoords[gender].coords), - GetBattlerSubpriority(gActiveBattler)); - gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -240; - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 2; - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[gender].tag); - gSprites[gBankSpriteIds[gActiveBattler]].data[5] = gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum; - gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum = GetSpriteTileStartByTag(gTrainerFrontPicTable[gender].tag); - gSprites[gBankSpriteIds[gActiveBattler]].oam.affineParam = gender; - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; - gBattleBankFunc[gActiveBattler] = sub_803757C; -} - -void LinkOpponentHandleTrainerSlide(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleTrainerSlideBack(void) -{ - oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBankSpriteIds[gActiveBattler]].data[2] = 280; - gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; - gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], SpriteCallbackDummy); - gBattleBankFunc[gActiveBattler] = sub_80375B4; -} - -void LinkOpponentHandlecmd10(void) -{ - if (ewram17810[gActiveBattler].unk4 == 0) - { - if (ewram17800[gActiveBattler].substituteSprite) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - ewram17810[gActiveBattler].unk4++; - } - else if (!ewram17810[gActiveBattler].unk0_6) - { - ewram17810[gActiveBattler].unk4 = 0; - PlaySE12WithPanning(SE_POKE_DEAD, 63); - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_8010384; - gBattleBankFunc[gActiveBattler] = sub_8037B78; - } -} - -void LinkOpponentHandlecmd11(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd12(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleBallThrow(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlePuase(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleMoveAnimation(void) -{ - if (!mplay_80342A4(gActiveBattler)) - { - u32 r0 = gBattleBufferA[gActiveBattler][1] - | (gBattleBufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleBufferA[gActiveBattler][3]; - gAnimMovePower = gBattleBufferA[gActiveBattler][4] - | (gBattleBufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleBufferA[gActiveBattler][6] - | (gBattleBufferA[gActiveBattler][7] << 8) - | (gBattleBufferA[gActiveBattler][8] << 16) - | (gBattleBufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleBufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleBufferA[gActiveBattler][12] - | (gBattleBufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - - // Dead code. sub_8031720 always returns 0. - if (sub_8031720(r0, gAnimMoveTurn) != 0) - { - LinkOpponentBufferExecCompleted(); - } - else - { - ewram17810[gActiveBattler].unk4 = 0; - gBattleBankFunc[gActiveBattler] = sub_8039B64; - } - } -} - -void sub_8039B64(void) -{ - u16 r4 = gBattleBufferA[gActiveBattler][1] - | (gBattleBufferA[gActiveBattler][2] << 8); - u8 r7 = gBattleBufferA[gActiveBattler][11]; - - switch (ewram17810[gActiveBattler].unk4) - { - case 0: - if (ewram17800[gActiveBattler].substituteSprite && !ewram17800[gActiveBattler].unk0_3) - { - ewram17800[gActiveBattler].unk0_3 = 1; - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - } - ewram17810[gActiveBattler].unk4 = 1; - break; - case 1: - if (!ewram17810[gActiveBattler].unk0_6) - { - sub_80326EC(0); - DoMoveAnim(r4); - ewram17810[gActiveBattler].unk4 = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - sub_80326EC(1); - if ((ewram17800[gActiveBattler].substituteSprite) && r7 <= 1) - { - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); - ewram17800[gActiveBattler].unk0_3 = 0; - } - ewram17810[gActiveBattler].unk4 = 3; - } - break; - case 3: - if (!ewram17810[gActiveBattler].unk0_6) - { - sub_8031F24(); - sub_80324BC( - gActiveBattler, - gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - ewram17810[gActiveBattler].unk4 = 0; - LinkOpponentBufferExecCompleted(); - } - break; - } -} - -void LinkOpponentHandlePrintString(void) -{ - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - BufferStringBattle(*(u16 *)&gBattleBufferA[gActiveBattler][2]); - Text_InitWindow8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15); - gBattleBankFunc[gActiveBattler] = sub_8037C2C; -} - -void LinkOpponentHandlePrintStringPlayerOnly(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd18(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd19(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd20(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleOpenBag(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd22(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd23(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleHealthBarUpdate(void) -{ - s16 r7; - - load_gfxc_health_bar(0); - r7 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); - if (r7 != 0x7FFF) - { - u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - u32 hp = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); - - sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, hp, r7); - } - else - { - u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - - sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, 0, r7); - } - gBattleBankFunc[gActiveBattler] = sub_8037B24; -} - -void LinkOpponentHandleExpBarUpdate(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleStatusIconUpdate(void) -{ - if (mplay_80342A4(gActiveBattler) == 0) - { - sub_8045A5C(gHealthboxIDs[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], 9); - ewram17810[gActiveBattler].unk0_4 = 0; - gBattleBankFunc[gActiveBattler] = sub_8037FAC; - } -} - -void LinkOpponentHandleStatusAnimation(void) -{ - if (mplay_80342A4(gActiveBattler) == 0) - { - move_anim_start_t2_for_situation( - gBattleBufferA[gActiveBattler][1], - gBattleBufferA[gActiveBattler][2] - | (gBattleBufferA[gActiveBattler][3] << 8) - | (gBattleBufferA[gActiveBattler][4] << 16) - | (gBattleBufferA[gActiveBattler][5] << 24)); - gBattleBankFunc[gActiveBattler] = sub_8037FAC; - } -} - -void LinkOpponentHandleStatusXor(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd29(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleDMATransfer(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd31(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd32(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd33(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd34(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd35(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd36(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd37(void) -{ - gUnknown_020238C8.unk0_0 = 0; - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd38(void) -{ - gUnknown_020238C8.unk0_0 = gBattleBufferA[gActiveBattler][1]; - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd39(void) -{ - gUnknown_020238C8.unk0_7 = 0; - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd40(void) -{ - gUnknown_020238C8.unk0_7 ^= 1; - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleHitAnimation(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].invisible == TRUE) - { - LinkOpponentBufferExecCompleted(); - } - else - { - gDoingBattleAnim = TRUE; - gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; - sub_8047858(gActiveBattler); - gBattleBankFunc[gActiveBattler] = dp01t_0F_4_move_anim; - } -} - -void LinkOpponentHandlecmd42(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleEffectivenessSound(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == 0) - pan = -64; - else - pan = 63; - PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan); - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd44(void) -{ - PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleFaintingCry(void) -{ - PlayCry3( - GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES), - 25, 5); - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleIntroSlide(void) -{ - StartBattleIntroAnim(gBattleBufferA[gActiveBattler][1]); - gUnknown_02024DE8 |= 1; - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleTrainerBallThrow(void) -{ - u8 taskId; - - oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBankSpriteIds[gActiveBattler]].data[2] = 280; - gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; - gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], sub_803A3A8); - taskId = CreateTask(sub_803A2C4, 5); - gTasks[taskId].data[0] = gActiveBattler; - if (ewram17810[gActiveBattler].unk0_0) - gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; - ewram17840.unk9_0 = 1; - gBattleBankFunc[gActiveBattler] = nullsub_47; -} - -void sub_803A2C4(u8 taskId) -{ - u8 r9; - - r9 = gActiveBattler; - gActiveBattler = gTasks[taskId].data[0]; - if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - sub_8039430(gActiveBattler, 0); - } - else - { - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - sub_8039430(gActiveBattler, 0); - gActiveBattler ^= 2; - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - sub_8039430(gActiveBattler, 0); - gActiveBattler ^= 2; - } - gBattleBankFunc[gActiveBattler] = sub_8037840; - gActiveBattler = r9; - DestroyTask(taskId); -} - -void sub_803A3A8(struct Sprite *sprite) -{ - sub_8031B74(sprite->oam.affineParam); - sprite->oam.tileNum = sprite->data[5]; - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); -} - -void LinkOpponentHandlecmd48(void) -{ - if (gBattleBufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == 0) - { - LinkOpponentBufferExecCompleted(); - return; - } - - ewram17810[gActiveBattler].unk0_0 = 1; - if (gBattleBufferA[gActiveBattler][2] != 0) - { - if (ewram17810[gActiveBattler].unk1_1 < 2) - { - ewram17810[gActiveBattler].unk1_1++; - return; - } - else - { - ewram17810[gActiveBattler].unk1_1 = 0; - } - } - gUnknown_02024E68[gActiveBattler] = sub_8044804( - gActiveBattler, - (struct BattleInterfaceStruct2 *)&gBattleBufferA[gActiveBattler][4], - gBattleBufferA[gActiveBattler][1], - gBattleBufferA[gActiveBattler][2]); - ewram17810[gActiveBattler].unk5 = 0; - if (gBattleBufferA[gActiveBattler][2] != 0) - ewram17810[gActiveBattler].unk5 = 0x5D; - gBattleBankFunc[gActiveBattler] = sub_803A4E0; -} - -void sub_803A4E0(void) -{ - if (ewram17810[gActiveBattler].unk5++ >= 93) - { - ewram17810[gActiveBattler].unk5 = 0; - LinkOpponentBufferExecCompleted(); - } -} - -void LinkOpponentHandlecmd49(void) -{ - if (ewram17810[gActiveBattler].unk0_0) - gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd50(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleSpriteInvisibility(void) -{ - if (IsBankSpritePresent(gActiveBattler) != 0) - { - gSprites[gBankSpriteIds[gActiveBattler]].invisible = gBattleBufferA[gActiveBattler][1]; - sub_8031F88(gActiveBattler); - } - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleBattleAnimation(void) -{ - if (mplay_80342A4(gActiveBattler) == 0) - { - u8 r3 = gBattleBufferA[gActiveBattler][1]; - u16 r4 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); - - if (move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, r3, r4) != 0) - LinkOpponentBufferExecCompleted(); - else - gBattleBankFunc[gActiveBattler] = sub_8037FD8; - } -} - -void LinkOpponentHandleLinkStandbyMsg(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandleResetActionMoveSelection(void) -{ - LinkOpponentBufferExecCompleted(); -} - -void LinkOpponentHandlecmd55(void) -{ - if (gBattleBufferA[gActiveBattler][1] == 3) - gBattleOutcome = gBattleBufferA[gActiveBattler][1]; - else - gBattleOutcome = gBattleBufferA[gActiveBattler][1] ^ 3; - FadeOutMapMusic(5); - BeginFastPaletteFade(3); - LinkOpponentBufferExecCompleted(); - gBattleBankFunc[gActiveBattler] = sub_8037F34; -} - -void LinkOpponentHandlecmd56(void) -{ -} diff --git a/src/battle/battle_controller_linkpartner.c b/src/battle/battle_controller_linkpartner.c deleted file mode 100644 index 0db2f54b4..000000000 --- a/src/battle/battle_controller_linkpartner.c +++ /dev/null @@ -1,1714 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_anim.h" -#include "battle_anim_813F0F4.h" -#include "battle_interface.h" -#include "data2.h" -#include "battle_811DA74.h" -#include "battle_anim_813F0F4.h" -#include "link.h" -#include "m4a.h" -#include "main.h" -#include "palette.h" -#include "pokeball.h" -#include "pokemon.h" -#include "rom3.h" -#include "rom_8077ABC.h" -#include "sound.h" -#include "constants/songs.h" -#include "sprite.h" -#include "string_util.h" -#include "task.h" -#include "text.h" -#include "util.h" -#include "ewram.h" - -struct MovePpInfo -{ - u16 moves[4]; - u8 pp[4]; - u8 ppBonuses; -}; - -extern u16 gBattleTypeFlags; -extern u8 gDisplayedStringBattle[]; -extern u8 gBattleBufferA[][0x200]; -extern u8 gActiveBattler; -extern u32 gBattleExecBuffer; -extern u16 gBattlerPartyIndexes[]; -extern u8 gBankSpriteIds[]; -extern u8 gBattleOutcome; -extern u16 gUnknown_02024DE8; -extern u8 gUnknown_02024E68[]; -extern u8 gDoingBattleAnim; -extern u32 gTransformedPersonalities[]; -extern struct SpriteTemplate gUnknown_02024E8C; -extern s32 gAnimMoveDmg; -extern u16 gAnimMovePower; -extern u8 gAnimFriendship; -extern u16 gWeatherMoveAnim; -extern u8 gAnimMoveTurn; -extern struct Window gUnknown_03004210; -extern MainCallback gPreBattleCallback1; -extern void (*gBattleBankFunc[])(void); -extern u8 gHealthboxIDs[]; -extern u8 gUnknown_0300434C[]; -extern u8 gBattleMonForms[]; -extern u8 gAnimScriptActive; -extern void (*gAnimScriptCallback)(void); - -extern u8 move_anim_start_t3(); -extern u8 IsBankSpritePresent(); -extern void sub_8044CA0(u8); -extern void sub_8030E38(struct Sprite *); -extern void StartBattleIntroAnim(); -extern void sub_8047858(); -extern void move_anim_start_t2_for_situation(); -extern void sub_8043D84(); -extern void BufferStringBattle(); -extern void sub_8031F24(void); -extern void sub_80326EC(); -extern void DoMoveAnim(); -extern void sub_80324BC(); -extern u8 sub_8031720(); -extern u8 mplay_80342A4(); -extern void oamt_add_pos2_onto_pos1(); -extern void StoreSpriteCallbackInData(); -extern void StartAnimLinearTranslation(struct Sprite *); -extern void sub_80105EC(struct Sprite *); -extern s32 sub_803FC34(u16); -extern void LoadPlayerTrainerBankSprite(); -extern void sub_80313A0(struct Sprite *); -extern u8 StartSendOutMonAnimation(); -extern void sub_80312F0(struct Sprite *); -extern u8 CreateInvisibleSpriteWithCallback(); -extern void BattleLoadPlayerMonSprite(); -extern u8 GetBattlerSpriteCoord(); -extern u8 sub_8077F68(); -extern u8 GetBattlerSubpriority(); -extern void nullsub_10(); -extern void sub_8045A5C(); -extern void sub_804777C(); -extern void sub_8043DFC(); -//extern s16 sub_8045C78(); -extern void sub_80440EC(); -extern void HandleLowHpMusicChange(); -extern void nullsub_9(u16); -extern void sub_8043DB0(); -extern void move_anim_start_t4(); -extern void c3_0802FDF4(u8); -extern void sub_8031F88(); -extern void c2_8011A1C(void); - -// this file's functions - -void LinkPartnerBufferRunCommand(void); -void sub_811E0A0(void); -void LinkPartnerBufferExecCompleted(void); -u32 dp01_getattr_by_ch1_for_player_pokemon(u8 a, u8 *b); -void sub_811EC68(u8); -void sub_811F864(u8, u8); -void sub_811FA5C(void); -void sub_811FF30(void); -void sub_812071C(u8); -void sub_81208E0(void); - -void LinkPartnerHandleGetAttributes(void); -void LinkPartnerHandlecmd1(void); -void LinkPartnerHandleSetAttributes(void); -void LinkPartnerHandlecmd3(void); -void LinkPartnerHandleLoadPokeSprite(void); -void LinkPartnerHandleSendOutPoke(void); -void LinkPartnerHandleReturnPokeToBall(void); -void LinkPartnerHandleTrainerThrow(void); -void LinkPartnerHandleTrainerSlide(void); -void LinkPartnerHandleTrainerSlideBack(void); -void LinkPartnerHandlecmd10(void); -void LinkPartnerHandlecmd11(void); -void LinkPartnerHandlecmd12(void); -void LinkPartnerHandleBallThrow(void); -void LinkPartnerHandlePuase(void); -void LinkPartnerHandleMoveAnimation(void); -void LinkPartnerHandlePrintString(void); -void LinkPartnerHandlePrintStringPlayerOnly(void); -void LinkPartnerHandlecmd18(void); -void LinkPartnerHandlecmd19(void); -void LinkPartnerHandlecmd20(void); -void LinkPartnerHandleOpenBag(void); -void LinkPartnerHandlecmd22(void); -void LinkPartnerHandlecmd23(void); -void LinkPartnerHandleHealthBarUpdate(void); -void LinkPartnerHandleExpBarUpdate(void); -void LinkPartnerHandleStatusIconUpdate(void); -void LinkPartnerHandleStatusAnimation(void); -void LinkPartnerHandleStatusXor(void); -void LinkPartnerHandlecmd29(void); -void LinkPartnerHandleDMATransfer(void); -void LinkPartnerHandlecmd31(void); -void LinkPartnerHandlecmd32(void); -void LinkPartnerHandlecmd33(void); -void LinkPartnerHandlecmd34(void); -void LinkPartnerHandlecmd35(void); -void LinkPartnerHandlecmd36(void); -void LinkPartnerHandlecmd37(void); -void LinkPartnerHandlecmd38(void); -void LinkPartnerHandlecmd39(void); -void LinkPartnerHandlecmd40(void); -void LinkPartnerHandleHitAnimation(void); -void LinkPartnerHandlecmd42(void); -void LinkPartnerHandleEffectivenessSound(void); -void LinkPartnerHandlecmd44(void); -void LinkPartnerHandleFaintingCry(void); -void LinkPartnerHandleIntroSlide(void); -void LinkPartnerHandleTrainerBallThrow(void); -void LinkPartnerHandlecmd48(void); -void LinkPartnerHandlecmd49(void); -void LinkPartnerHandlecmd50(void); -void LinkPartnerHandleSpriteInvisibility(void); -void LinkPartnerHandleBattleAnimation(void); -void LinkPartnerHandleLinkStandbyMsg(void); -void LinkPartnerHandleResetActionMoveSelection(void); -void LinkPartnerHandlecmd55(void); -void LinkPartnerHandlecmd56(void); - -// const data -typedef void (*BattleBufferCmd) (void); -static const BattleBufferCmd gLinkPartnerBufferCommands[] = -{ - LinkPartnerHandleGetAttributes, - LinkPartnerHandlecmd1, - LinkPartnerHandleSetAttributes, - LinkPartnerHandlecmd3, - LinkPartnerHandleLoadPokeSprite, - LinkPartnerHandleSendOutPoke, - LinkPartnerHandleReturnPokeToBall, - LinkPartnerHandleTrainerThrow, - LinkPartnerHandleTrainerSlide, - LinkPartnerHandleTrainerSlideBack, - LinkPartnerHandlecmd10, - LinkPartnerHandlecmd11, - LinkPartnerHandlecmd12, - LinkPartnerHandleBallThrow, - LinkPartnerHandlePuase, - LinkPartnerHandleMoveAnimation, - LinkPartnerHandlePrintString, - LinkPartnerHandlePrintStringPlayerOnly, - LinkPartnerHandlecmd18, - LinkPartnerHandlecmd19, - LinkPartnerHandlecmd20, - LinkPartnerHandleOpenBag, - LinkPartnerHandlecmd22, - LinkPartnerHandlecmd23, - LinkPartnerHandleHealthBarUpdate, - LinkPartnerHandleExpBarUpdate, - LinkPartnerHandleStatusIconUpdate, - LinkPartnerHandleStatusAnimation, - LinkPartnerHandleStatusXor, - LinkPartnerHandlecmd29, - LinkPartnerHandleDMATransfer, - LinkPartnerHandlecmd31, - LinkPartnerHandlecmd32, - LinkPartnerHandlecmd33, - LinkPartnerHandlecmd34, - LinkPartnerHandlecmd35, - LinkPartnerHandlecmd36, - LinkPartnerHandlecmd37, - LinkPartnerHandlecmd38, - LinkPartnerHandlecmd39, - LinkPartnerHandlecmd40, - LinkPartnerHandleHitAnimation, - LinkPartnerHandlecmd42, - LinkPartnerHandleEffectivenessSound, - LinkPartnerHandlecmd44, - LinkPartnerHandleFaintingCry, - LinkPartnerHandleIntroSlide, - LinkPartnerHandleTrainerBallThrow, - LinkPartnerHandlecmd48, - LinkPartnerHandlecmd49, - LinkPartnerHandlecmd50, - LinkPartnerHandleSpriteInvisibility, - LinkPartnerHandleBattleAnimation, - LinkPartnerHandleLinkStandbyMsg, - LinkPartnerHandleResetActionMoveSelection, - LinkPartnerHandlecmd55, - LinkPartnerHandlecmd56, -}; -// code starts here - -void nullsub_74(void) -{ -} - -void SetBankFuncToLinkPartnerBufferRunCommand(void) -{ - gBattleBankFunc[gActiveBattler] = LinkPartnerBufferRunCommand; -} - -void LinkPartnerBufferRunCommand(void) -{ - if (gBattleExecBuffer & gBitTable[gActiveBattler]) - { - if (gBattleBufferA[gActiveBattler][0] <= 0x38) - gLinkPartnerBufferCommands[gBattleBufferA[gActiveBattler][0]](); - else - LinkPartnerBufferExecCompleted(); - } -} - -void sub_811DAE4(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - LinkPartnerBufferExecCompleted(); -} - -void sub_811DB1C(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - nullsub_10(0); - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - LinkPartnerBufferExecCompleted(); - } -} - -void sub_811DB84(void) -{ - if ((--ewram17810[gActiveBattler].unk9) == 0xFF) - { - ewram17810[gActiveBattler].unk9 = 0; - LinkPartnerBufferExecCompleted(); - } -} - -void sub_811DBC0(void) -{ - bool8 r6 = FALSE; - - if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & 0x40))) - { - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) - r6 = TRUE; - } - else - { - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxIDs[gActiveBattler ^ 2]].callback == SpriteCallbackDummy) - r6 = TRUE; - } - if (IsCryPlayingOrClearCrySongs()) - r6 = FALSE; - if (r6) - { - ewram17810[gActiveBattler].unk9 = 3; - gBattleBankFunc[gActiveBattler] = sub_811DB84; - } -} - -void sub_811DCA0(void) -{ - u8 r2; - - if (!ewram17810[gActiveBattler].unk0_3) - { - // I couldn't get it to work as a bitfield here - r2 = *((u8 *)&ewram17810[gActiveBattler ^ 2]) & 8; - if (!r2 && (++ewram17810[gActiveBattler].unk9) != 1) - { - ewram17810[gActiveBattler].unk9 = r2; - if (IsDoubleBattle() && !(gBattleTypeFlags & 0x40)) - { - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler ^ 2]]); - sub_8045A5C(gHealthboxIDs[gActiveBattler ^ 2], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], 0); - sub_804777C(gActiveBattler ^ 2); - sub_8043DFC(gHealthboxIDs[gActiveBattler ^ 2]); - } - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); - sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 0); - sub_804777C(gActiveBattler); - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - (s8)ewram17810[4].unk9 &= ~1; - gBattleBankFunc[gActiveBattler] = sub_811DBC0; - } - } -} - -void sub_811DDE8(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].animEnded - && gSprites[gBankSpriteIds[gActiveBattler]].pos2.x == 0) - LinkPartnerBufferExecCompleted(); -} - -void bx_t3_healthbar_update(void) -{ - s16 r4; - - r4 = sub_8045C78(gActiveBattler, gHealthboxIDs[gActiveBattler], 0, 0); - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - if (r4 != -1) - { - sub_80440EC(gHealthboxIDs[gActiveBattler], r4, 0); - } - else - { - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - LinkPartnerBufferExecCompleted(); - } -} - -void sub_811DE98(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].pos1.y + gSprites[gBankSpriteIds[gActiveBattler]].pos2.y > 160) - { - nullsub_9(GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - FreeOamMatrix(gSprites[gBankSpriteIds[gActiveBattler]].oam.matrixNum); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - LinkPartnerBufferExecCompleted(); - } -} - -void sub_811DF34(void) -{ - if (!ewram17810[gActiveBattler].unk0_6) - { - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - LinkPartnerBufferExecCompleted(); - } -} - -void sub_811DFA0(void) -{ - if (gUnknown_03004210.state == 0) - LinkPartnerBufferExecCompleted(); -} - -void bx_blink_t3(void) -{ - u8 spriteId = gBankSpriteIds[gActiveBattler]; - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = 0; - LinkPartnerBufferExecCompleted(); - } - else - { - if ((gSprites[spriteId].data[1] % 4) == 0) - { - gSprites[spriteId].invisible ^= 1; - } - gSprites[spriteId].data[1]++; - } -} - -void sub_811E034(void) -{ - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) - { - if (ewram17800[gActiveBattler].substituteSprite) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); - gBattleBankFunc[gActiveBattler] = sub_811E0A0; - } -} - -void sub_811E0A0(void) -{ - if (!ewram17810[gActiveBattler].unk0_6) - LinkPartnerBufferExecCompleted(); -} - -void sub_811E0CC(void) -{ - if (ewram17810[gActiveBattler].unk1_0) - { - ewram17810[gActiveBattler].unk0_7 = 0; - ewram17810[gActiveBattler].unk1_0 = 0; - FreeSpriteTilesByTag(0x27F9); - FreeSpritePaletteByTag(0x27F9); - CreateTask(c3_0802FDF4, 10); - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 0); - sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 0); - sub_804777C(gActiveBattler); - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - sub_8031F88(gActiveBattler); - gBattleBankFunc[gActiveBattler] = sub_811E034; - } -} - -void sub_811E1BC(void) -{ - if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) - sub_8141828(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); - if (gSprites[gUnknown_0300434C[gActiveBattler]].callback == SpriteCallbackDummy - && !ewram17810[gActiveBattler].unk0_3) - { - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); - gBattleBankFunc[gActiveBattler] = sub_811E0CC; - } -} - -void sub_811E258(void) -{ - if (gReceivedRemoteLinkPlayers == 0) - { - m4aSongNumStop(0x5A); - gMain.inBattle = FALSE; - gMain.callback1 = gPreBattleCallback1; - SetMainCallback2(c2_8011A1C); - } -} - -void sub_811E29C(void) -{ - if (!gPaletteFade.active) - { - if (gBattleTypeFlags & 2) - { - sub_800832C(); - gBattleBankFunc[gActiveBattler] = sub_811E258; - } - else - { - m4aSongNumStop(0x5A); - gMain.inBattle = FALSE; - gMain.callback1 = gPreBattleCallback1; - SetMainCallback2(gMain.savedCallback); - } - } -} - -void LinkPartnerBufferExecCompleted(void) -{ - u8 multiplayerId; - - gBattleBankFunc[gActiveBattler] = LinkPartnerBufferRunCommand; - if (gBattleTypeFlags & 2) - { - multiplayerId = GetMultiplayerId(); - PrepareBufferDataTransferLink(2, 4, &multiplayerId); - gBattleBufferA[gActiveBattler][0] = 0x38; - } - else - { - gBattleExecBuffer &= ~gBitTable[gActiveBattler]; - } -} - -void sub_811E38C(void) -{ - if (!ewram17810[gActiveBattler].unk0_4) - LinkPartnerBufferExecCompleted(); -} - -void sub_811E3B8(void) -{ - if (!ewram17810[gActiveBattler].unk0_5) - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleGetAttributes(void) -{ - u8 unk[256]; - int r6 = 0; - s32 i; - - if (gBattleBufferA[gActiveBattler][2] == 0) - { - r6 = dp01_getattr_by_ch1_for_player_pokemon(gBattlerPartyIndexes[gActiveBattler], unk); - } - else - { - u8 r4 = gBattleBufferA[gActiveBattler][2]; - - for (i = 0; i < 6; i++) - { - if (r4 & 1) - r6 += dp01_getattr_by_ch1_for_player_pokemon(i, unk + r6); - r4 >>= 1; - } - } - Emitcmd29(1, r6, unk); - LinkPartnerBufferExecCompleted(); -} - -// Duplicate of dp01_getattr_by_ch1_for_player_pokemon_ -u32 dp01_getattr_by_ch1_for_player_pokemon(u8 a, u8 *buffer) -{ - struct BattlePokemon battlePokemon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; - - switch (gBattleBufferA[gActiveBattler][1]) - { - case 0: - battlePokemon.species = GetMonData(&gPlayerParty[a], MON_DATA_SPECIES); - battlePokemon.item = GetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM); - for (size = 0; size < 4; size++) - { - battlePokemon.moves[size] = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + size); - battlePokemon.pp[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); - } - battlePokemon.ppBonuses = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); - battlePokemon.friendship = GetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP); - battlePokemon.experience = GetMonData(&gPlayerParty[a], MON_DATA_EXP); - battlePokemon.hpIV = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); - battlePokemon.attackIV = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); - battlePokemon.defenseIV = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); - battlePokemon.speedIV = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); - battlePokemon.spAttackIV = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); - battlePokemon.spDefenseIV = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); - battlePokemon.personality = GetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY); - battlePokemon.status1 = GetMonData(&gPlayerParty[a], MON_DATA_STATUS); - battlePokemon.level = GetMonData(&gPlayerParty[a], MON_DATA_LEVEL); - battlePokemon.hp = GetMonData(&gPlayerParty[a], MON_DATA_HP); - battlePokemon.maxHP = GetMonData(&gPlayerParty[a], MON_DATA_MAX_HP); - battlePokemon.attack = GetMonData(&gPlayerParty[a], MON_DATA_ATK); - battlePokemon.defense = GetMonData(&gPlayerParty[a], MON_DATA_DEF); - battlePokemon.speed = GetMonData(&gPlayerParty[a], MON_DATA_SPEED); - battlePokemon.spAttack = GetMonData(&gPlayerParty[a], MON_DATA_SPATK); - battlePokemon.spDefense = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF); - battlePokemon.isEgg = GetMonData(&gPlayerParty[a], MON_DATA_IS_EGG); - battlePokemon.altAbility = GetMonData(&gPlayerParty[a], MON_DATA_ALT_ABILITY); - battlePokemon.otId = GetMonData(&gPlayerParty[a], MON_DATA_OT_ID); - GetMonData(&gPlayerParty[a], MON_DATA_NICKNAME, nickname); - StringCopy10(battlePokemon.nickname, nickname); - GetMonData(&gPlayerParty[a], MON_DATA_OT_NAME, battlePokemon.otName); - MEMCPY_ALT(&battlePokemon, buffer, sizeof(battlePokemon), size, src); - break; - case 1: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPECIES); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 2: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 3: - for (size = 0; size < 4; size++) - { - moveData.moves[size] = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); - MEMCPY_ALT(&moveData, buffer, sizeof(moveData), size, src); - break; - case 4: - case 5: - case 6: - case 7: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 8: - for (size = 0; size < 4; size++) - buffer[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); - buffer[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); - size++; - break; - case 9: - case 10: - case 11: - case 12: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9); - size = 1; - break; - case 17: - data32 = GetMonData(&gPlayerParty[a], MON_DATA_OT_ID); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case 18: - data32 = GetMonData(&gPlayerParty[a], MON_DATA_EXP); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case 19: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_EV); - size = 1; - break; - case 20: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_EV); - size = 1; - break; - case 21: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_EV); - size = 1; - break; - case 22: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_EV); - size = 1; - break; - case 23: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_EV); - size = 1; - break; - case 24: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_EV); - size = 1; - break; - case 25: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP); - size = 1; - break; - case 26: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_POKERUS); - size = 1; - break; - case 27: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_LOCATION); - size = 1; - break; - case 28: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_LEVEL); - size = 1; - break; - case 29: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_GAME); - size = 1; - break; - case 30: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_POKEBALL); - size = 1; - break; - case 31: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); - buffer[1] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); - buffer[2] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); - buffer[3] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); - buffer[4] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); - buffer[5] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); - size = 6; - break; - case 32: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); - size = 1; - break; - case 33: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); - size = 1; - break; - case 34: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); - size = 1; - break; - case 35: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); - size = 1; - break; - case 36: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); - size = 1; - break; - case 37: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); - size = 1; - break; - case 38: - data32 = GetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - buffer[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case 39: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_CHECKSUM); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 40: - data32 = GetMonData(&gPlayerParty[a], MON_DATA_STATUS); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - buffer[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case 41: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_LEVEL); - size = 1; - break; - case 42: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_HP); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 43: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_MAX_HP); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 44: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_ATK); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 45: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_DEF); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 46: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPEED); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 47: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPATK); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 48: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 49: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_COOL); - size = 1; - break; - case 50: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_BEAUTY); - size = 1; - break; - case 51: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_CUTE); - size = 1; - break; - case 52: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SMART); - size = 1; - break; - case 53: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_TOUGH); - size = 1; - break; - case 54: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SHEEN); - size = 1; - break; - case 55: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_COOL_RIBBON); - size = 1; - break; - case 56: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case 57: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case 58: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SMART_RIBBON); - size = 1; - break; - case 59: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - return size; -} - -void LinkPartnerHandlecmd1(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleSetAttributes(void) -{ - u8 i; - u8 r4; - - if (gBattleBufferA[gActiveBattler][2] == 0) - { - sub_811EC68(gBattlerPartyIndexes[gActiveBattler]); - } - else - { - r4 = gBattleBufferA[gActiveBattler][2]; - for (i = 0; i < 6; i++) - { - if (r4 & 1) - sub_811EC68(i); - r4 >>= 1; - } - } - LinkPartnerBufferExecCompleted(); -} - -// Duplicate of dp01_setattr_by_ch1_for_player_pokemon -void sub_811EC68(u8 a) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleBufferA[gActiveBattler][1]) - { - case 0: - { - u8 iv; - - SetMonData(&gPlayerParty[a], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < 4; i++) - { - SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gPlayerParty[a], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gPlayerParty[a], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gPlayerParty[a], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gPlayerParty[a], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gPlayerParty[a], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gPlayerParty[a], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gPlayerParty[a], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gPlayerParty[a], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gPlayerParty[a], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gPlayerParty[a], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case 1: - SetMonData(&gPlayerParty[a], MON_DATA_SPECIES, &gBattleBufferA[gActiveBattler][3]); - break; - case 2: - SetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]); - break; - case 3: - for (i = 0; i < 4; i++) - { - SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gPlayerParty[a], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case 4: - case 5: - case 6: - case 7: - SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4, &gBattleBufferA[gActiveBattler][3]); - break; - case 8: - SetMonData(&gPlayerParty[a], MON_DATA_PP1, &gBattleBufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[a], MON_DATA_PP2, &gBattleBufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[a], MON_DATA_PP3, &gBattleBufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[a], MON_DATA_PP4, &gBattleBufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBattler][7]); - break; - case 9: - case 10: - case 11: - case 12: - SetMonData(&gPlayerParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9, &gBattleBufferA[gActiveBattler][3]); - break; - case 17: - SetMonData(&gPlayerParty[a], MON_DATA_OT_ID, &gBattleBufferA[gActiveBattler][3]); - break; - case 18: - SetMonData(&gPlayerParty[a], MON_DATA_EXP, &gBattleBufferA[gActiveBattler][3]); - break; - case 19: - SetMonData(&gPlayerParty[a], MON_DATA_HP_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 20: - SetMonData(&gPlayerParty[a], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 21: - SetMonData(&gPlayerParty[a], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 22: - SetMonData(&gPlayerParty[a], MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 23: - SetMonData(&gPlayerParty[a], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 24: - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 25: - SetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBattler][3]); - break; - case 26: - SetMonData(&gPlayerParty[a], MON_DATA_POKERUS, &gBattleBufferA[gActiveBattler][3]); - break; - case 27: - SetMonData(&gPlayerParty[a], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBattler][3]); - break; - case 28: - SetMonData(&gPlayerParty[a], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBattler][3]); - break; - case 29: - SetMonData(&gPlayerParty[a], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBattler][3]); - break; - case 30: - SetMonData(&gPlayerParty[a], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBattler][3]); - break; - case 31: - SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][7]); - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][8]); - break; - case 32: - SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 33: - SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 34: - SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 35: - SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 36: - SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 37: - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 38: - SetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBattler][3]); - break; - case 39: - SetMonData(&gPlayerParty[a], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBattler][3]); - break; - case 40: - SetMonData(&gPlayerParty[a], MON_DATA_STATUS, &gBattleBufferA[gActiveBattler][3]); - break; - case 41: - SetMonData(&gPlayerParty[a], MON_DATA_LEVEL, &gBattleBufferA[gActiveBattler][3]); - break; - case 42: - SetMonData(&gPlayerParty[a], MON_DATA_HP, &gBattleBufferA[gActiveBattler][3]); - break; - case 43: - SetMonData(&gPlayerParty[a], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBattler][3]); - break; - case 44: - SetMonData(&gPlayerParty[a], MON_DATA_ATK, &gBattleBufferA[gActiveBattler][3]); - break; - case 45: - SetMonData(&gPlayerParty[a], MON_DATA_DEF, &gBattleBufferA[gActiveBattler][3]); - break; - case 46: - SetMonData(&gPlayerParty[a], MON_DATA_SPEED, &gBattleBufferA[gActiveBattler][3]); - break; - case 47: - SetMonData(&gPlayerParty[a], MON_DATA_SPATK, &gBattleBufferA[gActiveBattler][3]); - break; - case 48: - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF, &gBattleBufferA[gActiveBattler][3]); - break; - case 49: - SetMonData(&gPlayerParty[a], MON_DATA_COOL, &gBattleBufferA[gActiveBattler][3]); - break; - case 50: - SetMonData(&gPlayerParty[a], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBattler][3]); - break; - case 51: - SetMonData(&gPlayerParty[a], MON_DATA_CUTE, &gBattleBufferA[gActiveBattler][3]); - break; - case 52: - SetMonData(&gPlayerParty[a], MON_DATA_SMART, &gBattleBufferA[gActiveBattler][3]); - break; - case 53: - SetMonData(&gPlayerParty[a], MON_DATA_TOUGH, &gBattleBufferA[gActiveBattler][3]); - break; - case 54: - SetMonData(&gPlayerParty[a], MON_DATA_SHEEN, &gBattleBufferA[gActiveBattler][3]); - break; - case 55: - SetMonData(&gPlayerParty[a], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 56: - SetMonData(&gPlayerParty[a], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 57: - SetMonData(&gPlayerParty[a], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 58: - SetMonData(&gPlayerParty[a], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 59: - SetMonData(&gPlayerParty[a], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - } - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); -} - -void LinkPartnerHandlecmd3(void) -{ - u8 *dst; - u8 i; - - MEMSET_ALT(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1], - gBattleBufferA[gActiveBattler][3 + i], gBattleBufferA[gActiveBattler][2], i, dst); - - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleLoadPokeSprite(void) -{ - BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - GetMonSpriteTemplate_803C56C( - GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES), - GetBattlerPosition(gActiveBattler)); - gBankSpriteIds[gActiveBattler] = CreateSprite( - &gUnknown_02024E8C, - GetBattlerSpriteCoord(gActiveBattler, 2), - sub_8077F68(gActiveBattler), - GetBattlerSubpriority(gActiveBattler)); - gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -240; - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = gActiveBattler; - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], gBattleMonForms[gActiveBattler]); - gBattleBankFunc[gActiveBattler] = sub_811DDE8; -} - -void LinkPartnerHandleSendOutPoke(void) -{ - sub_8032AA8(gActiveBattler, gBattleBufferA[gActiveBattler][2]); - gBattlerPartyIndexes[gActiveBattler] = gBattleBufferA[gActiveBattler][1]; - BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - sub_811F864(gActiveBattler, gBattleBufferA[gActiveBattler][2]); - gBattleBankFunc[gActiveBattler] = sub_811E1BC; -} - -void sub_811F864(u8 a, u8 b) -{ - u16 species; - - sub_8032AA8(a, b); - gBattlerPartyIndexes[a] = gBattleBufferA[a][1]; - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[a]], MON_DATA_SPECIES); - gUnknown_0300434C[a] = CreateInvisibleSpriteWithCallback(sub_80312F0); - GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(a)); - gBankSpriteIds[a] = CreateSprite( - &gUnknown_02024E8C, - GetBattlerSpriteCoord(a, 2), - sub_8077F68(a), - GetBattlerSubpriority(a)); - gSprites[gUnknown_0300434C[a]].data[1] = gBankSpriteIds[a]; - gSprites[gBankSpriteIds[a]].data[0] = a; - gSprites[gBankSpriteIds[a]].data[2] = species; - gSprites[gBankSpriteIds[a]].oam.paletteNum = a; - StartSpriteAnim(&gSprites[gBankSpriteIds[a]], gBattleMonForms[a]); - gSprites[gBankSpriteIds[a]].invisible = TRUE; - gSprites[gBankSpriteIds[a]].callback = SpriteCallbackDummy; - gSprites[gUnknown_0300434C[a]].data[0] = StartSendOutMonAnimation(0, 0xFF); -} - -void LinkPartnerHandleReturnPokeToBall(void) -{ - if (gBattleBufferA[gActiveBattler][1] == 0) - { - ewram17810[gActiveBattler].unk4 = 0; - gBattleBankFunc[gActiveBattler] = sub_811FA5C; - } - else - { - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - LinkPartnerBufferExecCompleted(); - } -} - -void sub_811FA5C(void) -{ - switch (ewram17810[gActiveBattler].unk4) - { - case 0: - if (ewram17800[gActiveBattler].substituteSprite) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - ewram17810[gActiveBattler].unk4 = 1; - break; - case 1: - if (!ewram17810[gActiveBattler].unk0_6) - { - ewram17810[gActiveBattler].unk4 = 0; - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 1); - gBattleBankFunc[gActiveBattler] = sub_811DF34; - } - break; - } -} - -void LinkPartnerHandleTrainerThrow(void) -{ - s16 xOffset; - u32 gender; - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (GetBattlerPosition(gActiveBattler) & 2) - xOffset = 16; - else - xOffset = -16; - gender = gLinkPlayers[sub_803FC34(gActiveBattler)].gender; - } - else - { - xOffset = 0; - gender = gLinkPlayers[GetMultiplayerId() ^ 1].gender; - } - LoadPlayerTrainerBankSprite(gender, gActiveBattler); - GetMonSpriteTemplate_803C5A0(gender, GetBattlerPosition(gActiveBattler)); - gBankSpriteIds[gActiveBattler] = CreateSprite( - &gUnknown_02024E8C, - 80 + xOffset, 80 + 4 * (8 - gTrainerBackPicCoords[gender].coords), - GetBattlerSubpriority(gActiveBattler)); - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = 240; - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = -2; - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; - gBattleBankFunc[gActiveBattler] = sub_811DAE4; -} - -void LinkPartnerHandleTrainerSlide(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleTrainerSlideBack(void) -{ - oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBankSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; - gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], SpriteCallbackDummy); - gBattleBankFunc[gActiveBattler] = sub_811DB1C; -} - -void LinkPartnerHandlecmd10(void) -{ - if (ewram17810[gActiveBattler].unk4 == 0) - { - if (ewram17800[gActiveBattler].substituteSprite) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - ewram17810[gActiveBattler].unk4++; - } - else if (!ewram17810[gActiveBattler].unk0_6) - { - ewram17810[gActiveBattler].unk4 = 0; - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - PlaySE12WithPanning(SE_POKE_DEAD, -64); - gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; - gSprites[gBankSpriteIds[gActiveBattler]].data[2] = 5; - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80105EC; - gBattleBankFunc[gActiveBattler] = sub_811DE98; - } -} - -void LinkPartnerHandlecmd11(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd12(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleBallThrow(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlePuase(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleMoveAnimation(void) -{ - if (!mplay_80342A4(gActiveBattler)) - { - u32 r0 = gBattleBufferA[gActiveBattler][1] - | (gBattleBufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleBufferA[gActiveBattler][3]; - gAnimMovePower = gBattleBufferA[gActiveBattler][4] - | (gBattleBufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleBufferA[gActiveBattler][6] - | (gBattleBufferA[gActiveBattler][7] << 8) - | (gBattleBufferA[gActiveBattler][8] << 16) - | (gBattleBufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleBufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleBufferA[gActiveBattler][12] - | (gBattleBufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - - if (sub_8031720(r0, gAnimMoveTurn) != 0) - LinkPartnerBufferExecCompleted(); - else - { - ewram17810[gActiveBattler].unk4 = 0; - gBattleBankFunc[gActiveBattler] = sub_811FF30; - } - } -} - -void sub_811FF30(void) -{ - u16 r4 = gBattleBufferA[gActiveBattler][1] - | (gBattleBufferA[gActiveBattler][2] << 8); - u8 r7 = gBattleBufferA[gActiveBattler][11]; - - switch (ewram17810[gActiveBattler].unk4) - { - case 0: - if (ewram17800[gActiveBattler].substituteSprite && !ewram17800[gActiveBattler].unk0_3) - { - ewram17800[gActiveBattler].unk0_3 = 1; - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - } - ewram17810[gActiveBattler].unk4 = 1; - break; - case 1: - if (!ewram17810[gActiveBattler].unk0_6) - { - sub_80326EC(0); - DoMoveAnim(r4); - ewram17810[gActiveBattler].unk4 = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - sub_80326EC(1); - if ((ewram17800[gActiveBattler].substituteSprite) && r7 <= 1) - { - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); - ewram17800[gActiveBattler].unk0_3 = 0; - } - ewram17810[gActiveBattler].unk4 = 3; - } - break; - case 3: - if (!ewram17810[gActiveBattler].unk0_6) - { - sub_8031F24(); - sub_80324BC( - gActiveBattler, - gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - ewram17810[gActiveBattler].unk4 = 0; - LinkPartnerBufferExecCompleted(); - } - break; - } -} - -void LinkPartnerHandlePrintString(void) -{ - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - BufferStringBattle(*(u16 *)&gBattleBufferA[gActiveBattler][2]); - Text_InitWindow8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15); - gBattleBankFunc[gActiveBattler] = sub_811DFA0; -} - -void LinkPartnerHandlePrintStringPlayerOnly(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd18(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd19(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd20(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleOpenBag(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd22(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd23(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleHealthBarUpdate(void) -{ - s16 r7; - - load_gfxc_health_bar(0); - r7 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); - if (r7 != 0x7FFF) - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - u32 hp = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); - - sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, hp, r7); - } - else - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - - sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, 0, r7); - } - gBattleBankFunc[gActiveBattler] = bx_t3_healthbar_update; -} - -void LinkPartnerHandleExpBarUpdate(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleStatusIconUpdate(void) -{ - if (mplay_80342A4(gActiveBattler) == 0) - { - sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 9); - ewram17810[gActiveBattler].unk0_4 = 0; - gBattleBankFunc[gActiveBattler] = sub_811E38C; - } -} - -void LinkPartnerHandleStatusAnimation(void) -{ - if (mplay_80342A4(gActiveBattler) == 0) - { - move_anim_start_t2_for_situation( - gBattleBufferA[gActiveBattler][1], - gBattleBufferA[gActiveBattler][2] - | (gBattleBufferA[gActiveBattler][3] << 8) - | (gBattleBufferA[gActiveBattler][4] << 16) - | (gBattleBufferA[gActiveBattler][5] << 24)); - gBattleBankFunc[gActiveBattler] = sub_811E38C; - } -} - -void LinkPartnerHandleStatusXor(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd29(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleDMATransfer(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd31(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd32(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd33(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd34(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd35(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd36(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd37(void) -{ - gUnknown_020238C8.unk0_0 = 0; - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd38(void) -{ - gUnknown_020238C8.unk0_0 = gBattleBufferA[gActiveBattler][1]; - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd39(void) -{ - gUnknown_020238C8.unk0_7 = 0; - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd40(void) -{ - gUnknown_020238C8.unk0_7 ^= 1; - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleHitAnimation(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].invisible == TRUE) - { - LinkPartnerBufferExecCompleted(); - } - else - { - gDoingBattleAnim = TRUE; - gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; - sub_8047858(gActiveBattler); - gBattleBankFunc[gActiveBattler] = bx_blink_t3; - } -} - -void LinkPartnerHandlecmd42(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleEffectivenessSound(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == 0) - pan = -64; - else - pan = 63; - PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan); - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd44(void) -{ - PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleFaintingCry(void) -{ - PlayCry3( - GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES), - -25, 5); - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleIntroSlide(void) -{ - StartBattleIntroAnim(gBattleBufferA[gActiveBattler][1]); - gUnknown_02024DE8 |= 1; - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleTrainerBallThrow(void) -{ - u8 r4; - u8 taskId; - - oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 50; - gSprites[gBankSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; - gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - gSprites[gBankSpriteIds[gActiveBattler]].data[5] = gActiveBattler; - StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], sub_8030E38); - StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 1); - r4 = AllocSpritePalette(0xD6F9); - LoadCompressedPalette( - gTrainerBackPicPaletteTable[gLinkPlayers[sub_803FC34(gActiveBattler)].gender].data, - 0x100 + r4 * 16, 0x20); - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = r4; - taskId = CreateTask(sub_812071C, 5); - gTasks[taskId].data[0] = gActiveBattler; - if (ewram17810[gActiveBattler].unk0_0) - gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; - ewram17840.unk9_0 = 1; - gBattleBankFunc[gActiveBattler] = nullsub_74; -} - -void sub_812071C(u8 taskId) -{ - u8 r9; - - if (gTasks[taskId].data[1] < 24) - { - gTasks[taskId].data[1]++; - return; - } - - r9 = gActiveBattler; - gActiveBattler = gTasks[taskId].data[0]; - if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - sub_811F864(gActiveBattler, 0); - } - else - { - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - sub_811F864(gActiveBattler, 0); - gActiveBattler ^= 2; - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - sub_811F864(gActiveBattler, 0); - gActiveBattler ^= 2; - } - gBattleBankFunc[gActiveBattler] = sub_811DCA0; - gActiveBattler = r9; - DestroyTask(taskId); -} - -void LinkPartnerHandlecmd48(void) -{ - if (gBattleBufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == 0) - { - LinkPartnerBufferExecCompleted(); - return; - } - - ewram17810[gActiveBattler].unk0_0 = 1; - gUnknown_02024E68[gActiveBattler] = sub_8044804( - gActiveBattler, - (struct BattleInterfaceStruct2 *)&gBattleBufferA[gActiveBattler][4], - gBattleBufferA[gActiveBattler][1], - gBattleBufferA[gActiveBattler][2]); - ewram17810[gActiveBattler].unk5 = 0; - if (gBattleBufferA[gActiveBattler][2] != 0) - ewram17810[gActiveBattler].unk5 = 0x5D; - gBattleBankFunc[gActiveBattler] = sub_81208E0; -} - -void sub_81208E0(void) -{ - if (ewram17810[gActiveBattler].unk5++ >= 93) - { - ewram17810[gActiveBattler].unk5 = 0; - LinkPartnerBufferExecCompleted(); - } -} - -void LinkPartnerHandlecmd49(void) -{ - if (ewram17810[gActiveBattler].unk0_0) - gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd50(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleSpriteInvisibility(void) -{ - if (IsBankSpritePresent(gActiveBattler) != 0) - { - gSprites[gBankSpriteIds[gActiveBattler]].invisible = gBattleBufferA[gActiveBattler][1]; - sub_8031F88(gActiveBattler); - } - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleBattleAnimation(void) -{ - if (mplay_80342A4(gActiveBattler) == 0) - { - u8 r3 = gBattleBufferA[gActiveBattler][1]; - u16 r4 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); - - if (move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, r3, r4) != 0) - LinkPartnerBufferExecCompleted(); - else - gBattleBankFunc[gActiveBattler] = sub_811E3B8; - } -} - -void LinkPartnerHandleLinkStandbyMsg(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandleResetActionMoveSelection(void) -{ - LinkPartnerBufferExecCompleted(); -} - -void LinkPartnerHandlecmd55(void) -{ - gBattleOutcome = gBattleBufferA[gActiveBattler][1]; - FadeOutMapMusic(5); - BeginFastPaletteFade(3); - LinkPartnerBufferExecCompleted(); - gBattleBankFunc[gActiveBattler] = sub_811E29C; -} - -void LinkPartnerHandlecmd56(void) -{ -} diff --git a/src/battle/battle_controller_opponent.c b/src/battle/battle_controller_opponent.c deleted file mode 100644 index 15e077e92..000000000 --- a/src/battle/battle_controller_opponent.c +++ /dev/null @@ -1,2369 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_ai_switch_items.h" -#include "battle_anim.h" -#include "battle_interface.h" -#include "data2.h" -#include "battle_811DA74.h" -#include "battle_anim_813F0F4.h" -#include "battle_tower.h" -#include "link.h" -#include "m4a.h" -#include "main.h" -#include "palette.h" -#include "pokeball.h" -#include "pokemon.h" -#include "rom3.h" -#include "rom_8077ABC.h" -#include "sound.h" -#include "constants/songs.h" -#include "sprite.h" -#include "string_util.h" -#include "task.h" -#include "text.h" -#include "util.h" -#include "ewram.h" - -struct MovePpInfo -{ - u16 moves[4]; - u8 pp[4]; - u8 ppBonuses; -}; - -extern u8 gUnknown_02023A14_50; -extern u8 gActiveBattler; -extern u8 gBattleBufferA[][0x200]; -extern u16 gBattlerPartyIndexes[]; -extern u8 gBankSpriteIds[]; -extern u8 gBattleMonForms[]; -extern struct SpriteTemplate gUnknown_02024E8C; -extern void (*gBattleBankFunc[])(void); -extern u8 gUnknown_0300434C[]; -extern u8 gHealthboxIDs[]; -extern u16 gBattleTypeFlags; -extern u16 gTrainerBattleOpponent; -extern s32 gAnimMoveDmg; -extern u16 gAnimMovePower; -extern u8 gAnimFriendship; -extern u16 gWeatherMoveAnim; -extern u32 gTransformedPersonalities[]; -extern u8 gAnimMoveTurn; -extern u8 gAnimScriptActive; -extern void (*gAnimScriptCallback)(void); -extern struct Window gUnknown_03004210; -extern u8 gDisplayedStringBattle[]; -extern u8 gBankTarget; -extern u8 gAbsentBattlerFlags; -extern bool8 gDoingBattleAnim; -extern u16 gUnknown_02024DE8; -extern u8 gUnknown_02024E68[]; -extern MainCallback gPreBattleCallback1; -extern void (*const gOpponentBufferCommands[])(void); -extern struct MusicPlayerInfo gMPlay_SE1; -extern struct MusicPlayerInfo gMPlay_SE2; -extern struct MusicPlayerInfo gMPlay_BGM; -extern u32 gBattleExecBuffer; - -extern u8 GetBattlerSpriteCoord(); -extern u8 sub_8077F68(); -extern u8 GetBattlerSubpriority(); -extern void sub_8033018(void); -extern void BattleLoadOpponentMonSprite(); -extern u8 GetBattlerPosition(u8); -extern void sub_8032984(u8, u16); -extern void sub_80333D4(void); -extern void sub_80312F0(struct Sprite *); -extern u8 StartSendOutMonAnimation(); -extern void sub_8032A08(); -extern void sub_8043DB0(); -extern void sub_8033160(void); -extern u8 get_trainer_class_pic_index(void); -extern void sub_80313A0(struct Sprite *); -extern void sub_8032B4C(void); -extern void sub_8031A6C(u16, u8); -extern void sub_8032B84(void); -extern void StartAnimLinearTranslation(struct Sprite *); -extern void sub_8032BBC(void); -extern void oamt_add_pos2_onto_pos1(); -extern void StoreSpriteCallbackInData(); -extern void sub_803311C(void); -extern void sub_8010384(struct Sprite *); -extern bool8 mplay_80342A4(u8); -extern u8 sub_8031720(); -extern void DoMoveAnim(); -extern void sub_80326EC(); -extern void sub_8031F24(void); -extern void sub_80324BC(); -extern void BufferStringBattle(); -extern void sub_80331D0(void); -extern void AI_TrySwitchOrUseItem(void); -extern u8 GetBattlerAtPosition(u8); -extern void sub_80330C8(void); -extern void sub_8043D84(); -extern void sub_8045A5C(); -void sub_8033494(void); -extern void move_anim_start_t2_for_situation(); -extern void bx_blink_t7(void); -extern void sub_8047858(); -extern u8 GetBattlerSide(u8); -extern void StartBattleIntroAnim(); -extern void sub_8044CA0(u8); -extern void nullsub_45(void); -extern void sub_8031B74(); -extern bool8 IsDoubleBattle(void); -extern void sub_8032E2C(void); -extern u8 IsBankSpritePresent(); -extern u8 move_anim_start_t3(); -extern void sub_80334C0(void); - -// this file's functions - -void OpponentBufferExecCompleted(void); -void OpponentBufferRunCommand(void); -u32 sub_8033598(u8, u8 *); -void sub_8033E24(u8); -void sub_803495C(u8, u8); -void sub_8034B74(void); -void sub_8035238(void); -void sub_8035C10(struct Sprite *); -void sub_8035C44(u8); -void sub_8035E2C(void); -void sub_80332D0(void); - -void OpponentHandleGetAttributes(void); -void OpponentHandlecmd1(void); -void OpponentHandleSetAttributes(void); -void OpponentHandlecmd3(void); -void OpponentHandleLoadPokeSprite(void); -void OpponentHandleSendOutPoke(void); -void OpponentHandleReturnPokeToBall(void); -void OpponentHandleTrainerThrow(void); -void OpponentHandleTrainerSlide(void); -void OpponentHandleTrainerSlideBack(void); -void OpponentHandlecmd10(void); -void OpponentHandlecmd11(void); -void OpponentHandlecmd12(void); -void OpponentHandleBallThrow(void); -void OpponentHandlePuase(void); -void OpponentHandleMoveAnimation(void); -void OpponentHandlePrintString(void); -void OpponentHandlePrintStringPlayerOnly(void); -void OpponentHandlecmd18(void); -void OpponentHandlecmd19(void); -void OpponentHandlecmd20(void); -void OpponentHandleOpenBag(void); -void OpponentHandlecmd22(void); -void OpponentHandlecmd23(void); -void OpponentHandleHealthBarUpdate(void); -void OpponentHandleExpBarUpdate(void); -void OpponentHandleStatusIconUpdate(void); -void OpponentHandleStatusAnimation(void); -void OpponentHandleStatusXor(void); -void OpponentHandlecmd29(void); -void OpponentHandleDMATransfer(void); -void OpponentHandlecmd31(void); -void OpponentHandlecmd32(void); -void OpponentHandlecmd33(void); -void OpponentHandlecmd34(void); -void OpponentHandlecmd35(void); -void OpponentHandlecmd36(void); -void OpponentHandlecmd37(void); -void OpponentHandlecmd38(void); -void OpponentHandlecmd39(void); -void OpponentHandlecmd40(void); -void OpponentHandleHitAnimation(void); -void OpponentHandlecmd42(void); -void OpponentHandleEffectivenessSound(void); -void OpponentHandlecmd44(void); -void OpponentHandleFaintingCry(void); -void OpponentHandleIntroSlide(void); -void OpponentHandleTrainerBallThrow(void); -void OpponentHandlecmd48(void); -void OpponentHandlecmd49(void); -void OpponentHandlecmd50(void); -void OpponentHandleSpriteInvisibility(void); -void OpponentHandleBattleAnimation(void); -void OpponentHandleLinkStandbyMsg(void); -void OpponentHandleResetActionMoveSelection(void); -void OpponentHandlecmd55(void); -void OpponentHandlecmd56(void); - -// const data -typedef void (*BattleBufferCmd) (void); -static const BattleBufferCmd gOpponentBufferCommands[] = -{ - OpponentHandleGetAttributes, - OpponentHandlecmd1, - OpponentHandleSetAttributes, - OpponentHandlecmd3, - OpponentHandleLoadPokeSprite, - OpponentHandleSendOutPoke, - OpponentHandleReturnPokeToBall, - OpponentHandleTrainerThrow, - OpponentHandleTrainerSlide, - OpponentHandleTrainerSlideBack, - OpponentHandlecmd10, - OpponentHandlecmd11, - OpponentHandlecmd12, - OpponentHandleBallThrow, - OpponentHandlePuase, - OpponentHandleMoveAnimation, - OpponentHandlePrintString, - OpponentHandlePrintStringPlayerOnly, - OpponentHandlecmd18, - OpponentHandlecmd19, - OpponentHandlecmd20, - OpponentHandleOpenBag, - OpponentHandlecmd22, - OpponentHandlecmd23, - OpponentHandleHealthBarUpdate, - OpponentHandleExpBarUpdate, - OpponentHandleStatusIconUpdate, - OpponentHandleStatusAnimation, - OpponentHandleStatusXor, - OpponentHandlecmd29, - OpponentHandleDMATransfer, - OpponentHandlecmd31, - OpponentHandlecmd32, - OpponentHandlecmd33, - OpponentHandlecmd34, - OpponentHandlecmd35, - OpponentHandlecmd36, - OpponentHandlecmd37, - OpponentHandlecmd38, - OpponentHandlecmd39, - OpponentHandlecmd40, - OpponentHandleHitAnimation, - OpponentHandlecmd42, - OpponentHandleEffectivenessSound, - OpponentHandlecmd44, - OpponentHandleFaintingCry, - OpponentHandleIntroSlide, - OpponentHandleTrainerBallThrow, - OpponentHandlecmd48, - OpponentHandlecmd49, - OpponentHandlecmd50, - OpponentHandleSpriteInvisibility, - OpponentHandleBattleAnimation, - OpponentHandleLinkStandbyMsg, - OpponentHandleResetActionMoveSelection, - OpponentHandlecmd55, - OpponentHandlecmd56, -}; - -static const u8 sUnknownBytes[] = {0xB0, 0xB0, 0xC8, 0x98, 0x28, 0x28, 0x28, 0x20}; - -// code - -void nullsub_45(void) -{ -} - -void SetBankFuncToOpponentBufferRunCommand(void) -{ - gBattleBankFunc[gActiveBattler] = OpponentBufferRunCommand; -} - -void OpponentBufferRunCommand(void) -{ - if (gBattleExecBuffer & gBitTable[gActiveBattler]) - { - if (gBattleBufferA[gActiveBattler][0] <= 0x38) - gOpponentBufferCommands[gBattleBufferA[gActiveBattler][0]](); - else - OpponentBufferExecCompleted(); - } -} - -void sub_8032B4C(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - OpponentBufferExecCompleted(); -} - -// Duplicate of sub_8032B4C -void sub_8032B84(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - OpponentBufferExecCompleted(); -} - -void sub_8032BBC(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - sub_8031B74(gSprites[gBankSpriteIds[gActiveBattler]].oam.affineParam); - gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum = gSprites[gBankSpriteIds[gActiveBattler]].data[5]; - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - OpponentBufferExecCompleted(); - } -} - -void sub_8032C4C(void) -{ - if ((--ewram17810[gActiveBattler].unk9) == 0xFF) - { - ewram17810[gActiveBattler].unk9 = 0; - OpponentBufferExecCompleted(); - } -} - -void sub_8032C88(void) -{ - bool8 r6 = FALSE; - - if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) - { - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) - r6 = TRUE; - } - else - { - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxIDs[gActiveBattler ^ 2]].callback == SpriteCallbackDummy) - r6 = TRUE; - } - if (IsCryPlayingOrClearCrySongs()) - r6 = FALSE; - - if (r6 && ewram17810[gActiveBattler].unk1_0 && ewram17810[gActiveBattler ^ 2].unk1_0) - { - ewram17810[gActiveBattler].unk0_7 = 0; - ewram17810[gActiveBattler].unk1_0 = 0; - ewram17810[gActiveBattler ^ 2].unk0_7 = 0; - ewram17810[gActiveBattler ^ 2].unk1_0 = 0; - FreeSpriteTilesByTag(0x27F9); - FreeSpritePaletteByTag(0x27F9); - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - m4aMPlayContinue(&gMPlay_BGM); - else - m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 256); - ewram17810[gActiveBattler].unk9 = 3; - gBattleBankFunc[gActiveBattler] = sub_8032C4C; - } -} - -void sub_8032E2C(void) -{ - if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) - sub_8141828(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); - if (!ewram17810[gActiveBattler ^ 2].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_7) - sub_8141828(gActiveBattler ^ 2, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ 2]]); - if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_3) - { - if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler ^ 2]]); - sub_8045A5C( - gHealthboxIDs[gActiveBattler ^ 2], - &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], - 0); - sub_804777C(gActiveBattler ^ 2); - sub_8043DFC(gHealthboxIDs[gActiveBattler ^ 2]); - sub_8032984( - gActiveBattler ^ 2, - GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], MON_DATA_SPECIES)); - } - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); - sub_8045A5C( - gHealthboxIDs[gActiveBattler], - &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], - 0); - sub_804777C(gActiveBattler); - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - sub_8032984( - gActiveBattler, - GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - - ewram17840.unk9_0 = 0; - gBattleBankFunc[gActiveBattler] = sub_8032C88; - } -} - -void sub_8033018(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].animEnded == TRUE - && gSprites[gBankSpriteIds[gActiveBattler]].pos2.x == 0) - { - if (!ewram17810[gActiveBattler].unk0_7) - { - sub_8141828(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); - return; - } - if (ewram17810[gActiveBattler].unk1_0) - { - ewram17810[gActiveBattler].unk0_7 = 0; - ewram17810[gActiveBattler].unk1_0 = 0; - FreeSpriteTilesByTag(0x27F9); - FreeSpritePaletteByTag(0x27F9); - OpponentBufferExecCompleted(); - return; - } - } -} - -void sub_80330C8(void) -{ - s16 r4 = sub_8045C78(gActiveBattler, gHealthboxIDs[gActiveBattler], 0, 0); - - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - if (r4 != -1) - sub_80440EC(gHealthboxIDs[gActiveBattler], r4, 0); - else - OpponentBufferExecCompleted(); -} - -void sub_803311C(void) -{ - if (!gSprites[gBankSpriteIds[gActiveBattler]].inUse) - { - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - OpponentBufferExecCompleted(); - } -} - -void sub_8033160(void) -{ - if (!ewram17810[gActiveBattler].unk0_6) - { - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - sub_8032A08(gActiveBattler); - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - OpponentBufferExecCompleted(); - } -} - -void sub_80331D0(void) -{ - if (gUnknown_03004210.state == 0) - OpponentBufferExecCompleted(); -} - -void bx_blink_t7(void) -{ - u8 spriteId = gBankSpriteIds[gActiveBattler]; - - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = 0; - OpponentBufferExecCompleted(); - } - else - { - if (((u16)gSprites[spriteId].data[1] % 4) == 0) - gSprites[spriteId].invisible ^= 1; - gSprites[spriteId].data[1]++; - } -} - -void sub_8033264(void) -{ - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) - { - if (ewram17800[gActiveBattler].substituteSprite) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); - gBattleBankFunc[gActiveBattler] = sub_80332D0; - } -} - -void sub_80332D0(void) -{ - if (!ewram17810[gActiveBattler].unk0_6) - { - CreateTask(c3_0802FDF4, 10); - OpponentBufferExecCompleted(); - } -} - -void sub_8033308(void) -{ - if (ewram17810[gActiveBattler].unk1_0) - { - ewram17810[gActiveBattler].unk0_7 = 0; - ewram17810[gActiveBattler].unk1_0 = 0; - FreeSpriteTilesByTag(0x27F9); - FreeSpritePaletteByTag(0x27F9); - StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 0); - sub_8045A5C( - gHealthboxIDs[gActiveBattler], - &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], - 0); - sub_804777C(gActiveBattler); - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - sub_8031F88(gActiveBattler); - gBattleBankFunc[gActiveBattler] = sub_8033264; - } -} - -void sub_80333D4(void) -{ - if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) - sub_8141828(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); - if (gSprites[gUnknown_0300434C[gActiveBattler]].callback == SpriteCallbackDummy - && !ewram17810[gActiveBattler].unk0_3) - { - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); - sub_8032984(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - gBattleBankFunc[gActiveBattler] = sub_8033308; - } -} - -void sub_8033494(void) -{ - if (!ewram17810[gActiveBattler].unk0_4) - OpponentBufferExecCompleted(); -} - -void sub_80334C0(void) -{ - if (!ewram17810[gActiveBattler].unk0_5) - OpponentBufferExecCompleted(); -} - -void OpponentBufferExecCompleted(void) -{ - gBattleBankFunc[gActiveBattler] = OpponentBufferRunCommand; - gBattleExecBuffer &= ~gBitTable[gActiveBattler]; -} - -void OpponentHandleGetAttributes(void) -{ - u8 buffer[256]; - int r6 = 0; - s32 i; - - if (gBattleBufferA[gActiveBattler][2] == 0) - { - r6 = sub_8033598(gBattlerPartyIndexes[gActiveBattler], buffer); - } - else - { - u8 r4 = gBattleBufferA[gActiveBattler][2]; - - for (i = 0; i < 6; i++) - { - if (r4 & 1) - r6 += sub_8033598(i, buffer + r6); - r4 >>= 1; - } - } - Emitcmd29(1, r6, buffer); - OpponentBufferExecCompleted(); -} - -u32 sub_8033598(u8 a, u8 *buffer) -{ - struct BattlePokemon battlePokemon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; - - switch (gBattleBufferA[gActiveBattler][1]) - { - case 0: - battlePokemon.species = GetMonData(&gEnemyParty[a], MON_DATA_SPECIES); - battlePokemon.item = GetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM); - for (size = 0; size < 4; size++) - { - battlePokemon.moves[size] = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + size); - battlePokemon.pp[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size); - } - battlePokemon.ppBonuses = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES); - battlePokemon.friendship = GetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP); - battlePokemon.experience = GetMonData(&gEnemyParty[a], MON_DATA_EXP); - battlePokemon.hpIV = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV); - battlePokemon.attackIV = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV); - battlePokemon.defenseIV = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV); - battlePokemon.speedIV = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV); - battlePokemon.spAttackIV = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV); - battlePokemon.spDefenseIV = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV); - battlePokemon.personality = GetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY); - battlePokemon.status1 = GetMonData(&gEnemyParty[a], MON_DATA_STATUS); - battlePokemon.level = GetMonData(&gEnemyParty[a], MON_DATA_LEVEL); - battlePokemon.hp = GetMonData(&gEnemyParty[a], MON_DATA_HP); - battlePokemon.maxHP = GetMonData(&gEnemyParty[a], MON_DATA_MAX_HP); - battlePokemon.attack = GetMonData(&gEnemyParty[a], MON_DATA_ATK); - battlePokemon.defense = GetMonData(&gEnemyParty[a], MON_DATA_DEF); - battlePokemon.speed = GetMonData(&gEnemyParty[a], MON_DATA_SPEED); - battlePokemon.spAttack = GetMonData(&gEnemyParty[a], MON_DATA_SPATK); - battlePokemon.spDefense = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF); - battlePokemon.isEgg = GetMonData(&gEnemyParty[a], MON_DATA_IS_EGG); - battlePokemon.altAbility = GetMonData(&gEnemyParty[a], MON_DATA_ALT_ABILITY); - battlePokemon.otId = GetMonData(&gEnemyParty[a], MON_DATA_OT_ID); - GetMonData(&gEnemyParty[a], MON_DATA_NICKNAME, nickname); - StringCopy10(battlePokemon.nickname, nickname); - GetMonData(&gEnemyParty[a], MON_DATA_OT_NAME, battlePokemon.otName); - MEMCPY_ALT(&battlePokemon, buffer, sizeof(battlePokemon), size, src); - break; - case 1: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPECIES); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 2: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 3: - for (size = 0; size < 4; size++) - { - moveData.moves[size] = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES); - MEMCPY_ALT(&moveData, buffer, sizeof(moveData), size, src); - break; - case 4: - case 5: - case 6: - case 7: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 8: - for (size = 0; size < 4; size++) - buffer[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size); - buffer[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES); - size++; - break; - case 9: - case 10: - case 11: - case 12: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9); - size = 1; - break; - case 17: - data32 = GetMonData(&gEnemyParty[a], MON_DATA_OT_ID); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case 18: - data32 = GetMonData(&gEnemyParty[a], MON_DATA_EXP); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case 19: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_EV); - size = 1; - break; - case 20: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_EV); - size = 1; - break; - case 21: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_EV); - size = 1; - break; - case 22: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_EV); - size = 1; - break; - case 23: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_EV); - size = 1; - break; - case 24: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_EV); - size = 1; - break; - case 25: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP); - size = 1; - break; - case 26: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_POKERUS); - size = 1; - break; - case 27: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_LOCATION); - size = 1; - break; - case 28: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_LEVEL); - size = 1; - break; - case 29: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_GAME); - size = 1; - break; - case 30: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_POKEBALL); - size = 1; - break; - case 31: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV); - buffer[1] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV); - buffer[2] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV); - buffer[3] = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV); - buffer[4] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV); - buffer[5] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV); - size = 6; - break; - case 32: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV); - size = 1; - break; - case 33: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV); - size = 1; - break; - case 34: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV); - size = 1; - break; - case 35: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV); - size = 1; - break; - case 36: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV); - size = 1; - break; - case 37: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV); - size = 1; - break; - case 38: - data32 = GetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - buffer[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case 39: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_CHECKSUM); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 40: - data32 = GetMonData(&gEnemyParty[a], MON_DATA_STATUS); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - buffer[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case 41: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_LEVEL); - size = 1; - break; - case 42: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_HP); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 43: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_MAX_HP); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 44: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_ATK); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 45: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_DEF); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 46: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPEED); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 47: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPATK); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 48: - data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 49: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_COOL); - size = 1; - break; - case 50: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_BEAUTY); - size = 1; - break; - case 51: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_CUTE); - size = 1; - break; - case 52: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SMART); - size = 1; - break; - case 53: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_TOUGH); - size = 1; - break; - case 54: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SHEEN); - size = 1; - break; - case 55: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_COOL_RIBBON); - size = 1; - break; - case 56: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case 57: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case 58: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SMART_RIBBON); - size = 1; - break; - case 59: - buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - return size; -} - -void OpponentHandlecmd1(void) -{ - struct BattlePokemon buffer; - u8 i; - // TODO: Maybe fix this. Integrating this into MEMSET_ALT is too hard. - u8 *src = (u8 *)&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1]; - u8 *dst; - - MEMSET_ALT(&buffer + gBattleBufferA[gActiveBattler][1], src[i], gBattleBufferA[gActiveBattler][2], i, dst); - Emitcmd29(1, gBattleBufferA[gActiveBattler][2], dst); - OpponentBufferExecCompleted(); -} - -void OpponentHandleSetAttributes(void) -{ - u8 i; - u8 r4; - - if (gBattleBufferA[gActiveBattler][2] == 0) - { - sub_8033E24(gBattlerPartyIndexes[gActiveBattler]); - } - else - { - r4 = gBattleBufferA[gActiveBattler][2]; - for (i = 0; i < 6; i++) - { - if (r4 & 1) - sub_8033E24(i); - r4 >>= 1; - } - } - OpponentBufferExecCompleted(); -} - -void sub_8033E24(u8 a) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleBufferA[gActiveBattler][1]) - { - case 0: - { - u8 iv; - - SetMonData(&gEnemyParty[a], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < 4; i++) - { - SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gEnemyParty[a], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gEnemyParty[a], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gEnemyParty[a], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gEnemyParty[a], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gEnemyParty[a], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gEnemyParty[a], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gEnemyParty[a], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gEnemyParty[a], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gEnemyParty[a], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gEnemyParty[a], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gEnemyParty[a], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case 1: - SetMonData(&gEnemyParty[a], MON_DATA_SPECIES, &gBattleBufferA[gActiveBattler][3]); - break; - case 2: - SetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]); - break; - case 3: - for (i = 0; i < 4; i++) - { - SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gEnemyParty[a], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case 4: - case 5: - case 6: - case 7: - SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4, &gBattleBufferA[gActiveBattler][3]); - break; - case 8: - SetMonData(&gEnemyParty[a], MON_DATA_PP1, &gBattleBufferA[gActiveBattler][3]); - SetMonData(&gEnemyParty[a], MON_DATA_PP2, &gBattleBufferA[gActiveBattler][4]); - SetMonData(&gEnemyParty[a], MON_DATA_PP3, &gBattleBufferA[gActiveBattler][5]); - SetMonData(&gEnemyParty[a], MON_DATA_PP4, &gBattleBufferA[gActiveBattler][6]); - SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBattler][7]); - break; - case 9: - case 10: - case 11: - case 12: - SetMonData(&gEnemyParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9, &gBattleBufferA[gActiveBattler][3]); - break; - case 17: - SetMonData(&gEnemyParty[a], MON_DATA_OT_ID, &gBattleBufferA[gActiveBattler][3]); - break; - case 18: - SetMonData(&gEnemyParty[a], MON_DATA_EXP, &gBattleBufferA[gActiveBattler][3]); - break; - case 19: - SetMonData(&gEnemyParty[a], MON_DATA_HP_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 20: - SetMonData(&gEnemyParty[a], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 21: - SetMonData(&gEnemyParty[a], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 22: - SetMonData(&gEnemyParty[a], MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 23: - SetMonData(&gEnemyParty[a], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 24: - SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 25: - SetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBattler][3]); - break; - case 26: - SetMonData(&gEnemyParty[a], MON_DATA_POKERUS, &gBattleBufferA[gActiveBattler][3]); - break; - case 27: - SetMonData(&gEnemyParty[a], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBattler][3]); - break; - case 28: - SetMonData(&gEnemyParty[a], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBattler][3]); - break; - case 29: - SetMonData(&gEnemyParty[a], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBattler][3]); - break; - case 30: - SetMonData(&gEnemyParty[a], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBattler][3]); - break; - case 31: - SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); - SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][4]); - SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][5]); - SetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][6]); - SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][7]); - SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][8]); - break; - case 32: - SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 33: - SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 34: - SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 35: - SetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 36: - SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 37: - SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 38: - SetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBattler][3]); - break; - case 39: - SetMonData(&gEnemyParty[a], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBattler][3]); - break; - case 40: - SetMonData(&gEnemyParty[a], MON_DATA_STATUS, &gBattleBufferA[gActiveBattler][3]); - break; - case 41: - SetMonData(&gEnemyParty[a], MON_DATA_LEVEL, &gBattleBufferA[gActiveBattler][3]); - break; - case 42: - SetMonData(&gEnemyParty[a], MON_DATA_HP, &gBattleBufferA[gActiveBattler][3]); - break; - case 43: - SetMonData(&gEnemyParty[a], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBattler][3]); - break; - case 44: - SetMonData(&gEnemyParty[a], MON_DATA_ATK, &gBattleBufferA[gActiveBattler][3]); - break; - case 45: - SetMonData(&gEnemyParty[a], MON_DATA_DEF, &gBattleBufferA[gActiveBattler][3]); - break; - case 46: - SetMonData(&gEnemyParty[a], MON_DATA_SPEED, &gBattleBufferA[gActiveBattler][3]); - break; - case 47: - SetMonData(&gEnemyParty[a], MON_DATA_SPATK, &gBattleBufferA[gActiveBattler][3]); - break; - case 48: - SetMonData(&gEnemyParty[a], MON_DATA_SPDEF, &gBattleBufferA[gActiveBattler][3]); - break; - case 49: - SetMonData(&gEnemyParty[a], MON_DATA_COOL, &gBattleBufferA[gActiveBattler][3]); - break; - case 50: - SetMonData(&gEnemyParty[a], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBattler][3]); - break; - case 51: - SetMonData(&gEnemyParty[a], MON_DATA_CUTE, &gBattleBufferA[gActiveBattler][3]); - break; - case 52: - SetMonData(&gEnemyParty[a], MON_DATA_SMART, &gBattleBufferA[gActiveBattler][3]); - break; - case 53: - SetMonData(&gEnemyParty[a], MON_DATA_TOUGH, &gBattleBufferA[gActiveBattler][3]); - break; - case 54: - SetMonData(&gEnemyParty[a], MON_DATA_SHEEN, &gBattleBufferA[gActiveBattler][3]); - break; - case 55: - SetMonData(&gEnemyParty[a], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 56: - SetMonData(&gEnemyParty[a], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 57: - SetMonData(&gEnemyParty[a], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 58: - SetMonData(&gEnemyParty[a], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 59: - SetMonData(&gEnemyParty[a], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - } -} - -void OpponentHandlecmd3(void) -{ - u8 *dst; - u8 i; - - MEMSET_ALT(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][3 + i], - gBattleBufferA[gActiveBattler][2], i, dst); - OpponentBufferExecCompleted(); -} - -void OpponentHandleLoadPokeSprite(void) -{ - u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - BattleLoadOpponentMonSprite(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(gActiveBattler)); - gBankSpriteIds[gActiveBattler] = CreateSprite( - &gUnknown_02024E8C, - GetBattlerSpriteCoord(gActiveBattler, 2), - sub_8077F68(gActiveBattler), - GetBattlerSubpriority(gActiveBattler)); - gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -240; - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = gActiveBattler; - gSprites[gBankSpriteIds[gActiveBattler]].data[2] = species; - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], gBattleMonForms[gActiveBattler]); - sub_8032984(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); - gBattleBankFunc[gActiveBattler] = sub_8033018; -} - -void OpponentHandleSendOutPoke(void) -{ - gBattlerPartyIndexes[gActiveBattler] = gBattleBufferA[gActiveBattler][1]; - - sub_803495C(gActiveBattler, gBattleBufferA[gActiveBattler][2]); - gBattleBankFunc[gActiveBattler] = sub_80333D4; -} - -void sub_803495C(u8 a, u8 b) -{ - u16 species; - - sub_8032AA8(a, b); - gBattlerPartyIndexes[a] = gBattleBufferA[a][1]; - species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[a]], MON_DATA_SPECIES); - gUnknown_0300434C[a] = CreateInvisibleSpriteWithCallback(sub_80312F0); - BattleLoadOpponentMonSprite(&gEnemyParty[gBattlerPartyIndexes[a]], a); - GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(a)); - gBankSpriteIds[a] = CreateSprite( - &gUnknown_02024E8C, - GetBattlerSpriteCoord(a, 2), - sub_8077F68(a), - GetBattlerSubpriority(a)); - gSprites[gBankSpriteIds[a]].data[0] = a; - gSprites[gBankSpriteIds[a]].data[2] = species; - gSprites[gUnknown_0300434C[a]].data[1] = gBankSpriteIds[a]; - gSprites[gBankSpriteIds[a]].oam.paletteNum = a; - StartSpriteAnim(&gSprites[gBankSpriteIds[a]], gBattleMonForms[a]); - gSprites[gBankSpriteIds[a]].invisible = TRUE; - gSprites[gBankSpriteIds[a]].callback = SpriteCallbackDummy; - gSprites[gUnknown_0300434C[a]].data[0] = StartSendOutMonAnimation(0, 0xFE); -} - -void OpponentHandleReturnPokeToBall(void) -{ - if (gBattleBufferA[gActiveBattler][1] == 0) - { - ewram17810[gActiveBattler].unk4 = 0; - gBattleBankFunc[gActiveBattler] = sub_8034B74; - } - else - { - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - sub_8032A08(gActiveBattler); - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - OpponentBufferExecCompleted(); - } -} - -void sub_8034B74(void) -{ - switch (ewram17810[gActiveBattler].unk4) - { - case 0: - if (ewram17800[gActiveBattler].substituteSprite) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - ewram17810[gActiveBattler].unk4 = 1; - break; - case 1: - if (!ewram17810[gActiveBattler].unk0_6) - { - ewram17810[gActiveBattler].unk4 = 0; - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 2); - gBattleBankFunc[gActiveBattler] = sub_8033160; - } - break; - } -} - -void OpponentHandleTrainerThrow(void) -{ - u32 trainerPicIndex; - -#if DEBUG - if (gUnknown_02023A14_50 & 0x10) - { - trainerPicIndex = gSharedMem[0x160A3]; - } - else -#endif - { - if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) - trainerPicIndex = GetSecretBaseTrainerPicIndex(); - else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) - trainerPicIndex = get_trainer_class_pic_index(); - else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) - trainerPicIndex = GetEReaderTrainerPicIndex(); - else - trainerPicIndex = gTrainers[gTrainerBattleOpponent].trainerPic; - } - - sub_8031A6C(trainerPicIndex, gActiveBattler); - GetMonSpriteTemplate_803C5A0(trainerPicIndex, GetBattlerPosition(gActiveBattler)); - gBankSpriteIds[gActiveBattler] = CreateSprite( - &gUnknown_02024E8C, - 0xB0, - 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicIndex].coords), - GetBattlerSubpriority(gActiveBattler)); - gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -240; - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 2; - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicIndex].tag); - gSprites[gBankSpriteIds[gActiveBattler]].data[5] = gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum; - gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum = GetSpriteTileStartByTag(gTrainerFrontPicTable[trainerPicIndex].tag); - gSprites[gBankSpriteIds[gActiveBattler]].oam.affineParam = trainerPicIndex; - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; - gBattleBankFunc[gActiveBattler] = sub_8032B4C; -} - -void OpponentHandleTrainerSlide(void) -{ - u32 trainerPicIndex; - - if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) - trainerPicIndex = GetSecretBaseTrainerPicIndex(); - else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) - trainerPicIndex = get_trainer_class_pic_index(); - else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) - trainerPicIndex = GetEReaderTrainerPicIndex(); - else - trainerPicIndex = gTrainers[gTrainerBattleOpponent].trainerPic; - - sub_8031A6C(trainerPicIndex, gActiveBattler); - GetMonSpriteTemplate_803C5A0(trainerPicIndex, GetBattlerPosition(gActiveBattler)); - gBankSpriteIds[gActiveBattler] = CreateSprite( - &gUnknown_02024E8C, - 0xB0, - 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicIndex].coords), - 0x1E); - gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = 96; - gSprites[gBankSpriteIds[gActiveBattler]].pos1.x += 32; - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = -2; - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicIndex].tag); - gSprites[gBankSpriteIds[gActiveBattler]].data[5] = gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum; - gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum = GetSpriteTileStartByTag(gTrainerFrontPicTable[trainerPicIndex].tag); - gSprites[gBankSpriteIds[gActiveBattler]].oam.affineParam = trainerPicIndex; - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; - gBattleBankFunc[gActiveBattler] = sub_8032B84; -} - -void OpponentHandleTrainerSlideBack(void) -{ - oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBankSpriteIds[gActiveBattler]].data[2] = 280; - gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; - gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], SpriteCallbackDummy); - gBattleBankFunc[gActiveBattler] = sub_8032BBC; -} - -void OpponentHandlecmd10(void) -{ - if (ewram17810[gActiveBattler].unk4 == 0) - { - if (ewram17800[gActiveBattler].substituteSprite) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - ewram17810[gActiveBattler].unk4++; - } - else if (!ewram17810[gActiveBattler].unk0_6) - { - ewram17810[gActiveBattler].unk4 = 0; - PlaySE12WithPanning(SE_POKE_DEAD, 63); - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_8010384; - gBattleBankFunc[gActiveBattler] = sub_803311C; - } -} - -void OpponentHandlecmd11(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd12(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandleBallThrow(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandlePuase(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandleMoveAnimation(void) -{ - if (!mplay_80342A4(gActiveBattler)) - { - u32 r0 = gBattleBufferA[gActiveBattler][1] - | (gBattleBufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleBufferA[gActiveBattler][3]; - gAnimMovePower = gBattleBufferA[gActiveBattler][4] - | (gBattleBufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleBufferA[gActiveBattler][6] - | (gBattleBufferA[gActiveBattler][7] << 8) - | (gBattleBufferA[gActiveBattler][8] << 16) - | (gBattleBufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleBufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleBufferA[gActiveBattler][12] - | (gBattleBufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - - // Dead code. sub_8031720 always returns 0. - if (sub_8031720(r0, gAnimMoveTurn) != 0) - { - OpponentBufferExecCompleted(); - } - else - { - ewram17810[gActiveBattler].unk4 = 0; - gBattleBankFunc[gActiveBattler] = sub_8035238; - } - } -} - -void sub_8035238(void) -{ - u16 r4 = gBattleBufferA[gActiveBattler][1] - | (gBattleBufferA[gActiveBattler][2] << 8); - u8 r7 = gBattleBufferA[gActiveBattler][11]; - - switch (ewram17810[gActiveBattler].unk4) - { - case 0: - if (ewram17800[gActiveBattler].substituteSprite && !ewram17800[gActiveBattler].unk0_3) - { - ewram17800[gActiveBattler].unk0_3 = 1; - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - } - ewram17810[gActiveBattler].unk4 = 1; - break; - case 1: - if (!ewram17810[gActiveBattler].unk0_6) - { - sub_80326EC(0); - DoMoveAnim(r4); - ewram17810[gActiveBattler].unk4 = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - sub_80326EC(1); - if ((ewram17800[gActiveBattler].substituteSprite) && r7 <= 1) - { - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); - ewram17800[gActiveBattler].unk0_3 = 0; - } - ewram17810[gActiveBattler].unk4 = 3; - } - break; - case 3: - if (!ewram17810[gActiveBattler].unk0_6) - { - sub_8031F24(); - sub_80324BC( - gActiveBattler, - gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - ewram17810[gActiveBattler].unk4 = 0; - OpponentBufferExecCompleted(); - } - break; - } -} - -void OpponentHandlePrintString(void) -{ - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - BufferStringBattle(*(u16 *)&gBattleBufferA[gActiveBattler][2]); - Text_InitWindow8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15); - gBattleBankFunc[gActiveBattler] = sub_80331D0; -} - -void OpponentHandlePrintStringPlayerOnly(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd18(void) -{ - AI_TrySwitchOrUseItem(); - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd19(void) -{ - OpponentBufferExecCompleted(); -} - -#if DEBUG -NAKED -void OpponentHandlecmd20(void) -{ - asm("\ - push {r4, r5, r6, r7, lr}\n\ - mov r7, sl\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5, r6, r7}\n\ - ldr r6, ._549 @ gActiveBattler\n\ - ldrb r0, [r6]\n\ - lsl r0, r0, #0x9\n\ - ldr r1, ._549 + 4 @ gBattleBufferA\n\ - add r5, r0, r1\n\ - ldr r2, ._549 + 8 @ gUnknown_02023A14_50\n\ - ldrb r1, [r2]\n\ - mov r0, #0x4\n\ - and r0, r0, r1\n\ - mov sl, r6\n\ - cmp r0, #0\n\ - beq ._546 @cond_branch\n\ - ldr r0, ._549 + 12 @ gBattleMoves\n\ - mov r9, r0\n\ - ldr r1, ._549 + 16 @ \n\ - mov ip, r1\n\ - add r7, r6, #0\n\ - mov r0, #0x2\n\ - mov r8, r0\n\ - ldr r6, ._549 + 20 @ \n\ -._552:\n\ - ldrb r1, [r7]\n\ - mov r0, r8\n\ - and r0, r0, r1\n\ - lsl r0, r0, #0x18\n\ - lsr r0, r0, #0x19\n\ - add r0, r0, r6\n\ - mov r1, ip\n\ - add r3, r0, r1\n\ - ldrb r1, [r3]\n\ - lsl r0, r1, #0x1\n\ - add r0, r5, r0\n\ - ldrh r2, [r0]\n\ - add r4, r1, #0\n\ - cmp r2, #0\n\ - beq ._547 @cond_branch\n\ - add r0, r4, #1\n\ - strb r0, [r3]\n\ - b ._548\n\ -._550:\n\ - .align 2, 0\n\ -._549:\n\ - .word gActiveBattler\n\ - .word gBattleBufferA+4\n\ - .word gUnknown_02023A14_50\n\ - .word gBattleMoves\n\ - .word +0x2000000\n\ - .word 0x1609e\n\ -._547:\n\ - strb r2, [r3]\n\ -._548:\n\ - ldrb r0, [r7]\n\ - mov r1, r8\n\ - and r1, r1, r0\n\ - lsl r1, r1, #0x18\n\ - lsr r1, r1, #0x19\n\ - add r1, r1, r6\n\ - add r1, r1, ip\n\ - ldrb r0, [r1]\n\ - cmp r0, #0x3\n\ - bls ._551 @cond_branch\n\ - mov r0, #0x0\n\ - strb r0, [r1]\n\ -._551:\n\ - cmp r2, #0\n\ - beq ._552 @cond_branch\n\ - lsl r0, r2, #0x1\n\ - add r0, r0, r2\n\ - lsl r0, r0, #0x2\n\ - add r0, r0, r9\n\ - ldrb r3, [r0, #0x6]\n\ - mov r0, #0x12\n\ - and r0, r0, r3\n\ - cmp r0, #0\n\ - beq ._553 @cond_branch\n\ - mov r1, sl\n\ - ldrb r0, [r1]\n\ - b ._561\n\ -._553:\n\ - ldr r0, ._559 @ gBattleTypeFlags\n\ - ldrh r1, [r0]\n\ - mov r0, #0x1\n\ - and r0, r0, r1\n\ - cmp r0, #0\n\ - beq ._557 @cond_branch\n\ - ldr r0, ._559 + 4 @ gUnknown_02023A14_50\n\ - ldrb r1, [r0]\n\ - mov r5, #0x2\n\ - add r0, r5, #0\n\ - and r0, r0, r1\n\ - cmp r0, #0\n\ - beq ._556 @cond_branch\n\ - cmp r3, #0\n\ - bne ._557 @cond_branch\n\ - mov r1, sl\n\ - ldrb r0, [r1]\n\ - bl GetBattlerPosition\n\ - mov r1, #0x2\n\ - eor r0, r0, r1\n\ - lsl r0, r0, #0x18\n\ - lsr r0, r0, #0x18\n\ - b ._558\n\ -._560:\n\ - .align 2, 0\n\ -._559:\n\ - .word gBattleTypeFlags\n\ - .word gUnknown_02023A14_50\n\ -._556:\n\ - bl Random\n\ - add r1, r5, #0\n\ - and r1, r1, r0\n\ - lsl r1, r1, #0x10\n\ - lsr r0, r1, #0x10\n\ - b ._561\n\ -._557:\n\ - mov r0, #0x0\n\ -._558:\n\ - bl GetBattlerAtPosition\n\ - lsl r0, r0, #0x18\n\ - lsr r0, r0, #0x18\n\ -._561:\n\ - lsl r2, r0, #0x8\n\ - orr r2, r2, r4\n\ - mov r0, #0x1\n\ - mov r1, #0xa\n\ -._569:\n\ - bl Emitcmd33\n\ -._573:\n\ - bl OpponentBufferExecCompleted\n\ - b ._562\n\ -._546:\n\ - ldr r0, ._567 @ gBattleTypeFlags\n\ - ldrh r1, [r0]\n\ - mov r0, #0x93\n\ - lsl r0, r0, #0x3\n\ - and r0, r0, r1\n\ - cmp r0, #0\n\ - beq ._563 @cond_branch\n\ - bl BattleAI_SetupAIData\n\ - bl BattleAI_GetAIActionToUse\n\ - lsl r0, r0, #0x18\n\ - lsr r4, r0, #0x18\n\ - cmp r4, #0x4\n\ - beq ._564 @cond_branch\n\ - cmp r4, #0x5\n\ - bne ._565 @cond_branch\n\ - mov r0, #0x1\n\ - mov r1, #0x4\n\ - b ._566\n\ -._568:\n\ - .align 2, 0\n\ -._567:\n\ - .word gBattleTypeFlags\n\ -._564:\n\ - mov r0, #0x1\n\ - mov r1, #0x3\n\ -._566:\n\ - mov r2, #0x0\n\ - b ._569\n\ -._565:\n\ - ldr r3, ._574 @ gBattleMoves\n\ - lsl r0, r4, #0x1\n\ - add r2, r5, r0\n\ - ldrh r1, [r2]\n\ - lsl r0, r1, #0x1\n\ - add r0, r0, r1\n\ - lsl r0, r0, #0x2\n\ - add r0, r0, r3\n\ - ldrb r1, [r0, #0x6]\n\ - mov r0, #0x12\n\ - and r0, r0, r1\n\ - cmp r0, #0\n\ - beq ._570 @cond_branch\n\ - ldr r1, ._574 + 4 @ gBankTarget\n\ - ldrb r0, [r6]\n\ - strb r0, [r1]\n\ -._570:\n\ - ldrh r1, [r2]\n\ - lsl r0, r1, #0x1\n\ - add r0, r0, r1\n\ - lsl r0, r0, #0x2\n\ - add r0, r0, r3\n\ - ldrb r1, [r0, #0x6]\n\ - mov r0, #0x8\n\ - and r0, r0, r1\n\ - cmp r0, #0\n\ - beq ._572 @cond_branch\n\ - mov r0, #0x0\n\ - bl GetBattlerAtPosition\n\ - ldr r5, ._574 + 4 @ gBankTarget\n\ - strb r0, [r5]\n\ - ldr r0, ._574 + 8 @ gAbsentBattlerFlags\n\ - ldrb r1, [r0]\n\ - ldr r2, ._574 + 12 @ gBitTable\n\ - ldrb r0, [r5]\n\ - lsl r0, r0, #0x2\n\ - add r0, r0, r2\n\ - ldr r0, [r0]\n\ - and r1, r1, r0\n\ - cmp r1, #0\n\ - beq ._572 @cond_branch\n\ - mov r0, #0x2\n\ - bl GetBattlerAtPosition\n\ - strb r0, [r5]\n\ -._572:\n\ - ldr r0, ._574 + 4 @ gBankTarget\n\ - ldrb r2, [r0]\n\ - lsl r2, r2, #0x8\n\ - orr r2, r2, r4\n\ - mov r0, #0x1\n\ - mov r1, #0xa\n\ - bl Emitcmd33\n\ - b ._573\n\ -._575:\n\ - .align 2, 0\n\ -._574:\n\ - .word gBattleMoves\n\ - .word gBankTarget\n\ - .word gAbsentBattlerFlags\n\ - .word gBitTable\n\ -._563:\n\ - mov r6, #0x3\n\ -._576:\n\ - bl Random\n\ - add r4, r0, #0\n\ - and r4, r4, r6\n\ - lsl r0, r4, #0x1\n\ - add r0, r5, r0\n\ - ldrh r2, [r0]\n\ - cmp r2, #0\n\ - beq ._576 @cond_branch\n\ - ldr r1, ._579 @ gBattleMoves\n\ - lsl r0, r2, #0x1\n\ - add r0, r0, r2\n\ - lsl r0, r0, #0x2\n\ - add r0, r0, r1\n\ - ldrb r1, [r0, #0x6]\n\ - mov r0, #0x12\n\ - and r0, r0, r1\n\ - cmp r0, #0\n\ - beq ._577 @cond_branch\n\ - ldr r0, ._579 + 4 @ gActiveBattler\n\ - ldrb r2, [r0]\n\ - lsl r2, r2, #0x8\n\ - b ._578\n\ -._580:\n\ - .align 2, 0\n\ -._579:\n\ - .word gBattleMoves\n\ - .word gActiveBattler\n\ -._577:\n\ - ldr r0, ._583 @ gBattleTypeFlags\n\ - ldrh r1, [r0]\n\ - mov r0, #0x1\n\ - and r0, r0, r1\n\ - cmp r0, #0\n\ - beq ._581 @cond_branch\n\ - bl Random\n\ - mov r1, #0x2\n\ - and r1, r1, r0\n\ - lsl r1, r1, #0x18\n\ - lsr r1, r1, #0x18\n\ - add r0, r1, #0\n\ - bl GetBattlerAtPosition\n\ - add r2, r0, #0\n\ - lsl r2, r2, #0x18\n\ - lsr r2, r2, #0x10\n\ -._578:\n\ - orr r2, r2, r4\n\ - mov r0, #0x1\n\ - mov r1, #0xa\n\ - bl Emitcmd33\n\ - b ._582\n\ -._584:\n\ - .align 2, 0\n\ -._583:\n\ - .word gBattleTypeFlags\n\ -._581:\n\ - mov r0, #0x0\n\ - bl GetBattlerAtPosition\n\ - add r2, r0, #0\n\ - lsl r2, r2, #0x18\n\ - lsr r2, r2, #0x10\n\ - orr r2, r2, r4\n\ - mov r0, #0x1\n\ - mov r1, #0xa\n\ - bl Emitcmd33\n\ -._582:\n\ - bl OpponentBufferExecCompleted\n\ -._562:\n\ - pop {r3, r4, r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov sl, r5\n\ - pop {r4, r5, r6, r7}\n\ - pop {r0}\n\ - bx r0"); -} -#else -#ifdef NONMATCHING -void OpponentHandlecmd20(void) -{ - u16 r4; - // Needed to match closer - struct {u16 moves[4];} *r5 = (void *)&gBattleBufferA[gActiveBattler][4]; - - if (gBattleTypeFlags & 0x498) - { - BattleAI_SetupAIData(); - r4 = BattleAI_GetAIActionToUse(); - switch (r4) - { - case 5: - Emitcmd33(1, 4, 0); - break; - case 4: - Emitcmd33(1, 3, 0); - break; - default: - if (gBattleMoves[r5->moves[r4]].target & 0x12) - gBankTarget = gActiveBattler; - if (gBattleMoves[r5->moves[r4]].target & 8) - { - gBankTarget = GetBattlerAtPosition(0); - if (gAbsentBattlerFlags & gBitTable[gBankTarget]) - gBankTarget = GetBattlerAtPosition(2); - } - r4 |= gBankTarget << 8; - Emitcmd33(1, 10, r4); - break; - } - OpponentBufferExecCompleted(); - } - else - { - u16 r2; - - do - { - // Can't for the life of me get this to match. - r4 = Random() % 4; - r2 = r5->moves[r4]; - } while (r2 == 0); - - if (gBattleMoves[r2].target & 0x12) - { - r4 |= gActiveBattler << 8; - Emitcmd33(1, 10, r4); - } - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - u16 r2 = GetBattlerAtPosition(Random() & 2) << 8; - - Emitcmd33(1, 10, r4 | r2); - } - else - { - u16 r2 = GetBattlerAtPosition(0) << 8; - - Emitcmd33(1, 10, r4 | r2); - } - OpponentBufferExecCompleted(); - } -} -#else -NAKED -void OpponentHandlecmd20(void) -{ - asm(".syntax unified\n\ - push {r4-r6,lr}\n\ - ldr r6, _0803545C @ =gActiveBattler\n\ - ldrb r0, [r6]\n\ - lsls r0, 9\n\ - ldr r1, _08035460 @ =gBattleBufferA+4\n\ - adds r5, r0, r1\n\ - ldr r0, _08035464 @ =gBattleTypeFlags\n\ - ldrh r1, [r0]\n\ - movs r0, 0x93\n\ - lsls r0, 3\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _080354F8\n\ - bl BattleAI_SetupAIData\n\ - bl BattleAI_GetAIActionToUse\n\ - lsls r0, 24\n\ - lsrs r4, r0, 24\n\ - cmp r4, 0x4\n\ - beq _08035468\n\ - cmp r4, 0x5\n\ - bne _08035474\n\ - movs r0, 0x1\n\ - movs r1, 0x4\n\ - b _0803546C\n\ - .align 2, 0\n\ -_0803545C: .4byte gActiveBattler\n\ -_08035460: .4byte gBattleBufferA+4\n\ -_08035464: .4byte gBattleTypeFlags\n\ -_08035468:\n\ - movs r0, 0x1\n\ - movs r1, 0x3\n\ -_0803546C:\n\ - movs r2, 0\n\ - bl Emitcmd33\n\ - b _080354E0\n\ -_08035474:\n\ - ldr r3, _080354E8 @ =gBattleMoves\n\ - lsls r0, r4, 1\n\ - adds r2, r5, r0\n\ - ldrh r1, [r2]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r3\n\ - ldrb r1, [r0, 0x6]\n\ - movs r0, 0x12\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08035494\n\ - ldr r1, _080354EC @ =gBankTarget\n\ - ldrb r0, [r6]\n\ - strb r0, [r1]\n\ -_08035494:\n\ - ldrh r1, [r2]\n\ - lsls r0, r1, 1\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r3\n\ - ldrb r1, [r0, 0x6]\n\ - movs r0, 0x8\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _080354CE\n\ - movs r0, 0\n\ - bl GetBattlerAtPosition\n\ - ldr r5, _080354EC @ =gBankTarget\n\ - strb r0, [r5]\n\ - ldr r0, _080354F0 @ =gAbsentBattlerFlags\n\ - ldrb r1, [r0]\n\ - ldr r2, _080354F4 @ =gBitTable\n\ - ldrb r0, [r5]\n\ - lsls r0, 2\n\ - adds r0, r2\n\ - ldr r0, [r0]\n\ - ands r1, r0\n\ - cmp r1, 0\n\ - beq _080354CE\n\ - movs r0, 0x2\n\ - bl GetBattlerAtPosition\n\ - strb r0, [r5]\n\ -_080354CE:\n\ - ldr r0, _080354EC @ =gBankTarget\n\ - ldrb r0, [r0]\n\ - lsls r0, 8\n\ - orrs r4, r0\n\ - movs r0, 0x1\n\ - movs r1, 0xA\n\ - adds r2, r4, 0\n\ - bl Emitcmd33\n\ -_080354E0:\n\ - bl OpponentBufferExecCompleted\n\ - b _0803558A\n\ - .align 2, 0\n\ -_080354E8: .4byte gBattleMoves\n\ -_080354EC: .4byte gBankTarget\n\ -_080354F0: .4byte gAbsentBattlerFlags\n\ -_080354F4: .4byte gBitTable\n\ -_080354F8:\n\ - movs r6, 0x3\n\ -_080354FA:\n\ - bl Random\n\ - adds r4, r0, 0\n\ - ands r4, r6\n\ - lsls r0, r4, 1\n\ - adds r0, r5, r0\n\ - ldrh r2, [r0]\n\ - cmp r2, 0\n\ - beq _080354FA\n\ - ldr r1, _08035534 @ =gBattleMoves\n\ - lsls r0, r2, 1\n\ - adds r0, r2\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldrb r1, [r0, 0x6]\n\ - movs r0, 0x12\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _0803553C\n\ - ldr r0, _08035538 @ =gActiveBattler\n\ - ldrb r0, [r0]\n\ - lsls r0, 8\n\ - orrs r4, r0\n\ - movs r0, 0x1\n\ - movs r1, 0xA\n\ - adds r2, r4, 0\n\ - bl Emitcmd33\n\ - b _08035586\n\ - .align 2, 0\n\ -_08035534: .4byte gBattleMoves\n\ -_08035538: .4byte gActiveBattler\n\ -_0803553C:\n\ - ldr r0, _0803556C @ =gBattleTypeFlags\n\ - ldrh r1, [r0]\n\ - movs r0, 0x1\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08035570\n\ - bl Random\n\ - movs r1, 0x2\n\ - ands r1, r0\n\ - lsls r1, 24\n\ - lsrs r1, 24\n\ - adds r0, r1, 0\n\ - bl GetBattlerAtPosition\n\ - adds r2, r0, 0\n\ - lsls r2, 24\n\ - lsrs r2, 16\n\ - orrs r2, r4\n\ - movs r0, 0x1\n\ - movs r1, 0xA\n\ - bl Emitcmd33\n\ - b _08035586\n\ - .align 2, 0\n\ -_0803556C: .4byte gBattleTypeFlags\n\ -_08035570:\n\ - movs r0, 0\n\ - bl GetBattlerAtPosition\n\ - adds r2, r0, 0\n\ - lsls r2, 24\n\ - lsrs r2, 16\n\ - orrs r2, r4\n\ - movs r0, 0x1\n\ - movs r1, 0xA\n\ - bl Emitcmd33\n\ -_08035586:\n\ - bl OpponentBufferExecCompleted\n\ -_0803558A:\n\ - pop {r4-r6}\n\ - pop {r0}\n\ - bx r0\n\ - .syntax divided\n"); -} -#endif -#endif - -void OpponentHandleOpenBag(void) -{ - // What is this? - Emitcmd35(1, ewram160D4(gActiveBattler)); - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd22(void) -{ - s32 r4; - - if (ewram160C8arr(GetBattlerPosition(gActiveBattler)) == 6) - { - u8 r6; - u8 r5; - - r4 = GetMostSuitableMonToSwitchInto(); - if (r4 == 6) - { - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - r5 = GetBattlerAtPosition(1); - r6 = r5; - } - else - { - r6 = GetBattlerAtPosition(1); - r5 = GetBattlerAtPosition(3); - } - for (r4 = 0; r4 < 6; r4++) - { - if (GetMonData(&gEnemyParty[r4], MON_DATA_HP) != 0 - && r4 != gBattlerPartyIndexes[r6] - && r4 != gBattlerPartyIndexes[r5]) - break; - } - } - } - else - { - r4 = ewram160C8arr(GetBattlerPosition(gActiveBattler)); - ewram160C8arr(GetBattlerPosition(gActiveBattler)) = 6; - } - ewram16068arr(gActiveBattler) = r4; - Emitcmd34(1, r4, 0); - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd23(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandleHealthBarUpdate(void) -{ - s16 r7; - - load_gfxc_health_bar(0); - r7 = (gBattleBufferA[gActiveBattler][3] << 8) | gBattleBufferA[gActiveBattler][2]; - if (r7 != 0x7FFF) - { - u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - u32 hp = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); - - sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, hp, r7); - } - else - { - u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - - sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, 0, r7); - } - gBattleBankFunc[gActiveBattler] = sub_80330C8; -} - -void OpponentHandleExpBarUpdate(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandleStatusIconUpdate(void) -{ - if (mplay_80342A4(gActiveBattler) == 0) - { - sub_8045A5C(gHealthboxIDs[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], 9); - ewram17810[gActiveBattler].unk0_4 = 0; - gBattleBankFunc[gActiveBattler] = sub_8033494; - } -} - -void OpponentHandleStatusAnimation(void) -{ - if (mplay_80342A4(gActiveBattler) == 0) - { - move_anim_start_t2_for_situation( - gBattleBufferA[gActiveBattler][1], - gBattleBufferA[gActiveBattler][2] - | (gBattleBufferA[gActiveBattler][3] << 8) - | (gBattleBufferA[gActiveBattler][4] << 16) - | (gBattleBufferA[gActiveBattler][5] << 24)); - gBattleBankFunc[gActiveBattler] = sub_8033494; - } -} - -void OpponentHandleStatusXor(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd29(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandleDMATransfer(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd31(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd32(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd33(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd34(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd35(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd36(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd37(void) -{ - gUnknown_020238C8.unk0_0 = 0; - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd38(void) -{ - gUnknown_020238C8.unk0_0 = gBattleBufferA[gActiveBattler][1]; - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd39(void) -{ - gUnknown_020238C8.unk0_7 = 0; - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd40(void) -{ - gUnknown_020238C8.unk0_7 ^= 1; - OpponentBufferExecCompleted(); -} - -void OpponentHandleHitAnimation(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].invisible == TRUE) - { - OpponentBufferExecCompleted(); - } - else - { - gDoingBattleAnim = TRUE; - gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; - sub_8047858(gActiveBattler); - gBattleBankFunc[gActiveBattler] = bx_blink_t7; - } -} - -void OpponentHandlecmd42(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandleEffectivenessSound(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == 0) - pan = -64; - else - pan = 63; - PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan); - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd44(void) -{ - PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - OpponentBufferExecCompleted(); -} - -void OpponentHandleFaintingCry(void) -{ - PlayCry3( - GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES), - 25, 5); - OpponentBufferExecCompleted(); -} - -void OpponentHandleIntroSlide(void) -{ - StartBattleIntroAnim(gBattleBufferA[gActiveBattler][1]); - gUnknown_02024DE8 |= 1; - OpponentBufferExecCompleted(); -} - -void OpponentHandleTrainerBallThrow(void) -{ - u8 taskId; - - oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 35; - gSprites[gBankSpriteIds[gActiveBattler]].data[2] = 280; - gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; - gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], sub_8035C10); - taskId = CreateTask(sub_8035C44, 5); - gTasks[taskId].data[0] = gActiveBattler; - if (ewram17810[gActiveBattler].unk0_0) - gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; - ewram17840.unk9_0 = 1; - gBattleBankFunc[gActiveBattler] = nullsub_45; -} - -void sub_8035C10(struct Sprite *sprite) -{ - sub_8031B74(sprite->oam.affineParam); - sprite->oam.tileNum = sprite->data[5]; - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); -} - -void sub_8035C44(u8 taskId) -{ - u8 r9; - - r9 = gActiveBattler; - gActiveBattler = gTasks[taskId].data[0]; - if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - sub_803495C(gActiveBattler, 0); - } - else - { - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - sub_803495C(gActiveBattler, 0); - gActiveBattler ^= 2; - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - sub_803495C(gActiveBattler, 0); - gActiveBattler ^= 2; - } - gBattleBankFunc[gActiveBattler] = sub_8032E2C; - gActiveBattler = r9; - DestroyTask(taskId); -} - -void OpponentHandlecmd48(void) -{ - if (gBattleBufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == 0) - { - OpponentBufferExecCompleted(); - return; - } - - ewram17810[gActiveBattler].unk0_0 = 1; - if (gBattleBufferA[gActiveBattler][2] != 0) - { - if (ewram17810[gActiveBattler].unk1_1 < 2) - { - ewram17810[gActiveBattler].unk1_1++; - return; - } - else - { - ewram17810[gActiveBattler].unk1_1 = 0; - } - } - gUnknown_02024E68[gActiveBattler] = sub_8044804( - gActiveBattler, - (struct BattleInterfaceStruct2 *)&gBattleBufferA[gActiveBattler][4], - gBattleBufferA[gActiveBattler][1], - gBattleBufferA[gActiveBattler][2]); - ewram17810[gActiveBattler].unk5 = 0; - if (gBattleBufferA[gActiveBattler][2] != 0) - ewram17810[gActiveBattler].unk5 = 0x5D; - gBattleBankFunc[gActiveBattler] = sub_8035E2C; -} - -void sub_8035E2C(void) -{ - if (ewram17810[gActiveBattler].unk5++ >= 93) - { - ewram17810[gActiveBattler].unk5 = 0; - OpponentBufferExecCompleted(); - } -} - -void OpponentHandlecmd49(void) -{ - if (ewram17810[gActiveBattler].unk0_0) - gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd50(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandleSpriteInvisibility(void) -{ - if (IsBankSpritePresent(gActiveBattler) != 0) - { - gSprites[gBankSpriteIds[gActiveBattler]].invisible = gBattleBufferA[gActiveBattler][1]; - sub_8031F88(gActiveBattler); - } - OpponentBufferExecCompleted(); -} - -void OpponentHandleBattleAnimation(void) -{ - if (mplay_80342A4(gActiveBattler) == 0) - { - u8 r3 = gBattleBufferA[gActiveBattler][1]; - u16 r4 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); - - if (move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, r3, r4) != 0) - OpponentBufferExecCompleted(); - else - gBattleBankFunc[gActiveBattler] = sub_80334C0; - } -} - -void OpponentHandleLinkStandbyMsg(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandleResetActionMoveSelection(void) -{ - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd55(void) -{ - if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && !(gBattleTypeFlags & BATTLE_TYPE_WILD)) - { - gMain.inBattle = FALSE; - gMain.callback1 = gPreBattleCallback1; - SetMainCallback2(gMain.savedCallback); - } - OpponentBufferExecCompleted(); -} - -void OpponentHandlecmd56(void) -{ -} diff --git a/src/battle/battle_controller_player.c b/src/battle/battle_controller_player.c deleted file mode 100644 index 5d7a8955c..000000000 --- a/src/battle/battle_controller_player.c +++ /dev/null @@ -1,3239 +0,0 @@ -#include "global.h" -#include "data2.h" -#include "battle.h" -#include "battle_anim.h" -#include "battle_anim_813F0F4.h" -#include "battle_interface.h" -#include "battle_message.h" -#include "item.h" -#include "constants/items.h" -#include "link.h" -#include "m4a.h" -#include "main.h" -#include "menu_cursor.h" -#include "constants/moves.h" -#include "palette.h" -#include "pokemon.h" -#include "rom3.h" -#include "constants/songs.h" -#include "sound.h" -#include "string_util.h" -#include "task.h" -#include "text.h" -#include "util.h" -#include "ewram.h" - -struct MovePpInfo -{ - u16 moves[4]; - u8 pp[4]; - u8 ppBonuses; -}; - -#if ENGLISH -#define SUB_803037C_TILE_DATA_OFFSET 440 -#elif GERMAN -#define SUB_803037C_TILE_DATA_OFFSET 444 -#endif - -extern struct Window gUnknown_03004210; - -extern void (*gBattleBankFunc[])(void); - -extern u8 gBankAttacker; -extern u8 gBankTarget; -extern u32 gOamMatrixAllocBitmap; -extern u8 gUnknown_020297ED; -extern u8 gActiveBattler; -extern u8 gActionSelectionCursor[]; -extern u8 gDisplayedStringBattle[]; -extern u8 gMoveSelectionCursor[]; -extern u8 gBattleBufferA[][0x200]; -extern u8 gBankInMenu; -extern u16 gBattlerPartyIndexes[]; -extern u8 gHealthboxIDs[]; -extern u8 gDoingBattleAnim; -extern u8 gBankSpriteIds[]; -extern u16 gBattleTypeFlags; -extern u8 gBattleOutcome; -extern void (*gAnimScriptCallback)(void); -extern bool8 gAnimScriptActive; -extern u16 gAnimMovePower; -extern s32 gAnimMoveDmg; -extern u8 gAnimFriendship; -extern u16 gWeatherMoveAnim; -extern u32 gTransformedPersonalities[]; -extern u8 gBattleMonForms[]; -extern u16 gUnknown_02024DE8; -extern u8 gUnknown_02024E68[]; -extern struct SpriteTemplate gUnknown_02024E8C; -extern u8 gAnimMoveTurn; -extern u8 gUnknown_02038470[]; -extern u8 gUnknown_03004344; -extern u8 gUnknown_0300434C[]; - -extern const u8 BattleText_OtherMenu[]; -extern const u8 BattleText_MenuOptions[]; -extern const u8 BattleText_PP[]; - -extern void sub_802C68C(void); -extern void sub_802E1B0(void); -extern void sub_802E220(); -extern void sub_802E2D4(); -extern void sub_802E004(void); -extern void sub_802DF30(void); -extern void BattleStopLowHpSound(void); -extern void PlayerBufferExecCompleted(void); -extern void bx_t1_healthbar_update(void); -extern void nullsub_91(void); -extern void sub_802D924(u8); -extern void sub_802E434(void); -extern bool8 mplay_80342A4(u8); -extern void move_anim_start_t2_for_situation(); -extern void bx_blink_t1(void); -extern void sub_8047858(); -extern u8 GetBattlerSide(u8); -extern void StartBattleIntroAnim(); -extern void oamt_add_pos2_onto_pos1(); -extern void StartAnimLinearTranslation(struct Sprite *); -extern void StoreSpriteCallbackInData(); -extern void BattleLoadPlayerMonSprite(); -extern bool8 IsDoubleBattle(void); -extern void sub_802D500(void); -extern bool8 IsBankSpritePresent(u8); -extern bool8 move_anim_start_t3(); -extern void sub_802E460(void); -extern void b_link_standby_message(void); -extern void sub_802D18C(void); -extern void sub_802DF18(void); -extern void BufferStringBattle(); -extern void sub_80326EC(); -extern void sub_8031F24(void); -extern void sub_80324BC(); -extern u8 sub_8031720(); -extern void bx_wait_t1(void); -extern u8 GetBattlerAtPosition(u8); -extern void sub_802DE10(void); -extern void sub_80105EC(struct Sprite *); -extern void sub_802D274(void); -extern void sub_802D23C(void); -extern u8 GetBattlerPosition(u8); -extern void LoadPlayerTrainerBankSprite(); -extern void sub_80313A0(struct Sprite *); -extern void sub_802D204(void); -extern u8 GetBattlerSubpriority(); -extern void sub_802DEAC(void); -extern void sub_80312F0(struct Sprite *); -extern u8 GetBattlerSpriteCoord(); -extern u8 sub_8077F68(); -extern u8 StartSendOutMonAnimation(); -extern void sub_802D798(void); -extern void bx_0802E404(void); -extern u8 gActiveBattler; -extern void (*gBattleBankFunc[])(void); -extern bool8 gDoingBattleAnim; -extern u16 gBattleTypeFlags; -extern u32 gBattleExecBuffer; -extern u8 gBattleBufferA[][0x200]; -extern u8 gBankSpriteIds[]; -extern u8 gActionSelectionCursor[]; -extern u8 gMoveSelectionCursor[]; -extern u8 gAbsentBattlerFlags; -extern u8 gUnknown_03004344; -extern u8 gBattlersCount; -extern u16 gBattlerPartyIndexes[]; -extern struct Window gUnknown_03004210; -extern const u8 BattleText_SwitchWhich[]; -extern u8 gUnknown_03004348; -extern struct BattlePokemon gBattleMons[]; -extern MainCallback gPreBattleCallback1; -extern u8 gHealthboxIDs[]; -extern struct MusicPlayerInfo gMPlay_BGM; -extern u8 gUnknown_0300434C[]; -extern u8 gUnknown_0202E8F4; -extern u8 gUnknown_0202E8F5; -extern u8 gUnknown_02038470[]; -extern u16 gSpecialVar_ItemId; -extern u8 gDisplayedStringBattle[]; -extern const u8 BattleText_LinkStandby[]; - -extern void dp11b_obj_instanciate(u8, u8, s8, s8); -extern u8 GetBattlerPosition(u8); -extern u8 GetBattlerAtPosition(u8); -extern void dp11b_obj_free(u8, u8); -extern void sub_8010520(struct Sprite *); -extern void sub_8010574(struct Sprite *); -extern bool8 IsDoubleBattle(); -extern void sub_804777C(); -extern void sub_8094E20(u8); -extern void nullsub_14(void); -extern void sub_80A6DCC(void); -extern void ReshowBattleScreenAfterMenu(void); - -void PlayerHandleGetAttributes(void); -void PlayerHandlecmd1(void); -void PlayerHandleSetAttributes(void); -void PlayerHandlecmd3(void); -void PlayerHandleLoadPokeSprite(void); -void PlayerHandleSendOutPoke(void); -void PlayerHandleReturnPokeToBall(void); -void PlayerHandleTrainerThrow(void); -void PlayerHandleTrainerSlide(void); -void PlayerHandleTrainerSlideBack(void); -void PlayerHandlecmd10(void); -void PlayerHandlecmd11(void); -void PlayerHandlecmd12(void); -void PlayerHandleBallThrow(void); -void PlayerHandlePuase(void); -void PlayerHandleMoveAnimation(void); -void PlayerHandlePrintString(void); -void PlayerHandlePrintStringPlayerOnly(void); -void PlayerHandlecmd18(void); -void PlayerHandlecmd19(void); -void PlayerHandlecmd20(void); -void PlayerHandleOpenBag(void); -void PlayerHandlecmd22(void); -void PlayerHandlecmd23(void); -void PlayerHandleHealthBarUpdate(void); -void PlayerHandleExpBarUpdate(void); -void PlayerHandleStatusIconUpdate(void); -void PlayerHandleStatusAnimation(void); -void PlayerHandleStatusXor(void); -void PlayerHandlecmd29(void); -void PlayerHandleDMATransfer(void); -void PlayerHandlecmd31(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 PlayerHandlecmd44(void); -void PlayerHandleFaintingCry(void); -void PlayerHandleIntroSlide(void); -void PlayerHandleTrainerBallThrow(void); -void PlayerHandlecmd48(void); -void PlayerHandlecmd49(void); -void PlayerHandlecmd50(void); -void PlayerHandleSpriteInvisibility(void); -void PlayerHandleBattleAnimation(void); -void PlayerHandleLinkStandbyMsg(void); -void PlayerHandleResetActionMoveSelection(void); -void PlayerHandlecmd55(void); -void PlayerHandlecmd56(void); - -const u8 gString_TurnJP[] = _("ターン"); - -void (*const gPlayerBufferCommands[])(void) = -{ - PlayerHandleGetAttributes, - PlayerHandlecmd1, - PlayerHandleSetAttributes, - PlayerHandlecmd3, - PlayerHandleLoadPokeSprite, - PlayerHandleSendOutPoke, - PlayerHandleReturnPokeToBall, - PlayerHandleTrainerThrow, - PlayerHandleTrainerSlide, - PlayerHandleTrainerSlideBack, - PlayerHandlecmd10, - PlayerHandlecmd11, - PlayerHandlecmd12, - PlayerHandleBallThrow, - PlayerHandlePuase, - PlayerHandleMoveAnimation, - PlayerHandlePrintString, - PlayerHandlePrintStringPlayerOnly, - PlayerHandlecmd18, - PlayerHandlecmd19, - PlayerHandlecmd20, - PlayerHandleOpenBag, - PlayerHandlecmd22, - PlayerHandlecmd23, - PlayerHandleHealthBarUpdate, - PlayerHandleExpBarUpdate, - PlayerHandleStatusIconUpdate, - PlayerHandleStatusAnimation, - PlayerHandleStatusXor, - PlayerHandlecmd29, - PlayerHandleDMATransfer, - PlayerHandlecmd31, - PlayerHandlecmd32, - PlayerHandlecmd33, - PlayerHandlecmd34, - PlayerHandlecmd35, - PlayerHandlecmd36, - PlayerHandlecmd37, - PlayerHandlecmd38, - PlayerHandlecmd39, - PlayerHandlecmd40, - PlayerHandleHitAnimation, - PlayerHandlecmd42, - PlayerHandleEffectivenessSound, - PlayerHandlecmd44, - PlayerHandleFaintingCry, - PlayerHandleIntroSlide, - PlayerHandleTrainerBallThrow, - PlayerHandlecmd48, - PlayerHandlecmd49, - PlayerHandlecmd50, - PlayerHandleSpriteInvisibility, - PlayerHandleBattleAnimation, - PlayerHandleLinkStandbyMsg, - PlayerHandleResetActionMoveSelection, - PlayerHandlecmd55, - PlayerHandlecmd56, -}; - -void PlayerBufferRunCommand(void); -void sub_802C2EC(void); -void sub_802C68C(void); -void sub_802CA60(void); -void sub_802D730(void); -void sub_802DA9C(u8); -void sub_802DB6C(u8); -void sub_802DCB0(u8); -void sub_802DD10(u8); -void sub_802DDC4(u8); -void sub_802DF88(void); -void sub_802E03C(void); -void sub_802E12C(s32, const u8 *); -void sub_802E1B0(void); -void sub_802E220(void); -void sub_802E2D4(void); -void sub_802E3B4(u8, int); -void nullsub_7(u8); -void b_link_standby_message(void); -u32 dp01_getattr_by_ch1_for_player_pokemon_(u8, u8 *); -void dp01_setattr_by_ch1_for_player_pokemon(u8); -void sub_802F934(u8, u8); -void sub_802FB2C(void); -void sub_8030190(void); -void sub_80304A8(void); -void sub_8030E38(struct Sprite *); -void task05_08033660(u8); -void sub_8031064(void); - -void nullsub_91(void) -{ -} - -void SetBankFuncToPlayerBufferRunCommand(void) -{ - gBattleBankFunc[gActiveBattler] = PlayerBufferRunCommand; - gDoingBattleAnim = FALSE; -} - -void PlayerBufferExecCompleted(void) -{ - gBattleBankFunc[gActiveBattler] = PlayerBufferRunCommand; - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - u8 playerId = GetMultiplayerId(); - - PrepareBufferDataTransferLink(2, 4, &playerId); - gBattleBufferA[gActiveBattler][0] = 0x38; - } - else - { - gBattleExecBuffer &= ~gBitTable[gActiveBattler]; - } -} - -void PlayerBufferRunCommand(void) -{ - if (gBattleExecBuffer & gBitTable[gActiveBattler]) - { - if (gBattleBufferA[gActiveBattler][0] < 0x39) - gPlayerBufferCommands[gBattleBufferA[gActiveBattler][0]](); - else - PlayerBufferExecCompleted(); - } -} - -void bx_0802E404(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].pos2.x == 0) - PlayerBufferExecCompleted(); -} - -void sub_802C098(void) -{ - u16 itemId = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); - - dp11b_obj_instanciate(gActiveBattler, 1, 7, 1); - dp11b_obj_instanciate(gActiveBattler, 0, 7, 1); - if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - DestroyMenuCursor(); - - // Useless switch statement. - switch (gActionSelectionCursor[gActiveBattler]) - { - case 0: - Emitcmd33(1, 0, 0); - break; - case 1: - Emitcmd33(1, 1, 0); - break; - case 2: - Emitcmd33(1, 2, 0); - break; - case 3: - Emitcmd33(1, 3, 0); - break; - } - PlayerBufferExecCompleted(); - } - else if (gMain.newKeys & DPAD_LEFT) - { - if (gActionSelectionCursor[gActiveBattler] & 1) - { - PlaySE(SE_SELECT); - nullsub_8(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 1; - sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); - } - } - else if (gMain.newKeys & DPAD_RIGHT) - { - if (!(gActionSelectionCursor[gActiveBattler] & 1)) - { - PlaySE(SE_SELECT); - nullsub_8(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 1; - sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); - } - } - else if (gMain.newKeys & DPAD_UP) - { - if (gActionSelectionCursor[gActiveBattler] & 2) - { - PlaySE(SE_SELECT); - nullsub_8(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 2; - sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); - } - } - else if (gMain.newKeys & DPAD_DOWN) - { - if (!(gActionSelectionCursor[gActiveBattler] & 2)) - { - PlaySE(SE_SELECT); - nullsub_8(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 2; - sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); - } - } - else if (gMain.newKeys & B_BUTTON) - { - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - && GetBattlerPosition(gActiveBattler) == 2 - && !(gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(0)]) - && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - if (gBattleBufferA[gActiveBattler][1] == 1) - { - // Add item to bag if it is a ball - if (itemId <= ITEM_PREMIER_BALL) - AddBagItem(itemId, 1); - else - return; - } - PlaySE(SE_SELECT); - Emitcmd33(1, 12, 0); - PlayerBufferExecCompleted(); - DestroyMenuCursor(); - } - } - else if (gMain.newKeys & START_BUTTON) - { - sub_804454C(); - } -} - -void unref_sub_802C2B8(void) -{ - dp11b_obj_free(gActiveBattler, 1); - dp11b_obj_free(gActiveBattler, 0); - gBattleBankFunc[gActiveBattler] = sub_802C2EC; -} - -// TODO: fix this function -void sub_802C2EC(void) -{ - u8 arr[4] = {0, 2, 3, 1}; - s32 i; - - dp11b_obj_instanciate(gUnknown_03004344, 1, 15, 1); - i = 0; - if (gBattlersCount != 0) - { - do - { - if (i != gUnknown_03004344) - dp11b_obj_free(i, 1); - i++; - } while (i < gBattlersCount); - } - if (gMain.newKeys & A_BUTTON) - { - DestroyMenuCursor(); - PlaySE(SE_SELECT); - gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010574; - Emitcmd33(1, 10, gMoveSelectionCursor[gActiveBattler] | (gUnknown_03004344 << 8)); - dp11b_obj_free(gUnknown_03004344, 1); - PlayerBufferExecCompleted(); - } - //_0802C3A8 - else if (gMain.newKeys & B_BUTTON) - { - PlaySE(SE_SELECT); - gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010574; - gBattleBankFunc[gActiveBattler] = sub_802C68C; - dp11b_obj_instanciate(gActiveBattler, 1, 7, 1); - dp11b_obj_instanciate(gActiveBattler, 0, 7, 1); - dp11b_obj_free(gUnknown_03004344, 1); - } - else if (gMain.newKeys & 0x60) - { - PlaySE(SE_SELECT); - gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010574; - do - { - u8 var = GetBattlerPosition(gUnknown_03004344); - - for (i = 0; i < 4; i++) - { - if (var == arr[i]) - break; - } - do - { - i--; - if (i < 0) - i = 3; - gUnknown_03004344 = GetBattlerAtPosition(arr[i]); - } while(gUnknown_03004344 == gBattlersCount); - i = 0; - switch (GetBattlerPosition(gUnknown_03004344)) - { - case 0: - case 2: - if (gActiveBattler == gUnknown_03004344) - { - u32 moveId; - - asm("":::"memory"); - moveId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler]); - if (!(gBattleMoves[moveId].target & 2)) - break; - } - i++; - break; - case 1: - case 3: - i++; - } - //_0802C500 - if (gAbsentBattlerFlags & gBitTable[gUnknown_03004344]) - i = 0; - } while (i == 0); - gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010520; - } - //_0802C540 - else if (gMain.newKeys & 0x90) - { - PlaySE(SE_SELECT); - gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010574; - do - { - u8 var = GetBattlerPosition(gUnknown_03004344); - - for (i = 0; i < 4; i++) - { - if (var == arr[i]) - break; - } - do - { - i++; - if (i > 3) - i = 0; - gUnknown_03004344 = GetBattlerAtPosition(arr[i]); - } while (gUnknown_03004344 == gBattlersCount); - i = 0; - switch (GetBattlerPosition(gUnknown_03004344)) - { - case 0: - case 2: - if (gActiveBattler == gUnknown_03004344) - { - u32 moveId; - - asm("":::"memory"); - moveId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler]); - if (!(gBattleMoves[moveId].target & 2)) - break; - } - i++; - break; - case 1: - case 3: - i++; - } - if (gAbsentBattlerFlags & gBitTable[gUnknown_03004344]) - i = 0; - } while (i == 0); - gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010520; - } -} - -struct ChooseMoveStruct -{ - u16 moves[4]; - u8 pp[4]; - u8 unkC[0x12-0xC]; - u8 unk12; - u8 effectStringId; - u8 filler14[0x20-0x14]; -}; - -const u8 gUnknown_081FAE80[] = _("{PALETTE 5}{COLOR_HIGHLIGHT_SHADOW WHITE LIGHT_BLUE WHITE2}"); - -void debug_sub_8030C24(void); - -void sub_802C68C(void) -{ - u32 r8 = 0; -#if DEBUG - u8 count = 0; -#endif - struct ChooseMoveStruct *r6 = (struct ChooseMoveStruct *)(gBattleBufferA[gActiveBattler] + 4); - - if (gMain.newKeys & A_BUTTON) - { - u32 r4; - - PlaySE(SE_SELECT); - - if (r6->moves[gMoveSelectionCursor[gActiveBattler]] == MOVE_CURSE) - r4 = (r6->unk12 != TYPE_GHOST && (r6->effectStringId ^ 7)) ? 0x10 : 0; - else - r4 = gBattleMoves[r6->moves[gMoveSelectionCursor[gActiveBattler]]].target; - - if (r4 & 0x10) - gUnknown_03004344 = gActiveBattler; - else - gUnknown_03004344 = GetBattlerAtPosition((GetBattlerPosition(gActiveBattler) & 1) ^ 1); - - if (gBattleBufferA[gActiveBattler][1] == 0) - { - if ((r4 & 2) && gBattleBufferA[gActiveBattler][2] == 0) - r8++; - } - else - { - if (!(r4 & 0x7D)) - r8++; - if (r6->pp[gMoveSelectionCursor[gActiveBattler]] == 0) - { - r8 = 0; - } - else if (!(r4 & 0x12) && CountAliveMons(0) <= 1) - { - gUnknown_03004344 = sub_803C434(gActiveBattler); - r8 = 0; - } - } - if (r8 == 0) - { - DestroyMenuCursor(); - Emitcmd33(1, 10, gMoveSelectionCursor[gActiveBattler] | (gUnknown_03004344 << 8)); - PlayerBufferExecCompleted(); - } - else - { - gBattleBankFunc[gActiveBattler] = sub_802C2EC; - if (r4 & 0x12) - gUnknown_03004344 = gActiveBattler; - else if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(1)]) - gUnknown_03004344 = GetBattlerAtPosition(3); - else - gUnknown_03004344 = GetBattlerAtPosition(1); - gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010520; - } - } - else if (gMain.newKeys & B_BUTTON) - { - DestroyMenuCursor(); - PlaySE(SE_SELECT); - gBattle_BG0_X = 0; - gBattle_BG0_Y = 320; - Emitcmd33(1, 10, 0xFFFF); - PlayerBufferExecCompleted(); - } - else if (gMain.newKeys & DPAD_LEFT) - { - if (gMoveSelectionCursor[gActiveBattler] & 1) - { - nullsub_7(gMoveSelectionCursor[gActiveBattler]); - gMoveSelectionCursor[gActiveBattler] ^= 1; - PlaySE(SE_SELECT); - sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); - sub_802E220(); - sub_802E2D4(); - } - } - else if (gMain.newKeys & DPAD_RIGHT) - { - if (!(gMoveSelectionCursor[gActiveBattler] & 1) - && (gMoveSelectionCursor[gActiveBattler] ^ 1) < gUnknown_03004348) - { - nullsub_7(gMoveSelectionCursor[gActiveBattler]); - gMoveSelectionCursor[gActiveBattler] ^= 1; - PlaySE(SE_SELECT); - sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); - sub_802E220(); - sub_802E2D4(); - } - } - else if (gMain.newKeys & DPAD_UP) - { - if (gMoveSelectionCursor[gActiveBattler] & 2) - { - nullsub_7(gMoveSelectionCursor[gActiveBattler]); - gMoveSelectionCursor[gActiveBattler] ^= 2; - PlaySE(SE_SELECT); - sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); - sub_802E220(); - sub_802E2D4(); - } - } - else if (gMain.newKeys & DPAD_DOWN) - { - if (!(gMoveSelectionCursor[gActiveBattler] & 2) - && (gMoveSelectionCursor[gActiveBattler] ^ 2) < gUnknown_03004348) - { - nullsub_7(gMoveSelectionCursor[gActiveBattler]); - gMoveSelectionCursor[gActiveBattler] ^= 2; - PlaySE(SE_SELECT); - sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); - sub_802E220(); - sub_802E2D4(); - } - } - else if (gMain.newKeys & SELECT_BUTTON) - { - if (gUnknown_03004348 > 1 && !(gBattleTypeFlags & BATTLE_TYPE_LINK)) - { - sub_802E12C(gMoveSelectionCursor[gActiveBattler], gUnknown_081FAE80); - if (gMoveSelectionCursor[gActiveBattler] != 0) - gUnknown_03004344 = 0; - else - gUnknown_03004344 = gMoveSelectionCursor[gActiveBattler] + 1; - sub_802E3B4(gUnknown_03004344, 27); - Text_FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x37, 0x1C, 0x3A); - Text_InitWindow(&gUnknown_03004210, BattleText_SwitchWhich, 0x290, 0x17, 0x37); - Text_PrintWindow8002F44(&gUnknown_03004210); - gBattleBankFunc[gActiveBattler] = sub_802CA60; - } - } -#if DEBUG - else if (gUnknown_020297ED == 1 && (gMain.newKeys & START_BUTTON)) - { - const u8 *moveName; - s32 i; - - Text_FillWindowRect(&gUnknown_03004210, 0x1016, 1, 0x37, 16, 0x3A); - moveName = gMoveNames[GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1)]; - Text_InitWindowAndPrintText(&gUnknown_03004210, moveName, 0x100, 2, 0x37); - ConvertIntToDecimalStringN( - gDisplayedStringBattle, - GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1), - 2, 3); - Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 0x110, 10, 0x37); - Text_InitWindowAndPrintText(&gUnknown_03004210, gString_TurnJP, 0x116, 1, 0x39); - ConvertIntToDecimalStringN(gDisplayedStringBattle, gAnimMoveTurn, 2, 3); - Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 0x11C, 4, 0x39); - for (i = 0; i < 64; i++) - { - if (gSprites[i].inUse) - count++; - } - ConvertIntToDecimalStringN(gDisplayedStringBattle, count, 2, 2); - Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 0x122, 8, 0x39); - count = GetTaskCount(); - ConvertIntToDecimalStringN(gDisplayedStringBattle, count, 2, 2); - Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 0x126, 11, 0x39); - for (i = 0, count = 0; i < 32; i++) - { - if (gOamMatrixAllocBitmap & (1 << i)) - count++; - } - ConvertIntToDecimalStringN(gDisplayedStringBattle, count, 2, 2); - Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 0x12A, 14, 0x39); - gBattleBankFunc[gActiveBattler] = debug_sub_8030C24; - } -#endif -} - -extern const u8 BattleText_Format[]; - -void sub_802CA60(void) -{ - u8 perMovePPBonuses[4]; - struct - { - u16 moves[4]; - u8 pp[4]; - u8 filler18[8]; // what is this? - } sp0; - //struct ChooseMoveStruct sp0; - u8 totalPPBonuses; - - if (gMain.newKeys & (A_BUTTON | SELECT_BUTTON)) - { - PlaySE(SE_SELECT); - if (gMoveSelectionCursor[gActiveBattler] != gUnknown_03004344) - { - struct ChooseMoveStruct *r9 = (struct ChooseMoveStruct *)&gBattleBufferA[gActiveBattler][4]; - s32 i; - - i = r9->moves[gMoveSelectionCursor[gActiveBattler]]; - r9->moves[gMoveSelectionCursor[gActiveBattler]] = r9->moves[gUnknown_03004344]; - r9->moves[gUnknown_03004344] = i; - - i = r9->pp[gMoveSelectionCursor[gActiveBattler]]; - r9->pp[gMoveSelectionCursor[gActiveBattler]] = r9->pp[gUnknown_03004344]; - r9->pp[gUnknown_03004344] = i; - - i = r9->unkC[gMoveSelectionCursor[gActiveBattler]]; - r9->unkC[gMoveSelectionCursor[gActiveBattler]] = r9->unkC[gUnknown_03004344]; - r9->unkC[gUnknown_03004344] = i; - - if (gDisableStructs[gActiveBattler].unk18_b & gBitTable[gMoveSelectionCursor[gActiveBattler]]) - { - gDisableStructs[gActiveBattler].unk18_b &= ~gBitTable[gMoveSelectionCursor[gActiveBattler]]; - gDisableStructs[gActiveBattler].unk18_b |= gBitTable[gUnknown_03004344]; - } - - sub_802E1B0(); - - for (i = 0; i < 4; i++) - perMovePPBonuses[i] = (gBattleMons[gActiveBattler].ppBonuses & (3 << (i * 2))) >> (i * 2); - totalPPBonuses = perMovePPBonuses[gMoveSelectionCursor[gActiveBattler]]; - perMovePPBonuses[gMoveSelectionCursor[gActiveBattler]] = perMovePPBonuses[gUnknown_03004344]; - perMovePPBonuses[gUnknown_03004344] = totalPPBonuses; - - totalPPBonuses = 0; - for (i = 0; i < 4; i++) - totalPPBonuses |= perMovePPBonuses[i] << (i * 2); - gBattleMons[gActiveBattler].ppBonuses = totalPPBonuses; - - for (i = 0; i < 4; i++) - { - gBattleMons[gActiveBattler].moves[i] = r9->moves[i]; - gBattleMons[gActiveBattler].pp[i] = r9->pp[i]; - } - if (!(gBattleMons[gActiveBattler].status2 & 0x200000)) - { - for (i = 0; i < 4; i++) - { - sp0.moves[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + i); - sp0.pp[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_PP1 + i); - } - - totalPPBonuses = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_PP_BONUSES); - for (i = 0; i < 4; i++) - perMovePPBonuses[i] = (totalPPBonuses & (3 << (i * 2))) >> (i * 2); - - i = sp0.moves[gMoveSelectionCursor[gActiveBattler]]; - sp0.moves[gMoveSelectionCursor[gActiveBattler]] = sp0.moves[gUnknown_03004344]; - sp0.moves[gUnknown_03004344] = i; - - i = sp0.pp[gMoveSelectionCursor[gActiveBattler]]; - sp0.pp[gMoveSelectionCursor[gActiveBattler]] = sp0.pp[gUnknown_03004344]; - sp0.pp[gUnknown_03004344] = i; - - totalPPBonuses = perMovePPBonuses[gMoveSelectionCursor[gActiveBattler]]; - perMovePPBonuses[gMoveSelectionCursor[gActiveBattler]] = perMovePPBonuses[gUnknown_03004344]; - perMovePPBonuses[gUnknown_03004344] = totalPPBonuses; - - totalPPBonuses = 0; - for (i = 0; i < 4; i++) - totalPPBonuses |= perMovePPBonuses[i] << (i * 2); - - for (i = 0; i < 4; i++) - { - SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + i, &sp0.moves[i]); - SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_PP1 + i, &sp0.pp[i]); - } - SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_PP_BONUSES, &totalPPBonuses); - } - } - else - { - sub_802E12C(gUnknown_03004344, BattleText_Format); - } - gBattleBankFunc[gActiveBattler] = sub_802C68C; - gMoveSelectionCursor[gActiveBattler] = gUnknown_03004344; - sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); - Text_FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x37, 0x1C, 0x3A); - Text_InitWindow(&gUnknown_03004210, BattleText_PP, 0x290, 0x17, 0x37); - Text_PrintWindow8002F44(&gUnknown_03004210); - sub_802E220(); - sub_802E2D4(); - } - if (gMain.newKeys & (B_BUTTON | SELECT_BUTTON)) - { - PlaySE(SE_SELECT); - nullsub_7(gUnknown_03004344); - sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); - sub_802E12C(gMoveSelectionCursor[gActiveBattler], BattleText_Format); - gBattleBankFunc[gActiveBattler] = sub_802C68C; - Text_FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x37, 0x1C, 0x3A); - Text_InitWindow(&gUnknown_03004210, BattleText_PP, 0x290, 0x17, 0x37); - Text_PrintWindow8002F44(&gUnknown_03004210); - sub_802E220(); - sub_802E2D4(); - } - if ((gMain.newKeys & DPAD_LEFT) && (gUnknown_03004344 & 1)) - { - if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) - sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0x1D); - else - nullsub_7(gUnknown_03004344); - gUnknown_03004344 ^= 1; - PlaySE(SE_SELECT); - if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) - sub_802E3B4(gUnknown_03004344, 0); - else - sub_802E3B4(gUnknown_03004344, 0x1B); - } - if ((gMain.newKeys & DPAD_RIGHT) && !(gUnknown_03004344 & 1) && (gUnknown_03004344 ^ 1) < gUnknown_03004348) - { - if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) - sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0x1D); - else - nullsub_7(gUnknown_03004344); - gUnknown_03004344 ^= 1; - PlaySE(SE_SELECT); - if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) - sub_802E3B4(gUnknown_03004344, 0); - else - sub_802E3B4(gUnknown_03004344, 0x1B); - } - if ((gMain.newKeys & DPAD_UP) && (gUnknown_03004344 & 2)) - { - if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) - sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0x1D); - else - nullsub_7(gUnknown_03004344); - gUnknown_03004344 ^= 2; - PlaySE(SE_SELECT); - if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) - sub_802E3B4(gUnknown_03004344, 0); - else - sub_802E3B4(gUnknown_03004344, 0x1B); - } - if ((gMain.newKeys & DPAD_DOWN) && !(gUnknown_03004344 & 2) && (gUnknown_03004344 ^ 2) < gUnknown_03004348) - { - if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) - sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0x1D); - else - nullsub_7(gUnknown_03004344); - gUnknown_03004344 ^= 2; - PlaySE(SE_SELECT); - if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) - sub_802E3B4(gUnknown_03004344, 0); - else - sub_802E3B4(gUnknown_03004344, 0x1B); - } -} - -void sub_802D148(void) -{ - if (gReceivedRemoteLinkPlayers == 0) - { - m4aSongNumStop(SE_HINSI); - gMain.inBattle = FALSE; - gMain.callback1 = gPreBattleCallback1; - SetMainCallback2(c2_8011A1C); - } -} - -void sub_802D18C(void) -{ - if (!gPaletteFade.active) - { - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - sub_800832C(); - gBattleBankFunc[gActiveBattler] = sub_802D148; - } - else - { - m4aSongNumStop(SE_HINSI); - gMain.inBattle = FALSE; - gMain.callback1 = gPreBattleCallback1; - SetMainCallback2(gMain.savedCallback); - } - } -} - -#if DEBUG - -void debug_sub_803107C(void); - -void debug_sub_8030C24(void) -{ - s16 move = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1); - - switch (gMain.newAndRepeatedKeys) - { - case START_BUTTON: - dp11b_obj_free(gActiveBattler, 1); - dp11b_obj_free(gActiveBattler, 0); - gBankAttacker = gActiveBattler; - if ((gMain.heldKeysRaw & B_BUTTON) && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - gBankTarget = gBankAttacker ^ 2; - else if ((gMain.heldKeysRaw & A_BUTTON) && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - gBankTarget = GetBattlerAtPosition(3); - else - gBankTarget = GetBattlerAtPosition(1); - sub_80326EC(0); - DoMoveAnim(move); - gBattleBankFunc[gActiveBattler] = debug_sub_803107C; - break; - case SELECT_BUTTON: - dp11b_obj_free(gActiveBattler, 1); - dp11b_obj_free(gActiveBattler, 0); - gBankTarget = gActiveBattler; - if ((gMain.heldKeysRaw & B_BUTTON) && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - gBankAttacker = gBankTarget ^ 2; - else if ((gMain.heldKeysRaw & A_BUTTON) && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - gBankAttacker = GetBattlerAtPosition(3); - else - gBankAttacker = GetBattlerAtPosition(1); - sub_80326EC(0); - DoMoveAnim(move); - gBattleBankFunc[gActiveBattler] = debug_sub_803107C; - break; - case R_BUTTON: - if ((gMain.heldKeysRaw & B_BUTTON) && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - dp11b_obj_free(gActiveBattler, 1); - dp11b_obj_free(gActiveBattler, 0); - gBankAttacker = GetBattlerAtPosition(3); - gBankTarget = GetBattlerAtPosition(1); - sub_80326EC(0); - DoMoveAnim(move); - gBattleBankFunc[gActiveBattler] = debug_sub_803107C; - } - else - { - move += 9; - case DPAD_RIGHT: - if (++move > 354) - move = 1; - SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1, &move); - gBattleMons[gActiveBattler].moves[0] = move; - Text_FillWindowRect(&gUnknown_03004210, 0x1016, 1, 0x37, 16, 0x38); - Text_InitWindowAndPrintText(&gUnknown_03004210, gMoveNames[move], 0x100, 2, 0x37); - ConvertIntToDecimalStringN(gDisplayedStringBattle, move, 2, 3); - Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 272, 10, 0x37); - } - break; - case L_BUTTON: - if ((gMain.heldKeysRaw & B_BUTTON) && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - { - dp11b_obj_free(gActiveBattler, 1); - dp11b_obj_free(gActiveBattler, 0); - gBankAttacker = GetBattlerAtPosition(1); - gBankTarget = GetBattlerAtPosition(3); - sub_80326EC(0); - DoMoveAnim(move); - gBattleBankFunc[gActiveBattler] = debug_sub_803107C; - } - else - { - move -= 9; - case DPAD_LEFT: - if (--move <= 0) - move = 354; - SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1, &move); - gBattleMons[gActiveBattler].moves[0] = move; - Text_FillWindowRect(&gUnknown_03004210, 0x1016, 1, 0x37, 16, 0x38); - Text_InitWindowAndPrintText(&gUnknown_03004210, gMoveNames[move], 0x100, 2, 0x37); - ConvertIntToDecimalStringN(gDisplayedStringBattle, move, 2, 3); - Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 272, 10, 0x37); - } - break; - case DPAD_UP: - case DPAD_DOWN: - if (gMain.newAndRepeatedKeys == DPAD_UP) - gAnimMoveTurn--; - else - gAnimMoveTurn++; - ConvertIntToDecimalStringN(gDisplayedStringBattle, gAnimMoveTurn, 2, 3); - Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 284, 4, 0x39); - break; - } - - if ((gMain.heldKeysRaw & (L_BUTTON | R_BUTTON)) == (L_BUTTON | R_BUTTON)) - { - u8 i; - u32 move; - - for (i = 0; i < 4; i++) - { - StringCopy(gDisplayedStringBattle, BattleText_Format); - move = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + i); - StringAppend(gDisplayedStringBattle, gMoveNames[move]); - Text_InitWindow( - &gUnknown_03004210, - gDisplayedStringBattle, - 0x100 + i * 16, - (i & 1) ? 10 : 2, - (i < 2) ? 0x37 : 0x39); - Text_PrintWindow8002F44(&gUnknown_03004210); - } - gBattleBankFunc[gActiveBattler] = sub_802C68C; - } -} - -void debug_sub_803107C(void) -{ - u8 count = 0; - - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - s32 i; - - sub_80326EC(1); - dp11b_obj_instanciate(gActiveBattler, 1, 7, 1); - dp11b_obj_instanciate(gActiveBattler, 0, 7, 1); - - for (i = 0, count = 0; i < MAX_SPRITES; i++) - { - if (gSprites[i].inUse) - count++; - } - ConvertIntToDecimalStringN(gDisplayedStringBattle, count, 2, 2); - Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 290, 8, 0x39); - - count = GetTaskCount(); - ConvertIntToDecimalStringN(gDisplayedStringBattle, count, 2, 2); - Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 294, 11, 0x39); - - for (i = 0, count = 0; i < 32; i++) - { - if (gOamMatrixAllocBitmap & (1 << i)) - count++; - } - ConvertIntToDecimalStringN(gDisplayedStringBattle, count, 2, 2); - Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 298, 14, 0x39); - - gBattleBankFunc[gActiveBattler] = debug_sub_8030C24; - } -} - -#endif - -void sub_802D204(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - PlayerBufferExecCompleted(); -} - -// duplicate of sub_802D204 -void sub_802D23C(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - PlayerBufferExecCompleted(); -} - -void sub_802D274(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - { - nullsub_10(gSaveBlock2.playerGender); - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - PlayerBufferExecCompleted(); - } -} - -void sub_802D2E0(void) -{ - if (--ewram17810[gActiveBattler].unk9 == 0xFF) - { - ewram17810[gActiveBattler].unk9 = 0; - PlayerBufferExecCompleted(); - } -} - -void sub_802D31C(void) -{ - bool8 r6 = FALSE; - - if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) - { - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) - r6 = TRUE; - } - else - { - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy - && gSprites[gHealthboxIDs[gActiveBattler ^ 2]].callback == SpriteCallbackDummy) - r6 = TRUE; - } - if (IsCryPlayingOrClearCrySongs()) - r6 = FALSE; - - if (r6 && ewram17810[gActiveBattler].unk1_0 && ewram17810[gActiveBattler ^ 2].unk1_0) - { - ewram17810[gActiveBattler].unk0_7 = 0; - ewram17810[gActiveBattler].unk1_0 = 0; - ewram17810[gActiveBattler ^ 2].unk0_7 = 0; - ewram17810[gActiveBattler ^ 2].unk1_0 = 0; - FreeSpriteTilesByTag(0x27F9); - FreeSpritePaletteByTag(0x27F9); - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - m4aMPlayContinue(&gMPlay_BGM); - else - m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 256); - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - if (IsDoubleBattle()) - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], gActiveBattler ^ 2); - ewram17810[gActiveBattler].unk9 = 3; - gBattleBankFunc[gActiveBattler] = sub_802D2E0; - } -} - -void sub_802D500(void) -{ - if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) - sub_8141828(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); - if (!ewram17810[gActiveBattler ^ 2].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_7) - sub_8141828(gActiveBattler ^ 2, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ 2]]); - if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_3) - { - if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler ^ 2]]); - sub_8045A5C( - gHealthboxIDs[gActiveBattler ^ 2], - &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], - 0); - sub_804777C(gActiveBattler ^ 2); - sub_8043DFC(gHealthboxIDs[gActiveBattler ^ 2]); - } - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); - sub_8045A5C( - gHealthboxIDs[gActiveBattler], - &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], - 0); - sub_804777C(gActiveBattler); - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - ewram17840.unk9_0 = 0; - gBattleBankFunc[gActiveBattler] = sub_802D31C; - } -} - -void sub_802D680(void) -{ - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy - && ewram17810[gActiveBattler].unk1_0) - { - ewram17810[gActiveBattler].unk0_7 = 0; - ewram17810[gActiveBattler].unk1_0 = 0; - FreeSpriteTilesByTag(0x27F9); - FreeSpritePaletteByTag(0x27F9); - if (ewram17800[gActiveBattler].substituteSprite) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); - gBattleBankFunc[gActiveBattler] = sub_802D730; - } -} - -void sub_802D730(void) -{ - if (!ewram17810[gActiveBattler].unk0_6 && !IsCryPlayingOrClearCrySongs()) - { - m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - PlayerBufferExecCompleted(); - } -} - -void sub_802D798(void) -{ - if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) - sub_8141828(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); - if (gSprites[gUnknown_0300434C[gActiveBattler]].callback == SpriteCallbackDummy - && !ewram17810[gActiveBattler].unk0_3) - { - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); - sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 0); - sub_804777C(gActiveBattler); - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - sub_8031F88(gActiveBattler); - gBattleBankFunc[gActiveBattler] = sub_802D680; - } -} - -void c3_0802FDF4(u8 taskId) -{ - if (!IsCryPlayingOrClearCrySongs()) - { - m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); - DestroyTask(taskId); - } -} - -void bx_t1_healthbar_update(void) -{ - s16 r4 = sub_8045C78(gActiveBattler, gHealthboxIDs[gActiveBattler], 0, 0); - - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - if (r4 != -1) - { - sub_80440EC(gHealthboxIDs[gActiveBattler], r4, 0); - } - else - { - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - PlayerBufferExecCompleted(); - } -} - -void sub_802D90C(void) -{ - if (gUnknown_03004210.state == 0) - PlayerBufferExecCompleted(); -} - -// Rare Candy usage, maybe? -void sub_802D924(u8 taskId) -{ - u32 pkmnIndex = (u8)gTasks[taskId].data[0]; - u8 bank = gTasks[taskId].data[2]; - s16 gainedExp = gTasks[taskId].data[1]; - - if (IsDoubleBattle() == TRUE || pkmnIndex != gBattlerPartyIndexes[bank]) - { - struct Pokemon *pkmn = &gPlayerParty[pkmnIndex]; - u16 species = GetMonData(pkmn, MON_DATA_SPECIES); - u8 level = GetMonData(pkmn, MON_DATA_LEVEL); - u32 currExp = GetMonData(pkmn, MON_DATA_EXP); - u32 nextLvlExp = gExperienceTables[gBaseStats[species].growthRate][level + 1]; - - if (currExp + gainedExp >= nextLvlExp) - { - u8 savedActiveBank; - - SetMonData(pkmn, MON_DATA_EXP, &nextLvlExp); - CalculateMonStats(pkmn); - gainedExp -= nextLvlExp - currExp; - savedActiveBank = gActiveBattler; - gActiveBattler = bank; - Emitcmd33(1, 11, gainedExp); - gActiveBattler = savedActiveBank; - - if (IsDoubleBattle() == TRUE - && ((u16)pkmnIndex == gBattlerPartyIndexes[bank] || (u16)pkmnIndex == gBattlerPartyIndexes[bank ^ 2])) - gTasks[taskId].func = sub_802DCB0; - else - gTasks[taskId].func = sub_802DDC4; - } - else - { - currExp += gainedExp; - SetMonData(pkmn, MON_DATA_EXP, &currExp); - gBattleBankFunc[bank] = sub_802D90C; - DestroyTask(taskId); - } - } - else - { - gTasks[taskId].func = sub_802DA9C; - } -} - -void sub_802DA9C(u8 taskId) -{ - u8 pkmnIndex = gTasks[taskId].data[0]; - s32 r9 = gTasks[taskId].data[1]; - u8 bank = gTasks[taskId].data[2]; - struct Pokemon *pkmn = &gPlayerParty[pkmnIndex]; - u8 level = GetMonData(pkmn, MON_DATA_LEVEL); - u16 species = GetMonData(pkmn, MON_DATA_SPECIES); - u32 exp = GetMonData(pkmn, MON_DATA_EXP); - u32 currLvlExp = gExperienceTables[gBaseStats[species].growthRate][level]; - u32 expToNextLvl; - - exp -= currLvlExp; - expToNextLvl = gExperienceTables[gBaseStats[species].growthRate][level + 1] - currLvlExp; - sub_8043D84(bank, gHealthboxIDs[bank], expToNextLvl, exp, -r9); - PlaySE(SE_EXP); - gTasks[taskId].func = sub_802DB6C; -} - -#ifdef NONMATCHING -void sub_802DB6C(u8 taskId) -{ - if (gTasks[taskId].data[10] < 13) - { - gTasks[taskId].data[10]++; - } - else - { - u8 r9 = gTasks[taskId].data[0]; - s32 r10 = gTasks[taskId].data[1]; //s16? - u8 r7 = gTasks[taskId].data[2]; - s16 r4; - - r4 = sub_8045C78(r7, gHealthboxIDs[r7], 1, 0); - sub_8043DFC(gHealthboxIDs[r7]); - if (r4 == -1) - { - struct Pokemon *pkmn; - u8 r4; - u32 sp4; - u16 r0; - u32 sp0; - - m4aSongNumStop(SE_EXP); - pkmn = &gPlayerParty[r9]; - r4 = GetMonData(pkmn, MON_DATA_LEVEL); - sp4 = GetMonData(pkmn, MON_DATA_EXP); - r0 = GetMonData(pkmn, MON_DATA_SPECIES); - sp0 = gExperienceTables[gBaseStats[r0].growthRate][r4 + 1]; - if (sp4 + r10 >= sp0) - { - u8 r5; - u32 asdf; - - SetMonData(pkmn, MON_DATA_EXP, &sp0); - CalculateMonStats(pkmn); - //r10 -= sp0 - sp4; - asdf = sp0 - sp4; - //asdf = r10 - (sp0 - sp4); - r10 -= asdf; - r5 = gActiveBattler; - gActiveBattler = r7; - Emitcmd33(1, 11, r10); - gActiveBattler = r5; - gTasks[taskId].func = sub_802DCB0; - } - else - { - //u32 asdf = sp4 + r10; - sp4 += r10; - SetMonData(pkmn, MON_DATA_EXP, &sp4); - gBattleBankFunc[r7] = sub_802D90C; - DestroyTask(taskId); - } - } - } -} -#else -NAKED -void sub_802DB6C(u8 taskId) -{ - asm_unified("push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x8\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - mov r8, r0\n\ - ldr r1, _0802DB98 @ =gTasks\n\ - lsls r0, 2\n\ - add r0, r8\n\ - lsls r0, 3\n\ - adds r6, r0, r1\n\ - ldrh r1, [r6, 0x1C]\n\ - movs r2, 0x1C\n\ - ldrsh r0, [r6, r2]\n\ - cmp r0, 0xC\n\ - bgt _0802DB9C\n\ - adds r0, r1, 0x1\n\ - strh r0, [r6, 0x1C]\n\ - b _0802DC98\n\ - .align 2, 0\n\ -_0802DB98: .4byte gTasks\n\ -_0802DB9C:\n\ - ldrb r0, [r6, 0x8]\n\ - mov r9, r0\n\ - ldrh r2, [r6, 0xA]\n\ - mov r10, r2\n\ - ldrb r7, [r6, 0xC]\n\ - ldr r5, _0802DC64 @ =gHealthboxIDs\n\ - adds r5, r7, r5\n\ - ldrb r1, [r5]\n\ - adds r0, r7, 0\n\ - movs r2, 0x1\n\ - movs r3, 0\n\ - bl sub_8045C78\n\ - adds r4, r0, 0\n\ - lsls r4, 16\n\ - lsrs r4, 16\n\ - ldrb r0, [r5]\n\ - bl sub_8043DFC\n\ - lsls r4, 16\n\ - asrs r4, 16\n\ - movs r0, 0x1\n\ - negs r0, r0\n\ - cmp r4, r0\n\ - bne _0802DC98\n\ - movs r0, 0x21\n\ - bl m4aSongNumStop\n\ - movs r0, 0x64\n\ - mov r1, r9\n\ - muls r1, r0\n\ - ldr r0, _0802DC68 @ =gPlayerParty\n\ - adds r5, r1, r0\n\ - adds r0, r5, 0\n\ - movs r1, 0x38\n\ - bl GetMonData\n\ - adds r4, r0, 0\n\ - lsls r4, 24\n\ - lsrs r4, 24\n\ - adds r0, r5, 0\n\ - movs r1, 0x19\n\ - bl GetMonData\n\ - str r0, [sp, 0x4]\n\ - adds r0, r5, 0\n\ - movs r1, 0xB\n\ - bl GetMonData\n\ - lsls r0, 16\n\ - lsrs r0, 16\n\ - ldr r3, _0802DC6C @ =gExperienceTables\n\ - adds r4, 0x1\n\ - lsls r4, 2\n\ - ldr r2, _0802DC70 @ =gBaseStats\n\ - lsls r1, r0, 3\n\ - subs r1, r0\n\ - lsls r1, 2\n\ - adds r1, r2\n\ - ldrb r1, [r1, 0x13]\n\ - movs r0, 0xCA\n\ - lsls r0, 1\n\ - muls r0, r1\n\ - adds r4, r0\n\ - adds r4, r3\n\ - ldr r1, [r4]\n\ - str r1, [sp]\n\ - mov r2, r10\n\ - lsls r0, r2, 16\n\ - asrs r4, r0, 16\n\ - ldr r0, [sp, 0x4]\n\ - adds r0, r4\n\ - cmp r0, r1\n\ - blt _0802DC7C\n\ - adds r0, r5, 0\n\ - movs r1, 0x19\n\ - mov r2, sp\n\ - bl SetMonData\n\ - adds r0, r5, 0\n\ - bl CalculateMonStats\n\ - ldr r2, [sp]\n\ - add r0, sp, 0x4\n\ - ldrh r0, [r0]\n\ - subs r2, r0\n\ - subs r2, r4, r2\n\ - ldr r4, _0802DC74 @ =gActiveBattler\n\ - ldrb r5, [r4]\n\ - strb r7, [r4]\n\ - lsls r2, 16\n\ - lsrs r2, 16\n\ - movs r0, 0x1\n\ - movs r1, 0xB\n\ - bl Emitcmd33\n\ - strb r5, [r4]\n\ - ldr r0, _0802DC78 @ =sub_802DCB0\n\ - str r0, [r6]\n\ - b _0802DC98\n\ - .align 2, 0\n\ -_0802DC64: .4byte gHealthboxIDs\n\ -_0802DC68: .4byte gPlayerParty\n\ -_0802DC6C: .4byte gExperienceTables\n\ -_0802DC70: .4byte gBaseStats\n\ -_0802DC74: .4byte gActiveBattler\n\ -_0802DC78: .4byte sub_802DCB0\n\ -_0802DC7C:\n\ - str r0, [sp, 0x4]\n\ - add r2, sp, 0x4\n\ - adds r0, r5, 0\n\ - movs r1, 0x19\n\ - bl SetMonData\n\ - ldr r1, _0802DCA8 @ =gBattleBankFunc\n\ - lsls r0, r7, 2\n\ - adds r0, r1\n\ - ldr r1, _0802DCAC @ =sub_802D90C\n\ - str r1, [r0]\n\ - mov r0, r8\n\ - bl DestroyTask\n\ -_0802DC98:\n\ - add sp, 0x8\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_0802DCA8: .4byte gBattleBankFunc\n\ -_0802DCAC: .4byte sub_802D90C\n"); -} -#endif - -void sub_802DCB0(u8 taskId) -{ - u8 bank = gTasks[taskId].data[2]; - u8 pkmnIndex = gTasks[taskId].data[0]; - - if (IsDoubleBattle() == TRUE && pkmnIndex == gBattlerPartyIndexes[bank ^ 2]) - bank ^= 2; - move_anim_start_t4(bank, bank, bank, 0); - gTasks[taskId].func = sub_802DD10; -} - -void sub_802DD10(u8 taskId) -{ - u8 bank = gTasks[taskId].data[2]; - - if (!ewram17810[bank].unk0_6) - { - u8 pkmnIndex = gTasks[taskId].data[0]; - - GetMonData(&gPlayerParty[pkmnIndex], MON_DATA_LEVEL); // Unused return value - if (IsDoubleBattle() == TRUE && pkmnIndex == gBattlerPartyIndexes[bank ^ 2]) - sub_8045A5C(gHealthboxIDs[bank ^ 2], &gPlayerParty[pkmnIndex], 0); - else - sub_8045A5C(gHealthboxIDs[bank], &gPlayerParty[pkmnIndex], 0); - gTasks[taskId].func = sub_802DDC4; - } -} - -void sub_802DDC4(u8 taskId) -{ - u8 pkmnIndex; - u8 bank; - - pkmnIndex = gTasks[taskId].data[0]; - GetMonData(&gPlayerParty[pkmnIndex], MON_DATA_LEVEL); // Unused return value - bank = gTasks[taskId].data[2]; - gBattleBankFunc[bank] = sub_802D90C; - DestroyTask(taskId); -} - -void sub_802DE10(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].pos1.y + gSprites[gBankSpriteIds[gActiveBattler]].pos2.y > DISPLAY_HEIGHT) - { - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - nullsub_9(species); - FreeOamMatrix(gSprites[gBankSpriteIds[gActiveBattler]].oam.matrixNum); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - PlayerBufferExecCompleted(); - } -} - -void sub_802DEAC(void) -{ - if (!ewram17810[gActiveBattler].unk0_6) - { - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - PlayerBufferExecCompleted(); - } -} - -// Duplicate of sub_802D90C -void sub_802DF18(void) -{ - if (gUnknown_03004210.state == 0) - PlayerBufferExecCompleted(); -} - -void sub_802DF30(void) -{ - if (!gPaletteFade.active) - { - u8 r4; - - gBattleBankFunc[gActiveBattler] = sub_802DF88; - r4 = gTasks[gUnknown_0300434C[gActiveBattler]].data[0]; - DestroyTask(gUnknown_0300434C[gActiveBattler]); - sub_8094E20(r4); - } -} - -void sub_802DF88(void) -{ - if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) - { - if (gUnknown_0202E8F4 == 1) - Emitcmd34(1, gUnknown_0202E8F5, gUnknown_02038470); - else - Emitcmd34(1, 6, NULL); - if ((gBattleBufferA[gActiveBattler][1] & 0xF) == 1) - b_link_standby_message(); - PlayerBufferExecCompleted(); - } -} - -void sub_802E004(void) -{ - if (!gPaletteFade.active) - { - gBattleBankFunc[gActiveBattler] = sub_802E03C; - nullsub_14(); - sub_80A6DCC(); - } -} - -void sub_802E03C(void) -{ - if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) - { - Emitcmd35(1, gSpecialVar_ItemId); - PlayerBufferExecCompleted(); - } -} - -void bx_wait_t1(void) -{ - if (!gDoingBattleAnim || !ewram17810[gActiveBattler].unk0_6) - PlayerBufferExecCompleted(); -} - -void bx_blink_t1(void) -{ - u8 spriteId = gBankSpriteIds[gActiveBattler]; - - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = 0; - PlayerBufferExecCompleted(); - } - else - { - if (((u16)gSprites[spriteId].data[1] % 4) == 0) - gSprites[spriteId].invisible ^= 1; - gSprites[spriteId].data[1]++; - } -} - -void sub_802E12C(s32 a, const u8 *b) -{ - struct ChooseMoveStruct *r4 = (struct ChooseMoveStruct *)&gBattleBufferA[gActiveBattler][4]; - - StringCopy(gDisplayedStringBattle, b); - StringAppend(gDisplayedStringBattle, gMoveNames[r4->moves[a]]); - Text_InitWindow( - &gUnknown_03004210, - gDisplayedStringBattle, - 0x300 + a * 20, - (a & 1) ? 11 : 1, - (a < 2) ? 0x37 : 0x39); - Text_PrintWindow8002F44(&gUnknown_03004210); -} - -void sub_802E1B0(void) -{ - struct ChooseMoveStruct *r4 = (struct ChooseMoveStruct *)&gBattleBufferA[gActiveBattler][4]; - s32 i; - - gUnknown_03004348 = 0; - Text_FillWindowRect(&gUnknown_03004210, 0x1016, 1, 0x37, 0x14, 0x3A); - for (i = 0; i < 4; i++) - { - nullsub_7(i); - sub_802E12C(i, BattleText_Format); - if (r4->moves[i] != 0) - gUnknown_03004348++; - } -} - -void sub_802E220(void) -{ - if (gBattleBufferA[gActiveBattler][2] != 1) - { - struct ChooseMoveStruct *r4 = (struct ChooseMoveStruct *)&gBattleBufferA[gActiveBattler][4]; - u8 *str = gDisplayedStringBattle; - - str = StringCopy(str, BattleText_Format); - str[0] = EXT_CTRL_CODE_BEGIN; - str[1] = 0x11; - str[2] = 2; - str += 3; - str[0] = EXT_CTRL_CODE_BEGIN; - str[1] = 0x14; - str[2] = 6; - str += 3; - str = ConvertIntToDecimalStringN(str, r4->pp[gMoveSelectionCursor[gActiveBattler]], 1, 2); - *str++ = CHAR_SLASH; - ConvertIntToDecimalStringN(str, r4->unkC[gMoveSelectionCursor[gActiveBattler]], 1, 2); - Text_InitWindow(&gUnknown_03004210, gDisplayedStringBattle, 0x2A2, 0x19, 0x37); - Text_PrintWindow8002F44(&gUnknown_03004210); - } -} - -extern const u8 BattleText_ForgetMove[]; -extern const u8 gTypeNames[][7]; - -void sub_802E2D4(void) -{ - if (gBattleBufferA[gActiveBattler][2] == 1) - { - Text_FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x37, 0x1C, 0x3A); - Text_InitWindow(&gUnknown_03004210, BattleText_ForgetMove, 0x290, 0x13, 0x37); - } - else - { - struct ChooseMoveStruct *r4 = (struct ChooseMoveStruct *)&gBattleBufferA[gActiveBattler][4]; - u8 *str = gDisplayedStringBattle; - - str = StringCopy(str, BattleText_Format); - StringCopy(str, gTypeNames[gBattleMoves[r4->moves[gMoveSelectionCursor[gActiveBattler]]].type]); - Text_FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x39, 0x1C, 0x3A); - Text_InitWindow(&gUnknown_03004210, gDisplayedStringBattle, 0x2C0, 0x17, 0x39); - } - Text_PrintWindow8002F44(&gUnknown_03004210); -} - -const u8 gUnknown_081FAE89[][2] = -{ - { 8, 120}, - {88, 120}, - { 8, 136}, - {88, 136}, -}; - -const u8 gUnknown_081FAE91[][2] = -{ - {144, 120}, - {190, 120}, - {144, 136}, - {190, 136}, - { 72, 72}, - { 32, 90}, - { 80, 80}, - { 80, 88}, -}; - -void sub_802E3B4(u8 a, int unused) -{ - sub_814A958(0x48); - MenuCursor_SetPos814A880(gUnknown_081FAE89[a][0], gUnknown_081FAE89[a][1]); -} - -void nullsub_7(u8 a) -{ -} - -void sub_802E3E4(u8 a, int unused) -{ - sub_814A958(0x2A); - MenuCursor_SetPos814A880(gUnknown_081FAE91[a][0], gUnknown_081FAE91[a][1]); -} - -void nullsub_8(u8 a) -{ -} - -void sub_802E414(void) -{ - SetMainCallback2(ReshowBattleScreenAfterMenu); -} - -void sub_802E424(void) -{ - SetMainCallback2(ReshowBattleScreenAfterMenu); -} - -void sub_802E434(void) -{ - if (!ewram17810[gActiveBattler].unk0_4) - PlayerBufferExecCompleted(); -} - -void sub_802E460(void) -{ - if (!ewram17810[gActiveBattler].unk0_5) - PlayerBufferExecCompleted(); -} - -void b_link_standby_message(void) -{ - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - Text_InitWindow8002EB0(&gUnknown_03004210, BattleText_LinkStandby, 0x90, 2, 15); - } -} - -void PlayerHandleGetAttributes(void) -{ - u8 unkData[0x100]; - u32 offset = 0; - u8 r4; - s32 i; - - if (gBattleBufferA[gActiveBattler][2] == 0) - { - offset += dp01_getattr_by_ch1_for_player_pokemon_(gBattlerPartyIndexes[gActiveBattler], unkData); - } - else - { - r4 = gBattleBufferA[gActiveBattler][2]; - for (i = 0; i < 6; i++) - { - if (r4 & 1) - offset += dp01_getattr_by_ch1_for_player_pokemon_(i, unkData + offset); - r4 >>= 1; - } - } - Emitcmd29(1, offset, unkData); - PlayerBufferExecCompleted(); -} - -// Duplicate of dp01_getattr_by_ch1_for_player_pokemon -u32 dp01_getattr_by_ch1_for_player_pokemon_(u8 a, u8 *buffer) -{ - struct BattlePokemon battlePokemon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; - - switch (gBattleBufferA[gActiveBattler][1]) - { - case 0: - battlePokemon.species = GetMonData(&gPlayerParty[a], MON_DATA_SPECIES); - battlePokemon.item = GetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM); - for (size = 0; size < 4; size++) - { - battlePokemon.moves[size] = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + size); - battlePokemon.pp[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); - } - battlePokemon.ppBonuses = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); - battlePokemon.friendship = GetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP); - battlePokemon.experience = GetMonData(&gPlayerParty[a], MON_DATA_EXP); - battlePokemon.hpIV = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); - battlePokemon.attackIV = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); - battlePokemon.defenseIV = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); - battlePokemon.speedIV = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); - battlePokemon.spAttackIV = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); - battlePokemon.spDefenseIV = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); - battlePokemon.personality = GetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY); - battlePokemon.status1 = GetMonData(&gPlayerParty[a], MON_DATA_STATUS); - battlePokemon.level = GetMonData(&gPlayerParty[a], MON_DATA_LEVEL); - battlePokemon.hp = GetMonData(&gPlayerParty[a], MON_DATA_HP); - battlePokemon.maxHP = GetMonData(&gPlayerParty[a], MON_DATA_MAX_HP); - battlePokemon.attack = GetMonData(&gPlayerParty[a], MON_DATA_ATK); - battlePokemon.defense = GetMonData(&gPlayerParty[a], MON_DATA_DEF); - battlePokemon.speed = GetMonData(&gPlayerParty[a], MON_DATA_SPEED); - battlePokemon.spAttack = GetMonData(&gPlayerParty[a], MON_DATA_SPATK); - battlePokemon.spDefense = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF); - battlePokemon.isEgg = GetMonData(&gPlayerParty[a], MON_DATA_IS_EGG); - battlePokemon.altAbility = GetMonData(&gPlayerParty[a], MON_DATA_ALT_ABILITY); - battlePokemon.otId = GetMonData(&gPlayerParty[a], MON_DATA_OT_ID); - GetMonData(&gPlayerParty[a], MON_DATA_NICKNAME, nickname); - StringCopy10(battlePokemon.nickname, nickname); - GetMonData(&gPlayerParty[a], MON_DATA_OT_NAME, battlePokemon.otName); - MEMCPY_ALT(&battlePokemon, buffer, sizeof(battlePokemon), size, src); - break; - case 1: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPECIES); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 2: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 3: - for (size = 0; size < 4; size++) - { - moveData.moves[size] = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); - MEMCPY_ALT(&moveData, buffer, sizeof(moveData), size, src); - break; - case 4: - case 5: - case 6: - case 7: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 8: - for (size = 0; size < 4; size++) - buffer[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); - buffer[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); - size++; - break; - case 9: - case 10: - case 11: - case 12: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9); - size = 1; - break; - case 17: - data32 = GetMonData(&gPlayerParty[a], MON_DATA_OT_ID); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case 18: - data32 = GetMonData(&gPlayerParty[a], MON_DATA_EXP); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case 19: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_EV); - size = 1; - break; - case 20: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_EV); - size = 1; - break; - case 21: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_EV); - size = 1; - break; - case 22: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_EV); - size = 1; - break; - case 23: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_EV); - size = 1; - break; - case 24: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_EV); - size = 1; - break; - case 25: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP); - size = 1; - break; - case 26: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_POKERUS); - size = 1; - break; - case 27: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_LOCATION); - size = 1; - break; - case 28: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_LEVEL); - size = 1; - break; - case 29: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_GAME); - size = 1; - break; - case 30: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_POKEBALL); - size = 1; - break; - case 31: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); - buffer[1] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); - buffer[2] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); - buffer[3] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); - buffer[4] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); - buffer[5] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); - size = 6; - break; - case 32: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); - size = 1; - break; - case 33: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); - size = 1; - break; - case 34: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); - size = 1; - break; - case 35: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); - size = 1; - break; - case 36: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); - size = 1; - break; - case 37: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); - size = 1; - break; - case 38: - data32 = GetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - buffer[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case 39: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_CHECKSUM); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 40: - data32 = GetMonData(&gPlayerParty[a], MON_DATA_STATUS); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - buffer[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case 41: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_LEVEL); - size = 1; - break; - case 42: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_HP); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 43: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_MAX_HP); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 44: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_ATK); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 45: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_DEF); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 46: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPEED); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 47: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPATK); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 48: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 49: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_COOL); - size = 1; - break; - case 50: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_BEAUTY); - size = 1; - break; - case 51: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_CUTE); - size = 1; - break; - case 52: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SMART); - size = 1; - break; - case 53: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_TOUGH); - size = 1; - break; - case 54: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SHEEN); - size = 1; - break; - case 55: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_COOL_RIBBON); - size = 1; - break; - case 56: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case 57: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case 58: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SMART_RIBBON); - size = 1; - break; - case 59: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - return size; -} - -void PlayerHandlecmd1(void) -{ - struct BattlePokemon battleMon; - u8 i; - // TODO: Maybe fix this. Integrating this into MEMSET_ALT is too hard. - u8 *src = (u8 *)&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1]; - u8 *dst; - - MEMSET_ALT(&battleMon + gBattleBufferA[gActiveBattler][1], src[i], gBattleBufferA[gActiveBattler][2], i, dst); - Emitcmd29(1, gBattleBufferA[gActiveBattler][2], dst); - PlayerBufferExecCompleted(); -} - -void PlayerHandleSetAttributes(void) -{ - u8 r4; - u8 i; - - if (gBattleBufferA[gActiveBattler][2] == 0) - { - dp01_setattr_by_ch1_for_player_pokemon(gBattlerPartyIndexes[gActiveBattler]); - } - else - { - r4 = gBattleBufferA[gActiveBattler][2]; - for (i = 0; i < 6; i++) - { - if (r4 & 1) - dp01_setattr_by_ch1_for_player_pokemon(i); - r4 >>= 1; - } - } - PlayerBufferExecCompleted(); -} - -// Duplicate of sub_811EC68 -void dp01_setattr_by_ch1_for_player_pokemon(u8 a) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleBufferA[gActiveBattler][1]) - { - case 0: - { - u8 iv; - - SetMonData(&gPlayerParty[a], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < 4; i++) - { - SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gPlayerParty[a], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gPlayerParty[a], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gPlayerParty[a], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gPlayerParty[a], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gPlayerParty[a], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gPlayerParty[a], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gPlayerParty[a], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gPlayerParty[a], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gPlayerParty[a], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gPlayerParty[a], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case 1: - SetMonData(&gPlayerParty[a], MON_DATA_SPECIES, &gBattleBufferA[gActiveBattler][3]); - break; - case 2: - SetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]); - break; - case 3: - for (i = 0; i < 4; i++) - { - SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gPlayerParty[a], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case 4: - case 5: - case 6: - case 7: - SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4, &gBattleBufferA[gActiveBattler][3]); - break; - case 8: - SetMonData(&gPlayerParty[a], MON_DATA_PP1, &gBattleBufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[a], MON_DATA_PP2, &gBattleBufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[a], MON_DATA_PP3, &gBattleBufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[a], MON_DATA_PP4, &gBattleBufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBattler][7]); - break; - case 9: - case 10: - case 11: - case 12: - SetMonData(&gPlayerParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9, &gBattleBufferA[gActiveBattler][3]); - break; - case 17: - SetMonData(&gPlayerParty[a], MON_DATA_OT_ID, &gBattleBufferA[gActiveBattler][3]); - break; - case 18: - SetMonData(&gPlayerParty[a], MON_DATA_EXP, &gBattleBufferA[gActiveBattler][3]); - break; - case 19: - SetMonData(&gPlayerParty[a], MON_DATA_HP_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 20: - SetMonData(&gPlayerParty[a], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 21: - SetMonData(&gPlayerParty[a], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 22: - SetMonData(&gPlayerParty[a], MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 23: - SetMonData(&gPlayerParty[a], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 24: - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 25: - SetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBattler][3]); - break; - case 26: - SetMonData(&gPlayerParty[a], MON_DATA_POKERUS, &gBattleBufferA[gActiveBattler][3]); - break; - case 27: - SetMonData(&gPlayerParty[a], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBattler][3]); - break; - case 28: - SetMonData(&gPlayerParty[a], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBattler][3]); - break; - case 29: - SetMonData(&gPlayerParty[a], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBattler][3]); - break; - case 30: - SetMonData(&gPlayerParty[a], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBattler][3]); - break; - case 31: - SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][7]); - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][8]); - break; - case 32: - SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 33: - SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 34: - SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 35: - SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 36: - SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 37: - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 38: - SetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBattler][3]); - break; - case 39: - SetMonData(&gPlayerParty[a], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBattler][3]); - break; - case 40: - SetMonData(&gPlayerParty[a], MON_DATA_STATUS, &gBattleBufferA[gActiveBattler][3]); - break; - case 41: - SetMonData(&gPlayerParty[a], MON_DATA_LEVEL, &gBattleBufferA[gActiveBattler][3]); - break; - case 42: - SetMonData(&gPlayerParty[a], MON_DATA_HP, &gBattleBufferA[gActiveBattler][3]); - break; - case 43: - SetMonData(&gPlayerParty[a], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBattler][3]); - break; - case 44: - SetMonData(&gPlayerParty[a], MON_DATA_ATK, &gBattleBufferA[gActiveBattler][3]); - break; - case 45: - SetMonData(&gPlayerParty[a], MON_DATA_DEF, &gBattleBufferA[gActiveBattler][3]); - break; - case 46: - SetMonData(&gPlayerParty[a], MON_DATA_SPEED, &gBattleBufferA[gActiveBattler][3]); - break; - case 47: - SetMonData(&gPlayerParty[a], MON_DATA_SPATK, &gBattleBufferA[gActiveBattler][3]); - break; - case 48: - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF, &gBattleBufferA[gActiveBattler][3]); - break; - case 49: - SetMonData(&gPlayerParty[a], MON_DATA_COOL, &gBattleBufferA[gActiveBattler][3]); - break; - case 50: - SetMonData(&gPlayerParty[a], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBattler][3]); - break; - case 51: - SetMonData(&gPlayerParty[a], MON_DATA_CUTE, &gBattleBufferA[gActiveBattler][3]); - break; - case 52: - SetMonData(&gPlayerParty[a], MON_DATA_SMART, &gBattleBufferA[gActiveBattler][3]); - break; - case 53: - SetMonData(&gPlayerParty[a], MON_DATA_TOUGH, &gBattleBufferA[gActiveBattler][3]); - break; - case 54: - SetMonData(&gPlayerParty[a], MON_DATA_SHEEN, &gBattleBufferA[gActiveBattler][3]); - break; - case 55: - SetMonData(&gPlayerParty[a], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 56: - SetMonData(&gPlayerParty[a], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 57: - SetMonData(&gPlayerParty[a], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 58: - SetMonData(&gPlayerParty[a], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 59: - SetMonData(&gPlayerParty[a], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - } - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); -} - -void PlayerHandlecmd3(void) -{ - u8 i; - u8 *dst; - - MEMSET_ALT(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][3 + i], - gBattleBufferA[gActiveBattler][2], i, dst); - PlayerBufferExecCompleted(); -} - -void PlayerHandleLoadPokeSprite(void) -{ - BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gBattleBankFunc[gActiveBattler] = bx_0802E404; -} - -void PlayerHandleSendOutPoke(void) -{ - sub_8032AA8(gActiveBattler, gBattleBufferA[gActiveBattler][2]); - gBattlerPartyIndexes[gActiveBattler] = gBattleBufferA[gActiveBattler][1]; - BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - gActionSelectionCursor[gActiveBattler] = 0; - gMoveSelectionCursor[gActiveBattler] = 0; - sub_802F934(gActiveBattler, gBattleBufferA[gActiveBattler][2]); - gBattleBankFunc[gActiveBattler] = sub_802D798; -} - -void sub_802F934(u8 bank, u8 b) -{ - u16 species; - - sub_8032AA8(bank, b); - gBattlerPartyIndexes[bank] = gBattleBufferA[bank][1]; - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES); - gUnknown_0300434C[bank] = CreateInvisibleSpriteWithCallback(sub_80312F0); - GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(bank)); - gBankSpriteIds[bank] = CreateSprite( - &gUnknown_02024E8C, - GetBattlerSpriteCoord(bank, 2), - sub_8077F68(bank), - GetBattlerSubpriority(bank)); - gSprites[gUnknown_0300434C[bank]].data[1] = gBankSpriteIds[bank]; - gSprites[gBankSpriteIds[bank]].data[0] = bank; - gSprites[gBankSpriteIds[bank]].data[2] = species; - gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; - StartSpriteAnim(&gSprites[gBankSpriteIds[bank]], gBattleMonForms[bank]); - gSprites[gBankSpriteIds[bank]].invisible = TRUE; - gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; - gSprites[gUnknown_0300434C[bank]].data[0] = StartSendOutMonAnimation(0, 0xFF); -} - -void PlayerHandleReturnPokeToBall(void) -{ - if (gBattleBufferA[gActiveBattler][1] == 0) - { - ewram17810[gActiveBattler].unk4 = 0; - gBattleBankFunc[gActiveBattler] = sub_802FB2C; - } - else - { - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - PlayerBufferExecCompleted(); - } -} - -void sub_802FB2C(void) -{ - switch (ewram17810[gActiveBattler].unk4) - { - case 0: - if (ewram17800[gActiveBattler].substituteSprite) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - ewram17810[gActiveBattler].unk4 = 1; - break; - case 1: - if (!ewram17810[gActiveBattler].unk0_6) - { - ewram17810[gActiveBattler].unk4 = 0; - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 1); - gBattleBankFunc[gActiveBattler] = sub_802DEAC; - } - } -} - -void PlayerHandleTrainerThrow(void) -{ - s16 r7; - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (GetBattlerPosition(gActiveBattler) & 2) - r7 = 16; - else - r7 = -16; - } - else - { - r7 = 0; - } - LoadPlayerTrainerBankSprite(gSaveBlock2.playerGender, gActiveBattler); - GetMonSpriteTemplate_803C5A0(gSaveBlock2.playerGender, GetBattlerPosition(gActiveBattler)); - gBankSpriteIds[gActiveBattler] = CreateSprite( - &gUnknown_02024E8C, - r7 + 80, - (8 - gTrainerBackPicCoords[gSaveBlock2.playerGender].coords) * 4 + 80, - GetBattlerSubpriority(gActiveBattler)); - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = 240; - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = -2; - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; - gBattleBankFunc[gActiveBattler] = sub_802D204; -} - -void PlayerHandleTrainerSlide(void) -{ - LoadPlayerTrainerBankSprite(gSaveBlock2.playerGender, gActiveBattler); - GetMonSpriteTemplate_803C5A0(gSaveBlock2.playerGender, GetBattlerPosition(gActiveBattler)); - gBankSpriteIds[gActiveBattler] = CreateSprite( - &gUnknown_02024E8C, - 80, - (8 - gTrainerBackPicCoords[gSaveBlock2.playerGender].coords) * 4 + 80, - 30); - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -96; - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 2; - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; - gBattleBankFunc[gActiveBattler] = sub_802D23C; -} - -void PlayerHandleTrainerSlideBack(void) -{ - oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 50; - gSprites[gBankSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; - gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], SpriteCallbackDummy); - StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 1); - gBattleBankFunc[gActiveBattler] = sub_802D274; -} - -void PlayerHandlecmd10(void) -{ - if (ewram17810[gActiveBattler].unk4 == 0) - { - if (ewram17800[gActiveBattler].substituteSprite) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - ewram17810[gActiveBattler].unk4++; - } - else - { - if (ewram17810[gActiveBattler].unk0_6 == 0) - { - ewram17810[gActiveBattler].unk4 = 0; - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - PlaySE12WithPanning(SE_POKE_DEAD, -64); - gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; - gSprites[gBankSpriteIds[gActiveBattler]].data[2] = 5; - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80105EC; - gBattleBankFunc[gActiveBattler] = sub_802DE10; - } - } -} - -void PlayerHandlecmd11(void) -{ - BeginNormalPaletteFade(0xFFFFFFFF, 2, 0, 16, RGB(0, 0, 0)); - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd12(void) -{ - ewram17840.unk8 = 4; - gDoingBattleAnim = 1; - move_anim_start_t4(gActiveBattler, gActiveBattler, GetBattlerAtPosition(1), 3); - gBattleBankFunc[gActiveBattler] = bx_wait_t1; -} - -void PlayerHandleBallThrow(void) -{ - u8 var = gBattleBufferA[gActiveBattler][1]; - - ewram17840.unk8 = var; - gDoingBattleAnim = 1; - move_anim_start_t4(gActiveBattler, gActiveBattler, GetBattlerAtPosition(1), 3); - gBattleBankFunc[gActiveBattler] = bx_wait_t1; -} - -void PlayerHandlePuase(void) -{ - u8 var = gBattleBufferA[gActiveBattler][1]; - - // WTF is this?? - while (var != 0) - var--; - - PlayerBufferExecCompleted(); -} - -void PlayerHandleMoveAnimation(void) -{ - if (!mplay_80342A4(gActiveBattler)) - { - u16 r0 = gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleBufferA[gActiveBattler][3]; - gAnimMovePower = gBattleBufferA[gActiveBattler][4] | (gBattleBufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleBufferA[gActiveBattler][6] | (gBattleBufferA[gActiveBattler][7] << 8) | (gBattleBufferA[gActiveBattler][8] << 16) | (gBattleBufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleBufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleBufferA[gActiveBattler][12] | (gBattleBufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - if (sub_8031720(r0, gAnimMoveTurn) != 0) - { - // Dead code. sub_8031720 always returns 0. - PlayerBufferExecCompleted(); - } - else - { - ewram17810[gActiveBattler].unk4 = 0; - gBattleBankFunc[gActiveBattler] = sub_8030190; - } - } -} - -void sub_8030190(void) -{ - u16 r4 = gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8); - u8 r7 = gBattleBufferA[gActiveBattler][11]; - - switch (ewram17810[gActiveBattler].unk4) - { - case 0: - if (ewram17800[gActiveBattler].substituteSprite == 1 && ewram17800[gActiveBattler].unk0_3 == 0) - { - ewram17800[gActiveBattler].unk0_3 = 1; - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - } - ewram17810[gActiveBattler].unk4 = 1; - break; - case 1: - if (ewram17810[gActiveBattler].unk0_6 == 0) - { - sub_80326EC(0); - DoMoveAnim(r4); - ewram17810[gActiveBattler].unk4 = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - sub_80326EC(1); - if (ewram17800[gActiveBattler].substituteSprite == 1 && r7 < 2) - { - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); - ewram17800[gActiveBattler].unk0_3 = 0; - } - ewram17810[gActiveBattler].unk4 = 3; - } - break; - case 3: - if (ewram17810[gActiveBattler].unk0_6 == 0) - { - sub_8031F24(); - sub_80324BC(gActiveBattler, gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - ewram17810[gActiveBattler].unk4 = 0; - PlayerBufferExecCompleted(); - } - break; - } -} - -void PlayerHandlePrintString(void) -{ - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - BufferStringBattle(*(u16 *)&gBattleBufferA[gActiveBattler][2]); - Text_InitWindow8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 0x90, 2, 15); - gBattleBankFunc[gActiveBattler] = sub_802DF18; -} - -void PlayerHandlePrintStringPlayerOnly(void) -{ - if (GetBattlerSide(gActiveBattler) == 0) - PlayerHandlePrintString(); - else - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd18(void) -{ - int r4; - - gBattle_BG0_X = 0; - gBattle_BG0_Y = 160; - Text_FillWindowRect(&gUnknown_03004210, 10, 2, 15, 27, 18); - Text_FillWindowRect(&gUnknown_03004210, 10, 2, 35, 16, 38); - - gBattleBankFunc[gActiveBattler] = sub_802C098; - - Text_InitWindow(&gUnknown_03004210, BattleText_MenuOptions, 400, 18, 35); - Text_PrintWindow8002F44(&gUnknown_03004210); - MenuCursor_Create814A5C0(0, 0xFFFF, 12, 11679, 0); - - for (r4 = 0; r4 < 4; r4++) - nullsub_8(r4); - - sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); - - StrCpyDecodeToDisplayedStringBattle(BattleText_OtherMenu); - Text_InitWindow(&gUnknown_03004210, gDisplayedStringBattle, SUB_803037C_TILE_DATA_OFFSET, 2, 35); - Text_PrintWindow8002F44(&gUnknown_03004210); -} - -void PlayerHandlecmd19() -{ -} - -void PlayerHandlecmd20(void) -{ - MenuCursor_Create814A5C0(0, 0xFFFF, 12, 0x2D9F, 0); - sub_80304A8(); - gBattleBankFunc[gActiveBattler] = sub_802C68C; -} - -void sub_80304A8(void) -{ - gBattle_BG0_X = 0; - gBattle_BG0_Y = 320; - sub_802E1B0(); - gUnknown_03004344 = 0xFF; - sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); - if (gBattleBufferA[gActiveBattler][2] != 1) - { - Text_InitWindow(&gUnknown_03004210, BattleText_PP, 656, 23, 55); - Text_PrintWindow8002F44(&gUnknown_03004210); - } - sub_802E220(); - sub_802E2D4(); -} - -void PlayerHandleOpenBag(void) -{ - s32 i; - - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); - gBattleBankFunc[gActiveBattler] = sub_802E004; - gBankInMenu = gActiveBattler; - for (i = 0; i < 3; i++) - gUnknown_02038470[i] = gBattleBufferA[gActiveBattler][1 + i]; -} - -void PlayerHandlecmd22(void) -{ - s32 i; - - gUnknown_0300434C[gActiveBattler] = CreateTask(TaskDummy, 0xFF); - gTasks[gUnknown_0300434C[gActiveBattler]].data[0] = gBattleBufferA[gActiveBattler][1] & 0xF; - ewram16054 = gBattleBufferA[gActiveBattler][1] >> 4; - EWRAM_1609D = gBattleBufferA[gActiveBattler][2]; - ewram160C0 = gBattleBufferA[gActiveBattler][3]; - for (i = 0; i < 3; i++) - gUnknown_02038470[i] = gBattleBufferA[gActiveBattler][4 + i]; - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); - gBattleBankFunc[gActiveBattler] = sub_802DF30; - gBankInMenu = gActiveBattler; -} - -void PlayerHandlecmd23(void) -{ - BattleStopLowHpSound(); - BeginNormalPaletteFade(0xFFFFFFFF, 2, 0, 16, RGB(0, 0, 0)); - PlayerBufferExecCompleted(); -} - -void PlayerHandleHealthBarUpdate(void) -{ - s16 r7; - - load_gfxc_health_bar(0); - r7 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); - if (r7 != 0x7FFF) - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - u32 curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); - - sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, curHP, r7); - } - else - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - - sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, 0, r7); - sub_80440EC(gHealthboxIDs[gActiveBattler], 0, 0); - } - gBattleBankFunc[gActiveBattler] = bx_t1_healthbar_update; -} - -void PlayerHandleExpBarUpdate(void) -{ - u8 r7 = gBattleBufferA[gActiveBattler][1]; - - if (GetMonData(&gPlayerParty[r7], MON_DATA_LEVEL) >= 100) - { - PlayerBufferExecCompleted(); - } - else - { - u16 r4; - u8 taskId; - - load_gfxc_health_bar(1); - GetMonData(&gPlayerParty[r7], MON_DATA_SPECIES); // unused return value - r4 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); - taskId = CreateTask(sub_802D924, 10); - gTasks[taskId].data[0] = r7; - gTasks[taskId].data[1] = r4; - gTasks[taskId].data[2] = gActiveBattler; - gBattleBankFunc[gActiveBattler] = nullsub_91; - } -} - -void PlayerHandleStatusIconUpdate(void) -{ - if (!mplay_80342A4(gActiveBattler)) - { - sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 9); - ewram17810[gActiveBattler].unk0_4 = 0; - gBattleBankFunc[gActiveBattler] = sub_802E434; - } -} - -void PlayerHandleStatusAnimation(void) -{ - if (!mplay_80342A4(gActiveBattler)) - { - move_anim_start_t2_for_situation( - gBattleBufferA[gActiveBattler][1], - gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8) | (gBattleBufferA[gActiveBattler][4] << 16) | (gBattleBufferA[gActiveBattler][5] << 24)); - gBattleBankFunc[gActiveBattler] = sub_802E434; - } -} - -void PlayerHandleStatusXor(void) -{ - u8 val = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_STATUS) ^ gBattleBufferA[gActiveBattler][1]; - - SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_STATUS, &val); - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd29(void) -{ - PlayerBufferExecCompleted(); -} - -void PlayerHandleDMATransfer(void) -{ - u32 val1 = gBattleBufferA[gActiveBattler][1] - | (gBattleBufferA[gActiveBattler][2] << 8) - | (gBattleBufferA[gActiveBattler][3] << 16) - | (gBattleBufferA[gActiveBattler][4] << 24); - u16 val2 = gBattleBufferA[gActiveBattler][5] | (gBattleBufferA[gActiveBattler][6] << 8); - - Dma3CopyLarge16_(&gBattleBufferA[gActiveBattler][7], (u8 *)val1, val2); - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd31(void) -{ - PlayBGM(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd32(void) -{ - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd33(void) -{ - Emitcmd33(1, 0, 0); - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd34(void) -{ - Emitcmd34(1, 0, 0); - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd35(void) -{ - Emitcmd35(1, 0); - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd36(void) -{ - Emitcmd36(1, 0); - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd37(void) -{ - gUnknown_020238C8.unk0_0 = 0; - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd38(void) -{ - gUnknown_020238C8.unk0_0 = gBattleBufferA[gActiveBattler][1]; - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd39(void) -{ - gUnknown_020238C8.unk0_7 = 0; - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd40(void) -{ - gUnknown_020238C8.unk0_7 ^= 1; - PlayerBufferExecCompleted(); -} - -void PlayerHandleHitAnimation(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].invisible == TRUE) - { - PlayerBufferExecCompleted(); - } - else - { - gDoingBattleAnim = 1; - gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; - sub_8047858(gActiveBattler); - gBattleBankFunc[gActiveBattler] = bx_blink_t1; - } -} - -void PlayerHandlecmd42(void) -{ - PlayerBufferExecCompleted(); -} - -void PlayerHandleEffectivenessSound(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == 0) - pan = -64; - else - pan = 63; - PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan); - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd44(void) -{ - PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - PlayerBufferExecCompleted(); -} - -void PlayerHandleFaintingCry(void) -{ - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - PlayCry3(species, -25, 5); - PlayerBufferExecCompleted(); -} - -void PlayerHandleIntroSlide(void) -{ - StartBattleIntroAnim(gBattleBufferA[gActiveBattler][1]); - gUnknown_02024DE8 |= 1; - PlayerBufferExecCompleted(); -} - -void PlayerHandleTrainerBallThrow(void) -{ - u8 paletteNum; - u8 taskId; - - oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 50; - gSprites[gBankSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; - gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - gSprites[gBankSpriteIds[gActiveBattler]].data[5] = gActiveBattler; - StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], sub_8030E38); - StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 1); - paletteNum = AllocSpritePalette(0xD6F8); - LoadCompressedPalette(gTrainerBackPicPaletteTable[gSaveBlock2.playerGender].data, 0x100 + paletteNum * 16, 32); - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = paletteNum; - taskId = CreateTask(task05_08033660, 5); - gTasks[taskId].data[0] = gActiveBattler; - if (ewram17810[gActiveBattler].unk0_0) - gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; - ewram17810[4].unk9 |= 1; - gBattleBankFunc[gActiveBattler] = nullsub_91; -} - -void sub_8030E38(struct Sprite *sprite) -{ - u8 r4 = sprite->data[5]; - - FreeSpriteOamMatrix(sprite); - FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum)); - DestroySprite(sprite); - BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[r4]], r4); - StartSpriteAnim(&gSprites[gBankSpriteIds[r4]], 0); -} - -void task05_08033660(u8 taskId) -{ - if (gTasks[taskId].data[1] < 31) - { - gTasks[taskId].data[1]++; - } - else - { - u8 savedActiveBank = gActiveBattler; - - gActiveBattler = gTasks[taskId].data[0]; - if (!IsDoubleBattle() || (gBattleTypeFlags & 0x40)) - { - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - sub_802F934(gActiveBattler, 0); - } - else - { - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - sub_802F934(gActiveBattler, 0); - gActiveBattler ^= 2; - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - sub_802F934(gActiveBattler, 0); - gActiveBattler ^= 2; - } - gBattleBankFunc[gActiveBattler] = sub_802D500; - gActiveBattler = savedActiveBank; - DestroyTask(taskId); - } -} - -void PlayerHandlecmd48(void) -{ - if (gBattleBufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == 0) - { - PlayerBufferExecCompleted(); - } - else - { - ewram17810[gActiveBattler].unk0_0 = 1; - gUnknown_02024E68[gActiveBattler] = sub_8044804(gActiveBattler, (struct BattleInterfaceStruct2 *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); - ewram17810[gActiveBattler].unk5 = 0; - if (gBattleBufferA[gActiveBattler][2] != 0) - ewram17810[gActiveBattler].unk5 = 0x5D; - gBattleBankFunc[gActiveBattler] = sub_8031064; - } -} - -void sub_8031064(void) -{ - if (ewram17810[gActiveBattler].unk5++ > 0x5C) - { - ewram17810[gActiveBattler].unk5 = 0; - PlayerBufferExecCompleted(); - } -} - -void PlayerHandlecmd49(void) -{ - if (ewram17810[gActiveBattler].unk0_0) - gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd50(void) -{ - dp11b_obj_free(gActiveBattler, 1); - dp11b_obj_free(gActiveBattler, 0); - PlayerBufferExecCompleted(); -} - -void PlayerHandleSpriteInvisibility(void) -{ - if (IsBankSpritePresent(gActiveBattler)) - { - gSprites[gBankSpriteIds[gActiveBattler]].invisible = gBattleBufferA[gActiveBattler][1]; - sub_8031F88(gActiveBattler); - } - PlayerBufferExecCompleted(); -} - -void PlayerHandleBattleAnimation(void) -{ - if (!mplay_80342A4(gActiveBattler)) - { - u8 val2 = gBattleBufferA[gActiveBattler][1]; - u16 val = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); - - if (move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, val2, val)) - PlayerBufferExecCompleted(); - else - gBattleBankFunc[gActiveBattler] = sub_802E460; - } -} - -void PlayerHandleLinkStandbyMsg(void) -{ - switch (gBattleBufferA[gActiveBattler][1]) - { - case 0: - b_link_standby_message(); - // fall through - case 1: - dp11b_obj_free(gActiveBattler, 1); - dp11b_obj_free(gActiveBattler, 0); - break; - case 2: - b_link_standby_message(); - break; - } - PlayerBufferExecCompleted(); -} - -void PlayerHandleResetActionMoveSelection(void) -{ - switch (gBattleBufferA[gActiveBattler][1]) - { - case 0: - gActionSelectionCursor[gActiveBattler] = 0; - gMoveSelectionCursor[gActiveBattler] = 0; - break; - case 1: - gActionSelectionCursor[gActiveBattler] = 0; - break; - case 2: - gMoveSelectionCursor[gActiveBattler] = 0; - break; - } - PlayerBufferExecCompleted(); -} - -void PlayerHandlecmd55(void) -{ - gBattleOutcome = gBattleBufferA[gActiveBattler][1]; - FadeOutMapMusic(5); - BeginFastPaletteFade(3); - PlayerBufferExecCompleted(); - gBattleBankFunc[gActiveBattler] = sub_802D18C; -} - -void PlayerHandlecmd56(void) -{ -} diff --git a/src/battle/battle_controller_safari.c b/src/battle/battle_controller_safari.c deleted file mode 100644 index e547c4a3c..000000000 --- a/src/battle/battle_controller_safari.c +++ /dev/null @@ -1,720 +0,0 @@ -#include "global.h" -#include "battle_anim_81258BC.h" -#include "battle.h" -#include "battle_interface.h" -#include "battle_message.h" -#include "data2.h" -#include "link.h" -#include "main.h" -#include "menu_cursor.h" -#include "palette.h" -#include "rom3.h" -#include "constants/songs.h" -#include "sound.h" -#include "text.h" -#include "util.h" -#include "ewram.h" - -extern struct Window gUnknown_03004210; -extern u8 gDisplayedStringBattle[]; -extern u8 gActionSelectionCursor[]; - -extern const u8 BattleText_PlayerMenu[]; -extern u8 gActiveBattler; -extern const u8 BattleText_MenuOptionsSafari[]; - -extern void *gBattleBankFunc[]; -extern u8 gBattleBufferA[][0x200]; -extern bool8 gDoingBattleAnim; -extern u8 gBankSpriteIds[]; -extern struct SpriteTemplate gUnknown_02024E8C; -extern u16 gBattleTypeFlags; -extern u32 gBattleExecBuffer; -extern u16 gSpecialVar_ItemId; -extern MainCallback gPreBattleCallback1; -extern u8 gBankInMenu; -extern u8 gHealthboxIDs[]; -extern u16 gBattlerPartyIndexes[]; -extern u16 gUnknown_02024DE8; -extern u8 gBattleOutcome; - -extern u8 GetBattlerSide(u8); -extern u8 GetBattlerAtPosition(u8); -extern u8 GetBattlerPosition(u8); -extern void LoadPlayerTrainerBankSprite(); -extern u8 GetBattlerSubpriority(); -extern void sub_80313A0(struct Sprite *); -extern void sub_810BADC(void); -extern void sub_8045A5C(); -extern void StartBattleIntroAnim(); -extern void sub_804777C(); -extern void sub_8043DFC(); -extern bool8 move_anim_start_t3(); - -#if ENGLISH -#define SUB_812BB10_TILE_DATA_OFFSET 440 -#elif GERMAN -#define SUB_812BB10_TILE_DATA_OFFSET 444 -#endif - -// this file's functions -void SafariHandleGetAttributes(void); -void SafariHandlecmd1(void); -void SafariHandleSetAttributes(void); -void SafariHandlecmd3(void); -void SafariHandleLoadPokeSprite(void); -void SafariHandleSendOutPoke(void); -void SafariHandleReturnPokeToBall(void); -void SafariHandleTrainerThrow(void); -void SafariHandleTrainerSlide(void); -void SafariHandleTrainerSlideBack(void); -void SafariHandlecmd10(void); -void SafariHandlecmd11(void); -void SafariHandlecmd12(void); -void SafariHandleBallThrow(void); -void SafariHandlePuase(void); -void SafariHandleMoveAnimation(void); -void SafariHandlePrintString(void); -void SafariHandlePrintStringPlayerOnly(void); -void SafariHandlecmd18(void); -void SafariHandlecmd19(void); -void SafariHandlecmd20(void); -void SafariHandleOpenBag(void); -void SafariHandlecmd22(void); -void SafariHandlecmd23(void); -void SafariHandleHealthBarUpdate(void); -void SafariHandleExpBarUpdate(void); -void SafariHandleStatusIconUpdate(void); -void SafariHandleStatusAnimation(void); -void SafariHandleStatusXor(void); -void SafariHandlecmd29(void); -void SafariHandleDMATransfer(void); -void SafariHandlecmd31(void); -void SafariHandlecmd32(void); -void SafariHandlecmd33(void); -void SafariHandlecmd34(void); -void SafariHandlecmd35(void); -void SafariHandlecmd36(void); -void SafariHandlecmd37(void); -void SafariHandlecmd38(void); -void SafariHandlecmd39(void); -void SafariHandlecmd40(void); -void SafariHandleHitAnimation(void); -void SafariHandlecmd42(void); -void SafariHandleEffectivenessSound(void); -void SafariHandlecmd44(void); -void SafariHandleFaintingCry(void); -void SafariHandleIntroSlide(void); -void SafariHandleTrainerBallThrow(void); -void SafariHandlecmd48(void); -void SafariHandlecmd49(void); -void SafariHandlecmd50(void); -void SafariHandleSpriteInvisibility(void); -void SafariHandleBattleAnimation(void); -void SafariHandleLinkStandbyMsg(void); -void SafariHandleResetActionMoveSelection(void); -void SafariHandlecmd55(void); -void SafariHandlecmd56(void); - -// const data -typedef void (*BattleBufferCmd) (void); -const BattleBufferCmd gSafariBufferCommands[] = -{ - SafariHandleGetAttributes, - SafariHandlecmd1, - SafariHandleSetAttributes, - SafariHandlecmd3, - SafariHandleLoadPokeSprite, - SafariHandleSendOutPoke, - SafariHandleReturnPokeToBall, - SafariHandleTrainerThrow, - SafariHandleTrainerSlide, - SafariHandleTrainerSlideBack, - SafariHandlecmd10, - SafariHandlecmd11, - SafariHandlecmd12, - SafariHandleBallThrow, - SafariHandlePuase, - SafariHandleMoveAnimation, - SafariHandlePrintString, - SafariHandlePrintStringPlayerOnly, - SafariHandlecmd18, - SafariHandlecmd19, - SafariHandlecmd20, - SafariHandleOpenBag, - SafariHandlecmd22, - SafariHandlecmd23, - SafariHandleHealthBarUpdate, - SafariHandleExpBarUpdate, - SafariHandleStatusIconUpdate, - SafariHandleStatusAnimation, - SafariHandleStatusXor, - SafariHandlecmd29, - SafariHandleDMATransfer, - SafariHandlecmd31, - SafariHandlecmd32, - SafariHandlecmd33, - SafariHandlecmd34, - SafariHandlecmd35, - SafariHandlecmd36, - SafariHandlecmd37, - SafariHandlecmd38, - SafariHandlecmd39, - SafariHandlecmd40, - SafariHandleHitAnimation, - SafariHandlecmd42, - SafariHandleEffectivenessSound, - SafariHandlecmd44, - SafariHandleFaintingCry, - SafariHandleIntroSlide, - SafariHandleTrainerBallThrow, - SafariHandlecmd48, - SafariHandlecmd49, - SafariHandlecmd50, - SafariHandleSpriteInvisibility, - SafariHandleBattleAnimation, - SafariHandleLinkStandbyMsg, - SafariHandleResetActionMoveSelection, - SafariHandlecmd55, - SafariHandlecmd56, -}; -// code - -void SafariBufferExecCompleted(void); -void bx_wait_t6(void); -void sub_812B65C(void); -void SafariBufferRunCommand(void); -void sub_812B758(void); - -void unref_sub_812B464(void) -{ -} - -void SetBankFuncToSafariBufferRunCommand(void) -{ - gBattleBankFunc[gActiveBattler] = SafariBufferRunCommand; -} - -void SafariBufferRunCommand(void) -{ - if (gBattleExecBuffer & gBitTable[gActiveBattler]) - { - if (gBattleBufferA[gActiveBattler][0] < 0x39) - gSafariBufferCommands[gBattleBufferA[gActiveBattler][0]](); - else - SafariBufferExecCompleted(); - } -} - -void bx_battle_menu_t6_2(void) -{ - if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - DestroyMenuCursor(); - - // Useless switch statement. - switch (gActionSelectionCursor[gActiveBattler]) - { - case 0: - Emitcmd33(1, 5, 0); - break; - case 1: - Emitcmd33(1, 6, 0); - break; - case 2: - Emitcmd33(1, 7, 0); - break; - case 3: - Emitcmd33(1, 8, 0); - break; - } - SafariBufferExecCompleted(); - } - else if (gMain.newKeys & DPAD_LEFT) - { - if (gActionSelectionCursor[gActiveBattler] & 1) - { - PlaySE(SE_SELECT); - nullsub_8(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 1; - sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); - } - } - else if (gMain.newKeys & DPAD_RIGHT) - { - if (!(gActionSelectionCursor[gActiveBattler] & 1)) - { - PlaySE(SE_SELECT); - nullsub_8(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 1; - sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); - } - } - else if (gMain.newKeys & DPAD_UP) - { - if (gActionSelectionCursor[gActiveBattler] & 2) - { - PlaySE(SE_SELECT); - nullsub_8(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 2; - sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); - } - } - else if (gMain.newKeys & DPAD_DOWN) - { - if (!(gActionSelectionCursor[gActiveBattler] & 2)) - { - PlaySE(SE_SELECT); - nullsub_8(gActionSelectionCursor[gActiveBattler]); - gActionSelectionCursor[gActiveBattler] ^= 2; - sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); - } - } -#if DEBUG - else if (gMain.newKeys & R_BUTTON) - { - if (!ewram17810[gActiveBattler].unk0_5) - move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, 4, 0); - } - else if (gMain.newKeys & START_BUTTON) - { - sub_804454C(); - } -#endif -} - -void sub_812B65C(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - SafariBufferExecCompleted(); -} - -void sub_812B694(void) -{ - if (gUnknown_03004210.state == 0) - SafariBufferExecCompleted(); -} - -void sub_812B6AC(void) -{ - if (!gPaletteFade.active) - { - gMain.inBattle = FALSE; - gMain.callback1 = gPreBattleCallback1; - SetMainCallback2(gMain.savedCallback); - } -} - -void bx_wait_t6(void) -{ - if (!gDoingBattleAnim || !ewram17810[gActiveBattler].unk0_6) - SafariBufferExecCompleted(); -} - -void sub_812B724(void) -{ - if (!gPaletteFade.active) - { - gBattleBankFunc[gActiveBattler] = sub_812B758; - sub_810BADC(); - } -} - -void sub_812B758(void) -{ - if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) - { - Emitcmd35(1, gSpecialVar_ItemId); - SafariBufferExecCompleted(); - } -} - -void sub_812B794(void) -{ - if (!ewram17810[gActiveBattler].unk0_5) - SafariBufferExecCompleted(); -} - -void SafariBufferExecCompleted(void) -{ - gBattleBankFunc[gActiveBattler] = SafariBufferRunCommand; - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - u8 playerId = GetMultiplayerId(); - - PrepareBufferDataTransferLink(2, 4, &playerId); - gBattleBufferA[gActiveBattler][0] = 0x38; - } - else - { - gBattleExecBuffer &= ~gBitTable[gActiveBattler]; - } -} - -void unref_sub_812B838(void) -{ - if (!ewram17810[gActiveBattler].unk0_4) - SafariBufferExecCompleted(); -} - -void SafariHandleGetAttributes(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd1(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleSetAttributes(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd3(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleLoadPokeSprite(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleSendOutPoke(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleReturnPokeToBall(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleTrainerThrow(void) -{ - LoadPlayerTrainerBankSprite(gSaveBlock2.playerGender, gActiveBattler); - GetMonSpriteTemplate_803C5A0(gSaveBlock2.playerGender, GetBattlerPosition(gActiveBattler)); - gBankSpriteIds[gActiveBattler] = CreateSprite( - &gUnknown_02024E8C, - 80, - (8 - gTrainerBackPicCoords[gSaveBlock2.playerGender].coords) * 4 + 80, - 30); - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = 240; - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = -2; - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; - gBattleBankFunc[gActiveBattler] = sub_812B65C; -} - -void SafariHandleTrainerSlide(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleTrainerSlideBack(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd10(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd11(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd12(void) -{ - ewram17840.unk8 = 4; - gDoingBattleAnim = 1; - move_anim_start_t4(gActiveBattler, gActiveBattler, GetBattlerAtPosition(1), 4); - gBattleBankFunc[gActiveBattler] = bx_wait_t6; -} - -void SafariHandleBallThrow(void) -{ - u8 var = gBattleBufferA[gActiveBattler][1]; - - ewram17840.unk8 = var; - gDoingBattleAnim = 1; - move_anim_start_t4(gActiveBattler, gActiveBattler, GetBattlerAtPosition(1), 4); - gBattleBankFunc[gActiveBattler] = bx_wait_t6; -} - -// TODO: spell Pause correctly -void SafariHandlePuase(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleMoveAnimation(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlePrintString(void) -{ - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - BufferStringBattle(*(u16 *)&gBattleBufferA[gActiveBattler][2]); - Text_InitWindow8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15); - gBattleBankFunc[gActiveBattler] = sub_812B694; -} - -void SafariHandlePrintStringPlayerOnly(void) -{ - if (GetBattlerSide(gActiveBattler) == 0) - SafariHandlePrintString(); - else - SafariBufferExecCompleted(); -} - -void SafariHandlecmd18(void) -{ - int i; - - gBattle_BG0_X = 0; - gBattle_BG0_Y = 160; - gUnknown_03004210.paletteNum = 0; - Text_FillWindowRectDefPalette(&gUnknown_03004210, 10, 2, 15, 27, 18); - Text_FillWindowRectDefPalette(&gUnknown_03004210, 10, 2, 35, 16, 36); - gBattleBankFunc[gActiveBattler] = bx_battle_menu_t6_2; - - Text_InitWindow(&gUnknown_03004210, BattleText_MenuOptionsSafari, 400, 18, 35); - Text_PrintWindow8002F44(&gUnknown_03004210); - MenuCursor_Create814A5C0(0, 0xFFFF, 12, 11679, 0); - - for (i = 0; i < 4; i++) - nullsub_8(i); - - sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); - StrCpyDecodeToDisplayedStringBattle(BattleText_PlayerMenu); - - Text_InitWindow(&gUnknown_03004210, gDisplayedStringBattle, SUB_812BB10_TILE_DATA_OFFSET, 2, 35); - Text_PrintWindow8002F44(&gUnknown_03004210); -} - -void SafariHandlecmd19(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd20(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleOpenBag(void) -{ - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); - gBattleBankFunc[gActiveBattler] = sub_812B724; - gBankInMenu = gActiveBattler; -} - -void SafariHandlecmd22(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd23(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleHealthBarUpdate(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleExpBarUpdate(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleStatusIconUpdate(void) -{ - sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 11); - SafariBufferExecCompleted(); -} - -void SafariHandleStatusAnimation(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleStatusXor(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd29(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleDMATransfer(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd31(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd32(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd33(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd34(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd35(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd36(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd37(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd38(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd39(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd40(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleHitAnimation(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd42(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleEffectivenessSound(void) -{ - s8 pan; - - if (GetBattlerSide(gActiveBattler) == 0) - pan = -64; - else - pan = 63; - PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan); - SafariBufferExecCompleted(); -} - -void SafariHandlecmd44(void) -{ - PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - SafariBufferExecCompleted(); -} - -void SafariHandleFaintingCry(void) -{ - u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); - - PlayCry1(species, 25); - SafariBufferExecCompleted(); -} - -void SafariHandleIntroSlide(void) -{ - StartBattleIntroAnim(gBattleBufferA[gActiveBattler][1]); - gUnknown_02024DE8 |= 1; - SafariBufferExecCompleted(); -} - -void SafariHandleTrainerBallThrow(void) -{ - sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 10); - sub_804777C(gActiveBattler); - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - SafariBufferExecCompleted(); -} - -void SafariHandlecmd48(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd49(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd50(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleSpriteInvisibility(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleBattleAnimation(void) -{ - u8 r3 = gBattleBufferA[gActiveBattler][1]; - u16 r4 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); - - if (move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, r3, r4) != 0) - SafariBufferExecCompleted(); - else - gBattleBankFunc[gActiveBattler] = sub_812B794; -} - -void SafariHandleLinkStandbyMsg(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandleResetActionMoveSelection(void) -{ - SafariBufferExecCompleted(); -} - -void SafariHandlecmd55(void) -{ - gBattleOutcome = gBattleBufferA[gActiveBattler][1]; - FadeOutMapMusic(5); - BeginFastPaletteFade(3); - SafariBufferExecCompleted(); - if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && !(gBattleTypeFlags & BATTLE_TYPE_WILD)) - gBattleBankFunc[gActiveBattler] = sub_812B6AC; -} - -void SafariHandlecmd56(void) -{ -} diff --git a/src/battle/battle_controller_wally.c b/src/battle/battle_controller_wally.c deleted file mode 100644 index fa8b2a63b..000000000 --- a/src/battle/battle_controller_wally.c +++ /dev/null @@ -1,1605 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_anim.h" -#include "battle_anim_813F0F4.h" -#include "battle_interface.h" -#include "battle_message.h" -#include "data2.h" -#include "link.h" -#include "main.h" -#include "menu_cursor.h" -#include "palette.h" -#include "pokemon.h" -#include "rom3.h" -#include "constants/songs.h" -#include "sound.h" -#include "sprite.h" -#include "item_use.h" -#include "string_util.h" -#include "task.h" -#include "text.h" -#include "util.h" -#include "ewram.h" - -struct MovePpInfo -{ - u16 moves[4]; - u8 pp[4]; - u8 ppBonuses; -}; - -extern u8 gActiveBattler; -extern void (*gBattleBankFunc[])(void); -extern u32 gBattleExecBuffer; -extern u8 gBattleBufferA[][0x200]; -extern u8 gBankSpriteIds[]; -extern MainCallback gPreBattleCallback1; -extern bool8 gDoingBattleAnim; -extern u16 gBattlerPartyIndexes[]; -extern u8 gHealthboxIDs[]; -extern u16 gBattleTypeFlags; -extern u16 gAnimMovePower; -extern s32 gAnimMoveDmg; -extern u8 gAnimFriendship; -extern u16 gWeatherMoveAnim; -extern u32 gTransformedPersonalities[]; -extern void (*gAnimScriptCallback)(void); -extern bool8 gAnimScriptActive; -extern u8 gDisplayedStringBattle[]; -extern u8 gBankInMenu; -extern u8 gBattleMonForms[]; -extern u8 gBattleOutcome; -extern u16 gUnknown_02024DE8; -extern u8 gUnknown_02024E68[]; -extern struct SpriteTemplate gUnknown_02024E8C; -extern u8 gAnimMoveTurn; -extern struct Window gUnknown_03004210; -extern u8 gUnknown_0300434C[]; -extern const u8 BattleText_WallyMenu[]; -extern const u8 BattleText_MenuOptions[]; - -// TODO: include rom3.h when my other PR gets merged -extern void Emitcmd33(u8, u8, u16); -extern void Emitcmd35(u8, u16); - -extern void nullsub_14(void); -extern void PrepareBagForWallyTutorial(void); -extern void sub_8045A5C(); -extern void sub_804777C(); -extern void sub_8043DFC(); -extern bool8 IsDoubleBattle(void); -extern void c3_0802FDF4(u8); -extern void PlayerHandlecmd1(void); -extern void LoadPlayerTrainerBankSprite(); -extern u8 GetBattlerPosition(u8); -extern void sub_80313A0(struct Sprite *); -extern u8 GetBattlerAtPosition(u8); -extern u8 sub_8031720(); -extern void DoMoveAnim(); -extern void sub_80326EC(); -extern void sub_8031F24(void); -extern void sub_80324BC(); -extern void BufferStringBattle(); -extern u8 GetBattlerSide(u8); -extern void sub_80304A8(void); -extern void sub_8047858(); -extern void StartBattleIntroAnim(); -extern void oamt_add_pos2_onto_pos1(); -extern void StartAnimLinearTranslation(struct Sprite *); -extern void sub_8030E38(struct Sprite *); -extern void StoreSpriteCallbackInData(); -extern u8 StartSendOutMonAnimation(); -extern u8 GetBattlerSpriteCoord(); -extern u8 sub_8077F68(); -extern u8 GetBattlerSubpriority(); -extern void sub_80312F0(struct Sprite *); -extern bool8 move_anim_start_t3(); - -// this file's functions - -void WallyBufferRunCommand(void); -void sub_81374FC(void); -void sub_81376B8(void); -void WallyBufferExecCompleted(void); -u32 sub_8137A84(u8, u8 *); -void sub_8138294(u8); -void sub_81390D0(void); -void sub_8139A2C(u8); - -void WallyHandleGetAttributes(void); -void WallyHandlecmd1(void); -void WallyHandleSetAttributes(void); -void WallyHandlecmd3(void); -void WallyHandleLoadPokeSprite(void); -void WallyHandleSendOutPoke(void); -void WallyHandleReturnPokeToBall(void); -void WallyHandleTrainerThrow(void); -void WallyHandleTrainerSlide(void); -void WallyHandleTrainerSlideBack(void); -void WallyHandlecmd10(void); -void WallyHandlecmd11(void); -void WallyHandlecmd12(void); -void WallyHandleBallThrow(void); -void WallyHandlePuase(void); -void WallyHandleMoveAnimation(void); -void WallyHandlePrintString(void); -void WallyHandlePrintStringPlayerOnly(void); -void WallyHandlecmd18(void); -void WallyHandlecmd19(void); -void WallyHandlecmd20(void); -void WallyHandleOpenBag(void); -void WallyHandlecmd22(void); -void WallyHandlecmd23(void); -void WallyHandleHealthBarUpdate(void); -void WallyHandleExpBarUpdate(void); -void WallyHandleStatusIconUpdate(void); -void WallyHandleStatusAnimation(void); -void WallyHandleStatusXor(void); -void WallyHandlecmd29(void); -void WallyHandleDMATransfer(void); -void WallyHandlecmd31(void); -void WallyHandlecmd32(void); -void WallyHandlecmd33(void); -void WallyHandlecmd34(void); -void WallyHandlecmd35(void); -void WallyHandlecmd36(void); -void WallyHandlecmd37(void); -void WallyHandlecmd38(void); -void WallyHandlecmd39(void); -void WallyHandlecmd40(void); -void WallyHandleHitAnimation(void); -void WallyHandlecmd42(void); -void WallyHandleEffectivenessSound(void); -void WallyHandlecmd44(void); -void WallyHandleFaintingCry(void); -void WallyHandleIntroSlide(void); -void WallyHandleTrainerBallThrow(void); -void WallyHandlecmd48(void); -void WallyHandlecmd49(void); -void WallyHandlecmd50(void); -void WallyHandleSpriteInvisibility(void); -void WallyHandleBattleAnimation(void); -void WallyHandleLinkStandbyMsg(void); -void WallyHandleResetActionMoveSelection(void); -void WallyHandlecmd55(void); -void WallyHandlecmd56(void); - -// const data - -typedef void (*BattleBufferCmd) (void); -static const BattleBufferCmd gWallyBufferCommands[] = -{ - WallyHandleGetAttributes, - WallyHandlecmd1, - WallyHandleSetAttributes, - WallyHandlecmd3, - WallyHandleLoadPokeSprite, - WallyHandleSendOutPoke, - WallyHandleReturnPokeToBall, - WallyHandleTrainerThrow, - WallyHandleTrainerSlide, - WallyHandleTrainerSlideBack, - WallyHandlecmd10, - WallyHandlecmd11, - WallyHandlecmd12, - WallyHandleBallThrow, - WallyHandlePuase, - WallyHandleMoveAnimation, - WallyHandlePrintString, - WallyHandlePrintStringPlayerOnly, - WallyHandlecmd18, - WallyHandlecmd19, - WallyHandlecmd20, - WallyHandleOpenBag, - WallyHandlecmd22, - WallyHandlecmd23, - WallyHandleHealthBarUpdate, - WallyHandleExpBarUpdate, - WallyHandleStatusIconUpdate, - WallyHandleStatusAnimation, - WallyHandleStatusXor, - WallyHandlecmd29, - WallyHandleDMATransfer, - WallyHandlecmd31, - WallyHandlecmd32, - WallyHandlecmd33, - WallyHandlecmd34, - WallyHandlecmd35, - WallyHandlecmd36, - WallyHandlecmd37, - WallyHandlecmd38, - WallyHandlecmd39, - WallyHandlecmd40, - WallyHandleHitAnimation, - WallyHandlecmd42, - WallyHandleEffectivenessSound, - WallyHandlecmd44, - WallyHandleFaintingCry, - WallyHandleIntroSlide, - WallyHandleTrainerBallThrow, - WallyHandlecmd48, - WallyHandlecmd49, - WallyHandlecmd50, - WallyHandleSpriteInvisibility, - WallyHandleBattleAnimation, - WallyHandleLinkStandbyMsg, - WallyHandleResetActionMoveSelection, - WallyHandlecmd55, - WallyHandlecmd56, -}; - -// code - -void unref_sub_8137220(void) -{ -} - -void SetBankFuncToWallyBufferRunCommand(void) -{ - gBattleBankFunc[gActiveBattler] = WallyBufferRunCommand; - ewram160A8 = 0; - ewram160A9 = 0; - ewram160AA = 0; - ewram160AB = 0; -} - -void WallyBufferRunCommand(void) -{ - if (gBattleExecBuffer & gBitTable[gActiveBattler]) - { - if (gBattleBufferA[gActiveBattler][0] < 0x39) - gWallyBufferCommands[gBattleBufferA[gActiveBattler][0]](); - else - WallyBufferExecCompleted(); - } -} - -void sub_81372BC(void) -{ - u8 r4; - - switch (ewram160A8) - { - case 0: - ewram160AA = 64; - ewram160A8++; - // fall through - case 1: - r4 = --ewram160AA; - if (r4 == 0) - { - PlaySE(SE_SELECT); - Emitcmd33(1, 0, 0); - WallyBufferExecCompleted(); - ewram160A8++; - ewram160A9 = r4; - ewram160AA = 64; - } - break; - case 2: - r4 = --ewram160AA; - if (r4 == 0) - { - PlaySE(SE_SELECT); - Emitcmd33(1, 0, 0); - WallyBufferExecCompleted(); - ewram160A8++; - ewram160A9 = r4; - ewram160AA = 64; - } - break; - case 3: - r4 = --ewram160AA; - if (r4 == 0) - { - Emitcmd33(1, 9, 0); - WallyBufferExecCompleted(); - ewram160A8++; - ewram160A9 = r4; - ewram160AA = 64; - } - break; - case 4: - if (--ewram160AA == 0) - { - PlaySE(SE_SELECT); - nullsub_8(0); - sub_802E3E4(1, 0); - ewram160AA = 64; - ewram160A8++; - } - break; - case 5: - if (--ewram160AA == 0) - { - PlaySE(SE_SELECT); - DestroyMenuCursor(); - Emitcmd33(1, 1, 0); - WallyBufferExecCompleted(); - } - break; - } -} - -void sub_813741C(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - WallyBufferExecCompleted(); -} - -void sub_8137454(void) -{ - if (gUnknown_03004210.state == 0) - WallyBufferExecCompleted(); -} - -void sub_813746C(void) -{ - if (!gPaletteFade.active) - { - gMain.inBattle = FALSE; - gMain.callback1 = gPreBattleCallback1; - SetMainCallback2(gMain.savedCallback); - } -} - -void bx_wait_t5(void) -{ - if (!gDoingBattleAnim) - WallyBufferExecCompleted(); -} - -void sub_81374C4(void) -{ - if (!gPaletteFade.active) - { - gBattleBankFunc[gActiveBattler] = sub_81374FC; - nullsub_14(); - PrepareBagForWallyTutorial(); - } -} - -void sub_81374FC(void) -{ - if (gMain.callback2 == BattleMainCB2 - && !gPaletteFade.active) - { - Emitcmd35(1, gSpecialVar_ItemId); - WallyBufferExecCompleted(); - } -} - -void sub_8137538(void) -{ - if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) - sub_8141828(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); - - if (!ewram17810[gActiveBattler ^ 2].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_7) - sub_8141828(gActiveBattler ^ 2, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ 2]]); - - if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_3) - { - if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - { - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler ^ 2]]); - sub_8045A5C(gHealthboxIDs[gActiveBattler ^ 2], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], 0); - sub_804777C(gActiveBattler ^ 2); - sub_8043DFC(gHealthboxIDs[gActiveBattler ^ 2]); - } - DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); - sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 0); - sub_804777C(gActiveBattler); - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - ewram17840.unk9_0 = 0; - gBattleBankFunc[gActiveBattler] = sub_81376B8; - } -} - -void sub_81376B8(void) -{ - bool8 r4 = FALSE; - - if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) - r4 = TRUE; - if (r4 && ewram17810[gActiveBattler].unk1_0 && ewram17810[gActiveBattler ^ 2].unk1_0) - { - ewram17810[gActiveBattler].unk0_7 = 0; - ewram17810[gActiveBattler].unk1_0 = 0; - ewram17810[gActiveBattler ^ 2].unk0_7 = 0; - ewram17810[gActiveBattler ^ 2].unk1_0 = 0; - FreeSpriteTilesByTag(0x27F9); - FreeSpritePaletteByTag(0x27F9); - CreateTask(c3_0802FDF4, 10); - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - WallyBufferExecCompleted(); - } -} - -void sub_81377B0(void) -{ - s16 r4; - - r4 = sub_8045C78(gActiveBattler, gHealthboxIDs[gActiveBattler], 0, 0); - sub_8043DFC(gHealthboxIDs[gActiveBattler]); - if (r4 != -1) - { - sub_80440EC(gHealthboxIDs[gActiveBattler], r4, 0); - } - else - { - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); - WallyBufferExecCompleted(); - } -} - -void bx_blink_t5(void) -{ - u8 spriteId = gBankSpriteIds[gActiveBattler]; - - if (gSprites[spriteId].data[1] == 32) - { - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].invisible = FALSE; - gDoingBattleAnim = FALSE; - WallyBufferExecCompleted(); - } - else - { - if (((u16)gSprites[spriteId].data[1] % 4) == 0) - gSprites[spriteId].invisible ^= 1; - gSprites[spriteId].data[1]++; - } -} - -void sub_813789C(void) -{ - if (!ewram17810[gActiveBattler].unk0_6) - { - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - WallyBufferExecCompleted(); - } -} - -// Duplicate of sub_813741C -void sub_8137908(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) - WallyBufferExecCompleted(); -} - -void sub_8137940(void) -{ - if (!ewram17810[gActiveBattler].unk0_5) - WallyBufferExecCompleted(); -} - -void WallyBufferExecCompleted(void) -{ - gBattleBankFunc[gActiveBattler] = WallyBufferRunCommand; - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - u8 multiplayerId = GetMultiplayerId(); - - PrepareBufferDataTransferLink(2, 4, &multiplayerId); - gBattleBufferA[gActiveBattler][0] = 0x38; - } - else - { - gBattleExecBuffer &= ~gBitTable[gActiveBattler]; - } -} - -void unref_sub_81379E4(void) -{ - if (!ewram17810[gActiveBattler].unk0_4) - WallyBufferExecCompleted(); -} - -void WallyHandleGetAttributes(void) -{ - u8 arr[0x100]; - u32 r6 = 0; - u8 r4; - s32 i; - - if (gBattleBufferA[gActiveBattler][2] == 0) - { - r6 = sub_8137A84(gBattlerPartyIndexes[gActiveBattler], arr); - } - else - { - r4 = gBattleBufferA[gActiveBattler][2]; - for (i = 0; i < 6; i++) - { - if (r4 & 1) - r6 += sub_8137A84(i, arr + r6); - r4 >>= 1; - } - } - Emitcmd29(1, r6, arr); - WallyBufferExecCompleted(); -} - -u32 sub_8137A84(u8 a, u8 *buffer) -{ - struct BattlePokemon battlePokemon; - struct MovePpInfo moveData; - u8 nickname[20]; - u8 *src; - s16 data16; - u32 data32; - s32 size = 0; - - switch (gBattleBufferA[gActiveBattler][1]) - { - case 0: - battlePokemon.species = GetMonData(&gPlayerParty[a], MON_DATA_SPECIES); - battlePokemon.item = GetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM); - for (size = 0; size < 4; size++) - { - battlePokemon.moves[size] = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + size); - battlePokemon.pp[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); - } - battlePokemon.ppBonuses = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); - battlePokemon.friendship = GetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP); - battlePokemon.experience = GetMonData(&gPlayerParty[a], MON_DATA_EXP); - battlePokemon.hpIV = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); - battlePokemon.attackIV = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); - battlePokemon.defenseIV = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); - battlePokemon.speedIV = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); - battlePokemon.spAttackIV = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); - battlePokemon.spDefenseIV = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); - battlePokemon.personality = GetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY); - battlePokemon.status1 = GetMonData(&gPlayerParty[a], MON_DATA_STATUS); - battlePokemon.level = GetMonData(&gPlayerParty[a], MON_DATA_LEVEL); - battlePokemon.hp = GetMonData(&gPlayerParty[a], MON_DATA_HP); - battlePokemon.maxHP = GetMonData(&gPlayerParty[a], MON_DATA_MAX_HP); - battlePokemon.attack = GetMonData(&gPlayerParty[a], MON_DATA_ATK); - battlePokemon.defense = GetMonData(&gPlayerParty[a], MON_DATA_DEF); - battlePokemon.speed = GetMonData(&gPlayerParty[a], MON_DATA_SPEED); - battlePokemon.spAttack = GetMonData(&gPlayerParty[a], MON_DATA_SPATK); - battlePokemon.spDefense = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF); - battlePokemon.isEgg = GetMonData(&gPlayerParty[a], MON_DATA_IS_EGG); - battlePokemon.altAbility = GetMonData(&gPlayerParty[a], MON_DATA_ALT_ABILITY); - battlePokemon.otId = GetMonData(&gPlayerParty[a], MON_DATA_OT_ID); - GetMonData(&gPlayerParty[a], MON_DATA_NICKNAME, nickname); - StringCopy10(battlePokemon.nickname, nickname); - GetMonData(&gPlayerParty[a], MON_DATA_OT_NAME, battlePokemon.otName); - MEMCPY_ALT(&battlePokemon, buffer, sizeof(battlePokemon), size, src); - break; - case 1: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPECIES); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 2: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 3: - for (size = 0; size < 4; size++) - { - moveData.moves[size] = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + size); - moveData.pp[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); - } - moveData.ppBonuses = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); - MEMCPY_ALT(&moveData, buffer, sizeof(moveData), size, src); - break; - case 4: - case 5: - case 6: - case 7: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 8: - for (size = 0; size < 4; size++) - buffer[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); - buffer[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); - size++; - break; - case 9: - case 10: - case 11: - case 12: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9); - size = 1; - break; - case 17: - data32 = GetMonData(&gPlayerParty[a], MON_DATA_OT_ID); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case 18: - data32 = GetMonData(&gPlayerParty[a], MON_DATA_EXP); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - size = 3; - break; - case 19: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_EV); - size = 1; - break; - case 20: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_EV); - size = 1; - break; - case 21: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_EV); - size = 1; - break; - case 22: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_EV); - size = 1; - break; - case 23: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_EV); - size = 1; - break; - case 24: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_EV); - size = 1; - break; - case 25: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP); - size = 1; - break; - case 26: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_POKERUS); - size = 1; - break; - case 27: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_LOCATION); - size = 1; - break; - case 28: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_LEVEL); - size = 1; - break; - case 29: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_GAME); - size = 1; - break; - case 30: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_POKEBALL); - size = 1; - break; - case 31: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); - buffer[1] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); - buffer[2] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); - buffer[3] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); - buffer[4] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); - buffer[5] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); - size = 6; - break; - case 32: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); - size = 1; - break; - case 33: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); - size = 1; - break; - case 34: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); - size = 1; - break; - case 35: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); - size = 1; - break; - case 36: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); - size = 1; - break; - case 37: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); - size = 1; - break; - case 38: - data32 = GetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - buffer[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case 39: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_CHECKSUM); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 40: - data32 = GetMonData(&gPlayerParty[a], MON_DATA_STATUS); - buffer[0] = (data32 & 0x000000FF); - buffer[1] = (data32 & 0x0000FF00) >> 8; - buffer[2] = (data32 & 0x00FF0000) >> 16; - buffer[3] = (data32 & 0xFF000000) >> 24; - size = 4; - break; - case 41: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_LEVEL); - size = 1; - break; - case 42: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_HP); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 43: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_MAX_HP); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 44: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_ATK); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 45: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_DEF); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 46: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPEED); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 47: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPATK); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 48: - data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF); - buffer[0] = data16; - buffer[1] = data16 >> 8; - size = 2; - break; - case 49: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_COOL); - size = 1; - break; - case 50: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_BEAUTY); - size = 1; - break; - case 51: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_CUTE); - size = 1; - break; - case 52: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SMART); - size = 1; - break; - case 53: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_TOUGH); - size = 1; - break; - case 54: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SHEEN); - size = 1; - break; - case 55: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_COOL_RIBBON); - size = 1; - break; - case 56: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_BEAUTY_RIBBON); - size = 1; - break; - case 57: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_CUTE_RIBBON); - size = 1; - break; - case 58: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SMART_RIBBON); - size = 1; - break; - case 59: - buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_TOUGH_RIBBON); - size = 1; - break; - } - return size; -} - -void WallyHandlecmd1(void) -{ - PlayerHandlecmd1(); -} - -void WallyHandleSetAttributes(void) -{ - u8 r4; - u8 i; - - if (gBattleBufferA[gActiveBattler][2] == 0) - { - sub_8138294(gBattlerPartyIndexes[gActiveBattler]); - } - else - { - r4 = gBattleBufferA[gActiveBattler][2]; - for (i = 0; i < 6; i++) - { - if (r4 & 1) - sub_8138294(i); - r4 >>= 1; - } - } - WallyBufferExecCompleted(); -} - -void sub_8138294(u8 a) -{ - struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBattler][3]; - struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBattler][3]; - s32 i; - - switch (gBattleBufferA[gActiveBattler][1]) - { - case 0: - { - u8 iv; - - SetMonData(&gPlayerParty[a], MON_DATA_SPECIES, &battlePokemon->species); - SetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM, &battlePokemon->item); - for (i = 0; i < 4; i++) - { - SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); - SetMonData(&gPlayerParty[a], MON_DATA_PP1 + i, &battlePokemon->pp[i]); - } - SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); - SetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); - SetMonData(&gPlayerParty[a], MON_DATA_EXP, &battlePokemon->experience); - iv = battlePokemon->hpIV; - SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &iv); - iv = battlePokemon->attackIV; - SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &iv); - iv = battlePokemon->defenseIV; - SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &iv); - iv = battlePokemon->speedIV; - SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &iv); - iv = battlePokemon->spAttackIV; - SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &iv); - iv = battlePokemon->spDefenseIV; - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &iv); - SetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY, &battlePokemon->personality); - SetMonData(&gPlayerParty[a], MON_DATA_STATUS, &battlePokemon->status1); - SetMonData(&gPlayerParty[a], MON_DATA_LEVEL, &battlePokemon->level); - SetMonData(&gPlayerParty[a], MON_DATA_HP, &battlePokemon->hp); - SetMonData(&gPlayerParty[a], MON_DATA_MAX_HP, &battlePokemon->maxHP); - SetMonData(&gPlayerParty[a], MON_DATA_ATK, &battlePokemon->attack); - SetMonData(&gPlayerParty[a], MON_DATA_DEF, &battlePokemon->defense); - SetMonData(&gPlayerParty[a], MON_DATA_SPEED, &battlePokemon->speed); - SetMonData(&gPlayerParty[a], MON_DATA_SPATK, &battlePokemon->spAttack); - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF, &battlePokemon->spDefense); - } - break; - case 1: - SetMonData(&gPlayerParty[a], MON_DATA_SPECIES, &gBattleBufferA[gActiveBattler][3]); - break; - case 2: - SetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]); - break; - case 3: - for (i = 0; i < 4; i++) - { - SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + i, &moveData->moves[i]); - SetMonData(&gPlayerParty[a], MON_DATA_PP1 + i, &moveData->pp[i]); - } - SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &moveData->ppBonuses); - break; - case 4: - case 5: - case 6: - case 7: - SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4, &gBattleBufferA[gActiveBattler][3]); - break; - case 8: - SetMonData(&gPlayerParty[a], MON_DATA_PP1, &gBattleBufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[a], MON_DATA_PP2, &gBattleBufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[a], MON_DATA_PP3, &gBattleBufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[a], MON_DATA_PP4, &gBattleBufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBattler][7]); - break; - case 9: - case 10: - case 11: - case 12: - SetMonData(&gPlayerParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9, &gBattleBufferA[gActiveBattler][3]); - break; - case 17: - SetMonData(&gPlayerParty[a], MON_DATA_OT_ID, &gBattleBufferA[gActiveBattler][3]); - break; - case 18: - SetMonData(&gPlayerParty[a], MON_DATA_EXP, &gBattleBufferA[gActiveBattler][3]); - break; - case 19: - SetMonData(&gPlayerParty[a], MON_DATA_HP_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 20: - SetMonData(&gPlayerParty[a], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 21: - SetMonData(&gPlayerParty[a], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 22: - SetMonData(&gPlayerParty[a], MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 23: - SetMonData(&gPlayerParty[a], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 24: - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBattler][3]); - break; - case 25: - SetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBattler][3]); - break; - case 26: - SetMonData(&gPlayerParty[a], MON_DATA_POKERUS, &gBattleBufferA[gActiveBattler][3]); - break; - case 27: - SetMonData(&gPlayerParty[a], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBattler][3]); - break; - case 28: - SetMonData(&gPlayerParty[a], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBattler][3]); - break; - case 29: - SetMonData(&gPlayerParty[a], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBattler][3]); - break; - case 30: - SetMonData(&gPlayerParty[a], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBattler][3]); - break; - case 31: - SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); - SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][4]); - SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][5]); - SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][6]); - SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][7]); - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][8]); - break; - case 32: - SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 33: - SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 34: - SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 35: - SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 36: - SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 37: - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][3]); - break; - case 38: - SetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBattler][3]); - break; - case 39: - SetMonData(&gPlayerParty[a], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBattler][3]); - break; - case 40: - SetMonData(&gPlayerParty[a], MON_DATA_STATUS, &gBattleBufferA[gActiveBattler][3]); - break; - case 41: - SetMonData(&gPlayerParty[a], MON_DATA_LEVEL, &gBattleBufferA[gActiveBattler][3]); - break; - case 42: - SetMonData(&gPlayerParty[a], MON_DATA_HP, &gBattleBufferA[gActiveBattler][3]); - break; - case 43: - SetMonData(&gPlayerParty[a], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBattler][3]); - break; - case 44: - SetMonData(&gPlayerParty[a], MON_DATA_ATK, &gBattleBufferA[gActiveBattler][3]); - break; - case 45: - SetMonData(&gPlayerParty[a], MON_DATA_DEF, &gBattleBufferA[gActiveBattler][3]); - break; - case 46: - SetMonData(&gPlayerParty[a], MON_DATA_SPEED, &gBattleBufferA[gActiveBattler][3]); - break; - case 47: - SetMonData(&gPlayerParty[a], MON_DATA_SPATK, &gBattleBufferA[gActiveBattler][3]); - break; - case 48: - SetMonData(&gPlayerParty[a], MON_DATA_SPDEF, &gBattleBufferA[gActiveBattler][3]); - break; - case 49: - SetMonData(&gPlayerParty[a], MON_DATA_COOL, &gBattleBufferA[gActiveBattler][3]); - break; - case 50: - SetMonData(&gPlayerParty[a], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBattler][3]); - break; - case 51: - SetMonData(&gPlayerParty[a], MON_DATA_CUTE, &gBattleBufferA[gActiveBattler][3]); - break; - case 52: - SetMonData(&gPlayerParty[a], MON_DATA_SMART, &gBattleBufferA[gActiveBattler][3]); - break; - case 53: - SetMonData(&gPlayerParty[a], MON_DATA_TOUGH, &gBattleBufferA[gActiveBattler][3]); - break; - case 54: - SetMonData(&gPlayerParty[a], MON_DATA_SHEEN, &gBattleBufferA[gActiveBattler][3]); - break; - case 55: - SetMonData(&gPlayerParty[a], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 56: - SetMonData(&gPlayerParty[a], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 57: - SetMonData(&gPlayerParty[a], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 58: - SetMonData(&gPlayerParty[a], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - case 59: - SetMonData(&gPlayerParty[a], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBattler][3]); - break; - } - HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); -} - -void WallyHandlecmd3(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleLoadPokeSprite(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleSendOutPoke(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleReturnPokeToBall(void) -{ - if (gBattleBufferA[gActiveBattler][1] == 0) - { - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 1); - gBattleBankFunc[gActiveBattler] = sub_813789C; - } - else - { - FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); - DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); - sub_8043DB0(gHealthboxIDs[gActiveBattler]); - WallyBufferExecCompleted(); - } -} - -void WallyHandleTrainerThrow(void) -{ - LoadPlayerTrainerBankSprite(2, gActiveBattler); - GetMonSpriteTemplate_803C5A0(2, GetBattlerPosition(gActiveBattler)); - gBankSpriteIds[gActiveBattler] = CreateSprite( - &gUnknown_02024E8C, - 80, 80 + 4 * (8 - gTrainerBackPicCoords[2].coords), - 30); - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = 240; - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = -2; - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; - gBattleBankFunc[gActiveBattler] = sub_813741C; -} - -void WallyHandleTrainerSlide(void) -{ - LoadPlayerTrainerBankSprite(2, gActiveBattler); - GetMonSpriteTemplate_803C5A0(2, GetBattlerPosition(gActiveBattler)); - gBankSpriteIds[gActiveBattler] = CreateSprite( - &gUnknown_02024E8C, - 80, 80 + 4 * (8 - gTrainerBackPicCoords[2].coords), - 30); - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; - gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -96; - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 2; - gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; - gBattleBankFunc[gActiveBattler] = sub_8137908; -} - -void WallyHandleTrainerSlideBack(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd10(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd11(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd12(void) -{ - ewram17840.unk8 = 4; - gDoingBattleAnim = TRUE; - move_anim_start_t4(gActiveBattler, gActiveBattler, GetBattlerAtPosition(1), 4); - gBattleBankFunc[gActiveBattler] = bx_wait_t5; -} - -void WallyHandleBallThrow(void) -{ - u8 val = gBattleBufferA[gActiveBattler][1]; - - ewram17840.unk8 = val; - gDoingBattleAnim = TRUE; - move_anim_start_t4(gActiveBattler, gActiveBattler, GetBattlerAtPosition(1), 4); - gBattleBankFunc[gActiveBattler] = bx_wait_t5; -} - -void WallyHandlePuase(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleMoveAnimation(void) -{ - u16 move = gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8); - - gAnimMoveTurn = gBattleBufferA[gActiveBattler][3]; - gAnimMovePower = gBattleBufferA[gActiveBattler][4] | (gBattleBufferA[gActiveBattler][5] << 8); - gAnimMoveDmg = gBattleBufferA[gActiveBattler][6] | (gBattleBufferA[gActiveBattler][7] << 8) | (gBattleBufferA[gActiveBattler][8] << 16) | (gBattleBufferA[gActiveBattler][9] << 24); - gAnimFriendship = gBattleBufferA[gActiveBattler][10]; - gWeatherMoveAnim = gBattleBufferA[gActiveBattler][12] | (gBattleBufferA[gActiveBattler][13] << 8); - gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBattler][16]; - gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; - if (sub_8031720(move, gAnimMoveTurn) != 0) - { - // Dead code. sub_8031720 always returns 0. - WallyBufferExecCompleted(); - } - else - { - ewram17810[gActiveBattler].unk4 = 0; - gBattleBankFunc[gActiveBattler] = sub_81390D0; - } -} - -void sub_81390D0(void) -{ - u16 r4 = gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8); - -#ifndef NONMATCHING - asm("":::"r6"); -#endif - - switch (ewram17810[gActiveBattler].unk4) - { - case 0: - if (ewram17800[gActiveBattler].substituteSprite == 1) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); - ewram17810[gActiveBattler].unk4 = 1; - break; - case 1: - if (ewram17810[gActiveBattler].unk0_6 == 0) - { - sub_80326EC(0); - DoMoveAnim(r4); - ewram17810[gActiveBattler].unk4 = 2; - } - break; - case 2: - gAnimScriptCallback(); - if (!gAnimScriptActive) - { - sub_80326EC(1); - if (ewram17800[gActiveBattler].substituteSprite == 1) - move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); - ewram17810[gActiveBattler].unk4 = 3; - } - break; - case 3: - if (ewram17810[gActiveBattler].unk0_6 == 0) - { - sub_8031F24(); - sub_80324BC(gActiveBattler, gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - ewram17810[gActiveBattler].unk4 = 0; - WallyBufferExecCompleted(); - } - break; - } -} - -void WallyHandlePrintString(void) -{ - u16 *ptr; - - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - ptr = (u16 *)&gBattleBufferA[gActiveBattler][2]; - if (*ptr == 2) - DestroyMenuCursor(); - BufferStringBattle(*ptr); - Text_InitWindow8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 0x90, 2, 15); - gBattleBankFunc[gActiveBattler] = sub_8137454; -} - -void WallyHandlePrintStringPlayerOnly(void) -{ - if (GetBattlerSide(gActiveBattler) == 0) - WallyHandlePrintString(); - else - WallyBufferExecCompleted(); -} - -void WallyHandlecmd18(void) -{ - s32 i; - - gBattle_BG0_X = 0; - gBattle_BG0_Y = 160; - gUnknown_03004210.paletteNum = 0; - Text_FillWindowRectDefPalette(&gUnknown_03004210, 10, 2, 15, 27, 18); - Text_FillWindowRectDefPalette(&gUnknown_03004210, 10, 2, 35, 16, 36); - gBattleBankFunc[gActiveBattler] = sub_81372BC; - Text_InitWindow(&gUnknown_03004210, BattleText_MenuOptions, 400, 18, 35); - Text_PrintWindow8002F44(&gUnknown_03004210); - MenuCursor_Create814A5C0(0, 0xFFFF, 12, 0x2D9F, 0); - for (i = 0; i < 4; i++) - nullsub_8(i); - sub_802E3E4(0, 0); - StrCpyDecodeToDisplayedStringBattle(BattleText_WallyMenu); -#ifdef ENGLISH - Text_InitWindow(&gUnknown_03004210, gDisplayedStringBattle, 440, 2, 35); -#else - Text_InitWindow(&gUnknown_03004210, gDisplayedStringBattle, 444, 2, 35); -#endif - Text_PrintWindow8002F44(&gUnknown_03004210); -} - -void WallyHandlecmd19(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd20(void) -{ - switch (ewram160A9) - { - case 0: - sub_80304A8(); - ewram160A9++; - ewram160AB = 80; - // fall through - case 1: - ewram160AB--; - if (ewram160AB == 0) - { - DestroyMenuCursor(); - PlaySE(SE_SELECT); - Emitcmd33(1, 10, 256); - WallyBufferExecCompleted(); - } - break; - } -} - -void WallyHandleOpenBag(void) -{ - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); - gBattleBankFunc[gActiveBattler] = sub_81374C4; - gBankInMenu = gActiveBattler; -} - -void WallyHandlecmd22(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd23(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleHealthBarUpdate(void) -{ - s16 r7; - - load_gfxc_health_bar(0); - r7 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); - if (r7 != 0x7FFF) - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - u32 curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); - - sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, curHP, r7); - } - else - { - u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); - - sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, 0, r7); - sub_80440EC(gHealthboxIDs[gActiveBattler], 0, 0); - } - gBattleBankFunc[gActiveBattler] = sub_81377B0; -} - -void WallyHandleExpBarUpdate(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleStatusIconUpdate(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleStatusAnimation(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleStatusXor(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd29(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleDMATransfer(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd31(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd32(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd33(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd34(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd35(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd36(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd37(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd38(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd39(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd40(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleHitAnimation(void) -{ - if (gSprites[gBankSpriteIds[gActiveBattler]].invisible == TRUE) - { - WallyBufferExecCompleted(); - } - else - { - gDoingBattleAnim = 1; - gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; - sub_8047858(gActiveBattler); - gBattleBankFunc[gActiveBattler] = bx_blink_t5; - } -} - -void WallyHandlecmd42(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleEffectivenessSound(void) -{ - PlaySE(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - WallyBufferExecCompleted(); -} - -void WallyHandlecmd44(void) -{ - PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); - WallyBufferExecCompleted(); -} - -void WallyHandleFaintingCry(void) -{ - PlayCry1(GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES), 25); - WallyBufferExecCompleted(); -} - -void WallyHandleIntroSlide(void) -{ - StartBattleIntroAnim(gBattleBufferA[gActiveBattler][1]); - gUnknown_02024DE8 |= 1; - WallyBufferExecCompleted(); -} - -void WallyHandleTrainerBallThrow(void) -{ - u8 paletteNum; - u8 taskId; - - oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); - gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 50; - gSprites[gBankSpriteIds[gActiveBattler]].data[2] = -40; - gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; - gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; - gSprites[gBankSpriteIds[gActiveBattler]].data[5] = gActiveBattler; - StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], sub_8030E38); - StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 1); - paletteNum = AllocSpritePalette(0xD6F8); - LoadCompressedPalette(gTrainerBackPicPaletteTable[2].data, 0x100 + paletteNum * 16, 32); - gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = paletteNum; - taskId = CreateTask(sub_8139A2C, 5); - gTasks[taskId].data[0] = gActiveBattler; - if (ewram17810[gActiveBattler].unk0_0) - gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; - ewram17810[4].unk9 |= 1; - gBattleBankFunc[gActiveBattler] = nullsub_91; -} - -void sub_81398BC(u8 bank) -{ - u16 species; - - ewram17800[bank].transformedSpecies = 0; - gBattlerPartyIndexes[bank] = gBattleBufferA[bank][1]; - species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES); - gUnknown_0300434C[bank] = CreateInvisibleSpriteWithCallback(sub_80312F0); - GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(bank)); - gBankSpriteIds[bank] = CreateSprite( - &gUnknown_02024E8C, - GetBattlerSpriteCoord(bank, 2), - sub_8077F68(bank), - GetBattlerSubpriority(bank)); - gSprites[gUnknown_0300434C[bank]].data[1] = gBankSpriteIds[bank]; - gSprites[gBankSpriteIds[bank]].data[0] = bank; - gSprites[gBankSpriteIds[bank]].data[2] = species; - gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; - StartSpriteAnim(&gSprites[gBankSpriteIds[bank]], gBattleMonForms[bank]); - gSprites[gBankSpriteIds[bank]].invisible = TRUE; - gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; - gSprites[gUnknown_0300434C[bank]].data[0] = StartSendOutMonAnimation(0, 0xFF); -} - -void sub_8139A2C(u8 taskId) -{ - if (gTasks[taskId].data[1] < 31) - { - gTasks[taskId].data[1]++; - } - else - { - u8 savedActiveBank = gActiveBattler; - - gActiveBattler = gTasks[taskId].data[0]; - gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; - sub_81398BC(gActiveBattler); - gBattleBankFunc[gActiveBattler] = sub_8137538; - gActiveBattler = savedActiveBank; - DestroyTask(taskId); - } -} - -void WallyHandlecmd48(void) -{ - if (gBattleBufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == 0) - { - WallyBufferExecCompleted(); - } - else - { - ewram17810[gActiveBattler].unk0_0 = 1; - gUnknown_02024E68[gActiveBattler] = sub_8044804(gActiveBattler, (struct BattleInterfaceStruct2 *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); - WallyBufferExecCompleted(); - } -} - -void WallyHandlecmd49(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd50(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleSpriteInvisibility(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleBattleAnimation(void) -{ - u8 val2 = gBattleBufferA[gActiveBattler][1]; - u16 val = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); - - if (move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, val2, val)) - WallyBufferExecCompleted(); - else - gBattleBankFunc[gActiveBattler] = sub_8137940; -} - -void WallyHandleLinkStandbyMsg(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandleResetActionMoveSelection(void) -{ - WallyBufferExecCompleted(); -} - -void WallyHandlecmd55(void) -{ - gBattleOutcome = gBattleBufferA[gActiveBattler][1]; - FadeOutMapMusic(5); - BeginFastPaletteFade(3); - WallyBufferExecCompleted(); - if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && !(gBattleTypeFlags & BATTLE_TYPE_WILD)) - gBattleBankFunc[gActiveBattler] = sub_813746C; -} - -void WallyHandlecmd56(void) -{ -} diff --git a/src/battle/battle_interface.c b/src/battle/battle_interface.c deleted file mode 100644 index dedde2cb3..000000000 --- a/src/battle/battle_interface.c +++ /dev/null @@ -1,3423 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_interface.h" -#include "decompress.h" -#include "palette.h" -#include "pokedex.h" -#include "pokemon.h" -#include "rom_8077ABC.h" -#include "safari_zone.h" -#include "constants/songs.h" -#include "sound.h" -#include "sprite.h" -#include "string_util.h" -#include "task.h" -#include "text.h" -#include "ewram.h" -#include "graphics.h" - -struct UnknownStruct5 -{ - u8 unk0; - u32 unk4; - u32 unk8; - u32 unkC; - u32 unk10; -}; - -struct UnknownStruct7 -{ - u8 filler0[0x180]; -}; - -static void sub_8043CEC(struct Sprite *sprite); -static void sub_8045030(struct Sprite *sprite); -static void sub_804507C(struct Sprite *sprite); - -const struct OamData gOamData_820A4E4 = -{ - .shape = 1, - .size = 3, - .priority = 1, -}; - -const struct SpriteTemplate gSpriteTemplates_820A4EC[] = -{ - { - .tileTag = 55039, - .paletteTag = 55039, - .oam = &gOamData_820A4E4, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55040, - .paletteTag = 55039, - .oam = &gOamData_820A4E4, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, -}; - -const struct SpriteTemplate gSpriteTemplates_820A51C[] = -{ - { - .tileTag = 55041, - .paletteTag = 55039, - .oam = &gOamData_820A4E4, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, - { - .tileTag = 55042, - .paletteTag = 55039, - .oam = &gOamData_820A4E4, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, - }, -}; - -const struct SpriteTemplate gSpriteTemplate_820A54C = -{ - .tileTag = 55051, - .paletteTag = 55039, - .oam = &gOamData_820A4E4, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbackDummy, -}; - -const struct OamData gOamData_820A564 = -{ - .shape = 1, - .size = 1, - .priority = 1, -}; - -const struct SpriteTemplate gSpriteTemplates_820A56C[] = -{ - { - .tileTag = 55044, - .paletteTag = 55044, - .oam = &gOamData_820A564, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8043CEC, - }, - { - .tileTag = 55045, - .paletteTag = 55044, - .oam = &gOamData_820A564, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8043CEC, - }, - { - .tileTag = 55046, - .paletteTag = 55044, - .oam = &gOamData_820A564, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8043CEC, - }, - { - .tileTag = 55047, - .paletteTag = 55044, - .oam = &gOamData_820A564, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8043CEC, - }, -}; - -const struct Subsprite gSubspriteTable_820A5CC[] = -{ - { .x = -16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 3 }, // size := 64x32 - { .x = 48, .y = 0, .shape = ST_OAM_SQUARE, .priority = 1, .tileOffset = 32, .size = 2 }, // size := 32x32 - { .x = -16, .y = 32, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 48, .size = 1 }, // size := 32x8 - { .x = 16, .y = 32, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 52, .size = 1 }, // size := 32x8 - { .x = 48, .y = 32, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 56, .size = 1 }, // size := 32x8 -}; - -const struct Subsprite gSubspriteTable_820A5F4[] = -{ - { .x = -16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 64, .size = 3 }, // size := 64x32 - { .x = 48, .y = 0, .shape = ST_OAM_SQUARE, .priority = 1, .tileOffset = 96, .size = 2 }, // size := 32x32 - { .x = -16, .y = 32, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset =112, .size = 1 }, // size := 32x8 - { .x = 16, .y = 32, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset =116, .size = 1 }, // size := 32x8 - { .x = 48, .y = 32, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset =120, .size = 1 }, // size := 32x8 -}; - -const struct Subsprite gSubspriteTable_820A61C[] = -{ - { .x = -16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 3 }, // size := 64x32 - { .x = 48, .y = 0, .shape = ST_OAM_SQUARE, .priority = 1, .tileOffset = 32, .size = 2 }, // size := 32x32 -}; - -const struct Subsprite gSubspriteTable_820A62C[] = -{ - { .x = -16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 3 }, // size := 64x32 - { .x = 48, .y = 0, .shape = ST_OAM_SQUARE, .priority = 1, .tileOffset = 32, .size = 2 }, // size := 32x32 -}; - -const struct Subsprite gSubspriteTable_820A63C[] = -{ - { .x = -16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 1 }, // size := 32x8 - { .x = 16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 4, .size = 1 }, // size := 32x8 -}; - -const struct Subsprite gSubspriteTable_820A64C[] = -{ - { .x = -16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 1 }, // size := 32x8 - { .x = 16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 4, .size = 1 }, // size := 32x8 - { .x = -32, .y = 0, .shape = ST_OAM_SQUARE, .priority = 1, .tileOffset = 8, .size = 0 }, // size := 8x8 -}; - -const struct SubspriteTable gSubspriteTables_unreferenced[] = -{ - { ARRAY_COUNT(gSubspriteTable_820A5CC), gSubspriteTable_820A5CC }, - { ARRAY_COUNT(gSubspriteTable_820A61C), gSubspriteTable_820A61C }, - { ARRAY_COUNT(gSubspriteTable_820A5F4), gSubspriteTable_820A5F4 }, - { ARRAY_COUNT(gSubspriteTable_820A62C), gSubspriteTable_820A62C }, -}; - -const struct SubspriteTable gSubspriteTables_820A684[] = -{ - { ARRAY_COUNT(gSubspriteTable_820A63C), gSubspriteTable_820A63C }, - { ARRAY_COUNT(gSubspriteTable_820A64C), gSubspriteTable_820A64C }, -}; - -const struct Subsprite gSubspriteTable_820A694[] = -{ - { .x = -96, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 1 }, // size := 32x8 - { .x = -64, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 4, .size = 1 }, // size := 32x8 - { .x = -32, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 8, .size = 1 }, // size := 32x8 - { .x = 0, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 12, .size = 1 }, // size := 32x8 -}; - -const struct Subsprite gSubspriteTable_820A6B4[] = -{ - { .x = -96, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 1 }, // size := 32x8 - { .x = -64, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 4, .size = 1 }, // size := 32x8 - { .x = -32, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 8, .size = 1 }, // size := 32x8 - { .x = 0, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 8, .size = 1 }, // size := 32x8 - { .x = 32, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 8, .size = 1 }, // size := 32x8 - { .x = 64, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 12, .size = 1 }, // size := 32x8 -}; - -const struct SubspriteTable gSubspriteTables_820A6E4[] = -{ - { ARRAY_COUNT(gSubspriteTable_820A694), gSubspriteTable_820A694 }, -}; - -const struct SubspriteTable gSubspriteTables_820A6EC[] = -{ - { ARRAY_COUNT(gSubspriteTable_820A6B4), gSubspriteTable_820A6B4 }, -}; - -// unused dakuten/handakuten tiles -const u8 gUnusedDakuten[] = INCBIN_U8("graphics/unused/dakuten.4bpp"); - -const struct CompressedSpriteSheet gUnknown_0820A754[] = -{ - { gBattleGfx_BallStatusBar, 512, 0xd70c }, - { gBattleGfx_BallStatusBar, 512, 0xd70d }, -}; - -const struct SpritePalette gUnknown_0820A764[] = -{ - { gUnknown_08D1212C, 0xd710 }, - { gUnknown_08D1212C, 0xd711 }, -}; - -const struct SpritePalette gUnknown_0820A774[] = -{ - { gUnknown_08D1214C, 0xd712 }, - { gUnknown_08D1214C, 0xd713 }, -}; - -const struct CompressedSpriteSheet gUnknown_0820A784[] = -{ - { Tiles_D129AC, 0x80, 0xd714 }, - { Tiles_D129AC, 0x80, 0xd715 }, -}; - -const struct OamData gOamData_820A794 = -{ - .shape = 1, - .size = 3, - .priority = 1, -}; - -const struct OamData gOamData_820A79C = -{ - .shape = 0, - .size = 0, - .priority = 1, -}; - -const struct SpriteTemplate gSpriteTemplate_820A7A4 = -{ - .tileTag = 55052, - .paletteTag = 55056, - .oam = &gOamData_820A4E4, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8045030, -}; - -const struct SpriteTemplate gSpriteTemplate_820A7BC = -{ - .tileTag = 55053, - .paletteTag = 55057, - .oam = &gOamData_820A4E4, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_8045030, -}; - -const struct SpriteTemplate gSpriteTemplate_820A7D4 = -{ - .tileTag = 55060, - .paletteTag = 55058, - .oam = &gOamData_820A79C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_804507C, -}; - -const struct SpriteTemplate gSpriteTemplate_820A7EC = -{ - .tileTag = 55061, - .paletteTag = 55059, - .oam = &gOamData_820A79C, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_804507C, -}; - -u8 *const gUnknown_0820A804[2] = -{ - OBJ_VRAM0 + 32 * 74, - OBJ_VRAM0 + 32 * 75, -}; - -u8 *const gUnknown_0820A80C[2] = -{ - OBJ_VRAM0 + 32 * 41, - OBJ_VRAM0 + 32 * 42, -}; - -u8 *const gUnknown_0820A814[2] = -{ - OBJ_VRAM0 + 32 * 42, - OBJ_VRAM0 + 32 * 43, -}; - -const u8 gUnknown_0820A81C[] = __("{COLOR DARK_GREY}{HIGHLIGHT RED} "); - -u8 *const gUnknown_0820A83C[3] = -{ - OBJ_VRAM0 + 32 * 31, - OBJ_VRAM0 + 32 * 88, - OBJ_VRAM0 + 32 * 89, -}; - -u8 *const gUnknown_0820A848[3] = -{ - OBJ_VRAM0 + 32 * 22, - OBJ_VRAM0 + 32 * 23, - OBJ_VRAM0 + 32 * 48, -}; - -u8 *const gUnknown_0820A854[2] = -{ - OBJ_VRAM0 + 32 * 90, - OBJ_VRAM0 + 32 * 91, -}; - -u8 *const gUnknown_0820A85C[2] = -{ - OBJ_VRAM0 + 32 * 49, - OBJ_VRAM0 + 32 * 50, -}; - -const u8 gUnknown_0820A864[] = _("{COLOR DARK_GREY}{HIGHLIGHT RED} /"); - -u8 *const gUnknown_0820A87C[6] = -{ - OBJ_VRAM0 + 32 * 0, - OBJ_VRAM0 + 32 * 1, - OBJ_VRAM0 + 32 * 2, - OBJ_VRAM0 + 32 * 3, - OBJ_VRAM0 + 32 * 4, - OBJ_VRAM0 + 32 * 5, -}; - -u8 *const gUnknown_0820A894[2] = -{ - OBJ_VRAM0 + 32 * 6, - OBJ_VRAM0 + 32 * 7, -}; - -const u8 gUnknown_0820A89C[] = __("{COLOR DARK_GREY}{HIGHLIGHT TRANSPARENT} "); -const u8 gUnknown_0820A8B0[] = _("{HIGHLIGHT RED}"); - -u8 *const gUnknown_0820A8B4[10] = -{ - OBJ_VRAM0 + 32 * 2, - OBJ_VRAM0 + 32 * 3, - OBJ_VRAM0 + 32 * 4, - OBJ_VRAM0 + 32 * 5, - OBJ_VRAM0 + 32 * 6, - OBJ_VRAM0 + 32 * 7, - OBJ_VRAM0 + 32 * 64, - OBJ_VRAM0 + 32 * 65, - OBJ_VRAM0 + 32 * 66, - OBJ_VRAM0 + 32 * 67, -}; - -u8 *const gUnknown_0820A8DC[10] = -{ - OBJ_VRAM0 + 32 * 1, - OBJ_VRAM0 + 32 * 2, - OBJ_VRAM0 + 32 * 3, - OBJ_VRAM0 + 32 * 4, - OBJ_VRAM0 + 32 * 5, - OBJ_VRAM0 + 32 * 6, - OBJ_VRAM0 + 32 * 7, - OBJ_VRAM0 + 32 * 32, - OBJ_VRAM0 + 32 * 33, - OBJ_VRAM0 + 32 * 34, -}; - -u8 *const gUnknown_0820A904[10] = -{ - OBJ_VRAM0 + 32 * 2, - OBJ_VRAM0 + 32 * 3, - OBJ_VRAM0 + 32 * 4, - OBJ_VRAM0 + 32 * 5, - OBJ_VRAM0 + 32 * 6, - OBJ_VRAM0 + 32 * 7, - OBJ_VRAM0 + 32 * 32, - OBJ_VRAM0 + 32 * 33, - OBJ_VRAM0 + 32 * 34, - OBJ_VRAM0 + 32 * 35, -}; - -extern u8 gDisplayedStringBattle[]; -extern u8 gBattlersCount; -extern u16 gBattlerPartyIndexes[]; -extern u8 gBanksBySide[]; -extern u8 gHealthboxIDs[]; - -extern u16 gBattleTypeFlags; - -extern const u8 BattleText_SafariBalls[]; -extern const u8 BattleText_SafariBallsLeft[]; -extern const u8 BattleText_HighlightRed[]; -extern const u8 gHealthboxElementsGfxTable[][32]; - -extern const u16 gBattleInterfaceStatusIcons_DynPal[]; - -#define ABS(n) ((n) >= 0 ? (n) : -(n)) -// Used for computing copy destination addresses -#define MACRO1(n) ((n) - (n) / 8 * 8) + 64 * ((n) / 8) - -static void sub_8043D5C(struct Sprite *); -static const void *sub_8043CDC(u8); -/*static*/ void sub_8044210(u8, s16, u8); -/*static*/ void draw_status_ailment_maybe(u8); -extern void sub_8045180(struct Sprite *); -static void sub_8045110(struct Sprite *); -static void sub_8045048(struct Sprite *); -static void sub_8044F70(u8 taskId); -static void sub_8044E74(u8 taskId); -static void sub_8044ECC(u8 taskId); -static u8 sub_80457E8(u8, u8); -static int sub_8045F58(s32, s32, int, int *, u8, u16); -static u8 GetScaledExpFraction(int, int, int, u8); -static void sub_8045D58(u8, u8); -static u8 sub_804602C(int, int, int, int *, u8 *, u8); -static void sub_8046128(struct BattleInterfaceStruct1 *a, int *b, u16 *c); - -static int do_nothing(s16 unused1, s16 unused2, int unused3) -{ - return 9; -} - -#ifdef NONMATCHING -void sub_8043740(s16 a, u16 *b, u8 c) -{ - u8 sp0[4]; - s8 i; - s8 j; - s32 r9; - - for (i = 0; i < 4; i++) - sp0[i] = 0; - - //_0804377C - //i = 3; - //r9 = -1; - for (i = 3, r9 = -1;;) - { - if (a > 0) - { - sp0[i] = a % 10; - a /= 10; - i--; - } - else - break; - asm(""::"r"(r9)); - } - - //_080437AA - for (; i > r9; i--) - { - //asm("":"=r"(r9)); - sp0[i] = -1; - } - //_080437CE - if (sp0[3] == 0xFF) - sp0[3] = 0; - - //_080437DA - if (c == 0) - { - for (i = 0, j = 0; i < 4; i++) - { - if (sp0[j] == 0xFF) - { - b[j] = (b[j] & 0xFC00) | 0x1E; - b[i + 0x20] = (b[i + 0x20] & 0xFC00) | 0x1E; - } - else - { - b[j] = (b[j] & 0xFC00) | (sp0[j] + 0x14); - b[i + 0x20] = (b[i + 0x20] & 0xFC00) | (sp0[i] + 0x34); - } - j++; - } - - } - //_0804386A - else - { - for (i = 0; i < 4; i++) - { - if (sp0[i] == 0xFF) - { - b[i] = (b[i] & 0xFC00) | 0x1E; - b[i + 0x20] = (b[i + 0x20] & 0xFC00) | 0x1E; - } - else - { - b[i] = (b[i] & 0xFC00) | (sp0[i] + 0x14); - b[i + 0x20] = (b[i + 0x20] & 0xFC00) | (sp0[i] + 0x34); - } - } - } - asm(""::"r"(r9)); -} -#else -NAKED -void sub_8043740(s16 a, u16 *b, u8 c) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x4\n\ - adds r7, r1, 0\n\ - lsls r0, 16\n\ - lsrs r5, r0, 16\n\ - lsls r2, 24\n\ - lsrs r2, 24\n\ - mov r10, r2\n\ - movs r3, 0\n\ - movs r2, 0\n\ -_0804375C:\n\ - lsls r0, r3, 24\n\ - asrs r0, 24\n\ - mov r3, sp\n\ - adds r1, r3, r0\n\ - strb r2, [r1]\n\ - adds r0, 0x1\n\ - lsls r0, 24\n\ - lsrs r3, r0, 24\n\ - asrs r0, 24\n\ - cmp r0, 0x3\n\ - ble _0804375C\n\ - movs r3, 0x3\n\ - movs r0, 0x1\n\ - negs r0, r0\n\ - mov r9, r0\n\ - mov r8, sp\n\ -_0804377C:\n\ - lsls r0, r5, 16\n\ - asrs r6, r0, 16\n\ - cmp r6, 0\n\ - ble _080437AA\n\ - lsls r4, r3, 24\n\ - asrs r4, 24\n\ - mov r1, sp\n\ - adds r5, r1, r4\n\ - adds r0, r6, 0\n\ - movs r1, 0xA\n\ - bl __modsi3\n\ - strb r0, [r5]\n\ - adds r0, r6, 0\n\ - movs r1, 0xA\n\ - bl __divsi3\n\ - lsls r0, 16\n\ - lsrs r5, r0, 16\n\ - subs r4, 0x1\n\ - lsls r4, 24\n\ - lsrs r3, r4, 24\n\ - b _0804377C\n\ -_080437AA:\n\ - lsls r1, r3, 24\n\ - asrs r0, r1, 24\n\ - cmp r0, r9\n\ - ble _080437CE\n\ - movs r4, 0xFF\n\ - movs r3, 0x1\n\ - negs r3, r3\n\ -_080437B8:\n\ - asrs r2, r1, 24\n\ - mov r5, sp\n\ - adds r1, r5, r2\n\ - ldrb r0, [r1]\n\ - orrs r0, r4\n\ - strb r0, [r1]\n\ - subs r2, 0x1\n\ - lsls r1, r2, 24\n\ - asrs r0, r1, 24\n\ - cmp r0, r3\n\ - bgt _080437B8\n\ -_080437CE:\n\ - mov r1, r8\n\ - ldrb r0, [r1, 0x3]\n\ - cmp r0, 0xFF\n\ - bne _080437DA\n\ - movs r0, 0\n\ - strb r0, [r1, 0x3]\n\ -_080437DA:\n\ - mov r2, r10\n\ - cmp r2, 0\n\ - bne _0804386A\n\ - movs r3, 0\n\ - movs r1, 0\n\ - movs r6, 0xFC\n\ - lsls r6, 8\n\ - movs r5, 0x1E\n\ - mov r12, r5\n\ -_080437EC:\n\ - lsls r1, 24\n\ - asrs r2, r1, 24\n\ - mov r0, sp\n\ - adds r5, r0, r2\n\ - ldrb r0, [r5]\n\ - mov r8, r1\n\ - cmp r0, 0xFF\n\ - bne _08043822\n\ - lsls r1, r2, 1\n\ - adds r1, r7\n\ - ldrh r2, [r1]\n\ - adds r0, r6, 0\n\ - ands r0, r2\n\ - mov r2, r12\n\ - orrs r0, r2\n\ - strh r0, [r1]\n\ - lsls r3, 24\n\ - asrs r1, r3, 23\n\ - adds r1, r7\n\ - adds r1, 0x40\n\ - ldrh r2, [r1]\n\ - adds r0, r6, 0\n\ - ands r0, r2\n\ - mov r5, r12\n\ - orrs r0, r5\n\ - strh r0, [r1]\n\ - b _08043852\n\ -_08043822:\n\ - lsls r2, 1\n\ - adds r2, r7\n\ - ldrh r0, [r2]\n\ - adds r1, r6, 0\n\ - ands r1, r0\n\ - ldrb r0, [r5]\n\ - adds r0, 0x14\n\ - orrs r1, r0\n\ - strh r1, [r2]\n\ - lsls r4, r3, 24\n\ - asrs r3, r4, 24\n\ - lsls r2, r3, 1\n\ - adds r2, r7\n\ - adds r2, 0x40\n\ - ldrh r0, [r2]\n\ - adds r1, r6, 0\n\ - ands r1, r0\n\ - mov r5, sp\n\ - adds r0, r5, r3\n\ - ldrb r0, [r0]\n\ - adds r0, 0x34\n\ - orrs r1, r0\n\ - strh r1, [r2]\n\ - adds r3, r4, 0\n\ -_08043852:\n\ - movs r0, 0x80\n\ - lsls r0, 17\n\ - add r0, r8\n\ - lsrs r1, r0, 24\n\ - movs r2, 0x80\n\ - lsls r2, 17\n\ - adds r0, r3, r2\n\ - lsrs r3, r0, 24\n\ - asrs r0, 24\n\ - cmp r0, 0x3\n\ - ble _080437EC\n\ - b _080438CE\n\ -_0804386A:\n\ - movs r3, 0\n\ - movs r4, 0xFC\n\ - lsls r4, 8\n\ - movs r6, 0x1E\n\ -_08043872:\n\ - lsls r1, r3, 24\n\ - asrs r2, r1, 24\n\ - mov r3, sp\n\ - adds r5, r3, r2\n\ - ldrb r0, [r5]\n\ - adds r3, r1, 0\n\ - cmp r0, 0xFF\n\ - bne _0804389E\n\ - lsls r1, r2, 1\n\ - adds r1, r7\n\ - ldrh r2, [r1]\n\ - adds r0, r4, 0\n\ - ands r0, r2\n\ - orrs r0, r6\n\ - strh r0, [r1]\n\ - adds r1, 0x40\n\ - ldrh r2, [r1]\n\ - adds r0, r4, 0\n\ - ands r0, r2\n\ - orrs r0, r6\n\ - strh r0, [r1]\n\ - b _080438C0\n\ -_0804389E:\n\ - lsls r2, 1\n\ - adds r2, r7\n\ - ldrh r0, [r2]\n\ - adds r1, r4, 0\n\ - ands r1, r0\n\ - ldrb r0, [r5]\n\ - adds r0, 0x14\n\ - orrs r1, r0\n\ - strh r1, [r2]\n\ - adds r2, 0x40\n\ - ldrh r0, [r2]\n\ - adds r1, r4, 0\n\ - ands r1, r0\n\ - ldrb r0, [r5]\n\ - adds r0, 0x34\n\ - orrs r1, r0\n\ - strh r1, [r2]\n\ -_080438C0:\n\ - movs r5, 0x80\n\ - lsls r5, 17\n\ - adds r0, r3, r5\n\ - lsrs r3, r0, 24\n\ - asrs r0, 24\n\ - cmp r0, 0x3\n\ - ble _08043872\n\ -_080438CE:\n\ - add sp, 0x4\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .syntax divided\n"); -} -#endif - -void unref_sub_80438E0(s16 a, s16 b, u16 *c) -{ - c[4] = 0x1E; - sub_8043740(b, c, 0); - sub_8043740(a, c + 5, 1); -} - -u8 battle_make_oam_normal_battle(u8 a) -{ - int sp0 = 0; - u8 spriteId1; - u8 spriteId2; - u8 spriteId3; - struct Sprite *sprite; - - if (!IsDoubleBattle()) - { - if (GetBattlerSide(a) == 0) - { - spriteId1 = CreateSprite(&gSpriteTemplates_820A4EC[0], 240, 160, 1); - spriteId2 = CreateSpriteAtEnd(&gSpriteTemplates_820A4EC[0], 240, 160, 1); - - gSprites[spriteId1].oam.shape = 0; - gSprites[spriteId2].oam.shape = 0; - gSprites[spriteId2].oam.tileNum += 64; - } - else - { - spriteId1 = CreateSprite(&gSpriteTemplates_820A51C[0], 240, 160, 1); - spriteId2 = CreateSpriteAtEnd(&gSpriteTemplates_820A51C[0], 240, 160, 1); - - gSprites[spriteId2].oam.tileNum += 32; - sp0 = 2; - } - //_080439F2 - - gSprites[spriteId1].oam.affineParam = spriteId2; - gSprites[spriteId2].data[5] = spriteId1; - gSprites[spriteId2].callback = sub_8043D5C; - } - //_08043A28 - else - { - if (GetBattlerSide(a) == 0) - { - spriteId1 = CreateSprite(&gSpriteTemplates_820A4EC[GetBattlerPosition(a) / 2], 240, 160, 1); - spriteId2 = CreateSpriteAtEnd(&gSpriteTemplates_820A4EC[GetBattlerPosition(a) / 2], 240, 160, 1); - - gSprites[spriteId1].oam.affineParam = spriteId2; - gSprites[spriteId2].data[5] = spriteId1; - gSprites[spriteId2].oam.tileNum += 32; - gSprites[spriteId2].callback = sub_8043D5C; - sp0 = 1; - } - //_08043ACC - else - { - spriteId1 = CreateSprite(&gSpriteTemplates_820A51C[GetBattlerPosition(a) / 2], 240, 160, 1); - spriteId2 = CreateSpriteAtEnd(&gSpriteTemplates_820A51C[GetBattlerPosition(a) / 2], 240, 160, 1); - - gSprites[spriteId1].oam.affineParam = spriteId2; - gSprites[spriteId2].data[5] = spriteId1; - gSprites[spriteId2].oam.tileNum += 32; - gSprites[spriteId2].callback = sub_8043D5C; - sp0 = 2; - } - //_08043B4E - } - //_08043B50 - - spriteId3 = CreateSpriteAtEnd(&gSpriteTemplates_820A56C[gBanksBySide[a]], 140, 60, 0); - sprite = &gSprites[spriteId3]; - SetSubspriteTables(sprite, &gSubspriteTables_820A684[GetBattlerSide(a)]); - sprite->subspriteMode = 2; - sprite->oam.priority = 1; - CpuCopy32(sub_8043CDC(1), OBJ_VRAM0 + sprite->oam.tileNum * 32, 64); - - gSprites[spriteId1].data[5] = spriteId3; - gSprites[spriteId1].data[6] = a; - gSprites[spriteId1].invisible = TRUE; - gSprites[spriteId2].invisible = TRUE; - sprite->data[5] = spriteId1; - sprite->data[6] = sp0; - sprite->invisible = TRUE; - - return spriteId1; -} - -u8 battle_make_oam_safari_battle(void) -{ - u8 spriteId1 = CreateSprite(&gSpriteTemplate_820A54C, 240, 160, 1); - u8 spriteId2 = CreateSpriteAtEnd(&gSpriteTemplate_820A54C, 240, 160, 1); - - gSprites[spriteId1].oam.shape = 0; - gSprites[spriteId2].oam.shape = 0; - gSprites[spriteId2].oam.tileNum += 0x40; - gSprites[spriteId1].oam.affineParam = spriteId2; - gSprites[spriteId2].data[5] = spriteId1; - gSprites[spriteId2].callback = sub_8043D5C; - return spriteId1; -} - -static const void *sub_8043CDC(u8 a) -{ - return gHealthboxElementsGfxTable[a]; -} - -static void sub_8043CEC(struct Sprite *sprite) -{ - u8 r5 = sprite->data[5]; - - switch (sprite->data[6]) - { - case 0: - sprite->pos1.x = gSprites[r5].pos1.x + 16; - sprite->pos1.y = gSprites[r5].pos1.y; - break; - case 1: - sprite->pos1.x = gSprites[r5].pos1.x + 16; - sprite->pos1.y = gSprites[r5].pos1.y; - break; - default: - case 2: - sprite->pos1.x = gSprites[r5].pos1.x + 8; - sprite->pos1.y = gSprites[r5].pos1.y; - break; - } - sprite->pos2.x = gSprites[r5].pos2.x; - sprite->pos2.y = gSprites[r5].pos2.y; -} - -static void sub_8043D5C(struct Sprite *sprite) -{ - u8 data5 = sprite->data[5]; - - sprite->pos1.x = gSprites[data5].pos1.x + 64; - sprite->pos1.y = gSprites[data5].pos1.y; - sprite->pos2.x = gSprites[data5].pos2.x; - sprite->pos2.y = gSprites[data5].pos2.y; -} - -void sub_8043D84(u8 a, u8 b, u32 c, u32 d, u32 e) -{ - ewram17850[a].unk0 = b; - ewram17850[a].unk4 = c; - ewram17850[a].unk8 = d; - ewram17850[a].unkC = e; - ewram17850[a].unk10 = 0xFFFF8000; -} - -void sub_8043DB0(u8 a) -{ - gSprites[a].invisible = TRUE; - gSprites[gSprites[a].data[5]].invisible = TRUE; - gSprites[gSprites[a].oam.affineParam].invisible = TRUE; -} - -void sub_8043DFC(u8 a) -{ - gSprites[a].invisible = FALSE; - gSprites[gSprites[a].data[5]].invisible = FALSE; - gSprites[gSprites[a].oam.affineParam].invisible = FALSE; -} - -static void sub_8043E50(u8 spriteId, s16 x, s16 y) -{ - gSprites[spriteId].pos1.x = x; - gSprites[spriteId].pos1.y = y; -} - -void unref_sub_8043E70(u8 a) -{ - DestroySprite(&gSprites[gSprites[a].oam.affineParam]); - DestroySprite(&gSprites[gSprites[a].data[5]]); - DestroySprite(&gSprites[a]); -} - -void nullsub_11() -{ -} - -void UpdateOamPriorityInAllHealthboxes(u8 priority) -{ - s32 i; - - for (i = 0; i < gBattlersCount; i++) - { - u8 spriteId1; - u8 spriteId2; - u8 spriteId3; - - spriteId1 = gHealthboxIDs[i]; - spriteId2 = gSprites[spriteId1].oam.affineParam; - spriteId3 = gSprites[spriteId1].data[5]; - gSprites[spriteId1].oam.priority = priority; - gSprites[spriteId2].oam.priority = priority; - gSprites[spriteId3].oam.priority = priority; - } -} - -void sub_8043F44(u8 a) -{ - s16 x = 0; - s16 y = 0; - - if (!IsDoubleBattle()) - { - if (GetBattlerSide(a) != 0) - { - x = 44; - y = 30; - } - else - { - x = 158; - y = 88; - } - } - else - { - switch (GetBattlerPosition(a)) - { - case 0: - x = 159; - y = 77; - break; - case 2: - x = 171; - y = 102; - break; - case 1: - x = 44; - y = 19; - break; - case 3: - x = 32; - y = 44; - break; - } - } - sub_8043E50(gHealthboxIDs[a], x, y); -} - -#if ENGLISH -#define CHAR_LV_SEPARATOR CHAR_COLON -#elif GERMAN -#define CHAR_LV_SEPARATOR CHAR_PERIOD -#endif - -/*static*/ void sub_8043FC0(u8 a, u8 b) -{ - u8 str[30]; - u8 *const *r7; - u8 *ptr; - s32 i; - s32 two; - - // TODO: Make this a local variable - memcpy(str, gUnknown_0820A81C, sizeof(str)); - if (!IsDoubleBattle()) - { - if (GetBattlerSide(gSprites[a].data[6]) == 0) - r7 = gUnknown_0820A804; - else - r7 = gUnknown_0820A80C; - } - else - { - if (GetBattlerSide(gSprites[a].data[6]) == 0) - r7 = gUnknown_0820A814; - else - r7 = gUnknown_0820A80C; - } - - ptr = str + 6; - if (b == 100) - { - ptr = ConvertIntToDecimalStringN(ptr, 100, 0, 3); - } - else - { - *(ptr++) = EXT_CTRL_CODE_BEGIN; - *(ptr++) = 0x11; - *(ptr++) = 1; - *(ptr++) = EXT_CTRL_CODE_BEGIN; - *(ptr++) = 0x14; - *(ptr++) = 4; - *(ptr++) = CHAR_LV_SEPARATOR; - *(ptr++) = EXT_CTRL_CODE_BEGIN; - *(ptr++) = 0x14; - *(ptr++) = 0; - ptr = ConvertIntToDecimalStringN(ptr, b, 0, 2); - } - - *(ptr++) = EXT_CTRL_CODE_BEGIN; - *(ptr++) = 0x13; - *(ptr++) = 0xF; - *(ptr++) = EOS; - sub_80034D4(ewram0_9(0), str); - - two = 2; - for (i = 0; i < two; i++) - CpuCopy32((void *)(ewram0_9(1) + i * 64), r7[i] + gSprites[a].oam.tileNum * 32, 32); -} - -#ifdef NONMATCHING -void sub_80440EC(u8 a, s16 b, u8 c) -{ - u8 str[0x14]; - u8 *ptr; - s32 foo; - u8 *const *r4; - s32 i; - - // TODO: make this a local variable - memcpy(str, gUnknown_0820A864, sizeof(str)); - foo = gSprites[a].data[6]; - - if (IsDoubleBattle() == TRUE || GetBattlerSide(foo) == 1) - { - //_08044136 - sub_8044210(a, b, c); - return; - } - // - ptr = str + 6; - if (c == 0) - { - if (GetBattlerSide(gSprites[a].data[6]) == 0) - r4 = gUnknown_0820A83C; - else - r4 = gUnknown_0820A848; - c = 3; - ptr = sub_8003504(ptr, b, 0x13, 1); - *(ptr++) = 0xBA; - *(ptr++) = 0xFF; - sub_80034D4(ewram0_9(0), str); - } - else - { - if (GetBattlerSide(gSprites[a].data[6]) == 0) - r4 = gUnknown_0820A854; - else - r4 = gUnknown_0820A85C; - c = 2; - sub_8003504(ptr, b, 0xF, 1); - sub_80034D4(ewram0_9(0), str); - } - //asm(""::"r"(a)); - //_080441B6 - for (i = 0; i < c; i++) // _080440BC - { - void *temp = r4[i] + gSprites[a].oam.tileNum * 32; - CpuCopy32((void *)(ewram0_9(1) + i * 0x40), temp, 0x20); - } -} -#else -NAKED -void sub_80440EC(u8 a, s16 b, u8 c) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r8\n\ - push {r7}\n\ - sub sp, 0x14\n\ - lsls r0, 24\n\ - lsrs r7, r0, 24\n\ - lsls r1, 16\n\ - lsrs r6, r1, 16\n\ - lsls r2, 24\n\ - lsrs r2, 24\n\ - mov r8, r2\n\ - ldr r1, _08044144 @ =gUnknown_0820A864\n\ - mov r0, sp\n\ - movs r2, 0x14\n\ - bl memcpy\n\ - ldr r1, _08044148 @ =gSprites\n\ - lsls r0, r7, 4\n\ - adds r0, r7\n\ - lsls r0, 2\n\ - adds r4, r0, r1\n\ - movs r0, 0x3A\n\ - ldrsh r5, [r4, r0]\n\ - bl IsDoubleBattle\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0x1\n\ - beq _08044136\n\ - lsls r0, r5, 24\n\ - lsrs r0, 24\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0x1\n\ - bne _0804414C\n\ -_08044136:\n\ - lsls r1, r6, 16\n\ - asrs r1, 16\n\ - adds r0, r7, 0\n\ - mov r2, r8\n\ - bl sub_8044210\n\ - b _080441F0\n\ - .align 2, 0\n\ -_08044144: .4byte gUnknown_0820A864\n\ -_08044148: .4byte gSprites\n\ -_0804414C:\n\ - mov r5, sp\n\ - adds r5, 0x6\n\ - mov r0, r8\n\ - cmp r0, 0\n\ - bne _08044190\n\ - ldrh r0, [r4, 0x3A]\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - ldr r4, _08044188 @ =gUnknown_0820A848\n\ - cmp r0, 0\n\ - bne _0804416A\n\ - ldr r4, _0804418C @ =gUnknown_0820A83C\n\ -_0804416A:\n\ - movs r0, 0x3\n\ - mov r8, r0\n\ - lsls r1, r6, 16\n\ - asrs r1, 16\n\ - adds r0, r5, 0\n\ - movs r2, 0x13\n\ - movs r3, 0x1\n\ - bl sub_8003504\n\ - adds r5, r0, 0\n\ - movs r0, 0xBA\n\ - strb r0, [r5]\n\ - movs r0, 0xFF\n\ - strb r0, [r5, 0x1]\n\ - b _080441B6\n\ - .align 2, 0\n\ -_08044188: .4byte gUnknown_0820A848\n\ -_0804418C: .4byte gUnknown_0820A83C\n\ -_08044190:\n\ - ldrh r0, [r4, 0x3A]\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - ldr r4, _080441FC @ =gUnknown_0820A85C\n\ - cmp r0, 0\n\ - bne _080441A4\n\ - ldr r4, _08044200 @ =gUnknown_0820A854\n\ -_080441A4:\n\ - movs r0, 0x2\n\ - mov r8, r0\n\ - lsls r1, r6, 16\n\ - asrs r1, 16\n\ - adds r0, r5, 0\n\ - movs r2, 0xF\n\ - movs r3, 0x1\n\ - bl sub_8003504\n\ -_080441B6:\n\ - movs r0, 0x80\n\ - lsls r0, 18\n\ - mov r1, sp\n\ - bl sub_80034D4\n\ - mov r0, r8\n\ - cmp r0, 0\n\ - beq _080441F0\n\ - ldr r1, _08044204 @ =gSprites\n\ - lsls r0, r7, 4\n\ - adds r0, r7\n\ - lsls r0, 2\n\ - adds r6, r0, r1\n\ - adds r7, r4, 0\n\ - ldr r5, _08044208 @ =gSharedMem + 0x20\n\ - mov r4, r8\n\ -_080441D6:\n\ - ldrh r0, [r6, 0x4]\n\ - lsls r0, 22\n\ - lsrs r0, 17\n\ - ldm r7!, {r1}\n\ - adds r1, r0\n\ - adds r0, r5, 0\n\ - ldr r2, _0804420C @ =REG_BG0CNT\n\ - bl CpuSet\n\ - adds r5, 0x40\n\ - subs r4, 0x1\n\ - cmp r4, 0\n\ - bne _080441D6\n\ -_080441F0:\n\ - add sp, 0x14\n\ - pop {r3}\n\ - mov r8, r3\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_080441FC: .4byte gUnknown_0820A85C\n\ -_08044200: .4byte gUnknown_0820A854\n\ -_08044204: .4byte gSprites\n\ -_08044208: .4byte gSharedMem + 0x20\n\ -_0804420C: .4byte 0x04000008\n\ - .syntax divided\n"); -} -#endif - -/*static*/ void sub_8044210(u8 a, s16 b, u8 c) -{ - u8 str[0x14]; - u8 *ptr; - u8 *const *r7; - int r10; - int r4; - int i; - - // TODO: make this a local variable - memcpy(str, gUnknown_0820A89C, sizeof(str)); - r4 = gSprites[a].data[6]; - if ((ewram17800[r4].unk0_4) == 0) - return; - ptr = str + 6; - if (c == 0) - { - r7 = gUnknown_0820A87C; - r10 = 6; - ptr = sub_8003504(ptr, b, 0x2B, 1); - *(ptr++) = CHAR_SLASH; - *(ptr++) = EOS; - } - else - { - r7 = gUnknown_0820A894; - r10 = 2; - sub_8003504(ptr, b, 0xF, 1); - if (GetBattlerSide(r4) == 0) - { - CpuCopy32(sub_8043CDC(0x74), OBJ_VRAM0 + (gSprites[a].oam.tileNum + 0x34) * 32, 32); - } - } - r4 = gSprites[a].data[5]; - sub_80034D4(ewram0_9(0), str); - for (i = 0; i < r10; i++) - { - CpuCopy32((void *)(ewram0_9(1) + i * 0x40), r7[i] + gSprites[r4].oam.tileNum * 32, 32); - } -} - -#ifdef NONMATCHING -void sub_8044338(u8 a, struct Pokemon *pkmn) -{ - u8 str[0x14]; - u8 *r6; - s32 r8; - u8 nature; // = GetNature(pkmn); - s32 r7; - u8 i; - u8 r5; - - // TODO: make this a local variable - memcpy(str, gUnknown_0820A864, sizeof(str)); - r6 = ewram520[GetBattlerPosition(gSprites[a].data[6])].filler0; - r8 = 5; - nature = GetNature(pkmn); - StringCopy(str + 6, gNatureNames[nature]); - sub_80034D4(r6, str); - r7 = 6; - for (i = 0; i < (u32)r8; i++, r7++) //_080443AA - { - u8 val; - - if ((u8)(str[r7] - 0x37) <= 0x13 || (u8)(str[r7] + 0x79) <= 0x13) - val = 0x2C; - //_080443DC - else if ((u8)(str[r7] - 0x4B) <= 4 || (u8)(str[r7] + 0x65) <= 4) - val = 0x2D; - else - val = 0x2B; - - CpuCopy32(sub_8043CDC(val), r6 + i * 64, 32); - } - //r7 = 1; - //sp18 = a * 16; - for (r7 = 1; r7 < r8 + 1; r7++) - { - int foo; - - foo = gSprites[a].oam.tileNum + MACRO1(r7); - CpuCopy32(r6, (u8 *)0x06010000 + foo * 32, 32); - r6 += 32; - - foo = gSprites[a].oam.tileNum + 8 + MACRO1(r7); - CpuCopy32(r6, (u8 *)0x06010000 + foo * 32, 32); - r6 += 32; - } - //_08044486 - r5 = gSprites[a].data[5]; - ConvertIntToDecimalStringN(str + 6, ewram16089, 1, 2); - ConvertIntToDecimalStringN(str + 9, ewram16088, 1, 2); - str[5] = 0; - str[8] = 0xBA; - sub_80034D4(ewram0_9(0), str); - - for (r7 = 0; r7 < 5; r7++) - { - if (r7 <= 1) - { - int foo = (gSprites[r5].oam.tileNum + 2 + r7); - CpuCopy32(ewram0_9(1) + r7 * 0x40, (u8 *)0x06010000 + foo * 32, 32); - } - else - { - int foo = (r7 + gSprites[r5].oam.tileNum); - CpuCopy32(ewram0_9(1) + r7 * 0x40, (u8 *)0x060100C0 + foo * 32, 32); - } - } -} -#else -NAKED -void sub_8044338(u8 a, struct Pokemon *pkmn) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x20\n\ - adds r4, r1, 0\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - str r0, [sp, 0x14]\n\ - ldr r1, _080443CC @ =gUnknown_0820A864\n\ - mov r0, sp\n\ - movs r2, 0x14\n\ - bl memcpy\n\ - ldr r1, _080443D0 @ =gSprites\n\ - ldr r2, [sp, 0x14]\n\ - lsls r0, r2, 4\n\ - adds r0, r2\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - ldrh r0, [r0, 0x3A]\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - bl GetBattlerPosition\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - lsls r1, r0, 1\n\ - adds r1, r0\n\ - lsls r1, 7\n\ - ldr r3, _080443D4 @ =gSharedMem + 0x520\n\ - adds r6, r1, r3\n\ - movs r0, 0x5\n\ - mov r8, r0\n\ - adds r0, r4, 0\n\ - bl GetNature\n\ - lsls r0, 24\n\ - mov r4, sp\n\ - adds r4, 0x6\n\ - ldr r1, _080443D8 @ =gNatureNames\n\ - lsrs r0, 22\n\ - adds r0, r1\n\ - ldr r1, [r0]\n\ - adds r0, r4, 0\n\ - bl StringCopy\n\ - adds r0, r6, 0\n\ - mov r1, sp\n\ - bl sub_80034D4\n\ - movs r7, 0x6\n\ - movs r5, 0\n\ - mov r1, sp\n\ - adds r1, 0x9\n\ - str r1, [sp, 0x1C]\n\ -_080443AA:\n\ - mov r2, sp\n\ - adds r0, r2, r7\n\ - ldrb r1, [r0]\n\ - adds r0, r1, 0\n\ - subs r0, 0x37\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0x13\n\ - bls _080443C8\n\ - adds r0, r1, 0\n\ - adds r0, 0x79\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0x13\n\ - bhi _080443DC\n\ -_080443C8:\n\ - movs r0, 0x2C\n\ - b _080443FA\n\ - .align 2, 0\n\ -_080443CC: .4byte gUnknown_0820A864\n\ -_080443D0: .4byte gSprites\n\ -_080443D4: .4byte gSharedMem + 0x520\n\ -_080443D8: .4byte gNatureNames\n\ -_080443DC:\n\ - adds r0, r1, 0\n\ - subs r0, 0x4B\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0x4\n\ - bls _080443F4\n\ - adds r0, r1, 0\n\ - adds r0, 0x65\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0x4\n\ - bhi _080443F8\n\ -_080443F4:\n\ - movs r0, 0x2D\n\ - b _080443FA\n\ -_080443F8:\n\ - movs r0, 0x2B\n\ -_080443FA:\n\ - bl sub_8043CDC\n\ - lsls r1, r5, 6\n\ - adds r1, r6, r1\n\ - ldr r2, _080444F8 @ =REG_BG0CNT\n\ - bl CpuSet\n\ - adds r0, r5, 0x1\n\ - lsls r0, 24\n\ - lsrs r5, r0, 24\n\ - adds r7, 0x1\n\ - cmp r5, r8\n\ - bcc _080443AA\n\ - movs r7, 0x1\n\ - ldr r3, [sp, 0x14]\n\ - lsls r3, 4\n\ - str r3, [sp, 0x18]\n\ - movs r0, 0x1\n\ - add r0, r8\n\ - mov r9, r0\n\ - cmp r7, r9\n\ - bge _08044486\n\ - ldr r1, _080444FC @ =gSprites\n\ - ldr r2, _080444F8 @ =REG_BG0CNT\n\ - mov r10, r2\n\ - ldr r2, [sp, 0x14]\n\ - adds r0, r3, r2\n\ - lsls r0, 2\n\ - adds r0, r1\n\ - mov r8, r0\n\ -_08044436:\n\ - mov r3, r8\n\ - ldrh r0, [r3, 0x4]\n\ - lsls r0, 22\n\ - lsrs r0, 22\n\ - adds r5, r7, 0\n\ - cmp r7, 0\n\ - bge _08044446\n\ - adds r5, r7, 0x7\n\ -_08044446:\n\ - asrs r5, 3\n\ - lsls r4, r5, 3\n\ - subs r4, r7, r4\n\ - adds r0, r4\n\ - lsls r5, 6\n\ - adds r0, r5\n\ - lsls r0, 5\n\ - ldr r2, _08044500 @ =0x06010000\n\ - adds r1, r0, r2\n\ - adds r0, r6, 0\n\ - mov r2, r10\n\ - bl CpuSet\n\ - adds r6, 0x20\n\ - mov r3, r8\n\ - ldrh r0, [r3, 0x4]\n\ - lsls r0, 22\n\ - lsrs r0, 22\n\ - adds r4, 0x8\n\ - adds r0, r4\n\ - adds r0, r5\n\ - lsls r0, 5\n\ - ldr r2, _08044500 @ =0x06010000\n\ - adds r1, r0, r2\n\ - adds r0, r6, 0\n\ - mov r2, r10\n\ - bl CpuSet\n\ - adds r6, 0x20\n\ - adds r7, 0x1\n\ - cmp r7, r9\n\ - blt _08044436\n\ -_08044486:\n\ - ldr r6, _080444FC @ =gSprites\n\ - ldr r3, [sp, 0x18]\n\ - ldr r1, [sp, 0x14]\n\ - adds r0, r3, r1\n\ - lsls r0, 2\n\ - adds r0, r6\n\ - ldrh r5, [r0, 0x38]\n\ - lsls r5, 24\n\ - lsrs r5, 24\n\ - ldr r4, _08044504 @ =gSharedMem\n\ - ldr r2, _08044508 @ =0x00016089\n\ - adds r0, r4, r2\n\ - ldrb r1, [r0]\n\ - mov r0, sp\n\ - adds r0, 0x6\n\ - movs r2, 0x1\n\ - movs r3, 0x2\n\ - bl ConvertIntToDecimalStringN\n\ - ldr r3, _0804450C @ =0x00016088\n\ - adds r4, r3\n\ - ldrb r1, [r4]\n\ - ldr r0, [sp, 0x1C]\n\ - movs r2, 0x1\n\ - movs r3, 0x2\n\ - bl ConvertIntToDecimalStringN\n\ - mov r1, sp\n\ - movs r0, 0\n\ - strb r0, [r1, 0x5]\n\ - movs r0, 0xBA\n\ - strb r0, [r1, 0x8]\n\ - movs r0, 0x80\n\ - lsls r0, 18\n\ - bl sub_80034D4\n\ - movs r7, 0\n\ - lsls r0, r5, 4\n\ - adds r0, r5\n\ - lsls r0, 2\n\ - adds r5, r0, r6\n\ - ldr r4, _08044510 @ =gSharedMem + 0x20\n\ -_080444DA:\n\ - cmp r7, 0x1\n\ - bgt _08044514\n\ - ldrh r1, [r5, 0x4]\n\ - lsls r1, 22\n\ - lsrs r1, 22\n\ - adds r0, r7, 0x2\n\ - adds r1, r0\n\ - lsls r1, 5\n\ - ldr r0, _08044500 @ =0x06010000\n\ - adds r1, r0\n\ - adds r0, r4, 0\n\ - ldr r2, _080444F8 @ =REG_BG0CNT\n\ - bl CpuSet\n\ - b _0804452A\n\ - .align 2, 0\n\ -_080444F8: .4byte 0x04000008\n\ -_080444FC: .4byte gSprites\n\ -_08044500: .4byte 0x06010000\n\ -_08044504: .4byte gSharedMem\n\ -_08044508: .4byte 0x00016089\n\ -_0804450C: .4byte 0x00016088\n\ -_08044510: .4byte gSharedMem + 0x20\n\ -_08044514:\n\ - ldrh r1, [r5, 0x4]\n\ - lsls r1, 22\n\ - lsrs r1, 22\n\ - adds r1, r7, r1\n\ - lsls r1, 5\n\ - ldr r2, _08044544 @ =0x060100c0\n\ - adds r1, r2\n\ - adds r0, r4, 0\n\ - ldr r2, _08044548 @ =REG_BG0CNT\n\ - bl CpuSet\n\ -_0804452A:\n\ - adds r4, 0x40\n\ - adds r7, 0x1\n\ - cmp r7, 0x4\n\ - ble _080444DA\n\ - add sp, 0x20\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r0}\n\ - bx r0\n\ - .align 2, 0\n\ -_08044544: .4byte 0x060100c0\n\ -_08044548: .4byte 0x04000008\n\ - .syntax divided\n"); -} -#endif - -extern u8 gUnknown_020297ED; - -void sub_804454C(void) -{ - s32 i; - u8 spriteId; - - for (i = 0; i < gBattlersCount; i++) - { - if (gSprites[gHealthboxIDs[i]].callback == SpriteCallbackDummy -#if DEBUG - && (gUnknown_020297ED != 0 || GetBattlerSide(i) != 1) -#else - && GetBattlerSide(i) != 1 -#endif - && (IsDoubleBattle() || GetBattlerSide(i) != 0)) - { - u8 r6; - - ewram17800[i].unk0_4 ^= 1; - r6 = ewram17800[i].unk0_4; - if (GetBattlerSide(i) == 0) - { - - if (!IsDoubleBattle()) - continue; - if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) - continue; - - if (r6 == 1) - { - spriteId = gSprites[gHealthboxIDs[i]].data[5]; - - CpuFill32(0, OBJ_VRAM0 + gSprites[spriteId].oam.tileNum * 32, 0x100); - sub_8044210(gHealthboxIDs[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_HP), 0); - sub_8044210(gHealthboxIDs[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), 1); - } - else - { - draw_status_ailment_maybe(gHealthboxIDs[i]); - sub_8045A5C(gHealthboxIDs[i], &gPlayerParty[gBattlerPartyIndexes[i]], 5); - CpuCopy32(sub_8043CDC(0x75), OBJ_VRAM0 + 0x680 + gSprites[gHealthboxIDs[i]].oam.tileNum * 32, 32); - } - } - else - { - if (r6 == 1) - { - if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) - { - sub_8044338(gHealthboxIDs[i], &gEnemyParty[gBattlerPartyIndexes[i]]); - } - else - { - spriteId = gSprites[gHealthboxIDs[i]].data[5]; - - CpuFill32(0, OBJ_VRAM0 + gSprites[spriteId].oam.tileNum * 32, 0x100); - sub_8044210(gHealthboxIDs[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_HP), 0); - sub_8044210(gHealthboxIDs[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), 1); - } - } - else - { - draw_status_ailment_maybe(gHealthboxIDs[i]); - sub_8045A5C(gHealthboxIDs[i], &gEnemyParty[gBattlerPartyIndexes[i]], 5); - if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) - sub_8045A5C(gHealthboxIDs[i], &gEnemyParty[gBattlerPartyIndexes[i]], 4); - } - } - gSprites[gHealthboxIDs[i]].data[7] ^= 1; - } - } -} - -// This function almost matches except for just two instructions around 0x08044B52 that are swapped. -#ifdef NONMATCHING -u8 sub_8044804(u8 a, const struct BattleInterfaceStruct2 *b, u8 c, u8 d) -{ - u8 r7; - s16 x; - s16 y; - s16 r8; - s16 r5; - - int i; - u8 sp[6]; - s8 sp14; - u8 sp18; - u8 taskId; - - if (c == 0 || GetBattlerPosition(a) != 3) - { - if (GetBattlerSide(a) == 0) - { - r7 = 0; - x = 136; - y = 96; - r8 = 100; - r5 = -5; - } - else - { - r7 = 1; - if (c == 0 || !IsDoubleBattle()) - { - x = 104; - y = 40; - } - else - { - x = 104; - y = 16; - } - r8 = -100; - r5 = 5; - } - } - else - { - r7 = 1; - x = 104; - y = 40; - r8 = -100; - r5 = 5; - } - //_08044884 - - sp14 = 0; - for (i = 0; i < 6; i++) //_080448A0 - { - if (b[i].unk0 != 0xFFFF) - sp14++; - } - - LoadCompressedObjectPic(&gUnknown_0820A754[r7]); - LoadSpriteSheet(&gUnknown_0820A784[r7]); - LoadSpritePalette(&gUnknown_0820A764[r7]); - LoadSpritePalette(&gUnknown_0820A774[r7]); - - sp18 = CreateSprite(&gSpriteTemplate_820A7A4[r7], x, y, 10); - SetSubspriteTables(&gSprites[sp18], gSubspriteTables_820A6E4); - gSprites[sp18].pos2.x = r8; - gSprites[sp18].data[0] = r5; - if (r7 != 0) - { - gSprites[sp18].pos1.x -= 96; - gSprites[sp18].oam.matrixNum = 8; - } - else - { - gSprites[sp18].pos1.x += 0x60; - } - //_0804495A - for (i = 0; i < 6; i++) //_08044970 - { - sp[i] = CreateSpriteAtEnd(&gSpriteTemplate_820A7D4[r7], x, y - 4, 9); - if (d == 0) - { - gSprites[sp[i]].callback = sub_8045180; - } - //_080449A0 - if (r7 == 0) - { - gSprites[sp[i]].pos2.x = 0; - gSprites[sp[i]].pos2.y = 0; - } - //_080449BE - gSprites[sp[i]].data[0] = sp18; - if (r7 == 0) - { - gSprites[sp[i]].pos1.x += 10 * i + 24; - gSprites[sp[i]].data[1] = i * 7 + 10; - gSprites[sp[i]].pos2.x = 120; - } - //_08044A18 - else - { - gSprites[sp[i]].pos1.x -= 10 * (5 - i) + 24; - gSprites[sp[i]].data[1] = (6 - i) * 7 + 10; - gSprites[sp[i]].pos2.x = -120; - } - //_08044A56 - gSprites[sp[i]].data[2] = r7; - } - //_08044A76 - if (GetBattlerSide(a) == 0) - { - for (i = 0; i < 6; i++) //_08044A9A - { - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) // && b[i] != 0xFFFF && b[i] - { - if (b[i].unk0 == 0xFFFF) - { - //_08044AE6 - gSprites[sp[i]].oam.tileNum += 1; - gSprites[sp[i]].data[7] = 1; - // to _08044B52 - } - else if (b[i].unk0 == 0) - { - gSprites[sp[i]].oam.tileNum += 3; - // to _08044B46 - } - else if (b[i].unk4 != 0) - { - gSprites[sp[i]].oam.tileNum += 2; - } - } - //_08044ADC - else - { - if (i >= sp14) - { - //_08044AE6 - gSprites[sp[i]].oam.tileNum += 1; - gSprites[sp[i]].data[7] = 1; - // to _08044B52 - } - else if (b[i].unk0 == 0) - { - //_08044B14 - gSprites[sp[i]].oam.tileNum += 3; - // to _08044B46 - } - else if (b[i].unk4 != 0) - { - gSprites[sp[i]].oam.tileNum += 2; - } - } - } - } - //_08044B5E - else - { - // Mismatch occurrs in this loop initialization - for (i = 0; i < 6; i++) - { - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (b[i].unk0 == 0xFFFF) - { - gSprites[sp[5 - i]].oam.tileNum += 1; - gSprites[sp[5 - i]].data[7] = 1; - } - else if (b[i].unk0 == 0) - { - gSprites[sp[5 - i]].oam.tileNum += 3; - } - else if (b[i].unk4 != 0) - { - gSprites[sp[5 - i]].oam.tileNum += 2; - } - } - else - { - if (i >= sp14) - { - gSprites[sp[5 - i]].oam.tileNum += 1; - gSprites[sp[5 - i]].data[7] = 1; - } - else if (b[i].unk0 == 0) - { - gSprites[sp[5 - i]].oam.tileNum += 3; - } - else if (b[i].unk4 != 0) - { - gSprites[sp[5 - i]].oam.tileNum += 2; - } - } - // This corrects the initialization order, but messes up the counter update order - asm(""::"r"(&b[i])); - } - } - //_08044C38 - taskId = CreateTask(TaskDummy, 5); - gTasks[taskId].data[0] = a; - gTasks[taskId].data[1] = sp18; - for (i = 0; i < 6; i++) - gTasks[taskId].data[3 + i] = sp[i]; - gTasks[taskId].data[10] = d; - PlaySE12WithPanning(SE_TB_START, 0); - return taskId; -} -#else -NAKED -u8 sub_8044804(u8 a, const struct BattleInterfaceStruct2 *b, u8 c, u8 d) -{ - asm(".syntax unified\n\ - push {r4-r7,lr}\n\ - mov r7, r10\n\ - mov r6, r9\n\ - mov r5, r8\n\ - push {r5-r7}\n\ - sub sp, 0x28\n\ - str r1, [sp, 0xC]\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - str r0, [sp, 0x8]\n\ - lsls r2, 24\n\ - lsrs r2, 24\n\ - adds r4, r2, 0\n\ - lsls r3, 24\n\ - lsrs r3, 24\n\ - str r3, [sp, 0x10]\n\ - cmp r4, 0\n\ - beq _08044834\n\ - bl GetBattlerPosition\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - cmp r0, 0x3\n\ - beq _08044878\n\ -_08044834:\n\ - ldr r0, [sp, 0x8]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _08044854\n\ - movs r7, 0\n\ - movs r1, 0x88\n\ - movs r2, 0x60\n\ - movs r0, 0x64\n\ - mov r8, r0\n\ - ldr r5, _08044850 @ =0x0000fffb\n\ - b _08044884\n\ - .align 2, 0\n\ -_08044850: .4byte 0x0000fffb\n\ -_08044854:\n\ - movs r7, 0x1\n\ - cmp r4, 0\n\ - beq _08044864\n\ - bl IsDoubleBattle\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _0804486A\n\ -_08044864:\n\ - movs r1, 0x68\n\ - movs r2, 0x28\n\ - b _0804486E\n\ -_0804486A:\n\ - movs r1, 0x68\n\ - movs r2, 0x10\n\ -_0804486E:\n\ - ldr r3, _08044874 @ =0x0000ff9c\n\ - mov r8, r3\n\ - b _08044882\n\ - .align 2, 0\n\ -_08044874: .4byte 0x0000ff9c\n\ -_08044878:\n\ - movs r7, 0x1\n\ - movs r1, 0x68\n\ - movs r2, 0x28\n\ - ldr r5, _08044930 @ =0x0000ff9c\n\ - mov r8, r5\n\ -_08044882:\n\ - movs r5, 0x5\n\ -_08044884:\n\ - movs r6, 0\n\ - str r6, [sp, 0x14]\n\ - lsls r4, r7, 3\n\ - ldr r0, _08044934 @ =gUnknown_0820A754\n\ - mov r10, r0\n\ - lsls r3, r7, 1\n\ - mov r9, r3\n\ - lsls r1, 16\n\ - str r1, [sp, 0x20]\n\ - lsls r2, 16\n\ - str r2, [sp, 0x24]\n\ - ldr r2, _08044938 @ =0x0000ffff\n\ - ldr r1, [sp, 0xC]\n\ - movs r6, 0x5\n\ -_080448A0:\n\ - ldrh r0, [r1]\n\ - cmp r0, r2\n\ - beq _080448B4\n\ - ldr r3, [sp, 0x14]\n\ - lsls r0, r3, 24\n\ - movs r3, 0x80\n\ - lsls r3, 17\n\ - adds r0, r3\n\ - lsrs r0, 24\n\ - str r0, [sp, 0x14]\n\ -_080448B4:\n\ - adds r1, 0x8\n\ - subs r6, 0x1\n\ - cmp r6, 0\n\ - bge _080448A0\n\ - mov r6, r10\n\ - adds r0, r4, r6\n\ - bl LoadCompressedObjectPic\n\ - ldr r0, _0804493C @ =gUnknown_0820A784\n\ - adds r0, r4, r0\n\ - bl LoadSpriteSheet\n\ - ldr r0, _08044940 @ =gUnknown_0820A764\n\ - adds r0, r4, r0\n\ - bl LoadSpritePalette\n\ - ldr r0, _08044944 @ =gUnknown_0820A774\n\ - adds r0, r4, r0\n\ - bl LoadSpritePalette\n\ - mov r1, r9\n\ - adds r0, r1, r7\n\ - lsls r0, 3\n\ - ldr r1, _08044948 @ =gSpriteTemplate_820A7A4\n\ - adds r0, r1\n\ - ldr r2, [sp, 0x20]\n\ - asrs r1, r2, 16\n\ - ldr r3, [sp, 0x24]\n\ - asrs r2, r3, 16\n\ - movs r3, 0xA\n\ - bl CreateSprite\n\ - lsls r0, 24\n\ - lsrs r0, 24\n\ - str r0, [sp, 0x18]\n\ - lsls r0, 4\n\ - ldr r6, [sp, 0x18]\n\ - adds r0, r6\n\ - lsls r0, 2\n\ - ldr r1, _0804494C @ =gSprites\n\ - adds r4, r0, r1\n\ - ldr r1, _08044950 @ =gSubspriteTables_820A6E4\n\ - adds r0, r4, 0\n\ - bl SetSubspriteTables\n\ - mov r0, r8\n\ - strh r0, [r4, 0x24]\n\ - strh r5, [r4, 0x2E]\n\ - cmp r7, 0\n\ - beq _08044954\n\ - ldrh r0, [r4, 0x20]\n\ - subs r0, 0x60\n\ - strh r0, [r4, 0x20]\n\ - ldrb r1, [r4, 0x3]\n\ - movs r0, 0x3F\n\ - negs r0, r0\n\ - ands r0, r1\n\ - movs r1, 0x10\n\ - orrs r0, r1\n\ - strb r0, [r4, 0x3]\n\ - b _0804495A\n\ - .align 2, 0\n\ -_08044930: .4byte 0x0000ff9c\n\ -_08044934: .4byte gUnknown_0820A754\n\ -_08044938: .4byte 0x0000ffff\n\ -_0804493C: .4byte gUnknown_0820A784\n\ -_08044940: .4byte gUnknown_0820A764\n\ -_08044944: .4byte gUnknown_0820A774\n\ -_08044948: .4byte gSpriteTemplate_820A7A4\n\ -_0804494C: .4byte gSprites\n\ -_08044950: .4byte gSubspriteTables_820A6E4\n\ -_08044954:\n\ - ldrh r0, [r4, 0x20]\n\ - adds r0, 0x60\n\ - strh r0, [r4, 0x20]\n\ -_0804495A:\n\ - movs r6, 0\n\ - ldr r1, _08044A04 @ =gSprites\n\ - mov r10, r1\n\ - mov r4, sp\n\ - mov r2, r9\n\ - adds r0, r2, r7\n\ - lsls r0, 3\n\ - str r0, [sp, 0x1C]\n\ - movs r3, 0xA\n\ - mov r9, r3\n\ - mov r8, r6\n\ -_08044970:\n\ - ldr r0, _08044A08 @ =gSpriteTemplate_820A7D4\n\ - ldr r5, [sp, 0x24]\n\ - ldr r1, _08044A0C @ =0xfffc0000\n\ - adds r2, r5, r1\n\ - ldr r3, [sp, 0x1C]\n\ - adds r0, r3, r0\n\ - ldr r5, [sp, 0x20]\n\ - asrs r1, r5, 16\n\ - asrs r2, 16\n\ - movs r3, 0x9\n\ - bl CreateSpriteAtEnd\n\ - strb r0, [r4]\n\ - ldr r0, [sp, 0x10]\n\ - cmp r0, 0\n\ - bne _080449A0\n\ - ldrb r0, [r4]\n\ - lsls r1, r0, 4\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - ldr r2, _08044A10 @ =gSprites + 0x1C\n\ - adds r1, r2\n\ - ldr r0, _08044A14 @ =sub_8045180\n\ - str r0, [r1]\n\ -_080449A0:\n\ - ldr r5, _08044A04 @ =gSprites\n\ - cmp r7, 0\n\ - bne _080449BE\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 4\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - add r0, r10\n\ - strh r7, [r0, 0x24]\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 4\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - add r0, r10\n\ - strh r7, [r0, 0x26]\n\ -_080449BE:\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 4\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r5\n\ - movs r1, 0\n\ - mov r3, sp\n\ - ldrh r3, [r3, 0x18]\n\ - strh r3, [r0, 0x2E]\n\ - cmp r7, 0\n\ - bne _08044A18\n\ - ldrb r0, [r4]\n\ - lsls r1, r0, 4\n\ - adds r1, r0\n\ - lsls r1, 2\n\ - adds r1, r5\n\ - ldrh r0, [r1, 0x20]\n\ - adds r0, 0x18\n\ - add r0, r8\n\ - strh r0, [r1, 0x20]\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 4\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r5\n\ - mov r1, r9\n\ - strh r1, [r0, 0x30]\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 4\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r5\n\ - movs r1, 0x78\n\ - b _08044A56\n\ - .align 2, 0\n\ -_08044A04: .4byte gSprites\n\ -_08044A08: .4byte gSpriteTemplate_820A7D4\n\ -_08044A0C: .4byte 0xfffc0000\n\ -_08044A10: .4byte gSprites + 0x1C\n\ -_08044A14: .4byte sub_8045180\n\ -_08044A18:\n\ - ldrb r0, [r4]\n\ - lsls r2, r0, 4\n\ - adds r2, r0\n\ - lsls r2, 2\n\ - adds r2, r5\n\ - ldrh r3, [r2, 0x20]\n\ - subs r3, 0x18\n\ - movs r1, 0x5\n\ - subs r1, r6\n\ - lsls r0, r1, 2\n\ - adds r0, r1\n\ - lsls r0, 1\n\ - subs r3, r0\n\ - strh r3, [r2, 0x20]\n\ - ldrb r0, [r4]\n\ - lsls r2, r0, 4\n\ - adds r2, r0\n\ - lsls r2, 2\n\ - adds r2, r5\n\ - movs r1, 0x6\n\ - subs r1, r6\n\ - lsls r0, r1, 3\n\ - subs r0, r1\n\ - adds r0, 0xA\n\ - strh r0, [r2, 0x30]\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 4\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r5\n\ - ldr r1, _08044AC4 @ =0x0000ff88\n\ -_08044A56:\n\ - strh r1, [r0, 0x24]\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 4\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r5\n\ - strh r7, [r0, 0x32]\n\ - adds r4, 0x1\n\ - movs r2, 0x7\n\ - add r9, r2\n\ - movs r3, 0xA\n\ - add r8, r3\n\ - adds r6, 0x1\n\ - cmp r6, 0x5\n\ - bgt _08044A76\n\ - b _08044970\n\ -_08044A76:\n\ - ldr r0, [sp, 0x8]\n\ - bl GetBattlerSide\n\ - lsls r0, 24\n\ - cmp r0, 0\n\ - bne _08044B5E\n\ - movs r6, 0\n\ - ldr r5, _08044AC8 @ =gBattleTypeFlags\n\ - mov r10, r5\n\ - ldr r0, _08044ACC @ =0x0000ffff\n\ - mov r9, r0\n\ - ldr r7, _08044AD0 @ =gSprites\n\ - ldr r1, _08044AD4 @ =0x000003ff\n\ - mov r12, r1\n\ - ldr r2, _08044AD8 @ =0xfffffc00\n\ - mov r8, r2\n\ - mov r4, sp\n\ - ldr r5, [sp, 0xC]\n\ -_08044A9A:\n\ - mov r3, r10\n\ - ldrh r1, [r3]\n\ - movs r0, 0x40\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08044ADC\n\ - ldrh r0, [r5]\n\ - cmp r0, r9\n\ - beq _08044AE6\n\ - cmp r0, 0\n\ - bne _08044B2E\n\ - ldrb r0, [r4]\n\ - lsls r2, r0, 4\n\ - adds r2, r0\n\ - lsls r2, 2\n\ - adds r2, r7\n\ - ldrh r3, [r2, 0x4]\n\ - lsls r1, r3, 22\n\ - lsrs r1, 22\n\ - adds r1, 0x3\n\ - b _08044B46\n\ - .align 2, 0\n\ -_08044AC4: .4byte 0x0000ff88\n\ -_08044AC8: .4byte gBattleTypeFlags\n\ -_08044ACC: .4byte 0x0000ffff\n\ -_08044AD0: .4byte gSprites\n\ -_08044AD4: .4byte 0x000003ff\n\ -_08044AD8: .4byte 0xfffffc00\n\ -_08044ADC:\n\ - ldr r1, [sp, 0x14]\n\ - lsls r0, r1, 24\n\ - asrs r0, 24\n\ - cmp r6, r0\n\ - blt _08044B14\n\ -_08044AE6:\n\ - ldrb r0, [r4]\n\ - lsls r2, r0, 4\n\ - adds r2, r0\n\ - lsls r2, 2\n\ - adds r2, r7\n\ - ldrh r3, [r2, 0x4]\n\ - lsls r1, r3, 22\n\ - lsrs r1, 22\n\ - adds r1, 0x1\n\ - mov r0, r12\n\ - ands r1, r0\n\ - mov r0, r8\n\ - ands r0, r3\n\ - orrs r0, r1\n\ - strh r0, [r2, 0x4]\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 4\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r7\n\ - movs r1, 0x1\n\ - strh r1, [r0, 0x3C]\n\ - b _08044B52\n\ -_08044B14:\n\ - ldrh r0, [r5]\n\ - cmp r0, 0\n\ - bne _08044B2E\n\ - ldrb r0, [r4]\n\ - lsls r2, r0, 4\n\ - adds r2, r0\n\ - lsls r2, 2\n\ - adds r2, r7\n\ - ldrh r3, [r2, 0x4]\n\ - lsls r1, r3, 22\n\ - lsrs r1, 22\n\ - adds r1, 0x3\n\ - b _08044B46\n\ -_08044B2E:\n\ - ldr r0, [r5, 0x4]\n\ - cmp r0, 0\n\ - beq _08044B52\n\ - ldrb r0, [r4]\n\ - lsls r2, r0, 4\n\ - adds r2, r0\n\ - lsls r2, 2\n\ - adds r2, r7\n\ - ldrh r3, [r2, 0x4]\n\ - lsls r1, r3, 22\n\ - lsrs r1, 22\n\ - adds r1, 0x2\n\ -_08044B46:\n\ - mov r0, r12\n\ - ands r1, r0\n\ - mov r0, r8\n\ - ands r0, r3\n\ - orrs r0, r1\n\ - strh r0, [r2, 0x4]\n\ -_08044B52:\n\ - adds r4, 0x1\n\ - adds r5, 0x8\n\ - adds r6, 0x1\n\ - cmp r6, 0x5\n\ - ble _08044A9A\n\ - b _08044C38\n\ -_08044B5E:\n\ - movs r6, 0\n\ - ldr r1, _08044BA4 @ =gBattleTypeFlags\n\ - mov r10, r1\n\ - ldr r2, _08044BA8 @ =0x0000ffff\n\ - mov r9, r2\n\ - ldr r7, _08044BAC @ =gSprites\n\ - ldr r3, _08044BB0 @ =0x000003ff\n\ - mov r12, r3\n\ - ldr r5, _08044BB4 @ =0xfffffc00\n\ - mov r8, r5\n\ - ldr r5, [sp, 0xC]\n\ - mov r4, sp\n\ - adds r4, 0x5\n\ -_08044B78:\n\ - mov r0, r10\n\ - ldrh r1, [r0]\n\ - movs r0, 0x40\n\ - ands r0, r1\n\ - cmp r0, 0\n\ - beq _08044BB8\n\ - ldrh r0, [r5]\n\ - cmp r0, r9\n\ - beq _08044BC2\n\ - cmp r0, 0\n\ - bne _08044C0A\n\ - ldrb r0, [r4]\n\ - lsls r2, r0, 4\n\ - adds r2, r0\n\ - lsls r2, 2\n\ - adds r2, r7\n\ - ldrh r3, [r2, 0x4]\n\ - lsls r1, r3, 22\n\ - lsrs r1, 22\n\ - adds r1, 0x3\n\ - b _08044C22\n\ - .align 2, 0\n\ -_08044BA4: .4byte gBattleTypeFlags\n\ -_08044BA8: .4byte 0x0000ffff\n\ -_08044BAC: .4byte gSprites\n\ -_08044BB0: .4byte 0x000003ff\n\ -_08044BB4: .4byte 0xfffffc00\n\ -_08044BB8:\n\ - ldr r1, [sp, 0x14]\n\ - lsls r0, r1, 24\n\ - asrs r0, 24\n\ - cmp r6, r0\n\ - blt _08044BF0\n\ -_08044BC2:\n\ - ldrb r0, [r4]\n\ - lsls r2, r0, 4\n\ - adds r2, r0\n\ - lsls r2, 2\n\ - adds r2, r7\n\ - ldrh r3, [r2, 0x4]\n\ - lsls r1, r3, 22\n\ - lsrs r1, 22\n\ - adds r1, 0x1\n\ - mov r0, r12\n\ - ands r1, r0\n\ - mov r0, r8\n\ - ands r0, r3\n\ - orrs r0, r1\n\ - strh r0, [r2, 0x4]\n\ - ldrb r1, [r4]\n\ - lsls r0, r1, 4\n\ - adds r0, r1\n\ - lsls r0, 2\n\ - adds r0, r7\n\ - movs r1, 0x1\n\ - strh r1, [r0, 0x3C]\n\ - b _08044C2E\n\ -_08044BF0:\n\ - ldrh r0, [r5]\n\ - cmp r0, 0\n\ - bne _08044C0A\n\ - ldrb r0, [r4]\n\ - lsls r2, r0, 4\n\ - adds r2, r0\n\ - lsls r2, 2\n\ - adds r2, r7\n\ - ldrh r3, [r2, 0x4]\n\ - lsls r1, r3, 22\n\ - lsrs r1, 22\n\ - adds r1, 0x3\n\ - b _08044C22\n\ -_08044C0A:\n\ - ldr r0, [r5, 0x4]\n\ - cmp r0, 0\n\ - beq _08044C2E\n\ - ldrb r0, [r4]\n\ - lsls r2, r0, 4\n\ - adds r2, r0\n\ - lsls r2, 2\n\ - adds r2, r7\n\ - ldrh r3, [r2, 0x4]\n\ - lsls r1, r3, 22\n\ - lsrs r1, 22\n\ - adds r1, 0x2\n\ -_08044C22:\n\ - mov r0, r12\n\ - ands r1, r0\n\ - mov r0, r8\n\ - ands r0, r3\n\ - orrs r0, r1\n\ - strh r0, [r2, 0x4]\n\ -_08044C2E:\n\ - subs r4, 0x1\n\ - adds r5, 0x8\n\ - adds r6, 0x1\n\ - cmp r6, 0x5\n\ - ble _08044B78\n\ -_08044C38:\n\ - ldr r0, _08044C98 @ =TaskDummy\n\ - movs r1, 0x5\n\ - bl CreateTask\n\ - lsls r0, 24\n\ - lsrs r4, r0, 24\n\ - ldr r2, _08044C9C @ =gTasks\n\ - lsls r3, r4, 2\n\ - adds r1, r3, r4\n\ - lsls r1, 3\n\ - adds r0, r1, r2\n\ - mov r5, sp\n\ - ldrh r5, [r5, 0x8]\n\ - strh r5, [r0, 0x8]\n\ - mov r6, sp\n\ - ldrh r6, [r6, 0x18]\n\ - strh r6, [r0, 0xA]\n\ - movs r6, 0\n\ - adds r0, r2, 0\n\ - adds r0, 0xE\n\ - adds r1, r0\n\ -_08044C62:\n\ - mov r5, sp\n\ - adds r0, r5, r6\n\ - ldrb r0, [r0]\n\ - strh r0, [r1]\n\ - adds r1, 0x2\n\ - adds r6, 0x1\n\ - cmp r6, 0x5\n\ - ble _08044C62\n\ - adds r0, r3, r4\n\ - lsls r0, 3\n\ - adds r0, r2\n\ - ldrh r6, [r5, 0x10]\n\ - strh r6, [r0, 0x1C]\n\ - movs r0, 0x72\n\ - movs r1, 0\n\ - bl PlaySE12WithPanning\n\ - adds r0, r4, 0\n\ - add sp, 0x28\n\ - pop {r3-r5}\n\ - mov r8, r3\n\ - mov r9, r4\n\ - mov r10, r5\n\ - pop {r4-r7}\n\ - pop {r1}\n\ - bx r1\n\ - .align 2, 0\n\ -_08044C98: .4byte TaskDummy\n\ -_08044C9C: .4byte gTasks\n\ - .syntax divided\n"); -} -#endif - -void sub_8044CA0(u8 taskId) -{ - u8 sp[6]; - u8 r9; - u8 r10; - u8 sp8; - s32 i; - - r9 = gTasks[taskId].data[10]; - r10 = gTasks[taskId].data[1]; - sp8 = gTasks[taskId].data[0]; - for (i = 0; i < 6; i++) - sp[i] = gTasks[taskId].data[3 + i]; - - REG_BLDCNT = 0x3F40; - REG_BLDALPHA = 0x10; - gTasks[taskId].data[15] = 16; - for (i = 0; i < 6; i++) - gSprites[sp[i]].oam.objMode = 1; - gSprites[r10].oam.objMode = 1; - if (r9 != 0) - { - for (i = 0; i < 6; i++) - { - if (GetBattlerSide(sp8) != 0) - { - gSprites[sp[5 - i]].data[1] = 7 * i; - gSprites[sp[5 - i]].data[3] = 0; - gSprites[sp[5 - i]].data[4] = 0; - gSprites[sp[5 - i]].callback = sub_8045110; - } - else - { - gSprites[sp[i]].data[1] = 7 * i; - gSprites[sp[i]].data[3] = 0; - gSprites[sp[i]].data[4] = 0; - gSprites[sp[i]].callback = sub_8045110; - } - } - gSprites[r10].data[0] /= 2; - gSprites[r10].data[1] = 0; - gSprites[r10].callback = sub_8045048; - SetSubspriteTables(&gSprites[r10], gSubspriteTables_820A6EC); - gTasks[taskId].func = sub_8044E74; - } - else - { - gTasks[taskId].func = sub_8044F70; - } -} - -static void sub_8044E74(u8 taskId) -{ - u16 temp = gTasks[taskId].data[11]++; - - if ((temp & 1) == 0) - { - gTasks[taskId].data[15]--; - if (gTasks[taskId].data[15] < 0) - return; - REG_BLDALPHA = (gTasks[taskId].data[15]) | ((16 - gTasks[taskId].data[15]) << 8); - } - if (gTasks[taskId].data[15] == 0) - gTasks[taskId].func = sub_8044ECC; -} - -static void sub_8044ECC(u8 taskId) -{ - u8 sp[6]; - s32 i; - - gTasks[taskId].data[15]--; - if (gTasks[taskId].data[15] == -1) - { - u8 var = gTasks[taskId].data[1]; - - for (i = 0; i < 6; i++) - sp[i] = gTasks[taskId].data[3 + i]; - DestroySpriteAndFreeResources(&gSprites[var]); - DestroySpriteAndFreeResources(&gSprites[sp[0]]); - for (i = 1; i < 6; i++) - DestroySprite(&gSprites[sp[i]]); - } - else if (gTasks[taskId].data[15] == -3) - { - REG_BLDCNT = 0; - REG_BLDALPHA = 0; - DestroyTask(taskId); - } -} - -static void sub_8044F70(u8 taskId) -{ - u8 sp[6]; - s32 i; - - gTasks[taskId].data[15]--; - // Same as above function except with this check. - if (gTasks[taskId].data[15] >= 0) - { - REG_BLDALPHA = (gTasks[taskId].data[15]) | ((16 - gTasks[taskId].data[15]) << 8); - } - else if (gTasks[taskId].data[15] == -1) - { - u8 var = gTasks[taskId].data[1]; - - for (i = 0; i < 6; i++) - sp[i] = gTasks[taskId].data[3 + i]; - DestroySpriteAndFreeResources(&gSprites[var]); - DestroySpriteAndFreeResources(&gSprites[sp[0]]); - for (i = 1; i < 6; i++) - DestroySprite(&gSprites[sp[i]]); - } - else if (gTasks[taskId].data[15] == -3) - { - REG_BLDCNT = 0; - REG_BLDALPHA = 0; - DestroyTask(taskId); - } -} - -static void sub_8045030(struct Sprite *sprite) -{ - if (sprite->pos2.x != 0) - sprite->pos2.x += sprite->data[0]; -} - -static void sub_8045048(struct Sprite *sprite) -{ - sprite->data[1] += 32; - if (sprite->data[0] > 0) - sprite->pos2.x += sprite->data[1] >> 4; - else - sprite->pos2.x -= sprite->data[1] >> 4; - sprite->data[1] &= 0xF; -} - -static void sub_804507C(struct Sprite *sprite) -{ - u8 r3; - u16 r2; - s8 pan; - - if (sprite->data[1] > 0) - { - sprite->data[1]--; - return; - } - r3 = sprite->data[2]; - r2 = sprite->data[3]; - r2 += 56; - sprite->data[3] = r2 & 0xFFF0; - if (r3 != 0) - { - sprite->pos2.x += r2 >> 4; - if (sprite->pos2.x > 0) - sprite->pos2.x = 0; - } - else - { - sprite->pos2.x -= r2 >> 4; - if (sprite->pos2.x < 0) - sprite->pos2.x = 0; - } - if (sprite->pos2.x == 0) - { - pan = 63; - if (r3 != 0) - pan = -64; - if (sprite->data[7] != 0) - PlaySE2WithPanning(SE_TB_KARA, pan); - else - PlaySE1WithPanning(SE_TB_KON, pan); - sprite->callback = SpriteCallbackDummy; - } -} - -static void sub_8045110(struct Sprite *sprite) -{ - u8 r0; - u16 r2; - - if (sprite->data[1] > 0) - { - sprite->data[1]--; - return; - } - r0 = sprite->data[2]; - r2 = sprite->data[3]; - r2 += 56; - sprite->data[3] = r2 & 0xFFF0; - if (r0 != 0) - sprite->pos2.x += r2 >> 4; - else - sprite->pos2.x -= r2 >> 4; - if (sprite->pos2.x + sprite->pos1.x > 248 - || sprite->pos2.x + sprite->pos1.x < -8) - { - sprite->invisible = TRUE; - sprite->callback = SpriteCallbackDummy; - } -} - -void sub_8045180(struct Sprite *sprite) -{ - u8 spriteId = sprite->data[0]; - - sprite->pos2.x = gSprites[spriteId].pos2.x; - sprite->pos2.y = gSprites[spriteId].pos2.y; -} - -/*static*/ void sub_80451A0(u8 a, struct Pokemon *pkmn) -{ - u8 nickname[POKEMON_NAME_LENGTH]; - u8 gender; - u16 species; - u8 language; - u8 *ptr; - s32 i; - s32 _7; - u8 *const *r1; - - StringCopy(gDisplayedStringBattle, gUnknown_0820A8B0); - GetMonData(pkmn, MON_DATA_NICKNAME, nickname); - StringGetEnd10(nickname); - ptr = StringCopy(gDisplayedStringBattle + 3, nickname); - ptr[0] = EXT_CTRL_CODE_BEGIN; - ptr[1] = 3; - ptr[2] = 2; - ptr[3] = EXT_CTRL_CODE_BEGIN; - ptr[4] = 1; - ptr += 5; - gender = GetMonGender(pkmn); - species = GetMonData(pkmn, MON_DATA_SPECIES); - language = GetMonData(pkmn, MON_DATA_LANGUAGE); - if (ShouldHideGenderIconForLanguage(species, nickname, language)) - gender = 100; - switch (gender) - { - default: - ptr[0] = 0xB; - ptr[1] = EOS; - ptr += 1; - break; - case MON_MALE: - ptr[0] = 0xB; - ptr[1] = CHAR_MALE; - ptr[2] = EOS; - ptr += 2; - break; - case MON_FEMALE: - ptr[0] = 0xA; - ptr[1] = CHAR_FEMALE; - ptr[2] = EOS; - ptr += 2; - break; - } - ptr[0] = EXT_CTRL_CODE_BEGIN; - ptr[1] = 0x13; - ptr[2] = 0x37; - ptr[3] = EOS; - ptr = ewram520_2 + GetBattlerPosition(gSprites[a].data[6]) * 0x180; - sub_80034D4(ptr, gDisplayedStringBattle); - - i = 0; - _7 = 7; - if (GetMonData(pkmn, MON_DATA_LANGUAGE) == 1 - && GetMonData(pkmn, MON_DATA_IS_EGG) == 0) - { - u8 *p = gDisplayedStringBattle; - - while (*p != EOS) - { - if (*p == EXT_CTRL_CODE_BEGIN) - { - p += GetExtCtrlCodeLength(p[1]) + 1; - } - else - { - u8 r0; - - if ((*p >= 0x37 && *p <= 0x4A) || (*p >= 0x87 && *p <= 0x9A)) - r0 = 0x2C; - else if ((*p >= 0x4B && *p <= 0x4F) || (*p >= 0x9B && *p <= 0x9F)) - r0 = 0x2D; - else - r0 = 0x2B; - - CpuCopy32(sub_8043CDC(r0), ptr + 0x40 * i, 32); - i++; - p++; - } - } - } - - for (; i < _7; i++) - CpuCopy32(sub_8043CDC(0x2B), ptr + 64 * i, 32); - - if (GetBattlerSide(gSprites[a].data[6]) == 0 && !IsDoubleBattle()) - { - r1 = (u8 *const *)gUnknown_0820A8B4; - for (i = 0; i < _7; i++) - { - u8 *r4 = r1[i]; - - r4 += gSprites[a].oam.tileNum * 32; - CpuCopy32(ptr, r4, 32); - ptr += 32; - - r4 += 0x100; - CpuCopy32(ptr, r4, 32); - ptr += 32; - } - } - else - { - if (GetBattlerSide(gSprites[a].data[6]) == 0) - r1 = (u8 *const *)gUnknown_0820A904; - else - r1 = (u8 *const *)gUnknown_0820A8DC; - for (i = 0; i < _7; i++) - { - u8 *r4 = r1[i]; - - r4 += gSprites[a].oam.tileNum * 32; - CpuCopy32(ptr, r4, 32); - ptr += 32; - - r4 += 0x100; - CpuCopy32(ptr, r4, 32); - ptr += 32; - } - } -} - -static void sub_8045458(u8 a, u8 b) -{ - u8 r4; - - if (gBattleTypeFlags & 0x200) - return; - if (gBattleTypeFlags & 8) - return; - - r4 = gSprites[a].data[6]; - if (GetBattlerSide(r4) != 0) - { - u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[r4]], MON_DATA_SPECIES); - if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), 1) != 0) - { - r4 = gSprites[a].data[5]; - if (b != 0) - CpuCopy32(sub_8043CDC(0x46), OBJ_VRAM0 + (gSprites[r4].oam.tileNum + 8) * 32, 32); - else - CpuFill32(0, OBJ_VRAM0 + (gSprites[r4].oam.tileNum + 8) * 32, 32); - } - } -} - -/*static*/ void draw_status_ailment_maybe(u8 a) -{ - s32 r4; - s32 r4_2; - u8 r7; - u8 r10; - s16 r8; - const u8 *r6; - u8 r0; - s32 i; - - r7 = gSprites[a].data[6]; - r10 = gSprites[a].data[5]; - if (GetBattlerSide(r7) == 0) - { - r4 = GetMonData(&gPlayerParty[gBattlerPartyIndexes[r7]], MON_DATA_STATUS); - if (!IsDoubleBattle()) - r8 = 0x1A; - else - r8 = 0x12; - } - else - { - r4 = GetMonData(&gEnemyParty[gBattlerPartyIndexes[r7]], MON_DATA_STATUS); - r8 = 0x11; - } - if (r4 & 7) - { - r6 = sub_8043CDC(sub_80457E8(0x1B, r7)); - r0 = 2; - } - else if (r4 & 0x88) - { - r6 = sub_8043CDC(sub_80457E8(0x15, r7)); - r0 = 0; - } - else if (r4 & 0x10) - { - r6 = sub_8043CDC(sub_80457E8(0x21, r7)); - r0 = 4; - } - else if (r4 & 0x20) - { - r6 = sub_8043CDC(sub_80457E8(0x1E, r7)); - r0 = 3; - } - else if (r4 & 0x40) - { - r6 = sub_8043CDC(sub_80457E8(0x18, r7)); - r0 = 1; - } - else - { - r6 = sub_8043CDC(0x27); - - for (i = 0; i < 3; i++) - CpuCopy32(r6, OBJ_VRAM0 + (gSprites[a].oam.tileNum + r8 + i) * 32, 32); - - if (!ewram17800[r7].unk0_4) - CpuCopy32(sub_8043CDC(1), OBJ_VRAM0 + gSprites[r10].oam.tileNum * 32, 64); - - sub_8045458(a, 1); - return; - } - - r4_2 = gSprites[a].oam.paletteNum * 16; - r4_2 += r7 + 12; - // I don't like writing the array index like this, but I can't get it to match otherwise. - FillPalette(r0[gBattleInterfaceStatusIcons_DynPal], r4_2 + 0x100, 2); - CpuCopy16(gPlttBufferUnfaded + 0x100 + r4_2, (void *)(OBJ_PLTT + r4_2 * 2), 2); - CpuCopy32(r6, OBJ_VRAM0 + (gSprites[a].oam.tileNum + r8) * 32, 96); - if (IsDoubleBattle() == TRUE || GetBattlerSide(r7) == TRUE) - { - if (!ewram17800[r7].unk0_4) - { - CpuCopy32(sub_8043CDC(0), OBJ_VRAM0 + gSprites[r10].oam.tileNum * 32, 32); - CpuCopy32(sub_8043CDC(0x41), OBJ_VRAM0 + (gSprites[r10].oam.tileNum + 1) * 32, 32); - } - } - sub_8045458(a, 0); -} - -static u8 sub_80457E8(u8 a, u8 b) -{ - u8 ret = a; - - switch (a) - { - case 21: - if (b == 0) - ret = 21; - else if (b == 1) - ret = 71; - else if (b == 2) - ret = 86; - else - ret = 101; - break; - case 24: - if (b == 0) - ret = 24; - else if (b == 1) - ret = 74; - else if (b == 2) - ret = 89; - else - ret = 104; - break; - case 27: - if (b == 0) - ret = 27; - else if (b == 1) - ret = 77; - else if (b == 2) - ret = 92; - else - ret = 107; - break; - case 30: - if (b == 0) - ret = 30; - else if (b == 1) - ret = 80; - else if (b == 2) - ret = 95; - else - ret = 110; - break; - case 33: - if (b == 0) - ret = 33; - else if (b == 1) - ret = 83; - else if (b == 2) - ret = 98; - else - ret = 113; - break; - } - return ret; -} - -/*static*/ void sub_80458B0(u8 a) -{ - u8 *r6; - u8 r8; - u8 i; - s32 r7; - u8 *addr; - - r6 = ewram520_2 + GetBattlerPosition(gSprites[a].data[6]) * 0x180; - r8 = 7; - sub_80034D4(r6, BattleText_SafariBalls); - for (i = 0; i < r8; i++) - CpuCopy32(sub_8043CDC(0x2B), r6 + i * 64, 32); - for (r7 = 3; r7 < 3 + r8; r7++) - { - addr = OBJ_VRAM0 + (gSprites[a].oam.tileNum + MACRO1(r7)) * 32; - CpuCopy32(r6, addr, 32); - r6 += 32; - - addr = OBJ_VRAM0 + (8 + gSprites[a].oam.tileNum + MACRO1(r7)) * 32; - CpuCopy32(r6, addr, 32); - r6 += 32; - } - -} - -/*static*/ void sub_8045998(u8 a) -{ - u8 *r7; - u8 status; - s32 r6; - s32 i; - - r7 = StringCopy(gDisplayedStringBattle, BattleText_SafariBallsLeft); - r7 = sub_8003504(r7, gNumSafariBalls, 10, 1); - StringAppend(r7, BattleText_HighlightRed); - status = GetBattlerPosition(gSprites[a].data[6]); - r7 = ewram520_2 + status * 0x180; - r6 = 5; - sub_80034D4(r7, gDisplayedStringBattle); - r7 = ewram520_2 + status * 0x180 + 32; - for (i = 6; i < 6 + r6; i++) - { - CpuCopy32(r7, OBJ_VRAM0 + (gSprites[a].oam.tileNum + 0x18 + MACRO1(i)) * 32, 32); - r7 += 64; - } -} - -void sub_8045A5C(u8 a, struct Pokemon *pkmn, u8 c) -{ - u8 r10; - u32 maxhp; - u32 currhp; - - r10 = gSprites[a].data[6]; - if (GetBattlerSide(r10) == 0) - { - if (c == 3 || c == 0) - sub_8043FC0(a, GetMonData(pkmn, MON_DATA_LEVEL)); - if (c == 1 || c == 0) - sub_80440EC(a, GetMonData(pkmn, MON_DATA_HP), 0); - if (c == 2 || c == 0) - sub_80440EC(a, GetMonData(pkmn, MON_DATA_MAX_HP), 1); - if (c == 5 || c == 0) - { - load_gfxc_health_bar(0); - maxhp = GetMonData(pkmn, MON_DATA_MAX_HP); - currhp = GetMonData(pkmn, MON_DATA_HP); - sub_8043D84(r10, a, maxhp, currhp, 0); - sub_8045C78(r10, a, 0, 0); - } - if (!IsDoubleBattle() && (c == 6 || c == 0)) - { - u16 species; - u8 level; - u32 exp; - u32 var1; - u32 var2; - u32 currLevelExp; - - load_gfxc_health_bar(3); - species = GetMonData(pkmn, MON_DATA_SPECIES); - level = GetMonData(pkmn, MON_DATA_LEVEL); - exp = GetMonData(pkmn, MON_DATA_EXP); - currLevelExp = gExperienceTables[gBaseStats[species].growthRate][level]; - var1 = exp - currLevelExp; - var2 = gExperienceTables[gBaseStats[species].growthRate][level + 1] - currLevelExp; - sub_8043D84(r10, a, var2, var1, 0); - sub_8045C78(r10, a, 1, 0); - } - if (c == 4 || c == 0) - sub_80451A0(a, pkmn); - if (c == 9 || c == 0) - draw_status_ailment_maybe(a); - if (c == 10) - sub_80458B0(a); - if (c == 10 || c == 11) - sub_8045998(a); - } - else - { - if (c == 3 || c == 0) - sub_8043FC0(a, GetMonData(pkmn, MON_DATA_LEVEL)); -#if DEBUG - if (gUnknown_020297ED == 1) - { - if (c == 1 || c == 0) - sub_80440EC(a, GetMonData(pkmn, MON_DATA_HP), 0); - if (c == 2 || c == 0) - sub_80440EC(a, GetMonData(pkmn, MON_DATA_MAX_HP), 1); - } -#endif - if (c == 5 || c == 0) - { - load_gfxc_health_bar(0); - maxhp = GetMonData(pkmn, MON_DATA_MAX_HP); - currhp = GetMonData(pkmn, MON_DATA_HP); - sub_8043D84(r10, a, maxhp, currhp, 0); - sub_8045C78(r10, a, 0, 0); - } - if (c == 4 || c == 0) - sub_80451A0(a, pkmn); - if (c == 9 || c == 0) - draw_status_ailment_maybe(a); - } -} - -s32 sub_8045C78(u8 a, u8 unused1, u8 c, u8 unused2) -{ - s32 r6; - - if (c == 0) - { - r6 = sub_8045F58(ewram17850[a].unk4, ewram17850[a].unk8, ewram17850[a].unkC, &ewram17850[a].unk10, 6, 1); - } - else - { - u16 r5; - s32 r8; - - r5 = GetScaledExpFraction(ewram17850[a].unk8, ewram17850[a].unkC, ewram17850[a].unk4, 8); - if (r5 == 0) - r5 = 1; - r8 = ewram17850[a].unkC; - r5 = ABS(r8 / r5); - r6 = sub_8045F58(ewram17850[a].unk4, ewram17850[a].unk8, r8, &ewram17850[a].unk10, 8, r5); - } - if (c == 1 || (c == 0 && (!ewram17800[a].unk0_4))) - sub_8045D58(a, c); - if (r6 == -1) - ewram17850[a].unk10 = 0; - return r6; -} - -static void sub_8045D58(u8 a, u8 b) -{ - u8 sp8[7]; - u8 r0; - u8 r8; - u8 i; - - switch (b) - { - case 0: - r0 = sub_804602C(ewram17850[a].unk4, ewram17850[a].unk8, ewram17850[a].unkC, &ewram17850[a].unk10, sp8, 6); - r8 = 3; - if (r0 <= 0x18) - { - r8 = 0x38; - if (r0 > 9) - r8 = 0x2F; - } - for (i = 0; i < 6; i++) - { - u8 r4 = gSprites[ewram17850[a].unk0].data[5]; - if (i < 2) - CpuCopy32(sub_8043CDC(r8) + sp8[i] * 32, OBJ_VRAM0 + (gSprites[r4].oam.tileNum + 2 + i) * 32, 32); - else - CpuCopy32(sub_8043CDC(r8) + sp8[i] * 32, OBJ_VRAM0 + 64 + (i + gSprites[r4].oam.tileNum) * 32, 32); - } - break; - case 1: - sub_804602C(ewram17850[a].unk4, ewram17850[a].unk8, ewram17850[a].unkC, &ewram17850[a].unk10, sp8, 8); - r0 = GetMonData(&gPlayerParty[gBattlerPartyIndexes[a]], MON_DATA_LEVEL); - if (r0 == 100) - { - for (i = 0; i < 8; i++) - sp8[i] = 0; - } - for (i = 0; i < 8; i++) - { - if (i < 4) - CpuCopy32(sub_8043CDC(0xC) + sp8[i] * 32, OBJ_VRAM0 + (gSprites[ewram17850[a].unk0].oam.tileNum + 0x24 + i) * 32, 32); - else - CpuCopy32(sub_8043CDC(0xC) + sp8[i] * 32, OBJ_VRAM0 + 0xB80 + (i + gSprites[ewram17850[a].unk0].oam.tileNum) * 32, 32); - } - break; - } -} - -static int sub_8045F58(s32 a, s32 b, int c, int *d, u8 e, u16 f) -{ - u8 r2 = e << 3; - int r6; - int ret; - - if (*d == -32768) - { - if (a < r2) - *d = b << 8; - else - *d = b; - } - //_08045F8A - b -= c; - if (b < 0) - b = 0; - else if (b > a) - b = a; - if (a < r2) - { - int var = *d >> 8; - - r6 = *d; - if (b == var && (r6 & 0xFF) == 0) - return -1; - } - else - { - r6 = *d; - if (b == r6) - return -1; - } - //_08045FC4 - if (a < r2) - { - int r0 = (a << 8) / r2; - - if (c < 0) - { - *d = r6 + r0; - ret = *d >> 8; - if (ret >= b) - { - *d = b << 8; - ret = b; - } - } - //_08045FE2 - else - { - *d = r6 - r0; - ret = *d >> 8; - if ((*d & 0xFF) > 0) - ret++; - if (ret <= b) - { - *d = b << 8; - ret = b; - } - } - } - else - { - //_08045FFE - if (c < 0) - { - *d += f; - if (*d > b) - *d = b; - ret = *d; - } - //_08046010 - else - { - *d -= f; - if (*d < b) - *d = b; - ret = *d; - } - } - return ret; -} - -static u8 sub_804602C(int a, int b, int c, int *d, u8 *e, u8 f) -{ - s32 r5 = b - c; - u8 r3; - u8 i; - u8 r2; - - if (r5 < 0) - r5 = 0; - else if (r5 > a) - r5 = a; - r3 = f << 3; - for (i = 0; i < f; i++) - e[i] = 0; - if (a < r3) - r2 = *d * r3 / a >> 8; - else - r2 = *d * r3 / a; - r3 = r2; - if (r3 == 0 && r5 > 0) - { - e[0] = 1; - r3 = 1; - } - else - { - for (i = 0; i < f; i++) - { - if (r2 >= 8) - { - e[i] = 8; - } - else - { - e[i] = r2; - break; - } - r2 -= 8; - } - } - return r3; -} - -s16 sub_80460C8(struct BattleInterfaceStruct1 *a, int *b, u16 *c, int d) -{ - u16 r7; - s16 r1; - - r7 = sub_8045F58(a->unk0, a->unk4, a->unk8, b, 6, 1); - sub_8046128(a, b, c); - if (a->unk0 < 0x30) - r1 = *b >> 8; - else - r1 = *b; - do_nothing(a->unk0, r1, d); - return r7; -} - -static void sub_8046128(struct BattleInterfaceStruct1 *a, int *b, u16 *c) -{ - u8 sp8[6]; - u16 sp10[6]; - u8 i; - - sub_804602C(a->unk0, a->unk4, a->unk8, b, (u8 *)sp8, 6); - for (i = 0; i < 6; i++) - sp10[i] = (a->unkC_0 << 12) | (a->unk10 + sp8[i]); - CpuCopy16(sp10, c, sizeof(sp10)); -} - -static u8 GetScaledExpFraction(int a, int b, int c, u8 d) -{ - u8 r7 = d * 8; - int r5 = a - b; - s8 r4; - s8 r0; - s32 result; - - if (r5 < 0) - r5 = 0; - else if (r5 > c) - r5 = c; - - r4 = a * r7 / c; - r0 = r5 * r7 / c; - result = r4 - r0; - return ABS(result); -} - -u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale) -{ - u8 result = hp * scale / maxhp; - - if (result == 0 && hp > 0) - return 1; - return result; -} - -u8 GetHPBarLevel(s16 hp, s16 maxhp) -{ - int result; - - if (hp == maxhp) - result = 4; - else - { - u8 fraction = GetScaledHPFraction(hp, maxhp, 48); - if (fraction >= 25) - result = 3; - else if (fraction >= 10) - result = 2; - else if (fraction > 0) - result = 1; - else - result = 0; - } - return result; -} diff --git a/src/battle/battle_message.c b/src/battle/battle_message.c deleted file mode 100644 index 30d127be3..000000000 --- a/src/battle/battle_message.c +++ /dev/null @@ -1,1054 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_message.h" -#include "battle_tower.h" -#include "item.h" -#include "event_data.h" -#include "constants/items.h" -#include "pokemon.h" -#include "data2.h" -#include "text.h" -#include "string_util.h" -#include "link.h" -#include "battle_setup.h" -#include "battle_tower.h" -#include "constants/flags.h" -#include "ewram.h" - -#define BATTLESTRING_TO_SUB 12 -#define BATTLESTRINGS_NO 351 -#define BATTLESTRINGS_MAX BATTLESTRINGS_NO + BATTLESTRING_TO_SUB - -#ifdef GERMAN -#include "../data/battle_strings_de.h" // TODO: German -#else -#include "../data/battle_strings_en.h" -#endif - -// This is four lists of moves which use a different attack string in Japanese -// to the default. See the documentation for sub_8121D74 for more detail. -const u16 gUnknown_084016BC[] = -{ - MOVE_SWORDS_DANCE, - MOVE_STRENGTH, - MOVE_GROWTH, - MOVE_HARDEN, - MOVE_MINIMIZE, - MOVE_SMOKESCREEN, - MOVE_WITHDRAW, - MOVE_DEFENSE_CURL, - MOVE_EGG_BOMB, - MOVE_SMOG, - MOVE_BONE_CLUB, - MOVE_FLASH, - MOVE_SPLASH, - MOVE_ACID_ARMOR, - MOVE_BONEMERANG, - MOVE_REST, - MOVE_SHARPEN, - MOVE_SUBSTITUTE, - MOVE_MIND_READER, - MOVE_SNORE, - MOVE_PROTECT, - MOVE_SPIKES, - MOVE_ENDURE, - MOVE_ROLLOUT, - MOVE_SWAGGER, - MOVE_SLEEP_TALK, - MOVE_HIDDEN_POWER, - MOVE_PSYCH_UP, - MOVE_EXTREME_SPEED, - MOVE_FOLLOW_ME, - MOVE_TRICK, - MOVE_ASSIST, - MOVE_INGRAIN, - MOVE_KNOCK_OFF, - MOVE_CAMOUFLAGE, - MOVE_ASTONISH, - MOVE_ODOR_SLEUTH, - MOVE_GRASS_WHISTLE, - MOVE_SHEER_COLD, - MOVE_MUDDY_WATER, - MOVE_IRON_DEFENSE, - MOVE_BOUNCE, - 0, - MOVE_TELEPORT, - MOVE_RECOVER, - MOVE_BIDE, - MOVE_AMNESIA, - MOVE_FLAIL, - MOVE_TAUNT, - MOVE_BULK_UP, - 0, - MOVE_MEDITATE, - MOVE_AGILITY, - MOVE_MIMIC, - MOVE_DOUBLE_TEAM, - MOVE_BARRAGE, - MOVE_TRANSFORM, - MOVE_STRUGGLE, - MOVE_SCARY_FACE, - MOVE_CHARGE, - MOVE_WISH, - MOVE_BRICK_BREAK, - MOVE_YAWN, - MOVE_FEATHER_DANCE, - MOVE_TEETER_DANCE, - MOVE_MUD_SPORT, - MOVE_FAKE_TEARS, - MOVE_WATER_SPORT, - MOVE_CALM_MIND, - 0, - MOVE_POUND, - MOVE_SCRATCH, - MOVE_VICE_GRIP, - MOVE_WING_ATTACK, - MOVE_FLY, - MOVE_BIND, - MOVE_SLAM, - MOVE_HORN_ATTACK, - MOVE_WRAP, - MOVE_THRASH, - MOVE_TAIL_WHIP, - MOVE_LEER, - MOVE_BITE, - MOVE_GROWL, - MOVE_ROAR, - MOVE_SING, - MOVE_PECK, - MOVE_ABSORB, - MOVE_STRING_SHOT, - MOVE_EARTHQUAKE, - MOVE_FISSURE, - MOVE_DIG, - MOVE_TOXIC, - MOVE_SCREECH, - MOVE_METRONOME, - MOVE_LICK, - MOVE_CLAMP, - MOVE_CONSTRICT, - MOVE_POISON_GAS, - MOVE_BUBBLE, - MOVE_SLASH, - MOVE_SPIDER_WEB, - MOVE_NIGHTMARE, - MOVE_CURSE, - MOVE_FORESIGHT, - MOVE_CHARM, - MOVE_ATTRACT, - MOVE_ROCK_SMASH, - MOVE_UPROAR, - MOVE_SPIT_UP, - MOVE_SWALLOW, - MOVE_TORMENT, - MOVE_FLATTER, - MOVE_ROLE_PLAY, - MOVE_ENDEAVOR, - MOVE_TICKLE, - MOVE_COVET, - 0, -}; - -const u8 gUnknown_084017A8[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // empty flags - -extern const u8* const gBattleStringsTable[BATTLESTRINGS_NO]; - -extern u16 gLastUsedItem; -extern u8 gLastUsedAbility; -extern u8 gActiveBattler; -extern u8 gBankAttacker; -extern u8 gBankTarget; -extern u8 gStringBank; -extern u8 gEffectBank; -extern u8 gBattleTextBuff1[]; -extern u8 gBattleTextBuff2[]; -extern u8 gBattleTextBuff3[]; -extern u8 gStringVar1[]; -extern u8 gStringVar2[]; -extern u8 gStringVar3[]; -extern u16 gBattleTypeFlags; -extern u16 gTrainerBattleOpponent; -extern u8 gDisplayedStringBattle[]; -extern u8 gStringVar1[]; -extern u8 gStringVar2[]; -extern u8 gStringVar3[]; -extern u16 gBattlerPartyIndexes[4]; -extern struct BattleEnigmaBerry gEnigmaBerries[4]; -extern u8 gBattleBufferA[4][0x200]; - -EWRAM_DATA u8 gAbilitiesPerBank[4] = {0}; - -extern const u8* const gUnknown_08401674[]; // table of pointers to 'a -TYPE' strings -extern const u8* const gUnknown_08400F58[]; // table of pointers to stat strings -extern const u8* const gUnknown_08400F78[]; // table of pointers to flavour strings - -struct StatusFlagString -{ - u8* flag; - u8* ptr; -}; - -extern const struct StatusFlagString gUnknown_081FA6D4[7]; // status flag/text - -extern struct StringInfoBattle* gSelectedOrderFromParty; -#define gStringInfo gSelectedOrderFromParty - -void sub_8121D1C(u8* textBuff); -void sub_8121D74(u8* textBuff); -void StrCpyDecodeBattleTextBuff(u8* src, u8* dst); - -u8 GetBattlerSide(u8 bank); -s32 sub_803FC34(u16); -void get_trainer_name(u8* dst); -u8 get_trainer_class_name_index(void); -u8 GetMultiplayerId(void); -u8 GetBattlerAtPosition(u8 ID); -u8 GetBattlerSide(u8 bank); -u8 GetBattlerPosition(u8 bank); -#ifdef GERMAN -extern u8 *de_sub_804110C(); -#endif - -void BufferStringBattle(u16 stringID) -{ - int i; - const u8* stringPtr = NULL; - - gStringInfo = (struct StringInfoBattle*)(&gBattleBufferA[gActiveBattler][4]); - gLastUsedItem = gStringInfo->lastItem; - gLastUsedAbility = gStringInfo->lastAbility; - gBattleStruct->scriptingActive = gStringInfo->scrActive; - gBattleStruct->unk1605E = gStringInfo->unk1605E; - gBattleStruct->hpScale = gStringInfo->hpScale; - gStringBank = gStringInfo->StringBank; - gBattleStruct->stringMoveType = gStringInfo->moveType; - for (i = 0; i < 4; i++) - { - gAbilitiesPerBank[i] = gStringInfo->abilities[i]; - } - for (i = 0; i < 0x10; i++) - { - gBattleTextBuff1[i] = gStringInfo->textBuffs[0][i]; - gBattleTextBuff2[i] = gStringInfo->textBuffs[1][i]; - gBattleTextBuff3[i] = gStringInfo->textBuffs[2][i]; - } - switch (stringID) - { - case 0: // first battle msg - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - { - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - stringPtr = BattleText_DoubleWantToBattle; - else - stringPtr = BattleText_SingleWantToBattle2; - } - else - { - stringPtr = BattleText_SingleWantToBattle1; -#ifdef GERMAN - stringPtr = de_sub_804110C(0xFFFF, stringPtr); -#endif - } - } - else - { - if (gBattleTypeFlags & BATTLE_TYPE_LEGENDARY) - stringPtr = BattleText_WildAppeared2; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) // interesting, looks like they had something planned for wild double battles - stringPtr = BattleText_WildDoubleAppeared; - else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) - stringPtr = BattleText_WildAppeared3; - else - stringPtr = BattleText_WildAppeared1; - } - break; - case 1: // poke first send-out - if (GetBattlerSide(gActiveBattler) == 0) - { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - stringPtr = BattleText_SentOutSingle11; - else - stringPtr = BattleText_SentOutDouble4; - } - else - stringPtr = BattleText_SentOutSingle6; - } - else - { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - stringPtr = BattleText_SentOutDouble3; - else if (gBattleTypeFlags & BATTLE_TYPE_LINK) - stringPtr = BattleText_SentOutDouble2; - else - { - stringPtr = BattleText_SentOutDouble1; -#ifdef GERMAN - stringPtr = de_sub_804110C(0xFFFF, stringPtr); -#endif - } - } - else if (gBattleTypeFlags & BATTLE_TYPE_LINK) - stringPtr = BattleText_SentOutSingle3; - else - { - stringPtr = BattleText_SentOutSingle1; -#ifdef GERMAN - stringPtr = de_sub_804110C(0xFFFF, stringPtr); -#endif - } - } - break; - case 2: // sending poke to ball msg - if (GetBattlerSide(gActiveBattler) == 0) - { - if (gBattleStruct->hpScale == 0) - stringPtr = BattleText_ComeBackSingle1; - else if (gBattleStruct->hpScale == 1 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - stringPtr = BattleText_ComeBackSingle2; - else if (gBattleStruct->hpScale == 2) - stringPtr = BattleText_ComeBackSingle3; - else - stringPtr = BattleText_ComeBackSingle4; - } - else - { - if (gTrainerBattleOpponent == LINK_BATTLE_OPPONENT) - { - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - stringPtr = BattleText_WithdrewPoke3; - else - stringPtr = BattleText_WithdrewPoke2; - } - else - { - stringPtr = BattleText_WithdrewPoke1; -#ifdef GERMAN - stringPtr = de_sub_804110C(0xFFFF, stringPtr); -#endif - } - } - break; - case 3: // switch-in msg - if (GetBattlerSide(gBattleStruct->scriptingActive) == 0) - { - if (gBattleStruct->hpScale == 0 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - stringPtr = BattleText_SentOutSingle7; - else if (gBattleStruct->hpScale == 1) - stringPtr = BattleText_SentOutSingle8; - else if (gBattleStruct->hpScale == 2) - stringPtr = BattleText_SentOutSingle9; - else - stringPtr = BattleText_SentOutSingle10; - } - else - { - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - stringPtr = BattleText_SentOutSingle5; - else - stringPtr = BattleText_SentOutSingle4; - } - else - { - stringPtr = BattleText_SentOutSingle2; -#ifdef GERMAN - stringPtr = de_sub_804110C(0xFFFF, stringPtr); -#endif - } - } - break; - case 4: // pokemon used a move msg - sub_8121D1C(gBattleTextBuff1); - if (gStringInfo->currentMove > 0x162) - StringCopy(gBattleTextBuff2, gUnknown_08401674[gBattleStruct->stringMoveType]); - else - StringCopy(gBattleTextBuff2, gMoveNames[gStringInfo->currentMove]); - sub_8121D74(gBattleTextBuff2); - stringPtr = BattleText_OpponentUsedMove; - break; - case 5: // battle end - if (gBattleTextBuff1[0] & 0x80) - { - gBattleTextBuff1[0] &= ~(0x80); - if (GetBattlerSide(gActiveBattler) == 1 && gBattleTextBuff1[0] != 3) - gBattleTextBuff1[0] ^= 3; - if (gBattleTextBuff1[0] == BATTLE_LOST || gBattleTextBuff1[0] == BATTLE_DREW) - stringPtr = BattleText_GotAwaySafely; - else - { - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - stringPtr = BattleText_FledDouble; - else - stringPtr = BattleText_FledSingle; - } - } - else - { - if (GetBattlerSide(gActiveBattler) == 1 && gBattleTextBuff1[0] != 3) - gBattleTextBuff1[0] ^= 3; - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - switch (gBattleTextBuff1[0]) - { - case BATTLE_WON: - stringPtr = BattleText_PlayerDefeatedTrainers; - break; - case BATTLE_LOST: - stringPtr = BattleText_PlayerLostTrainers; - break; - case BATTLE_DREW: - stringPtr = BattleText_PlayerTiedTrainers; - break; - } - } - else - { - switch (gBattleTextBuff1[0]) - { - case BATTLE_WON: - stringPtr = BattleText_PlayerDefeatedTrainer; - break; - case BATTLE_LOST: - stringPtr = BattleText_PlayerLostTrainer; - break; - case BATTLE_DREW: - stringPtr = BattleText_PlayerTiedTrainer; - break; - } - } - } - break; - default: // load a string from the table - if (stringID >= BATTLESTRINGS_MAX) - { - gDisplayedStringBattle[0] = EOS; - return; - } - else - { - stringPtr = gBattleStringsTable[stringID - BATTLESTRING_TO_SUB]; -#ifdef GERMAN - stringPtr = de_sub_804110C(stringID, stringPtr); -#endif - } - break; - } - StrCpyDecodeToDisplayedStringBattle(stringPtr); -} - -u32 StrCpyDecodeToDisplayedStringBattle(const u8* src) -{ - StrCpyDecodeBattle(src, gDisplayedStringBattle); -} - -const u8* AppendStatusString(u8* src) -{ - u32 i; - u8 status[8]; - u32 flag1, flag2; - u8* statusPtr; - - memcpy(status, gUnknown_084017A8, 8); - - statusPtr = status; - for (i = 0; i < sizeof(struct StatusFlagString); i++) - { - if (*src == EOS) - break; - *statusPtr = *src; - src++; - statusPtr++; - } - flag1 = *(u32*)(&status[0]); - flag2 = *(u32*)(&status[4]); - for (i = 0; i < 7; i++) - { - if (flag1 == *(u32*)(&gUnknown_081FA6D4[i].flag[0]) && flag2 == *(u32*)(&gUnknown_081FA6D4[i].flag[4])) - return gUnknown_081FA6D4[i].ptr; - } - return NULL; -} - -#ifdef GERMAN -extern u8 *de_sub_8073174(u8 *, const u8 *); -extern u8 *de_sub_8041024(s32, u32); -#endif - -#ifdef ENGLISH -#define HANDLE_NICKNAME_STRING_CASE(bank, monIndex) \ - if (GetBattlerSide(bank) != 0) \ - { \ - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) \ - toCpy = BattleText_Foe; \ - else \ - toCpy = BattleText_Wild; \ - while (*toCpy != EOS) \ - { \ - dst[dstID] = *toCpy; \ - dstID++; \ - toCpy++; \ - } \ - GetMonData(&gEnemyParty[monIndex], MON_DATA_NICKNAME, text); \ - } \ - else \ - { \ - GetMonData(&gPlayerParty[monIndex], MON_DATA_NICKNAME, text); \ - } \ - StringGetEnd10(text); \ - toCpy = text; -#else -#define HANDLE_NICKNAME_STRING_CASE(bank, monIndex) \ - if (GetBattlerSide(bank) != 0) \ - { \ - GetMonData(&gEnemyParty[monIndex], MON_DATA_NICKNAME, text); \ - StringGetEnd10(text); \ - toCpy = text; \ - while (*toCpy != EOS) \ - { \ - dst[dstID] = *toCpy; \ - dstID++; \ - toCpy++; \ - } \ - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) \ - toCpy = BattleText_Foe; \ - else \ - toCpy = BattleText_Wild; \ - } \ - else \ - { \ - GetMonData(&gPlayerParty[monIndex], MON_DATA_NICKNAME, text); \ - StringGetEnd10(text); \ - toCpy = text; \ - } -#endif - -u32 StrCpyDecodeBattle(const u8* src, u8* dst) -{ - u32 dstID = 0; // if they used dstID, why not use srcID as well? - const u8* toCpy = NULL; - u8 text[12]; - u8 multiplayerID = GetMultiplayerId(); - - while (*src != EOS) - { - if (*src == 0xFD) - { - src++; - switch (*src) - { - case 0: - if (gBattleTextBuff1[0] == 0xFD) - { - StrCpyDecodeBattleTextBuff(gBattleTextBuff1, gStringVar1); - toCpy = gStringVar1; - } - else - { - toCpy = AppendStatusString(gBattleTextBuff1); - if (toCpy == 0) - toCpy = gBattleTextBuff1; - } - break; - case 1: - if (gBattleTextBuff2[0] == 0xFD) - { - StrCpyDecodeBattleTextBuff(gBattleTextBuff2, gStringVar2); - toCpy = gStringVar2; - } - else - toCpy = gBattleTextBuff2; - break; - case 42: - if (gBattleTextBuff3[0] == 0xFD) - { - StrCpyDecodeBattleTextBuff(gBattleTextBuff3, gStringVar3); - toCpy = gStringVar3; - } - else - toCpy = gBattleTextBuff3; - break; - case 2: // first player poke name - GetMonData(&gPlayerParty[gBattlerPartyIndexes[GetBattlerAtPosition(0)]], MON_DATA_NICKNAME, text); - StringGetEnd10(text); - toCpy = text; - break; - case 3: // first enemy poke name - GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(1)]], MON_DATA_NICKNAME, text); - StringGetEnd10(text); - toCpy = text; - break; - case 4: // second player poke name - GetMonData(&gPlayerParty[gBattlerPartyIndexes[GetBattlerAtPosition(2)]], MON_DATA_NICKNAME, text); - StringGetEnd10(text); - toCpy = text; - break; - case 5: // second enemy poke name - GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(3)]], MON_DATA_NICKNAME, text); - StringGetEnd10(text); - toCpy = text; - break; - case 6: // link first player poke name - GetMonData(&gPlayerParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerID].lp_field_18]], MON_DATA_NICKNAME, text); - StringGetEnd10(text); - toCpy = text; - break; - case 7: // link first opponent poke name - GetMonData(&gEnemyParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerID].lp_field_18 ^ 1]], MON_DATA_NICKNAME, text); - StringGetEnd10(text); - toCpy = text; - break; - case 8: // link second player poke name - GetMonData(&gPlayerParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerID].lp_field_18 ^ 2]], MON_DATA_NICKNAME, text); - StringGetEnd10(text); - toCpy = text; - break; - case 9: // link second opponent poke name - GetMonData(&gEnemyParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerID].lp_field_18 ^ 3]], MON_DATA_NICKNAME, text); - StringGetEnd10(text); - toCpy = text; - break; - case 10: // attacker name with prefix, only bank 0/1 - HANDLE_NICKNAME_STRING_CASE(gBankAttacker, gBattlerPartyIndexes[GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) & 1)]) - break; - case 11: // attacker partner name, only bank 0/1 - if (GetBattlerSide(gBankAttacker) == 0) - GetMonData(&gPlayerParty[gBattlerPartyIndexes[GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) & 1) + 2]], MON_DATA_NICKNAME, text); - else - GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) & 1) + 2]], MON_DATA_NICKNAME, text); - - StringGetEnd10(text); - toCpy = text; - break; - case 12: // attacker name with prefix - HANDLE_NICKNAME_STRING_CASE(gBankAttacker, gBattlerPartyIndexes[gBankAttacker]) - break; - case 13: // target name with prefix - HANDLE_NICKNAME_STRING_CASE(gBankTarget, gBattlerPartyIndexes[gBankTarget]) - break; - case 14: // effect bank name with prefix - HANDLE_NICKNAME_STRING_CASE(gEffectBank, gBattlerPartyIndexes[gEffectBank]) - break; - case 15: // active bank name with prefix - HANDLE_NICKNAME_STRING_CASE(gActiveBattler, gBattlerPartyIndexes[gActiveBattler]) - break; - case 16: // scripting active bank name with prefix - HANDLE_NICKNAME_STRING_CASE(gBattleStruct->scriptingActive, gBattlerPartyIndexes[gBattleStruct->scriptingActive]) - break; - case 17: // current move name - if (gStringInfo->currentMove > 0x162) - toCpy = (void*) &gUnknown_08401674[gBattleStruct->stringMoveType]; - else - toCpy = gMoveNames[gStringInfo->currentMove]; - break; - case 18: // last used move name - if (gStringInfo->lastMove > 0x162) - toCpy = (void*) &gUnknown_08401674[gBattleStruct->stringMoveType]; - else - toCpy = gMoveNames[gStringInfo->lastMove]; - break; - case 19: // last used item - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - if (gLastUsedItem == ITEM_ENIGMA_BERRY) - { - if (gLinkPlayers[gBattleStruct->linkPlayerIndex].lp_field_18 == gStringBank) - { - StringCopy(text, gEnigmaBerries[gStringBank].name); -#ifdef ENGLISH - StringAppend(text, BattleText_Berry); -#else - de_sub_8073174(text, BattleText_Berry); -#endif - toCpy = text; - } - else - toCpy = BattleText_EnigmaBerry; - } - else - { - CopyItemName(gLastUsedItem, text); - toCpy = text; - } - } - else - { - CopyItemName(gLastUsedItem, text); - toCpy = text; - } - break; - case 20: // last used ability - toCpy = gAbilityNames[gLastUsedAbility]; - break; - case 21: // attacker ability - toCpy = gAbilityNames[gAbilitiesPerBank[gBankAttacker]]; - break; - case 22: // target ability - toCpy = gAbilityNames[gAbilitiesPerBank[gBankTarget]]; - break; - case 23: // scripting active ability - toCpy = gAbilityNames[gAbilitiesPerBank[gBattleStruct->scriptingActive]]; - break; - case 24: // effect bank ability - toCpy = gAbilityNames[gAbilitiesPerBank[gEffectBank]]; - break; - case 25: // trainer class name -#ifdef ENGLISH - if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) - toCpy = gTrainerClassNames[GetSecretBaseTrainerNameIndex()]; - else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) - toCpy = gTrainerClassNames[get_trainer_class_name_index()]; - else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) - toCpy = gTrainerClassNames[GetEReaderTrainerClassNameIndex()]; - else - toCpy = gTrainerClassNames[gTrainers[gTrainerBattleOpponent].trainerClass]; - break; -#else - if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) - toCpy = de_sub_8041024(gTrainerBattleOpponent, 0); - else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) - toCpy = de_sub_8041024(BATTLE_TYPE_BATTLE_TOWER, 0); - else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) - toCpy = de_sub_8041024(BATTLE_TYPE_EREADER_TRAINER, 0); - else - toCpy = de_sub_8041024(0, gTrainerBattleOpponent); - break; -#endif - case 26: // trainer name - if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) - { - memset(text, 0xFF, 8); - memcpy(text, ewram17002, 7); - toCpy = text; - } - else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) - { - get_trainer_name(text); - toCpy = text; - } - else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) - { - SetEReaderTrainerName(text); - toCpy = text; - } - else - toCpy = gTrainers[gTrainerBattleOpponent].trainerName; - break; - case 27: // link player name? - toCpy = gLinkPlayers[multiplayerID].name; - break; - case 28: // link partner name? - toCpy = gLinkPlayers[sub_803FC34(2 ^ gLinkPlayers[multiplayerID].lp_field_18)].name; - break; - case 29: // link opponent 1 name? - toCpy = gLinkPlayers[sub_803FC34(1 ^ gLinkPlayers[multiplayerID].lp_field_18)].name; - break; - case 30: // link opponent 2 name? - toCpy = gLinkPlayers[sub_803FC34(3 ^ gLinkPlayers[multiplayerID].lp_field_18)].name; - break; - case 31: // link scripting active name - toCpy = gLinkPlayers[sub_803FC34(gBattleStruct->scriptingActive)].name; - break; - case 32: // player name - toCpy = gSaveBlock2.playerName; - break; - case 33: // ? - toCpy = GetTrainerLoseText(); - break; - case 34: // ? - HANDLE_NICKNAME_STRING_CASE(gBattleStruct->scriptingActive, gBattleStruct->unk1605E) - break; - case 35: // lanette pc - if (FlagGet(FLAG_SYS_PC_LANETTE)) - toCpy = BattleText_Lanette; - else - toCpy = BattleText_Someone; - break; - case 38: - if (GetBattlerSide(gBankAttacker) == 0) - toCpy = BattleText_Ally2; - else - toCpy = BattleText_Foe3; - break; - case 39: - if (GetBattlerSide(gBankTarget) == 0) - toCpy = BattleText_Ally2; - else - toCpy = BattleText_Foe3; - break; - case 36: - if (GetBattlerSide(gBankAttacker) == 0) - toCpy = BattleText_Ally; - else - toCpy = BattleText_Foe2; - break; - case 37: - if (GetBattlerSide(gBankTarget) == 0) - toCpy = BattleText_Ally; - else - toCpy = BattleText_Foe2; - break; - case 40: - if (GetBattlerSide(gBankAttacker) == 0) - toCpy = BattleText_Ally3; - else - toCpy = BattleText_Foe4; - break; - case 41: - if (GetBattlerSide(gBankTarget) == 0) - toCpy = BattleText_Ally3; - else - toCpy = BattleText_Foe4; - break; - } - //if (toCpy != NULL) really GF, why did you forget about this? - while (*toCpy != EOS) - { - dst[dstID] = *toCpy; - dstID++; - toCpy++; - } - if (*src == 33) - { - dst[dstID] = 0xFC; - dstID++; - dst[dstID] = 9; - dstID++; - } - } - else - { - dst[dstID] = *src; - dstID++; - } - src++; - } - dst[dstID] = *src; - dstID++; - return dstID; -} - -#define ByteRead16(ptr) ((ptr)[0] | ((ptr)[1] << 8)) -#define ByteRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) - -void StrCpyDecodeBattleTextBuff(u8* src, u8* dst) -{ - u32 srcID = 1; - u32 value = 0; - u8 text[12]; - u16 hword; - - *dst = EOS; - while (src[srcID] != EOS) - { - switch (src[srcID]) - { - case 0: // battle string - hword = ByteRead16(&src[srcID + 1]); -#ifdef GERMAN - if (hword == 209 || hword == 211) - srcID += 3; -#endif - StringAppend(dst, gBattleStringsTable[hword - BATTLESTRING_TO_SUB]); - srcID += 3; - break; - case 1: // int to string - switch (src[srcID + 1]) - { - case 1: - value = src[srcID + 3]; - break; - case 2: - value = ByteRead16(&src[srcID + 3]); - break; - case 4: - value = ByteRead32(&src[srcID + 3]); - break; - } - ConvertIntToDecimalStringN(dst, value, 0, src[srcID + 2]); - srcID += src[srcID + 1] + 3; - break; - case 2: // move name - StringAppend(dst, gMoveNames[ByteRead16(&src[srcID + 1])]); - srcID += 3; - break; - case 3: // type name - StringAppend(dst, gTypeNames[src[srcID + 1]]); - srcID += 2; - break; - case 4: // poke nick with prefix -#ifdef ENGLISH - if (GetBattlerSide(src[srcID + 1]) == 0) - { - GetMonData(&gPlayerParty[src[srcID + 2]], MON_DATA_NICKNAME, text); - } - else - { - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - StringAppend(dst, BattleText_Foe); - else - StringAppend(dst, BattleText_Wild); - GetMonData(&gEnemyParty[src[srcID + 2]], MON_DATA_NICKNAME, text); - } - StringGetEnd10(text); - StringAppend(dst, text); -#else - if (GetBattlerSide(src[srcID + 1]) == 0) - { - GetMonData(&gPlayerParty[src[srcID + 2]], MON_DATA_NICKNAME, text); - StringGetEnd10(text); - StringAppend(dst, text); - } - else - { - GetMonData(&gEnemyParty[src[srcID + 2]], MON_DATA_NICKNAME, text); - StringGetEnd10(text); - StringAppend(dst, text); - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - StringAppend(dst, BattleText_Foe); - else - StringAppend(dst, BattleText_Wild); - } -#endif - srcID += 3; - break; - case 5: // stats - StringAppend(dst, gUnknown_08400F58[src[srcID + 1]]); - srcID += 2; - break; - case 6: // species name - GetSpeciesName(dst, ByteRead16(&src[srcID + 1])); - srcID += 3; - break; - case 7: // poke nick without prefix - if (GetBattlerSide(src[srcID + 1]) == 0) - GetMonData(&gPlayerParty[src[srcID + 2]], MON_DATA_NICKNAME, dst); - else - GetMonData(&gEnemyParty[src[srcID + 2]], MON_DATA_NICKNAME, dst); - StringGetEnd10(dst); - srcID += 3; - break; - case 8: // flavour table - StringAppend(dst, gUnknown_08400F78[src[srcID + 1]]); - srcID += 2; - break; - case 9: // ability names - StringAppend(dst, gAbilityNames[src[srcID + 1]]); - srcID += 2; - break; - case 10: // item name - { - hword = ByteRead16(&src[srcID + 1]); - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - if (hword == ITEM_ENIGMA_BERRY) - { - if (gLinkPlayers[gBattleStruct->linkPlayerIndex].lp_field_18 == gStringBank) - { - StringCopy(dst, gEnigmaBerries[gStringBank].name); -#ifdef ENGLISH - StringAppend(dst, BattleText_Berry); -#else - de_sub_8073174(dst, BattleText_Berry); -#endif - } - else - StringAppend(dst, BattleText_EnigmaBerry); - } - else - CopyItemName(hword, dst); - } - else - CopyItemName(hword, dst); - srcID += 3; - } - break; - } - } -} - -// Loads one of two text strings into the provided buffer. This is functionally -// unused, since the value loaded into the buffer is not read; it loaded one of -// two particles (either "は" or "の") which works in tandem with sub_8121D74 -// below to effect changes in the meaning of the line. -void sub_8121D1C(u8* textBuff) -{ - s32 counter = 0; - u32 i = 0; - - while (counter != 4) - { - if (gUnknown_084016BC[i] == 0) - counter++; - if (gUnknown_084016BC[i++] == gStringInfo->currentMove) - break; - } - - if (counter >= 0) - { - if (counter <= 2) - StringCopy(textBuff, BattleText_Format10); // is - else if (counter <= 4) - StringCopy(textBuff, BattleText_Format11); // 's - } -} - -// Appends "!" to the text buffer `dst`. In the original Japanese this looked -// into the table of moves at gUnknown_084016BC and varied the line accordingly. -// -// BattleText_Exclamation was a plain "!", used for any attack not on the list. -// It resulted in the translation "'s !". -// -// BattleText_Exclamation2 was "を つかった!". This resulted in the translation -// " used !", which was used for all attacks in English. -// -// BattleText_Exclamation3 was "した!". This was used for those moves whose -// names were verbs, such as Recover, and resulted in translations like " -// recovered itself!". -// -// BattleText_Exclamation4 was "を した!" This resulted in a translation of -// " did an !". -// -// BattleText_Exclamation5 was " こうげき!" This resulted in a translation of -// "'s attack!". -void sub_8121D74(u8* dst) -{ - s32 counter = 0; - s32 i = 0; - - while (*dst != EOS) - dst++; - - while (counter != 4) - { - if (gUnknown_084016BC[i] == 0) - counter++; - if (gUnknown_084016BC[i++] == gStringInfo->currentMove) - break; - } - - switch (counter) - { - case 0: - StringCopy(dst, BattleText_Exclamation2); - break; - case 1: - StringCopy(dst, BattleText_Exclamation3); - break; - case 2: - StringCopy(dst, BattleText_Exclamation4); - break; - case 3: - StringCopy(dst, BattleText_Exclamation5); - break; - case 4: - StringCopy(dst, BattleText_Exclamation); - break; - } -} diff --git a/src/battle/battle_party_menu.c b/src/battle/battle_party_menu.c deleted file mode 100644 index e758b7957..000000000 --- a/src/battle/battle_party_menu.c +++ /dev/null @@ -1,731 +0,0 @@ -#include "global.h" -#include "battle_party_menu.h" -#include "battle.h" -#include "item_menu.h" -#include "item_use.h" -#include "main.h" -#include "menu.h" -#include "menu_helpers.h" -#include "palette.h" -#include "party_menu.h" -#include "pokemon.h" -#include "pokemon_summary_screen.h" -#include "rom_8077ABC.h" -#include "rom_8094928.h" -#include "constants/songs.h" -#include "sound.h" -#include "string_util.h" -#include "strings.h" -#include "task.h" -#include "text.h" -#include "ewram.h" - -extern u8 sub_806BD58(u8, u8); -extern void PartyMenuPrintMonsLevelOrStatus(void); -extern void nullsub_13(void); -extern void sub_802E414(void); -extern void sub_80A6DCC(void); -extern u8 *sub_8040D08(); -extern void sub_8040B8C(void); -extern void nullsub_14(); -extern u8 sub_803FBBC(void); - -extern u8 gPlayerPartyCount; -extern u8 gBattlersCount; -extern u16 gBattlerPartyIndexes[]; -extern u8 gBankInMenu; -extern u8 gUnknown_0202E8F4; -extern u8 gUnknown_0202E8F5; -extern u8 gUnknown_0202E8F6; -extern u8 gUnknown_02038470[3]; -extern u8 gUnknown_02038473; -extern u8 gUnknown_020384F0; -extern void (*gPokemonItemUseCallback)(); //don't know types yet -extern struct PokemonStorage gPokemonStorage; -extern void nullsub_14(); - -void sub_8094C98(u8, u8); -u8 pokemon_order_func(u8); - -static void sub_8094998(u8[3], u8); -static void sub_8094A74(u8[3], u8, u32); -static void sub_8094D60(void); -static void Task_809527C(u8); -static void Task_80952B4(u8); -static void Task_80952E4(u8); -static void Task_8095330(u8); -static void Task_809538C(void); -static void Task_HandlePopupMenuInput(u8); -static void Task_BattlePartyMenuSummary(u8 taskId); -static void Task_BattlePartyMenuShift(u8 taskId); -static void Task_BattlePartyMenuCancel(u8 taskId); - -static const struct MenuAction2 sBattlePartyMenuActions[] = -{ - {OtherText_Summary, Task_BattlePartyMenuSummary}, - {gOtherText_CancelNoTerminator, Task_BattlePartyMenuCancel}, - {OtherText_Shift, Task_BattlePartyMenuShift}, - {OtherText_SendOut, Task_BattlePartyMenuShift}, -}; -static const u8 Unknown_83B5FEC[] = {2, 0, 1}; //SHIFT, SUMMARY, CANCEL -static const u8 Unknown_83B5FEF[] = {3, 0, 1}; //SEND OUT, SUMMARY, CANCEL -static const u8 Unknown_83B5FF2[] = {0, 1}; //SUMMARY, CANCEL -static const struct PartyPopupMenu sBattlePartyPopupMenus[] = -{ - {ARRAY_COUNT(Unknown_83B5FEC), 9, Unknown_83B5FEC}, - {ARRAY_COUNT(Unknown_83B5FEF), 9, Unknown_83B5FEF}, - {ARRAY_COUNT(Unknown_83B5FF2), 9, Unknown_83B5FF2}, -}; - -void unref_sub_8094928(struct PokemonStorage *ptr) -{ - *ptr = gPokemonStorage; -} - -void unref_sub_8094940(struct PokemonStorage *ptr) -{ - gPokemonStorage = *ptr; -} - -void sub_8094958(void) -{ - sub_8094998(gUnknown_02038470, sub_803FBBC()); -} - -void sub_8094978(u8 arg1, u8 arg2) -{ - sub_8094A74((UNK_201606C_ARRAY) + arg1 * 3, arg2, arg1); -} - -static void sub_8094998(u8 arg[3], u8 player_number) -{ - int i; - u32 pos; - u8 temp[6]; - if (IsLinkDoubleBattle() == TRUE) - { - if (player_number) - { - *arg = 0x30; - arg[1] = 0x45; - arg[2] = 0x12; - } - else - { - *arg = 0x03; - arg[1] = 0x12; - arg[2] = 0x45; - } - } - else - { - if (!IsDoubleBattle()) - { - pos = 1; - *temp = gBattlerPartyIndexes[GetBattlerAtPosition(0)]; - for (i = 0; i <= 5; i++) - if (i != *temp) - temp[pos++] = i; - } - else - { - pos = 2; - *temp = gBattlerPartyIndexes[GetBattlerAtPosition(0)]; - temp[1] = gBattlerPartyIndexes[GetBattlerAtPosition(2)]; - for (i = 0; i <= 5; i++) - if ((i != *temp) && (i != temp[1])) - temp[pos++] = i; - } - for (i = 0; i <= 2; i++) - arg[i] = (temp[i << 1] << 4) | temp[(i << 1) + 1]; - } -} - -static void sub_8094A74(u8 arg[3], u8 player_number, u32 arg3) -{ - int i, j; - u8 temp[6]; - if (!GetBattlerSide(arg3)) - { - i = GetBattlerAtPosition(0); - j = GetBattlerAtPosition(2); - } - else - { - i = GetBattlerAtPosition(1); - j = GetBattlerAtPosition(3); - } - if (IsLinkDoubleBattle() == TRUE) - { - if (player_number) - { - *arg = 0x30; - arg[1] = 0x45; - arg[2] = 0x12; - } - else - { - *arg = 0x03; - arg[1] = 0x12; - arg[2] = 0x45; - } - } - else - { - if (!IsDoubleBattle()) - { - int pos = 1; - *temp = gBattlerPartyIndexes[i]; - for (i = 0; i <= 5; i++) - if (i != *temp) - temp[pos++] = i; - } - else - { - int pos = 2; - *temp = gBattlerPartyIndexes[i]; - temp[1] = gBattlerPartyIndexes[j]; - for (i = 0; i <= 5; i++) - if ((i != *temp) && (i != temp[1])) - temp[pos++] = i; - } - for (i = 0; i <= 2; i++) - arg[i] = (temp[i << 1] << 4) | temp[(i << 1) + 1]; - } -} - -void sub_8094B6C(u8 a, u8 b, u8 c) -{ - s32 i; - s32 j; - u8 temp[6]; - u8 r3; - u8 r7 = 0; - - if (IsLinkDoubleBattle()) - { - u8 *arr = &ewram1606Carr(0, a); - - for (i = 0, j = 0; i < 3; i++) - { - temp[j++] = arr[i] >> 4; - temp[j++] = arr[i] & 0xF; - } - r3 = temp[c]; - for (i = 0; i < 6; i++) - { - if (temp[i] == b) - { - r7 = temp[i]; - temp[i] = r3; - break; - } - } - if (i != 6) - { - temp[c] = r7; - - arr[0] = (temp[0] << 4) | temp[1]; - arr[1] = (temp[2] << 4) | temp[3]; - arr[2] = (temp[4] << 4) | temp[5]; - } - } -} - -u8 sub_8094C20(u8 monIndex) -{ - u8 retVal; - u8 val = monIndex & 1; - - monIndex /= 2; - if (val) - retVal = gUnknown_02038470[monIndex] & 0xF; - else - retVal = gUnknown_02038470[monIndex] >> 4; - return retVal; -} - -void sub_8094C54(u8 a, u8 b) -{ - u8 val = a & 1; - - a /= 2; - if (val) - gUnknown_02038470[a] = (gUnknown_02038470[a] & 0xF0) | b; - else - gUnknown_02038470[a] = (gUnknown_02038470[a] & 0xF) | (b << 4); -} - -void sub_8094C98(u8 a, u8 b) -{ - u8 r4 = sub_8094C20(a); - u8 r1 = sub_8094C20(b); - - sub_8094C54(a, r1); - sub_8094C54(b, r4); -} - -u8 pokemon_order_func(u8 a) -{ - u8 i; - u8 r2; - - for (i = 0, r2 = 0; i < 3; i++) - { - if ((gUnknown_02038470[i] >> 4) == a) - return r2; - r2++; - if ((gUnknown_02038470[i] & 0xF) == a) - return r2; - r2++; - } - return 0; -} - -void pokemon_change_order(void) -{ - u8 i; - - memcpy(ewram1B000.unk0, gPlayerParty, sizeof(gPlayerParty)); - for (i = 0; i < 6; i++) - { - u8 n = pokemon_order_func(i); - - memcpy(&gPlayerParty[n], &ewram1B000.unk0[i], sizeof(struct Pokemon)); - } -} - -static void sub_8094D60(void) -{ - struct Pokemon temp[6]; - u8 i; - - memcpy(temp, gPlayerParty, sizeof(gPlayerParty)); - for (i = 0; i < 6; i++) - { - u8 n = sub_8094C20(i); - - memcpy(&gPlayerParty[n], &temp[i], sizeof(struct Pokemon)); - } -} - -void unref_sub_8094DB0(void) -{ - u8 i; - u8 r4; - - for (i = 1; i < 6; i++) - { - u8 n = sub_8094C20(i); - - if (GetMonData(&gPlayerParty[n], MON_DATA_SPECIES) != 0 - && GetMonData(&gPlayerParty[n], MON_DATA_HP) != 0) - { - r4 = sub_8094C20(0); - sub_8094C98(0, i); - SwapPokemon(&gPlayerParty[r4], &gPlayerParty[n]); - break; - } - } -} - -void sub_8094E20(u8 a) -{ - gPaletteFade.bufferTransferDisabled = TRUE; - gUnknown_02038473 = a; - nullsub_14(); - pokemon_change_order(); - OpenPartyMenu(PARTY_MENU_TYPE_BATTLE, 0xFF); -} - -void sub_8094E4C(void) -{ - sub_8094E20(3); -} - -bool8 SetUpBattlePartyMenu(void) -{ - switch (EWRAM_1B000.setupState) - //switch (ewram1B000.unk264[0]) - { - case 0: - //TODO: try to get rid of this duplicate code - if (IsLinkDoubleBattle() == TRUE) - { - if (EWRAM_1B000.monIndex != 6) - { - TryCreatePartyMenuMonIcon(EWRAM_1B000.menuHandlerTaskId, EWRAM_1B000.monIndex, &gPlayerParty[EWRAM_1B000.monIndex]); - EWRAM_1B000.monIndex++; - } - else - { - EWRAM_1B000.monIndex = 0; - EWRAM_1B000.setupState++; - } - } - else - { - if (EWRAM_1B000.monIndex < 6) - { - TryCreatePartyMenuMonIcon(EWRAM_1B000.menuHandlerTaskId, EWRAM_1B000.monIndex, &gPlayerParty[EWRAM_1B000.monIndex]); - EWRAM_1B000.monIndex++; - } - else - { - EWRAM_1B000.monIndex = 0; - EWRAM_1B000.setupState++; - } - } - break; - case 1: - LoadHeldItemIconGraphics(); - EWRAM_1B000.setupState++; - break; - case 2: - CreateHeldItemIcons_806DC34(EWRAM_1B000.menuHandlerTaskId); - EWRAM_1B000.setupState++; - break; - case 3: - if (sub_806BD58(EWRAM_1B000.menuHandlerTaskId, EWRAM_1B000.monIndex) == 1) - { - EWRAM_1B000.monIndex = 0; - EWRAM_1B000.setupState++; - } - else - EWRAM_1B000.monIndex++; - break; - case 4: - PartyMenuPrintMonsLevelOrStatus(); - EWRAM_1B000.setupState++; - break; - case 5: - PrintPartyMenuMonNicknames(); - EWRAM_1B000.setupState++; - break; - case 6: - PartyMenuTryPrintMonsHP(); - EWRAM_1B000.setupState++; - break; - case 7: - nullsub_13(); - EWRAM_1B000.setupState++; - break; - case 8: - PartyMenuDrawHPBars(); - EWRAM_1B000.setupState++; - break; - case 9: - if (DrawPartyMonBackground(EWRAM_1B000.monIndex) == 1) - { - EWRAM_1B000.monIndex = 0; - EWRAM_1B000.setupState++; - } - else - EWRAM_1B000.monIndex++; - break; - case 10: - if (gUnknown_02038473 == 3) - { - if (GetItemEffectType(gSpecialVar_ItemId) == 10) - ewram1B000.promptTextId = 0xFF; - else - ewram1B000.promptTextId = 3; - } - return TRUE; - } - return FALSE; -} - -static void sub_8095050(u8 a, u8 b) -{ - if (!GetMonData(&gPlayerParty[b], MON_DATA_IS_EGG)) - { - if (gUnknown_02038473 == 1) - { - gTasks[EWRAM_1B000.menuHandlerTaskId].data[4] = 1; - gTasks[EWRAM_1B000.menuHandlerTaskId].data[5] = 1; - } - else - { - gTasks[EWRAM_1B000.menuHandlerTaskId].data[4] = 0; - gTasks[EWRAM_1B000.menuHandlerTaskId].data[5] = 0; - } - } - else - { - gTasks[EWRAM_1B000.menuHandlerTaskId].data[4] = 2; - gTasks[EWRAM_1B000.menuHandlerTaskId].data[5] = 2; - } - - ShowPartyPopupMenu(gTasks[a].data[4], sBattlePartyPopupMenus, sBattlePartyMenuActions, 0); -} - -void HandleBattlePartyMenu(u8 taskId) -{ - if (!gPaletteFade.active) - { - if (gUnknown_02038473 == 3 && GetItemEffectType(gSpecialVar_ItemId) == 10) - { - gPokemonItemUseCallback(taskId, gSpecialVar_ItemId, Task_80952E4); - return; - } - - switch (HandleDefaultPartyMenuInput(taskId)) - { - case A_BUTTON: - if (gUnknown_02038473 == 3) - { - if (GetMonData(&gPlayerParty[sub_806CA38(taskId)], MON_DATA_IS_EGG)) - PlaySE(SE_HAZURE); - else - { - sub_806D5A4(); - gPokemonItemUseCallback(taskId, gSpecialVar_ItemId, Task_80952E4); - } - } - else - { - PlaySE(SE_SELECT); - GetMonNickname(&gPlayerParty[sub_806CA38(taskId)], gStringVar1); - sub_8095050(taskId, sub_806CA38(taskId)); - SetTaskFuncWithFollowupFunc(taskId, Task_HandlePopupMenuInput, HandleBattlePartyMenu); - } - break; - case B_BUTTON: - if (gUnknown_02038473 == 1) - PlaySE(SE_HAZURE); - else - { - PlaySE(SE_SELECT); - if (gUnknown_02038473 == 3) - { - gUnknown_0202E8F4 = 0; - gTasks[taskId].func = Task_80952E4; - } - else - { - gUnknown_0202E8F4 = 0; - gTasks[taskId].func = Task_809527C; - } - } - break; - } - } -} - -static void Task_809527C(u8 taskId) -{ - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); - gTasks[taskId].func = Task_80952B4; -} - -static void Task_80952B4(u8 taskId) -{ - if (!gPaletteFade.active) - { - sub_8094D60(); - DestroyTask(taskId); - SetMainCallback2(sub_802E414); - } -} - -static void Task_80952E4(u8 taskId) -{ - if (gUnknown_0202E8F4 != 0) - Task_809527C(taskId); - else - { - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); - gTasks[taskId].func = Task_8095330; - } -} - -static void Task_8095330(u8 taskId) -{ - if (!gPaletteFade.active) - { - sub_8094D60(); - DestroyTask(taskId); - sub_80A6DCC(); - } -} - -static void Task_809535C(void) -{ - gPaletteFade.bufferTransferDisabled = TRUE; - SetPartyMenuSettings(PARTY_MENU_TYPE_BATTLE, 0xFF, HandleBattlePartyMenu, 5); - SetMainCallback2(Task_809538C); -} - -static void Task_809538C(void) -{ - do - { - if (InitPartyMenu() == TRUE) - { - sub_806C994(EWRAM_1B000.menuHandlerTaskId, gUnknown_020384F0); - ChangePartyMenuSelection(EWRAM_1B000.menuHandlerTaskId, 0); - GetMonNickname(&gPlayerParty[gUnknown_020384F0], gStringVar1); - sub_8095050(EWRAM_1B000.menuHandlerTaskId, gUnknown_020384F0); - SetTaskFuncWithFollowupFunc(EWRAM_1B000.menuHandlerTaskId, Task_HandlePopupMenuInput, HandleBattlePartyMenu); - SetMainCallback2(CB2_PartyMenuMain); - return; - } - } while (sub_80F9344() != 1); -} - -static void Task_HandlePopupMenuInput(u8 taskId) -{ - TaskFunc func; - - if (!gPaletteFade.active) - { - if (gMain.newAndRepeatedKeys & DPAD_UP) - { - PlaySE(SE_SELECT); - Menu_MoveCursor(-1); - return; - } - if (gMain.newAndRepeatedKeys & DPAD_DOWN) - { - PlaySE(SE_SELECT); - Menu_MoveCursor(1); - return; - } - if (gMain.newKeys & A_BUTTON) - { - PlaySE(SE_SELECT); - func = PartyMenuGetPopupMenuFunc(gTasks[taskId].data[4], - sBattlePartyPopupMenus, - sBattlePartyMenuActions, - Menu_GetCursorPos()); - func(taskId); - return; - } - if (gMain.newKeys & B_BUTTON) - { - PlaySE(SE_SELECT); - Task_BattlePartyMenuCancel(taskId); - return; - } - } -} - -static void Task_80954C0(u8 taskId) -{ - if (gUnknown_0202E8F6 == 0) - Task_BattlePartyMenuCancel(taskId); -} - -static void Task_ShowSummaryScreen(u8 taskId) -{ - u8 partySelection = sub_806CA38(taskId); - - if (!gPaletteFade.active) - { - DestroyTask(taskId); - EWRAM_1B000.unk262 = 1; - ShowPokemonSummaryScreen(gPlayerParty, partySelection, gPlayerPartyCount - 1, Task_809535C, PSS_MODE_NO_MOVE_ORDER_EDIT); - } -} - -static void Task_BattlePartyMenuSummary(u8 taskId) -{ - sub_806CA38(taskId); //an unused variable was probably set with this. - gTasks[taskId].func = Task_ShowSummaryScreen; - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); -} - -static void Task_BattlePartyMenuShift(u8 taskId) -{ - u8 partySelection; - u8 i; - u8 r4; - - ClosePartyPopupMenu(gTasks[taskId].data[4], sBattlePartyPopupMenus); - partySelection = sub_806CA38(taskId); - if (IsLinkDoubleBattle() == TRUE && (partySelection == 1 || partySelection == 4 || partySelection == 5)) - { - sub_806D5A4(); - StringCopy(gStringVar1, sub_8040D08()); - StringExpandPlaceholders(gStringVar4, gOtherText_CantSwitchPokeWithYours); - sub_806E834(gStringVar4, 0); - gTasks[taskId].func = Task_80954C0; - return; - } - if (GetMonData(&gPlayerParty[partySelection], MON_DATA_HP) == 0) - { - sub_806D5A4(); - GetMonNickname(&gPlayerParty[partySelection], gStringVar1); - StringExpandPlaceholders(gStringVar4, gOtherText_NoEnergyLeft); - sub_806E834(gStringVar4, 0); - gTasks[taskId].func = Task_80954C0; - return; - } - for (i = 0; i < gBattlersCount; i++) - { - if (GetBattlerSide(i) == 0 - && sub_8094C20(partySelection) == gBattlerPartyIndexes[i]) - { - sub_806D5A4(); - GetMonNickname(&gPlayerParty[partySelection], gStringVar1); - StringExpandPlaceholders(gStringVar4, gOtherText_AlreadyBattle); - sub_806E834(gStringVar4, 0); - gTasks[taskId].func = Task_80954C0; - return; - } - } - if (GetMonData(&gPlayerParty[partySelection], MON_DATA_IS_EGG)) - { - sub_806D5A4(); - StringExpandPlaceholders(gStringVar4, gOtherText_EGGCantBattle); - sub_806E834(gStringVar4, 0); - gTasks[taskId].func = Task_80954C0; - return; - } - if (sub_8094C20(partySelection) == EWRAM_1609D) - { - sub_806D5A4(); - GetMonNickname(&gPlayerParty[partySelection], gStringVar1); - StringExpandPlaceholders(gStringVar4, gOtherText_AlreadySelected); - sub_806E834(gStringVar4, 0); - gTasks[taskId].func = Task_80954C0; - return; - } - if (gUnknown_02038473 == 4) - { - sub_806D5A4(); - sub_8040B8C(); - sub_806E834(gStringVar4, 0); - gTasks[taskId].func = Task_80954C0; - return; - } - if (gUnknown_02038473 == 2) - { - u8 r0; - u8 r4 = gBankInMenu; - - sub_806D5A4(); - r0 = pokemon_order_func(gBattlerPartyIndexes[r4]); - GetMonNickname(&gPlayerParty[r0], gStringVar1); - StringExpandPlaceholders(gStringVar4, gOtherText_CantBeSwitched); - sub_806E834(gStringVar4, 0); - gTasks[taskId].func = Task_80954C0; - return; - } - gUnknown_0202E8F5 = sub_8094C20(partySelection); - gUnknown_0202E8F4 = 1; - r4 = pokemon_order_func(gBattlerPartyIndexes[gBankInMenu]); - sub_8094C98(r4, partySelection); - SwapPokemon(&gPlayerParty[r4], &gPlayerParty[partySelection]); - gTasks[taskId].func = Task_809527C; -} - -static void Task_BattlePartyMenuCancel(u8 taskId) -{ - Menu_DestroyCursor(); - ClosePartyPopupMenu(gTasks[taskId].data[4], sBattlePartyPopupMenus); - gTasks[taskId].data[4] = gTasks[taskId].data[5]; - PrintPartyMenuPromptText(0, 0); - SwitchTaskToFollowupFunc(taskId); -} diff --git a/src/battle/battle_records.c b/src/battle/battle_records.c deleted file mode 100644 index d94d88032..000000000 --- a/src/battle/battle_records.c +++ /dev/null @@ -1,382 +0,0 @@ -#include "global.h" -#include "battle_records.h" -#include "constants/game_stat.h" -#include "link.h" -#include "menu.h" -#include "overworld.h" -#include "string_util.h" -#include "strings2.h" -#include "trainer_card.h" - -struct DebugStruct1 -{ - u16 var0; - u8 var1[10]; -}; - -extern struct LinkPlayerEventObject gLinkPlayerEventObjects[4]; -extern u8 gBattleOutcome; - -#if DEBUG -const struct DebugStruct1 gUnknown_Debug_4245CC[] = -{ - { 1, _("NUMBER1") }, - { 2, _("ナンバー2") }, - { 3, _("ナンバー3") }, - { 4, _("ナンバー4") }, - { 5, _("ナンバー5") }, - { 6, _("ナンバー6") }, - { 7, _("ナンバー7") }, -}; - -const struct {u8 unk0; u8 unk1;} gUnknown_Debug_8424620[] = -{ - { 1, 1 }, - { 2, 1 }, - { 3, 1 }, -}; -#endif - -static void InitLinkBattleRecord(struct LinkBattleRecord *record) -{ - CpuFill16(0, record, sizeof(struct LinkBattleRecord)); - record->name[0] = 0xFF; - record->trainerId = 0; - record->wins = 0; - record->losses = 0; - record->draws = 0; -} - -static void InitLinkBattleRecords_(struct LinkBattleRecord *records) -{ - int i; - for (i = 0; i < 5; i++) - { - InitLinkBattleRecord(records + i); - } - SetGameStat(GAME_STAT_LINK_BATTLE_WINS, 0); - SetGameStat(GAME_STAT_LINK_BATTLE_LOSSES, 0); - SetGameStat(GAME_STAT_LINK_BATTLE_DRAWS, 0); -} - -static int GetLinkBattleRecordTotalBattles(struct LinkBattleRecord *record) -{ - return record->wins + record->losses + record->draws; -} - -static int FindLinkBattleRecord(struct LinkBattleRecord *records, const u8 *name, u16 trainerId) -{ - int i; - - for (i = 0; i < 5; i++) - { - memcpy(gStringVar1, records[i].name, 7); - gStringVar1[7] = EOS; - if (!StringCompareWithoutExtCtrlCodes(gStringVar1, name) && records[i].trainerId == trainerId) - return i; - } - - return 5; -} - -static void SortLinkBattleRecords(struct LinkBattleRecord *records) -{ - int i, j; - - for (i = 4; i > 0; i--) - { - for (j = i - 1; j >= 0; j--) - { - int totalBattlesI = GetLinkBattleRecordTotalBattles(records + i); - int totalBattlesJ = GetLinkBattleRecordTotalBattles(records + j); - - if (totalBattlesI > totalBattlesJ) - { - struct LinkBattleRecord temp = *(records + i); - *(records + i) = *(records + j); - *(records + j) = temp; - } - } - } -} - -static void UpdateLinkBattleRecord(struct LinkBattleRecord *record, int battleOutcome) -{ - switch (battleOutcome) - { - case 1: - record->wins++; - if (record->wins > 9999) - record->wins = 9999; - break; - case 2: - record->losses++; - if (record->losses > 9999) - record->losses = 9999; - break; - case 3: - record->draws++; - if (record->draws > 9999) - record->draws = 9999; - break; - } -} - -static void UpdateLinkBattleGameStats(int battleOutcome) -{ - u8 stat; - - switch (battleOutcome) - { - case 1: - stat = GAME_STAT_LINK_BATTLE_WINS; - break; - case 2: - stat = GAME_STAT_LINK_BATTLE_LOSSES; - break; - case 3: - stat = GAME_STAT_LINK_BATTLE_DRAWS; - break; - default: - return; - } - - if (GetGameStat(stat) < 9999) - IncrementGameStat(stat); -} - -static void UpdateLinkBattleRecords_(struct LinkBattleRecord *records, const u8 *name, u16 trainerId, int battleOutcome, u8 language) -{ - int index; - UpdateLinkBattleGameStats(battleOutcome); - SortLinkBattleRecords(records); - index = FindLinkBattleRecord(records, name, trainerId); - if (index == 5) - { - index = 4; - InitLinkBattleRecord(records + index); - if (language == LANGUAGE_JAPANESE) - { - records[index].name[0] = EXT_CTRL_CODE_BEGIN; - records[index].name[1] = 0x15; - StringCopyN(records[index].name + 2, name, 5); - } - else - { - StringCopyN(records[index].name, name, 7); - } - - // needed block to match - { - struct LinkBattleRecord *record = records + index; - record->trainerId = trainerId; - } - } - UpdateLinkBattleRecord(records + index, battleOutcome); - SortLinkBattleRecords(records); -} - -void InitLinkBattleRecords(void) -{ - InitLinkBattleRecords_(gSaveBlock1.linkBattleRecords); -} - -static void IncTrainerCardWins(int id) -{ - u16 *wins = &gTrainerCards[id].linkBattleWins; - (*wins)++; - if (*wins > 9999) - *wins = 9999; -} - -static void IncTrainerCardLosses(int id) -{ - u16 *losses = &gTrainerCards[id].linkBattleLosses; - (*losses)++; - if (*losses > 9999) - *losses = 9999; -} - -static void UpdateTrainerCardWinsLosses(int id) -{ - switch (gBattleOutcome) - { - case 1: - IncTrainerCardWins(id ^ 1); - IncTrainerCardLosses(id); - break; - case 2: - IncTrainerCardLosses(id ^ 1); - IncTrainerCardWins(id); - break; - } -} - -void UpdateLinkBattleRecords(int id) -{ - UpdateTrainerCardWinsLosses(id); - UpdateLinkBattleRecords_( - gSaveBlock1.linkBattleRecords, - gTrainerCards[id].playerName, - gTrainerCards[id].trainerId, - gBattleOutcome, - gLinkPlayers[gLinkPlayerEventObjects[id].linkPlayerId].language); -} - -#if DEBUG -void debug_sub_81257E0(void) -{ - u32 i; - - InitLinkBattleRecords(); - for (i = 0; i < 3; i++) - { - u32 id = gUnknown_Debug_8424620[i].unk0 - 1; - - UpdateLinkBattleRecords_( - gSaveBlock1.linkBattleRecords, - gUnknown_Debug_4245CC[id].var1, - gUnknown_Debug_4245CC[id].var0, - gUnknown_Debug_8424620[i].unk1, - gLinkPlayers[gLinkPlayerEventObjects[id].linkPlayerId].language); - } -} -#endif - -static void PrintLinkBattleWinsLossesDraws(struct LinkBattleRecord *records) -{ - ConvertIntToDecimalStringN_DigitWidth6(gStringVar1, GetGameStat(GAME_STAT_LINK_BATTLE_WINS), STR_CONV_MODE_RIGHT_ALIGN, 4); - ConvertIntToDecimalStringN_DigitWidth6(gStringVar2, GetGameStat(GAME_STAT_LINK_BATTLE_LOSSES), STR_CONV_MODE_RIGHT_ALIGN, 4); - ConvertIntToDecimalStringN_DigitWidth6(gStringVar3, GetGameStat(GAME_STAT_LINK_BATTLE_DRAWS), STR_CONV_MODE_RIGHT_ALIGN, 4); - Menu_PrintText(gOtherText_WinRecord, 3, 3); -} - -static void PrintLinkBattleRecord(struct LinkBattleRecord *record, u8 y) -{ - if (!record->wins && !record->losses && !record->draws) - { - u8 buffer[16]; - buffer[0] = EXT_CTRL_CODE_BEGIN; - buffer[1] = 0x14; - buffer[2] = 6; - buffer[3] = EXT_CTRL_CODE_BEGIN; - buffer[4] = 0x11; - buffer[5] = 1; - StringCopy(buffer + 6, gOtherText_SevenDashes); - Menu_PrintText(buffer, 3, y); - StringCopy(buffer + 6, gOtherText_FourDashes); - Menu_PrintText(buffer, 11, y); - Menu_PrintText(buffer, 17, y); - Menu_PrintText(buffer, 23, y); - } - else - { - StringFillWithTerminator(gStringVar1, 8); - StringCopyN(gStringVar1, record->name, 7); - Menu_PrintText(gStringVar1, 3, y); - gStringVar1[0] = EXT_CTRL_CODE_BEGIN; - gStringVar1[1] = 0x14; - gStringVar1[2] = 6; - ConvertIntToDecimalStringN(gStringVar1 + 3, record->wins, STR_CONV_MODE_RIGHT_ALIGN, 4); - Menu_PrintText(gStringVar1, 11, y); - ConvertIntToDecimalStringN(gStringVar1 + 3, record->losses, STR_CONV_MODE_RIGHT_ALIGN, 4); - Menu_PrintText(gStringVar1, 17, y); - ConvertIntToDecimalStringN(gStringVar1 + 3, record->draws, STR_CONV_MODE_RIGHT_ALIGN, 4); - Menu_PrintText(gStringVar1, 23, y); - } -} - -void ShowLinkBattleRecords(void) -{ - s32 i; - Menu_DrawStdWindowFrame(1, 0, 28, 18); - MenuPrint_Centered(gOtherText_BattleResults, 0, 1, 240); - - PrintLinkBattleWinsLossesDraws(gSaveBlock1.linkBattleRecords); -#if ENGLISH - Menu_PrintText(gOtherText_WinLoseDraw, 12, 6); -#elif GERMAN - Menu_PrintTextPixelCoords(gOtherText_WinLoseDraw, 88, 48, 1); -#endif - - for (i = 0; i < 5; i++) - { - PrintLinkBattleRecord(&gSaveBlock1.linkBattleRecords[i], 6 + (i + 1) * 2); - } -} - -static bool32 sub_8110494(u8 level) -{ - struct BattleTowerData *battleTower = &gSaveBlock2.battleTower; - - switch (battleTower->var_4AE[level]) - { - case 0: - return FALSE; - case 1: - return FALSE; - case 2: - return TRUE; - case 4: - return FALSE; - case 3: - return TRUE; - case 5: - return FALSE; - case 6: - return TRUE; - default: - return FALSE; - } -} - -static void PrintWinStreak(const u8 *str, u16 streak, u8 left, u8 top) -{ - Menu_PrintText(str, left, top); - if (streak > 9999) - streak = 9999; - AlignInt1InMenuWindow(gStringVar1, streak, 24, 1); - Menu_PrintText(gOtherText_WinStreak, left + 7, top); -} - -static void PrintRecordWinStreak(u8 level, u8 left, u8 top) -{ - struct BattleTowerData *battleTower = &gSaveBlock2.battleTower; - u16 winStreak = battleTower->recordWinStreaks[level]; - PrintWinStreak(gOtherText_Record, winStreak, left, top); -} - -static u16 GetLastWinStreak(u8 level) -{ - u16 winStreak = gSaveBlock2.battleTower.currentWinStreaks[level]; - if (winStreak > 9999) - winStreak = 9999; - - return winStreak; -} - -static void PrintLastWinStreak(u8 level, u8 left, u8 top) -{ - u16 winStreak = GetLastWinStreak(level); - if (sub_8110494(level) == TRUE) - PrintWinStreak(gOtherText_Current, winStreak, left, top); - else - PrintWinStreak(gOtherText_Prev, winStreak, left, top); -} - -void ShowBattleTowerRecords(void) -{ - u16 i; - Menu_DrawStdWindowFrame(3, 1, 27, 17); - MenuPrint_Centered(gOtherText_BattleTowerResults, 3, 2, 0xC8); - Menu_PrintText(gOtherText_Lv50, 5, 6); - Menu_PrintText(gOtherText_Lv100, 5, 12); - for (i = 5; i < 26; i++) - { - sub_8071F60(CHAR_HYPHEN, i, 10); - } - PrintLastWinStreak(0, 10, 6); - PrintRecordWinStreak(0, 10, 8); - PrintLastWinStreak(1, 10, 12); - PrintRecordWinStreak(1, 10, 14); -} diff --git a/src/battle/battle_setup.c b/src/battle/battle_setup.c deleted file mode 100644 index c457cc8ec..000000000 --- a/src/battle/battle_setup.c +++ /dev/null @@ -1,1482 +0,0 @@ -#include "global.h" -#include "battle_setup.h" -#include "battle.h" -#include "battle_transition.h" -#include "data2.h" -#include "event_data.h" -#include "field_control_avatar.h" -#include "field_fadetransition.h" -#include "field_message_box.h" -#include "field_player_avatar.h" -#include "field_weather.h" -#include "fieldmap.h" -#include "fldeff_poison.h" -#include "main.h" -#include "metatile_behavior.h" -#include "palette.h" -#include "random.h" -#include "overworld.h" -#include "safari_zone.h" -#include "script.h" -#include "script_pokemon_80C4.h" -#include "secret_base.h" -#include "sound.h" -#include "starter_choose.h" -#include "string_util.h" -#include "strings.h" -#include "task.h" -#include "text.h" -#include "trainer.h" -#include "constants/map_types.h" -#include "constants/maps.h" -#include "constants/opponents.h" -#include "constants/songs.h" -#include "constants/species.h" - -extern u16 gSpecialVar_Result; - -extern void (*gFieldCallback)(void); - -EWRAM_DATA static u16 sTrainerBattleMode = 0; -EWRAM_DATA u16 gTrainerBattleOpponent = 0; -EWRAM_DATA static u16 sTrainerEventObjectLocalId = 0; -EWRAM_DATA static u8 *sTrainerIntroSpeech = NULL; -EWRAM_DATA static u8 *sTrainerDefeatSpeech = NULL; -EWRAM_DATA static u8 *sTrainerVictorySpeech = NULL; -EWRAM_DATA static u8 *sTrainerCannotBattleSpeech = NULL; -EWRAM_DATA static u8 *sTrainerBattleScriptRetAddr = NULL; -EWRAM_DATA static u8 *sTrainerBattleEndScript = NULL; - -extern u16 gBattleTypeFlags; -extern u16 gSpecialVar_LastTalked; -extern u8 gBattleOutcome; - -extern struct EventObject gEventObjects[]; - -extern u8 gUnknown_0819F818[]; -extern u8 gUnknown_0819F840[]; -extern u8 gUnknown_0819F878[]; -extern u8 gUnknown_0819F887[]; -extern u8 gUnknown_0819F8AE[]; - -extern u8 gUnknown_0819F80B[]; -extern u8 gUnknown_081C6C02[]; - -// The first transition is used if the enemy pokemon are lower level than our pokemon. -// Otherwise, the second transition is used. -static const u8 gBattleTransitionTable_Wild[][2] = -{ - {B_TRANSITION_SLICE, B_TRANSITION_WHITEFADE}, // Normal - {B_TRANSITION_CLOCKWISE_BLACKFADE, B_TRANSITION_GRID_SQUARES}, // Cave - {B_TRANSITION_BLUR, B_TRANSITION_GRID_SQUARES}, // Cave with flash used - {B_TRANSITION_WAVE, B_TRANSITION_RIPPLE}, // Water -}; -static const u8 gBattleTransitionTable_Trainer[][2] = -{ - {B_TRANSITION_POKEBALLS_TRAIL, B_TRANSITION_SHARDS}, // Normal - {B_TRANSITION_SHUFFLE, B_TRANSITION_BIG_POKEBALL}, // Cave - {B_TRANSITION_BLUR, B_TRANSITION_GRID_SQUARES}, // Cave with flash used - {B_TRANSITION_SWIRL, B_TRANSITION_RIPPLE}, // Water -}; - -enum -{ - TRAINER_PARAM_LOAD_VAL_8BIT, - TRAINER_PARAM_LOAD_VAL_16BIT, - TRAINER_PARAM_LOAD_VAL_32BIT, - TRAINER_PARAM_CLEAR_VAL_8BIT, - TRAINER_PARAM_CLEAR_VAL_16BIT, - TRAINER_PARAM_CLEAR_VAL_32BIT, - TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR, -}; - -struct TrainerBattleParameter -{ - void *varPtr; - u8 ptrType; -}; - -static const struct TrainerBattleParameter gTrainerBattleSpecs_0[] = -{ - {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, - {&gTrainerBattleOpponent, TRAINER_PARAM_LOAD_VAL_16BIT}, - {&sTrainerEventObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, - {&sTrainerIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerDefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, - {&sTrainerCannotBattleSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, - {&sTrainerBattleEndScript, TRAINER_PARAM_CLEAR_VAL_32BIT}, - {&sTrainerBattleScriptRetAddr, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR}, -}; -static const struct TrainerBattleParameter gTrainerBattleSpecs_1[] = -{ - {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, - {&gTrainerBattleOpponent, TRAINER_PARAM_LOAD_VAL_16BIT}, - {&sTrainerEventObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, - {&sTrainerIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerDefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, - {&sTrainerCannotBattleSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, - {&sTrainerBattleEndScript, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerBattleScriptRetAddr, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR}, -}; -static const struct TrainerBattleParameter gTrainerBattleSpecs_2[] = -{ - {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, - {&gTrainerBattleOpponent, TRAINER_PARAM_LOAD_VAL_16BIT}, - {&sTrainerEventObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, - {&sTrainerIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerDefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, - {&sTrainerCannotBattleSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerBattleEndScript, TRAINER_PARAM_CLEAR_VAL_32BIT}, - {&sTrainerBattleScriptRetAddr, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR}, -}; -static const struct TrainerBattleParameter gTrainerBattleSpecs_3[] = -{ - {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, - {&gTrainerBattleOpponent, TRAINER_PARAM_LOAD_VAL_16BIT}, - {&sTrainerEventObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, - {&sTrainerIntroSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, - {&sTrainerDefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, - {&sTrainerCannotBattleSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, - {&sTrainerBattleEndScript, TRAINER_PARAM_CLEAR_VAL_32BIT}, - {&sTrainerBattleScriptRetAddr, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR}, -}; -static const struct TrainerBattleParameter gTrainerBattleSpecs_4[] = -{ - {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, - {&gTrainerBattleOpponent, TRAINER_PARAM_LOAD_VAL_16BIT}, - {&sTrainerEventObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, - {&sTrainerIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerDefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, - {&sTrainerCannotBattleSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerBattleEndScript, TRAINER_PARAM_LOAD_VAL_32BIT}, - {&sTrainerBattleScriptRetAddr, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR}, -}; - -const struct TrainerEyeTrainer gTrainerEyeTrainers[] = -{ - { - {TRAINER_ROSE_1, TRAINER_ROSE_2, TRAINER_ROSE_3, TRAINER_ROSE_4, TRAINER_ROSE_5}, - MAP_GROUP(ROUTE118), - MAP_NUM(ROUTE118), - }, - { - {TRAINER_DUSTY_1, TRAINER_DUSTY_2, TRAINER_DUSTY_3, TRAINER_DUSTY_4, TRAINER_DUSTY_5}, - MAP_GROUP(ROUTE111), - MAP_NUM(ROUTE111), - }, - { - {TRAINER_LOLA_1, TRAINER_LOLA_2, TRAINER_LOLA_3, TRAINER_LOLA_4, TRAINER_LOLA_5}, - MAP_GROUP(ROUTE109), - MAP_NUM(ROUTE109), - }, - { - {TRAINER_RICKY_1, TRAINER_RICKY_2, TRAINER_RICKY_3, TRAINER_RICKY_4, TRAINER_RICKY_5}, - MAP_GROUP(ROUTE109), - MAP_NUM(ROUTE109), - }, - { - {TRAINER_RITA_AND_SAM_1, TRAINER_RITA_AND_SAM_2, TRAINER_RITA_AND_SAM_3, TRAINER_RITA_AND_SAM_4, TRAINER_RITA_AND_SAM_5}, - MAP_GROUP(ROUTE124), - MAP_NUM(ROUTE124), - }, - { - {TRAINER_BROOKE_1, TRAINER_BROOKE_2, TRAINER_BROOKE_3, TRAINER_BROOKE_4, TRAINER_BROOKE_5}, - MAP_GROUP(ROUTE111), - MAP_NUM(ROUTE111), - }, - { - {TRAINER_WILTON_1, TRAINER_WILTON_2, TRAINER_WILTON_3, TRAINER_WILTON_4, TRAINER_WILTON_5}, - MAP_GROUP(ROUTE111), - MAP_NUM(ROUTE111), - }, - { - {TRAINER_VALERIE_1, TRAINER_VALERIE_2, TRAINER_VALERIE_3, TRAINER_VALERIE_4, TRAINER_VALERIE_5}, - MAP_GROUP(MT_PYRE_6F), - MAP_NUM(MT_PYRE_6F), - }, - { - {TRAINER_CINDY_1, TRAINER_CINDY_3, TRAINER_CINDY_4, TRAINER_CINDY_5, TRAINER_CINDY_6}, - MAP_GROUP(ROUTE104), - MAP_NUM(ROUTE104), - }, - { - {TRAINER_JESSICA_1, TRAINER_JESSICA_2, TRAINER_JESSICA_3, TRAINER_JESSICA_4, TRAINER_JESSICA_5}, - MAP_GROUP(ROUTE121), - MAP_NUM(ROUTE121), - }, - { - {TRAINER_WINSTON_1, TRAINER_WINSTON_2, TRAINER_WINSTON_3, TRAINER_WINSTON_4, TRAINER_WINSTON_5}, - MAP_GROUP(ROUTE104), - MAP_NUM(ROUTE104), - }, - { - {TRAINER_STEVE_1, TRAINER_STEVE_2, TRAINER_STEVE_3, TRAINER_STEVE_4, TRAINER_STEVE_5}, - MAP_GROUP(ROUTE114), - MAP_NUM(ROUTE114), - }, - { - {TRAINER_TONY_1, TRAINER_TONY_2, TRAINER_TONY_3, TRAINER_TONY_4, TRAINER_TONY_5}, - MAP_GROUP(ROUTE107), - MAP_NUM(ROUTE107), - }, - { - {TRAINER_NOB_1, TRAINER_NOB_2, TRAINER_NOB_3, TRAINER_NOB_4, TRAINER_NOB_5}, - MAP_GROUP(ROUTE115), - MAP_NUM(ROUTE115), - }, - { - {TRAINER_DALTON_1, TRAINER_DALTON_2, TRAINER_DALTON_3, TRAINER_DALTON_4, TRAINER_DALTON_5}, - MAP_GROUP(ROUTE118), - MAP_NUM(ROUTE118), - }, - { - {TRAINER_BERNIE_1, TRAINER_BERNIE_2, TRAINER_BERNIE_3, TRAINER_BERNIE_4, TRAINER_BERNIE_5}, - MAP_GROUP(ROUTE114), - MAP_NUM(ROUTE114), - }, - { - {TRAINER_ETHAN_1, TRAINER_ETHAN_2, TRAINER_ETHAN_3, TRAINER_ETHAN_4, TRAINER_ETHAN_5}, - MAP_GROUP(JAGGED_PASS), - MAP_NUM(JAGGED_PASS), - }, - { - {TRAINER_JOHN_AND_JAY_1, TRAINER_JOHN_AND_JAY_2, TRAINER_JOHN_AND_JAY_3, TRAINER_JOHN_AND_JAY_4, TRAINER_JOHN_AND_JAY_5}, - MAP_GROUP(METEOR_FALLS_1F_2R), - MAP_NUM(METEOR_FALLS_1F_2R), - }, - { - {TRAINER_BRANDON_1, TRAINER_BRANDON_2, TRAINER_BRANDON_3, TRAINER_BRANDON_4, TRAINER_BRANDON_5}, - MAP_GROUP(ROUTE120), - MAP_NUM(ROUTE120), - }, - { - {TRAINER_CAMERON_1, TRAINER_CAMERON_2, TRAINER_CAMERON_3, TRAINER_CAMERON_4, TRAINER_CAMERON_5}, - MAP_GROUP(ROUTE123), - MAP_NUM(ROUTE123), - }, - { - {TRAINER_JACKI_1, TRAINER_JACKI_2, TRAINER_JACKI_3, TRAINER_JACKI_4, TRAINER_JACKI_5}, - MAP_GROUP(ROUTE123), - MAP_NUM(ROUTE123), - }, - { - {TRAINER_WALTER_1, TRAINER_WALTER_2, TRAINER_WALTER_3, TRAINER_WALTER_4, TRAINER_WALTER_5}, - MAP_GROUP(ROUTE121), - MAP_NUM(ROUTE121), - }, - { - {TRAINER_KAREN_1, TRAINER_KAREN_2, TRAINER_KAREN_3, TRAINER_KAREN_4, TRAINER_KAREN_5}, - MAP_GROUP(ROUTE116), - MAP_NUM(ROUTE116), - }, - { - {TRAINER_JERRY_1, TRAINER_JERRY_2, TRAINER_JERRY_3, TRAINER_JERRY_4, TRAINER_JERRY_5}, - MAP_GROUP(ROUTE116), - MAP_NUM(ROUTE116), - }, - { - {TRAINER_ANNA_AND_MEG_1, TRAINER_ANNA_AND_MEG_2, TRAINER_ANNA_AND_MEG_3, TRAINER_ANNA_AND_MEG_4, TRAINER_ANNA_AND_MEG_5}, - MAP_GROUP(ROUTE117), - MAP_NUM(ROUTE117), - }, - { - {TRAINER_ISABEL_1, TRAINER_ISABEL_2, TRAINER_ISABEL_3, TRAINER_ISABEL_4, TRAINER_ISABEL_5}, - MAP_GROUP(ROUTE110), - MAP_NUM(ROUTE110), - }, - { - {TRAINER_MIGUEL_1, TRAINER_MIGUEL_2, TRAINER_MIGUEL_3, TRAINER_MIGUEL_4, TRAINER_MIGUEL_5}, - MAP_GROUP(ROUTE103), - MAP_NUM(ROUTE103), - }, - { - {TRAINER_TIMOTHY_1, TRAINER_TIMOTHY_2, TRAINER_TIMOTHY_3, TRAINER_TIMOTHY_4, TRAINER_TIMOTHY_5}, - MAP_GROUP(ROUTE115), - MAP_NUM(ROUTE115), - }, - { - {TRAINER_SHELBY_1, TRAINER_SHELBY_2, TRAINER_SHELBY_3, TRAINER_SHELBY_4, TRAINER_SHELBY_5}, - MAP_GROUP(MT_CHIMNEY), - MAP_NUM(MT_CHIMNEY), - }, - { - {TRAINER_CALVIN_1, TRAINER_CALVIN_2, TRAINER_CALVIN_3, TRAINER_CALVIN_4, TRAINER_CALVIN_5}, - MAP_GROUP(ROUTE102), - MAP_NUM(ROUTE102), - }, - { - {TRAINER_ELLIOT_1, TRAINER_ELLIOT_2, TRAINER_ELLIOT_3, TRAINER_ELLIOT_4, TRAINER_ELLIOT_5}, - MAP_GROUP(ROUTE106), - MAP_NUM(ROUTE106), - }, - { - {TRAINER_ABIGAIL_1, TRAINER_ABIGAIL_2, TRAINER_ABIGAIL_3, TRAINER_ABIGAIL_4, TRAINER_ABIGAIL_5}, - MAP_GROUP(ROUTE110), - MAP_NUM(ROUTE110), - }, - { - {TRAINER_BENJAMIN_1, TRAINER_BENJAMIN_2, TRAINER_BENJAMIN_3, TRAINER_BENJAMIN_4, TRAINER_BENJAMIN_5}, - MAP_GROUP(ROUTE110), - MAP_NUM(ROUTE110), - }, - { - {TRAINER_ISAIAH_1, TRAINER_ISAIAH_2, TRAINER_ISAIAH_3, TRAINER_ISAIAH_4, TRAINER_ISAIAH_5}, - MAP_GROUP(ROUTE128), - MAP_NUM(ROUTE128), - }, - { - {TRAINER_KATELYN_1, TRAINER_KATELYN_2, TRAINER_KATELYN_3, TRAINER_KATELYN_4, TRAINER_KATELYN_5}, - MAP_GROUP(ROUTE128), - MAP_NUM(ROUTE128), - }, - { - {TRAINER_MARIA_1, TRAINER_MARIA_2, TRAINER_MARIA_3, TRAINER_MARIA_4, TRAINER_MARIA_5}, - MAP_GROUP(ROUTE117), - MAP_NUM(ROUTE117), - }, - { - {TRAINER_DYLAN_1, TRAINER_DYLAN_2, TRAINER_DYLAN_3, TRAINER_DYLAN_4, TRAINER_DYLAN_5}, - MAP_GROUP(ROUTE117), - MAP_NUM(ROUTE117), - }, - { - {TRAINER_NICOLAS_1, TRAINER_NICOLAS_2, TRAINER_NICOLAS_3, TRAINER_NICOLAS_4, TRAINER_NICOLAS_5}, - MAP_GROUP(METEOR_FALLS_1F_2R), - MAP_NUM(METEOR_FALLS_1F_2R), - }, - { - {TRAINER_ROBERT_1, TRAINER_ROBERT_2, TRAINER_ROBERT_3, TRAINER_ROBERT_4, TRAINER_ROBERT_5}, - MAP_GROUP(ROUTE120), - MAP_NUM(ROUTE120), - }, - { - {TRAINER_LAO_1, TRAINER_LAO_2, TRAINER_LAO_3, TRAINER_LAO_4, TRAINER_LAO_5}, - MAP_GROUP(ROUTE113), - MAP_NUM(ROUTE113), - }, - { - {TRAINER_CYNDY_1, TRAINER_CYNDY_2, TRAINER_CYNDY_3, TRAINER_CYNDY_4, TRAINER_CYNDY_5}, - MAP_GROUP(ROUTE115), - MAP_NUM(ROUTE115), - }, - { - {TRAINER_MADELINE_1, TRAINER_MADELINE_2, TRAINER_MADELINE_3, TRAINER_MADELINE_4, TRAINER_MADELINE_5}, - MAP_GROUP(ROUTE113), - MAP_NUM(ROUTE113), - }, - { - {TRAINER_JENNY_1, TRAINER_JENNY_2, TRAINER_JENNY_3, TRAINER_JENNY_4, TRAINER_JENNY_5}, - MAP_GROUP(ROUTE124), - MAP_NUM(ROUTE124), - }, - { - {TRAINER_DIANA_1, TRAINER_DIANA_2, TRAINER_DIANA_3, TRAINER_DIANA_4, TRAINER_DIANA_5}, - MAP_GROUP(JAGGED_PASS), - MAP_NUM(JAGGED_PASS), - }, - { - {TRAINER_AMY_AND_LIV_1, TRAINER_AMY_AND_LIV_2, TRAINER_AMY_AND_LIV_4, TRAINER_AMY_AND_LIV_5, TRAINER_AMY_AND_LIV_6}, - MAP_GROUP(ROUTE103), - MAP_NUM(ROUTE103), - }, - { - {TRAINER_ERNEST_1, TRAINER_ERNEST_2, TRAINER_ERNEST_3, TRAINER_ERNEST_4, TRAINER_ERNEST_5}, - MAP_GROUP(ROUTE125), - MAP_NUM(ROUTE125), - }, - { - {TRAINER_EDWIN_1, TRAINER_EDWIN_2, TRAINER_EDWIN_3, TRAINER_EDWIN_4, TRAINER_EDWIN_5}, - MAP_GROUP(ROUTE110), - MAP_NUM(ROUTE110), - }, - { - {TRAINER_LYDIA_1, TRAINER_LYDIA_2, TRAINER_LYDIA_3, TRAINER_LYDIA_4, TRAINER_LYDIA_5}, - MAP_GROUP(ROUTE117), - MAP_NUM(ROUTE117), - }, - { - {TRAINER_ISAAC_1, TRAINER_ISAAC_2, TRAINER_ISAAC_3, TRAINER_ISAAC_4, TRAINER_ISAAC_5}, - MAP_GROUP(ROUTE117), - MAP_NUM(ROUTE117), - }, - { - {TRAINER_CATHERINE_1, TRAINER_CATHERINE_2, TRAINER_CATHERINE_3, TRAINER_CATHERINE_4, TRAINER_CATHERINE_5}, - MAP_GROUP(ROUTE119), - MAP_NUM(ROUTE119), - }, - { - {TRAINER_JACKSON_1, TRAINER_JACKSON_2, TRAINER_JACKSON_3, TRAINER_JACKSON_4, TRAINER_JACKSON_5}, - MAP_GROUP(ROUTE119), - MAP_NUM(ROUTE119), - }, - { - {TRAINER_HALEY_1, TRAINER_HALEY_2, TRAINER_HALEY_3, TRAINER_HALEY_4, TRAINER_HALEY_5}, - MAP_GROUP(ROUTE104), - MAP_NUM(ROUTE104), - }, - { - {TRAINER_JAMES_1, TRAINER_JAMES_2, TRAINER_JAMES_3, TRAINER_JAMES_4, TRAINER_JAMES_5}, - MAP_GROUP(PETALBURG_WOODS), - MAP_NUM(PETALBURG_WOODS), - }, - { - {TRAINER_TRENT_1, TRAINER_TRENT_2, TRAINER_TRENT_3, TRAINER_TRENT_4, TRAINER_TRENT_5}, - MAP_GROUP(ROUTE112), - MAP_NUM(ROUTE112), - }, - { - {TRAINER_LOIS_AND_HAL_1, TRAINER_LOIS_AND_HAL_2, TRAINER_LOIS_AND_HAL_3, TRAINER_LOIS_AND_HAL_4, TRAINER_LOIS_AND_HAL_5}, - MAP_GROUP(ABANDONED_SHIP_ROOMS2_1F), - MAP_NUM(ABANDONED_SHIP_ROOMS2_1F), - }, - { - {TRAINER_WALLY_3, TRAINER_WALLY_4, TRAINER_WALLY_5, TRAINER_WALLY_6, TRAINER_NONE}, - MAP_GROUP(VICTORY_ROAD_1F), - MAP_NUM(VICTORY_ROAD_1F), - }, -}; - -static const u16 sBadgeFlags[] = -{ - FLAG_BADGE01_GET, - FLAG_BADGE02_GET, - FLAG_BADGE03_GET, - FLAG_BADGE04_GET, - FLAG_BADGE05_GET, - FLAG_BADGE06_GET, - FLAG_BADGE07_GET, - FLAG_BADGE08_GET, -}; - -static void DoStandardWildBattle(void); -static void DoSafariBattle(void); -static void SetTrainerFlagsAfterTrainerEyeRematch(void); -static void CB2_EndWildBattle(void); -static void CB2_EndScriptedWildBattle(void); -static u8 GetWildBattleTransition(void); -static u8 GetTrainerBattleTransition(void); -static void CB2_GiveStarter(void); -static void CB2_StartFirstBattle(void); -static void CB2_EndFirstBattle(void); -static bool32 IsPlayerDefeated(u32 a1); - -#define tState data[0] -#define tTransition data[1] - -static void Task_BattleStart(u8 taskId) -{ - s16 *data = gTasks[taskId].data; - - switch (tState) - { - case 0: - if (!FldeffPoison_IsActive()) // is poison not active? - { - BattleTransition_StartOnField(tTransition); - tState++; // go to case 1. - } - break; - case 1: - if (IsBattleTransitionDone() == TRUE) - { - SetMainCallback2(sub_800E7C4); - RestartWildEncounterImmunitySteps(); - ClearPoisonStepCounter(); - DestroyTask(taskId); - } - break; - } -} - -static void CreateBattleStartTask(u8 transition, u16 song) -{ - u8 taskId = CreateTask(Task_BattleStart, 1); - - gTasks[taskId].tTransition = transition; - current_map_music_set__default_for_battle(song); -} - -#undef tState -#undef tTransition - -void BattleSetup_StartWildBattle(void) -{ - if (GetSafariZoneFlag()) - DoSafariBattle(); - else - DoStandardWildBattle(); -} - -static void DoStandardWildBattle(void) -{ - ScriptContext2_Enable(); - FreezeEventObjects(); - sub_80597F4(); - gMain.savedCallback = CB2_EndWildBattle; - gBattleTypeFlags = 0; - CreateBattleStartTask(GetWildBattleTransition(), 0); - IncrementGameStat(GAME_STAT_TOTAL_BATTLES); - IncrementGameStat(GAME_STAT_WILD_BATTLES); -} - -void BattleSetup_StartRoamerBattle(void) -{ - ScriptContext2_Enable(); - FreezeEventObjects(); - sub_80597F4(); - gMain.savedCallback = CB2_EndWildBattle; - gBattleTypeFlags = BATTLE_TYPE_ROAMER; - CreateBattleStartTask(GetWildBattleTransition(), 0); - IncrementGameStat(GAME_STAT_TOTAL_BATTLES); - IncrementGameStat(GAME_STAT_WILD_BATTLES); -} - -static void DoSafariBattle(void) -{ - ScriptContext2_Enable(); - FreezeEventObjects(); - sub_80597F4(); - gMain.savedCallback = sub_80C824C; - gBattleTypeFlags = BATTLE_TYPE_SAFARI; - CreateBattleStartTask(GetWildBattleTransition(), 0); -} - -static void StartTheBattle(void) -{ - CreateBattleStartTask(GetTrainerBattleTransition(), 0); - IncrementGameStat(GAME_STAT_TOTAL_BATTLES); - IncrementGameStat(GAME_STAT_TRAINER_BATTLES); -} - -//Initiates battle where Wally catches Ralts -void ScrSpecial_StartWallyTutorialBattle(void) -{ - CreateMaleMon(&gEnemyParty[0], SPECIES_RALTS, 5); - ScriptContext2_Enable(); - gMain.savedCallback = c2_exit_to_overworld_1_continue_scripts_restart_music; - gBattleTypeFlags = BATTLE_TYPE_WALLY_TUTORIAL; - CreateBattleStartTask(B_TRANSITION_SLICE, 0); -} - -void BattleSetup_StartScriptedWildBattle(void) -{ - ScriptContext2_Enable(); - gMain.savedCallback = CB2_EndScriptedWildBattle; - gBattleTypeFlags = 0; - CreateBattleStartTask(GetWildBattleTransition(), 0); - IncrementGameStat(GAME_STAT_TOTAL_BATTLES); - IncrementGameStat(GAME_STAT_WILD_BATTLES); -} - -void ScrSpecial_StartSouthernIslandBattle(void) -{ - ScriptContext2_Enable(); - gMain.savedCallback = CB2_EndScriptedWildBattle; - gBattleTypeFlags = BATTLE_TYPE_LEGENDARY; - CreateBattleStartTask(GetWildBattleTransition(), 0); - IncrementGameStat(GAME_STAT_TOTAL_BATTLES); - IncrementGameStat(GAME_STAT_WILD_BATTLES); -} - -void ScrSpecial_StartRayquazaBattle(void) -{ - ScriptContext2_Enable(); - gMain.savedCallback = CB2_EndScriptedWildBattle; - gBattleTypeFlags = BATTLE_TYPE_LEGENDARY; - CreateBattleStartTask(B_TRANSITION_BLUR, MUS_BATTLE34); - IncrementGameStat(GAME_STAT_TOTAL_BATTLES); - IncrementGameStat(GAME_STAT_WILD_BATTLES); -} - -void ScrSpecial_StartGroudonKyogreBattle(void) -{ - ScriptContext2_Enable(); - gMain.savedCallback = CB2_EndScriptedWildBattle; - gBattleTypeFlags = BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_KYOGRE_GROUDON; - if (gGameVersion == VERSION_RUBY) - CreateBattleStartTask(B_TRANSITION_SHARDS, MUS_BATTLE34); // GROUDON - else - CreateBattleStartTask(B_TRANSITION_RIPPLE, MUS_BATTLE34); // KYOGRE - IncrementGameStat(GAME_STAT_TOTAL_BATTLES); - IncrementGameStat(GAME_STAT_WILD_BATTLES); -} - -void ScrSpecial_StartRegiBattle(void) -{ - ScriptContext2_Enable(); - gMain.savedCallback = CB2_EndScriptedWildBattle; - gBattleTypeFlags = BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_REGI; - CreateBattleStartTask(B_TRANSITION_GRID_SQUARES, MUS_BATTLE36); - IncrementGameStat(GAME_STAT_TOTAL_BATTLES); - IncrementGameStat(GAME_STAT_WILD_BATTLES); -} - -static void CB2_EndWildBattle(void) -{ - CpuFill16(0, (void *)BG_PLTT, BG_PLTT_SIZE); - ResetOamRange(0, 128); - - if (IsPlayerDefeated(gBattleOutcome) == TRUE) - { - SetMainCallback2(CB2_WhiteOut); - } - else - { - SetMainCallback2(CB2_ReturnToField); - gFieldCallback = sub_8080E44; - } -} - -void CB2_EndScriptedWildBattle(void) -{ - CpuFill16(0, (void *)BG_PLTT, BG_PLTT_SIZE); - ResetOamRange(0, 128); - - if (IsPlayerDefeated(gBattleOutcome) == TRUE) - SetMainCallback2(CB2_WhiteOut); - else - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); -} - -s8 BattleSetup_GetTerrain(void) -{ - u16 tileBehavior; - s16 x, y; - - PlayerGetDestCoords(&x, &y); - tileBehavior = MapGridGetMetatileBehaviorAt(x, y); - - if (MetatileBehavior_IsTallGrass(tileBehavior)) - return BATTLE_TERRAIN_GRASS; - if (MetatileBehavior_IsLongGrass(tileBehavior)) - return BATTLE_TERRAIN_LONG_GRASS; - if (MetatileBehavior_IsSandOrDeepSand(tileBehavior)) - return BATTLE_TERRAIN_SAND; - switch (gMapHeader.mapType) - { - case MAP_TYPE_TOWN: - case MAP_TYPE_CITY: - case MAP_TYPE_ROUTE: - break; - case MAP_TYPE_UNDERGROUND: - if (MetatileBehavior_IsIndoorEncounter(tileBehavior)) - return BATTLE_TERRAIN_BUILDING; - if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) - return BATTLE_TERRAIN_POND; - return BATTLE_TERRAIN_CAVE; - case MAP_TYPE_INDOOR: - case MAP_TYPE_SECRET_BASE: - return BATTLE_TERRAIN_BUILDING; - case MAP_TYPE_UNDERWATER: - return BATTLE_TERRAIN_UNDERWATER; - case MAP_TYPE_6: - if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) - return BATTLE_TERRAIN_WATER; - return BATTLE_TERRAIN_PLAIN; - } - if (MetatileBehavior_IsOceanWater(tileBehavior)) - return BATTLE_TERRAIN_WATER; - if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) - return BATTLE_TERRAIN_POND; - if (MetatileBehavior_IsMountainTop(tileBehavior)) - return BATTLE_TERRAIN_MOUNTAIN; - if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) - { - if (MetatileBehavior_GetBridgeType(tileBehavior)) - return BATTLE_TERRAIN_POND; - if (MetatileBehavior_IsBridge(tileBehavior) == TRUE) - return BATTLE_TERRAIN_WATER; - } - if (gSaveBlock1.location.mapGroup == MAP_GROUP(ROUTE113) && gSaveBlock1.location.mapNum == MAP_NUM(ROUTE113)) - return BATTLE_TERRAIN_SAND; - if (GetSav1Weather() == 8) - return BATTLE_TERRAIN_SAND; - return BATTLE_TERRAIN_PLAIN; -} - -static s8 GetBattleTransitionTypeByMap(void) -{ - u16 tileBehavior; - s16 x, y; - - PlayerGetDestCoords(&x, &y); - tileBehavior = MapGridGetMetatileBehaviorAt(x, y); - if (Overworld_GetFlashLevel()) - return 2; - if (!MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) - { - switch (gMapHeader.mapType) - { - case MAP_TYPE_UNDERGROUND: - return 1; - case MAP_TYPE_UNDERWATER: - return 3; - default: - return 0; - } - } - return 3; -} - -static u16 GetSumOfPlayerPartyLevel(u8 numMons) -{ - u8 sum = 0; - int i; - - for (i = 0; i < 6; i++) - { - u32 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); - - if (species != SPECIES_EGG && species != SPECIES_NONE && GetMonData(&gPlayerParty[i], MON_DATA_HP) != 0) - { - sum += GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); - numMons--; - if (numMons == 0) - break; - } - } - return sum; -} - -static u8 GetSumOfEnemyPartyLevel(u16 opponentId, u8 numMons) -{ - u8 i; - u8 sum; - u32 count = numMons; - - if (gTrainers[opponentId].partySize < count) - count = gTrainers[opponentId].partySize; - - sum = 0; - - switch (gTrainers[opponentId].partyFlags) - { - case 0: - { - const struct TrainerMonNoItemDefaultMoves *party; - party = gTrainers[opponentId].party.NoItemDefaultMoves; - for (i = 0; i < count; i++) - sum += party[i].level; - } - break; - case F_TRAINER_PARTY_CUSTOM_MOVESET: - { - const struct TrainerMonNoItemCustomMoves *party; - party = gTrainers[opponentId].party.NoItemCustomMoves; - for (i = 0; i < count; i++) - sum += party[i].level; - } - break; - case F_TRAINER_PARTY_HELD_ITEM: - { - const struct TrainerMonItemDefaultMoves *party; - party = gTrainers[opponentId].party.ItemDefaultMoves; - for (i = 0; i < count; i++) - sum += party[i].level; - } - break; - case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM: - { - const struct TrainerMonItemCustomMoves *party; - party = gTrainers[opponentId].party.ItemCustomMoves; - for (i = 0; i < count; i++) - sum += party[i].level; - } - break; - } - - return sum; -} - -static u8 GetWildBattleTransition(void) -{ - u8 transitionType = GetBattleTransitionTypeByMap(); - u8 enemyLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL); - u8 playerLevel = GetSumOfPlayerPartyLevel(1); - - if (enemyLevel < playerLevel) - return gBattleTransitionTable_Wild[transitionType][0]; - else - return gBattleTransitionTable_Wild[transitionType][1]; -} - -static u8 GetTrainerBattleTransition(void) -{ - const struct Trainer *trainer; - u8 minPartyCount; - u8 transitionType; - u8 enemyLevel; - u8 playerLevel; - - if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) - return B_TRANSITION_STEVEN; - - trainer = gTrainers; - - if (trainer[gTrainerBattleOpponent].trainerClass == TRAINER_CLASS_ELITE_FOUR) - { - if (gTrainerBattleOpponent == TRAINER_SIDNEY) - return B_TRANSITION_SYDNEY; - if (gTrainerBattleOpponent == TRAINER_PHOEBE) - return B_TRANSITION_PHOEBE; - if (gTrainerBattleOpponent == TRAINER_GLACIA) - return B_TRANSITION_GLACIA; - if (gTrainerBattleOpponent == TRAINER_DRAKE) - return B_TRANSITION_DRAKE; - return B_TRANSITION_STEVEN; - } - - if (trainer[gTrainerBattleOpponent].trainerClass == TRAINER_CLASS_CHAMPION) - return B_TRANSITION_STEVEN; - - if (trainer[gTrainerBattleOpponent].doubleBattle == TRUE) - minPartyCount = 2; // double battles always at least have 2 pokemon. - else - minPartyCount = 1; - - transitionType = GetBattleTransitionTypeByMap(); - enemyLevel = GetSumOfEnemyPartyLevel(gTrainerBattleOpponent, minPartyCount); - playerLevel = GetSumOfPlayerPartyLevel(minPartyCount); - if (enemyLevel < playerLevel) // is wild mon level than the player's mon level? - return gBattleTransitionTable_Trainer[transitionType][0]; - else - return gBattleTransitionTable_Trainer[transitionType][1]; -} - -u8 BattleSetup_GetBattleTowerBattleTransition(void) -{ - u8 enemyLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL); - u8 playerLevel = GetSumOfPlayerPartyLevel(1); - - if (enemyLevel < playerLevel) - return B_TRANSITION_POKEBALLS_TRAIL; - else - return B_TRANSITION_BIG_POKEBALL; -} - -void ScrSpecial_ChooseStarter(void) -{ - SetMainCallback2(CB2_ChooseStarter); - gMain.savedCallback = CB2_GiveStarter; -} - -static void CB2_GiveStarter(void) -{ - u16 starterPoke; - - *GetVarPointer(VAR_STARTER_MON) = gSpecialVar_Result; - starterPoke = GetStarterPokemon(gSpecialVar_Result); - ScriptGiveMon(starterPoke, 5, 0, 0, 0, 0); - ResetTasks(); - sub_80408BC(); - SetMainCallback2(CB2_StartFirstBattle); - BattleTransition_Start(0); -} - -static void CB2_StartFirstBattle(void) -{ - UpdatePaletteFade(); - RunTasks(); - - if (IsBattleTransitionDone() == TRUE) - { - gBattleTypeFlags = BATTLE_TYPE_FIRST_BATTLE; - gMain.savedCallback = CB2_EndFirstBattle; - SetMainCallback2(sub_800E7C4); - RestartWildEncounterImmunitySteps(); - ClearPoisonStepCounter(); - IncrementGameStat(GAME_STAT_TOTAL_BATTLES); - IncrementGameStat(GAME_STAT_WILD_BATTLES); - } -} - -static void CB2_EndFirstBattle(void) -{ - Overworld_ClearSavedMusic(); - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); -} - -// why not just use the macros? maybe its because they didnt want to uncast const every time? -static u32 TrainerBattleLoadArg32(const u8 *ptr) -{ - return T1_READ_32(ptr); -} - -static u16 TrainerBattleLoadArg16(const u8 *ptr) -{ - return T1_READ_16(ptr); -} - -static u8 TrainerBattleLoadArg8(const u8 *ptr) -{ - return T1_READ_8(ptr); -} - -static u16 CurrentOpponentTrainerFlag(void) -{ - return TRAINER_FLAG_START + gTrainerBattleOpponent; -} - -static bool32 IsPlayerDefeated(u32 battleOutcome) -{ - switch (battleOutcome) - { - case BATTLE_LOST: - case BATTLE_DREW: - return TRUE; - case BATTLE_WON: - case BATTLE_RAN: - case BATTLE_PLAYER_TELEPORTED: - case BATTLE_POKE_FLED: - case BATTLE_CAUGHT: - return FALSE; - default: - return FALSE; - } -} - -static void ResetTrainerOpponentIds(void) -{ - sTrainerBattleMode = 0; - gTrainerBattleOpponent = 0; - sTrainerEventObjectLocalId = 0; - sTrainerIntroSpeech = 0; - sTrainerDefeatSpeech = 0; - sTrainerVictorySpeech = 0; - sTrainerCannotBattleSpeech = 0; - sTrainerBattleScriptRetAddr = 0; - sTrainerBattleEndScript = 0; -} - -static void TrainerBattleLoadArgs(const struct TrainerBattleParameter *specs, const u8 *data) -{ - while (1) - { - switch (specs->ptrType) - { - case TRAINER_PARAM_LOAD_VAL_8BIT: - *(u8 *)specs->varPtr = TrainerBattleLoadArg8(data); - data += 1; - break; - case TRAINER_PARAM_LOAD_VAL_16BIT: - *(u16 *)specs->varPtr = TrainerBattleLoadArg16(data); - data += 2; - break; - case TRAINER_PARAM_LOAD_VAL_32BIT: - *(u32 *)specs->varPtr = TrainerBattleLoadArg32(data); - data += 4; - break; - case TRAINER_PARAM_CLEAR_VAL_8BIT: - *(u8 *)specs->varPtr = 0; - break; - case TRAINER_PARAM_CLEAR_VAL_16BIT: - *(u16 *)specs->varPtr = 0; - break; - case TRAINER_PARAM_CLEAR_VAL_32BIT: - *(u32 *)specs->varPtr = 0; - break; - case TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR: - *(const u8 **)specs->varPtr = data; - return; - } - specs++; - } -} - -static void SetMapVarsToTrainer(void) -{ - if (sTrainerEventObjectLocalId) - { - gSpecialVar_LastTalked = sTrainerEventObjectLocalId; - gSelectedEventObject = GetEventObjectIdByLocalIdAndMap(sTrainerEventObjectLocalId, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup); - } -} - -u8 *BattleSetup_ConfigureTrainerBattle(const u8 *data) -{ - ResetTrainerOpponentIds(); - sTrainerBattleMode = TrainerBattleLoadArg8(data); - - switch (sTrainerBattleMode) - { - case 3: - TrainerBattleLoadArgs(gTrainerBattleSpecs_3, data); - return gUnknown_0819F878; - case 4: - TrainerBattleLoadArgs(gTrainerBattleSpecs_2, data); - SetMapVarsToTrainer(); - return gUnknown_0819F840; - case 1: - case 2: - TrainerBattleLoadArgs(gTrainerBattleSpecs_1, data); - SetMapVarsToTrainer(); - return gUnknown_0819F818; - case 6: - case 8: - TrainerBattleLoadArgs(gTrainerBattleSpecs_4, data); - SetMapVarsToTrainer(); - return gUnknown_0819F840; - case 7: - TrainerBattleLoadArgs(gTrainerBattleSpecs_2, data); - SetMapVarsToTrainer(); - gTrainerBattleOpponent = GetRematchTrainerId(gTrainerBattleOpponent); - return gUnknown_0819F8AE; - case 5: - TrainerBattleLoadArgs(gTrainerBattleSpecs_0, data); - SetMapVarsToTrainer(); - gTrainerBattleOpponent = GetRematchTrainerId(gTrainerBattleOpponent); - return gUnknown_0819F887; - default: - TrainerBattleLoadArgs(gTrainerBattleSpecs_0, data); - SetMapVarsToTrainer(); - return gUnknown_0819F818; - } -} - -void TrainerWantsBattle(u8 trainerEventObjId, const u8 *trainerScript) -{ - gSelectedEventObject = trainerEventObjId; - gSpecialVar_LastTalked = gEventObjects[trainerEventObjId].localId; - BattleSetup_ConfigureTrainerBattle(trainerScript + 1); - ScriptContext1_SetupScript(gUnknown_0819F80B); - ScriptContext2_Enable(); -} - -bool32 GetTrainerFlagFromScriptPointer(const u8 *data) -{ - u32 flag = TrainerBattleLoadArg16(data + 2); - return FlagGet(TRAINER_FLAG_START + flag); -} - -void sub_8082524(void) -{ - struct EventObject *eventObject = &gEventObjects[gSelectedEventObject]; - - SetTrainerMovementType(eventObject, GetTrainerFacingDirectionMovementType(eventObject->facingDirection)); -} - -u8 ScrSpecial_GetTrainerBattleMode(void) -{ - return sTrainerBattleMode; -} - -u8 ScrSpecial_HasTrainerBeenFought(void) -{ - return FlagGet(CurrentOpponentTrainerFlag()); -} - -void SetCurrentTrainerBattledFlag(void) -{ - FlagSet(CurrentOpponentTrainerFlag()); -} - -void unref_sub_8082590(void) -{ - FlagSet(CurrentOpponentTrainerFlag()); // duplicate function -} - -u8 HasTrainerAlreadyBeenFought(u16 flag) -{ - return FlagGet(TRAINER_FLAG_START + flag); -} - -void SetTrainerFlag(u16 flag) -{ - FlagSet(TRAINER_FLAG_START + flag); -} - -void ClearTrainerFlag(u16 flag) -{ - FlagClear(TRAINER_FLAG_START + flag); -} - -void BattleSetup_StartTrainerBattle(void) -{ - gBattleTypeFlags = BATTLE_TYPE_TRAINER; - gMain.savedCallback = CB2_EndTrainerBattle; - StartTheBattle(); - ScriptContext1_Stop(); -} - -void CB2_EndTrainerBattle(void) -{ - if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) - { - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); - } - else if (IsPlayerDefeated(gBattleOutcome) == TRUE) - { - SetMainCallback2(CB2_WhiteOut); - } - else - { - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); - SetCurrentTrainerBattledFlag(); - } -} - -void CB2_EndTrainerEyeRematchBattle(void) -{ - if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) - { - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); - } - else if (IsPlayerDefeated(gBattleOutcome) == TRUE) - { - SetMainCallback2(CB2_WhiteOut); - } - else - { - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); - SetCurrentTrainerBattledFlag(); - SetTrainerFlagsAfterTrainerEyeRematch(); - } -} - -void ScrSpecial_StartTrainerEyeRematch(void) -{ - gBattleTypeFlags = BATTLE_TYPE_TRAINER; - gMain.savedCallback = CB2_EndTrainerEyeRematchBattle; - StartTheBattle(); - ScriptContext1_Stop(); -} - -static const u8 *GetTrainerIntroSpeech(void); -static const u8 *GetTrainerNonBattlingSpeech(void); - -void ScrSpecial_ShowTrainerIntroSpeech(void) -{ - ShowFieldMessage(GetTrainerIntroSpeech()); -} - -u8 *BattleSetup_GetScriptAddrAfterBattle(void) -{ - if (sTrainerBattleScriptRetAddr) - return sTrainerBattleScriptRetAddr; - else - return gUnknown_081C6C02; -} - -u8 *BattleSetup_GetTrainerPostBattleScript(void) -{ - if (sTrainerBattleEndScript) - return sTrainerBattleEndScript; - else - return gUnknown_081C6C02; -} - -void ScrSpecial_ShowTrainerNonBattlingSpeech(void) -{ - ShowFieldMessage(GetTrainerNonBattlingSpeech()); -} - -void PlayTrainerEncounterMusic(void) -{ - u16 music; - - if (sTrainerBattleMode != 1 && sTrainerBattleMode != 8) - { - switch (sub_803FC58(gTrainerBattleOpponent)) - { - case TRAINER_ENCOUNTER_MUSIC_MALE: - music = MUS_BOYEYE; - break; - case TRAINER_ENCOUNTER_MUSIC_FEMALE: - music = MUS_GIRLEYE; - break; - case TRAINER_ENCOUNTER_MUSIC_GIRL: - music = MUS_SYOUJOEYE; - break; - case TRAINER_ENCOUNTER_MUSIC_INTENSE: - music = MUS_HAGESHII; - break; - case TRAINER_ENCOUNTER_MUSIC_COOL: - music = MUS_KAKKOII; - break; - case TRAINER_ENCOUNTER_MUSIC_AQUA: - music = MUS_AQA_0; - break; - case TRAINER_ENCOUNTER_MUSIC_MAGMA: - music = MUS_MGM0; - break; - case TRAINER_ENCOUNTER_MUSIC_SWIMMER: - music = MUS_SWIMEYE; - break; - case TRAINER_ENCOUNTER_MUSIC_TWINS: - music = MUS_HUTAGO; - break; - case TRAINER_ENCOUNTER_MUSIC_ELITE_FOUR: - music = MUS_SITENNOU; - break; - case TRAINER_ENCOUNTER_MUSIC_HIKER: - music = MUS_YAMA_EYE; - break; - case TRAINER_ENCOUNTER_MUSIC_INTERVIEWER: - music = MUS_INTER_V; - break; - case TRAINER_ENCOUNTER_MUSIC_RICH: - music = MUS_TEST; - break; - default: - music = MUS_AYASII; - } - PlayNewMapMusic(music); - } -} - -//Returns an empty string if a null pointer was passed, otherwise returns str -static const u8 *SanitizeString(const u8 *str) -{ - if (str) - return str; - else - return gOtherText_CancelWithTerminator; -} - -static const u8 *GetTrainerIntroSpeech(void) -{ - return SanitizeString(sTrainerIntroSpeech); -} - -u8 *GetTrainerLoseText(void) -{ - const u8 *str; - - if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) - str = GetSecretBaseTrainerLoseText(); - else - str = sTrainerDefeatSpeech; - - StringExpandPlaceholders(gStringVar4, SanitizeString(str)); - return gStringVar4; -} - -const u8 *unref_sub_808286C(void) -{ - return SanitizeString(sTrainerVictorySpeech); -} - -static const u8 *GetTrainerNonBattlingSpeech(void) -{ - return SanitizeString(sTrainerCannotBattleSpeech); -} - -s32 FirstBattleTrainerIdToRematchTableId(const struct TrainerEyeTrainer *trainers, u16 opponentId) -{ - s32 i; - - for (i = 0; i < NUM_TRAINER_EYE_TRAINERS; i++) - { - if (trainers[i].opponentIDs[0] == opponentId) - return i; - } - return -1; -} - -s32 TrainerIdToRematchTableId(const struct TrainerEyeTrainer *trainers, u16 opponentId) -{ - s32 i; - s32 j; - - for (i = 0; i < NUM_TRAINER_EYE_TRAINERS; i++) - { - for (j = 0; j < 5 && trainers[i].opponentIDs[j] != 0; j++) - { - if (trainers[i].opponentIDs[j] == opponentId) - return i; - } - } - return -1; -} - -bool32 UpdateRandomTrainerEyeRematches(const struct TrainerEyeTrainer *trainers, u16 mapGroup, u16 mapNum) -{ - int i; - bool32 ret = FALSE; - - for (i = 0; i < NUM_TRAINER_EYE_TRAINERS; i++) - { - if (trainers[i].mapGroup == mapGroup && trainers[i].mapNum == mapNum) - { - if (gSaveBlock1.trainerRematches[i] != 0) - { - // Trainer already wants rematch. Don't bother updating it - ret = TRUE; - } - else if (HasTrainerAlreadyBeenFought(trainers[i].opponentIDs[0]) == TRUE - && (Random() % 100) <= 30) // 31% chance of getting a rematch - { - int rematches = 1; - - while (rematches < 5 && trainers[i].opponentIDs[rematches] != 0 - && HasTrainerAlreadyBeenFought(trainers[i].opponentIDs[rematches])) - rematches++; - gSaveBlock1.trainerRematches[i] = rematches; - ret = TRUE; - } - } - } - return ret; -} - -s32 DoesSomeoneWantRematchIn_(const struct TrainerEyeTrainer *trainers, u16 mapGroup, u16 mapNum) -{ - s32 i; - - for (i = 0; i < NUM_TRAINER_EYE_TRAINERS; i++) - { - if (trainers[i].mapGroup == mapGroup && trainers[i].mapNum == mapNum && gSaveBlock1.trainerRematches[i]) - return 1; - } - return 0; -} - -s32 IsRematchTrainerIn_(const struct TrainerEyeTrainer *trainers, u16 mapGroup, u16 mapNum) -{ - s32 i; - - for (i = 0; i < NUM_TRAINER_EYE_TRAINERS; i++) - { - if (trainers[i].mapGroup == mapGroup && trainers[i].mapNum == mapNum) - return 1; - } - return 0; -} - -bool8 IsFirstTrainerIdReadyForRematch(const struct TrainerEyeTrainer *trainers, u16 opponentId) -{ - s32 trainerEyeIndex = FirstBattleTrainerIdToRematchTableId(trainers, opponentId); - - if (trainerEyeIndex != -1 && trainerEyeIndex < 100 && gSaveBlock1.trainerRematches[trainerEyeIndex]) - return TRUE; - else - return FALSE; -} - -bool8 GetTrainerEyeRematchFlag(const struct TrainerEyeTrainer *trainers, u16 opponentId) -{ - s32 trainerEyeIndex = TrainerIdToRematchTableId(trainers, opponentId); - - if (trainerEyeIndex != -1 && trainerEyeIndex < 100 && gSaveBlock1.trainerRematches[trainerEyeIndex]) - return TRUE; - else - return FALSE; -} - -u16 GetRematchTrainerIdFromTable(const struct TrainerEyeTrainer *trainers, u16 opponentId) -{ - int i; - const struct TrainerEyeTrainer *trainer; - s32 trainerEyeIndex = FirstBattleTrainerIdToRematchTableId(trainers, opponentId); - - if (trainerEyeIndex == -1) - return 0; - trainer = &trainers[trainerEyeIndex]; - for (i = 1; i < 5; i++) - { - if (!trainer->opponentIDs[i]) - return trainer->opponentIDs[i - 1]; - if (!HasTrainerAlreadyBeenFought(trainer->opponentIDs[i])) - return trainer->opponentIDs[i]; - } - return trainer->opponentIDs[4]; -} - -void ClearTrainerEyeRematchFlag(const struct TrainerEyeTrainer *trainers, u16 opponentId) -{ - s32 trainerEyeIndex = TrainerIdToRematchTableId(trainers, opponentId); - - if (trainerEyeIndex != -1) - gSaveBlock1.trainerRematches[trainerEyeIndex] = 0; -} - -bool8 WasSecondRematchWon(const struct TrainerEyeTrainer *trainers, u16 opponentId) -{ - s32 trainerEyeIndex = FirstBattleTrainerIdToRematchTableId(trainers, opponentId); - - if (trainerEyeIndex != -1 && HasTrainerAlreadyBeenFought(trainers[trainerEyeIndex].opponentIDs[1])) - return TRUE; - else - return FALSE; -} - -bool32 HasAtLeastFiveBadges(void) -{ - int badgeCount = 0; - u32 i; - - for (i = 0; i < 8; i++) - { - if (FlagGet(sBadgeFlags[i]) == TRUE) - { - badgeCount++; - if (badgeCount >= 5) - return TRUE; - } - } - return FALSE; -} - -void IncrementRematchStepCounter(void) -{ - if (HasAtLeastFiveBadges()) - { - if (gSaveBlock1.trainerRematchStepCounter >= TRAINER_REMATCH_STEPS) - gSaveBlock1.trainerRematchStepCounter = TRAINER_REMATCH_STEPS; - else - gSaveBlock1.trainerRematchStepCounter++; - } -} - -bool32 IsRematchStepCounterMaxed(void) -{ - if (HasAtLeastFiveBadges() && gSaveBlock1.trainerRematchStepCounter >= TRAINER_REMATCH_STEPS) - return TRUE; - else - return FALSE; -} - -void TryUpdateRandomTrainerRematches(u16 mapGroup, u16 mapNum) -{ - if (IsRematchStepCounterMaxed() && UpdateRandomTrainerEyeRematches(gTrainerEyeTrainers, mapGroup, mapNum) == TRUE) - gSaveBlock1.trainerRematchStepCounter = 0; -} - -s32 DoesSomeoneWantRematchIn(u16 mapGroup, u16 mapNum) -{ - return DoesSomeoneWantRematchIn_(gTrainerEyeTrainers, mapGroup, mapNum); -} - -s32 IsRematchTrainerIn(u16 mapGroup, u16 mapNum) -{ - return IsRematchTrainerIn_(gTrainerEyeTrainers, mapGroup, mapNum); -} - -u16 GetRematchTrainerId(u16 opponentId) -{ - return GetRematchTrainerIdFromTable(gTrainerEyeTrainers, opponentId); -} - -bool8 ShouldTryRematchBattle(void) -{ - if (IsFirstTrainerIdReadyForRematch(gTrainerEyeTrainers, gTrainerBattleOpponent)) - return 1; - else - return WasSecondRematchWon(gTrainerEyeTrainers, gTrainerBattleOpponent); -} - -u8 ScrSpecial_GetTrainerEyeRematchFlag(void) -{ - return GetTrainerEyeRematchFlag(gTrainerEyeTrainers, gTrainerBattleOpponent); -} - -void SetTrainerFlagsAfterTrainerEyeRematch(void) -{ - ClearTrainerEyeRematchFlag(gTrainerEyeTrainers, gTrainerBattleOpponent); - SetCurrentTrainerBattledFlag(); -} diff --git a/src/battle/battle_transition.c b/src/battle/battle_transition.c deleted file mode 100644 index a0c94f713..000000000 --- a/src/battle/battle_transition.c +++ /dev/null @@ -1,2511 +0,0 @@ -#include "global.h" -#include "battle_transition.h" -#include "main.h" -#include "overworld.h" -#include "task.h" -#include "palette.h" -#include "trig.h" -#include "field_effect.h" -#include "field_weather.h" -#include "random.h" -#include "sprite.h" -#include "sound.h" -#include "trainer.h" -#include "field_camera.h" -#include "ewram.h" -#include "scanline_effect.h" -#include "constants/songs.h" -#include "constants/field_effects.h" - -void ScanlineEffect_Clear(void); - -extern const struct OamData gFieldOamData_32x32; - -struct TransitionData -{ - vs8 VBlank_DMA; - u16 WININ; - u16 WINOUT; - u16 field_6; - u16 WIN0V; - u16 field_A; - u16 field_C; - u16 BLDCNT; - u16 BLDALPHA; - u16 BLDY; - s16 field_14; - s16 field_16; - s16 field_18; - s16 field_1A; - s16 field_1C; - s16 field_1E; // unused - s16 field_20; - s16 field_22; // unused - s16 data[11]; -}; - -typedef bool8 (*TransitionState)(struct Task* task); -typedef bool8 (*TransitionSpriteCallback)(struct Sprite* sprite); - -// this file's functions -static void LaunchBattleTransitionTask(u8 transitionID); -static void Task_BattleTransitionMain(u8 taskID); -static void Phase1Task_TransitionAll(u8 taskID); -static void Phase2Task_Transition_Blur(u8 taskID); -static void Phase2Task_Transition_Swirl(u8 taskID); -static void Phase2Task_Transition_Shuffle(u8 taskID); -static void Phase2Task_Transition_BigPokeball(u8 taskID); -static void Phase2Task_Transition_PokeballsTrail(u8 taskID); -static void Phase2Task_Transition_Clockwise_BlackFade(u8 taskID); -static void Phase2Task_Transition_Ripple(u8 taskID); -static void Phase2Task_Transition_Wave(u8 taskID); -static void Phase2Task_Transition_Slice(u8 taskID); -static void Phase2Task_Transition_WhiteFade(u8 taskID); -static void Phase2Task_Transition_GridSquares(u8 taskID); -static void Phase2Task_Transition_Shards(u8 taskID); -static void Phase2Task_Transition_Sydney(u8 taskID); -static void Phase2Task_Transition_Phoebe(u8 taskID); -static void Phase2Task_Transition_Glacia(u8 taskID); -static void Phase2Task_Transition_Drake(u8 taskID); -static void Phase2Task_Transition_Steven(u8 taskID); -static bool8 Transition_Phase1(struct Task* task); -static bool8 Transition_WaitForPhase1(struct Task* task); -static bool8 Transition_Phase2(struct Task* task); -static bool8 Transition_WaitForPhase2(struct Task* task); -static void VBlankCB_Phase2_Transition_Swirl(void); -static void HBlankCB_Phase2_Transition_Swirl(void); -static void VBlankCB_Phase2_Transition_Shuffle(void); -static void HBlankCB_Phase2_Transition_Shuffle(void); -static void VBlankCB0_Phase2_Transition_BigPokeball(void); -static void VBlankCB1_Phase2_Transition_BigPokeball(void); -static void VBlankCB_Phase2_Transition_Clockwise_BlackFade(void); -static void VBlankCB_Phase2_Transition_Ripple(void); -static void HBlankCB_Phase2_Transition_Ripple(void); -static void VBlankCB_Phase2_Transition_Wave(void); -static void VBlankCB_Phase2_Transition_Slice(void); -static void HBlankCB_Phase2_Transition_Slice(void); -static void VBlankCB0_Phase2_Transition_WhiteFade(void); -static void VBlankCB1_Phase2_Transition_WhiteFade(void); -static void HBlankCB_Phase2_Transition_WhiteFade(void); -static void VBlankCB0_Phase2_Mugshots(void); -static void VBlankCB1_Phase2_Mugshots(void); -static void HBlankCB_Phase2_Mugshots(void); -static void VBlankCB_Phase2_Transition_Shards(void); -static bool8 Phase2_Transition_Blur_Func1(struct Task* task); -static bool8 Phase2_Transition_Blur_Func2(struct Task* task); -static bool8 Phase2_Transition_Blur_Func3(struct Task* task); -static bool8 Phase2_Transition_Swirl_Func1(struct Task* task); -static bool8 Phase2_Transition_Swirl_Func2(struct Task* task); -static bool8 Phase2_Transition_Shuffle_Func1(struct Task* task); -static bool8 Phase2_Transition_Shuffle_Func2(struct Task* task); -static bool8 Phase2_Transition_BigPokeball_Func1(struct Task* task); -static bool8 Phase2_Transition_BigPokeball_Func2(struct Task* task); -static bool8 Phase2_Transition_BigPokeball_Func3(struct Task* task); -static bool8 Phase2_Transition_BigPokeball_Func4(struct Task* task); -static bool8 Phase2_Transition_BigPokeball_Func5(struct Task* task); -static bool8 Phase2_Transition_BigPokeball_Func6(struct Task* task); -static bool8 Phase2_Transition_PokeballsTrail_Func1(struct Task* task); -static bool8 Phase2_Transition_PokeballsTrail_Func2(struct Task* task); -static bool8 Phase2_Transition_PokeballsTrail_Func3(struct Task* task); -static bool8 Phase2_Transition_Clockwise_BlackFade_Func1(struct Task* task); -static bool8 Phase2_Transition_Clockwise_BlackFade_Func2(struct Task* task); -static bool8 Phase2_Transition_Clockwise_BlackFade_Func3(struct Task* task); -static bool8 Phase2_Transition_Clockwise_BlackFade_Func4(struct Task* task); -static bool8 Phase2_Transition_Clockwise_BlackFade_Func5(struct Task* task); -static bool8 Phase2_Transition_Clockwise_BlackFade_Func6(struct Task* task); -static bool8 Phase2_Transition_Clockwise_BlackFade_Func7(struct Task* task); -static bool8 Phase2_Transition_Ripple_Func1(struct Task* task); -static bool8 Phase2_Transition_Ripple_Func2(struct Task* task); -static bool8 Phase2_Transition_Wave_Func1(struct Task* task); -static bool8 Phase2_Transition_Wave_Func2(struct Task* task); -static bool8 Phase2_Transition_Wave_Func3(struct Task* task); -static bool8 Phase2_Transition_Slice_Func1(struct Task* task); -static bool8 Phase2_Transition_Slice_Func2(struct Task* task); -static bool8 Phase2_Transition_Slice_Func3(struct Task* task); -static bool8 Phase2_Transition_WhiteFade_Func1(struct Task* task); -static bool8 Phase2_Transition_WhiteFade_Func2(struct Task* task); -static bool8 Phase2_Transition_WhiteFade_Func3(struct Task* task); -static bool8 Phase2_Transition_WhiteFade_Func4(struct Task* task); -static bool8 Phase2_Transition_WhiteFade_Func5(struct Task* task); -static bool8 Phase2_Transition_GridSquares_Func1(struct Task* task); -static bool8 Phase2_Transition_GridSquares_Func2(struct Task* task); -static bool8 Phase2_Transition_GridSquares_Func3(struct Task* task); -static bool8 Phase2_Transition_Shards_Func1(struct Task* task); -static bool8 Phase2_Transition_Shards_Func2(struct Task* task); -static bool8 Phase2_Transition_Shards_Func3(struct Task* task); -static bool8 Phase2_Transition_Shards_Func4(struct Task* task); -static bool8 Phase2_Transition_Shards_Func5(struct Task* task); -static bool8 Phase2_Mugshot_Func1(struct Task* task); -static bool8 Phase2_Mugshot_Func2(struct Task* task); -static bool8 Phase2_Mugshot_Func3(struct Task* task); -static bool8 Phase2_Mugshot_Func4(struct Task* task); -static bool8 Phase2_Mugshot_Func5(struct Task* task); -static bool8 Phase2_Mugshot_Func6(struct Task* task); -static bool8 Phase2_Mugshot_Func7(struct Task* task); -static bool8 Phase2_Mugshot_Func8(struct Task* task); -static bool8 Phase2_Mugshot_Func9(struct Task* task); -static bool8 Phase2_Mugshot_Func10(struct Task* task); -static void Phase2Task_MugShotTransition(u8 taskID); -static void Mugshots_CreateOpponentPlayerSprites(struct Task* task); -static void sub_811CA10(s16 spriteID, s16 value); -static void sub_811CA28(s16 spriteID); -static s16 sub_811CA44(s16 spriteID); -static bool8 sub_811C934(struct Sprite* sprite); -static bool8 sub_811C938(struct Sprite* sprite); -static bool8 sub_811C984(struct Sprite* sprite); -static bool8 sub_811C9B8(struct Sprite* sprite); -static bool8 sub_811C9E4(struct Sprite* sprite); -static void CreatePhase1Task(s16 a0, s16 a1, s16 a2, s16 a3, s16 a4); -static bool8 sub_811D52C(void); -static void Phase1_Task_RunFuncs(u8 taskID); -static bool8 Phase1_TransitionAll_Func1(struct Task* task); -static bool8 Phase1_TransitionAll_Func2(struct Task* task); -static void sub_811D658(void); -static void VBlankCB_BattleTransition(void); -static void sub_811D6A8(u16** a0, u16** a1); -static void sub_811D690(u16** a0); -static void sub_811D6D4(void); -static void sub_811D6E8(s16* array, s16 sinAdd, s16 index, s16 indexIncrementer, s16 amplitude, s16 arrSize); -static void sub_811D764(u16* a0, s16 a1, s16 a2, s16 a3); -static void sub_811D8FC(s16* a0, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6); -static bool8 sub_811D978(s16* a0, bool8 a1, bool8 a2); -static void sub_811CFD0(struct Sprite* sprite); -static void sub_811B720(struct Sprite* sprite); -static void sub_811C90C(struct Sprite* sprite); - -// const data - -static const u32 sBigPokeball_Tileset[] = INCBIN_U32("graphics/battle_transitions/big_pokeball.4bpp"); -static const u32 sPokeballTrail_Tileset[] = INCBIN_U32("graphics/battle_transitions/pokeball_trail.4bpp"); -static const u8 sSpriteImage_83FC148[] = INCBIN_U8("graphics/battle_transitions/pokeball.4bpp"); -static const u32 sUnknown_083FC348[] = INCBIN_U32("graphics/battle_transitions/elite_four_bg.4bpp"); -static const u8 sSpriteImage_83FC528[] = INCBIN_U8("graphics/battle_transitions/unused_brendan.4bpp"); -static const u8 sSpriteImage_83FCD28[] = INCBIN_U8("graphics/battle_transitions/unused_lass.4bpp"); -static const u32 sShrinkingBoxTileset[] = INCBIN_U32("graphics/battle_transitions/shrinking_box.4bpp"); - -static struct TransitionData * const sTransitionStructPtr = &TRANSITION_STRUCT; - -static const TaskFunc sPhase1_Tasks[TRANSITIONS_NO] = -{ - [0 ... TRANSITIONS_NO - 1] = &Phase1Task_TransitionAll -}; - -static const TaskFunc sPhase2_Tasks[TRANSITIONS_NO] = -{ - Phase2Task_Transition_Blur, // 0 - Phase2Task_Transition_Swirl, // 1 - Phase2Task_Transition_Shuffle, // 2 - Phase2Task_Transition_BigPokeball, // 3 - Phase2Task_Transition_PokeballsTrail, // 4 - Phase2Task_Transition_Clockwise_BlackFade, // 5 - Phase2Task_Transition_Ripple, // 6 - Phase2Task_Transition_Wave, // 7 - Phase2Task_Transition_Slice, // 8 - Phase2Task_Transition_WhiteFade, // 9 - Phase2Task_Transition_GridSquares, // 10 - Phase2Task_Transition_Shards, // 11 - Phase2Task_Transition_Sydney, // 12 - Phase2Task_Transition_Phoebe, // 13 - Phase2Task_Transition_Glacia, // 14 - Phase2Task_Transition_Drake, // 15 - Phase2Task_Transition_Steven, // 16 -}; - -static const TransitionState sMainTransitionPhases[] = -{ - &Transition_Phase1, - &Transition_WaitForPhase1, - &Transition_Phase2, - &Transition_WaitForPhase2 -}; - -static const TransitionState sPhase2_Transition_Blur_Funcs[] = -{ - Phase2_Transition_Blur_Func1, - Phase2_Transition_Blur_Func2, - Phase2_Transition_Blur_Func3 -}; - -static const TransitionState sPhase2_Transition_Swirl_Funcs[] = -{ - Phase2_Transition_Swirl_Func1, - Phase2_Transition_Swirl_Func2, -}; - -static const TransitionState sPhase2_Transition_Shuffle_Funcs[] = -{ - Phase2_Transition_Shuffle_Func1, - Phase2_Transition_Shuffle_Func2, -}; - -static const TransitionState sPhase2_Transition_BigPokeball_Funcs[] = -{ - Phase2_Transition_BigPokeball_Func1, - Phase2_Transition_BigPokeball_Func2, - Phase2_Transition_BigPokeball_Func3, - Phase2_Transition_BigPokeball_Func4, - Phase2_Transition_BigPokeball_Func5, - Phase2_Transition_BigPokeball_Func6 -}; - -static const TransitionState sPhase2_Transition_PokeballsTrail_Funcs[] = -{ - Phase2_Transition_PokeballsTrail_Func1, - Phase2_Transition_PokeballsTrail_Func2, - Phase2_Transition_PokeballsTrail_Func3 -}; - -static const s16 sUnknown_083FD7E4[2] = {-16, 256}; -static const s16 sUnknown_083FD7E8[5] = {0, 32, 64, 18, 48}; -static const s16 sUnknown_083FD7F2[2] = {8, -8}; - -static const TransitionState sPhase2_Transition_Clockwise_BlackFade_Funcs[] = -{ - Phase2_Transition_Clockwise_BlackFade_Func1, - Phase2_Transition_Clockwise_BlackFade_Func2, - Phase2_Transition_Clockwise_BlackFade_Func3, - Phase2_Transition_Clockwise_BlackFade_Func4, - Phase2_Transition_Clockwise_BlackFade_Func5, - Phase2_Transition_Clockwise_BlackFade_Func6, - Phase2_Transition_Clockwise_BlackFade_Func7 -}; - -static const TransitionState sPhase2_Transition_Ripple_Funcs[] = -{ - Phase2_Transition_Ripple_Func1, - Phase2_Transition_Ripple_Func2 -}; - -static const TransitionState sPhase2_Transition_Wave_Funcs[] = -{ - Phase2_Transition_Wave_Func1, - Phase2_Transition_Wave_Func2, - Phase2_Transition_Wave_Func3 -}; - -static const TransitionState sPhase2_Mugshot_Transition_Funcs[] = -{ - Phase2_Mugshot_Func1, - Phase2_Mugshot_Func2, - Phase2_Mugshot_Func3, - Phase2_Mugshot_Func4, - Phase2_Mugshot_Func5, - Phase2_Mugshot_Func6, - Phase2_Mugshot_Func7, - Phase2_Mugshot_Func8, - Phase2_Mugshot_Func9, - Phase2_Mugshot_Func10 -}; - -static const u8 sMugshotsTrainerPicIDsTable[MUGSHOTS_NO] = {TRAINER_PIC_SIDNEY, TRAINER_PIC_PHOEBE, TRAINER_PIC_GLACIA, TRAINER_PIC_DRAKE, TRAINER_PIC_STEVEN}; -static const s16 sMugshotsOpponentRotationScales[MUGSHOTS_NO][2] = -{ - {0x200, 0x200}, - {0x200, 0x200}, - {0x1B0, 0x1B0}, - {0x1A0, 0x1A0}, - {0x188, 0x188}, -}; -static const s16 sMugshotsOpponentCoords[MUGSHOTS_NO][2] = -{ - {0, 0}, - {0, 0}, - {-4, 4}, - {0, 5}, - {0, 7}, -}; - -static const TransitionSpriteCallback sUnknown_083FD880[] = -{ - sub_811C934, - sub_811C938, - sub_811C984, - sub_811C9B8, - sub_811C934, - sub_811C9E4, - sub_811C934 -}; - -static const s16 sUnknown_083FD89C[2] = {12, -12}; -static const s16 sUnknown_083FD8A0[2] = {-1, 1}; - -static const TransitionState sPhase2_Transition_Slice_Funcs[] = -{ - Phase2_Transition_Slice_Func1, - Phase2_Transition_Slice_Func2, - Phase2_Transition_Slice_Func3 -}; - -static const TransitionState sPhase2_Transition_WhiteFade_Funcs[] = -{ - Phase2_Transition_WhiteFade_Func1, - Phase2_Transition_WhiteFade_Func2, - Phase2_Transition_WhiteFade_Func3, - Phase2_Transition_WhiteFade_Func4, - Phase2_Transition_WhiteFade_Func5 -}; - -static const s16 sUnknown_083FD8C4[8] = {0, 20, 15, 40, 10, 25, 35, 5}; - -static const TransitionState sPhase2_Transition_GridSquares_Funcs[] = -{ - Phase2_Transition_GridSquares_Func1, - Phase2_Transition_GridSquares_Func2, - Phase2_Transition_GridSquares_Func3 -}; - -static const TransitionState sPhase2_Transition_Shards_Funcs[] = -{ - Phase2_Transition_Shards_Func1, - Phase2_Transition_Shards_Func2, - Phase2_Transition_Shards_Func3, - Phase2_Transition_Shards_Func4, - Phase2_Transition_Shards_Func5 -}; - -static const s16 sUnknown_083FD8F4[][5] = -{ - {56, 0, 0, 160, 0}, - {104, 160, 240, 88, 1}, - {240, 72, 56, 0, 1}, - {0, 32, 144, 160, 0}, - {144, 160, 184, 0, 1}, - {56, 0, 168, 160, 0}, - {168, 160, 48, 0, 1}, -}; - -static const s16 sUnknown_083FD93A[] = {8, 4, 2, 1, 1, 1, 0}; - -static const TransitionState sPhase1_TransitionAll_Funcs[] = -{ - Phase1_TransitionAll_Func1, - Phase1_TransitionAll_Func2 -}; - -static const struct SpriteFrameImage sSpriteImageTable_83FD950[] = -{ - sSpriteImage_83FC148, 0x200 -}; - -static const union AnimCmd sSpriteAnim_83FD958[] = -{ - ANIMCMD_FRAME(0, 1), - ANIMCMD_END -}; - -static const union AnimCmd *const sSpriteAnimTable_83FD960[] = -{ - sSpriteAnim_83FD958 -}; - -static const union AffineAnimCmd sSpriteAffineAnim_83FD964[] = -{ - AFFINEANIMCMD_FRAME(0, 0, -4, 1), - AFFINEANIMCMD_JUMP(0) -}; - -static const union AffineAnimCmd sSpriteAffineAnim_83FD974[] = -{ - AFFINEANIMCMD_FRAME(0, 0, 4, 1), - AFFINEANIMCMD_JUMP(0) -}; - -static const union AffineAnimCmd *const sSpriteAffineAnimTable_83FD984[] = -{ - sSpriteAffineAnim_83FD964, - sSpriteAffineAnim_83FD974 -}; - -static const struct SpriteTemplate sSpriteTemplate_83FD98C = -{ - .tileTag = 0xFFFF, - .paletteTag = 4105, - .oam = &gFieldOamData_32x32, - .anims = sSpriteAnimTable_83FD960, - .images = sSpriteImageTable_83FD950, - .affineAnims = sSpriteAffineAnimTable_83FD984, - .callback = sub_811B720 -}; - -static const struct OamData gOamData_83FD9A4 = -{ - .y = 0, - .affineMode = 0, - .objMode = 0, - .mosaic = 0, - .bpp = 0, - .shape = 0, - .x = 0, - .matrixNum = 0, - .size = 3, - .tileNum = 0, - .priority = 0, - .paletteNum = 0, - .affineParam = 0, -}; - -static const struct SpriteFrameImage sSpriteImageTable_83FD9AC[] = -{ - sSpriteImage_83FC528, 0x800 -}; - -static const struct SpriteFrameImage sSpriteImageTable_83FD9B4[] = -{ - sSpriteImage_83FCD28, 0x800 -}; - -static const union AnimCmd sSpriteAnim_83FD9BC[] = -{ - ANIMCMD_FRAME(0, 1), - ANIMCMD_END -}; - -static const union AnimCmd *const sSpriteAnimTable_83FD9C4[] = -{ - sSpriteAnim_83FD9BC -}; - -static const struct SpriteTemplate sSpriteTemplate_83FD9C8 = -{ - .tileTag = 0xFFFF, - .paletteTag = 4106, - .oam = &gOamData_83FD9A4, - .anims = sSpriteAnimTable_83FD9C4, - .images = sSpriteImageTable_83FD9AC, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_811C90C -}; - -static const struct SpriteTemplate sSpriteTemplate_83FD9E0 = -{ - .tileTag = 0xFFFF, - .paletteTag = 4106, - .oam = &gOamData_83FD9A4, - .anims = sSpriteAnimTable_83FD9C4, - .images = sSpriteImageTable_83FD9B4, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_811C90C -}; - -static const u16 gFieldEffectObjectPalette10[] = INCBIN_U16("graphics/field_effect_objects/palettes/10.gbapal"); - -const struct SpritePalette gFieldEffectObjectPaletteInfo10 = -{ - gFieldEffectObjectPalette10, 0x1009 -}; - -static const u16 sMugshotPal_Sydney[] = INCBIN_U16("graphics/battle_transitions/sidney_bg.gbapal"); -static const u16 sMugshotPal_Phoebe[] = INCBIN_U16("graphics/battle_transitions/phoebe_bg.gbapal"); -static const u16 sMugshotPal_Glacia[] = INCBIN_U16("graphics/battle_transitions/glacia_bg.gbapal"); -static const u16 sMugshotPal_Drake[] = INCBIN_U16("graphics/battle_transitions/drake_bg.gbapal"); -static const u16 sMugshotPal_Steven[] = INCBIN_U16("graphics/battle_transitions/steven_bg.gbapal"); -static const u16 sMugshotPal_Brendan[] = INCBIN_U16("graphics/battle_transitions/brendan_bg.gbapal"); -static const u16 sMugshotPal_May[] = INCBIN_U16("graphics/battle_transitions/may_bg.gbapal"); - -static const u16 * const sOpponentMugshotsPals[MUGSHOTS_NO] = -{ - sMugshotPal_Sydney, - sMugshotPal_Phoebe, - sMugshotPal_Glacia, - sMugshotPal_Drake, - sMugshotPal_Steven -}; - -static const u16 * const sPlayerMugshotsPals[2] = -{ - sMugshotPal_Brendan, - sMugshotPal_May -}; - -static const u16 sUnusedTrainerPalette[] = INCBIN_U16("graphics/battle_transitions/unused_trainer.gbapal"); -static const struct SpritePalette sSpritePalette_UnusedTrainer = -{ - sUnusedTrainerPalette, 0x100A -}; - -static const u16 sBigPokeball_Tilemap[] = INCBIN_U16("graphics/battle_transitions/big_pokeball_map.bin"); -static const u16 sMugshotsTilemap[] = INCBIN_U16("graphics/battle_transitions/elite_four_bg_map.bin"); - -// actual code starts here - -void BattleTransition_StartOnField(u8 transitionID) -{ - gMain.callback2 = CB2_OverworldBasic; - LaunchBattleTransitionTask(transitionID); -} - -void BattleTransition_Start(u8 transitionID) -{ - LaunchBattleTransitionTask(transitionID); -} - -#define tState data[0] -#define tTransitionID data[1] -#define tTransitionDone data[15] - -bool8 IsBattleTransitionDone(void) -{ - u8 taskID = FindTaskIdByFunc(Task_BattleTransitionMain); - if (gTasks[taskID].tTransitionDone) - { - DestroyTask(taskID); - return TRUE; - } - else - return FALSE; -} - -static void LaunchBattleTransitionTask(u8 transitionID) -{ - u8 taskID = CreateTask(Task_BattleTransitionMain, 2); - gTasks[taskID].tTransitionID = transitionID; -} - -static void Task_BattleTransitionMain(u8 taskID) -{ - while (sMainTransitionPhases[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Transition_Phase1(struct Task* task) -{ - SetWeatherScreenFadeOut(); - CpuCopy32(gPlttBufferFaded, gPlttBufferUnfaded, 0x400); - if (sPhase1_Tasks[task->tTransitionID] != NULL) - { - CreateTask(sPhase1_Tasks[task->tTransitionID], 4); - task->tState++; - return FALSE; - } - else - { - task->tState = 2; - return TRUE; - } -} - -static bool8 Transition_WaitForPhase1(struct Task* task) -{ - if (FindTaskIdByFunc(sPhase1_Tasks[task->tTransitionID]) == 0xFF) - { - task->tState++; - return TRUE; - } - else - return FALSE; -} - -static bool8 Transition_Phase2(struct Task* task) -{ - CreateTask(sPhase2_Tasks[task->tTransitionID], 0); - task->tState++; - return FALSE; -} - -static bool8 Transition_WaitForPhase2(struct Task* task) -{ - task->tTransitionDone = 0; - if (FindTaskIdByFunc(sPhase2_Tasks[task->tTransitionID]) == 0xFF) - task->tTransitionDone = 1; - return FALSE; -} - -static void Phase1Task_TransitionAll(u8 taskID) -{ - if (gTasks[taskID].tState == 0) - { - gTasks[taskID].tState++; - CreatePhase1Task(0, 0, 3, 2, 2); - } - else if (sub_811D52C()) - DestroyTask(taskID); -} - -static void Phase2Task_Transition_Blur(u8 taskID) -{ - while (sPhase2_Transition_Blur_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Transition_Blur_Func1(struct Task* task) -{ - REG_MOSAIC = 0; - REG_BG1CNT |= BGCNT_MOSAIC; - REG_BG2CNT |= BGCNT_MOSAIC; - REG_BG3CNT |= BGCNT_MOSAIC; - task->tState++; - return TRUE; -} - -static bool8 Phase2_Transition_Blur_Func2(struct Task* task) -{ - if (task->data[1] != 0) - task->data[1]--; - else - { - task->data[1] = 4; - if (++task->data[2] == 10) - BeginNormalPaletteFade(0xFFFFFFFF, -1, 0, 16, RGB(0, 0, 0)); - REG_MOSAIC = (task->data[2] & 15) * 17; - if (task->data[2] > 14) - task->tState++; - } - return FALSE; -} - -static bool8 Phase2_Transition_Blur_Func3(struct Task* task) -{ - if (!gPaletteFade.active) - { - u8 taskID = FindTaskIdByFunc(Phase2Task_Transition_Blur); - DestroyTask(taskID); - } - return FALSE; -} - -static void Phase2Task_Transition_Swirl(u8 taskID) -{ - while (sPhase2_Transition_Swirl_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Transition_Swirl_Func1(struct Task* task) -{ - u16 savedIME; - - sub_811D658(); - ScanlineEffect_Clear(); - BeginNormalPaletteFade(0xFFFFFFFF, 4, 0, 16, RGB(0, 0, 0)); - sub_811D6E8(gScanlineEffectRegBuffers[1], TRANSITION_STRUCT.field_14, 0, 2, 0, 160); - - SetVBlankCallback(VBlankCB_Phase2_Transition_Swirl); - SetHBlankCallback(HBlankCB_Phase2_Transition_Swirl); - - savedIME = REG_IME; - REG_IME = 0; - REG_IE |= (INTR_FLAG_VBLANK | INTR_FLAG_HBLANK); - REG_IME = savedIME; - REG_DISPSTAT |= (DISPSTAT_VBLANK_INTR | DISPSTAT_HBLANK_INTR); - - task->tState++; - return FALSE; -} - -static bool8 Phase2_Transition_Swirl_Func2(struct Task* task) -{ - TRANSITION_STRUCT.VBlank_DMA = 0; - task->data[1] += 4; - task->data[2] += 8; - - sub_811D6E8(gScanlineEffectRegBuffers[0], TRANSITION_STRUCT.field_14, task->data[1], 2, task->data[2], 160); - - if (!gPaletteFade.active) - { - u8 taskID = FindTaskIdByFunc(Phase2Task_Transition_Swirl); - DestroyTask(taskID); - } - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static void VBlankCB_Phase2_Transition_Swirl(void) -{ - VBlankCB_BattleTransition(); - if (TRANSITION_STRUCT.VBlank_DMA) - DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); -} - -static void HBlankCB_Phase2_Transition_Swirl(void) -{ - u16 var = gScanlineEffectRegBuffers[1][REG_VCOUNT]; - REG_BG1HOFS = var; - REG_BG2HOFS = var; - REG_BG3HOFS = var; -} - -static void Phase2Task_Transition_Shuffle(u8 taskID) -{ - while (sPhase2_Transition_Shuffle_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Transition_Shuffle_Func1(struct Task* task) -{ - u16 savedIME; - - sub_811D658(); - ScanlineEffect_Clear(); - - BeginNormalPaletteFade(0xFFFFFFFF, 4, 0, 16, RGB(0, 0, 0)); - memset(gScanlineEffectRegBuffers[1], TRANSITION_STRUCT.field_16, 0x140); - - SetVBlankCallback(VBlankCB_Phase2_Transition_Shuffle); - SetHBlankCallback(HBlankCB_Phase2_Transition_Shuffle); - - savedIME = REG_IME; - REG_IME = 0; - REG_IE |= (INTR_FLAG_VBLANK | INTR_FLAG_HBLANK); - REG_IME = savedIME; - REG_DISPSTAT |= (DISPSTAT_VBLANK_INTR | DISPSTAT_HBLANK_INTR); - - task->tState++; - return FALSE; -} - -static bool8 Phase2_Transition_Shuffle_Func2(struct Task* task) -{ - u8 i; - u16 r3, r4; - - TRANSITION_STRUCT.VBlank_DMA = 0; - r4 = task->data[1]; - r3 = task->data[2] >> 8; - task->data[1] += 4224; - task->data[2] += 384; - - for (i = 0; i < 160; i++, r4 += 4224) - { - u16 var = r4 / 256; - gScanlineEffectRegBuffers[0][i] = TRANSITION_STRUCT.field_16 + Sin(var, r3); - } - - if (!gPaletteFade.active) - DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Shuffle)); - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static void VBlankCB_Phase2_Transition_Shuffle(void) -{ - VBlankCB_BattleTransition(); - if (TRANSITION_STRUCT.VBlank_DMA) - DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); -} - -static void HBlankCB_Phase2_Transition_Shuffle(void) -{ - u16 var = gScanlineEffectRegBuffers[1][REG_VCOUNT]; - REG_BG1VOFS = var; - REG_BG2VOFS = var; - REG_BG3VOFS = var; -} - -static void Phase2Task_Transition_BigPokeball(u8 taskID) -{ - while (sPhase2_Transition_BigPokeball_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Transition_BigPokeball_Func1(struct Task* task) -{ - u16 i; - u16 *dst1, *dst2; - - sub_811D658(); - ScanlineEffect_Clear(); - - task->data[1] = 16; - task->data[2] = 0; - task->data[4] = 0; - task->data[5] = 0x4000; - TRANSITION_STRUCT.WININ = 63; - TRANSITION_STRUCT.WINOUT = 0; - TRANSITION_STRUCT.field_6 = 240; - TRANSITION_STRUCT.WIN0V = 160; - TRANSITION_STRUCT.BLDCNT = 0x3F41; - TRANSITION_STRUCT.BLDALPHA = task->data[1] * 256; // 16 * 256 = 0x1000 - - for (i = 0; i < 160; i++) - { - gScanlineEffectRegBuffers[1][i] = 240; - } - - SetVBlankCallback(VBlankCB0_Phase2_Transition_BigPokeball); - - sub_811D6A8(&dst1, & dst2); - CpuFill16(0, dst1, 0x800); - CpuSet(sBigPokeball_Tileset, dst2, 0x2C0); - LoadPalette(gFieldEffectObjectPalette10, 240, 32); - - task->tState++; - return FALSE; -} - -static bool8 Phase2_Transition_BigPokeball_Func2(struct Task* task) -{ - s16 i, j; - u16 *dst1, *dst2; - const u16* BigPokeballMap; - - BigPokeballMap = sBigPokeball_Tilemap; - sub_811D6A8(&dst1, &dst2); - for (i = 0; i < 20; i++) - { - for (j = 0; j < 30; j++, BigPokeballMap++) - { - dst1[i * 32 + j] = *BigPokeballMap | 0xF000; - } - } - sub_811D6E8(gScanlineEffectRegBuffers[0], 0, task->data[4], 132, task->data[5], 160); - - task->tState++; - return TRUE; -} - -static bool8 Phase2_Transition_BigPokeball_Func3(struct Task* task) -{ - TRANSITION_STRUCT.VBlank_DMA = 0; - if (task->data[3] == 0 || --task->data[3] == 0) - { - task->data[2]++; - task->data[3] = 2; - } - TRANSITION_STRUCT.BLDALPHA = (task->data[1] << 8) | task->data[2]; - if (task->data[2] > 15) - task->tState++; - task->data[4] += 8; - task->data[5] -= 256; - - sub_811D6E8(gScanlineEffectRegBuffers[0], 0, task->data[4], 132, task->data[5] >> 8, 160); - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Transition_BigPokeball_Func4(struct Task* task) -{ - TRANSITION_STRUCT.VBlank_DMA = 0; - if (task->data[3] == 0 || --task->data[3] == 0) - { - task->data[1]--; - task->data[3] = 2; - } - TRANSITION_STRUCT.BLDALPHA = (task->data[1] << 8) | task->data[2]; - if (task->data[1] == 0) - task->tState++; - task->data[4] += 8; - task->data[5] -= 256; - - sub_811D6E8(gScanlineEffectRegBuffers[0], 0, task->data[4], 132, task->data[5] >> 8, 160); - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Transition_BigPokeball_Func5(struct Task* task) -{ - TRANSITION_STRUCT.VBlank_DMA = 0; - task->data[4] += 8; - task->data[5] -= 256; - - sub_811D6E8(gScanlineEffectRegBuffers[0], 0, task->data[4], 132, task->data[5] >> 8, 160); - - if (task->data[5] <= 0) - { - task->tState++; - task->data[1] = 160; - task->data[2] = 256; - task->data[3] = 0; - } - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Transition_BigPokeball_Func6(struct Task* task) -{ - TRANSITION_STRUCT.VBlank_DMA = 0; - if (task->data[2] < 1024) - task->data[2] += 128; - if (task->data[1] != 0) - { - task->data[1] -= (task->data[2] >> 8); - if (task->data[1] < 0) - task->data[1] = 0; - } - sub_811D764(gScanlineEffectRegBuffers[0], 120, 80, task->data[1]); - if (task->data[1] == 0) - { - DmaStop(0); - sub_811D6D4(); - DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_BigPokeball)); - } - if (task->data[3] == 0) - { - task->data[3]++; - SetVBlankCallback(VBlankCB1_Phase2_Transition_BigPokeball); - } - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static void Transition_BigPokeball_Vblank(void) -{ - DmaStop(0); - VBlankCB_BattleTransition(); - if (TRANSITION_STRUCT.VBlank_DMA) - DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); - REG_WININ = TRANSITION_STRUCT.WININ; - REG_WINOUT = TRANSITION_STRUCT.WINOUT; - REG_WIN0V = TRANSITION_STRUCT.WIN0V; - REG_BLDCNT = TRANSITION_STRUCT.BLDCNT; - REG_BLDALPHA = TRANSITION_STRUCT.BLDALPHA; -} - -static void VBlankCB0_Phase2_Transition_BigPokeball(void) -{ - Transition_BigPokeball_Vblank(); - DmaSet(0, gScanlineEffectRegBuffers[1], ®_BG0HOFS, 0xA2400001); -} - -static void VBlankCB1_Phase2_Transition_BigPokeball(void) -{ - Transition_BigPokeball_Vblank(); - DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, 0xA2400001); -} - -static void Phase2Task_Transition_PokeballsTrail(u8 taskID) -{ - while (sPhase2_Transition_PokeballsTrail_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Transition_PokeballsTrail_Func1(struct Task* task) -{ - u16 *dst1, *dst2; - - sub_811D6A8(&dst1, &dst2); - CpuSet(sPokeballTrail_Tileset, dst2, 0x20); - CpuFill32(0, dst1, 0x800); - LoadPalette(gFieldEffectObjectPalette10, 0xF0, 0x20); - - task->tState++; - return FALSE; -} - -static bool8 Phase2_Transition_PokeballsTrail_Func2(struct Task* task) -{ - s16 i; - s16 rand; - s16 arr0[2]; - s16 arr1[5]; - - memcpy(arr0, sUnknown_083FD7E4, sizeof(sUnknown_083FD7E4)); - memcpy(arr1, sUnknown_083FD7E8, sizeof(sUnknown_083FD7E8)); - rand = Random() & 1; - for (i = 0; i <= 4; i++, rand ^= 1) - { - gFieldEffectArguments[0] = arr0[rand]; // x - gFieldEffectArguments[1] = (i * 32) + 16; // y - gFieldEffectArguments[2] = rand; - gFieldEffectArguments[3] = arr1[i]; - FieldEffectStart(FLDEFF_POKEBALL); - } - - task->tState++; - return FALSE; -} - -static bool8 Phase2_Transition_PokeballsTrail_Func3(struct Task* task) -{ - if (!FieldEffectActiveListContains(FLDEFF_POKEBALL)) - { - sub_811D6D4(); - DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_PokeballsTrail)); - } - return FALSE; -} - -bool8 FldEff_Pokeball(void) -{ - u8 spriteID = CreateSpriteAtEnd(&sSpriteTemplate_83FD98C, gFieldEffectArguments[0], gFieldEffectArguments[1], 0); - gSprites[spriteID].oam.priority = 0; - gSprites[spriteID].oam.affineMode = 1; - gSprites[spriteID].data[0] = gFieldEffectArguments[2]; - gSprites[spriteID].data[1] = gFieldEffectArguments[3]; - gSprites[spriteID].data[2] = -1; - InitSpriteAffineAnim(&gSprites[spriteID]); - StartSpriteAffineAnim(&gSprites[spriteID], gFieldEffectArguments[2]); - return FALSE; -} - -#define SOME_VRAM_STORE(ptr, posY, posX, toStore) \ -{ \ - u32 index = (posY) * 32 + posX; \ - ptr[index] = toStore; \ -} - -static void sub_811B720(struct Sprite* sprite) -{ - s16 arr0[2]; - - memcpy(arr0, sUnknown_083FD7F2, sizeof(sUnknown_083FD7F2)); - if (sprite->data[1] != 0) - sprite->data[1]--; - else - { - if (sprite->pos1.x >= 0 && sprite->pos1.x <= 240) - { - s16 posX = sprite->pos1.x >> 3; - s16 posY = sprite->pos1.y >> 3; - - if (posX != sprite->data[2]) - { - u32 var; - u16 *ptr; - - sprite->data[2] = posX; - var = (((REG_BG0CNT >> 8) & 0x1F) << 11); // r2 - ptr = (u16 *)(VRAM + var); - - SOME_VRAM_STORE(ptr, posY - 2, posX, 0xF001); - SOME_VRAM_STORE(ptr, posY - 1, posX, 0xF001); - SOME_VRAM_STORE(ptr, posY - 0, posX, 0xF001); - SOME_VRAM_STORE(ptr, posY + 1, posX, 0xF001); - } - } - sprite->pos1.x += arr0[sprite->data[0]]; - if (sprite->pos1.x < -15 || sprite->pos1.x > 255) - FieldEffectStop(sprite, FLDEFF_POKEBALL); - } -} - -static void Phase2Task_Transition_Clockwise_BlackFade(u8 taskID) -{ - while (sPhase2_Transition_Clockwise_BlackFade_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Transition_Clockwise_BlackFade_Func1(struct Task* task) -{ - u16 i; - - sub_811D658(); - ScanlineEffect_Clear(); - - TRANSITION_STRUCT.WININ = 0; - TRANSITION_STRUCT.WINOUT = 63; - TRANSITION_STRUCT.field_6 = -3855; - TRANSITION_STRUCT.WIN0V = 160; - - for (i = 0; i < 160; i++) - { - gScanlineEffectRegBuffers[1][i] = 0xF3F4; - } - - SetVBlankCallback(VBlankCB_Phase2_Transition_Clockwise_BlackFade); - TRANSITION_STRUCT.data[4] = 120; - - task->tState++; - return TRUE; -} - -static bool8 Phase2_Transition_Clockwise_BlackFade_Func2(struct Task* task) -{ - TRANSITION_STRUCT.VBlank_DMA = 0; - - sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, TRANSITION_STRUCT.data[4], -1, 1, 1); - do - { - gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (TRANSITION_STRUCT.data[2] + 1) | 0x7800; - } while (!sub_811D978(TRANSITION_STRUCT.data, 1, 1)); - - TRANSITION_STRUCT.data[4] += 16; - if (TRANSITION_STRUCT.data[4] >= 240) - { - TRANSITION_STRUCT.data[5] = 0; - task->tState++; - } - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Transition_Clockwise_BlackFade_Func3(struct Task* task) -{ - s16 r1, r3; - vu8 var = 0; - - TRANSITION_STRUCT.VBlank_DMA = 0; - - sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, 240, TRANSITION_STRUCT.data[5], 1, 1); - - while (1) - { - r1 = 120, r3 = TRANSITION_STRUCT.data[2] + 1; - if (TRANSITION_STRUCT.data[5] >= 80) - r1 = TRANSITION_STRUCT.data[2], r3 = 240; - gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (r3) | (r1 << 8); - if (var != 0) - break; - var = sub_811D978(TRANSITION_STRUCT.data, 1, 1); - } - - TRANSITION_STRUCT.data[5] += 8; - if (TRANSITION_STRUCT.data[5] >= 160) - { - TRANSITION_STRUCT.data[4] = 240; - task->tState++; - } - else - { - while (TRANSITION_STRUCT.data[3] < TRANSITION_STRUCT.data[5]) - { - gScanlineEffectRegBuffers[0][++TRANSITION_STRUCT.data[3]] = (r3) | (r1 << 8); - } - } - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Transition_Clockwise_BlackFade_Func4(struct Task* task) -{ - TRANSITION_STRUCT.VBlank_DMA = 0; - - sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, TRANSITION_STRUCT.data[4], 160, 1, 1); - do - { - gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (TRANSITION_STRUCT.data[2] << 8) | 0xF0; - } while (!sub_811D978(TRANSITION_STRUCT.data, 1, 1)); - - TRANSITION_STRUCT.data[4] -= 16; - if (TRANSITION_STRUCT.data[4] <= 0) - { - TRANSITION_STRUCT.data[5] = 160; - task->tState++; - } - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Transition_Clockwise_BlackFade_Func5(struct Task* task) -{ - s16 r1, r2, r3; - vu8 var = 0; - - TRANSITION_STRUCT.VBlank_DMA = 0; - - sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, 0, TRANSITION_STRUCT.data[5], 1, 1); - - while (1) - { - r1 = gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] & 0xFF, r2 = TRANSITION_STRUCT.data[2]; - if (TRANSITION_STRUCT.data[5] <= 80) - r2 = 120, r1 = TRANSITION_STRUCT.data[2]; - gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (r1) | (r2 << 8); - r3 = 0; - if (var != 0) - break; - var = sub_811D978(TRANSITION_STRUCT.data, 1, 1); - } - - TRANSITION_STRUCT.data[5] -= 8; - if (TRANSITION_STRUCT.data[5] <= 0) - { - TRANSITION_STRUCT.data[4] = r3; - task->tState++; - } - else - { - while (TRANSITION_STRUCT.data[3] > TRANSITION_STRUCT.data[5]) - { - gScanlineEffectRegBuffers[0][--TRANSITION_STRUCT.data[3]] = (r1) | (r2 << 8); - } - } - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Transition_Clockwise_BlackFade_Func6(struct Task* task) -{ - TRANSITION_STRUCT.VBlank_DMA = 0; - - sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, TRANSITION_STRUCT.data[4], 0, 1, 1); - do - { - s16 r2, r3; - - r2 = 120, r3 = TRANSITION_STRUCT.data[2]; - if (TRANSITION_STRUCT.data[2] >= 120) - r2 = 0, r3 = 240; - gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (r3) | (r2 << 8); - - } while (!sub_811D978(TRANSITION_STRUCT.data, 1, 1)); - - TRANSITION_STRUCT.data[4] += 16; - if (TRANSITION_STRUCT.data[2] > 120) - task->tState++; - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Transition_Clockwise_BlackFade_Func7(struct Task* task) -{ - DmaStop(0); - sub_811D6D4(); - DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Clockwise_BlackFade)); - return FALSE; -} - -static void VBlankCB_Phase2_Transition_Clockwise_BlackFade(void) -{ - DmaStop(0); - VBlankCB_BattleTransition(); - if (TRANSITION_STRUCT.VBlank_DMA != 0) - DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); - REG_WININ = TRANSITION_STRUCT.WININ; - REG_WINOUT = TRANSITION_STRUCT.WINOUT; - REG_WIN0V = TRANSITION_STRUCT.WIN0V; - REG_WIN0H = gScanlineEffectRegBuffers[1][0]; - DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, 0xA2400001); -} - -static void Phase2Task_Transition_Ripple(u8 taskID) -{ - while (sPhase2_Transition_Ripple_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Transition_Ripple_Func1(struct Task* task) -{ - u8 i; - - sub_811D658(); - ScanlineEffect_Clear(); - - for (i = 0; i < 160; i++) - { - gScanlineEffectRegBuffers[1][i] = TRANSITION_STRUCT.field_16; - } - - SetVBlankCallback(VBlankCB_Phase2_Transition_Ripple); - SetHBlankCallback(HBlankCB_Phase2_Transition_Ripple); - - REG_IE |= INTR_FLAG_HBLANK; - REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; - - task->tState++; - return TRUE; -} - -static bool8 Phase2_Transition_Ripple_Func2(struct Task* task) -{ - u8 i; - s16 r3; - u16 r4, r8; - - TRANSITION_STRUCT.VBlank_DMA = 0; - - r3 = task->data[2] >> 8; - r4 = task->data[1]; - r8 = 384; - task->data[1] += 0x400; - if (task->data[2] <= 0x1FFF) - task->data[2] += 0x180; - - for (i = 0; i < 160; i++, r4 += r8) - { - // todo: fix the asm - s16 var = r4 >> 8; - asm(""); - gScanlineEffectRegBuffers[0][i] = TRANSITION_STRUCT.field_16 + Sin(var, r3); - asm(""); - } - - if (++task->data[3] == 81) - { - task->data[4]++; - BeginNormalPaletteFade(0xFFFFFFFF, -2, 0, 16, RGB(0, 0, 0)); - } - - if (task->data[4] != 0 && !gPaletteFade.active) - DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Ripple)); - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static void VBlankCB_Phase2_Transition_Ripple(void) -{ - VBlankCB_BattleTransition(); - if (TRANSITION_STRUCT.VBlank_DMA) - DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); -} - -static void HBlankCB_Phase2_Transition_Ripple(void) -{ - u16 var = gScanlineEffectRegBuffers[1][REG_VCOUNT]; - REG_BG1VOFS = var; - REG_BG2VOFS = var; - REG_BG3VOFS = var; -} - -static void Phase2Task_Transition_Wave(u8 taskID) -{ - while (sPhase2_Transition_Wave_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Transition_Wave_Func1(struct Task* task) -{ - u8 i; - - sub_811D658(); - ScanlineEffect_Clear(); - - TRANSITION_STRUCT.WININ = 63; - TRANSITION_STRUCT.WINOUT = 0; - TRANSITION_STRUCT.field_6 = 240; - TRANSITION_STRUCT.WIN0V = 160; - - for (i = 0; i < 160; i++) - { - gScanlineEffectRegBuffers[1][i] = 242; - } - - SetVBlankCallback(VBlankCB_Phase2_Transition_Wave); - - task->tState++; - return TRUE; -} - -static bool8 Phase2_Transition_Wave_Func2(struct Task* task) -{ - u8 i, r5; - u16* toStore; - bool8 nextFunc; - - TRANSITION_STRUCT.VBlank_DMA = 0; - toStore = gScanlineEffectRegBuffers[0]; - r5 = task->data[2]; - task->data[2] += 16; - task->data[1] += 8; - - for (i = 0, nextFunc = TRUE; i < 160; i++, r5 += 4, toStore++) - { - s16 value = task->data[1] + Sin(r5, 40); - if (value < 0) - value = 0; - if (value > 240) - value = 240; - *toStore = (value << 8) | (0xF1); - if (value < 240) - nextFunc = FALSE; - } - if (nextFunc) - task->tState++; - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Transition_Wave_Func3(struct Task* task) -{ - DmaStop(0); - sub_811D6D4(); - DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Wave)); - return FALSE; -} - -static void VBlankCB_Phase2_Transition_Wave(void) -{ - DmaStop(0); - VBlankCB_BattleTransition(); - if (TRANSITION_STRUCT.VBlank_DMA != 0) - DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); - REG_WININ = TRANSITION_STRUCT.WININ; - REG_WINOUT = TRANSITION_STRUCT.WINOUT; - REG_WIN0V = TRANSITION_STRUCT.WIN0V; - DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, 0xA2400001); -} - -#define tMugshotOpponentID data[13] -#define tMugshotPlayerID data[14] -#define tMugshotID data[15] - -static void Phase2Task_Transition_Sydney(u8 taskID) -{ - gTasks[taskID].tMugshotID = MUGSHOT_SYDNEY; - Phase2Task_MugShotTransition(taskID); -} - -static void Phase2Task_Transition_Phoebe(u8 taskID) -{ - gTasks[taskID].tMugshotID = MUGSHOT_PHOEBE; - Phase2Task_MugShotTransition(taskID); -} - -static void Phase2Task_Transition_Glacia(u8 taskID) -{ - gTasks[taskID].tMugshotID = MUGSHOT_GLACIA; - Phase2Task_MugShotTransition(taskID); -} - -static void Phase2Task_Transition_Drake(u8 taskID) -{ - gTasks[taskID].tMugshotID = MUGSHOT_DRAKE; - Phase2Task_MugShotTransition(taskID); -} - -static void Phase2Task_Transition_Steven(u8 taskID) -{ - gTasks[taskID].tMugshotID = MUGSHOT_STEVEN; - Phase2Task_MugShotTransition(taskID); -} - -static void Phase2Task_MugShotTransition(u8 taskID) -{ - while (sPhase2_Mugshot_Transition_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Mugshot_Func1(struct Task* task) -{ - u8 i; - - sub_811D658(); - ScanlineEffect_Clear(); - Mugshots_CreateOpponentPlayerSprites(task); - - task->data[1] = 0; - task->data[2] = 1; - task->data[3] = 239; - TRANSITION_STRUCT.WININ = 63; - TRANSITION_STRUCT.WINOUT = 62; - TRANSITION_STRUCT.WIN0V = 160; - - for (i = 0; i < 160; i++) - { - gScanlineEffectRegBuffers[1][i] = 0xF0F1; - } - - SetVBlankCallback(VBlankCB0_Phase2_Mugshots); - - task->tState++; - return FALSE; -} - -static bool8 Phase2_Mugshot_Func2(struct Task* task) -{ - s16 i, j; - u16 *dst1, *dst2; - const u16* MugshotsMap; - - MugshotsMap = sMugshotsTilemap; - sub_811D6A8(&dst1, &dst2); - CpuSet(sUnknown_083FC348, dst2, 0xF0); - LoadPalette(sOpponentMugshotsPals[task->tMugshotID], 0xF0, 0x20); - LoadPalette(sPlayerMugshotsPals[gSaveBlock2.playerGender], 0xFA, 0xC); - - for (i = 0; i < 20; i++) - { - for (j = 0; j < 32; j++, MugshotsMap++) - { - dst1[i * 32 + j] = *MugshotsMap | 0xF000; - } - } - - REG_IE |= INTR_FLAG_HBLANK; - REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; - SetHBlankCallback(HBlankCB_Phase2_Mugshots); - task->tState++; - return FALSE; -} - -static bool8 Phase2_Mugshot_Func3(struct Task* task) -{ - u8 i, r5; - u16* toStore; - s16 value; - s32 mergedValue; - - TRANSITION_STRUCT.VBlank_DMA = 0; - - toStore = gScanlineEffectRegBuffers[0]; - r5 = task->data[1]; - task->data[1] += 0x10; - - for (i = 0; i < 80; i++, toStore++, r5 += 0x10) - { - value = task->data[2] + Sin(r5, 0x10); - if (value < 0) - value = 1; - if (value > 0xF0) - value = 0xF0; - *toStore = value; - } - for (; i < 160; i++, toStore++, r5 += 0x10) - { - value = task->data[3] - Sin(r5, 0x10); - if (value < 0) - value = 0; - if (value > 0xEF) - value = 0xEF; - *toStore = (value << 8) | (0xF0); - } - - task->data[2] += 8; - task->data[3] -= 8; - if (task->data[2] > 0xF0) - task->data[2] = 0xF0; - if (task->data[3] < 0) - task->data[3] = 0; - mergedValue = *(s32*)(&task->data[2]); - if (mergedValue == 0xF0) - task->tState++; - - TRANSITION_STRUCT.field_18 -= 8; - TRANSITION_STRUCT.field_1A += 8; - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Mugshot_Func4(struct Task* task) -{ - u8 i; - u16* toStore; - - TRANSITION_STRUCT.VBlank_DMA = 0; - - for (i = 0, toStore = gScanlineEffectRegBuffers[0]; i < 160; i++, toStore++) - { - *toStore = 0xF0; - } - - task->tState++; - task->data[1] = 0; - task->data[2] = 0; - task->data[3] = 0; - TRANSITION_STRUCT.field_18 -= 8; - TRANSITION_STRUCT.field_1A += 8; - - sub_811CA10(task->tMugshotOpponentID, 0); - sub_811CA10(task->tMugshotPlayerID, 1); - sub_811CA28(task->tMugshotOpponentID); - - PlaySE(SE_BT_START); - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Mugshot_Func5(struct Task* task) -{ - TRANSITION_STRUCT.field_18 -= 8; - TRANSITION_STRUCT.field_1A += 8; - if (sub_811CA44(task->tMugshotOpponentID)) - { - task->tState++; - sub_811CA28(task->tMugshotPlayerID); - } - return FALSE; -} - -static bool8 Phase2_Mugshot_Func6(struct Task* task) -{ - TRANSITION_STRUCT.field_18 -= 8; - TRANSITION_STRUCT.field_1A += 8; - if (sub_811CA44(task->tMugshotPlayerID)) - { - TRANSITION_STRUCT.VBlank_DMA = 0; - SetVBlankCallback(NULL); - DmaStop(0); - memset(gScanlineEffectRegBuffers[0], 0, 0x140); - memset(gScanlineEffectRegBuffers[1], 0, 0x140); - REG_WIN0H = 0xF0; - REG_BLDY = 0; - task->tState++; - task->data[3] = 0; - task->data[4] = 0; - TRANSITION_STRUCT.BLDCNT = 0xBF; - SetVBlankCallback(VBlankCB1_Phase2_Mugshots); - } - return FALSE; -} - -static bool8 Phase2_Mugshot_Func7(struct Task* task) -{ - bool32 r6; - - TRANSITION_STRUCT.VBlank_DMA = 0; - r6 = TRUE; - TRANSITION_STRUCT.field_18 -= 8; - TRANSITION_STRUCT.field_1A += 8; - - if (task->data[4] < 0x50) - task->data[4] += 2; - if (task->data[4] > 0x50) - task->data[4] = 0x50; - - if (++task->data[3] & 1) - { - s16 i; - for (i = 0, r6 = FALSE; i <= task->data[4]; i++) - { - s16 index1 = 0x50 - i; - s16 index2 = 0x50 + i; - if (gScanlineEffectRegBuffers[0][index1] <= 15) - { - r6 = TRUE; - gScanlineEffectRegBuffers[0][index1]++; - } - if (gScanlineEffectRegBuffers[0][index2] <= 15) - { - r6 = TRUE; - gScanlineEffectRegBuffers[0][index2]++; - } - } - } - - if (task->data[4] == 0x50 && !r6) - task->tState++; - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Mugshot_Func8(struct Task* task) -{ - TRANSITION_STRUCT.VBlank_DMA = 0; - BlendPalettes(0xFFFFFFFF, 16, RGB(31, 31, 31)); - TRANSITION_STRUCT.BLDCNT = 0xFF; - task->data[3] = 0; - - task->tState++; - return TRUE; -} - -static bool8 Phase2_Mugshot_Func9(struct Task* task) -{ - TRANSITION_STRUCT.VBlank_DMA = 0; - - task->data[3]++; - memset(gScanlineEffectRegBuffers[0], task->data[3], 0x140); - if (task->data[3] > 15) - task->tState++; - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Mugshot_Func10(struct Task* task) -{ - DmaStop(0); - sub_811D6D4(); - DestroyTask(FindTaskIdByFunc(task->func)); - return FALSE; -} - -static void VBlankCB0_Phase2_Mugshots(void) -{ - DmaStop(0); - VBlankCB_BattleTransition(); - if (TRANSITION_STRUCT.VBlank_DMA != 0) - DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); - REG_BG0VOFS = TRANSITION_STRUCT.field_1C; - REG_WININ = TRANSITION_STRUCT.WININ; - REG_WINOUT = TRANSITION_STRUCT.WINOUT; - REG_WIN0V = TRANSITION_STRUCT.WIN0V; - DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, 0xA2400001); -} - -static void VBlankCB1_Phase2_Mugshots(void) -{ - DmaStop(0); - VBlankCB_BattleTransition(); - if (TRANSITION_STRUCT.VBlank_DMA != 0) - DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); - REG_BLDCNT = TRANSITION_STRUCT.BLDCNT; - DmaSet(0, gScanlineEffectRegBuffers[1], ®_BLDY, 0xA2400001); -} - -static void HBlankCB_Phase2_Mugshots(void) -{ - if (REG_VCOUNT < 80) - REG_BG0HOFS = TRANSITION_STRUCT.field_18; - else - REG_BG0HOFS = TRANSITION_STRUCT.field_1A; -} - -static void Mugshots_CreateOpponentPlayerSprites(struct Task* task) -{ - struct Sprite *opponentSprite, *playerSprite; - - s16 mugshotID = task->tMugshotID; - task->tMugshotOpponentID = CreateTrainerSprite(sMugshotsTrainerPicIDsTable[mugshotID], - sMugshotsOpponentCoords[mugshotID][0] - 32, - sMugshotsOpponentCoords[mugshotID][1] + 42, - 0, ewramC03C); - task->tMugshotPlayerID = CreateTrainerSprite(gSaveBlock2.playerGender, 272, 106, 0, ewramC03C); - - opponentSprite = &gSprites[task->tMugshotOpponentID]; - playerSprite = &gSprites[task->tMugshotPlayerID]; - - opponentSprite->callback = sub_811C90C; - playerSprite->callback = sub_811C90C; - - opponentSprite->oam.affineMode = 3; - playerSprite->oam.affineMode = 3; - - opponentSprite->oam.matrixNum = AllocOamMatrix(); - playerSprite->oam.matrixNum = AllocOamMatrix(); - - opponentSprite->oam.shape = 1; - playerSprite->oam.shape = 1; - - opponentSprite->oam.size = 3; - playerSprite->oam.size = 3; - - CalcCenterToCornerVec(opponentSprite, 1, 3, 3); - CalcCenterToCornerVec(playerSprite, 1, 3, 3); - - SetOamMatrixRotationScaling(opponentSprite->oam.matrixNum, sMugshotsOpponentRotationScales[mugshotID][0], sMugshotsOpponentRotationScales[mugshotID][1], 0); - SetOamMatrixRotationScaling(playerSprite->oam.matrixNum, -512, 0x200, 0); -} - -static void sub_811C90C(struct Sprite* sprite) -{ - while (sUnknown_083FD880[sprite->data[0]](sprite)); -} - -static bool8 sub_811C934(struct Sprite* sprite) -{ - return FALSE; -} - -static bool8 sub_811C938(struct Sprite* sprite) -{ - s16 arr0[2]; - s16 arr1[2]; - - memcpy(arr0, sUnknown_083FD89C, sizeof(sUnknown_083FD89C)); - memcpy(arr1, sUnknown_083FD8A0, sizeof(sUnknown_083FD8A0)); - - sprite->data[0]++; - sprite->data[1] = arr0[sprite->data[7]]; - sprite->data[2] = arr1[sprite->data[7]]; - return TRUE; -} - -static bool8 sub_811C984(struct Sprite* sprite) -{ - sprite->pos1.x += sprite->data[1]; - if (sprite->data[7] && sprite->pos1.x < 133) - sprite->data[0]++; - else if (!sprite->data[7] && sprite->pos1.x > 103) - sprite->data[0]++; - return FALSE; -} - -static bool8 sub_811C9B8(struct Sprite* sprite) -{ - sprite->data[1] += sprite->data[2]; - sprite->pos1.x += sprite->data[1]; - if (sprite->data[1] == 0) - { - sprite->data[0]++; - sprite->data[2] = -sprite->data[2]; - sprite->data[6] = 1; - } - return FALSE; -} - -static bool8 sub_811C9E4(struct Sprite* sprite) -{ - sprite->data[1] += sprite->data[2]; - sprite->pos1.x += sprite->data[1]; - if (sprite->pos1.x < -31 || sprite->pos1.x > 271) - sprite->data[0]++; - return FALSE; -} - -static void sub_811CA10(s16 spriteID, s16 value) -{ - gSprites[spriteID].data[7] = value; -} - -static void sub_811CA28(s16 spriteID) -{ - gSprites[spriteID].data[0]++; -} - -static s16 sub_811CA44(s16 spriteID) -{ - return gSprites[spriteID].data[6]; -} - -#undef tMugshotOpponentID -#undef tMugshotPlayerID -#undef tMugshotID - -static void Phase2Task_Transition_Slice(u8 taskID) -{ - while (sPhase2_Transition_Slice_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Transition_Slice_Func1(struct Task* task) -{ - u16 i; - - sub_811D658(); - ScanlineEffect_Clear(); - - task->data[2] = 256; - task->data[3] = 1; - TRANSITION_STRUCT.WININ = 63; - TRANSITION_STRUCT.WINOUT = 0; - TRANSITION_STRUCT.WIN0V = 160; - - for (i = 0; i < 160; i++) - { - gScanlineEffectRegBuffers[1][i] = TRANSITION_STRUCT.field_14; - gScanlineEffectRegBuffers[1][160 + i] = 0xF0; - } - - REG_IE |= INTR_FLAG_HBLANK; - REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; - - SetVBlankCallback(VBlankCB_Phase2_Transition_Slice); - SetHBlankCallback(HBlankCB_Phase2_Transition_Slice); - - task->tState++; - return TRUE; -} - -static bool8 Phase2_Transition_Slice_Func2(struct Task* task) -{ - u16 i; - - TRANSITION_STRUCT.VBlank_DMA = 0; - - task->data[1] += (task->data[2] >> 8); - if (task->data[1] > 0xF0) - task->data[1] = 0xF0; - if (task->data[2] <= 0xFFF) - task->data[2] += task->data[3]; - if (task->data[3] < 128) - task->data[3] <<= 1; // multiplying by two - - for (i = 0; i < 160; i++) - { - u16* storeLoc1 = &gScanlineEffectRegBuffers[0][i]; - u16* storeLoc2 = &gScanlineEffectRegBuffers[0][i + 160]; - if (1 & i) - { - *storeLoc1 = TRANSITION_STRUCT.field_14 + task->data[1]; - *storeLoc2 = 0xF0 - task->data[1]; - } - else - { - *storeLoc1 = TRANSITION_STRUCT.field_14 - task->data[1]; - *storeLoc2 = (task->data[1] << 8) | (0xF1); - } - } - - if (task->data[1] > 0xEF) - task->tState++; - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Transition_Slice_Func3(struct Task* task) -{ - DmaStop(0); - sub_811D6D4(); - DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Slice)); - return FALSE; -} - -static void VBlankCB_Phase2_Transition_Slice(void) -{ - DmaStop(0); - VBlankCB_BattleTransition(); - REG_WININ = TRANSITION_STRUCT.WININ; - REG_WINOUT = TRANSITION_STRUCT.WINOUT; - REG_WIN0V = TRANSITION_STRUCT.WIN0V; - if (TRANSITION_STRUCT.VBlank_DMA) - DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 640); - DmaSet(0, &gScanlineEffectRegBuffers[1][160], ®_WIN0H, 0xA2400001); -} - -static void HBlankCB_Phase2_Transition_Slice(void) -{ - u16 var = gScanlineEffectRegBuffers[1][REG_VCOUNT]; - REG_BG1HOFS = var; - REG_BG2HOFS = var; - REG_BG3HOFS = var; -} - -static void Phase2Task_Transition_WhiteFade(u8 taskID) -{ - while (sPhase2_Transition_WhiteFade_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Transition_WhiteFade_Func1(struct Task* task) -{ - u16 i; - - sub_811D658(); - ScanlineEffect_Clear(); - - TRANSITION_STRUCT.BLDCNT = 0xBF; - TRANSITION_STRUCT.BLDY = 0; - TRANSITION_STRUCT.WININ = 0x1E; - TRANSITION_STRUCT.WINOUT = 0x3F; - TRANSITION_STRUCT.WIN0V = 0xA0; - - for (i = 0; i < 160; i++) - { - gScanlineEffectRegBuffers[1][i] = 0; - gScanlineEffectRegBuffers[1][i + 160] = 0xF0; - } - - REG_IE |= INTR_FLAG_HBLANK; - REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; - - SetHBlankCallback(HBlankCB_Phase2_Transition_WhiteFade); - SetVBlankCallback(VBlankCB0_Phase2_Transition_WhiteFade); - - task->tState++; - return FALSE; -} - -static bool8 Phase2_Transition_WhiteFade_Func2(struct Task* task) -{ - s16 i, posY; - s16 arr1[8]; - struct Sprite* sprite; - - memcpy(arr1, sUnknown_083FD8C4, sizeof(sUnknown_083FD8C4)); - for (i = 0, posY = 0; i < 8; i++, posY += 0x14) - { - sprite = &gSprites[CreateInvisibleSprite(sub_811CFD0)]; - sprite->pos1.x = 0xF0; - sprite->pos1.y = posY; - sprite->data[5] = arr1[i]; - } - sprite->data[6]++; - - task->tState++; - return FALSE; -} - -static bool8 Phase2_Transition_WhiteFade_Func3(struct Task* task) -{ - TRANSITION_STRUCT.VBlank_DMA = 0; - if (TRANSITION_STRUCT.field_20 > 7) - { - BlendPalettes(0xFFFFFFFF, 16, RGB(31, 31, 31)); - task->tState++; - } - return FALSE; -} - -static bool8 Phase2_Transition_WhiteFade_Func4(struct Task* task) -{ - TRANSITION_STRUCT.VBlank_DMA = 0; - - DmaStop(0); - SetVBlankCallback(0); - SetHBlankCallback(0); - - TRANSITION_STRUCT.field_6 = 0xF0; - TRANSITION_STRUCT.BLDY = 0; - TRANSITION_STRUCT.BLDCNT = 0xFF; - TRANSITION_STRUCT.WININ = 0x3F; - - SetVBlankCallback(VBlankCB1_Phase2_Transition_WhiteFade); - - task->tState++; - return FALSE; -} - -static bool8 Phase2_Transition_WhiteFade_Func5(struct Task* task) -{ - if (++TRANSITION_STRUCT.BLDY > 16) - { - sub_811D6D4(); - DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_WhiteFade)); - } - return FALSE; -} - -static void VBlankCB0_Phase2_Transition_WhiteFade(void) -{ - DmaStop(0); - VBlankCB_BattleTransition(); - REG_BLDCNT = TRANSITION_STRUCT.BLDCNT; - REG_WININ = TRANSITION_STRUCT.WININ; - REG_WINOUT = TRANSITION_STRUCT.WINOUT; - REG_WIN0V = TRANSITION_STRUCT.field_6; - if (TRANSITION_STRUCT.VBlank_DMA) - DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 640); - DmaSet(0, &gScanlineEffectRegBuffers[1][160], ®_WIN0H, 0xA2400001); -} - -static void VBlankCB1_Phase2_Transition_WhiteFade(void) -{ - VBlankCB_BattleTransition(); - REG_BLDY = TRANSITION_STRUCT.BLDY; - REG_BLDCNT = TRANSITION_STRUCT.BLDCNT; - REG_WININ = TRANSITION_STRUCT.WININ; - REG_WINOUT = TRANSITION_STRUCT.WINOUT; - REG_WIN0H = TRANSITION_STRUCT.field_6; - REG_WIN0V = TRANSITION_STRUCT.WIN0V; -} - -static void HBlankCB_Phase2_Transition_WhiteFade(void) -{ - REG_BLDY = gScanlineEffectRegBuffers[1][REG_VCOUNT]; -} - -static void sub_811CFD0(struct Sprite* sprite) -{ - if (sprite->data[5]) - { - sprite->data[5]--; - if (sprite->data[6]) - TRANSITION_STRUCT.VBlank_DMA = 1; - } - else - { - u16 i; - u16* ptr1 = &gScanlineEffectRegBuffers[0][sprite->pos1.y]; - u16* ptr2 = &gScanlineEffectRegBuffers[0][sprite->pos1.y + 160]; - for (i = 0; i < 20; i++) - { - ptr1[i] = sprite->data[0] >> 8; - ptr2[i] = (u8)(sprite->pos1.x); - } - if (sprite->pos1.x == 0 && sprite->data[0] == 0x1000) - sprite->data[1] = 1; - - sprite->pos1.x -= 16; - sprite->data[0] += 0x80; - - if (sprite->pos1.x < 0) - sprite->pos1.x = 0; - if (sprite->data[0] > 0x1000) - sprite->data[0] = 0x1000; - - if (sprite->data[6]) - TRANSITION_STRUCT.VBlank_DMA = 1; - - if (sprite->data[1]) - { - if (sprite->data[6] == 0 || (TRANSITION_STRUCT.field_20 > 6 && sprite->data[2]++ > 7)) - { - TRANSITION_STRUCT.field_20++; - DestroySprite(sprite); - } - } - } -} - -static void Phase2Task_Transition_GridSquares(u8 taskID) -{ - while (sPhase2_Transition_GridSquares_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Transition_GridSquares_Func1(struct Task* task) -{ - u16 *dst1, *dst2; - - sub_811D6A8(&dst1, &dst2); - CpuSet(sShrinkingBoxTileset, dst2, 0x10); - CpuFill16(0xF000, dst1, 0x800); - LoadPalette(gFieldEffectObjectPalette10, 0xF0, 0x20); - - task->tState++; - return FALSE; -} - -static bool8 Phase2_Transition_GridSquares_Func2(struct Task* task) -{ - u16* dst1; - - if (task->data[1] == 0) - { - sub_811D690(&dst1); - task->data[1] = 3; - task->data[2]++; - CpuSet(sShrinkingBoxTileset + (task->data[2] * 8), dst1, 0x10); - if (task->data[2] > 0xD) - { - task->tState++; - task->data[1] = 16; - } - } - - task->data[1]--; - return FALSE; -} - -static bool8 Phase2_Transition_GridSquares_Func3(struct Task* task) -{ - if (--task->data[1] == 0) - { - sub_811D6D4(); - DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_GridSquares)); - } - return FALSE; -} - -static void Phase2Task_Transition_Shards(u8 taskID) -{ - while (sPhase2_Transition_Shards_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase2_Transition_Shards_Func1(struct Task* task) -{ - u16 i; - - sub_811D658(); - ScanlineEffect_Clear(); - - TRANSITION_STRUCT.WININ = 0x3F; - TRANSITION_STRUCT.WINOUT = 0; - TRANSITION_STRUCT.WIN0V = 0xA0; - - for (i = 0; i < 160; i++) - { - gScanlineEffectRegBuffers[0][i] = 0xF0; - } - - CpuSet(gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 0xA0); - SetVBlankCallback(VBlankCB_Phase2_Transition_Shards); - - task->tState++; - return TRUE; -} - -static bool8 Phase2_Transition_Shards_Func2(struct Task* task) -{ - sub_811D8FC(TRANSITION_STRUCT.data, - sUnknown_083FD8F4[task->data[1]][0], - sUnknown_083FD8F4[task->data[1]][1], - sUnknown_083FD8F4[task->data[1]][2], - sUnknown_083FD8F4[task->data[1]][3], - 1, 1); - task->data[2] = sUnknown_083FD8F4[task->data[1]][4]; - task->tState++; - return TRUE; -} - -static bool8 Phase2_Transition_Shards_Func3(struct Task* task) -{ - s16 i; - bool8 nextFunc; - - TRANSITION_STRUCT.VBlank_DMA = 0; - - for (i = 0, nextFunc = FALSE; i < 16; i++) - { - s16 r3 = gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] >> 8; - s16 r4 = gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] & 0xFF; - if (task->data[2] == 0) - { - if (r3 < TRANSITION_STRUCT.data[2]) - r3 = TRANSITION_STRUCT.data[2]; - if (r3 > r4) - r3 = r4; - } - else - { - if (r4 > TRANSITION_STRUCT.data[2]) - r4 = TRANSITION_STRUCT.data[2]; - if (r4 <= r3) - r4 = r3; - } - gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (r4) | (r3 << 8); - if (nextFunc) - { - task->tState++; - break; - } - else - nextFunc = sub_811D978(TRANSITION_STRUCT.data, 1, 1); - } - - TRANSITION_STRUCT.VBlank_DMA++; - return FALSE; -} - -static bool8 Phase2_Transition_Shards_Func4(struct Task* task) -{ - if (++task->data[1] < 7) - { - task->tState++; - task->data[3] = sUnknown_083FD93A[task->data[1] - 1]; - return TRUE; - } - else - { - DmaStop(0); - sub_811D6D4(); - DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Shards)); - return FALSE; - } -} - -static bool8 Phase2_Transition_Shards_Func5(struct Task* task) -{ - if (--task->data[3] == 0) - { - task->tState = 1; - return TRUE; - } - else - return FALSE; -} - -static void VBlankCB_Phase2_Transition_Shards(void) -{ - DmaStop(0); - VBlankCB_BattleTransition(); - if (TRANSITION_STRUCT.VBlank_DMA) - DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); - REG_WININ = TRANSITION_STRUCT.WININ; - REG_WINOUT = TRANSITION_STRUCT.WINOUT; - REG_WIN0V = TRANSITION_STRUCT.WIN0V; - REG_WIN0H = gScanlineEffectRegBuffers[1][0]; - DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, 0xA2400001); -} - -static void CreatePhase1Task(s16 a0, s16 a1, s16 a2, s16 a3, s16 a4) -{ - u8 taskID = CreateTask(Phase1_Task_RunFuncs, 3); - gTasks[taskID].data[1] = a0; - gTasks[taskID].data[2] = a1; - gTasks[taskID].data[3] = a2; - gTasks[taskID].data[4] = a3; - gTasks[taskID].data[5] = a4; - gTasks[taskID].data[6] = a0; -} - -static bool8 sub_811D52C(void) -{ - if (FindTaskIdByFunc(Phase1_Task_RunFuncs) == 0xFF) - return TRUE; - else - return FALSE; -} - -static void Phase1_Task_RunFuncs(u8 taskID) -{ - while (sPhase1_TransitionAll_Funcs[gTasks[taskID].tState](&gTasks[taskID])); -} - -static bool8 Phase1_TransitionAll_Func1(struct Task* task) -{ - if (task->data[6] == 0 || --task->data[6] == 0) - { - task->data[6] = task->data[1]; - task->data[7] += task->data[4]; - if (task->data[7] > 16) - task->data[7] = 16; - BlendPalettes(0xFFFFFFFF, task->data[7], RGB(11, 11, 11)); - } - if (task->data[7] > 15) - { - task->tState++; - task->data[6] = task->data[2]; - } - return FALSE; -} - -static bool8 Phase1_TransitionAll_Func2(struct Task* task) -{ - if (task->data[6] == 0 || --task->data[6] == 0) - { - task->data[6] = task->data[2]; - task->data[7] -= task->data[5]; - if (task->data[7] < 0) - task->data[7] = 0; - BlendPalettes(0xFFFFFFFF, task->data[7], RGB(11, 11, 11)); - } - if (task->data[7] == 0) - { - if (--task->data[3] == 0) - DestroyTask(FindTaskIdByFunc(Phase1_Task_RunFuncs)); - else - { - task->data[6] = task->data[1]; - task->tState = 0; - } - } - return FALSE; -} - -static void sub_811D658(void) -{ - struct TransitionData* const* dummy = &sTransitionStructPtr; - memset(*dummy, 0, sizeof(struct TransitionData)); - sub_8057B14(&TRANSITION_STRUCT.field_14, &TRANSITION_STRUCT.field_16); -} - -static void VBlankCB_BattleTransition(void) -{ - LoadOam(); - ProcessSpriteCopyRequests(); - TransferPlttBuffer(); -} - -static void sub_811D690(u16** a0) -{ - u16 reg, *vram; - - reg = REG_BG0CNT >> 2; - reg <<= 0xE; - vram = (u16*)(VRAM + reg); - - *a0 = vram; -} - -static void sub_811D6A8(u16** a0, u16** a1) -{ - u16 reg0, reg1, *vram0, *vram1; - - reg0 = REG_BG0CNT >> 8; - reg1 = REG_BG0CNT >> 2; - - reg0 <<= 0xB; - reg1 <<= 0xE; - - vram0 = (u16*)(VRAM + reg0); - *a0 = vram0; - - vram1 = (u16*)(VRAM + reg1); - *a1 = vram1; -} - -static void sub_811D6D4(void) -{ - BlendPalettes(0xFFFFFFFF, 16, RGB(0, 0, 0)); -} - -static void sub_811D6E8(s16* array, s16 sinAdd, s16 index, s16 indexIncrementer, s16 amplitude, s16 arrSize) -{ - u8 i; - for (i = 0; arrSize > 0; arrSize--, i++, index += indexIncrementer) - { - array[i] = sinAdd + Sin(0xFF & index, amplitude); - } -} - -static void sub_811D764(u16* array, s16 a1, s16 a2, s16 a3) -{ - s16 i; - - memset(array, 0xA, 160 * sizeof(s16)); - for (i = 0; i < 64; i++) - { - s16 sinResult, cosResult; - s16 toStoreOrr, r2, r3, toStore, r7, r8; - - sinResult = Sin(i, a3); - cosResult = Cos(i, a3); - - toStoreOrr = a1 - sinResult; - toStore = a1 + sinResult; - r7 = a2 - cosResult; - r8 = a2 + cosResult; - - if (toStoreOrr < 0) - toStoreOrr = 0; - if (toStore > 0xF0) - toStore = 0xF0; - if (r7 < 0) - r7 = 0; - if (r8 > 0x9F) - r8 = 0x9F; - - toStore |= (toStoreOrr << 8); - array[r7] = toStore; - array[r8] = toStore; - - cosResult = Cos(i + 1, a3); - r3 = a2 - cosResult; - r2 = a2 + cosResult; - - if (r3 < 0) - r3 = 0; - if (r2 > 0x9F) - r2 = 0x9F; - - while (r7 > r3) - array[--r7] = toStore; - while (r7 < r3) - array[++r7] = toStore; - - while (r8 > r2) - array[--r8] = toStore; - while (r8 < r2) - array[++r8] = toStore; - } -} - -static void sub_811D8FC(s16* data, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6) -{ - data[0] = a1; - data[1] = a2; - data[2] = a1; - data[3] = a2; - data[4] = a3; - data[5] = a4; - data[6] = a5; - data[7] = a6; - data[8] = a3 - a1; - if (data[8] < 0) - { - data[8] = -data[8]; - data[6] = -a5; - } - data[9] = a4 - a2; - if (data[9] < 0) - { - data[9] = -data[9]; - data[7] = -a6; - } - data[10] = 0; -} - -static bool8 sub_811D978(s16* data, bool8 a1, bool8 a2) -{ - u8 var; - if (data[8] > data[9]) - { - data[2] += data[6]; - data[10] += data[9]; - if (data[10] > data[8]) - { - data[3] += data[7]; - data[10] -= data[8]; - } - } - else - { - data[3] += data[7]; - data[10] += data[8]; - if (data[10] > data[9]) - { - data[2] += data[6]; - data[10] -= data[9]; - } - } - var = 0; - if ((data[6] > 0 && data[2] >= data[4]) || (data[6] < 0 && data[2] <= data[4])) - { - var++; - if (a1) - data[2] = data[4]; - } - if ((data[7] > 0 && data[3] >= data[5]) || (data[7] < 0 && data[3] <= data[5])) - { - var++; - if (a2) - data[3] = data[5]; - } - if (var == 2) - return TRUE; - else - return FALSE; -} diff --git a/src/battle/battle_util.c b/src/battle/battle_util.c deleted file mode 100644 index 3d1770239..000000000 --- a/src/battle/battle_util.c +++ /dev/null @@ -1,3549 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_util.h" -#include "data2.h" -#include "event_data.h" -#include "ewram.h" -#include "field_weather.h" -#include "item.h" -#include "link.h" -#include "pokemon.h" -#include "random.h" -#include "rom_8077ABC.h" -#include "string_util.h" -#include "text.h" -#include "util.h" -#include "constants/abilities.h" -#include "constants/battle_move_effects.h" -#include "constants/flags.h" -#include "constants/hold_effects.h" -#include "constants/items.h" -#include "constants/moves.h" -#include "constants/species.h" -#include "constants/weather.h" - -extern u8 gUnknown_02023A14_50; - -extern const u8* gBattlescriptCurrInstr; -extern u8 gActiveBattler; -extern u8 gBattleBufferB[4][0x200]; -extern u8* gSelectionBattleScripts[4]; //battlescript location when you try to choose a move you're not allowed to -extern u16 gLastUsedMove[4]; -extern struct BattlePokemon gBattleMons[4]; -extern struct BattleEnigmaBerry gEnigmaBerries[4]; -extern u8 gStringBank; -extern u16 gLastUsedItem; -extern u16 gCurrentMove; -extern const u32 gBitTable[]; -extern u16 gBattleTypeFlags; -extern u8 gBattlersCount; -extern u32 gStatuses3[4]; -extern u8 gBankAttacker; -extern u8 gBankTarget; -extern u8 gBanksByTurnOrder[4]; -extern u16 gSideAffecting[2]; -extern u16 gBattleWeather; -extern void (*gBattleMainFunc)(void); -extern u8 gAbsentBattlerFlags; -extern u8 gBattleCommunication[]; -extern u32 gHitMarker; -extern u8 gEffectBank; -extern u8 gBank1; -extern s32 gBattleMoveDamage; -extern u16 gBattlerPartyIndexes[4]; -extern u16 gChosenMovesByBanks[4]; -extern s32 gTakenDmg[4]; -extern u8 gTakenDmgBanks[4]; -extern u8 gMoveResultFlags; -extern u8 gLastUsedAbility; -extern u8 gBattleTextBuff2[]; -extern u8 gCurrentActionFuncId; -extern struct BattleEnigmaBerry gEnigmaBerries[4]; -extern u8 gUnknown_02024BE5; -extern u8 gCurrMovePos; -extern u16 gRandomMove; -extern s32 gBattleMoveDamage; -extern u16 gDynamicBasePower; -extern u32 gBattleExecBuffer; -extern u8 gSentPokesToOpponent[2]; -extern const u16 gSoundMovesTable[]; -extern const u8 gStatusConditionString_PoisonJpn[]; -extern const u8 gStatusConditionString_SleepJpn[]; -extern const u8 gStatusConditionString_ParalysisJpn[]; -extern const u8 gStatusConditionString_BurnJpn[]; -extern const u8 gStatusConditionString_IceJpn[]; -extern const u8 gStatusConditionString_ConfusionJpn[]; -extern const u8 gStatusConditionString_LoveJpn[]; -extern const BattleCmdFunc gBattleScriptingCommandsTable[]; - -u8 IsImprisoned(u8 bank, u16 move); -u8 GetBattlerAtPosition(u8 ID); -u8 GetBattlerPosition(u8 bank); -u8 GetBattlerSide(u8 bank); -void SetMoveEffect(bool8 primary, u8 certainArg); -bool8 UproarWakeUpCheck(u8 bank); -bool8 sub_8018018(u8 bank, u8, u8); -s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 a4, u16 powerOverride, u8 typeOverride, u8 bank_atk, u8 bank_def); -u8 CountTrailingZeroBits(u32 a); -u8 GetMoveTarget(u16 move, u8 useMoveTarget); -u8 sub_803FC34(u8 bank); -u16 sub_803FBFC(u8 a); -void RecordAbilityBattle(u8 bank, u8 ability); -void RecordItemBattle(u8 bank, u8 holdEffect); -s8 GetPokeFlavourRelation(u32 pid, u8 flavor); - -extern u8 BattleScript_MoveSelectionDisabledMove[]; -extern u8 BattleScript_MoveSelectionTormented[]; -extern u8 BattleScript_MoveSelectionTaunted[]; -extern u8 BattleScript_MoveSelectionImprisoned[]; -extern u8 BattleScript_MoveSelectionChoiceBanded[]; -extern u8 BattleScript_MoveSelectionNoPP[]; -extern u8 BattleScript_NoMovesLeft[]; -extern u8 BattleScript_WishComesTrue[]; -extern u8 BattleScript_IngrainTurnHeal[]; -extern u8 BattleScript_LeechSeedTurnDrain[]; -extern u8 BattleScript_PoisonTurnDmg[]; -extern u8 BattleScript_BurnTurnDmg[]; -extern u8 BattleScript_NightmareTurnDmg[]; -extern u8 BattleScript_CurseTurnDmg[]; -extern u8 BattleScript_WrapTurnDmg[]; -extern u8 BattleScript_WrapEnds[]; -extern u8 BattleScript_DisabledNoMore[]; -extern u8 BattleScript_EncoredNoMore[]; - -extern u8 BattleScript_SideStatusWoreOff[]; -extern u8 BattleScript_RainContinuesOrEnds[]; -extern u8 BattleScript_SandStormHailEnds[]; -extern u8 BattleScript_DamagingWeatherContinues[]; -extern u8 BattleScript_SunlightFaded[]; -extern u8 BattleScript_SunlightContinues[]; -extern u8 BattleScript_SafeguardEnds[]; -extern u8 BattleScript_MonWokeUpInUproar[]; //uproar wakeup BS -extern u8 BattleScript_PrintUproarOverTurns[]; //uproar BS -extern u8 BattleScript_ThrashConfuses[]; -extern u8 BattleScript_YawnMakesAsleep[]; -extern u8 BattleScript_MonTookFutureAttack[]; -extern u8 BattleScript_PerishSongHits[]; -extern u8 BattleScript_PerishSongTimerGoesDown[]; -extern u8 BattleScript_GiveExp[]; -extern u8 BattleScript_HandleFaintedMon[]; - -extern u8 BattleScript_MoveUsedIsAsleep[]; -extern u8 BattleScript_MoveUsedWokeUp[]; -extern u8 BattleScript_MoveUsedIsFrozen[]; -extern u8 BattleScript_MoveUsedUnfroze[]; -extern u8 BattleScript_MoveUsedLoafingAround[]; -extern u8 BattleScript_MoveUsedMustRecharge[]; -extern u8 BattleScript_MoveUsedFlinched[]; -extern u8 BattleScript_MoveUsedIsDisabled[]; -extern u8 BattleScript_MoveUsedIsTaunted[]; -extern u8 BattleScript_MoveUsedIsImprisoned[]; -extern u8 BattleScript_MoveUsedIsConfused[]; -extern u8 BattleScript_MoveUsedIsConfusedNoMore[]; -extern u8 BattleScript_MoveUsedIsParalyzed[]; -extern u8 BattleScript_MoveUsedIsParalyzedCantAttack[]; -extern u8 BattleScript_MoveUsedIsInLove[]; -extern u8 BattleScript_BideStoringEnergy[]; -extern u8 BattleScript_BideAttack[]; -extern u8 BattleScript_BideNoEnergyToAttack[]; - -extern u8 BattleScript_OverworldWeatherStarts[]; //load weather from overworld -extern u8 BattleScript_DrizzleActivates[]; -extern u8 BattleScript_SandstreamActivates[]; -extern u8 BattleScript_DroughtActivates[]; -extern u8 BattleScript_CastformChange[]; -extern u8 BattleScript_RainDishActivates[]; -extern u8 BattleScript_ShedSkinActivates[]; -extern u8 BattleScript_SpeedBoostActivates[]; -extern u8 BattleScript_SoundproofProtected[]; -extern u8 BattleScript_MoveHPDrain[]; -extern u8 BattleScript_MoveHPDrain_PPLoss[]; -extern u8 BattleScript_FlashFireBoost[]; -extern u8 BattleScript_FlashFireBoost_PPLoss[]; -extern u8 BattleScript_MoveHPDrain_FullHP[]; -extern u8 BattleScript_MoveHPDrain_FullHP_PPLoss[]; -extern u8 BattleScript_ColorChangeActivates[]; -extern u8 BattleScript_RoughSkinActivates[]; -extern u8 BattleScript_ApplySecondaryEffect[]; -extern u8 BattleScript_CuteCharmActivates[]; -extern u8 BattleScript_AbilityCuredStatus[]; //ability status clear -extern u8 BattleScript_SynchronizeActivates[]; -extern u8 gUnknown_081D978C[]; //intimidate1 -extern u8 gUnknown_081D9795[]; //intimidate2 -extern u8 BattleScript_TraceActivates[]; - -extern u8 BattleScript_WhiteHerbEnd2[]; -extern u8 BattleScript_WhiteHerbRet[]; -extern u8 BattleScript_ItemHealHP_RemoveItem[]; -extern u8 BattleScript_BerryPPHealEnd2[]; -extern u8 BattleScript_ItemHealHP_End2[]; -extern u8 BattleScript_BerryConfuseHealEnd2[]; -extern u8 BattleScript_BerryStatRaiseEnd2[]; -extern u8 BattleScript_BerryFocusEnergyEnd2[]; -extern u8 BattleScript_BerryCurePrlzEnd2[]; -extern u8 BattleScript_BerryCurePsnEnd2[]; -extern u8 BattleScript_BerryCureBrnEnd2[]; -extern u8 BattleScript_BerryCureFrzEnd2[]; -extern u8 BattleScript_BerryCureSlpEnd2[]; -extern u8 BattleScript_BerryCureConfusionEnd2[]; -extern u8 BattleScript_BerryCureChosenStatusEnd2[]; //berry cure any status end2 -extern u8 BattleScript_BerryCureParRet[]; -extern u8 BattleScript_BerryCurePsnRet[]; -extern u8 BattleScript_BerryCureBrnRet[]; -extern u8 BattleScript_BerryCureFrzRet[]; -extern u8 BattleScript_BerryCureSlpRet[]; -extern u8 BattleScript_BerryCureConfusionRet[]; -extern u8 BattleScript_BerryCureChosenStatusRet[]; //berry cure any status return - -extern u8 BattleScript_ItemHealHP_Ret[]; - -extern u8 gUnknown_081D995F[]; //disobedient while asleep -extern u8 BattleScript_IgnoresAndUsesRandomMove[]; //disobedient, uses a random move -extern u8 BattleScript_IgnoresAndFallsAsleep[]; //disobedient, went to sleep -extern u8 gUnknown_081D99A0[]; //disobedient, hits itself - -//array entries for battle communication -#define MOVE_EFFECT_BYTE 0x3 -#define MULTISTRING_CHOOSER 0x5 -#define MSG_DISPLAY 0x7 - -u8 GetBattleBank(u8 caseId) -{ - u8 ret = 0; - switch (caseId) - { - case BS_GET_TARGET: - ret = gBankTarget; - break; - case BS_GET_ATTACKER: - ret = gBankAttacker; - break; - case BS_GET_EFFECT_BANK: - ret = gEffectBank; - break; - case BS_GET_BANK_0: - ret = 0; - break; - case BS_GET_SCRIPTING_BANK: - ret = ewram16003; - break; - case BS_GET_gBank1: - ret = gBank1; - break; - case 5: - ret = gBank1; - break; - } - return ret; -} - -void PressurePPLose(u8 bankDef, u8 bankAtk, u16 move) -{ - s32 i; - - if (gBattleMons[bankDef].ability != ABILITY_PRESSURE) - return; - - for (i = 0; i < 4; i++) - { - if (gBattleMons[bankAtk].moves[i] == move) - break; - } - - if (i == 4) // mons don't share any moves - return; - - if (gBattleMons[bankAtk].pp[i] != 0) - gBattleMons[bankAtk].pp[i]--; - - if (!(gBattleMons[bankAtk].status2 & STATUS2_TRANSFORMED) - && !(gDisableStructs[bankAtk].unk18_b & gBitTable[i])) - { - gActiveBattler = bankAtk; - EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + i, 0, 1, &gBattleMons[gActiveBattler].pp[i]); - MarkBufferBankForExecution(gActiveBattler); - } -} - -void PressurePPLoseOnUsingImprision(u8 bankAtk) -{ - s32 i, j; - s32 imprisionPos = 4; - u8 atkSide = GetBattlerSide(bankAtk); - - for (i = 0; i < gBattlersCount; i++) - { - if (atkSide != GetBattlerSide(i) && gBattleMons[i].ability == ABILITY_PRESSURE) - { - for (j = 0; j < 4; j++) - { - if (gBattleMons[bankAtk].moves[j] == MOVE_IMPRISON) - break; - } - if (j != 4) - { - imprisionPos = j; - if (gBattleMons[bankAtk].pp[j] != 0) - gBattleMons[bankAtk].pp[j]--; - } - } - } - - if (imprisionPos != 4 - && !(gBattleMons[bankAtk].status2 & STATUS2_TRANSFORMED) - && !(gDisableStructs[bankAtk].unk18_b & gBitTable[imprisionPos])) - { - gActiveBattler = bankAtk; - EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + imprisionPos, 0, 1, &gBattleMons[gActiveBattler].pp[imprisionPos]); - MarkBufferBankForExecution(gActiveBattler); - } -} - -void PressurePPLoseOnUsingPerishSong(u8 bankAtk) -{ - s32 i, j; - s32 perishSongPos = 4; - - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleMons[i].ability == ABILITY_PRESSURE && i != bankAtk) - { - for (j = 0; j < 4; j++) - { - if (gBattleMons[bankAtk].moves[j] == MOVE_PERISH_SONG) - break; - } - if (j != 4) - { - perishSongPos = j; - if (gBattleMons[bankAtk].pp[j] != 0) - gBattleMons[bankAtk].pp[j]--; - } - } - } - - if (perishSongPos != 4 - && !(gBattleMons[bankAtk].status2 & STATUS2_TRANSFORMED) - && !(gDisableStructs[bankAtk].unk18_b & gBitTable[perishSongPos])) - { - gActiveBattler = bankAtk; - EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + perishSongPos, 0, 1, &gBattleMons[gActiveBattler].pp[perishSongPos]); - MarkBufferBankForExecution(gActiveBattler); - } -} - - -void MarkAllBufferBanksForExecution(void) // unused -{ - s32 i; - - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - for (i = 0; i < gBattlersCount; i++) - gBattleExecBuffer |= gBitTable[i] << 0x1C; - } - else - { - for (i = 0; i < gBattlersCount; i++) - gBattleExecBuffer |= gBitTable[i]; - } -} - -void MarkBufferBankForExecution(u8 bank) -{ - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - gBattleExecBuffer |= gBitTable[bank] << 0x1C; - } - else - { - gBattleExecBuffer |= gBitTable[bank]; - } -} - -void sub_80155A4(u8 arg0) -{ - s32 i; - - for (i = 0; i < GetLinkPlayerCount(); i++) - gBattleExecBuffer |= gBitTable[arg0] << (i << 2); - - gBattleExecBuffer &= ~(0x10000000 << arg0); -} - -void CancelMultiTurnMoves(u8 bank) -{ - gBattleMons[bank].status2 &= ~(STATUS2_MULTIPLETURNS); - gBattleMons[bank].status2 &= ~(STATUS2_LOCK_CONFUSE); - gBattleMons[bank].status2 &= ~(STATUS2_UPROAR); - gBattleMons[bank].status2 &= ~(STATUS2_BIDE); - - gStatuses3[bank] &= ~(STATUS3_SEMI_INVULNERABLE); - - gDisableStructs[bank].rolloutTimer1 = 0; - gDisableStructs[bank].furyCutterCounter = 0; -} - -bool8 WasUnableToUseMove(u8 bank) -{ - if (gProtectStructs[bank].prlzImmobility - || gProtectStructs[bank].notEffective - || gProtectStructs[bank].usedImprisionedMove - || gProtectStructs[bank].loveImmobility - || gProtectStructs[bank].usedDisabledMove - || gProtectStructs[bank].usedTauntedMove - || gProtectStructs[bank].flag2Unknown - || gProtectStructs[bank].flinchImmobility - || gProtectStructs[bank].confusionSelfDmg) - return TRUE; - else - return FALSE; -} - -void PrepareStringBattle(u16 stringId, u8 bank) -{ - gActiveBattler = bank; - EmitPrintString(0, stringId); - MarkBufferBankForExecution(gActiveBattler); -} - -void ResetSentPokesToOpponentValue(void) -{ - s32 i; - u32 bits = 0; - - gSentPokesToOpponent[0] = 0; - gSentPokesToOpponent[1] = 0; - - for (i = 0; i < gBattlersCount; i += 2) - bits |= gBitTable[gBattlerPartyIndexes[i]]; - - for (i = 1; i < gBattlersCount; i += 2) - gSentPokesToOpponent[(i & BIT_FLANK) >> 1] = bits; -} - -void sub_8015740(u8 bank) -{ - s32 i = 0; - u32 bits = 0; - - if (GetBattlerSide(bank) == B_SIDE_OPPONENT) - { - u8 id = ((bank & BIT_FLANK) >> 1); - gSentPokesToOpponent[id] = 0; - - for (i = 0; i < gBattlersCount; i += 2) - { - if (!(gAbsentBattlerFlags & gBitTable[i])) - bits |= gBitTable[gBattlerPartyIndexes[i]]; - } - - gSentPokesToOpponent[id] = bits; - } -} - -void sub_80157C4(u8 bank) -{ - if (GetBattlerSide(bank) == B_SIDE_OPPONENT) - { - sub_8015740(bank); - } - else - { - s32 i; - for (i = 1; i < gBattlersCount; i++) - gSentPokesToOpponent[(i & BIT_FLANK) >> 1] |= gBitTable[gBattlerPartyIndexes[bank]]; - } -} - -void BattleScriptPush(const u8* BS_ptr) -{ - B_BATTLESCRIPTS_STACK->ptr[B_BATTLESCRIPTS_STACK->size++] = BS_ptr; -} - -void BattleScriptPushCursor(void) -{ - B_BATTLESCRIPTS_STACK->ptr[B_BATTLESCRIPTS_STACK->size++] = gBattlescriptCurrInstr; -} - -void BattleScriptPop(void) -{ - gBattlescriptCurrInstr = B_BATTLESCRIPTS_STACK->ptr[--B_BATTLESCRIPTS_STACK->size]; -} - -u8 TrySetCantSelectMoveBattleScript(void) //msg can't select a move -{ - u8 limitations = 0; - u16 move = gBattleMons[gActiveBattler].moves[gBattleBufferB[gActiveBattler][2]]; - u8 holdEffect; - u16* choicedMove = CHOICED_MOVE(gActiveBattler); - if (gDisableStructs[gActiveBattler].disabledMove == move && move) - { - gBattleStruct->scriptingActive = gActiveBattler; - gCurrentMove = move; - gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionDisabledMove; - limitations++; - } - if (move == gLastUsedMove[gActiveBattler] && move != MOVE_STRUGGLE && gBattleMons[gActiveBattler].status2 & STATUS2_TORMENT) - { - CancelMultiTurnMoves(gActiveBattler); - gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionTormented; - limitations++; - } - if (gDisableStructs[gActiveBattler].tauntTimer1 && gBattleMoves[move].power == 0) - { - gCurrentMove = move; - gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionTaunted; - limitations++; - } - if (IsImprisoned(gActiveBattler, move)) - { - gCurrentMove = move; - gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionImprisoned; - limitations++; - } - if (gBattleMons[gActiveBattler].item == ITEM_ENIGMA_BERRY) - holdEffect = gEnigmaBerries[gActiveBattler].holdEffect; - else - holdEffect = ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item); - gStringBank = gActiveBattler; - if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != move) - { - gCurrentMove = *choicedMove; - gLastUsedItem = gBattleMons[gActiveBattler].item; - gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionChoiceBanded; - limitations++; - } - if (gBattleMons[gActiveBattler].pp[gBattleBufferB[gActiveBattler][2]] == 0) - { - gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionNoPP; - limitations++; - } - return limitations; -} - -#define MOVE_LIMITATION_ZEROMOVE (1 << 0) -#define MOVE_LIMITATION_PP (1 << 1) -#define MOVE_LIMITATION_DISABLED (1 << 2) -#define MOVE_LIMITATION_TORMENTED (1 << 3) -#define MOVE_LIMITATION_TAUNT (1 << 4) -#define MOVE_LIMITATION_IMPRISION (1 << 5) - -u8 CheckMoveLimitations(u8 bank, u8 unusableMoves, u8 check) -{ - u8 holdEffect; - u16* choicedMove = CHOICED_MOVE(bank); - s32 i; - if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY) - holdEffect = gEnigmaBerries[bank].holdEffect; - else - holdEffect = ItemId_GetHoldEffect(gBattleMons[bank].item); - gStringBank = bank; - for (i = 0; i < 4; i++) - { - if (gBattleMons[bank].moves[i] == 0 && check & MOVE_LIMITATION_ZEROMOVE) - unusableMoves |= gBitTable[i]; - if (gBattleMons[bank].pp[i] == 0 && check & MOVE_LIMITATION_PP) - unusableMoves |= gBitTable[i]; - if (gBattleMons[bank].moves[i] == gDisableStructs[bank].disabledMove && check & MOVE_LIMITATION_DISABLED) - unusableMoves |= gBitTable[i]; - if (gBattleMons[bank].moves[i] == gLastUsedMove[bank] && check & MOVE_LIMITATION_TORMENTED && gBattleMons[bank].status2 & STATUS2_TORMENT) - unusableMoves |= gBitTable[i]; - if (gDisableStructs[bank].tauntTimer1 && check & MOVE_LIMITATION_TAUNT && gBattleMoves[gBattleMons[bank].moves[i]].power == 0) - unusableMoves |= gBitTable[i]; - if (IsImprisoned(bank, gBattleMons[bank].moves[i]) && check & MOVE_LIMITATION_IMPRISION) - unusableMoves |= gBitTable[i]; - if (gDisableStructs[bank].encoreTimer1 && gDisableStructs[bank].encoredMove != gBattleMons[bank].moves[i]) - unusableMoves |= gBitTable[i]; - if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[bank].moves[i]) - unusableMoves |= gBitTable[i]; - } - return unusableMoves; -} - -bool8 AreAllMovesUnusable(void) -{ - u8 unusable; - unusable = CheckMoveLimitations(gActiveBattler, 0, 0xFF); - if (unusable == 0xF) //all moves are unusable - { - gProtectStructs[gActiveBattler].onlyStruggle = 1; - gSelectionBattleScripts[gActiveBattler] = BattleScript_NoMovesLeft; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - gBattleBufferB[gActiveBattler][3] = GetBattlerAtPosition((GetBattlerPosition(gActiveBattler) ^ 1) | (Random() & 2)); - else - gBattleBufferB[gActiveBattler][3] = GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ 1); - } - else - gProtectStructs[gActiveBattler].onlyStruggle = 0; - return (unusable == 0xF); -} - -u8 IsImprisoned(u8 bank, u16 move) -{ - u8 imprisionedMoves = 0; - u8 bankSide = GetBattlerSide(bank); - s32 i; - for (i = 0; i < gBattlersCount; i++) - { - if (bankSide != GetBattlerSide(i) && gStatuses3[i] & STATUS3_IMPRISIONED) - { - s32 j; - for (j = 0; j < 4; j++) - { - if (move == gBattleMons[i].moves[j]) - break; - } - if (j < 4) - imprisionedMoves++; - } - } - return imprisionedMoves; -} - -u8 UpdateTurnCounters(void) -{ - u8 effect = 0; - s32 i; - - for (gBankAttacker = 0; gBankAttacker < gBattlersCount && gAbsentBattlerFlags & gBitTable[gBankAttacker]; gBankAttacker++) - { - } - for (gBankTarget = 0; gBankTarget < gBattlersCount && gAbsentBattlerFlags & gBitTable[gBankTarget]; gBankTarget++) - { - } - - do - { - u8 sideBank; - - switch (gBattleStruct->turncountersTracker) - { - case 0: - for (i = 0; i < gBattlersCount; i++) - { - gBanksByTurnOrder[i] = i; - } - for (i = 0; i < gBattlersCount - 1; i++) - { - s32 j; - for (j = i + 1; j < gBattlersCount; j++) - { - if (GetWhoStrikesFirst(gBanksByTurnOrder[i], gBanksByTurnOrder[j], 0)) - SwapTurnOrder(i, j); - } - } - gBattleStruct->turncountersTracker++; - gBattleStruct->turnSideTracker = 0; - case 1: - while (gBattleStruct->turnSideTracker < 2) - { - gActiveBattler = gBankAttacker = sideBank = gBattleStruct->turnSideTracker; - - if (gSideAffecting[sideBank] & SIDE_STATUS_REFLECT) - { - if (--gSideTimers[sideBank].reflectTimer == 0) - { - - gSideAffecting[sideBank] &= ~SIDE_STATUS_REFLECT; - BattleScriptExecute(BattleScript_SideStatusWoreOff); - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = MOVE_REFLECT; - gBattleTextBuff1[3] = MOVE_REFLECT >> 8; - gBattleTextBuff1[4] = EOS; - effect++; - } - } - gBattleStruct->turnSideTracker++; - if (effect) - break; - } - if (!effect) - { - gBattleStruct->turncountersTracker++; - gBattleStruct->turnSideTracker = 0; - } - break; - case 2: - while (gBattleStruct->turnSideTracker < 2) - { - gActiveBattler = gBankAttacker = sideBank = gBattleStruct->turnSideTracker; - if (gSideAffecting[sideBank] & SIDE_STATUS_LIGHTSCREEN) - { - if (--gSideTimers[sideBank].lightscreenTimer == 0) - { - gSideAffecting[sideBank] &= ~SIDE_STATUS_LIGHTSCREEN; - BattleScriptExecute(BattleScript_SideStatusWoreOff); - gBattleCommunication[MULTISTRING_CHOOSER] = sideBank; - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = MOVE_LIGHT_SCREEN; - gBattleTextBuff1[3] = MOVE_LIGHT_SCREEN >> 8; - gBattleTextBuff1[4] = EOS; - effect++; - } - } - gBattleStruct->turnSideTracker++; - if (effect) - break; - } - if (!effect) - { - gBattleStruct->turncountersTracker++; - gBattleStruct->turnSideTracker = 0; - } - break; - case 3: - while (gBattleStruct->turnSideTracker < 2) - { - gActiveBattler = gBankAttacker = sideBank = gBattleStruct->turnSideTracker; - if (gSideTimers[sideBank].mistTimer && --gSideTimers[sideBank].mistTimer == 0) - { - gSideAffecting[sideBank] &= ~SIDE_STATUS_MIST; - BattleScriptExecute(BattleScript_SideStatusWoreOff); - gBattleCommunication[MULTISTRING_CHOOSER] = sideBank; - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = MOVE_MIST; - gBattleTextBuff1[3] = MOVE_MIST >> 8; - gBattleTextBuff1[4] = EOS; - effect++; - } - gBattleStruct->turnSideTracker++; - if (effect) - break; - } - if (!effect) - { - gBattleStruct->turncountersTracker++; - gBattleStruct->turnSideTracker = 0; - } - break; - case 4: - while (gBattleStruct->turnSideTracker < 2) - { - gActiveBattler = gBankAttacker = sideBank = gBattleStruct->turnSideTracker; - if (gSideAffecting[sideBank] & SIDE_STATUS_SAFEGUARD) - { - if (--gSideTimers[sideBank].safeguardTimer == 0) - { - gSideAffecting[sideBank] &= ~SIDE_STATUS_SAFEGUARD; - BattleScriptExecute(BattleScript_SafeguardEnds); - effect++; - } - } - gBattleStruct->turnSideTracker++; - if (effect) - break; - } - if (!effect) - { - gBattleStruct->turncountersTracker++; - gBattleStruct->turnSideTracker = 0; - } - break; - case 5: - while (gBattleStruct->turnSideTracker < gBattlersCount) - { - gActiveBattler = gBanksByTurnOrder[gBattleStruct->turnSideTracker]; - if (gWishFutureKnock.wishCounter[gActiveBattler] && --gWishFutureKnock.wishCounter[gActiveBattler] == 0 && gBattleMons[gActiveBattler].hp) - { - gBankTarget = gActiveBattler; - BattleScriptExecute(BattleScript_WishComesTrue); - effect++; - } - gBattleStruct->turnSideTracker++; - if (effect) - break; - } - if (!effect) - { - gBattleStruct->turncountersTracker++; - } - break; - case 6: - if (gBattleWeather & WEATHER_RAIN_ANY) - { - if (!(gBattleWeather & WEATHER_RAIN_PERMANENT)) - { - if (--gWishFutureKnock.weatherDuration == 0) - { - gBattleWeather &= ~WEATHER_RAIN_TEMPORARY; - gBattleWeather &= ~WEATHER_RAIN_DOWNPOUR; - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - } - else if (gBattleWeather & WEATHER_RAIN_DOWNPOUR) - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - else if (gBattleWeather & WEATHER_RAIN_DOWNPOUR) - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - BattleScriptExecute(BattleScript_RainContinuesOrEnds); - effect++; - } - gBattleStruct->turncountersTracker++; - break; - case 7: - if (gBattleWeather & WEATHER_SANDSTORM_ANY) - { - if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT) && --gWishFutureKnock.weatherDuration == 0) - { - gBattleWeather &= ~WEATHER_SANDSTORM_TEMPORARY; - gBattlescriptCurrInstr = BattleScript_SandStormHailEnds; - } - else - gBattlescriptCurrInstr = BattleScript_DamagingWeatherContinues; - - gBattleStruct->animArg1 = B_ANIM_SANDSTORM_CONTINUES; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - BattleScriptExecute(gBattlescriptCurrInstr); - effect++; - } - gBattleStruct->turncountersTracker++; - break; - case 8: - if (gBattleWeather & WEATHER_SUN_ANY) - { - if (!(gBattleWeather & WEATHER_SUN_PERMANENT) && --gWishFutureKnock.weatherDuration == 0) - { - gBattleWeather &= ~WEATHER_SUN_TEMPORARY; - gBattlescriptCurrInstr = BattleScript_SunlightFaded; - } - else - gBattlescriptCurrInstr = BattleScript_SunlightContinues; - - BattleScriptExecute(gBattlescriptCurrInstr); - effect++; - } - gBattleStruct->turncountersTracker++; - break; - case 9: - if (gBattleWeather & WEATHER_HAIL) - { - if (--gWishFutureKnock.weatherDuration == 0) - { - gBattleWeather &= ~WEATHER_HAIL; - gBattlescriptCurrInstr = BattleScript_SandStormHailEnds; - } - else - gBattlescriptCurrInstr = BattleScript_DamagingWeatherContinues; - - gBattleStruct->animArg1 = B_ANIM_HAIL_CONTINUES; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - BattleScriptExecute(gBattlescriptCurrInstr); - effect++; - } - gBattleStruct->turncountersTracker++; - break; - case 10: - effect++; - break; - } - } while (effect == 0); - return (gBattleMainFunc != BattleTurnPassed); -} - -#define TURNBASED_MAX_CASE 19 - -u8 TurnBasedEffects(void) -{ - u8 effect = 0; - - gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20); - while (gBattleStruct->turnEffectsBank < gBattlersCount && gBattleStruct->turnEffectsTracker <= TURNBASED_MAX_CASE) - { - gActiveBattler = gBankAttacker = gBanksByTurnOrder[gBattleStruct->turnEffectsBank]; - if (gAbsentBattlerFlags & gBitTable[gActiveBattler]) - { - gBattleStruct->turnEffectsBank++; - } - else - { - switch (gBattleStruct->turnEffectsTracker) - { - case 0: // ingrain - if ((gStatuses3[gActiveBattler] & STATUS3_ROOTED) - && gBattleMons[gActiveBattler].hp != gBattleMons[gActiveBattler].maxHP - && gBattleMons[gActiveBattler].hp != 0) - { - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - BattleScriptExecute(BattleScript_IngrainTurnHeal); - effect++; - } - gBattleStruct->turnEffectsTracker++; - break; - case 1: // end turn abilities - if (AbilityBattleEffects(ABILITYEFFECT_ENDTURN, gActiveBattler, 0, 0, 0)) - effect++; - gBattleStruct->turnEffectsTracker++; - break; - case 2: // item effects - if (ItemBattleEffects(1, gActiveBattler, 0)) - effect++; - gBattleStruct->turnEffectsTracker++; - break; - case 18: // item effects again - if (ItemBattleEffects(1, gActiveBattler, 1)) - effect++; - gBattleStruct->turnEffectsTracker++; - break; - case 3: // leech seed - if (gStatuses3[gActiveBattler] & STATUS3_LEECHSEED && gBattleMons[gStatuses3[gActiveBattler] & STATUS3_LEECHSEED_BANK].hp != 0 && gBattleMons[gActiveBattler].hp != 0) - { - gBankTarget = gStatuses3[gActiveBattler] & STATUS3_LEECHSEED_BANK; //funny how the 'target' is actually the bank that receives HP - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleStruct->animArg1 = gBankTarget; - gBattleStruct->animArg2 = gBankAttacker; - BattleScriptExecute(BattleScript_LeechSeedTurnDrain); - effect++; - } - gBattleStruct->turnEffectsTracker++; - break; - case 4: // poison - if ((gBattleMons[gActiveBattler].status1 & STATUS_POISON) && gBattleMons[gActiveBattler].hp != 0) - { - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - BattleScriptExecute(BattleScript_PoisonTurnDmg); - effect++; - } - gBattleStruct->turnEffectsTracker++; - break; - case 5: // toxic poison - if ((gBattleMons[gActiveBattler].status1 & STATUS_TOXIC_POISON) && gBattleMons[gActiveBattler].hp != 0) - { - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - if ((gBattleMons[gActiveBattler].status1 & 0xF00) != 0xF00) //not 16 turns - gBattleMons[gActiveBattler].status1 += 0x100; - gBattleMoveDamage *= (gBattleMons[gActiveBattler].status1 & 0xF00) >> 8; - BattleScriptExecute(BattleScript_PoisonTurnDmg); - effect++; - } - gBattleStruct->turnEffectsTracker++; - break; - case 6: // burn - if ((gBattleMons[gActiveBattler].status1 & STATUS_BURN) && gBattleMons[gActiveBattler].hp != 0) - { - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - BattleScriptExecute(BattleScript_BurnTurnDmg); - effect++; - } - gBattleStruct->turnEffectsTracker++; - break; - case 7: // spooky nightmares - if ((gBattleMons[gActiveBattler].status2 & STATUS2_NIGHTMARE) && gBattleMons[gActiveBattler].hp != 0) - { - // missing sleep check - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 4; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - BattleScriptExecute(BattleScript_NightmareTurnDmg); - effect++; - } - gBattleStruct->turnEffectsTracker++; - break; - case 8: // curse - if ((gBattleMons[gActiveBattler].status2 & STATUS2_CURSED) && gBattleMons[gActiveBattler].hp != 0) - { - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 4; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - BattleScriptExecute(BattleScript_CurseTurnDmg); - effect++; - } - gBattleStruct->turnEffectsTracker++; - break; - case 9: // wrap - if ((gBattleMons[gActiveBattler].status2 & STATUS2_WRAPPED) && gBattleMons[gActiveBattler].hp != 0) - { - gBattleMons[gActiveBattler].status2 -= 0x2000; - if (gBattleMons[gActiveBattler].status2 & STATUS2_WRAPPED) // damaged by wrap - { - gBattleStruct->animArg1 = ewram16004arr(0, gActiveBattler); - gBattleStruct->animArg2 = ewram16004arr(1, gActiveBattler); - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = ewram16004arr(0, gActiveBattler); - gBattleTextBuff1[3] = ewram16004arr(1, gActiveBattler); - gBattleTextBuff1[4] = EOS; - gBattlescriptCurrInstr = BattleScript_WrapTurnDmg; - gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - } - else // broke free - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = ewram16004arr(0, gActiveBattler); - gBattleTextBuff1[3] = ewram16004arr(1, gActiveBattler); - gBattleTextBuff1[4] = EOS; - gBattlescriptCurrInstr = BattleScript_WrapEnds; - } - BattleScriptExecute(gBattlescriptCurrInstr); - effect++; - } - gBattleStruct->turnEffectsTracker++; - break; - case 10: // uproar - if (gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR) - { - for (gBankAttacker = 0; gBankAttacker < gBattlersCount; gBankAttacker++) - { - if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) - && gBattleMons[gBankAttacker].ability != ABILITY_SOUNDPROOF) - { - gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - BattleScriptExecute(BattleScript_MonWokeUpInUproar); - gActiveBattler = gBankAttacker; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); - MarkBufferBankForExecution(gActiveBattler); - break; - } - } - if (gBankAttacker != gBattlersCount) - { - effect = 2; // a pokemon was awaken - break; - } - else - { - gBankAttacker = gActiveBattler; - gBattleMons[gActiveBattler].status2 -= 0x10; // uproar timer goes down - if (WasUnableToUseMove(gActiveBattler)) - { - CancelMultiTurnMoves(gActiveBattler); - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - else if (gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - gBattleMons[gActiveBattler].status2 |= STATUS2_MULTIPLETURNS; - } - else - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - CancelMultiTurnMoves(gActiveBattler); - } - BattleScriptExecute(BattleScript_PrintUproarOverTurns); - effect = 1; - } - } - if (effect != 2) - gBattleStruct->turnEffectsTracker++; - break; - case 11: // thrash - if (gBattleMons[gActiveBattler].status2 & STATUS2_LOCK_CONFUSE) - { - gBattleMons[gActiveBattler].status2 -= 0x400; - if (WasUnableToUseMove(gActiveBattler)) - CancelMultiTurnMoves(gActiveBattler); - else if (!(gBattleMons[gActiveBattler].status2 & STATUS2_LOCK_CONFUSE) - && (gBattleMons[gActiveBattler].status2 & STATUS2_MULTIPLETURNS)) - { - gBattleMons[gActiveBattler].status2 &= ~(STATUS2_MULTIPLETURNS); - if (!(gBattleMons[gActiveBattler].status2 & STATUS2_CONFUSION)) - { - gBattleCommunication[MOVE_EFFECT_BYTE] = 0x47; - SetMoveEffect(1, 0); - if (gBattleMons[gActiveBattler].status2 & STATUS2_CONFUSION) - BattleScriptExecute(BattleScript_ThrashConfuses); - effect++; - } - } - } - gBattleStruct->turnEffectsTracker++; - break; - case 12: // disable - if (gDisableStructs[gActiveBattler].disableTimer1 != 0) - { - int i; - for (i = 0; i < 4; i++) - { - if (gDisableStructs[gActiveBattler].disabledMove == gBattleMons[gActiveBattler].moves[i]) - break; - } - if (i == 4) // pokemon does not have the disabled move anymore - { - gDisableStructs[gActiveBattler].disabledMove = 0; - gDisableStructs[gActiveBattler].disableTimer1 = 0; - } - else if (--gDisableStructs[gActiveBattler].disableTimer1 == 0) // disable ends - { - gDisableStructs[gActiveBattler].disabledMove = 0; - BattleScriptExecute(BattleScript_DisabledNoMore); - effect++; - } - } - gBattleStruct->turnEffectsTracker++; - break; - case 13: // encore - if (gDisableStructs[gActiveBattler].encoreTimer1 != 0) - { - if (gBattleMons[gActiveBattler].moves[gDisableStructs[gActiveBattler].encoredMovePos] != gDisableStructs[gActiveBattler].encoredMove) // pokemon does not have the encored move anymore - { - gDisableStructs[gActiveBattler].encoredMove = 0; - gDisableStructs[gActiveBattler].encoreTimer1 = 0; - } - else if (--gDisableStructs[gActiveBattler].encoreTimer1 == 0 - || gBattleMons[gActiveBattler].pp[gDisableStructs[gActiveBattler].encoredMovePos] == 0) - { - gDisableStructs[gActiveBattler].encoredMove = 0; - gDisableStructs[gActiveBattler].encoreTimer1 = 0; - BattleScriptExecute(BattleScript_EncoredNoMore); - effect++; - } - } - gBattleStruct->turnEffectsTracker++; - break; - case 14: // lock-on decrement - if (gStatuses3[gActiveBattler] & STATUS3_ALWAYS_HITS) - gStatuses3[gActiveBattler] -= 0x8; - gBattleStruct->turnEffectsTracker++; - break; - case 15: // charge - if (gDisableStructs[gActiveBattler].chargeTimer1 && --gDisableStructs[gActiveBattler].chargeTimer1 == 0) - gStatuses3[gActiveBattler] &= ~STATUS3_CHARGED_UP; - gBattleStruct->turnEffectsTracker++; - break; - case 16: // taunt - if (gDisableStructs[gActiveBattler].tauntTimer1) - gDisableStructs[gActiveBattler].tauntTimer1--; - gBattleStruct->turnEffectsTracker++; - break; - case 17: // yawn - if (gStatuses3[gActiveBattler] & STATUS3_YAWN) - { - gStatuses3[gActiveBattler] -= 0x800; - if (!(gStatuses3[gActiveBattler] & STATUS3_YAWN) && !(gBattleMons[gActiveBattler].status1 & STATUS_ANY) - && gBattleMons[gActiveBattler].ability != ABILITY_VITAL_SPIRIT - && gBattleMons[gActiveBattler].ability != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBattler)) - { - CancelMultiTurnMoves(gActiveBattler); - gBattleMons[gActiveBattler].status1 |= (Random() & 3) + 2; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); - MarkBufferBankForExecution(gActiveBattler); - gEffectBank = gActiveBattler; - BattleScriptExecute(BattleScript_YawnMakesAsleep); - effect++; - } - } - gBattleStruct->turnEffectsTracker++; - break; - case 19: // done - gBattleStruct->turnEffectsTracker = 0; - gBattleStruct->turnEffectsBank++; - break; - } - if (effect != 0) - return effect; - } - } - gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20); - return 0; -} - -bool8 HandleWishPerishSongOnTurnEnd(void) -{ - gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20); - switch (gBattleStruct->sub80170DC_Tracker) - { - case 0: // future sight - while (gBattleStruct->sub80170DC_Bank < gBattlersCount) - { - gActiveBattler = gBattleStruct->sub80170DC_Bank; - if (gAbsentBattlerFlags & gBitTable[gActiveBattler]) - gBattleStruct->sub80170DC_Bank++; - else - { - gBattleStruct->sub80170DC_Bank++; - if (gWishFutureKnock.futureSightCounter[gActiveBattler] && --gWishFutureKnock.futureSightCounter[gActiveBattler] == 0 && gBattleMons[gActiveBattler].hp) - { - if (gWishFutureKnock.futureSightMove[gActiveBattler] == MOVE_FUTURE_SIGHT) - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - else //Doom Desire - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = gWishFutureKnock.futureSightMove[gActiveBattler]; - gBattleTextBuff1[3] = gWishFutureKnock.futureSightMove[gActiveBattler] >> 8; - gBattleTextBuff1[4] = 0xFF; - gBankTarget = gActiveBattler; - gBankAttacker = gWishFutureKnock.futureSightAttacker[gActiveBattler]; - gBattleMoveDamage = gWishFutureKnock.futureSightDmg[gActiveBattler]; - gSpecialStatuses[gBankTarget].moveturnLostHP = 0xFFFF; - BattleScriptExecute(BattleScript_MonTookFutureAttack); - return 1; - } - } - } - gBattleStruct->sub80170DC_Tracker = 1; - gBattleStruct->sub80170DC_Bank = 0; - case 1: // perish song - while (gBattleStruct->sub80170DC_Bank < gBattlersCount) - { - gActiveBattler = gBankAttacker = gBanksByTurnOrder[gBattleStruct->sub80170DC_Bank]; - if (gAbsentBattlerFlags & gBitTable[gActiveBattler]) - gBattleStruct->sub80170DC_Bank++; - else - { - gBattleStruct->sub80170DC_Bank++; - if (gStatuses3[gActiveBattler] & STATUS3_PERISH_SONG) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 1; - gBattleTextBuff1[2] = 1; - gBattleTextBuff1[3] = 1; - gBattleTextBuff1[4] = gDisableStructs[gActiveBattler].perishSongTimer1; - gBattleTextBuff1[5] = 0xFF; - if (gDisableStructs[gActiveBattler].perishSongTimer1 == 0) - { - gStatuses3[gActiveBattler] &= ~(STATUS3_PERISH_SONG); - gBattleMoveDamage = gBattleMons[gActiveBattler].hp; - gBattlescriptCurrInstr = BattleScript_PerishSongHits; - } - else - { - gDisableStructs[gActiveBattler].perishSongTimer1--; - gBattlescriptCurrInstr = BattleScript_PerishSongTimerGoesDown; - } - BattleScriptExecute(gBattlescriptCurrInstr); - return 1; - } - } - } - break; - } - gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20); - return 0; -} - -#define HandleFaintedMonActions_MAX_CASE 7 - -bool8 HandleFaintedMonActions(void) -{ - if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) - return 0; - do - { - int i; - switch (gBattleStruct->sub80173A4_Tracker) - { - case 0: - gBattleStruct->unk1605A = 0; - gBattleStruct->sub80173A4_Tracker++; - for (i = 0; i < gBattlersCount; i++) - { - if (gAbsentBattlerFlags & gBitTable[i] && !sub_8018018(i, 6, 6)) - gAbsentBattlerFlags &= ~(gBitTable[i]); - } - case 1: - do - { - gBank1 = gBankTarget = gBattleStruct->unk1605A; - if (gBattleMons[gBattleStruct->unk1605A].hp == 0 && !(gBattleStruct->unk16113 & gBitTable[gBattlerPartyIndexes[gBattleStruct->unk1605A]]) && !(gAbsentBattlerFlags & gBitTable[gBattleStruct->unk1605A])) - { - BattleScriptExecute(BattleScript_GiveExp); - gBattleStruct->sub80173A4_Tracker = 2; - return 1; - } - } while (++gBattleStruct->unk1605A != gBattlersCount); - gBattleStruct->sub80173A4_Tracker = 3; - break; - case 2: - sub_8015740(gBank1); - if (++gBattleStruct->unk1605A == gBattlersCount) - gBattleStruct->sub80173A4_Tracker = 3; - else - gBattleStruct->sub80173A4_Tracker = 1; - break; - case 3: - gBattleStruct->unk1605A = 0; - gBattleStruct->sub80173A4_Tracker++; - case 4: - do - { - gBank1 = gBankTarget = gBattleStruct->unk1605A; //or should banks be switched? - if (gBattleMons[gBattleStruct->unk1605A].hp == 0 && !(gAbsentBattlerFlags & gBitTable[gBattleStruct->unk1605A])) - { - BattleScriptExecute(BattleScript_HandleFaintedMon); - gBattleStruct->sub80173A4_Tracker = 5; - return 1; - } - } while (++gBattleStruct->unk1605A != gBattlersCount); - gBattleStruct->sub80173A4_Tracker = 6; - break; - case 5: - if (++gBattleStruct->unk1605A == gBattlersCount) - gBattleStruct->sub80173A4_Tracker = 6; - else - gBattleStruct->sub80173A4_Tracker = 4; - break; - case 6: - if (AbilityBattleEffects(9, 0, 0, 0, 0) || AbilityBattleEffects(0xB, 0, 0, 0, 0) || ItemBattleEffects(1, 0, 1) || AbilityBattleEffects(6, 0, 0, 0, 0)) - return 1; - gBattleStruct->sub80173A4_Tracker++; - break; - case 7: - break; - } - } while (gBattleStruct->sub80173A4_Tracker != HandleFaintedMonActions_MAX_CASE); - return 0; -} - -void TryClearRageStatuses(void) -{ - int i; - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleMons[i].status2 & STATUS2_RAGE && gChosenMovesByBanks[i] != MOVE_RAGE) - gBattleMons[i].status2 &= ~(STATUS2_RAGE); - } -} - -#define ATKCANCELLER_MAX_CASE 14 - -u8 AtkCanceller_UnableToUseMove(void) -{ - u8 effect = 0; - s32* bideDmg = &gBattleStruct->bideDmg; - do - { - switch (gBattleStruct->atkCancellerTracker) - { - case 0: // flags clear - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_DESTINY_BOND); - gStatuses3[gBankAttacker] &= ~(STATUS3_GRUDGE); - gBattleStruct->atkCancellerTracker++; - break; - case 1: // check being asleep - if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) - { - if (UproarWakeUpCheck(gBankAttacker)) - { - gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); - BattleScriptPushCursor(); - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; - effect = 2; - } - else - { - u8 toSub; - if (gBattleMons[gBankAttacker].ability == ABILITY_EARLY_BIRD) - toSub = 2; - else - toSub = 1; - if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) < toSub) - gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); - else - gBattleMons[gBankAttacker].status1 -= toSub; - if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) - { - if (gCurrentMove != MOVE_SNORE && gCurrentMove != MOVE_SLEEP_TALK) - { - gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 2; - } - } - else - { - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); - BattleScriptPushCursor(); - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; - effect = 2; - } - } - } - gBattleStruct->atkCancellerTracker++; - break; - case 2: // check being frozen - if (gBattleMons[gBankAttacker].status1 & STATUS_FREEZE) - { - if (Random() % 5) - { - if (gBattleMoves[gCurrentMove].effect != EFFECT_THAW_HIT) // unfreezing via a move effect happens in case 13 - { - gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen; - gHitMarker |= HITMARKER_NO_ATTACKSTRING; - } - else - { - gBattleStruct->atkCancellerTracker++; - break; - } - } - else // unfreeze - { - gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - effect = 2; - } - gBattleStruct->atkCancellerTracker++; - break; - case 3: // truant - if (gBattleMons[gBankAttacker].ability == ABILITY_TRUANT && gDisableStructs[gBankAttacker].truantCounter) - { - CancelMultiTurnMoves(gBankAttacker); - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; - gMoveResultFlags |= MOVE_RESULT_MISSED; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case 4: // recharge - if (gBattleMons[gBankAttacker].status2 & STATUS2_RECHARGE) - { - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_RECHARGE); - gDisableStructs[gBankAttacker].rechargeCounter = 0; - CancelMultiTurnMoves(gBankAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case 5: // flinch - if (gBattleMons[gBankAttacker].status2 & STATUS2_FLINCHED) - { - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_FLINCHED); - gProtectStructs[gBankAttacker].flinchImmobility = 1; - CancelMultiTurnMoves(gBankAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedFlinched; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case 6: // disabled move - if (gDisableStructs[gBankAttacker].disabledMove == gCurrentMove && gDisableStructs[gBankAttacker].disabledMove != 0) - { - gProtectStructs[gBankAttacker].usedDisabledMove = 1; - gBattleStruct->scriptingActive = gBankAttacker; - CancelMultiTurnMoves(gBankAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsDisabled; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case 7: // taunt - if (gDisableStructs[gBankAttacker].tauntTimer1 && gBattleMoves[gCurrentMove].power == 0) - { - gProtectStructs[gBankAttacker].usedTauntedMove = 1; - CancelMultiTurnMoves(gBankAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case 8: // imprisoned - if (IsImprisoned(gBankAttacker, gCurrentMove)) - { - gProtectStructs[gBankAttacker].usedImprisionedMove = 1; - CancelMultiTurnMoves(gBankAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case 9: // confusion - if (gBattleMons[gBankAttacker].status2 & STATUS2_CONFUSION) - { - gBattleMons[gBankAttacker].status2--; - if (gBattleMons[gBankAttacker].status2 & STATUS2_CONFUSION) - { - if (Random() & 1) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - BattleScriptPushCursor(); - } - else // confusion dmg - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gBankTarget = gBankAttacker; - gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankAttacker], MOVE_POUND, 0, 40, 0, gBankAttacker, gBankAttacker); - gProtectStructs[gBankAttacker].confusionSelfDmg = 1; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - } - gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfused; - } - else // snapped out of confusion - { - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfusedNoMore; - } - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case 10: // paralysis - if (gBattleMons[gBankAttacker].status1 & STATUS_PARALYSIS && (Random() % 4) == 0) - { - gProtectStructs[gBankAttacker].prlzImmobility = 1; - CancelMultiTurnMoves(gBankAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case 11: // infatuation - if (gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) - { - gBattleStruct->scriptingActive = CountTrailingZeroBits((gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) >> 0x10); - if (Random() & 1) - BattleScriptPushCursor(); - else - { - BattleScriptPush(BattleScript_MoveUsedIsParalyzedCantAttack); - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - gProtectStructs[gBankAttacker].loveImmobility = 1; - CancelMultiTurnMoves(gBankAttacker); - } - gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case 12: // bide - if (gBattleMons[gBankAttacker].status2 & STATUS2_BIDE) - { - gBattleMons[gBankAttacker].status2 -= 0x100; - if (gBattleMons[gBankAttacker].status2 & STATUS2_BIDE) - gBattlescriptCurrInstr = BattleScript_BideStoringEnergy; - else - { - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_MULTIPLETURNS); - if (gTakenDmg[gBankAttacker]) - { - gCurrentMove = MOVE_BIDE; - *bideDmg = gTakenDmg[gBankAttacker] * 2; - gBankTarget = gTakenDmgBanks[gBankAttacker]; - if (gAbsentBattlerFlags & gBitTable[gBankTarget]) - gBankTarget = GetMoveTarget(MOVE_BIDE, 1); - gBattlescriptCurrInstr = BattleScript_BideAttack; - } - else - gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack; - } - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case 13: // move thawing - if (gBattleMons[gBankAttacker].status1 & STATUS_FREEZE) - { - if (gBattleMoves[gCurrentMove].effect == EFFECT_THAW_HIT) - { - gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - effect = 2; - } - gBattleStruct->atkCancellerTracker++; - break; - case 14: // last case - break; - } - - } while (gBattleStruct->atkCancellerTracker != ATKCANCELLER_MAX_CASE && effect == 0); - - if (effect == 2) - { - gActiveBattler = gBankAttacker; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); - MarkBufferBankForExecution(gActiveBattler); - } - return effect; -} - -bool8 sub_8018018(u8 bank, u8 r1, u8 r2) -{ - struct Pokemon* party; - u8 r7; - u8 r6; - s32 i; - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - return 0; - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - r7 = sub_803FC34(bank); - if (GetBattlerSide(bank) == 0) - party = gPlayerParty; - else - party = gEnemyParty; - r6 = sub_803FBFC(r7); - for (i = r6 * 3; i < r6 * 3 + 3; i++) - { - if (GetMonData(&party[i], MON_DATA_HP) && GetMonData(&party[i], MON_DATA_SPECIES2) && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG) - break; - } - return (i == r6 * 3 + 3); - } - else - { - if (GetBattlerSide(bank) == 1) - { - r7 = GetBattlerAtPosition(1); - r6 = GetBattlerAtPosition(3); - party = gEnemyParty; - } - else - { - r7 = GetBattlerAtPosition(0); - r6 = GetBattlerAtPosition(2); - party = gPlayerParty; - } - if (r1 == 6) - r1 = gBattlerPartyIndexes[r7]; - if (r2 == 6) - r2 = gBattlerPartyIndexes[r6]; - for (i = 0; i < 6; i++) - { - if (GetMonData(&party[i], MON_DATA_HP) && GetMonData(&party[i], MON_DATA_SPECIES2) && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG && i != r1 && i != r2 && i != ewram16068arr(r7) && i != ewram16068arr(r6)) - break; - } - return (i == 6); - } -} - -enum -{ - CASTFORM_NO_CHANGE, //0 - CASTFORM_TO_NORMAL, //1 - CASTFORM_TO_FIRE, //2 - CASTFORM_TO_WATER, //3 - CASTFORM_TO_ICE, //4 -}; - -u8 CastformDataTypeChange(u8 bank) -{ - u8 formChange = 0; - if (gBattleMons[bank].species != SPECIES_CASTFORM || gBattleMons[bank].ability != ABILITY_FORECAST || gBattleMons[bank].hp == 0) - return CASTFORM_NO_CHANGE; - if (!WEATHER_HAS_EFFECT && gBattleMons[bank].type1 != TYPE_NORMAL && gBattleMons[bank].type2 != TYPE_NORMAL) - { - gBattleMons[bank].type1 = TYPE_NORMAL; - gBattleMons[bank].type2 = TYPE_NORMAL; - return CASTFORM_TO_NORMAL; - } - if (!WEATHER_HAS_EFFECT) - return CASTFORM_NO_CHANGE; - if (!(gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SUN_ANY | WEATHER_HAIL)) && gBattleMons[bank].type1 != TYPE_NORMAL && gBattleMons[bank].type2 != TYPE_NORMAL) - { - gBattleMons[bank].type1 = TYPE_NORMAL; - gBattleMons[bank].type2 = TYPE_NORMAL; - formChange = CASTFORM_TO_NORMAL; - } - if (gBattleWeather & WEATHER_SUN_ANY && gBattleMons[bank].type1 != TYPE_FIRE && gBattleMons[bank].type2 != TYPE_FIRE) - { - gBattleMons[bank].type1 = TYPE_FIRE; - gBattleMons[bank].type2 = TYPE_FIRE; - formChange = CASTFORM_TO_FIRE; - } - if (gBattleWeather & WEATHER_RAIN_ANY && gBattleMons[bank].type1 != TYPE_WATER && gBattleMons[bank].type2 != TYPE_WATER) - { - gBattleMons[bank].type1 = TYPE_WATER; - gBattleMons[bank].type2 = TYPE_WATER; - formChange = CASTFORM_TO_WATER; - } - if (gBattleWeather & WEATHER_HAIL && gBattleMons[bank].type1 != TYPE_ICE && gBattleMons[bank].type2 != TYPE_ICE) - { - gBattleMons[bank].type1 = TYPE_ICE; - gBattleMons[bank].type2 = TYPE_ICE; - formChange = CASTFORM_TO_ICE; - } - return formChange; -} - -u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) -{ - u8 effect = 0; - struct Pokemon* pokeAtk; - struct Pokemon* pokeDef; - u16 speciesAtk; - u16 speciesDef; - u32 pidAtk; - u32 pidDef; - - if (gBankAttacker >= gBattlersCount) - gBankAttacker = bank; - if (GetBattlerSide(gBankAttacker) == 0) - pokeAtk = &gPlayerParty[gBattlerPartyIndexes[gBankAttacker]]; - else - pokeAtk = &gEnemyParty[gBattlerPartyIndexes[gBankAttacker]]; - - if (gBankTarget >= gBattlersCount) - gBankTarget = bank; - if (GetBattlerSide(gBankTarget) == 0) - pokeDef = &gPlayerParty[gBattlerPartyIndexes[gBankTarget]]; - else - pokeDef = &gEnemyParty[gBattlerPartyIndexes[gBankTarget]]; - - speciesAtk = GetMonData(pokeAtk, MON_DATA_SPECIES); - pidAtk = GetMonData(pokeAtk, MON_DATA_PERSONALITY); - - speciesDef = GetMonData(pokeDef, MON_DATA_SPECIES); - pidDef = GetMonData(pokeDef, MON_DATA_PERSONALITY); - - if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) // why isn't that check done at the beginning? - { - u8 moveType; - s32 i; - u16 move; - u8 side; - u8 target1; - - if (special) - gLastUsedAbility = special; - else - gLastUsedAbility = gBattleMons[bank].ability; - - if (moveArg) - move = moveArg; - else - move = gCurrentMove; - - if (gBattleStruct->dynamicMoveType) - moveType = gBattleStruct->dynamicMoveType & 0x3F; - else - moveType = gBattleMoves[move].type; - - switch (caseID) - { - case ABILITYEFFECT_ON_SWITCHIN: // 0 - if (gBankAttacker >= gBattlersCount) - gBankAttacker = bank; - switch (gLastUsedAbility) - { - case 0xFF: //weather from overworld - switch (GetCurrentWeather()) - { - case WEATHER_RAIN_LIGHT: - case WEATHER_RAIN_MED: - case WEATHER_RAIN_HEAVY: - if (!(gBattleWeather & WEATHER_RAIN_ANY)) - { - gBattleWeather = (WEATHER_RAIN_TEMPORARY | WEATHER_RAIN_PERMANENT); - gBattleStruct->animArg1 = B_ANIM_RAIN_CONTINUES; - gBattleStruct->scriptingActive = bank; - effect++; - } - break; - case WEATHER_SANDSTORM: - if (!(gBattleWeather & WEATHER_SANDSTORM_ANY)) - { - gBattleWeather = (WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY); - gBattleStruct->animArg1 = B_ANIM_SANDSTORM_CONTINUES; - gBattleStruct->scriptingActive = bank; - effect++; - } - break; - case WEATHER_DROUGHT: - if (!(gBattleWeather & WEATHER_SUN_ANY)) - { - gBattleWeather = (WEATHER_SUN_PERMANENT | WEATHER_SUN_TEMPORARY); - gBattleStruct->animArg1 = B_ANIM_SUN_CONTINUES; - gBattleStruct->scriptingActive = bank; - effect++; - } - break; - } - if (effect) - { - gBattleCommunication[MULTISTRING_CHOOSER] = GetCurrentWeather(); - BattleScriptPushCursorAndCallback(BattleScript_OverworldWeatherStarts); - } - break; - case ABILITY_DRIZZLE: - if (!(gBattleWeather & WEATHER_RAIN_PERMANENT)) - { - gBattleWeather = (WEATHER_RAIN_PERMANENT | WEATHER_RAIN_TEMPORARY); - BattleScriptPushCursorAndCallback(BattleScript_DrizzleActivates); - gBattleStruct->scriptingActive = bank; - effect++; - } - break; - case ABILITY_SAND_STREAM: - if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT)) - { - gBattleWeather = (WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY); - BattleScriptPushCursorAndCallback(BattleScript_SandstreamActivates); - gBattleStruct->scriptingActive = bank; - effect++; - } - break; - case ABILITY_DROUGHT: - if (!(gBattleWeather & WEATHER_SUN_PERMANENT)) - { - gBattleWeather = (WEATHER_SUN_PERMANENT | WEATHER_SUN_TEMPORARY); - BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates); - gBattleStruct->scriptingActive = bank; - effect++; - } - break; - case ABILITY_INTIMIDATE: - if (!(gSpecialStatuses[bank].intimidatedPoke)) - { - gStatuses3[bank] |= STATUS3_INTIMIDATE_POKES; - gSpecialStatuses[bank].intimidatedPoke = 1; - } - break; - case ABILITY_FORECAST: - effect = CastformDataTypeChange(bank); - if (effect != 0) - { - BattleScriptPushCursorAndCallback(BattleScript_CastformChange); - gBattleStruct->scriptingActive = bank; - gBattleStruct->castformToChangeInto = effect - 1; - } - break; - case ABILITY_TRACE: - if (!(gSpecialStatuses[bank].traced)) - { - gStatuses3[bank] |= STATUS3_TRACE; - gSpecialStatuses[bank].traced = 1; - } - break; - case ABILITY_CLOUD_NINE: - case ABILITY_AIR_LOCK: - { - // that's a weird choice for a variable, why not use i or bank? - for (target1 = 0; target1 < gBattlersCount; target1++) - { - effect = CastformDataTypeChange(target1); - if (effect != 0) - { - BattleScriptPushCursorAndCallback(BattleScript_CastformChange); - gBattleStruct->scriptingActive = target1; - gBattleStruct->castformToChangeInto = effect - 1; - break; - } - } - } - break; - } - break; - case ABILITYEFFECT_ENDTURN: // 1 - if (gBattleMons[bank].hp != 0) - { - gBankAttacker = bank; - switch (gLastUsedAbility) - { - case ABILITY_RAIN_DISH: - if (WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY) - && gBattleMons[bank].maxHP > gBattleMons[bank].hp) - { - gLastUsedAbility = ABILITY_RAIN_DISH; // why - BattleScriptPushCursorAndCallback(BattleScript_RainDishActivates); - gBattleMoveDamage = gBattleMons[bank].maxHP / 16; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - effect++; - } - break; - case ABILITY_SHED_SKIN: - if ((gBattleMons[bank].status1 & STATUS_ANY) && (Random() % 3) == 0) - { - if (gBattleMons[bank].status1 & (STATUS_POISON | STATUS_TOXIC_POISON)) - StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); - if (gBattleMons[bank].status1 & STATUS_SLEEP) - StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); - if (gBattleMons[bank].status1 & STATUS_PARALYSIS) - StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); - if (gBattleMons[bank].status1 & STATUS_BURN) - StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); - if (gBattleMons[bank].status1 & STATUS_FREEZE) - StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); - gBattleMons[bank].status1 = 0; - // BUG: The nightmare status does not get cleared here. This was fixed in Emerald. - //gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); - gBattleStruct->scriptingActive = gActiveBattler = bank; - BattleScriptPushCursorAndCallback(BattleScript_ShedSkinActivates); - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1); - MarkBufferBankForExecution(gActiveBattler); - effect++; - } - break; - case ABILITY_SPEED_BOOST: - if (gBattleMons[bank].statStages[STAT_STAGE_SPEED] < 0xC && gDisableStructs[bank].isFirstTurn != 2) - { - gBattleMons[bank].statStages[STAT_STAGE_SPEED]++; - gBattleStruct->animArg1 = 0x11; - gBattleStruct->animArg2 = 0; - BattleScriptPushCursorAndCallback(BattleScript_SpeedBoostActivates); - gBattleStruct->scriptingActive = bank; - effect++; - } - break; - case ABILITY_TRUANT: - gDisableStructs[gBankAttacker].truantCounter ^= 1; - break; - } - } - break; - case ABILITYEFFECT_MOVES_BLOCK: // 2 - if (gLastUsedAbility == ABILITY_SOUNDPROOF) - { - for (i = 0; gSoundMovesTable[i] != 0xFFFF; i++) - { - if (gSoundMovesTable[i] == move) - break; - } - if (gSoundMovesTable[i] != 0xFFFF) - { - if (gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS) - gHitMarker |= HITMARKER_NO_PPDEDUCT; - gBattlescriptCurrInstr = BattleScript_SoundproofProtected; - effect = 1; - } - } - break; - case ABILITYEFFECT_ABSORBING: // 3 - if (move) - { - switch (gLastUsedAbility) - { - case ABILITY_VOLT_ABSORB: - if (moveType == TYPE_ELECTRIC && gBattleMoves[move].power != 0) - { - if (gProtectStructs[gBankAttacker].notFirstStrike) - gBattlescriptCurrInstr = BattleScript_MoveHPDrain; - else - gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss; - effect = 1; - } - break; - case ABILITY_WATER_ABSORB: - if (moveType == TYPE_WATER && gBattleMoves[move].power != 0) - { - if (gProtectStructs[gBankAttacker].notFirstStrike) - gBattlescriptCurrInstr = BattleScript_MoveHPDrain; - else - gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss; - effect = 1; - } - break; - case ABILITY_FLASH_FIRE: - if (moveType == TYPE_FIRE && !(gBattleMons[bank].status1 & STATUS_FREEZE)) - { - if (!(eFlashFireArr.arr[bank] & 1)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - if (gProtectStructs[gBankAttacker].notFirstStrike) - gBattlescriptCurrInstr = BattleScript_FlashFireBoost; - else - gBattlescriptCurrInstr = BattleScript_FlashFireBoost_PPLoss; - eFlashFireArr.arr[bank] |= 1; - effect = 2; - } - else - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - if (gProtectStructs[gBankAttacker].notFirstStrike) - gBattlescriptCurrInstr = BattleScript_FlashFireBoost; - else - gBattlescriptCurrInstr = BattleScript_FlashFireBoost_PPLoss; - effect = 2; - } - } - break; - } - if (effect == 1) - { - if (gBattleMons[bank].maxHP == gBattleMons[bank].hp) - { - if ((gProtectStructs[gBankAttacker].notFirstStrike)) - gBattlescriptCurrInstr = BattleScript_MoveHPDrain_FullHP; - else - gBattlescriptCurrInstr = BattleScript_MoveHPDrain_FullHP_PPLoss; - } - else - { - gBattleMoveDamage = gBattleMons[bank].maxHP / 4; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - gBattleMoveDamage *= -1; - } - } - } - break; - case ABILITYEFFECT_CONTACT: // 4 - switch (gLastUsedAbility) - { - case ABILITY_COLOR_CHANGE: - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && move != MOVE_STRUGGLE - && gBattleMoves[move].power != 0 - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) - && gBattleMons[bank].type1 != moveType - && gBattleMons[bank].type2 != moveType - && gBattleMons[bank].hp != 0) - { - gBattleMons[bank].type1 = moveType; - gBattleMons[bank].type2 = moveType; - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 3; - gBattleTextBuff1[2] = moveType; - gBattleTextBuff1[3] = 0xFF; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ColorChangeActivates; - effect++; - } - break; - case ABILITY_ROUGH_SKIN: - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gBattleMons[gBankAttacker].hp != 0 - && !gProtectStructs[gBankAttacker].confusionSelfDmg - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) - && (gBattleMoves[move].flags & F_MAKES_CONTACT)) - { - gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_RoughSkinActivates; - effect++; - } - break; - case ABILITY_EFFECT_SPORE: - if (DEBUG && (gUnknown_02023A14_50 & 4)) - { - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gBattleMons[gBankAttacker].hp != 0 - && !gProtectStructs[gBankAttacker].confusionSelfDmg - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) - && (gBattleMoves[move].flags & F_MAKES_CONTACT)) - { - do - { - gBattleCommunication[MOVE_EFFECT_BYTE] = Random() & 3; - } while (gBattleCommunication[MOVE_EFFECT_BYTE] == 0); - if (gBattleCommunication[MOVE_EFFECT_BYTE] == 3) - gBattleCommunication[MOVE_EFFECT_BYTE] += 2; - gBattleCommunication[MOVE_EFFECT_BYTE] += 0x40; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; - gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; - effect++; - } - } - else - { - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gBattleMons[gBankAttacker].hp != 0 - && !gProtectStructs[gBankAttacker].confusionSelfDmg - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) - && (gBattleMoves[move].flags & F_MAKES_CONTACT) - && (Random() % 10) == 0) - { - do - { - gBattleCommunication[MOVE_EFFECT_BYTE] = Random() & 3; - } while (gBattleCommunication[MOVE_EFFECT_BYTE] == 0); - if (gBattleCommunication[MOVE_EFFECT_BYTE] == 3) - gBattleCommunication[MOVE_EFFECT_BYTE] += 2; - gBattleCommunication[MOVE_EFFECT_BYTE] += 0x40; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; - gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; - effect++; - } - } - break; - case ABILITY_POISON_POINT: - if (DEBUG && (gUnknown_02023A14_50 & 4)) - { - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gBattleMons[gBankAttacker].hp != 0 - && !gProtectStructs[gBankAttacker].confusionSelfDmg - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) - && (gBattleMoves[move].flags & F_MAKES_CONTACT)) - { - gBattleCommunication[MOVE_EFFECT_BYTE] = 0x42; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; - gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; - effect++; - } - } - else - { - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gBattleMons[gBankAttacker].hp != 0 - && !gProtectStructs[gBankAttacker].confusionSelfDmg - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) - && (gBattleMoves[move].flags & F_MAKES_CONTACT) - && (Random() % 3) == 0) - { - gBattleCommunication[MOVE_EFFECT_BYTE] = 0x42; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; - gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; - effect++; - } - } - break; - case ABILITY_STATIC: - if (DEBUG && (gUnknown_02023A14_50 & 4)) - { - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gBattleMons[gBankAttacker].hp != 0 - && !gProtectStructs[gBankAttacker].confusionSelfDmg - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) - && (gBattleMoves[move].flags & F_MAKES_CONTACT)) - { - gBattleCommunication[MOVE_EFFECT_BYTE] = 0x45; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; - gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; - effect++; - } - } - else - { - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gBattleMons[gBankAttacker].hp != 0 - && !gProtectStructs[gBankAttacker].confusionSelfDmg - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) - && (gBattleMoves[move].flags & F_MAKES_CONTACT) - && (Random() % 3) == 0) - { - gBattleCommunication[MOVE_EFFECT_BYTE] = 0x45; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; - gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; - effect++; - } - } - break; - case ABILITY_FLAME_BODY: - if (DEBUG && (gUnknown_02023A14_50 & 4)) - { - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gBattleMons[gBankAttacker].hp != 0 - && !gProtectStructs[gBankAttacker].confusionSelfDmg - && (gBattleMoves[move].flags & F_MAKES_CONTACT) - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)) - { - gBattleCommunication[MOVE_EFFECT_BYTE] = 0x43; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; - gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; - effect++; - } - } - else - { - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gBattleMons[gBankAttacker].hp != 0 - && !gProtectStructs[gBankAttacker].confusionSelfDmg - && (gBattleMoves[move].flags & F_MAKES_CONTACT) - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) - && (Random() % 3) == 0) - { - gBattleCommunication[MOVE_EFFECT_BYTE] = 0x43; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; - gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; - effect++; - } - } - break; - case ABILITY_CUTE_CHARM: - if (DEBUG && (gUnknown_02023A14_50 & 4)) - { - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gBattleMons[gBankAttacker].hp != 0 - && !gProtectStructs[gBankAttacker].confusionSelfDmg - && (gBattleMoves[move].flags & F_MAKES_CONTACT) - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) - && gBattleMons[gBankTarget].hp != 0 - && gBattleMons[gBankAttacker].ability != ABILITY_OBLIVIOUS - && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) - && !(gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) - && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != 0xFF - && GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) != 0xFF) - { - gBattleMons[gBankAttacker].status2 |= (gBitTable[gBankTarget] << 0x10); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_CuteCharmActivates; - effect++; - } - } - else - { - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gBattleMons[gBankAttacker].hp != 0 - && !gProtectStructs[gBankAttacker].confusionSelfDmg - && (gBattleMoves[move].flags & F_MAKES_CONTACT) - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) - && gBattleMons[gBankTarget].hp != 0 - && (Random() % 3) == 0 - && gBattleMons[gBankAttacker].ability != ABILITY_OBLIVIOUS - && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) - && !(gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) - && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != 0xFF - && GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) != 0xFF) - { - gBattleMons[gBankAttacker].status2 |= (gBitTable[gBankTarget] << 0x10); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_CuteCharmActivates; - effect++; - } - } - break; - } - break; - case ABILITYEFFECT_IMMUNITY: // 5 - { - for (bank = 0; bank < gBattlersCount; bank++) - { - switch (gBattleMons[bank].ability) - { - case ABILITY_IMMUNITY: - if (gBattleMons[bank].status1 & (STATUS_POISON | STATUS_TOXIC_POISON | 0xF00)) // TODO: what is 0xF00? - { - StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); - effect = 1; - } - break; - case ABILITY_OWN_TEMPO: - if (gBattleMons[bank].status2 & STATUS2_CONFUSION) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn); - effect = 2; - } - break; - case ABILITY_LIMBER: - if (gBattleMons[bank].status1 & STATUS_PARALYSIS) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); - effect = 1; - } - break; - case ABILITY_INSOMNIA: - case ABILITY_VITAL_SPIRIT: - if (gBattleMons[bank].status1 & STATUS_SLEEP) - { - gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); - StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); - effect = 1; - } - break; - case ABILITY_WATER_VEIL: - if (gBattleMons[bank].status1 & STATUS_BURN) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); - effect = 1; - } - break; - case ABILITY_MAGMA_ARMOR: - if (gBattleMons[bank].status1 & STATUS_FREEZE) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); - effect = 1; - } - break; - case ABILITY_OBLIVIOUS: - if (gBattleMons[bank].status2 & STATUS2_INFATUATION) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); - effect = 3; - } - break; - } - if (effect) - { - switch (effect) - { - case 1: // status cleared - gBattleMons[bank].status1 = 0; - break; - case 2: // get rid of confusion - gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); - break; - case 3: // get rid of infatuation - gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION); - break; - } - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_AbilityCuredStatus; - gBattleStruct->scriptingActive = bank; - gActiveBattler = bank; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); - MarkBufferBankForExecution(gActiveBattler); - return effect; - } - } - } - break; - case ABILITYEFFECT_FORECAST: // 6 - { - for (bank = 0; bank < gBattlersCount; bank++) - { - if (gBattleMons[bank].ability == ABILITY_FORECAST) - { - effect = CastformDataTypeChange(bank); - if (effect) - { - BattleScriptPushCursorAndCallback(BattleScript_CastformChange); - gBattleStruct->scriptingActive = bank; - gBattleStruct->castformToChangeInto = effect - 1; - return effect; - } - } - } - } - break; - case ABILITYEFFECT_SYNCHRONIZE: // 7 - if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONISE_EFFECT)) - { - gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT); - gBattleStruct->synchroniseEffect &= 0x3F; - if (gBattleStruct->synchroniseEffect == 6) - gBattleStruct->synchroniseEffect = 2; - gBattleCommunication[MOVE_EFFECT_BYTE] = gBattleStruct->synchroniseEffect + 0x40; - gBattleStruct->scriptingActive = gBankTarget; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_SynchronizeActivates; - gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; - effect++; - } - break; - case ABILITYEFFECT_ATK_SYNCHRONIZE: // 8 - if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONISE_EFFECT)) - { - gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT); - gBattleStruct->synchroniseEffect &= 0x3F; - if (gBattleStruct->synchroniseEffect == 6) - gBattleStruct->synchroniseEffect = 2; - gBattleCommunication[MOVE_EFFECT_BYTE] = gBattleStruct->synchroniseEffect; - gBattleStruct->scriptingActive = gBankAttacker; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_SynchronizeActivates; - gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; - effect++; - } - break; - case ABILITYEFFECT_INTIMIDATE1: // 9 - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleMons[i].ability == ABILITY_INTIMIDATE && gStatuses3[i] & STATUS3_INTIMIDATE_POKES) - { - gLastUsedAbility = ABILITY_INTIMIDATE; - gStatuses3[i] &= ~(STATUS3_INTIMIDATE_POKES); - BattleScriptPushCursorAndCallback(gUnknown_081D978C); - gBattleStruct->intimidateBank = i; - effect++; - break; - } - } - break; - case ABILITYEFFECT_TRACE: // 11 - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleMons[i].ability == ABILITY_TRACE && (gStatuses3[i] & STATUS3_TRACE)) - { - u8 target2; - side = (GetBattlerPosition(i) ^ 1) & 1; - target1 = GetBattlerAtPosition(side); - target2 = GetBattlerAtPosition(side + 2); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - if (gBattleMons[target1].ability != 0 && gBattleMons[target1].hp != 0 - && gBattleMons[target2].ability != 0 && gBattleMons[target2].hp != 0) - { - gActiveBattler = GetBattlerAtPosition(((Random() & 1) * 2) | side); - gBattleMons[i].ability = gBattleMons[gActiveBattler].ability; - gLastUsedAbility = gBattleMons[gActiveBattler].ability; - effect++; - } - else if (gBattleMons[target1].ability != 0 && gBattleMons[target1].hp != 0) - { - gActiveBattler = target1; - gBattleMons[i].ability = gBattleMons[gActiveBattler].ability; - gLastUsedAbility = gBattleMons[gActiveBattler].ability; - effect++; - } - else if (gBattleMons[target2].ability != 0 && gBattleMons[target2].hp != 0) - { - gActiveBattler = target2; - gBattleMons[i].ability = gBattleMons[gActiveBattler].ability; - gLastUsedAbility = gBattleMons[gActiveBattler].ability; - effect++; - } - } - else - { - gActiveBattler = target1; - if (gBattleMons[target1].ability && gBattleMons[target1].hp) - { - gBattleMons[i].ability = gBattleMons[target1].ability; - gLastUsedAbility = gBattleMons[target1].ability; - effect++; - } - } - if (effect) - { - BattleScriptPushCursorAndCallback(BattleScript_TraceActivates); - gStatuses3[i] &= ~(STATUS3_TRACE); - gBattleStruct->scriptingActive = i; - - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 4; - gBattleTextBuff1[2] = gActiveBattler; - gBattleTextBuff1[3] = gBattlerPartyIndexes[gActiveBattler]; - gBattleTextBuff1[4] = EOS; - - gBattleTextBuff2[0] = 0xFD; - gBattleTextBuff2[1] = 9; - gBattleTextBuff2[2] = gLastUsedAbility; - gBattleTextBuff2[3] = EOS; - break; - } - } - } - break; - case ABILITYEFFECT_INTIMIDATE2: // 10 - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleMons[i].ability == ABILITY_INTIMIDATE && (gStatuses3[i] & STATUS3_INTIMIDATE_POKES)) - { - gLastUsedAbility = ABILITY_INTIMIDATE; - gStatuses3[i] &= ~(STATUS3_INTIMIDATE_POKES); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = gUnknown_081D9795; - gBattleStruct->intimidateBank = i; - effect++; - break; - } - } - break; - case ABILITYEFFECT_CHECK_OTHER_SIDE: // 12 - side = GetBattlerSide(bank); - for (i = 0; i < gBattlersCount; i++) - { - if (GetBattlerSide(i) != side && gBattleMons[i].ability == ability) - { - gLastUsedAbility = ability; - effect = i + 1; - } - } - break; - case ABILITYEFFECT_CHECK_BANK_SIDE: // 13 - side = GetBattlerSide(bank); - for (i = 0; i < gBattlersCount; i++) - { - if (GetBattlerSide(i) == side && gBattleMons[i].ability == ability) - { - gLastUsedAbility = ability; - effect = i + 1; - } - } - break; - case ABILITYEFFECT_FIELD_SPORT: // 14 - switch (gLastUsedAbility) - { - case 0xFD: - for (i = 0; i < gBattlersCount; i++) - { - if (gStatuses3[i] & STATUS3_MUDSPORT) - effect = i + 1; - } - break; - case 0xFE: - for (i = 0; i < gBattlersCount; i++) - { - if (gStatuses3[i] & STATUS3_WATERSPORT) - effect = i + 1; - } - break; - default: - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleMons[i].ability == ability) - { - gLastUsedAbility = ability; - effect = i + 1; - } - } - break; - } - break; - case ABILITYEFFECT_CHECK_ON_FIELD: // 19 - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleMons[i].ability == ability && gBattleMons[i].hp != 0) - { - gLastUsedAbility = ability; - effect = i + 1; - } - } - break; - case ABILITYEFFECT_CHECK_FIELD_EXCEPT_BANK: // 15 - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleMons[i].ability == ability && i != bank) - { - gLastUsedAbility = ability; - effect = i + 1; - } - } - break; - case ABILITYEFFECT_COUNT_OTHER_SIZE: // 16 - side = GetBattlerSide(bank); - for (i = 0; i < gBattlersCount; i++) - { - if (GetBattlerSide(i) != side && gBattleMons[i].ability == ability) - { - gLastUsedAbility = ability; - effect++; - } - } - break; - case ABILITYEFFECT_COUNT_BANK_SIDE: // 17 - side = GetBattlerSide(bank); - for (i = 0; i < gBattlersCount; i++) - { - if (GetBattlerSide(i) == side && gBattleMons[i].ability == ability) - { - gLastUsedAbility = ability; - effect++; - } - } - break; - case ABILITYEFFECT_COUNT_ON_FIELD: // 18 - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleMons[i].ability == ability && i != bank) - { - gLastUsedAbility = ability; - effect++; - } - } - break; - } - if (effect && caseID < 0xC && gLastUsedAbility != 0xFF) - RecordAbilityBattle(bank, gLastUsedAbility); - } - - return effect; -} - -void BattleScriptExecute(const u8* BS_ptr) -{ - gBattlescriptCurrInstr = BS_ptr; - B_FUNCTION_STACK->ptr[B_FUNCTION_STACK->size++] = gBattleMainFunc; - gBattleMainFunc = RunBattleScriptCommands_PopCallbacksStack; - gCurrentActionFuncId = 0; -} - -void BattleScriptPushCursorAndCallback(u8* BS_ptr) -{ - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BS_ptr; - B_FUNCTION_STACK->ptr[B_FUNCTION_STACK->size++] = gBattleMainFunc; - gBattleMainFunc = RunBattleScriptCommands; -} - -enum -{ - ITEM_NO_EFFECT, // 0 - ITEM_STATUS_CHANGE, // 1 - ITEM_EFFECT_OTHER, // 2 - ITEM_PP_CHANGE, // 3 - ITEM_HP_CHANGE, // 4 - ITEM_STATS_CHANGE, // 5 -}; - -enum -{ - FLAVOR_SPICY, // 0 - FLAVOR_DRY, // 1 - FLAVOR_SWEET, // 2 - FLAVOR_BITTER, // 3 - FLAVOR_SOUR, // 4 -}; - -u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) -{ - int i = 0; - u8 effect = ITEM_NO_EFFECT; - u8 changedPP = 0; - u8 bankHoldEffect, atkHoldEffect, defHoldEffect; - u8 bankQuality, atkQuality, defQuality; - u16 atkItem, defItem; - - gLastUsedItem = gBattleMons[bank].item; - if (gLastUsedItem == ITEM_ENIGMA_BERRY) - { - bankHoldEffect = gEnigmaBerries[bank].holdEffect; - bankQuality = gEnigmaBerries[bank].holdEffectParam; - } - else - { - bankHoldEffect = ItemId_GetHoldEffect(gLastUsedItem); - bankQuality = ItemId_GetHoldEffectParam(gLastUsedItem); - } - - atkItem = gBattleMons[gBankAttacker].item; - if (atkItem == ITEM_ENIGMA_BERRY) - { - atkHoldEffect = gEnigmaBerries[gBankAttacker].holdEffect; - atkQuality = gEnigmaBerries[gBankAttacker].holdEffectParam; - } - else - { - atkHoldEffect = ItemId_GetHoldEffect(atkItem); - atkQuality = ItemId_GetHoldEffectParam(atkItem); - } - - // def variables are unused - defItem = gBattleMons[gBankTarget].item; - if (defItem == ITEM_ENIGMA_BERRY) - { - defHoldEffect = gEnigmaBerries[gBankTarget].holdEffect; - defQuality = gEnigmaBerries[gBankTarget].holdEffectParam; - } - else - { - defHoldEffect = ItemId_GetHoldEffect(defItem); - defQuality = ItemId_GetHoldEffectParam(defItem); - } - - switch (caseID) - { - case 0: - switch (bankHoldEffect) - { - case HOLD_EFFECT_DOUBLE_PRIZE: - gBattleStruct->moneyMultiplier = 2; - break; - case HOLD_EFFECT_RESTORE_STATS: - for (i = 0; i < 8; i++) - { - if (gBattleMons[bank].statStages[i] < 6) - { - gBattleMons[bank].statStages[i] = 6; - effect = ITEM_STATS_CHANGE; - } - } - if (effect) - { - gBattleStruct->scriptingActive = bank; - gStringBank = bank; - gActiveBattler = gBankAttacker = bank; - BattleScriptExecute(BattleScript_WhiteHerbEnd2); - } - break; - } - break; - case 1: - if (gBattleMons[bank].hp) - { - switch (bankHoldEffect) - { - case HOLD_EFFECT_RESTORE_HP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) - { - gBattleMoveDamage = bankQuality; - if (gBattleMons[bank].hp + bankQuality > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; - gBattleMoveDamage *= -1; - BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); - effect = 4; - } - break; - case HOLD_EFFECT_RESTORE_PP: - if (!moveTurn) - { - struct Pokemon* poke; - u8 ppBonuses; - u16 move; - - if (GetBattlerSide(bank) == 0) - poke = &gPlayerParty[gBattlerPartyIndexes[bank]]; - else - poke = &gEnemyParty[gBattlerPartyIndexes[bank]]; - for (i = 0; i < 4; i++) - { - move = GetMonData(poke, MON_DATA_MOVE1 + i); - changedPP = GetMonData(poke, MON_DATA_PP1 + i); - ppBonuses = GetMonData(poke, MON_DATA_PP_BONUSES); - if (move && changedPP == 0) - break; - } - if (i != 4) - { - u8 maxPP = CalculatePPWithBonus(move, ppBonuses, i); - if (changedPP + bankQuality > maxPP) - changedPP = maxPP; - else - changedPP = changedPP + bankQuality; - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 2; - gBattleTextBuff1[2] = move; - gBattleTextBuff1[3] = move >> 8; - gBattleTextBuff1[4] = 0xFF; - BattleScriptExecute(BattleScript_BerryPPHealEnd2); - EmitSetMonData(0, i + REQUEST_PPMOVE1_BATTLE, 0, 1, &changedPP); - MarkBufferBankForExecution(gActiveBattler); - effect = ITEM_PP_CHANGE; - } - } - break; - case HOLD_EFFECT_RESTORE_STATS: - for (i = 0; i < 8; i++) - { - if (gBattleMons[bank].statStages[i] < 6) - { - gBattleMons[bank].statStages[i] = 6; - effect = ITEM_STATS_CHANGE; - } - } - if (effect) - { - gBattleStruct->scriptingActive = bank; - gStringBank = bank; - gActiveBattler = gBankAttacker = bank; - BattleScriptExecute(BattleScript_WhiteHerbEnd2); - } - break; - case HOLD_EFFECT_LEFTOVERS: - if (gBattleMons[bank].hp < gBattleMons[bank].maxHP && !moveTurn) - { - gBattleMoveDamage = gBattleMons[bank].maxHP / 16; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; - gBattleMoveDamage *= -1; - BattleScriptExecute(BattleScript_ItemHealHP_End2); - effect = ITEM_HP_CHANGE; - RecordItemBattle(bank, bankHoldEffect); - } - break; - // nice copy/paste there gamefreak, making a function for confuse berries was too much eh? - case HOLD_EFFECT_CONFUSE_SPICY: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 8; - gBattleTextBuff1[2] = FLAVOR_SPICY; - gBattleTextBuff1[3] = EOS; - gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; - gBattleMoveDamage *= -1; - if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_SPICY) < 0) - BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); - else - BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); - effect = ITEM_HP_CHANGE; - } - break; - case HOLD_EFFECT_CONFUSE_DRY: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 8; - gBattleTextBuff1[2] = FLAVOR_DRY; - gBattleTextBuff1[3] = EOS; - gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; - gBattleMoveDamage *= -1; - if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_DRY) < 0) - BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); - else - BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); - effect = ITEM_HP_CHANGE; - } - break; - case HOLD_EFFECT_CONFUSE_SWEET: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 8; - gBattleTextBuff1[2] = FLAVOR_SWEET; - gBattleTextBuff1[3] = EOS; - gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; - gBattleMoveDamage *= -1; - if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_SWEET) < 0) - BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); - else - BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); - effect = ITEM_HP_CHANGE; - } - break; - case HOLD_EFFECT_CONFUSE_BITTER: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 8; - gBattleTextBuff1[2] = FLAVOR_BITTER; - gBattleTextBuff1[3] = EOS; - gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; - gBattleMoveDamage *= -1; - if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_BITTER) < 0) - BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); - else - BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); - effect = ITEM_HP_CHANGE; - } - break; - case HOLD_EFFECT_CONFUSE_SOUR: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 8; - gBattleTextBuff1[2] = FLAVOR_SOUR; - gBattleTextBuff1[3] = EOS; - gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = 1; - if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) - gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; - gBattleMoveDamage *= -1; - if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_SOUR) < 0) - BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); - else - BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); - effect = ITEM_HP_CHANGE; - } - break; - // copy/paste again, smh - case HOLD_EFFECT_ATTACK_UP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_ATK] < 0xC) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 5; - gBattleTextBuff1[2] = STAT_STAGE_ATK; - gBattleTextBuff1[3] = EOS; - - gBattleTextBuff2[0] = 0xFD; - gBattleTextBuff2[1] = 0; - gBattleTextBuff2[2] = 0xD2; - gBattleTextBuff2[3] = 0xD2 >> 8; - gBattleTextBuff2[4] = EOS; - - gEffectBank = bank; - gBattleStruct->statChanger = 0x10 + STAT_STAGE_ATK; - gBattleStruct->animArg1 = 0xE + STAT_STAGE_ATK; - gBattleStruct->animArg2 = 0; - BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); - effect = ITEM_STATS_CHANGE; - } - break; - case HOLD_EFFECT_DEFENSE_UP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_DEF] < 0xC) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 5; - gBattleTextBuff1[2] = STAT_STAGE_DEF; - gBattleTextBuff1[3] = EOS; - - gEffectBank = bank; - gBattleStruct->statChanger = 0x10 + STAT_STAGE_DEF; - gBattleStruct->animArg1 = 0xE + STAT_STAGE_DEF; - gBattleStruct->animArg2 = 0; - BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); - effect = ITEM_STATS_CHANGE; - } - break; - case HOLD_EFFECT_SPEED_UP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPEED] < 0xC) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 5; - gBattleTextBuff1[2] = STAT_STAGE_SPEED; - gBattleTextBuff1[3] = EOS; - - gEffectBank = bank; - gBattleStruct->statChanger = 0x10 + STAT_STAGE_SPEED; - gBattleStruct->animArg1 = 0xE + STAT_STAGE_SPEED; - gBattleStruct->animArg2 = 0; - BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); - effect = ITEM_STATS_CHANGE; - } - break; - case HOLD_EFFECT_SP_ATTACK_UP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPATK] < 0xC) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 5; - gBattleTextBuff1[2] = STAT_STAGE_SPATK; - gBattleTextBuff1[3] = EOS; - - gEffectBank = bank; - gBattleStruct->statChanger = 0x10 + STAT_STAGE_SPATK; - gBattleStruct->animArg1 = 0xE + STAT_STAGE_SPATK; - gBattleStruct->animArg2 = 0; - BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); - effect = ITEM_STATS_CHANGE; - } - break; - case HOLD_EFFECT_SP_DEFENSE_UP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPDEF] < 0xC) - { - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 5; - gBattleTextBuff1[2] = STAT_STAGE_SPDEF; - gBattleTextBuff1[3] = EOS; - - gEffectBank = bank; - gBattleStruct->statChanger = 0x10 + STAT_STAGE_SPDEF; - gBattleStruct->animArg1 = 0xE + STAT_STAGE_SPDEF; - gBattleStruct->animArg2 = 0; - BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); - effect = ITEM_STATS_CHANGE; - } - break; - case HOLD_EFFECT_CRITICAL_UP: - if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && !(gBattleMons[bank].status2 & STATUS2_FOCUS_ENERGY)) - { - gBattleMons[bank].status2 |= STATUS2_FOCUS_ENERGY; - BattleScriptExecute(BattleScript_BerryFocusEnergyEnd2); - effect = ITEM_EFFECT_OTHER; - } - break; - case HOLD_EFFECT_RANDOM_STAT_UP: - if (!moveTurn && gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality) - { - for (i = 0; i < 5; i++) - { - if (gBattleMons[bank].statStages[STAT_STAGE_ATK + i] < 0xC) - break; - } - if (i != 5) - { - do - { - i = Random() % 5; - } while (gBattleMons[bank].statStages[STAT_STAGE_ATK + i] == 0xC); - - gBattleTextBuff1[0] = 0xFD; - gBattleTextBuff1[1] = 5; - gBattleTextBuff1[2] = i + 1; - gBattleTextBuff1[3] = EOS; - - gBattleTextBuff2[0] = 0xFD; - gBattleTextBuff2[1] = 0; - gBattleTextBuff2[2] = 0xD1; - gBattleTextBuff2[3] = 0xD1 >> 8; - gBattleTextBuff2[4] = 0; - gBattleTextBuff2[5] = 0xD2; - gBattleTextBuff2[6] = 0xD2 >> 8; - gBattleTextBuff2[7] = EOS; - - gEffectBank = bank; - gBattleStruct->statChanger = 0x21 + i; - gBattleStruct->animArg1 = 0x21 + i + 6; - gBattleStruct->animArg2 = 0; - BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); - effect = ITEM_STATS_CHANGE; - } - } - break; - case HOLD_EFFECT_CURE_PAR: - if (gBattleMons[bank].status1 & STATUS_PARALYSIS) - { - gBattleMons[bank].status1 &= ~(STATUS_PARALYSIS); - BattleScriptExecute(BattleScript_BerryCurePrlzEnd2); - effect = ITEM_STATUS_CHANGE; - } - break; - case HOLD_EFFECT_CURE_PSN: - if (gBattleMons[bank].status1 & STATUS_PSN_ANY) - { - gBattleMons[bank].status1 &= ~(STATUS_PSN_ANY | STATUS_TOXIC_COUNTER); - BattleScriptExecute(BattleScript_BerryCurePsnEnd2); - effect = ITEM_STATUS_CHANGE; - } - break; - case HOLD_EFFECT_CURE_BRN: - if (gBattleMons[bank].status1 & STATUS_BURN) - { - gBattleMons[bank].status1 &= ~(STATUS_BURN); - BattleScriptExecute(BattleScript_BerryCureBrnEnd2); - effect = ITEM_STATUS_CHANGE; - } - break; - case HOLD_EFFECT_CURE_FRZ: - if (gBattleMons[bank].status1 & STATUS_FREEZE) - { - gBattleMons[bank].status1 &= ~(STATUS_FREEZE); - BattleScriptExecute(BattleScript_BerryCureFrzEnd2); - effect = ITEM_STATUS_CHANGE; - } - break; - case HOLD_EFFECT_CURE_SLP: - if (gBattleMons[bank].status1 & STATUS_SLEEP) - { - gBattleMons[bank].status1 &= ~(STATUS_SLEEP); - gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); - BattleScriptExecute(BattleScript_BerryCureSlpEnd2); - effect = ITEM_STATUS_CHANGE; - } - break; - case HOLD_EFFECT_CURE_CONFUSION: - if (gBattleMons[bank].status2 & STATUS2_CONFUSION) - { - gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); - BattleScriptExecute(BattleScript_BerryCureConfusionEnd2); - effect = ITEM_EFFECT_OTHER; - } - break; - case HOLD_EFFECT_CURE_STATUS: - if (gBattleMons[bank].status1 & STATUS_ANY || gBattleMons[bank].status2 & STATUS2_CONFUSION) - { - i = 0; - if (gBattleMons[bank].status1 & STATUS_PSN_ANY) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); - i++; - } - if (gBattleMons[bank].status1 & STATUS_SLEEP) - { - gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); - StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); - i++; - } - if (gBattleMons[bank].status1 & STATUS_PARALYSIS) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); - i++; - } - if (gBattleMons[bank].status1 & STATUS_BURN) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); - i++; - } - if (gBattleMons[bank].status1 & STATUS_FREEZE) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); - i++; - } - if (gBattleMons[bank].status2 & STATUS2_CONFUSION) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn); - i++; - } - if (!(i > 1)) - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - gBattleMons[bank].status1 = 0; - gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); - BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2); - effect = ITEM_STATUS_CHANGE; - } - break; - case HOLD_EFFECT_CURE_ATTRACT: - if (gBattleMons[bank].status2 & STATUS2_INFATUATION) - { - gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION); - StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); - BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2); - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - effect = ITEM_EFFECT_OTHER; - } - break; - } - if (effect) - { - gBattleStruct->scriptingActive = bank; - gStringBank = bank; - gActiveBattler = gBankAttacker = bank; - switch (effect) - { - case ITEM_STATUS_CHANGE: - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1); - MarkBufferBankForExecution(gActiveBattler); - break; - case ITEM_PP_CHANGE: - if (!(gBattleMons[bank].status2 & STATUS2_TRANSFORMED) && !(gDisableStructs[bank].unk18_b & gBitTable[i])) - gBattleMons[bank].pp[i] = changedPP; - break; - } - } - } - break; - case 2: - break; - case 3: - for (bank = 0; bank < gBattlersCount; bank++) - { - gLastUsedItem = gBattleMons[bank].item; - if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY) - { - bankHoldEffect = gEnigmaBerries[bank].holdEffect; - bankQuality = gEnigmaBerries[bank].holdEffectParam; - } - else - { - bankHoldEffect = ItemId_GetHoldEffect(gLastUsedItem); - bankQuality = ItemId_GetHoldEffectParam(gLastUsedItem); - } - switch (bankHoldEffect) - { - case HOLD_EFFECT_CURE_PAR: - if (gBattleMons[bank].status1 & STATUS_PARALYSIS) - { - gBattleMons[bank].status1 &= ~(STATUS_PARALYSIS); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_BerryCureParRet; - effect = ITEM_STATUS_CHANGE; - } - break; - case HOLD_EFFECT_CURE_PSN: - if (gBattleMons[bank].status1 & STATUS_PSN_ANY) - { - gBattleMons[bank].status1 &= ~(STATUS_PSN_ANY | STATUS_TOXIC_COUNTER); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_BerryCurePsnRet; - effect = ITEM_STATUS_CHANGE; - } - break; - case HOLD_EFFECT_CURE_BRN: - if (gBattleMons[bank].status1 & STATUS_BURN) - { - gBattleMons[bank].status1 &= ~(STATUS_BURN); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_BerryCureBrnRet; - effect = ITEM_STATUS_CHANGE; - } - break; - case HOLD_EFFECT_CURE_FRZ: - if (gBattleMons[bank].status1 & STATUS_FREEZE) - { - gBattleMons[bank].status1 &= ~(STATUS_FREEZE); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_BerryCureFrzRet; - effect = ITEM_STATUS_CHANGE; - } - break; - case HOLD_EFFECT_CURE_SLP: - if (gBattleMons[bank].status1 & STATUS_SLEEP) - { - gBattleMons[bank].status1 &= ~(STATUS_SLEEP); - gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_BerryCureSlpRet; - effect = ITEM_STATUS_CHANGE; - } - break; - case HOLD_EFFECT_CURE_CONFUSION: - if (gBattleMons[bank].status2 & STATUS2_CONFUSION) - { - gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_BerryCureConfusionRet; - effect = ITEM_EFFECT_OTHER; - } - break; - case HOLD_EFFECT_CURE_ATTRACT: - if (gBattleMons[bank].status2 & STATUS2_INFATUATION) - { - gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION); - StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); - BattleScriptPushCursor(); - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet; - effect = ITEM_EFFECT_OTHER; - } - break; - case HOLD_EFFECT_CURE_STATUS: - if (gBattleMons[bank].status1 & STATUS_ANY || gBattleMons[bank].status2 & STATUS2_CONFUSION) - { - if (gBattleMons[bank].status1 & STATUS_PSN_ANY) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); - } - if (gBattleMons[bank].status1 & STATUS_SLEEP) - { - gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); - StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); - } - if (gBattleMons[bank].status1 & STATUS_PARALYSIS) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); - } - if (gBattleMons[bank].status1 & STATUS_BURN) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); - } - if (gBattleMons[bank].status1 & STATUS_FREEZE) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); - } - if (gBattleMons[bank].status2 & STATUS2_CONFUSION) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn); - } - gBattleMons[bank].status1 = 0; - gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); - BattleScriptPushCursor(); - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet; - effect = ITEM_STATUS_CHANGE; - } - break; - case HOLD_EFFECT_RESTORE_STATS: - for (i = 0; i < 8; i++) - { - if (gBattleMons[bank].statStages[i] < 6) - { - gBattleMons[bank].statStages[i] = 6; - effect = ITEM_STATS_CHANGE; - } - } - if (effect) - { - gBattleStruct->scriptingActive = bank; - gStringBank = bank; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_WhiteHerbRet; - return effect; // unnecessary return - } - break; - } - if (effect) - { - gBattleStruct->scriptingActive = bank; - gStringBank = bank; - gActiveBattler = bank; - EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); - MarkBufferBankForExecution(gActiveBattler); - break; - } - } - break; - case 4: - if (gBattleMoveDamage) - { - switch (atkHoldEffect) - { - case HOLD_EFFECT_FLINCH: - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) - && (Random() % 100) < bankQuality - && gBattleMoves[gCurrentMove].flags & F_AFFECTED_BY_KINGS_ROCK - && gBattleMons[gBankTarget].hp) - { - gBattleCommunication[MOVE_EFFECT_BYTE] = 8; - BattleScriptPushCursor(); - SetMoveEffect(0, 0); - BattleScriptPop(); - } - break; - case HOLD_EFFECT_SHELL_BELL: - if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) - && gSpecialStatuses[gBankTarget].moveturnLostHP != 0 - && gSpecialStatuses[gBankTarget].moveturnLostHP != 0xFFFF - && gBankAttacker != gBankTarget - && gBattleMons[gBankAttacker].hp != gBattleMons[gBankAttacker].maxHP - && gBattleMons[gBankAttacker].hp != 0) - { - gLastUsedItem = atkItem; - gStringBank = gBankAttacker; - gBattleStruct->scriptingActive = gBankAttacker; - gBattleMoveDamage = (gSpecialStatuses[gBankTarget].moveturnLostHP / atkQuality) * -1; - if (gBattleMoveDamage == 0) - gBattleMoveDamage = -1; - gSpecialStatuses[gBankTarget].moveturnLostHP = 0; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_ItemHealHP_Ret; - effect++; - } - break; - } - } - break; - } - - return effect; -} - -struct CombinedMove -{ - u16 move1; - u16 move2; - u16 newMove; -}; - -static const struct CombinedMove sCombinedMoves[2] = -{ - {MOVE_EMBER, MOVE_GUST, MOVE_HEAT_WAVE}, - {0xFFFF, 0xFFFF, 0xFFFF} -}; - -void unref_sub_801B40C(void) -{ - int i = 0; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - do - { - u8 bank = 0; - do - { - u8 absent = gAbsentBattlerFlags; - if (gBitTable[bank] & absent || absent & gBitTable[bank + 2]) - bank++; - else - { - if (sCombinedMoves[i].move1 == gChosenMovesByBanks[bank] && sCombinedMoves[i].move2 == gChosenMovesByBanks[bank + 2]) - { - gSideTimers[GetBattlerPosition(bank) & 1].field3 = (bank) | ((bank + 2) << 4); - gSideTimers[GetBattlerPosition(bank) & 1].field4 = sCombinedMoves[i].newMove; - gSideAffecting[GetBattlerPosition(bank) & 1] |= SIDE_STATUS_X4; - } - if (sCombinedMoves[i].move1 == gChosenMovesByBanks[bank + 2] && sCombinedMoves[i].move2 == gChosenMovesByBanks[bank]) - { - gSideTimers[GetBattlerPosition(bank) & 1].field3 = (bank + 2) | ((bank) << 4); - gSideTimers[GetBattlerPosition(bank) & 1].field4 = sCombinedMoves[i].newMove; - gSideAffecting[GetBattlerPosition(bank) & 1] |= SIDE_STATUS_X4; - } - bank++; - } - } while (bank < 2); - i++; - } while (sCombinedMoves[i].move1 != 0xFFFF); - } -} - -void sub_801B594(void) -{ - if (gBattleExecBuffer == 0) - gBattleScriptingCommandsTable[*gBattlescriptCurrInstr](); -} - -u8 GetMoveTarget(u16 move, u8 useMoveTarget) //get move target -{ - u8 targetBank = 0; - u8 moveTarget; - u8 side; - - if (useMoveTarget) - moveTarget = useMoveTarget - 1; - else - moveTarget = gBattleMoves[move].target; - - switch (moveTarget) - { - case 0: - side = GetBattlerSide(gBankAttacker) ^ 1; - if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp) - targetBank = gSideTimers[side].followmeTarget; - else - { - side = GetBattlerSide(gBankAttacker); - do - { - targetBank = Random() % gBattlersCount; - } while (targetBank == gBankAttacker || side == GetBattlerSide(targetBank) || gAbsentBattlerFlags & gBitTable[targetBank]); - if (gBattleMoves[move].type == TYPE_ELECTRIC - && AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIZE, gBankAttacker, ABILITY_LIGHTNING_ROD, 0, 0) - && gBattleMons[targetBank].ability != ABILITY_LIGHTNING_ROD) - { - targetBank ^= 2; - RecordAbilityBattle(targetBank, gBattleMons[targetBank].ability); - gSpecialStatuses[targetBank].lightningRodRedirected = 1; - } - } - break; - case 1: - case 8: - case 32: - case 64: - targetBank = GetBattlerAtPosition((GetBattlerPosition(gBankAttacker) & 1) ^ 1); - if (gAbsentBattlerFlags & gBitTable[targetBank]) - targetBank ^= 2; - break; - case 4: - side = GetBattlerSide(gBankAttacker) ^ 1; - if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp) - targetBank = gSideTimers[side].followmeTarget; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && moveTarget & 4) - { - if (GetBattlerSide(gBankAttacker) == 0) - { - if (Random() & 1) - targetBank = GetBattlerAtPosition(1); - else - targetBank = GetBattlerAtPosition(3); - } - else - { - if (Random() & 1) - targetBank = GetBattlerAtPosition(0); - else - targetBank = GetBattlerAtPosition(2); - } - if (gAbsentBattlerFlags & gBitTable[targetBank]) - targetBank ^= 2; - } - else - targetBank = GetBattlerAtPosition((GetBattlerPosition(gBankAttacker) & 1) ^ 1); - break; - case 2: - case 16: - targetBank = gBankAttacker; - break; - } - ewram16010arr(gBankAttacker) = targetBank; - return targetBank; -} - -u8 IsMonDisobedient(void) -{ - u8 obedienceLevel; - s32 rnd; - s32 calc; - - if (gBattleTypeFlags & BATTLE_TYPE_LINK - || GetBattlerSide(gBankAttacker) == 1 - || !IsOtherTrainer(gBattleMons[gBankAttacker].otId, gBattleMons[gBankAttacker].otName)) - return 0; - - if (DEBUG && (gUnknown_02023A14_50 & 0x40)) - { - obedienceLevel = 10; - } - else - { - if (FlagGet(FLAG_BADGE08_GET)) - return 0; - obedienceLevel = 10; - if (FlagGet(FLAG_BADGE02_GET)) - obedienceLevel = 30; - if (FlagGet(FLAG_BADGE04_GET)) - obedienceLevel = 50; - if (FlagGet(FLAG_BADGE06_GET)) - obedienceLevel = 70; - } - - if (gBattleMons[gBankAttacker].level <= obedienceLevel) - return 0; - rnd = (Random() & 255); - calc = (gBattleMons[gBankAttacker].level + obedienceLevel) * rnd >> 8; - if (calc < obedienceLevel) - return 0; - - // is not obedient - if (gCurrentMove == MOVE_RAGE) - gBattleMons[gBankAttacker].status2 &= ~(STATUS2_RAGE); - if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP && (gCurrentMove == MOVE_SNORE || gCurrentMove == MOVE_SLEEP_TALK)) - { - gBattlescriptCurrInstr = gUnknown_081D995F; - return 1; - } - - rnd = (Random() & 255); - calc = (gBattleMons[gBankAttacker].level + obedienceLevel) * rnd >> 8; - if (calc < obedienceLevel) - { - calc = CheckMoveLimitations(gBankAttacker, gBitTable[gCurrMovePos], 0xFF); - if (calc == 0xF) // all moves cannot be used - { - gBattleCommunication[MULTISTRING_CHOOSER] = Random() & 3; - gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; - return 1; - } - else // use a random move - { - do - { - gCurrMovePos = gUnknown_02024BE5 = Random() & 3; - } while (gBitTable[gCurrMovePos] & calc); - gRandomMove = gBattleMons[gBankAttacker].moves[gCurrMovePos]; - gBattleCommunication[3] = 0; - gDynamicBasePower = 0; - gBattleStruct->dynamicMoveType = 0; - gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove; - gBankTarget = GetMoveTarget(gRandomMove, 0); - gHitMarker |= HITMARKER_x200000; - return 2; - } - } - else - { - obedienceLevel = gBattleMons[gBankAttacker].level - obedienceLevel; - - calc = (Random() & 255); - if (calc < obedienceLevel && !(gBattleMons[gBankAttacker].status1 & STATUS_ANY) && gBattleMons[gBankAttacker].ability != ABILITY_VITAL_SPIRIT && gBattleMons[gBankAttacker].ability != ABILITY_INSOMNIA) - { - // try putting asleep - int i; - for (i = 0; i < gBattlersCount; i++) - { - if (gBattleMons[i].status2 & STATUS2_UPROAR) - break; - } - if (i == gBattlersCount) - { - gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep; - return 1; - } - } - calc -= obedienceLevel; - if (calc < obedienceLevel) - { - gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankAttacker], MOVE_POUND, 0, 40, 0, gBankAttacker, gBankAttacker); - gBankTarget = gBankAttacker; - gBattlescriptCurrInstr = gUnknown_081D99A0; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - return 2; - } - else - { - gBattleCommunication[MULTISTRING_CHOOSER] = Random() & 3; - gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; - return 1; - } - } -} diff --git a/src/battle/calculate_base_damage.c b/src/battle/calculate_base_damage.c deleted file mode 100644 index e4ae70c0b..000000000 --- a/src/battle/calculate_base_damage.c +++ /dev/null @@ -1,338 +0,0 @@ -#include "global.h" -#include "constants/abilities.h" -#include "constants/battle_move_effects.h" -#include "constants/hold_effects.h" -#include "constants/items.h" -#include "constants/moves.h" -#include "constants/species.h" -#include "battle.h" -#include "berry.h" -#include "data2.h" -#include "event_data.h" -#include "item.h" -#include "pokemon.h" -#include "ewram.h" - -extern u16 gBattleTypeFlags; -extern struct BattlePokemon gBattleMons[4]; -extern u16 gCurrentMove; -extern u8 gCritMultiplier; -extern u16 gBattleWeather; -extern struct BattleEnigmaBerry gEnigmaBerries[]; -extern u16 gBattleMovePower; -extern u16 gTrainerBattleOpponent; - -// Masks for getting PP Up count, also PP Max values -const u8 gPPUpReadMasks[] = {0x03, 0x0c, 0x30, 0xc0}; - -// Masks for setting PP Up count -const u8 gPPUpWriteMasks[] = {0xFC, 0xF3, 0xCF, 0x3F}; - -// Values added to PP Up count -const u8 gPPUpValues[] = {0x01, 0x04, 0x10, 0x40}; - -const u8 gStatStageRatios[][2] = -{ - {10, 40}, // -6 - {10, 35}, // -5 - {10, 30}, // -4 - {10, 25}, // -3 - {10, 20}, // -2 - {10, 15}, // -1 - {10, 10}, // 0 - {15, 10}, // 1 - {20, 10}, // 2 - {25, 10}, // 3 - {30, 10}, // 4 - {35, 10}, // 5 - {40, 10} // 6 -}; - -const u8 unknownGameFreakAbbrev_820825E[] = _("ゲーフリ"); - -const u8 gHoldEffectToType[][2] = -{ - {HOLD_EFFECT_BUG_POWER, TYPE_BUG}, - {HOLD_EFFECT_STEEL_POWER, TYPE_STEEL}, - {HOLD_EFFECT_GROUND_POWER, TYPE_GROUND}, - {HOLD_EFFECT_ROCK_POWER, TYPE_ROCK}, - {HOLD_EFFECT_GRASS_POWER, TYPE_GRASS}, - {HOLD_EFFECT_DARK_POWER, TYPE_DARK}, - {HOLD_EFFECT_FIGHTING_POWER, TYPE_FIGHTING}, - {HOLD_EFFECT_ELECTRIC_POWER, TYPE_ELECTRIC}, - {HOLD_EFFECT_WATER_POWER, TYPE_WATER}, - {HOLD_EFFECT_FLYING_POWER, TYPE_FLYING}, - {HOLD_EFFECT_POISON_POWER, TYPE_POISON}, - {HOLD_EFFECT_ICE_POWER, TYPE_ICE}, - {HOLD_EFFECT_GHOST_POWER, TYPE_GHOST}, - {HOLD_EFFECT_PSYCHIC_POWER, TYPE_PSYCHIC}, - {HOLD_EFFECT_FIRE_POWER, TYPE_FIRE}, - {HOLD_EFFECT_DRAGON_POWER, TYPE_DRAGON}, - {HOLD_EFFECT_NORMAL_POWER, TYPE_NORMAL} -}; - -u8 GetBattlerSide(u8 bank); - -#define APPLY_STAT_MOD(var, mon, stat, statIndex) \ -{ \ - (var) = (stat) * (gStatStageRatios)[(mon)->statStages[(statIndex)]][0]; \ - (var) /= (gStatStageRatios)[(mon)->statStages[(statIndex)]][1]; \ -} - -#define BADGE_BOOST(badge, stat, bank) ({ \ -if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER))) \ -{ \ - if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) \ - && gTrainerBattleOpponent != SECRET_BASE_OPPONENT \ - && FlagGet(FLAG_BADGE0##badge##_GET) \ - && GetBattlerSide(bank) == B_SIDE_PLAYER) \ - (stat) = (110 * (stat)) / 100; \ -} \ -}) - -s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 sideStatus, u16 powerOverride, u8 typeOverride, u8 bankAtk, u8 bankDef) -{ - u32 i; - s32 damage = 0; - s32 damageHelper; - u8 type; - u16 attack, defense; - u16 spAttack, spDefense; - u8 defenderHoldEffect; - u8 defenderHoldEffectParam; - u8 attackerHoldEffect; - u8 attackerHoldEffectParam; - - if (!powerOverride) - gBattleMovePower = gBattleMoves[move].power; - else - gBattleMovePower = powerOverride; - - if (!typeOverride) - type = gBattleMoves[move].type; - else - type = typeOverride & 0x3F; - - attack = attacker->attack; - defense = defender->defense; - spAttack = attacker->spAttack; - spDefense = defender->spDefense; - - if (attacker->item == ITEM_ENIGMA_BERRY) - { - attackerHoldEffect = gEnigmaBerries[bankAtk].holdEffect; - attackerHoldEffectParam = gEnigmaBerries[bankAtk].holdEffectParam; - } - else - { - attackerHoldEffect = ItemId_GetHoldEffect(attacker->item); - attackerHoldEffectParam = ItemId_GetHoldEffectParam(attacker->item); - } - - if (defender->item == ITEM_ENIGMA_BERRY) - { - defenderHoldEffect = gEnigmaBerries[bankDef].holdEffect; - defenderHoldEffectParam = gEnigmaBerries[bankDef].holdEffectParam; - } - else - { - defenderHoldEffect = ItemId_GetHoldEffect(defender->item); - defenderHoldEffectParam = ItemId_GetHoldEffectParam(defender->item); - } - - if (attacker->ability == ABILITY_HUGE_POWER || attacker->ability == ABILITY_PURE_POWER) - attack *= 2; - - BADGE_BOOST(1, attack, bankAtk); - BADGE_BOOST(5, defense, bankDef); - BADGE_BOOST(7, spAttack, bankAtk); - BADGE_BOOST(7, spDefense, bankDef); - - for (i = 0; i < 17; i++) - { - if (attackerHoldEffect == gHoldEffectToType[i][0] - && type == gHoldEffectToType[i][1]) - { - if (TYPE_IS_PHYSICAL(type)) - attack = (attack * (attackerHoldEffectParam + 100)) / 100; - else - spAttack = (spAttack * (attackerHoldEffectParam + 100)) / 100; - break; - } - } - - if (attackerHoldEffect == HOLD_EFFECT_CHOICE_BAND) - attack = (150 * attack) / 100; - if (attackerHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) && (attacker->species == SPECIES_LATIAS || attacker->species == SPECIES_LATIOS)) - spAttack = (150 * spAttack) / 100; - if (defenderHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) && (defender->species == SPECIES_LATIAS || defender->species == SPECIES_LATIOS)) - spDefense = (150 * spDefense) / 100; - if (attackerHoldEffect == HOLD_EFFECT_DEEP_SEA_TOOTH && attacker->species == SPECIES_CLAMPERL) - spAttack *= 2; - if (defenderHoldEffect == HOLD_EFFECT_DEEP_SEA_SCALE && defender->species == SPECIES_CLAMPERL) - spDefense *= 2; - if (attackerHoldEffect == HOLD_EFFECT_LIGHT_BALL && attacker->species == SPECIES_PIKACHU) - spAttack *= 2; - if (defenderHoldEffect == HOLD_EFFECT_METAL_POWDER && defender->species == SPECIES_DITTO) - defense *= 2; - if (attackerHoldEffect == HOLD_EFFECT_THICK_CLUB && (attacker->species == SPECIES_CUBONE || attacker->species == SPECIES_MAROWAK)) - attack *= 2; - if (defender->ability == ABILITY_THICK_FAT && (type == TYPE_FIRE || type == TYPE_ICE)) - spAttack /= 2; - if (attacker->ability == ABILITY_HUSTLE) - attack = (150 * attack) / 100; - if (attacker->ability == ABILITY_PLUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MINUS, 0, 0)) - spAttack = (150 * spAttack) / 100; - if (attacker->ability == ABILITY_MINUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_PLUS, 0, 0)) - spAttack = (150 * spAttack) / 100; - if (attacker->ability == ABILITY_GUTS && attacker->status1) - attack = (150 * attack) / 100; - if (defender->ability == ABILITY_MARVEL_SCALE && defender->status1) - defense = (150 * defense) / 100; - if (type == TYPE_ELECTRIC && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFD, 0)) - gBattleMovePower /= 2; - if (type == TYPE_FIRE && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFE, 0)) - gBattleMovePower /= 2; - if (type == TYPE_GRASS && attacker->ability == ABILITY_OVERGROW && attacker->hp <= (attacker->maxHP / 3)) - gBattleMovePower = (150 * gBattleMovePower) / 100; - if (type == TYPE_FIRE && attacker->ability == ABILITY_BLAZE && attacker->hp <= (attacker->maxHP / 3)) - gBattleMovePower = (150 * gBattleMovePower) / 100; - if (type == TYPE_WATER && attacker->ability == ABILITY_TORRENT && attacker->hp <= (attacker->maxHP / 3)) - gBattleMovePower = (150 * gBattleMovePower) / 100; - if (type == TYPE_BUG && attacker->ability == ABILITY_SWARM && attacker->hp <= (attacker->maxHP / 3)) - gBattleMovePower = (150 * gBattleMovePower) / 100; - if (gBattleMoves[gCurrentMove].effect == EFFECT_EXPLOSION) - defense /= 2; - - if (TYPE_IS_PHYSICAL(type)) // type < TYPE_MYSTERY - { - if (gCritMultiplier == 2) - { - if (attacker->statStages[STAT_STAGE_ATK] > 6) - APPLY_STAT_MOD(damage, attacker, attack, STAT_STAGE_ATK) - else - damage = attack; - } - else - APPLY_STAT_MOD(damage, attacker, attack, STAT_STAGE_ATK) - - damage = damage * gBattleMovePower; - damage *= (2 * attacker->level / 5 + 2); - - if (gCritMultiplier == 2) - { - if (defender->statStages[STAT_STAGE_DEF] < 6) - APPLY_STAT_MOD(damageHelper, defender, defense, STAT_STAGE_DEF) - else - damageHelper = defense; - } - else - APPLY_STAT_MOD(damageHelper, defender, defense, STAT_STAGE_DEF) - - damage = damage / damageHelper; - damage /= 50; - - if ((attacker->status1 & STATUS_BURN) && attacker->ability != ABILITY_GUTS) - damage /= 2; - - if ((sideStatus & SIDE_STATUS_REFLECT) && gCritMultiplier == 1) - { - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMons(2) == 2) - damage = 2 * (damage / 3); - else - damage /= 2; - } - - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMons(2) == 2) - damage /= 2; - - // moves always do at least 1 damage. - if (damage == 0) - damage = 1; - } - - if (type == TYPE_MYSTERY) - damage = 0; // is ??? type. does 0 damage. - - if (TYPE_IS_SPECIAL(type)) // type > TYPE_MYSTERY - { - if (gCritMultiplier == 2) - { - if (attacker->statStages[STAT_STAGE_SPATK] > 6) - APPLY_STAT_MOD(damage, attacker, spAttack, STAT_STAGE_SPATK) - else - damage = spAttack; - } - else - APPLY_STAT_MOD(damage, attacker, spAttack, STAT_STAGE_SPATK) - - damage = damage * gBattleMovePower; - damage *= (2 * attacker->level / 5 + 2); - - if (gCritMultiplier == 2) - { - if (defender->statStages[STAT_STAGE_SPDEF] < 6) - APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_STAGE_SPDEF) - else - damageHelper = spDefense; - } - else - APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_STAGE_SPDEF) - - damage = (damage / damageHelper); - damage /= 50; - - if ((sideStatus & SIDE_STATUS_LIGHTSCREEN) && gCritMultiplier == 1) - { - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMons(2) == 2) - damage = 2 * (damage / 3); - else - damage /= 2; - } - - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMons(2) == 2) - damage /= 2; - - // are effects of weather negated with cloud nine or air lock - if (!AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_CLOUD_NINE, 0, 0) - && !AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_AIR_LOCK, 0, 0)) - { - if (gBattleWeather & WEATHER_RAIN_TEMPORARY) - { - switch (type) - { - case TYPE_FIRE: - damage /= 2; - break; - case TYPE_WATER: - damage = (15 * damage) / 10; - break; - } - } - - // any weather except sun weakens solar beam - if ((gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_HAIL)) && gCurrentMove == MOVE_SOLAR_BEAM) - damage /= 2; - - // sunny - if (gBattleWeather & WEATHER_SUN_ANY) - { - switch (type) - { - case TYPE_FIRE: - damage = (15 * damage) / 10; - break; - case TYPE_WATER: - damage /= 2; - break; - } - } - } - - // flash fire triggered - if ((eFlashFireArr.arr[bankAtk] & 1) && type == TYPE_FIRE) - damage = (15 * damage) / 10; - } - - return damage + 2; -} diff --git a/src/battle/contest_link_80C2020.c b/src/battle/contest_link_80C2020.c deleted file mode 100644 index 2dde3895c..000000000 --- a/src/battle/contest_link_80C2020.c +++ /dev/null @@ -1,2906 +0,0 @@ -#include "global.h" -#include "data2.h" -#include "util.h" -#include "random.h" -#include "overworld.h" -#include "constants/songs.h" -#include "ewram.h" -#include "main.h" -#include "scanline_effect.h" -#include "decompress.h" -#include "palette.h" -#include "blend_palette.h" -#include "graphics.h" -#include "strings2.h" -#include "text.h" -#include "string_util.h" -#include "menu.h" -#include "sound.h" -#include "pokedex.h" -#include "pokemon_icon.h" -#include "tv.h" -#include "battle.h" -#include "contest.h" -#include "link.h" -#include "field_effect.h" -#include "field_specials.h" -#include "contest_link_80C857C.h" -#include "contest_link_80C2020.h" -#include "pokemon_storage_system.h" -#include "event_data.h" -#include "script.h" -#include "trig.h" - -#define ABS(x) ((x) < 0 ? -(x) : (x)) - -#define GET_CONTEST_WINNER(var) { \ - for ((var) = 0; (var) < 4; (var)++) \ - { \ - if (gContestFinalStandings[i] == 0) \ - break; \ - } \ -} - -struct UnkEwramStruct18000 { - u8 unk_00; - u8 unk_01; - u8 unk_02; - u8 unk_03; - u8 unk_04; - u8 unk_05; - u8 unk_06; - u8 unk_07; - u8 unk_08; - u8 unk_09; - u8 unk_0a; - s16 unk_0c[4]; - u8 unk_14; -}; - -struct UnkEwramStruct18018 { - s32 unk_00; - s32 unk_04; - u32 unk_08; - u32 unk_0c; - u8 unk_10; - u8 unk_11; - u8 unk_12; -}; - -#define eContestLink80C2020Struct2018000 (*(struct UnkEwramStruct18000 *)(gSharedMem + 0x18000)) -#define eContestLink80C2020Struct2018018 ((struct UnkEwramStruct18018 *)(gSharedMem + 0x18018)) -#define eContestLink80C2020Struct2018068 (gSharedMem + 0x18068) - -static void sub_80C2430(void); -static void sub_80C2448(void); -static void sub_80C24F4(u8 taskId); -static void sub_80C255C(u8 taskId); -static void sub_80C25A4(u8 taskId); -static void sub_80C25C0(u8 taskId); -static void sub_80C2600(u8 taskId); -static void sub_80C26E4(u8 taskId); -static void sub_80C2770(u8 taskId); -static void sub_80C27EC(u8 taskId); -static void sub_80C2878(u8 taskId); -static void sub_80C2A8C(u8 taskId); -static void sub_80C2D1C(u8 taskId); -static void sub_80C2D80(u8 taskId); -static void sub_80C2DD8(u8 taskId); -static void sub_80C2E14(u8 taskId); -static void sub_80C2EA0(u8 taskId); -static void sub_80C2F28(u8 taskId); -static void sub_80C2F64(u8 taskId); -static void LoadAllContestMonIcons(u8 srcOffset, bool8 useDmaNow); -void sub_80C310C(void); -void sub_80C3158(const u8 *string, u8 spriteId); -void sub_80C33DC(void); -u16 sub_80C34AC(const u8 *string); -void sub_80C34CC(s16 data4, u16 pos0y, u16 data5, u16 data6); -void sub_80C3520(u16 a0); -void sub_80C3588(struct Sprite *sprite); -void sub_80C35FC(struct Sprite *sprite); -void sub_80C3630(struct Sprite *sprite); -void sub_80C3698(const u8 *string); -void sub_80C3764(void); -void sub_80C37E4(void); -u8 sub_80C3990(u8 a0, u8 a1); -s8 sub_80C39E4(u8 a0, u8 a1); -void sub_80C3A5C(u8 taskId); -void sub_80C3BD8(u8 taskId); -void sub_80C3B30(u8 taskId); -void sub_80C3C44(struct Sprite *sprite); -void sub_80C3CB8(struct Sprite *sprite); -void sub_80C3D04(u8 taskId); -void sub_80C3DF0(struct Sprite *sprite); -void sub_80C3E60(u8 a0, u8 a1); -void sub_80C3EA4(u8 taskId); -void sub_80C3F00(void); -void sub_80C40D4(u8 a0, u8 a1); -void sub_80C42C0(u8 taskId); -void sub_80C49C4(u8 taskId); -void sub_80C49F0(u8 taskId); -void sub_80C4A0C(u8 taskId); -void sub_80C4A28(u8 taskId); -void sub_80C4A44(u8 taskId); -void sub_80C4B0C(u8 taskId); -void sub_80C4B5C(u8 taskId); -void sub_80C4BA4(u8 taskId); -void sub_80C4BCC(u8 taskId); - -const u16 gUnknown_083D1624[] = INCBIN_U16("graphics/unknown/unknown_3D1624/0.4bpp"); -const u16 gUnknown_083D1644[] = INCBIN_U16("graphics/unknown/unknown_3D1624/1.4bpp"); -const u16 gUnknown_083D1664[] = INCBIN_U16("graphics/unknown/unknown_3D1624/2.4bpp"); -const u16 gUnknown_083D1684[] = INCBIN_U16("graphics/unknown/unknown_3D1624/3.4bpp"); -const u16 gUnknown_083D16A4[] = INCBIN_U16("graphics/unknown/unknown_3D1624/4.4bpp"); -const u16 gUnknown_083D16C4[] = INCBIN_U16("graphics/unknown/unknown_3D1624/5.4bpp"); -const u16 gUnknown_083D16E4[] = INCBIN_U16("graphics/unknown/unknown_3D1624/6.4bpp"); -const u16 gUnknown_083D1704[] = INCBIN_U16("graphics/unknown/unknown_3D1624/7.4bpp"); -const u16 gMiscBlank_Pal[] = INCBIN_U16("graphics/interface/blank.gbapal"); - -const struct OamData gOamData_83D1744 = { - .shape = ST_OAM_H_RECTANGLE, - .size = 3, - .priority = 3, - .paletteNum = 2 -}; - -const struct SpriteTemplate gSpriteTemplate_83D174C = { - 0xbc1, - 0xbc1, - &gOamData_83D1744, - gDummySpriteAnimTable, - NULL, - gDummySpriteAffineAnimTable, - SpriteCallbackDummy -}; - -const struct SpriteSheet gUnknown_083D1764[] = { - {gMiscBlank_Gfx, 0x400, 0xbc1}, - {gMiscBlank_Gfx, 0x400, 0xbc2}, - {gMiscBlank_Gfx, 0x400, 0xbc3}, - {gMiscBlank_Gfx, 0x400, 0xbc4}, - {gMiscBlank_Gfx, 0x400, 0xbc5}, - {gMiscBlank_Gfx, 0x400, 0xbc6}, - {gMiscBlank_Gfx, 0x400, 0xbc7}, - {gMiscBlank_Gfx, 0x400, 0xbc8}, -}; - -const struct SpritePalette gUnknown_083D17A4 = { - gMiscBlank_Pal, 0xbc1 -}; - -const struct OamData gOamData_83D17AC = {}; - -const struct SpriteTemplate gSpriteTemplate_83D17B4 = { - 0xbc9, - 0xbc9, - &gOamData_83D17AC, - gDummySpriteAnimTable, - NULL, - gDummySpriteAffineAnimTable, - sub_80C3DF0 -}; - -const struct CompressedSpriteSheet gUnknown_083D17CC = {gContestConfetti_Gfx, 0x220, 0xbc9}; - -const struct CompressedSpritePalette gUnknown_083D17D4 = {gContestConfetti_Pal, 0xbc9}; - -const u8 gUnknown_083D17DC[] = _("{COLOR RED}"); -const u8 gUnknown_083D17E0[] = _("/"); -const u8 gUnknown_083D17E2[] = _("{SIZE 3}{COLOR_HIGHLIGHT_SHADOW WHITE2 DARK_GREY LIGHT_BLUE}"); - -void sub_80C2020(void) -{ - REG_DISPCNT = DISPCNT_OBJ_1D_MAP; - Text_LoadWindowTemplate(&gWindowTemplate_81E6FA0); - Text_InitWindowWithTemplate(&gMenuWindow, &gWindowTemplate_81E6FA0); - REG_BG0CNT = BGCNT_WRAP | BGCNT_SCREENBASE(30); - REG_BG1CNT = BGCNT_PRIORITY(3) | BGCNT_SCREENBASE(24); - REG_BG2CNT = BGCNT_PRIORITY(3) | BGCNT_SCREENBASE(28); - REG_BG3CNT = BGCNT_WRAP | BGCNT_PRIORITY(3) | BGCNT_SCREENBASE(26); - REG_MOSAIC = 0; - REG_WININ = 0x3f3f; - REG_WINOUT = 0x3f2e; - REG_WIN0H = 0; - REG_WIN0V = 0; - REG_WIN1H = 0; - REG_WIN1V = 0; - REG_BLDCNT = 0; - REG_BLDALPHA = 0; - REG_BLDY = 0; - REG_BG0HOFS = 0; - REG_BG0VOFS = 0; - REG_BG1HOFS = 0; - REG_BG1VOFS = 0; - REG_BG2HOFS = 0; - REG_BG2VOFS = 0; - REG_BG3HOFS = 0; - REG_BG3VOFS = 0; - REG_DISPCNT |= DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON | DISPCNT_WIN0_ON | DISPCNT_WIN1_ON; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gBattle_BG1_X = 0; - gBattle_BG1_Y = 0; - gBattle_BG2_X = 0; - gBattle_BG2_Y = 0; - gBattle_BG3_X = 0; - gBattle_BG3_Y = 0; - gBattle_WIN0H = 0; - gBattle_WIN0V = 0; - gBattle_WIN1H = 0; - gBattle_WIN1V = 0; -} - -void sub_80C2144(void) -{ - int i; - int j; - s8 r7; - s8 r4; - u16 r6; - u16 r3; - - DmaFill32Large(3, 0, VRAM, VRAM_SIZE, 0x1000); - LZDecompressVram(gUnknown_08D1977C, BG_SCREEN_ADDR(0)); - LZDecompressVram(gUnknown_08D1A490, BG_SCREEN_ADDR(26)); - LZDecompressVram(gUnknown_08D1A364, BG_SCREEN_ADDR(28)); - LZDecompressVram(gUnknown_08D1A250, BG_SCREEN_ADDR(30)); - sub_80C37E4(); - LoadCompressedPalette(gUnknown_08D1A618, 0, 0x200); - LoadFontDefaultPalette(&gWindowTemplate_81E6FA0); - for (i = 0; i < 4; i++) - { - r7 = sub_80C3990(i, 1); - r4 = sub_80C39E4(i, 1); - for (j = 0; j < 10; j++) - { - r6 = 0x60b2; - if (j < r7) - r6 = 0x60b4; - if (j < ABS(r4)) - { - r3 = 0x60a4; - if (r4 < 0) - r3 = 0x60a6; - } - else - r3 = 0x60a2; - ((u16 *)BG_VRAM)[i * 0x60 + j + 0x60b3] = r6; - ((u16 *)BG_VRAM)[i * 0x60 + j + 0x60d3] = r3; - } - } -} - -void sub_80C226C(u8 a0) -{ - u8 *strbuf; - - if (a0 == gContestPlayerMonIndex) - strbuf = StringCopy(gDisplayedStringBattle, gUnknown_083D17DC); - else - strbuf = gDisplayedStringBattle; - strbuf[0] = EXT_CTRL_CODE_BEGIN; - strbuf[1] = 0x06; - strbuf[2] = 0x04; - strbuf += 3; - strbuf = StringCopy(strbuf, gContestMons[a0].nickname); - strbuf[0] = EXT_CTRL_CODE_BEGIN; - strbuf[1] = 0x13; - strbuf[2] = 0x32; - strbuf += 3; - strbuf = StringCopy(strbuf, gUnknown_083D17E0); - if (gIsLinkContest & 1) - StringCopy(strbuf, gLinkPlayers[a0].name); - else - StringCopy(strbuf, gContestMons[a0].trainerName); - Text_InitWindowAndPrintText(&gMenuWindow, gDisplayedStringBattle, a0 * 36 + 770, 7, a0 * 3 + 4); -} - -void sub_80C2340(void) -{ - int i; - - for (i = 0; i < 4; i++) - sub_80C226C(i); -} - -void sub_80C2358(void) -{ - gPaletteFade.bufferTransferDisabled = TRUE; - SetVBlankCallback(NULL); - sub_80C2020(); - ScanlineEffect_Clear(); - ResetPaletteFade(); - ResetSpriteData(); - ResetTasks(); - FreeAllSpritePalettes(); - sub_80C2144(); - sub_80C310C(); - LoadAllContestMonIcons(0, TRUE); - sub_80C2340(); - eContestLink80C2020Struct2018000 = (struct UnkEwramStruct18000){}; - memset(eContestLink80C2020Struct2018018, 0, 4 * sizeof(struct UnkEwramStruct18018)); - sub_80C33DC(); - BeginNormalPaletteFade(0xffffffff, 0, 16, 0, 0); - gPaletteFade.bufferTransferDisabled = FALSE; - eContestLink80C2020Struct2018000.unk_02 = CreateTask(sub_80C24F4, 5); - SetMainCallback2(sub_80C2430); - gBattle_WIN1H = 0xf0; - gBattle_WIN1V = 0x80a0; - CreateTask(sub_80C2F28, 20); - sub_80C3F00(); - PlayBGM(MUS_CON_K); - SetVBlankCallback(sub_80C2448); -} - -static void sub_80C2430(void) -{ - AnimateSprites(); - BuildOamBuffer(); - RunTasks(); - UpdatePaletteFade(); -} - -static void sub_80C2448(void) -{ - REG_BG0HOFS = gBattle_BG0_X; - REG_BG0VOFS = gBattle_BG0_Y; - REG_BG1HOFS = gBattle_BG1_X; - REG_BG1VOFS = gBattle_BG1_Y; - REG_BG2HOFS = gBattle_BG2_X; - REG_BG2VOFS = gBattle_BG2_Y; - REG_BG3HOFS = gBattle_BG3_X; - REG_BG3VOFS = gBattle_BG3_Y; - REG_WIN0H = gBattle_WIN0H; - REG_WIN0V = gBattle_WIN0V; - REG_WIN1H = gBattle_WIN1H; - REG_WIN1V = gBattle_WIN1V; - LoadOam(); - ProcessSpriteCopyRequests(); - TransferPlttBuffer(); - ScanlineEffect_InitHBlankDmaTransfer(); -} - -static void sub_80C24F4(u8 taskId) -{ - if (!gPaletteFade.active) - { - if (gIsLinkContest & 1) - { - sub_80C3698(gOtherText_LinkStandby); - gTasks[taskId].func = sub_80C255C; - } - else - { - gTasks[taskId].func = sub_80C2600; - } - } -} - -static void sub_80C255C(u8 taskId) -{ - if (gReceivedRemoteLinkPlayers && GetLinkPlayerCount() == MAX_LINK_PLAYERS) - { - CreateTask(sub_80C25A4, 0); - gTasks[taskId].func = TaskDummy; - } -} - -static void sub_80C25A4(u8 taskId) -{ - SetTaskFuncWithFollowupFunc(taskId, sub_80C89DC, sub_80C25C0); -} - -static void sub_80C25C0(u8 taskId) -{ - if (IsLinkTaskFinished()) - { - DestroyTask(taskId); - gTasks[eContestLink80C2020Struct2018000.unk_02].func = sub_80C2600; - sub_80C3764(); - } -} - -static void sub_80C2600(u8 taskId) -{ - if (gTasks[taskId].data[0] == 0) - { - CreateTask(sub_80C2F64, 20); - sub_80C3158(gContestText_AnnounceResults, eContestLink80C2020Struct2018000.unk_00); - sub_80C34CC(sub_80C34AC(gContestText_AnnounceResults), 0x90, 0x78, 0x440); - gTasks[taskId].data[0]++; - } - else if (gTasks[taskId].data[0] == 1) - { - if (eContestLink80C2020Struct2018000.unk_04 == 0) - { - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[0]++; - } - } - else if (gTasks[taskId].data[0] == 2) - { - if (++gTasks[taskId].data[1] == 0x15) - { - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[0]++; - } - } - else if (gTasks[taskId].data[0] == 3) - { - sub_80C3158(gContestText_PreliminaryResults, eContestLink80C2020Struct2018000.unk_00); - sub_80C34CC(sub_80C34AC(gContestText_PreliminaryResults), 0x90, 0xffff, 0x440); - gTasks[taskId].data[0]++; - } - else if (gTasks[taskId].data[0] == 4) - { - if (eContestLink80C2020Struct2018000.unk_04 == 2) - { - gTasks[taskId].data[0] = 0; - gTasks[taskId].func = sub_80C26E4; - } - } -} - -static void sub_80C26E4(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - case 0: - if (eContestLink80C2020Struct2018000.unk_0a == 0) - { - sub_80C40D4(0, gTasks[taskId].data[2]++); - if (eContestLink80C2020Struct2018000.unk_14 == 0) - { - gTasks[taskId].data[0] = 2; - } - else - { - gTasks[taskId].data[0]++; - } - } - break; - case 1: - if (eContestLink80C2020Struct2018000.unk_14 == 0) - { - gTasks[taskId].data[0] = 0; - } - break; - case 2: - sub_80C3520(0x440); - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[2] = 0; - gTasks[taskId].func = sub_80C2770; - break; - } -} - -static void sub_80C2770(u8 taskId) -{ - if (eContestLink80C2020Struct2018000.unk_04 == 0) - { - if (++gTasks[taskId].data[1] == 21) - { - gTasks[taskId].data[1] = 0; - sub_80C3158(gContestText_Round2Results, eContestLink80C2020Struct2018000.unk_00); - sub_80C34CC(sub_80C34AC(gContestText_Round2Results), 0x90, 0xffff, 0x440); - } - } - else if (eContestLink80C2020Struct2018000.unk_04 == 2) - { - gTasks[taskId].func = sub_80C27EC; - } -} - -static void sub_80C27EC(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - case 0: - if (eContestLink80C2020Struct2018000.unk_0a == 0) - { - sub_80C40D4(1, gTasks[taskId].data[2]++); - if (eContestLink80C2020Struct2018000.unk_14 == 0) - { - gTasks[taskId].data[0] = 2; - } - else - { - gTasks[taskId].data[0]++; - } - } - break; - case 1: - if (eContestLink80C2020Struct2018000.unk_14 == 0) - { - gTasks[taskId].data[0] = 0; - } - break; - case 2: - sub_80C3520(0x440); - gTasks[taskId].data[0] = 0; - gTasks[taskId].func = sub_80C2878; - break; - } -} - -static void sub_80C2878(u8 taskId) -{ - int i; - u8 taskId2; - u8 strbuf[100]; - - switch (gTasks[taskId].data[0]) - { - case 0: - if (eContestLink80C2020Struct2018000.unk_04 == 0) - gTasks[taskId].data[0]++; - break; - case 1: - if (++gTasks[taskId].data[1] == 31) - { - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[0]++; - } - break; - case 2: - for (i = 0; i < 4; i++) - { - taskId2 = CreateTask(sub_80C3A5C, 10); - gTasks[taskId2].data[0] = gContestFinalStandings[i]; - gTasks[taskId2].data[1] = i; - } - gTasks[taskId].data[0]++; - break; - case 3: - if (eContestLink80C2020Struct2018000.unk_05 == 4) - { - if (++gTasks[taskId].data[1] == 31) - { - gTasks[taskId].data[1] = 0; - CreateTask(sub_80C3B30, 10); - gTasks[taskId].data[0]++; - GET_CONTEST_WINNER(i); - sub_80C3E60(i, 14); - } - } - break; - case 4: - if (++gTasks[taskId].data[1] == 21) - { - gTasks[taskId].data[1] = 0; - GET_CONTEST_WINNER(i); - if (gIsLinkContest & 1) - { - StringCopy(gStringVar1, gLinkPlayers[i].name); - } - else - { - StringCopy(gStringVar1, gContestMons[i].trainerName); - } - StringCopy(gStringVar2, gContestMons[i].nickname); - StringExpandPlaceholders(strbuf, gContestText_PokeWon); - sub_80C3158(strbuf, eContestLink80C2020Struct2018000.unk_00); - sub_80C34CC(sub_80C34AC(strbuf), 0x90, 0xffff, 0x440); - gTasks[taskId].data[0]++; - } - break; - case 5: - gTasks[taskId].data[0] = 0; - gTasks[taskId].func = sub_80C2A8C; - break; - } -} - -static void sub_80C2A8C(u8 taskId) -{ - int i; - u8 spriteId; - u16 species; - u32 personality; - u32 otId; - const struct CompressedSpritePalette *monPal; - - switch (gTasks[taskId].data[0]) - { - case 0: - gBattle_WIN0H = 0xf0; - gBattle_WIN0V = 0x5050; - GET_CONTEST_WINNER(i); - species = gContestMons[i].species; - personality = gContestMons[i].personality; - otId = gContestMons[i].otId; - HandleLoadSpecialPokePic(gMonFrontPicTable + species, gMonFrontPicCoords[species].coords, gMonFrontPicCoords[species].y_offset, (intptr_t)gSharedMem, gUnknown_081FAF4C[1], species, personality); - monPal = GetMonSpritePalStructFromOtIdPersonality(species, otId, personality); - LoadCompressedObjectPalette(monPal); - GetMonSpriteTemplate_803C56C(species, 1); - gUnknown_02024E8C.paletteTag = monPal->tag; - spriteId = CreateSprite(&gUnknown_02024E8C, 0x110, 0x50, 10); - gSprites[spriteId].data[1] = species; - gSprites[spriteId].oam.priority = 0; - gSprites[spriteId].callback = sub_80C3C44; - eContestLink80C2020Struct2018000.unk_08 = spriteId; - LoadCompressedObjectPic(&gUnknown_083D17CC); - LoadCompressedObjectPalette(&gUnknown_083D17D4); - CreateTask(sub_80C3D04, 10); - gTasks[taskId].data[0]++; - break; - case 1: - if (++gTasks[taskId].data[3] == 1) - { - u8 win0v; - gTasks[taskId].data[3] = 0; - gTasks[taskId].data[2] += 2; - if (gTasks[taskId].data[2] > 0x20) - gTasks[taskId].data[2] = 0x20; - win0v = gTasks[taskId].data[2]; - gBattle_WIN0V = ((0x50 - win0v) << 8) | (0x50 + win0v); - if (win0v == 0x20) - { - gTasks[taskId].data[0]++; - } - } - break; - case 2: - if (eContestLink80C2020Struct2018000.unk_06 == 1) - { - gTasks[taskId].data[0]++; - } - break; - case 3: - if (++gTasks[taskId].data[1] == 121) - { - gTasks[taskId].data[1] = 0; - gSprites[eContestLink80C2020Struct2018000.unk_08].callback = sub_80C3CB8; - gTasks[taskId].data[0]++; - } - break; - case 4: - if (eContestLink80C2020Struct2018000.unk_06 == 2) - { - u8 win0v = (gBattle_WIN0V >> 8); - win0v += 2; - if (win0v > 0x50) - win0v = 0x50; - gBattle_WIN0V = (win0v << 8) | (0xa0 - win0v); - if (win0v == 0x50) - { - gTasks[taskId].data[0]++; - } - } - break; - case 5: - if (eContestLink80C2020Struct2018000.unk_06 == 2) - { - eContestLink80C2020Struct2018000.unk_09 = 1; - gTasks[taskId].data[0] = 0; - gTasks[taskId].func = sub_80C2D1C; - } - break; - } -} - -static void sub_80C2D1C(u8 taskId) -{ - int i; - - if (gMain.newKeys & A_BUTTON) - { - if (!(gIsLinkContest & 1)) - { - for (i = 0; i < 4; i++) - { - GetSetPokedexFlag(SpeciesToNationalPokedexNum(gContestMons[i].species), FLAG_SET_SEEN); - } - } - gTasks[taskId].func = sub_80C2D80; - } -} - -static void sub_80C2D80(u8 taskId) -{ - if (gIsLinkContest & 1) - { - sub_80C3698(gOtherText_LinkStandby); - sub_800832C(); - gTasks[taskId].func = sub_80C2DD8; - } - else - { - gTasks[taskId].func = sub_80C2E14; - } -} - -static void sub_80C2DD8(u8 taskId) -{ - if (gReceivedRemoteLinkPlayers == 0) - { - gIsLinkContest = 0; - sub_80C3764(); - gTasks[taskId].func = sub_80C2E14; - } -} - -static void sub_80C2E14(u8 taskId) -{ - sub_80BE284(gContestFinalStandings[gContestPlayerMonIndex]); - sub_810FB10(2); - Contest_SaveWinner(gSpecialVar_ContestRank); - Contest_SaveWinner(0xFE); - ewram15DDF = 1; - ewram15DDE = sub_80B2C4C(0xfe, 0); - BeginHardwarePaletteFade(0xff, 0, 0, 16, 0); - gTasks[taskId].func = sub_80C2EA0; -} - -static void sub_80C2EA0(u8 taskId) -{ - if (!gPaletteFade.active) - { - if (gTasks[taskId].data[1] == 0) - { - DestroyTask(eContestLink80C2020Struct2018000.unk_03); - BlendPalettes(0x0000ffff, 16, 0); - gTasks[taskId].data[1]++; - } - else if (gTasks[taskId].data[1] == 1) - { - BlendPalettes(0xffff0000, 16, 0); - gTasks[taskId].data[1]++; - } - else - { - REG_BLDCNT = 0; - REG_BLDY = 0; - DestroyTask(taskId); - SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); - } - } -} - -static void sub_80C2F28(u8 taskId) -{ - gBattle_BG3_X += 2; - gBattle_BG3_Y++; - if (gBattle_BG3_X > 0xff) - gBattle_BG3_X -= 0xff; - if (gBattle_BG3_Y > 0xff) - gBattle_BG3_Y -= 0xff; -} - -static void sub_80C2F64(u8 taskId) -{ - if (++gTasks[taskId].data[0] == 2) - { - gTasks[taskId].data[0] = 0; - if (gTasks[taskId].data[2] == 0) - gTasks[taskId].data[1]++; - else - gTasks[taskId].data[1]--; - if (gTasks[taskId].data[1] == 16) - gTasks[taskId].data[2] = 1; - else if (gTasks[taskId].data[1] == 0) - gTasks[taskId].data[2] = 0; - BlendPalette(0x6b, 0x01, gTasks[taskId].data[1], RGB(30, 22, 11)); - BlendPalette(0x68, 0x01, gTasks[taskId].data[1], RGB(31, 31, 31)); - BlendPalette(0x6e, 0x01, gTasks[taskId].data[1], RGB(30, 29, 29)); - } - if (gTasks[taskId].data[1] == 0) - eContestLink80C2020Struct2018000.unk_0a = 0; - else - eContestLink80C2020Struct2018000.unk_0a = 1; -} - -void sub_80C3024(u16 species, u8 destOffset, u8 srcOffset, bool8 useDmaNow, u32 personality) -{ - int i; - int j; - u16 tile; - u16 offset; - u16 var0; - u16 var1; - - if (useDmaNow) - { - DmaCopy32Defvars(3, GetMonIconPtr(species, personality) + (srcOffset << 9) + 0x80, BG_CHAR_ADDR(1) + (destOffset << 9), 0x180); - var0 = ((destOffset + 10) << 12); - var1 = (destOffset * 16 + 0x200); - tile = var1 | var0; - offset = destOffset * 0x60 + 0x83; - for (i = 0; i < 3; i++) - { - for (j = 0; j < 4; j++) - { - ((u16 *)BG_CHAR_ADDR(3))[(i << 5) + j + offset] = tile; - tile++; - } - } - } - else - { - RequestSpriteCopy(GetMonIconPtr(species, personality) + (srcOffset << 9) + 0x80, BG_CHAR_ADDR(1) + (destOffset << 9), 0x180); - } -} - -static void LoadAllContestMonIcons(u8 srcOffset, bool8 useDmaNow) -{ - int i; - - for (i = 0; i < 4; i++) - { - sub_80C3024(gContestMons[i].species, i, srcOffset, useDmaNow, gContestMons[i].personality); - } -} - -void sub_80C310C(void) -{ - int i; - register u16 species asm("r0"); - - for (i = 0; i < 4; i++) - { - species = mon_icon_convert_unown_species_id(gContestMons[i].species, 0); - LoadPalette(gMonIconPalettes[gMonIconPaletteIndices[species]], 0xa0 + 0x10 * i, 0x20); - } -} - -#ifdef NONMATCHING -void sub_80C3158(const u8 *string, u8 spriteId) -{ - int i, j; - u8 width; - u8 * displayedStringBattle; - void * dest; - u8 * d1; - u8 * d2; - void *d3; - void *d4; - void *d5; - void *d6; - int w; - u16 sp00[4]; - struct Sprite *sprite = &gSprites[spriteId]; - sp00[0] = gSprites[spriteId].oam.tileNum; - sp00[1] = gSprites[sprite->data[0]].oam.tileNum; - sp00[2] = gSprites[sprite->data[1]].oam.tileNum; - sp00[3] = gSprites[sprite->data[2]].oam.tileNum; - - for (i = 0; i < 4; i++) - { - DmaClear32(3, (void *)VRAM + 0x10000 + 32 * sp00[i], 0x400); - } - - width = Text_GetStringWidthFromWindowTemplate(&gWindowTemplate_81E7278, string); - displayedStringBattle = gDisplayedStringBattle; - displayedStringBattle = StringCopy(displayedStringBattle, gUnknown_083D17E2); - if ((~width + 1) & 7) - { - displayedStringBattle[0] = EXT_CTRL_CODE_BEGIN; - displayedStringBattle[1] = 0x11; - displayedStringBattle[2] = ((~width + 1) & 7) / 2; - displayedStringBattle += 3; - } - - width += -8 & (width + 7); - displayedStringBattle = StringCopy(displayedStringBattle, string); - - displayedStringBattle[0] = EXT_CTRL_CODE_BEGIN; - displayedStringBattle[1] = 0x13; - displayedStringBattle[2] = width; - displayedStringBattle[3] = EOS; - - sub_80034D4(eContestLink80C2020Struct2018068, gDisplayedStringBattle); - - CpuCopy32(&gUnknown_083D1624[0x0], (void *)0x6010000 + 32 * sp00[0], 32); - CpuCopy32(&gUnknown_083D1624[0x40], (void *)0x6010000 + 32 * sp00[0] + 0x100, 32); - CpuCopy32(&gUnknown_083D1624[0x40], (void *)0x6010000 + 32 * sp00[0] + 0x200, 32); - CpuCopy32(&gUnknown_083D1624[0x20], (void *)0x6010000 + 32 * sp00[0] + 0x300, 32); - - w = width / 8; - j = 0; - if (j <= w) - { - d2 = eContestLink80C2020Struct2018068 + 0x20; - d1 = eContestLink80C2020Struct2018068; - d3 = (void *)VRAM + 0x0FD20; - d4 = (void *)VRAM + 0x0FE20; - d5 = (void *)VRAM + 0x0FF20; - d6 = (void *)VRAM + 0x10020; - while (j <= w) - { - if (j < 7) - dest = 32 * sp00[0] + d6; - else if (j < 15) - dest = 32 * sp00[1] + d5; - else if (j < 23) - dest = 32 * sp00[2] + d4; - else - dest = 32 * sp00[3] + d3; - - if (j == w) - break; - - CpuCopy32(gUnknown_083D16E4, dest, 32); - CpuCopy32(gUnknown_083D16E4 + 0x10, dest + 0x300, 32); - CpuCopy32(j * 0x40 + d2, dest + 0x100, 32); - CpuCopy32(j * 0x40 + d1, dest + 0x200, 32); - - d3 += 0x20; - d4 += 0x20; - d5 += 0x20; - d6 += 0x20; - j++; - } - } - - CpuCopy32(gUnknown_083D1644, dest, 32); - CpuCopy32(gUnknown_083D1644 + 0x40, dest + 0x100, 32); - CpuCopy32(gUnknown_083D1644 + 0x40, dest + 0x200, 32); - CpuCopy32(gUnknown_083D1644 + 0x20, dest + 0x300, 32); -} -#else -asm(".include \"constants/gba_constants.inc\""); -asm(".include \"include/macros.inc\""); -NAKED -void sub_80C3158(const u8 * string, u8 spriteId) -{ - asm_unified("\tpush {r4-r7,lr}\n" - "\tmov r7, r10\n" - "\tmov r6, r9\n" - "\tmov r5, r8\n" - "\tpush {r5-r7}\n" - "\tsub sp, 0x1C\n" - "\tmov r9, r0\n" - "\tlsls r1, 24\n" - "\tlsrs r1, 24\n" - "\tlsls r2, r1, 4\n" - "\tadds r2, r1\n" - "\tlsls r2, 2\n" - "\tldr r3, _080C32C0 @ =gSprites\n" - "\tadds r2, r3\n" - "\tmov r1, sp\n" - "\tldrh r0, [r2, 0x4]\n" - "\tlsls r0, 22\n" - "\tlsrs r0, 22\n" - "\tstrh r0, [r1]\n" - "\tmov r4, sp\n" - "\tmovs r0, 0x2E\n" - "\tldrsh r1, [r2, r0]\n" - "\tlsls r0, r1, 4\n" - "\tadds r0, r1\n" - "\tlsls r0, 2\n" - "\tadds r0, r3\n" - "\tldrh r0, [r0, 0x4]\n" - "\tlsls r0, 22\n" - "\tlsrs r0, 22\n" - "\tstrh r0, [r4, 0x2]\n" - "\tmovs r0, 0x30\n" - "\tldrsh r1, [r2, r0]\n" - "\tlsls r0, r1, 4\n" - "\tadds r0, r1\n" - "\tlsls r0, 2\n" - "\tadds r0, r3\n" - "\tldrh r0, [r0, 0x4]\n" - "\tlsls r0, 22\n" - "\tlsrs r0, 22\n" - "\tstrh r0, [r4, 0x4]\n" - "\tmovs r0, 0x32\n" - "\tldrsh r1, [r2, r0]\n" - "\tlsls r0, r1, 4\n" - "\tadds r0, r1\n" - "\tlsls r0, 2\n" - "\tadds r0, r3\n" - "\tldrh r0, [r0, 0x4]\n" - "\tlsls r0, 22\n" - "\tlsrs r0, 22\n" - "\tstrh r0, [r4, 0x6]\n" - "\tldr r1, _080C32C4 @ =gWindowTemplate_81E7278\n" - "\tmov r8, r1\n" - "\tldr r7, _080C32C8 @ =0x06010000\n" - "\tldr r2, _080C32CC @ =0x040000d4\n" - "\tldr r6, _080C32D0 @ =0x85000100\n" - "\tmov r1, sp\n" - "\tmovs r5, 0\n" - "\tadd r3, sp, 0x8\n" - "\tmovs r4, 0x3\n" - "_080C31CE:\n" - "\tldrh r0, [r1]\n" - "\tlsls r0, 5\n" - "\tadds r0, r7\n" - "\tstr r5, [sp, 0x8]\n" - "\tstr r3, [r2]\n" - "\tstr r0, [r2, 0x4]\n" - "\tstr r6, [r2, 0x8]\n" - "\tldr r0, [r2, 0x8]\n" - "\tadds r1, 0x2\n" - "\tsubs r4, 0x1\n" - "\tcmp r4, 0\n" - "\tbge _080C31CE\n" - "\tmov r0, r8\n" - "\tmov r1, r9\n" - "\tbl Text_GetStringWidthFromWindowTemplate\n" - "\tlsls r0, 24\n" - "\tlsrs r5, r0, 24\n" - "\tldr r2, _080C32D4 @ =gDisplayedStringBattle\n" - "\tldr r1, _080C32D8 @ =gUnknown_083D17E2\n" - "\tadds r0, r2, 0\n" - "\tbl StringCopy\n" - "\tadds r2, r0, 0\n" - "\tmvns r0, r5\n" - "\tadds r1, r0, 0x1\n" - "\tmovs r0, 0x7\n" - "\tands r1, r0\n" - "\tcmp r1, 0\n" - "\tbeq _080C3218\n" - "\tmovs r0, 0xFC\n" - "\tstrb r0, [r2]\n" - "\tmovs r0, 0x11\n" - "\tstrb r0, [r2, 0x1]\n" - "\tlsrs r0, r1, 1\n" - "\tstrb r0, [r2, 0x2]\n" - "\tadds r2, 0x3\n" - "_080C3218:\n" - "\tadds r6, r5, 0x7\n" - "\tmovs r1, 0x8\n" - "\tnegs r1, r1\n" - "\tadds r0, r1, 0\n" - "\tands r6, r0\n" - "\tlsls r6, 24\n" - "\tlsrs r5, r6, 24\n" - "\tadds r0, r2, 0\n" - "\tmov r1, r9\n" - "\tbl StringCopy\n" - "\tadds r2, r0, 0\n" - "\tmovs r0, 0xFC\n" - "\tstrb r0, [r2]\n" - "\tmovs r0, 0x13\n" - "\tstrb r0, [r2, 0x1]\n" - "\tstrb r5, [r2, 0x2]\n" - "\tmovs r0, 0xFF\n" - "\tstrb r0, [r2, 0x3]\n" - "\tldr r0, _080C32DC @ =gSharedMem + 0x18068\n" - "\tmov r10, r0\n" - "\tldr r1, _080C32D4 @ =gDisplayedStringBattle\n" - "\tbl sub_80034D4\n" - "\tmov r0, sp\n" - "\tldrh r4, [r0]\n" - "\tlsls r4, 5\n" - "\tldr r1, _080C32C8 @ =0x06010000\n" - "\tadds r7, r4, r1\n" - "\tldr r0, _080C32E0 @ =gUnknown_083D1624\n" - "\tmov r9, r0\n" - "\tldr r1, _080C32E4 @ =REG_BG0CNT\n" - "\tmov r8, r1\n" - "\tadds r1, r7, 0\n" - "\tmov r2, r8\n" - "\tbl CpuSet\n" - "\tmov r5, r9\n" - "\tadds r5, 0x80\n" - "\tldr r0, _080C32E8 @ =0x06010100\n" - "\tadds r1, r4, r0\n" - "\tadds r0, r5, 0\n" - "\tmov r2, r8\n" - "\tbl CpuSet\n" - "\tldr r0, _080C32EC @ =0x06010200\n" - "\tadds r1, r4, r0\n" - "\tadds r0, r5, 0\n" - "\tmov r2, r8\n" - "\tbl CpuSet\n" - "\tmov r0, r9\n" - "\tadds r0, 0x40\n" - "\tldr r1, _080C32F0 @ =0x06010300\n" - "\tadds r4, r1\n" - "\tadds r1, r4, 0\n" - "\tmov r2, r8\n" - "\tbl CpuSet\n" - "\tlsrs r5, r6, 27\n" - "\tmovs r4, 0\n" - "\tcmp r4, r5\n" - "\tbgt _080C3382\n" - "\tmov r6, sp\n" - "\tmov r0, r10\n" - "\tadds r0, 0x20\n" - "\tstr r0, [sp, 0xC]\n" - "\tmov r1, r10\n" - "\tstr r1, [sp, 0x10]\n" - "\tldr r0, _080C32F4 @ =0x0600fd20\n" - "\tstr r0, [sp, 0x14]\n" - "\tldr r1, _080C32F8 @ =0x0600fe20\n" - "\tstr r1, [sp, 0x18]\n" - "\tldr r0, _080C32FC @ =0x0600ff20\n" - "\tmov r10, r0\n" - "\tldr r1, _080C3300 @ =0x06010020\n" - "\tmov r9, r1\n" - "_080C32B2:\n" - "\tcmp r4, 0x6\n" - "\tbgt _080C3304\n" - "\tldrh r0, [r6]\n" - "\tlsls r0, 5\n" - "\tmov r1, r9\n" - "\tb _080C3322\n" - "\t.align 2, 0\n" - "_080C32C0: .4byte gSprites\n" - "_080C32C4: .4byte gWindowTemplate_81E7278\n" - "_080C32C8: .4byte 0x06010000\n" - "_080C32CC: .4byte 0x040000d4\n" - "_080C32D0: .4byte 0x85000100\n" - "_080C32D4: .4byte gDisplayedStringBattle\n" - "_080C32D8: .4byte gUnknown_083D17E2\n" - "_080C32DC: .4byte gSharedMem + 0x18068\n" - "_080C32E0: .4byte gUnknown_083D1624\n" - "_080C32E4: .4byte REG_BG0CNT\n" - "_080C32E8: .4byte 0x06010100\n" - "_080C32EC: .4byte 0x06010200\n" - "_080C32F0: .4byte 0x06010300\n" - "_080C32F4: .4byte 0x0600fd20\n" - "_080C32F8: .4byte 0x0600fe20\n" - "_080C32FC: .4byte 0x0600ff20\n" - "_080C3300: .4byte 0x06010020\n" - "_080C3304:\n" - "\tcmp r4, 0xE\n" - "\tbgt _080C3310\n" - "\tldrh r0, [r6, 0x2]\n" - "\tlsls r0, 5\n" - "\tmov r1, r10\n" - "\tb _080C3322\n" - "_080C3310:\n" - "\tcmp r4, 0x16\n" - "\tbgt _080C331C\n" - "\tldrh r0, [r6, 0x4]\n" - "\tlsls r0, 5\n" - "\tldr r1, [sp, 0x18]\n" - "\tb _080C3322\n" - "_080C331C:\n" - "\tldrh r0, [r6, 0x6]\n" - "\tlsls r0, 5\n" - "\tldr r1, [sp, 0x14]\n" - "_080C3322:\n" - "\tadds r7, r0, r1\n" - "\tcmp r4, r5\n" - "\tbeq _080C3382\n" - "\tldr r0, _080C33D0 @ =gUnknown_083D16E4\n" - "\tadds r1, r7, 0\n" - "\tmov r2, r8\n" - "\tbl CpuSet\n" - "\tmovs r0, 0xC0\n" - "\tlsls r0, 2\n" - "\tadds r1, r7, r0\n" - "\tldr r0, _080C33D0 @ =gUnknown_083D16E4\n" - "\tadds r0, 0x20\n" - "\tmov r2, r8\n" - "\tbl CpuSet\n" - "\tmovs r0, 0x80\n" - "\tlsls r0, 1\n" - "\tadds r1, r7, r0\n" - "\tldr r0, [sp, 0x10]\n" - "\tmov r2, r8\n" - "\tbl CpuSet\n" - "\tmovs r0, 0x80\n" - "\tlsls r0, 2\n" - "\tadds r1, r7, r0\n" - "\tldr r0, [sp, 0xC]\n" - "\tmov r2, r8\n" - "\tbl CpuSet\n" - "\tldr r1, [sp, 0xC]\n" - "\tadds r1, 0x40\n" - "\tstr r1, [sp, 0xC]\n" - "\tldr r0, [sp, 0x10]\n" - "\tadds r0, 0x40\n" - "\tstr r0, [sp, 0x10]\n" - "\tldr r1, [sp, 0x14]\n" - "\tadds r1, 0x20\n" - "\tstr r1, [sp, 0x14]\n" - "\tldr r0, [sp, 0x18]\n" - "\tadds r0, 0x20\n" - "\tstr r0, [sp, 0x18]\n" - "\tmovs r1, 0x20\n" - "\tadd r10, r1\n" - "\tadd r9, r1\n" - "\tadds r4, 0x1\n" - "\tcmp r4, r5\n" - "\tble _080C32B2\n" - "_080C3382:\n" - "\tldr r4, _080C33D4 @ =gUnknown_083D1644\n" - "\tldr r5, _080C33D8 @ =REG_BG0CNT\n" - "\tadds r0, r4, 0\n" - "\tadds r1, r7, 0\n" - "\tadds r2, r5, 0\n" - "\tbl CpuSet\n" - "\tadds r6, r4, 0\n" - "\tadds r6, 0x80\n" - "\tmovs r0, 0x80\n" - "\tlsls r0, 1\n" - "\tadds r1, r7, r0\n" - "\tadds r0, r6, 0\n" - "\tadds r2, r5, 0\n" - "\tbl CpuSet\n" - "\tmovs r0, 0x80\n" - "\tlsls r0, 2\n" - "\tadds r1, r7, r0\n" - "\tadds r0, r6, 0\n" - "\tadds r2, r5, 0\n" - "\tbl CpuSet\n" - "\tadds r4, 0x40\n" - "\tmovs r0, 0xC0\n" - "\tlsls r0, 2\n" - "\tadds r1, r7, r0\n" - "\tadds r0, r4, 0\n" - "\tadds r2, r5, 0\n" - "\tbl CpuSet\n" - "\tadd sp, 0x1C\n" - "\tpop {r3-r5}\n" - "\tmov r8, r3\n" - "\tmov r9, r4\n" - "\tmov r10, r5\n" - "\tpop {r4-r7}\n" - "\tpop {r0}\n" - "\tbx r0\n" - "\t.align 2, 0\n" - "_080C33D0: .4byte gUnknown_083D16E4\n" - "_080C33D4: .4byte gUnknown_083D1644\n" - "_080C33D8: .4byte REG_BG0CNT"); -} -#endif //NONMATCHING - -void sub_80C33DC(void) -{ - int i; - struct SpriteTemplate template; - u8 spriteIds[8]; - - template = gSpriteTemplate_83D174C; - for (i = 0; i <8; i++) - LoadSpriteSheet(&gUnknown_083D1764[i]); - - LoadSpritePalette(&gUnknown_083D17A4); - for (i = 0; i < 8; i++) - { - spriteIds[i] = CreateSprite(&template, 272, 144, 10); - template.tileTag++; - } - - gSprites[spriteIds[0]].data[0] = spriteIds[1]; - gSprites[spriteIds[0]].data[1] = spriteIds[2]; - gSprites[spriteIds[0]].data[2] = spriteIds[3]; - - gSprites[spriteIds[4]].data[0] = spriteIds[5]; - gSprites[spriteIds[4]].data[1] = spriteIds[6]; - gSprites[spriteIds[4]].data[2] = spriteIds[7]; - - eContestLink80C2020Struct2018000.unk_00 = spriteIds[0]; - eContestLink80C2020Struct2018000.unk_04 = 0; - eContestLink80C2020Struct2018000.unk_01 = spriteIds[4]; - sub_80C3764(); -} - -u16 sub_80C34AC(const u8 * string) -{ - u8 width = (StringLength(string) * 6); - return 0x70 - (width / 2); -} - -void sub_80C34CC(s16 arg0, u16 y, u16 arg2, u16 arg3) -{ - struct Sprite *sprite = &gSprites[eContestLink80C2020Struct2018000.unk_00]; - sprite->pos1.x = 272; - sprite->pos1.y = y; - sprite->pos2.x = 0; - sprite->pos2.y = 0; - sprite->data[4] = arg0 + 32; - sprite->data[5] = arg2; - sprite->data[6] = arg3; - sprite->data[7] = 0; - sprite->callback = sub_80C3588; - eContestLink80C2020Struct2018000.unk_04 = 1; -} - -void sub_80C3520(u16 arg0) -{ - struct Sprite *sprite = &gSprites[eContestLink80C2020Struct2018000.unk_00]; - sprite->pos1.x += sprite->pos2.x; - sprite->pos1.y += sprite->pos2.y; - sprite->pos2.y = 0; - sprite->pos2.x = 0; - sprite->data[6] = arg0; - sprite->data[7] = 0; - sprite->callback = sub_80C3630; - eContestLink80C2020Struct2018000.unk_04 = 3; -} - -void sub_80C3564(struct Sprite *sprite) -{ - sprite->pos1.x = 272; - sprite->pos1.y = 144; - sprite->pos2.y = 0; - sprite->pos2.x = 0; - sprite->callback = SpriteCallbackDummy; - eContestLink80C2020Struct2018000.unk_04 = 0; -} - - -void sub_80C3588(struct Sprite *sprite) -{ - int i; - s16 var0; - - var0 = (u16)sprite->data[7] + (u16)sprite->data[6]; - sprite->pos1.x -= var0 >> 8; - sprite->data[7] = (sprite->data[6] + sprite->data[7]) & 0xFF; - if (sprite->pos1.x < sprite->data[4]) - sprite->pos1.x = sprite->data[4]; - - for (i = 0; i < 3; i++) - { - struct Sprite *sprite2 = &gSprites[sprite->data[i]]; - sprite2->pos1.x = sprite->pos1.x + sprite->pos2.x + (i + 1) * 64; - } - - if (sprite->pos1.x == sprite->data[4]) - sprite->callback = sub_80C35FC; -} - -void sub_80C35FC(struct Sprite *sprite) -{ - eContestLink80C2020Struct2018000.unk_04 = 2; - if ((u16)sprite->data[5] != 0xFFFF) - { - if (--sprite->data[5] == -1) - sub_80C3520(sprite->data[6]); - } -} - -void sub_80C3630(struct Sprite *sprite) -{ - int i; - s16 var0; - - var0 = (u16)sprite->data[7] + (u16)sprite->data[6]; - sprite->pos1.x -= var0 >> 8; - sprite->data[7] = (sprite->data[6] + sprite->data[7]) & 0xFF; - for (i = 0; i < 3; i++) - { - struct Sprite *sprite2 = &gSprites[sprite->data[i]]; - sprite2->pos1.x = sprite->pos1.x + sprite->pos2.x + (i + 1) * 64; - } - - if (sprite->pos1.x + sprite->pos2.x < -224) - sub_80C3564(sprite); -} - -void sub_80C3698(const u8 *text) -{ - int i; - u16 x; - struct Sprite *sprite; - - sub_80C3158(text, eContestLink80C2020Struct2018000.unk_01); - x = sub_80C34AC(text); - sprite = &gSprites[eContestLink80C2020Struct2018000.unk_01]; - sprite->pos1.x = x + 32; - sprite->pos1.y = 80; - sprite->invisible = 0; - for (i = 0; i < 3; i++) - { - gSprites[sprite->data[i]].pos1.x = sprite->pos1.x + sprite->pos2.x + (i + 1) * 64; - gSprites[sprite->data[i]].pos1.y = sprite->pos1.y; - gSprites[sprite->data[i]].invisible = 0; - } - - gBattle_WIN0H = 0x00F0; - gBattle_WIN0V = ((sprite->pos1.y - 16) << 8) | (sprite->pos1.y + 16); - REG_WININ = WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR | WININ_WIN0_BG1 | WININ_WIN0_BG2 | WININ_WIN0_BG3 | WININ_WIN0_OBJ | WININ_WIN0_CLR; -} - -void sub_80C3764(void) -{ - int i; - struct Sprite *sprite; - - sprite = &gSprites[eContestLink80C2020Struct2018000.unk_01]; - sprite->invisible = 1; - for (i = 0; i < 3; i++) - gSprites[sprite->data[i]].invisible = 1; - - gBattle_WIN0H = 0; - gBattle_WIN0V = 0; - REG_WIN0H = gBattle_WIN0H; - REG_WIN0V = gBattle_WIN0V; - REG_WININ = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR; -} - -#ifdef ENGLISH -#ifdef NONMATCHING -static inline s32 de_sub_80C39A8(s32 a0) -{ - s32 result = 0; - if (gIsLinkContest & 0x1) - { - sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 9, 2, 8, 2); - result = 8; - } - else if (gSpecialVar_ContestRank == 0) - { - sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 0, 0, 9, 2); - result = 9; - } - else if (gSpecialVar_ContestRank == 1) - { - sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 9, 0, 8, 2); - result = 8; - } - else if (gSpecialVar_ContestRank == 2) - { - sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 17, 0, 8, 2); - result = 8; - } - else - { - sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 0, 2, 9, 2); - result = 9; - } - return result; -} - -static inline s32 de_sub_80C3A84(s32 a0, s32 * a1) -{ - s32 result; - if (gSpecialVar_ContestCategory == 0) - { - *a1 = 0; - sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 17, 2, 10, 2); - result = 10; - } - else if (gSpecialVar_ContestCategory == 1) - { - *a1 = 1; - sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 0, 4, 11, 2); - result = 11; - } - else if (gSpecialVar_ContestCategory == 2) - { - *a1 = 2; - sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 11, 4, 10, 2); - result = 10; - } - else if (gSpecialVar_ContestCategory == 3) - { - *a1 = 3; - sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 21, 4, 10, 2); - result = 10; - } - else - { - *a1 = 4; - sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 0, 6, 10, 2); - result = 10; - } - return result; -} - -void sub_80C37E4(void) -{ - s32 sp0; - s32 i; - de_sub_80C3A84(de_sub_80C39A8(5) + 5, &sp0); - for (i = 0; i < 0x80; i++) - { - ((vu16 *)0x0600E000)[i] &= 0xFFF; - ((vu16 *)0x0600E000)[i] |= sp0 << 12;; - } -} -#else -NAKED -void sub_80C37E4(void) -{ - asm_unified("\tpush {r4-r6,lr}\n" - "\tsub sp, 0x10\n" - "\tmovs r5, 0x1\n" - "\tmovs r4, 0\n" - "\tldr r0, _080C3808 @ =gIsLinkContest\n" - "\tldrb r0, [r0]\n" - "\tadds r1, r5, 0\n" - "\tands r1, r0\n" - "\tcmp r1, 0\n" - "\tbeq _080C3814\n" - "\tldr r0, _080C380C @ =0x0600e000\n" - "\tldr r3, _080C3810 @ =gUnknown_08E964B8\n" - "\tmovs r1, 0x9\n" - "\tstr r1, [sp]\n" - "\tmovs r2, 0x2\n" - "\tstr r2, [sp, 0x4]\n" - "\tb _080C386A\n" - "\t.align 2, 0\n" - "_080C3808: .4byte gIsLinkContest\n" - "_080C380C: .4byte 0x0600e000\n" - "_080C3810: .4byte gUnknown_08E964B8\n" - "_080C3814:\n" - "\tldr r0, _080C3830 @ =gSpecialVar_ContestRank\n" - "\tldrh r2, [r0]\n" - "\tcmp r2, 0\n" - "\tbne _080C383C\n" - "\tmovs r4, 0x1\n" - "\tldr r0, _080C3834 @ =0x0600e000\n" - "\tldr r3, _080C3838 @ =gUnknown_08E964B8\n" - "\tstr r2, [sp]\n" - "\tstr r2, [sp, 0x4]\n" - "\tmovs r1, 0x9\n" - "\tstr r1, [sp, 0x8]\n" - "\tmovs r1, 0x2\n" - "\tstr r1, [sp, 0xC]\n" - "\tb _080C3870\n" - "\t.align 2, 0\n" - "_080C3830: .4byte gSpecialVar_ContestRank\n" - "_080C3834: .4byte 0x0600e000\n" - "_080C3838: .4byte gUnknown_08E964B8\n" - "_080C383C:\n" - "\tcmp r2, 0x1\n" - "\tbne _080C385C\n" - "\tldr r0, _080C3854 @ =0x0600e000\n" - "\tldr r3, _080C3858 @ =gUnknown_08E964B8\n" - "\tmovs r1, 0x9\n" - "\tstr r1, [sp]\n" - "\tstr r4, [sp, 0x4]\n" - "\tmovs r1, 0x8\n" - "\tstr r1, [sp, 0x8]\n" - "\tmovs r1, 0x2\n" - "\tstr r1, [sp, 0xC]\n" - "\tb _080C3870\n" - "\t.align 2, 0\n" - "_080C3854: .4byte 0x0600e000\n" - "_080C3858: .4byte gUnknown_08E964B8\n" - "_080C385C:\n" - "\tcmp r2, 0x2\n" - "\tbne _080C3884\n" - "\tldr r0, _080C387C @ =0x0600e000\n" - "\tldr r3, _080C3880 @ =gUnknown_08E964B8\n" - "\tmovs r1, 0x11\n" - "\tstr r1, [sp]\n" - "\tstr r4, [sp, 0x4]\n" - "_080C386A:\n" - "\tmovs r1, 0x8\n" - "\tstr r1, [sp, 0x8]\n" - "\tstr r2, [sp, 0xC]\n" - "_080C3870:\n" - "\tmovs r1, 0x5\n" - "\tmovs r2, 0x1\n" - "\tbl sub_809D104\n" - "\tb _080C389E\n" - "\t.align 2, 0\n" - "_080C387C: .4byte 0x0600e000\n" - "_080C3880: .4byte gUnknown_08E964B8\n" - "_080C3884:\n" - "\tmovs r4, 0x1\n" - "\tldr r0, _080C38C0 @ =0x0600e000\n" - "\tldr r3, _080C38C4 @ =gUnknown_08E964B8\n" - "\tstr r1, [sp]\n" - "\tmovs r2, 0x2\n" - "\tstr r2, [sp, 0x4]\n" - "\tmovs r1, 0x9\n" - "\tstr r1, [sp, 0x8]\n" - "\tstr r2, [sp, 0xC]\n" - "\tmovs r1, 0x5\n" - "\tmovs r2, 0x1\n" - "\tbl sub_809D104\n" - "_080C389E:\n" - "\tadds r4, 0xD\n" - "\tldr r0, _080C38C8 @ =gSpecialVar_ContestCategory\n" - "\tldrh r0, [r0]\n" - "\tcmp r0, 0\n" - "\tbne _080C38CC\n" - "\tmovs r6, 0\n" - "\tldr r0, _080C38C0 @ =0x0600e000\n" - "\tldr r3, _080C38C4 @ =gUnknown_08E964B8\n" - "\tmovs r1, 0x11\n" - "\tstr r1, [sp]\n" - "\tmovs r2, 0x2\n" - "\tstr r2, [sp, 0x4]\n" - "\tmovs r1, 0xA\n" - "\tstr r1, [sp, 0x8]\n" - "\tstr r2, [sp, 0xC]\n" - "\tb _080C392A\n" - "\t.align 2, 0\n" - "_080C38C0: .4byte 0x0600e000\n" - "_080C38C4: .4byte gUnknown_08E964B8\n" - "_080C38C8: .4byte gSpecialVar_ContestCategory\n" - "_080C38CC:\n" - "\tcmp r0, 0x1\n" - "\tbne _080C38EC\n" - "\tmovs r6, 0x1\n" - "\tldr r0, _080C38E4 @ =0x0600e000\n" - "\tldr r3, _080C38E8 @ =gUnknown_08E964B8\n" - "\tmovs r1, 0\n" - "\tstr r1, [sp]\n" - "\tmovs r1, 0x4\n" - "\tstr r1, [sp, 0x4]\n" - "\tmovs r1, 0xB\n" - "\tb _080C3924\n" - "\t.align 2, 0\n" - "_080C38E4: .4byte 0x0600e000\n" - "_080C38E8: .4byte gUnknown_08E964B8\n" - "_080C38EC:\n" - "\tcmp r0, 0x2\n" - "\tbne _080C3910\n" - "\tmovs r6, 0x2\n" - "\tldr r0, _080C3908 @ =0x0600e000\n" - "\tldr r3, _080C390C @ =gUnknown_08E964B8\n" - "\tmovs r1, 0xB\n" - "\tstr r1, [sp]\n" - "\tmovs r1, 0x4\n" - "\tstr r1, [sp, 0x4]\n" - "\tmovs r1, 0xA\n" - "\tstr r1, [sp, 0x8]\n" - "\tstr r6, [sp, 0xC]\n" - "\tb _080C392A\n" - "\t.align 2, 0\n" - "_080C3908: .4byte 0x0600e000\n" - "_080C390C: .4byte gUnknown_08E964B8\n" - "_080C3910:\n" - "\tcmp r0, 0x3\n" - "\tbne _080C393C\n" - "\tmovs r6, 0x3\n" - "\tldr r0, _080C3934 @ =0x0600e000\n" - "\tldr r3, _080C3938 @ =gUnknown_08E964B8\n" - "\tmovs r1, 0x15\n" - "\tstr r1, [sp]\n" - "\tmovs r1, 0x4\n" - "\tstr r1, [sp, 0x4]\n" - "\tmovs r1, 0xA\n" - "_080C3924:\n" - "\tstr r1, [sp, 0x8]\n" - "\tmovs r1, 0x2\n" - "\tstr r1, [sp, 0xC]\n" - "_080C392A:\n" - "\tadds r1, r4, 0\n" - "\tadds r2, r5, 0\n" - "\tbl sub_809D104\n" - "\tb _080C395A\n" - "\t.align 2, 0\n" - "_080C3934: .4byte 0x0600e000\n" - "_080C3938: .4byte gUnknown_08E964B8\n" - "_080C393C:\n" - "\tmovs r6, 0x4\n" - "\tldr r0, _080C3984 @ =0x0600e000\n" - "\tldr r3, _080C3988 @ =gUnknown_08E964B8\n" - "\tmovs r1, 0\n" - "\tstr r1, [sp]\n" - "\tmovs r1, 0x6\n" - "\tstr r1, [sp, 0x4]\n" - "\tmovs r1, 0xA\n" - "\tstr r1, [sp, 0x8]\n" - "\tmovs r1, 0x2\n" - "\tstr r1, [sp, 0xC]\n" - "\tadds r1, r4, 0\n" - "\tadds r2, r5, 0\n" - "\tbl sub_809D104\n" - "_080C395A:\n" - "\tldr r5, _080C398C @ =0x00000fff\n" - "\tlsls r4, r6, 12\n" - "\tldr r2, _080C3984 @ =0x0600e000\n" - "\tmovs r3, 0x7F\n" - "_080C3962:\n" - "\tldrh r1, [r2]\n" - "\tadds r0, r5, 0\n" - "\tands r0, r1\n" - "\tstrh r0, [r2]\n" - "\tldrh r1, [r2]\n" - "\tadds r0, r4, 0\n" - "\torrs r0, r1\n" - "\tstrh r0, [r2]\n" - "\tadds r2, 0x2\n" - "\tsubs r3, 0x1\n" - "\tcmp r3, 0\n" - "\tbge _080C3962\n" - "\tadd sp, 0x10\n" - "\tpop {r4-r6}\n" - "\tpop {r0}\n" - "\tbx r0\n" - "\t.align 2, 0\n" - "_080C3984: .4byte 0x0600e000\n" - "_080C3988: .4byte gUnknown_08E964B8\n" - "_080C398C: .4byte 0x00000fff"); -} -#endif // NONMATCHING - -#elif defined(GERMAN) -s16 de_sub_80C39A8(s32 a0) -{ - s16 result; - if (gIsLinkContest & 1) - { - sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 11, 3, 8, 3); - result = 8; - } - else if (gSpecialVar_ContestRank == 0) - { - sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 0, 0, 11, 3); - result = 11; - } - else if (gSpecialVar_ContestRank == 1) - { - sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 11, 0, 10, 3); - result = 10; - } - else if (gSpecialVar_ContestRank == 2) - { - sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 21, 0, 10, 3); - result = 10; - } - else - { - sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 0, 3, 11, 3); - result = 11; - } - return result; -} - -s16 de_sub_80C3A84(s32 a0, s32 * a1) -{ - s16 result; - if (gSpecialVar_ContestCategory == 0) - { - *a1 = 0; - sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 19, 3, 7, 3); - result = 7; - } - else if (gSpecialVar_ContestCategory == 1) - { - *a1 = 1; - sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 0, 6, 7, 3); - result = 7; - } - else if (gSpecialVar_ContestCategory == 2) - { - *a1 = 2; - sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 7, 6, 4, 3); - result = 4; - } - else if (gSpecialVar_ContestCategory == 3) - { - *a1 = 3; - sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 11, 6, 6, 3); - result = 6; - } - else - { - *a1 = 4; - sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 17, 6, 5, 3); - result = 5; - } - return result; -} - -void sub_80C37E4(void) -{ - s32 sp0; - s32 i; - de_sub_80C3A84(de_sub_80C39A8(6) + 6, &sp0); - for (i = 0; i < 0x80; i++) - { - ((vu16 *)0x0600E000)[i] &= 0xFFF; - ((vu16 *)0x0600E000)[i] |= sp0 << 12;; - } -} -#endif - -// fakematching? -u8 sub_80C3990(u8 monIndex, u8 arg1) -{ - u32 var0; - u32 var1; - - var0 = gContestMonConditions[monIndex] << 16; - var1 = var0 / 0x3F; - if (var1 & 0xFFFF) - var1 += 0x10000; - - var1 >>= 16; - if (var1 == 0 && var0) - var1 = 1; - - if (arg1 && var1 > 10) - var1 = 10; - - return var1; -} - -s8 sub_80C39E4(u8 arg0, u8 arg1) -{ - u32 r4; - u32 r2; - s16 val; - s8 ret; - - val = gUnknown_02038688[arg0]; - if (val < 0) - r4 = -val << 16; - else - r4 = val << 16; - r2 = r4 / 80; - if (r2 & 0xFFFF) - r2 += 0x10000; - - r2 >>= 16; - if (r2 == 0 && r4 != 0) - r2 = 1; - - if (arg1 != 0 && r2 > 10) - r2 = 10; - - if (gUnknown_02038688[arg0] < 0) - ret = -r2; - else - ret = r2; - - return ret; -} - -void sub_80C3A5C(u8 taskId) -{ - u16 firstTileNum; - - if (gTasks[taskId].data[10] == 0) - { - gTasks[taskId].data[11] = (3 - gTasks[taskId].data[0]) * 40; - gTasks[taskId].data[10]++; - } - else if (gTasks[taskId].data[10] == 1) - { - if (--gTasks[taskId].data[11] == -1) - { - firstTileNum = gTasks[taskId].data[0] * 2 + 0x5043; - *(vu16 *)(0x0600E142 + gTasks[taskId].data[1] * 192) = firstTileNum + 0x00; - *(vu16 *)(0x0600E144 + gTasks[taskId].data[1] * 192) = firstTileNum + 0x01; - *(vu16 *)(0x0600E182 + gTasks[taskId].data[1] * 192) = firstTileNum + 0x10; - *(vu16 *)(0x0600E184 + gTasks[taskId].data[1] * 192) = firstTileNum + 0x11; - eContestLink80C2020Struct2018000.unk_05++; - DestroyTask(taskId); - PlaySE(SE_JYUNI); - } - } -} - -#ifdef NONMATCHING -void sub_80C3B30(u8 taskId) -{ - int i, j, k; - - for (i = 0; i < 4 && gContestFinalStandings[i] != 0; i++) - ; - - for (j = 0; j < 3; j++) - { - for (k = 0; k < 30; k++) - { - ((u16 *)(0x0600E100 + 2 * (96 * i + 32 * j)))[k] &= 0x0FFF; - ((u16 *)(0x0600E100 + 2 * (96 * i + 32 * j)))[k] |= 0x9000; - } - } - gTasks[taskId].data[10] = i; - gTasks[taskId].data[12] = 1; - gTasks[taskId].func = sub_80C3BD8; - eContestLink80C2020Struct2018000.unk_03 = taskId; -} -#else -NAKED -void sub_80C3B30(u8 taskId) -{ - asm_unified("\tpush {r4-r7,lr}\n" - "\tmov r7, r10\n" - "\tmov r6, r9\n" - "\tmov r5, r8\n" - "\tpush {r5-r7}\n" - "\tlsls r0, 24\n" - "\tlsrs r0, 24\n" - "\tmov r12, r0\n" - "\tmovs r5, 0\n" - "\tldr r1, _080C3BC0 @ =gContestFinalStandings\n" - "\tldrb r0, [r1]\n" - "\tldr r2, _080C3BC4 @ =gTasks\n" - "\tmov r10, r2\n" - "\tcmp r0, 0\n" - "\tbeq _080C3B5C\n" - "_080C3B4E:\n" - "\tadds r5, 0x1\n" - "\tcmp r5, 0x3\n" - "\tbgt _080C3B5C\n" - "\tadds r0, r5, r1\n" - "\tldrb r0, [r0]\n" - "\tcmp r0, 0\n" - "\tbne _080C3B4E\n" - "_080C3B5C:\n" - "\tmovs r1, 0\n" - "\tlsls r0, r5, 1\n" - "\tmov r2, r12\n" - "\tlsls r2, 2\n" - "\tmov r9, r2\n" - "\tadds r0, r5\n" - "\tlsls r0, 5\n" - "\tmov r8, r0\n" - "\tldr r7, _080C3BC8 @ =0x00000fff\n" - "\tmovs r0, 0x90\n" - "\tlsls r0, 8\n" - "\tadds r6, r0, 0\n" - "_080C3B74:\n" - "\tlsls r0, r1, 5\n" - "\tadds r4, r1, 0x1\n" - "\tadd r0, r8\n" - "\t@ the next two instructions are swapped\n" - "\tmovs r3, 0x1D\n" - "\tlsls r0, 1\n" - "\tldr r1, _080C3BCC @ =0x0600e100\n" - "\tadds r2, r0, r1\n" - "_080C3B82:\n" - "\tldrh r1, [r2]\n" - "\tadds r0, r7, 0\n" - "\tands r0, r1\n" - "\torrs r0, r6\n" - "\tstrh r0, [r2]\n" - "\tadds r2, 0x2\n" - "\tsubs r3, 0x1\n" - "\tcmp r3, 0\n" - "\tbge _080C3B82\n" - "\tadds r1, r4, 0\n" - "\tcmp r1, 0x2\n" - "\tble _080C3B74\n" - "\tmov r0, r9\n" - "\tadd r0, r12\n" - "\tlsls r0, 3\n" - "\tadd r0, r10\n" - "\tstrh r5, [r0, 0x1C]\n" - "\tmovs r1, 0x1\n" - "\tstrh r1, [r0, 0x20]\n" - "\tldr r2, _080C3BD0 @ =sub_80C3BD8\n" - "\tstr r2, [r0]\n" - "\tmov r1, r12\n" - "\tldr r0, _080C3BD4 @ =gSharedMem + 0x18000\n" - "\tstrb r1, [r0, 0x3]\n" - "\tpop {r3-r5}\n" - "\tmov r8, r3\n" - "\tmov r9, r4\n" - "\tmov r10, r5\n" - "\tpop {r4-r7}\n" - "\tpop {r0}\n" - "\tbx r0\n" - "\t.align 2, 0\n" - "_080C3BC0: .4byte gContestFinalStandings\n" - "_080C3BC4: .4byte gTasks\n" - "_080C3BC8: .4byte 0x00000fff\n" - "_080C3BCC: .4byte 0x0600e100\n" - "_080C3BD0: .4byte sub_80C3BD8\n" - "_080C3BD4: .4byte gSharedMem + 0x18000"); -} -#endif //NONMATCHING - -void sub_80C3BD8(u8 taskId) -{ - if (++gTasks[taskId].data[11] == 1) - { - gTasks[taskId].data[11] = 0; - BlendPalette(0x91, 1, gTasks[taskId].data[12], RGB(13, 28, 27)); - if (gTasks[taskId].data[13] == 0) - { - if (++gTasks[taskId].data[12] == 16) - gTasks[taskId].data[13] = 1; - } - else - { - if (--gTasks[taskId].data[12] == 0) - gTasks[taskId].data[13] = 0; - } - } -} - -void sub_80C3C44(struct Sprite *sprite) -{ - if (sprite->data[0] < 10) - { - if (++sprite->data[0] == 10) - { - PlayCry1(sprite->data[1], 0); - sprite->data[1] = 0; - } - } - else - { - s16 delta = (u16)sprite->data[1] + 0x600; - sprite->pos1.x -= delta >> 8; - sprite->data[1] = (sprite->data[1] + 0x600) & 0xFF; - if (sprite->pos1.x < 120) - sprite->pos1.x = 120; - - if (sprite->pos1.x == 120) - { - sprite->callback = SpriteCallbackDummy; - sprite->data[1] = 0; - eContestLink80C2020Struct2018000.unk_06 = 1; - } - } -} - -void sub_80C3CB8(struct Sprite *sprite) -{ - s16 delta = (u16)sprite->data[1] + 0x600; - sprite->pos1.x -= delta >> 8; - sprite->data[1] = (sprite->data[1] + 0x600) & 0xFF; - if (sprite->pos1.x < -32) - { - sprite->callback = SpriteCallbackDummy; - sprite->invisible = 1; - eContestLink80C2020Struct2018000.unk_06 = 2; - } -} - -void sub_80C3D04(u8 taskId) -{ - if (++gTasks[taskId].data[0] == 5) - { - gTasks[taskId].data[0] = 0; - if (eContestLink80C2020Struct2018000.unk_07 < 40) - { - u8 spriteId = CreateSprite(&gSpriteTemplate_83D17B4, (Random() % 240) - 20, 44, 5); - gSprites[spriteId].data[0] = Random() % 512; - gSprites[spriteId].data[1] = (Random() % 24) + 16; - gSprites[spriteId].data[2] = (Random() % 256) + 48; - gSprites[spriteId].oam.tileNum += Random() % 17; - eContestLink80C2020Struct2018000.unk_07++; - } - } - - if (eContestLink80C2020Struct2018000.unk_09) - DestroyTask(taskId); -} - -void sub_80C3DF0(struct Sprite *sprite) -{ - register s16 var0 asm("r1"); - - sprite->data[3] += sprite->data[0]; - sprite->pos2.x = Sin(sprite->data[3] >> 8, sprite->data[1]); - var0 = sprite->data[4] + sprite->data[2]; - sprite->pos1.x += var0 >> 8; - var0 = var0 & 0xFF; - sprite->data[4] = var0; - sprite->pos1.y++; - if (eContestLink80C2020Struct2018000.unk_09) - sprite->invisible = 1; - - if (sprite->pos1.x > 248 || sprite->pos1.y > 116) - { - DestroySprite(sprite); - eContestLink80C2020Struct2018000.unk_07--; - } -} - -void sub_80C3E60(u8 monIndex, u8 numFrames) -{ - u8 taskId = CreateTask(sub_80C3EA4, 8); - gTasks[taskId].data[0] = monIndex; - gTasks[taskId].data[1] = numFrames; - gTasks[taskId].data[2] = gContestMons[monIndex].species; -} - -void sub_80C3EA4(u8 taskId) -{ - u8 monIndex = gTasks[taskId].data[0]; - if (gTasks[taskId].data[10]++ == gTasks[taskId].data[1]) - { - gTasks[taskId].data[10] = 0; - sub_80C3024(gTasks[taskId].data[2], monIndex, gTasks[taskId].data[11], FALSE, gContestMons[monIndex].personality); - gTasks[taskId].data[11] ^= 1; - } -} - -void sub_80C3F00(void) -{ - s32 i; - s16 r2 = gUnknown_02038678[0]; - s32 r4; - u32 r5; - s8 r0; - - for (i = 1; i < 4; i++) - { - if (r2 < gUnknown_02038678[i]) - r2 = gUnknown_02038678[i]; - } - - if (r2 < 0) - { - r2 = gUnknown_02038678[0]; - - for (i = 1; i < 4; i++) - { - if (r2 > gUnknown_02038678[i]) - r2 = gUnknown_02038678[i]; - } - } - - for (i = 0; i < 4; i++) - { - r4 = 1000 * gContestMonConditions[i] / ABS(r2); - if ((r4 % 10) >= 5) - r4 += 10; - eContestLink80C2020Struct2018018[i].unk_00 = r4 / 10; - - r4 = 1000 * ABS(gUnknown_02038688[i]) / ABS(r2); - if ((r4 % 10) >= 5) - r4 += 10; - eContestLink80C2020Struct2018018[i].unk_04 = r4 / 10; - - if (gUnknown_02038688[i] < 0) - eContestLink80C2020Struct2018018[i].unk_10 = 1; - - r5 = 22528 * eContestLink80C2020Struct2018018[i].unk_00 / 100; - if ((r5 % 256) >= 128) - r5 += 256; - eContestLink80C2020Struct2018018[i].unk_08 = r5 / 256; - - r5 = eContestLink80C2020Struct2018018[i].unk_04 * 22528 / 100; - if ((r5 % 256) >= 128) - r5 += 256; - eContestLink80C2020Struct2018018[i].unk_0c = r5 / 256; - - eContestLink80C2020Struct2018018[i].unk_11 = sub_80C3990(i, 1); - r0 = sub_80C39E4(i, 1); - eContestLink80C2020Struct2018018[i].unk_12 = ABS(r0); - - if (gContestFinalStandings[i]) - { - s16 r2__ = eContestLink80C2020Struct2018018[i].unk_08; - s16 r1__ = eContestLink80C2020Struct2018018[i].unk_0c; - if (eContestLink80C2020Struct2018018[i].unk_10) - r1__ = -r1__; - if (r2__ + r1__ == 88) - { - if (r1__ > 0) - eContestLink80C2020Struct2018018[i].unk_0c--; - else if (r2__ > 0) - eContestLink80C2020Struct2018018[i].unk_08--; - } - } - } -} - -#ifdef NONMATCHING -void sub_80C40D4(u8 arg0, u8 arg1) -{ - int i; - u8 taskId; - u8 sp8, spC; - - sp8 = 0; - spC = 0; - if (!arg0) - { - u32 var0; - for (i = 0; i < 4; i++) - { - u8 var1 = eContestLink80C2020Struct2018018[i].unk_11; - if (arg1 < var1) - { - int x = var1 + 19; - x += 32 * (i * 3 + 5); - x -= arg1; - x--; - *(vu16 *)(0x0600C000 + 2 * x) = 0x60B3; - taskId = CreateTask(sub_80C42C0, 10); - var0 = ((eContestLink80C2020Struct2018018[i].unk_08 << 16) / eContestLink80C2020Struct2018018[i].unk_11) * (arg1 + 1); - if ((var0 % 0x10000) >= 0x8000) - var0 += 0x10000; - - gTasks[taskId].data[0] = i; - gTasks[taskId].data[1] = var0 >> 16; - eContestLink80C2020Struct2018000.unk_14++; - sp8++; - } - } - } - else - { - u32 var0; - for (i = 0; i < 4; i++) - { - int tile; - s8 var1 = eContestLink80C2020Struct2018018[i].unk_12; - tile = eContestLink80C2020Struct2018018[i].unk_10 ? 0x60A5 : 0x60A3; - if (arg1 < var1) - { - int x = var1 + 19; - x += 32 * (i * 3 + 6); - x -= arg1; - x--; - *(vu16 *)(0x0600C000 + 2 * x) = tile; - taskId = CreateTask(sub_80C42C0, 10); - var0 = ((eContestLink80C2020Struct2018018[i].unk_0c << 16) / eContestLink80C2020Struct2018018[i].unk_12) * (arg1 + 1); - if ((var0 % 0x10000) >= 0x8000) - var0 += 0x10000; - - gTasks[taskId].data[0] = i; - if (eContestLink80C2020Struct2018018[i].unk_10) - { - gTasks[taskId].data[2] = 1; - spC++; - } - else - { - sp8++; - } - - if (eContestLink80C2020Struct2018018[i].unk_10) - gTasks[taskId].data[1] = -(var0 >> 16) + eContestLink80C2020Struct2018018[i].unk_08; - else - gTasks[taskId].data[1] = (var0 >> 16) + eContestLink80C2020Struct2018018[i].unk_08; - - eContestLink80C2020Struct2018000.unk_14++; - } - } - } - - if (spC) - PlaySE(SE_BOO); - - if (sp8) - PlaySE(SE_PIN); -} -#else -// Assorted register differences -NAKED -void sub_80C40D4(u8 arg0, u8 arg1) -{ - asm_unified("\tpush {r4-r7,lr}\n" - "\tmov r7, r10\n" - "\tmov r6, r9\n" - "\tmov r5, r8\n" - "\tpush {r5-r7}\n" - "\tsub sp, 0x8\n" - "\tlsls r0, 24\n" - "\tlsls r1, 24\n" - "\tlsrs r7, r1, 24\n" - "\tmovs r1, 0\n" - "\tmov r10, r1\n" - "\tmovs r2, 0\n" - "\tstr r2, [sp]\n" - "\tcmp r0, 0\n" - "\tbne _080C4198\n" - "\tmov r8, r2\n" - "\tldr r0, _080C417C @ =gSharedMem + 0x18018\n" - "\tsubs r1, 0x18\n" - "\tadds r1, r0\n" - "\tmov r9, r1\n" - "\tadds r4, r0, 0\n" - "\tadds r4, 0x8\n" - "\tmovs r6, 0xA0\n" - "_080C4102:\n" - "\tldrb r0, [r4, 0x9]\n" - "\tcmp r7, r0\n" - "\tbcs _080C416A\n" - "\tadds r0, 0x13\n" - "\tadds r0, r6, r0\n" - "\tsubs r0, r7\n" - "\tlsls r0, 1\n" - "\tldr r2, _080C4180 @ =0x0600bffe\n" - "\tadds r0, r2\n" - "\tldr r2, _080C4184 @ =0x000060b3\n" - "\tadds r1, r2, 0\n" - "\tstrh r1, [r0]\n" - "\tldr r0, _080C4188 @ =sub_80C42C0\n" - "\tmovs r1, 0xA\n" - "\tbl CreateTask\n" - "\tlsls r0, 24\n" - "\tlsrs r5, r0, 24\n" - "\tldr r0, [r4]\n" - "\tlsls r0, 16\n" - "\tldrb r1, [r4, 0x9]\n" - "\tbl __udivsi3\n" - "\tadds r1, r7, 0x1\n" - "\tadds r3, r0, 0\n" - "\tmuls r3, r1\n" - "\tldr r0, _080C418C @ =0x0000ffff\n" - "\tands r0, r3\n" - "\tldr r1, _080C4190 @ =0x00007fff\n" - "\tcmp r0, r1\n" - "\tbls _080C4146\n" - "\tmovs r0, 0x80\n" - "\tlsls r0, 9\n" - "\tadds r3, r0\n" - "_080C4146:\n" - "\tldr r1, _080C4194 @ =gTasks\n" - "\tlsls r0, r5, 2\n" - "\tadds r0, r5\n" - "\tlsls r0, 3\n" - "\tadds r0, r1\n" - "\tmov r1, r8\n" - "\tstrh r1, [r0, 0x8]\n" - "\tlsrs r1, r3, 16\n" - "\tstrh r1, [r0, 0xA]\n" - "\tmov r2, r9\n" - "\tldrb r0, [r2, 0x14]\n" - "\tadds r0, 0x1\n" - "\tstrb r0, [r2, 0x14]\n" - "\tmov r0, r10\n" - "\tadds r0, 0x1\n" - "\tlsls r0, 24\n" - "\tlsrs r0, 24\n" - "\tmov r10, r0\n" - "_080C416A:\n" - "\tadds r4, 0x14\n" - "\tadds r6, 0x60\n" - "\tmovs r0, 0x1\n" - "\tadd r8, r0\n" - "\tmov r1, r8\n" - "\tcmp r1, 0x3\n" - "\tble _080C4102\n" - "\tb _080C4292\n" - "\t.align 2, 0\n" - "_080C417C: .4byte gSharedMem + 0x18018\n" - "_080C4180: .4byte 0x0600bffe\n" - "_080C4184: .4byte 0x000060b3\n" - "_080C4188: .4byte sub_80C42C0\n" - "_080C418C: .4byte 0x0000ffff\n" - "_080C4190: .4byte 0x00007fff\n" - "_080C4194: .4byte gTasks\n" - "_080C4198:\n" - "\tmovs r2, 0\n" - "\tmov r8, r2\n" - "\tldr r0, _080C4220 @ =gSharedMem + 0x18018\n" - "\tmov r12, r0\n" - "\tmov r9, r2\n" - "\tmovs r1, 0xC0\n" - "\tstr r1, [sp, 0x4]\n" - "_080C41A6:\n" - "\tmov r6, r9\n" - "\tadd r6, r12\n" - "\tldrb r1, [r6, 0x12]\n" - "\tldrb r0, [r6, 0x10]\n" - "\tldr r2, _080C4224 @ =0x000060a3\n" - "\tcmp r0, 0\n" - "\tbeq _080C41B6\n" - "\tadds r2, 0x2\n" - "_080C41B6:\n" - "\tlsls r0, r1, 24\n" - "\tasrs r0, 24\n" - "\tcmp r7, r0\n" - "\tbge _080C427E\n" - "\tadds r0, 0x13\n" - "\tldr r1, [sp, 0x4]\n" - "\tadds r0, r1, r0\n" - "\tsubs r0, r7\n" - "\tlsls r0, 1\n" - "\tldr r1, _080C4228 @ =0x0600bffe\n" - "\tadds r0, r1\n" - "\tstrh r2, [r0]\n" - "\tldr r0, _080C422C @ =sub_80C42C0\n" - "\tmovs r1, 0xA\n" - "\tbl CreateTask\n" - "\tlsls r0, 24\n" - "\tlsrs r5, r0, 24\n" - "\tldr r0, [r6, 0xC]\n" - "\tlsls r0, 16\n" - "\tldrb r1, [r6, 0x12]\n" - "\tbl __udivsi3\n" - "\tadds r1, r7, 0x1\n" - "\tadds r3, r0, 0\n" - "\tmuls r3, r1\n" - "\tldr r0, _080C4230 @ =0x0000ffff\n" - "\tands r0, r3\n" - "\tldr r1, _080C4234 @ =0x00007fff\n" - "\tcmp r0, r1\n" - "\tbls _080C41FA\n" - "\tmovs r2, 0x80\n" - "\tlsls r2, 9\n" - "\tadds r3, r2\n" - "_080C41FA:\n" - "\tldr r1, _080C4238 @ =gTasks\n" - "\tlsls r2, r5, 2\n" - "\tadds r0, r2, r5\n" - "\tlsls r0, 3\n" - "\tadds r4, r0, r1\n" - "\tmov r0, r8\n" - "\tstrh r0, [r4, 0x8]\n" - "\tldrb r0, [r6, 0x10]\n" - "\tadds r6, r1, 0\n" - "\tcmp r0, 0\n" - "\tbeq _080C423C\n" - "\tmovs r0, 0x1\n" - "\tstrh r0, [r4, 0xC]\n" - "\tldr r0, [sp]\n" - "\tadds r0, 0x1\n" - "\tlsls r0, 24\n" - "\tlsrs r0, 24\n" - "\tstr r0, [sp]\n" - "\tb _080C4246\n" - "\t.align 2, 0\n" - "_080C4220: .4byte gSharedMem + 0x18018\n" - "_080C4224: .4byte 0x000060a3\n" - "_080C4228: .4byte 0x0600bffe\n" - "_080C422C: .4byte sub_80C42C0\n" - "_080C4230: .4byte 0x0000ffff\n" - "_080C4234: .4byte 0x00007fff\n" - "_080C4238: .4byte gTasks\n" - "_080C423C:\n" - "\tmov r0, r10\n" - "\tadds r0, 0x1\n" - "\tlsls r0, 24\n" - "\tlsrs r0, 24\n" - "\tmov r10, r0\n" - "_080C4246:\n" - "\tldr r0, _080C4264 @ =gSharedMem + 0x18018\n" - "\tmov r1, r9\n" - "\tadds r4, r1, r0\n" - "\tldrb r1, [r4, 0x10]\n" - "\tmov r12, r0\n" - "\tcmp r1, 0\n" - "\tbeq _080C4268\n" - "\tadds r0, r2, r5\n" - "\tlsls r0, 3\n" - "\tadds r0, r6\n" - "\tlsrs r2, r3, 16\n" - "\tldr r1, [r4, 0x8]\n" - "\tsubs r1, r2\n" - "\tb _080C4274\n" - "\t.align 2, 0\n" - "_080C4264: .4byte gSharedMem + 0x18018\n" - "_080C4268:\n" - "\tadds r0, r2, r5\n" - "\tlsls r0, 3\n" - "\tadds r0, r6\n" - "\tlsrs r2, r3, 16\n" - "\tldr r1, [r4, 0x8]\n" - "\tadds r1, r2\n" - "_080C4274:\n" - "\tstrh r1, [r0, 0xA]\n" - "\tldr r1, _080C42BC @ =gSharedMem + 0x18000\n" - "\tldrb r0, [r1, 0x14]\n" - "\tadds r0, 0x1\n" - "\tstrb r0, [r1, 0x14]\n" - "_080C427E:\n" - "\tmovs r2, 0x14\n" - "\tadd r9, r2\n" - "\tldr r0, [sp, 0x4]\n" - "\tadds r0, 0x60\n" - "\tstr r0, [sp, 0x4]\n" - "\tmovs r1, 0x1\n" - "\tadd r8, r1\n" - "\tmov r2, r8\n" - "\tcmp r2, 0x3\n" - "\tble _080C41A6\n" - "_080C4292:\n" - "\tldr r0, [sp]\n" - "\tcmp r0, 0\n" - "\tbeq _080C429E\n" - "\tmovs r0, 0x16\n" - "\tbl PlaySE\n" - "_080C429E:\n" - "\tmov r1, r10\n" - "\tcmp r1, 0\n" - "\tbeq _080C42AA\n" - "\tmovs r0, 0x15\n" - "\tbl PlaySE\n" - "_080C42AA:\n" - "\tadd sp, 0x8\n" - "\tpop {r3-r5}\n" - "\tmov r8, r3\n" - "\tmov r9, r4\n" - "\tmov r10, r5\n" - "\tpop {r4-r7}\n" - "\tpop {r0}\n" - "\tbx r0\n" - "\t.align 2, 0\n" - "_080C42BC: .4byte gSharedMem + 0x18000"); -} -#endif //NONMATCHING - -void sub_80C42C0(u8 taskId /*r12*/) -{ - bool32 r6 = FALSE; - bool32 r9 = FALSE; - u8 r5 = gTasks[taskId].data[0]; - s16 r7 = gTasks[taskId].data[1]; - s16 r1 = gTasks[taskId].data[2]; - s32 i; - - if (r1 != 0) - { - if (eContestLink80C2020Struct2018000.unk_0c[r5] <= 0) - r6 = TRUE; - } - else - { - if (eContestLink80C2020Struct2018000.unk_0c[r5] >= 88) - r6 = TRUE; - } - if (eContestLink80C2020Struct2018000.unk_0c[r5] == r7) - r9 = TRUE; - - if (!r9) - { - if (r6) - { - eContestLink80C2020Struct2018000.unk_0c[r5] = r7; - } - else if (r1 != 0) - { - eContestLink80C2020Struct2018000.unk_0c[r5]--; - } - else - { - eContestLink80C2020Struct2018000.unk_0c[r5]++; - } - } - if (!r6) - { - if (!r9) - { - for (i = 0; i < 11; i++) - { - u8 r0; - u16 tile; - if (eContestLink80C2020Struct2018000.unk_0c[r5] >= 8 * (i + 1)) - { - r0 = 8; - } - else if (eContestLink80C2020Struct2018000.unk_0c[r5] >= 8 * i) - { - r0 = eContestLink80C2020Struct2018000.unk_0c[r5] % 8; - } - else - { - r0 = 0; - } - if (r0 < 4) - tile = 0x504C + r0; - else - tile = 0x5057 + r0; - *(vu16 *)(0x0600E18E + 2 * (96 * r5 + i)) = tile; - } - } - } - if (r9) - { - eContestLink80C2020Struct2018000.unk_14--; - DestroyTask(taskId); - } -} - -void ScrSpecial_CheckSelectedMonAndInitContest(void) -{ - u8 result = CanMonParticipateInContest(&gPlayerParty[gContestMonPartyIndex]); - if (result != 0) - { - Contest_InitAllPokemon(gSpecialVar_ContestCategory, gSpecialVar_ContestRank); - InitContestMonConditions(gSpecialVar_ContestCategory); - } - gSpecialVar_Result = result; -} - -u16 ScrSpecial_CanMonParticipateInSelectedLinkContest(void) -{ - u16 result = 0; - struct Pokemon *mon = &gPlayerParty[gContestMonPartyIndex]; - switch (gSpecialVar_ContestCategory) - { - case CONTEST_CATEGORY_COOL: - if (GetMonData(mon, MON_DATA_COOL_RIBBON) > gSpecialVar_ContestRank) - result = 1; - break; - case CONTEST_CATEGORY_BEAUTY: - if (GetMonData(mon, MON_DATA_BEAUTY_RIBBON) > gSpecialVar_ContestRank) - result = 1; - break; - case CONTEST_CATEGORY_CUTE: - if (GetMonData(mon, MON_DATA_CUTE_RIBBON) > gSpecialVar_ContestRank) - result = 1; - break; - case CONTEST_CATEGORY_SMART: - if (GetMonData(mon, MON_DATA_SMART_RIBBON) > gSpecialVar_ContestRank) - result = 1; - break; - case CONTEST_CATEGORY_TOUGH: - if (GetMonData(mon, MON_DATA_TOUGH_RIBBON) > gSpecialVar_ContestRank) - result = 1; - break; - } - - return result; -} - - -void ScrSpecial_GiveContestRibbon(void) -{ - u8 ribbonData; - - if (gContestFinalStandings[gContestPlayerMonIndex] != 0) - return; - - switch (gSpecialVar_ContestCategory) - { - case CONTEST_CATEGORY_COOL: - ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON); - if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) - { - ribbonData++; - SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON, &ribbonData); - } - break; - case CONTEST_CATEGORY_BEAUTY: - ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON); - if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) - { - ribbonData++; - SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON, &ribbonData); - } - break; - case CONTEST_CATEGORY_CUTE: - ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON); - if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) - { - ribbonData++; - SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON, &ribbonData); - } - break; - case CONTEST_CATEGORY_SMART: - ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON); - if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) - { - ribbonData++; - SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON, &ribbonData); - } - break; - case CONTEST_CATEGORY_TOUGH: - ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON); - if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) - { - ribbonData++; - SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON, &ribbonData); - } - break; - } -} - -void Contest_CopyAndConvertTrainerName_Intl(u8 * dest, const u8 * src) -{ - StringCopy(dest, src); - if (dest[0] == EXT_CTRL_CODE_BEGIN && dest[1] == 0x15) - ConvertInternationalString(dest, LANGUAGE_JAPANESE); -} - -void Contest_CopyAndConvertNicknameI_Intl(u8 * dest, u8 idx) -{ - StringCopy(dest, gContestMons[idx].nickname); - if (gIsLinkContest & 1) - { - if (gLinkPlayers[idx].language == LANGUAGE_JAPANESE) - { - ConvertInternationalString(dest, GetStringLanguage(dest)); - } - } -} - -void Contest_GetTrainerNameI_StringVar1(void) -{ - if (gIsLinkContest & 1) - { - Contest_CopyAndConvertTrainerName_Intl(gStringVar1, gLinkPlayers[gSpecialVar_0x8006].name); - } - else - { - Contest_CopyAndConvertTrainerName_Intl(gStringVar1, gContestMons[gSpecialVar_0x8006].trainerName); - } -} - -void Contest_GetNicknameI_StringVar1(void) -{ - Contest_CopyAndConvertNicknameI_Intl(gStringVar3, gSpecialVar_0x8006); -} - -void ScrSpecial_CountContestMonsWithBetterCondition(void) -{ - u8 i; - u8 count; - - for (i = 0, count = 0; i < 4; i++) - { - if (gContestMonConditions[gSpecialVar_0x8006] < gContestMonConditions[i]) - count++; - } - - gSpecialVar_0x8004 = count; -} - -void ScrSpecial_GetMonCondition(void) -{ - gSpecialVar_0x8004 = gContestMonConditions[gSpecialVar_0x8006]; -} - -void ScrSpecial_GetContestWinnerIdx(void) -{ - u8 i; - - for (i = 0; i < 4 && gContestFinalStandings[i] != 0; i++) - ; - - gSpecialVar_0x8005 = i; -} - -void ScrSpecial_GetContestWinnerTrainerName(void) -{ - u8 i; - - for (i = 0; i < 4 && gContestFinalStandings[i] != 0; i++) - ; - - if (gIsLinkContest & 1) - { - Contest_CopyAndConvertTrainerName_Intl(gStringVar3, gLinkPlayers[i].name); - } - else - { - Contest_CopyAndConvertTrainerName_Intl(gStringVar3, gContestMons[i].trainerName); - } -} - -void ScrSpecial_GetContestWinnerNick(void) -{ - u8 i; - - for (i = 0; i < 4 && gContestFinalStandings[i] != 0; i++) - ; - - Contest_CopyAndConvertNicknameI_Intl(gStringVar1, i); -} - -void sub_80C488C(void) -{ - SetMainCallback2(CB2_StartContest); -} - -void sub_80C489C(u8 taskId) -{ - if (!gPaletteFade.active) - { - DestroyTask(taskId); - SetMainCallback2(sub_80C488C); - } -} - -void sub_80C48C8(void) -{ - ScriptContext2_Enable(); - CreateTask(sub_80C489C, 10); - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); -} - -void sub_80C48F4(void) -{ - gSpecialVar_0x8004 = gContestMons[gSpecialVar_0x8006].species; -} - -void sub_80C4914(u8 taskId) -{ - if (!gPaletteFade.active) - { - DestroyTask(taskId); - SetMainCallback2(sub_80C2358); - } -} - -void sub_80C4940(void) -{ - ScriptContext2_Enable(); - CreateTask(sub_80C4914, 10); - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); -} - -void ScrSpecial_GetContestPlayerMonIdx(void) -{ - gSpecialVar_0x8004 = gContestPlayerMonIndex; -} - -void sub_80C4980(u8 taskId) -{ - u8 taskId2; - ScriptContext2_Enable(); - taskId2 = CreateTask(sub_80C8604, 0); - SetTaskFuncWithFollowupFunc(taskId2, sub_80C8604, sub_80C49C4); - gTasks[taskId2].data[9] = taskId; -} - -void sub_80C49C4(u8 taskId) -{ - Contest_CreatePlayerMon(gContestMonPartyIndex); - SetTaskFuncWithFollowupFunc(taskId, sub_80C8734, sub_80C49F0); -} - -void sub_80C49F0(u8 taskId) -{ - SetTaskFuncWithFollowupFunc(taskId, sub_80C88AC, sub_80C4A0C); -} - -void sub_80C4A0C(u8 taskId) -{ - SetTaskFuncWithFollowupFunc(taskId, sub_80C8E1C, sub_80C4A28); -} - -void sub_80C4A28(u8 taskId) -{ - SetTaskFuncWithFollowupFunc(taskId, sub_80C8938, sub_80C4A44); -} - -void sub_80C4A44(u8 taskId) -{ - u8 i; - u8 sp0[4]; - u8 sp4[4]; - - for (i = 0; i < 4; i++) - sp0[i] = gTasks[taskId].data[i + 1]; - - for (i = 0; i < 4; i++) - { - if (sp0[0] != sp0[i]) - break; - } - - if (i == 4) - gSpecialVar_0x8004 = 0; - else - gSpecialVar_0x8004 = 1; - - for (i = 0; i < 4; i++) - sp4[i] = gTasks[taskId].data[i + 5]; - - gUnknown_0203869B = sub_80C4B34(sp4); - InitContestMonConditions(gSpecialVar_ContestCategory); - SetTaskFuncWithFollowupFunc(taskId, sub_80C8EBC, sub_80C4B0C); -} - -void sub_80C4B0C(u8 taskId) -{ - sub_80B0F28(0); - SetTaskFuncWithFollowupFunc(taskId, sub_80C8F34, sub_80C4B5C); -} - -u8 sub_80C4B34(u8 * a0) -{ - s32 i; - u8 result = 0; - - for (i = 1; i < 4; i++) - { - if (a0[result] < a0[i]) - result = i; - } - - return result; -} - -void sub_80C4B5C(u8 taskId) -{ - if (gSpecialVar_0x8004 == 1) - { - if (IsLinkTaskFinished()) - gTasks[taskId].func = sub_80C4BA4; - } - else - { - DestroyTask(taskId); - ScriptContext2_Disable(); - EnableBothScriptContexts(); - } -} - -void sub_80C4BA4(u8 taskId) -{ - sub_800832C(); - gTasks[taskId].func = sub_80C4BCC; -} - -void sub_80C4BCC(u8 taskId) -{ - if (!gReceivedRemoteLinkPlayers) - { - DestroyTask(taskId); - ScriptContext2_Disable(); - EnableBothScriptContexts(); - } -} diff --git a/src/battle/contest_link_80C857C.c b/src/battle/contest_link_80C857C.c deleted file mode 100644 index a694380df..000000000 --- a/src/battle/contest_link_80C857C.c +++ /dev/null @@ -1,755 +0,0 @@ -#include "global.h" -#include "ewram.h" -#include "random.h" -#include "task.h" -#include "contest.h" -#include "text.h" -#include "string_util.h" -#include "link.h" - -static void sub_80C8644(u8 taskId); -static void sub_80C8660(u8 taskId); -#if GERMAN -static void de_sub_80C9274(bool32 arg0); -static void de_sub_80C9294(bool32 arg0); -#endif - -static void SendBlockToAllOpponents(const void *data, u16 size) -{ - memcpy(eContestLinkSendBuffer, data, size); - SendBlock(bitmask_all_link_players_but_self(), eContestLinkSendBuffer, size); -} - -static bool8 HasPlayerReceivedBlock(u8 who) -{ - u8 flag = 1 << who; - if (!(GetBlockReceivedStatus() & flag)) - return FALSE; - ResetBlockReceivedFlag(flag); - return TRUE; -} - -static bool8 HaveAllPlayersReceivedBlock(void) -{ - int i; - - for (i = 0; i < MAX_LINK_PLAYERS; i++) - { - if (!((GetBlockReceivedStatus() >> i) & 1)) - return FALSE; - } - ResetBlockReceivedFlags(); - return TRUE; -} - -void sub_80C8604(u8 taskId) -{ -#if ENGLISH - u8 i; - - for (i = 0; i < 4; i++) - gBlockRecvBuffer[i][0] = 0xff; -#endif - gTasks[taskId].data[0] = 0; - gTasks[taskId].func = sub_80C8644; -} - -static void sub_80C8644(u8 taskId) -{ - gTasks[taskId].func = sub_80C8660; -} - -static void sub_80C8660(u8 taskId) -{ - if (gReceivedRemoteLinkPlayers) - { - gContestPlayerMonIndex = GetMultiplayerId(); - if (GetLinkPlayerCount() == MAX_LINK_PLAYERS) - { - gIsLinkContest = TRUE; - SwitchTaskToFollowupFunc(taskId); - } - } -} - -#ifdef NONMATCHING -u8 GetStringLanguage(const u8 *string) -{ - u8 language = GAME_LANGUAGE; - if (string[0] == EXT_CTRL_CODE_BEGIN && string[1] == 0x15) - return language; - if (StringLength(string) > 5) - return language; - for (; *string != EOS; string++) - { - if (!((*string >= CHAR_A && *string <= CHAR_z) || - (*string >= CHAR_0 + 0 && *string <= CHAR_0 + 9) || - *string == CHAR_SPACE || - *string == CHAR_PERIOD || - *string == CHAR_COMMA || - *string == 0xAB || - *string == CHAR_QUESTION_MARK || - *string == CHAR_MALE || - *string == CHAR_FEMALE || - *string == CHAR_SLASH || - *string == CHAR_HYPHEN || - *string == CHAR_ELLIPSIS || - *string == 0xB1 || - *string == 0xB2 || - *string == 0xB3 || - *string == 0xB1 - )) - { - language = LANGUAGE_JAPANESE; - break; - } - } - return language; -} -#else -NAKED u8 GetStringLanguage(const u8 *string) -{ - asm_unified("\tpush {r4,r5,lr}\n" - "\tadds r4, r0, 0\n" - ".ifdef ENGLISH\n" - "\tmovs r5, 0x2\n" - ".else\n" - "\tmovs r5, 0x5\n" - ".endif\n" - "\tldrb r0, [r4]\n" - "\tcmp r0, 0xFC\n" - "\tbne _080C86B6\n" - "\tldrb r0, [r4, 0x1]\n" - "\tcmp r0, 0x15\n" - "\tbne _080C86B6\n" - ".ifdef ENGLISH\n" - "\tmovs r0, 0x2\n" - ".else\n" - "\tmovs r0, 0x5\n" - ".endif\n" - "\tb _080C872C\n" - "_080C86B6:\n" - "\tadds r0, r4, 0\n" - "\tbl StringLength\n" - "\tlsls r0, 16\n" - "\tlsrs r0, 16\n" - "\tcmp r0, 0x5\n" - "\tbhi _080C872A\n" - "\tldrb r0, [r4]\n" - "\tcmp r0, 0xFF\n" - "\tbeq _080C872A\n" - "_080C86CA:\n" - "\tldrb r1, [r4]\n" - "\tadds r0, r1, 0\n" - "\tadds r0, 0x45\n" - "\tlsls r0, 24\n" - "\tlsrs r0, 24\n" - "\tcmp r0, 0x33\n" - "\tbls _080C871E\n" - "\tadds r0, r1, 0\n" - "\tadds r0, 0x5F\n" - "\tlsls r0, 24\n" - "\tlsrs r0, 24\n" - "\tcmp r0, 0x9\n" - "\tbls _080C871E\n" - "\tadds r0, r1, 0\n" - "\tcmp r0, 0\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xAD\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xB8\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xAB\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xAC\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xB5\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xB6\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xBA\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xAE\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xB0\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xB1\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xB2\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xB3\n" - "\tbeq _080C871E\n" - "\tcmp r0, 0xB1\n" - "\tbne _080C8728\n" - "_080C871E:\n" - "\tadds r4, 0x1\n" - "\tldrb r0, [r4]\n" - "\tcmp r0, 0xFF\n" - "\tbne _080C86CA\n" - "\tb _080C872A\n" - "_080C8728:\n" - "\tmovs r5, 0x1\n" - "_080C872A:\n" - "\tadds r0, r5, 0\n" - "_080C872C:\n" - "\tpop {r4,r5}\n" - "\tpop {r1}\n" - "\tbx r1"); -} -#endif - -void sub_80C8734(u8 taskId) -{ - int i; - u8 *name; - - switch (gTasks[taskId].data[0]) { -#if ENGLISH - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; -#elif GERMAN - case 8: -#endif - case 0: - if (GetMultiplayerId() == 0) { - if (IsLinkTaskFinished()) { -#if ENGLISH - memcpy(gBlockSendBuffer, gContestMons + gContestPlayerMonIndex, sizeof(struct ContestPokemon)); - sub_8007E9C(2); - gTasks[taskId].data[0]++; -#elif GERMAN - if (gTasks[taskId].data[0] == 0) - { - gTasks[taskId].data[0] = 3; - } - else - { - memcpy(gBlockSendBuffer, gContestMons + gContestPlayerMonIndex, sizeof(struct ContestPokemon)); - de_sub_80C9274(FALSE); - sub_8007E9C(2); - gTasks[taskId].data[0] = 1; - } -#endif - } - } - else - { - memcpy(gBlockSendBuffer, gContestMons + gContestPlayerMonIndex, sizeof(struct ContestPokemon)); -#if GERMAN - de_sub_80C9294(FALSE); -#endif - gTasks[taskId].data[0]++; - } - break; - case 1: - if (HaveAllPlayersReceivedBlock()) - { - for (i = 0; i < MAX_LINK_PLAYERS; i++) - { - memcpy(gContestMons + i, gBlockRecvBuffer[i], sizeof(struct ContestPokemon)); - name = gContestMons[i].nickname; - if (gLinkPlayers[i].language == LANGUAGE_JAPANESE) - { - ConvertInternationalString(name, GetStringLanguage(name)); - } - else if (name[10] == EXT_CTRL_CODE_BEGIN) - { - ConvertInternationalString(name, LANGUAGE_JAPANESE); - } else - { - name[5] = name[10]; - name[10] = EOS; - } - name = gContestMons[i].trainerName; - if (gLinkPlayers[i].language == LANGUAGE_JAPANESE) - { - name[7] = EOS; - name[6] = name[4]; - name[5] = name[3]; - name[4] = name[2]; - name[3] = name[1]; - name[2] = name[0]; - name[1] = 0x15; - name[0] = EXT_CTRL_CODE_BEGIN; - } - else - { - name[5] = name[7]; - name[7] = EOS; - } - } - gTasks[taskId].data[0]++; - } - break; -#if GERMAN - case 2: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - default: - gTasks[taskId].data[0]++; - break; -#endif - } -} - -void sub_80C88AC(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - case 0: - if (GetMultiplayerId() == 0) - { - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(&gRngValue, sizeof(u32)); - gTasks[taskId].data[0]++; - } - } - else - { - gTasks[taskId].data[0]++; - } - break; - case 1: - if (HasPlayerReceivedBlock(0)) - { - memcpy(&gRngValue, gBlockRecvBuffer[0], sizeof(u32)); - memcpy(&gContestRngValue, gBlockRecvBuffer[0], sizeof(u32)); - gTasks[taskId].data[0]++; - } - break; - } -} - -void sub_80C8938(u8 taskId) -{ - int i; - - switch (gTasks[taskId].data[0]) - { -#if ENGLISH - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; -#elif GERMAN - case 8: -#endif - case 0: - gBlockSendBuffer[0] = gTasks[taskId].data[9]; - if (GetMultiplayerId() == 0) - { - if (IsLinkTaskFinished()) - { -#if ENGLISH - sub_8007E9C(2); - gTasks[taskId].data[0]++; -#elif GERMAN - if (gTasks[taskId].data[0] == 0) - { - gTasks[taskId].data[0] = 3; - } - else - { - de_sub_80C9274(TRUE); - sub_8007E9C(2); - gTasks[taskId].data[0] = 1; - } -#endif - } - } - else - { -#if GERMAN - de_sub_80C9294(TRUE); -#endif - gTasks[taskId].data[0]++; - } - break; - case 1: - if (HaveAllPlayersReceivedBlock()) - { - for (i = 0; i < MAX_LINK_PLAYERS; i++) - { - gTasks[taskId].data[i + 1] = gBlockRecvBuffer[i][0]; - } - gTasks[taskId].data[0]++; - } - break; -#if GERMAN - case 2: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - default: - gTasks[taskId].data[0]++; - break; -#endif - } -} - -void sub_80C89DC(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - case 0: - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(&gContestPlayerMonIndex, sizeof(u8)); - gTasks[taskId].data[0]++; - } - break; - case 1: - if (HaveAllPlayersReceivedBlock()) - { - gTasks[taskId].data[0]++; - } - break; - } -} - -void sub_80C8A38(u8 taskId) -{ - int i; - - switch (gTasks[taskId].data[0]) - { - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - case 0: - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(&sContestantStatus[gContestPlayerMonIndex].currMove, sizeof(u16)); - gTasks[taskId].data[0]++; - } - break; - case 1: - if (HaveAllPlayersReceivedBlock()) - { - for (i = 0; i < MAX_LINK_PLAYERS; i++) - { - *&sContestantStatus[i].currMove = gBlockRecvBuffer[i][0]; - } - gTasks[taskId].data[0]++; - } - break; - } -} - -void sub_80C8AD0(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - case 0: - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(gUnknown_02038678, sizeof gUnknown_02038678); - gTasks[taskId].data[0]++; - } - break; - case 1: - if (HaveAllPlayersReceivedBlock()) - { - memcpy(gUnknown_02038678, gBlockRecvBuffer[gUnknown_0203869B], sizeof gUnknown_02038678); - gTasks[taskId].data[0]++; - } - break; - case 2: - case 5: - case 8: - case 11: - if (gTasks[taskId].data[1]++ > 10) - { - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[0]++; - } - break; - case 3: - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(gUnknown_02038680, sizeof gUnknown_02038680); - gTasks[taskId].data[0]++; - } - break; - case 4: - if (HaveAllPlayersReceivedBlock()) - { - memcpy(gUnknown_02038680, gBlockRecvBuffer[gUnknown_0203869B], sizeof gUnknown_02038680); - gTasks[taskId].data[0]++; - } - break; - case 6: - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(gUnknown_02038688, sizeof gUnknown_02038688); - gTasks[taskId].data[0]++; - } - break; - case 7: - if (HaveAllPlayersReceivedBlock()) - { - memcpy(gUnknown_02038688, gBlockRecvBuffer[gUnknown_0203869B], sizeof gUnknown_02038688); - gTasks[taskId].data[0]++; - } - break; - case 9: - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(gContestFinalStandings, sizeof gContestFinalStandings); - gTasks[taskId].data[0]++; - } - break; - case 10: - if (HaveAllPlayersReceivedBlock()) - { - memcpy(gContestFinalStandings, gBlockRecvBuffer[gUnknown_0203869B], sizeof gContestFinalStandings); - gTasks[taskId].data[0]++; - } - break; - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - } -} - -void sub_80C8C80(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - case 0: - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(sContestantStatus, 4 * sizeof(struct ContestantStatus)); - gTasks[taskId].data[0]++; - } - break; - case 1: - if (HaveAllPlayersReceivedBlock()) - { - memcpy(sContestantStatus, gBlockRecvBuffer[gUnknown_0203869B], 4 * sizeof(struct ContestantStatus)); - gTasks[taskId].data[0]++; - } - break; - case 2: - case 5: - case 8: - case 11: - if (gTasks[taskId].data[1]++ > 10) - { - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[0]++; - } - break; - case 3: - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(&shared192D0, sizeof shared192D0); - gTasks[taskId].data[0]++; - } - break; - case 4: - if (HaveAllPlayersReceivedBlock()) - { - memcpy(&shared192D0, gBlockRecvBuffer[gUnknown_0203869B], sizeof shared192D0); - gTasks[taskId].data[0]++; - } - break; - case 6: - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(&shared19328, sizeof shared19328); - gTasks[taskId].data[0]++; - } - break; - case 7: - if (HaveAllPlayersReceivedBlock()) - { - memcpy(&shared19328, gBlockRecvBuffer[gUnknown_0203869B], sizeof shared19328); - gTasks[taskId].data[0]++; - } - break; - case 9: - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(gUnknown_02038696, sizeof gUnknown_02038696); - gTasks[taskId].data[0]++; - } - break; - case 10: - if (HaveAllPlayersReceivedBlock()) - { - memcpy(gUnknown_02038696, gBlockRecvBuffer[gUnknown_0203869B], sizeof gUnknown_02038696); - gTasks[taskId].data[0]++; - } - break; - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - } -} - -void sub_80C8E1C(u8 taskId) -{ - int i; - - switch (gTasks[taskId].data[0]) - { -#if ENGLISH - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; -#elif GERMAN - case 8: -#endif - case 0: - gBlockSendBuffer[0] = 0x64; - if (GetMultiplayerId() == 0) - { - if (IsLinkTaskFinished()) - { -#if ENGLISH - sub_8007E9C(2); - gTasks[taskId].data[0]++; -#elif GERMAN - if (gTasks[taskId].data[0] == 0) - { - gTasks[taskId].data[0] = 3; - } - else - { - de_sub_80C9274(FALSE); - sub_8007E9C(2); - gTasks[taskId].data[0] = 1; - } -#endif - } - } - else - { -#if GERMAN - de_sub_80C9294(FALSE); -#endif - gTasks[taskId].data[0]++; - } - break; - case 1: - if (HaveAllPlayersReceivedBlock()) - { - for (i = 0; i < MAX_LINK_PLAYERS; i++) - { - gTasks[taskId].data[5 + i] = gBlockRecvBuffer[i][0]; - } - gTasks[taskId].data[0]++; - } - break; -#if GERMAN - case 2: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - default: - gTasks[taskId].data[0]++; - break; -#endif - } -} - -void sub_80C8EBC(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - case 0: - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(gContestMonConditions, sizeof gContestMonConditions); - gTasks[taskId].data[0]++; - } - break; - case 1: - if (HaveAllPlayersReceivedBlock()) - { - memcpy(gContestMonConditions, gBlockRecvBuffer[gUnknown_0203869B], sizeof gContestMonConditions); - gTasks[taskId].data[0]++; - } - break; - } -} - -void sub_80C8F34(u8 taskId) -{ - switch (gTasks[taskId].data[0]) - { - default: - gTasks[taskId].data[0] = 0; - SwitchTaskToFollowupFunc(taskId); - break; - case 0: - if (IsLinkTaskFinished()) - { - SendBlockToAllOpponents(gUnknown_02038696, sizeof gUnknown_02038696); - gTasks[taskId].data[0]++; - } - break; - case 1: - if (HaveAllPlayersReceivedBlock()) - { - memcpy(gUnknown_02038696, gBlockRecvBuffer[gUnknown_0203869B], sizeof gUnknown_02038696); - gTasks[taskId].data[0]++; - } - break; - } -} - -#if GERMAN - -static void de_sub_80C9274(bool32 arg0) -{ - if (deUnkValue2 == 1) - { - if (arg0) - deUnkValue2 = 3; - else - deUnkValue2 = 2; - } -} - -static void de_sub_80C9294(bool32 arg0) -{ - if (deUnkValue2 == 1) - { - if (arg0) - deUnkValue2 = 3; - else - deUnkValue2 = 2; - } - else if (deUnkValue2 == 2) - { - SendBlock(0, sBlockRequestLookupTable[deUnkValue1].address, sBlockRequestLookupTable[deUnkValue1].size); - if (arg0) - deUnkValue2 = 0; - else - deUnkValue2 = 1; - } -} - -#endif diff --git a/src/battle/pokeball.c b/src/battle/pokeball.c deleted file mode 100644 index abfdf2c3d..000000000 --- a/src/battle/pokeball.c +++ /dev/null @@ -1,1203 +0,0 @@ -#include "global.h" -#include "gba/m4a_internal.h" -#include "battle.h" -#include "battle_anim_813F0F4.h" -#include "decompress.h" -#include "graphics.h" -#include "m4a.h" -#include "main.h" -#include "pokeball.h" -#include "pokemon.h" -#include "rom_8077ABC.h" -#include "constants/songs.h" -#include "sound.h" -#include "sprite.h" -#include "task.h" -#include "trig.h" -#include "util.h" -#include "ewram.h" - -extern struct MusicPlayerInfo gMPlay_BGM; -extern u16 gBattleTypeFlags; -extern u8 gBankTarget; -extern u8 gActiveBattler; -extern u16 gBattlerPartyIndexes[]; -extern u8 gBankSpriteIds[]; -extern u8 gDoingBattleAnim; -extern u8 gHealthboxIDs[]; - -#define GFX_TAG_POKEBALL 55000 -#define GFX_TAG_GREATBALL 55001 -#define GFX_TAG_SAFARIBALL 55002 -#define GFX_TAG_ULTRABALL 55003 -#define GFX_TAG_MASTERBALL 55004 -#define GFX_TAG_NETBALL 55005 -#define GFX_TAG_DIVEBALL 55006 -#define GFX_TAG_NESTBALL 55007 -#define GFX_TAG_REPEATBALL 55008 -#define GFX_TAG_TIMERBALL 55009 -#define GFX_TAG_LUXURYBALL 55010 -#define GFX_TAG_PREMIERBALL 55011 - -static const struct CompressedSpriteSheet sBallSpriteSheets[] = -{ - {gInterfaceGfx_PokeBall, 384, GFX_TAG_POKEBALL}, - {gInterfaceGfx_GreatBall, 384, GFX_TAG_GREATBALL}, - {gInterfaceGfx_SafariBall, 384, GFX_TAG_SAFARIBALL}, - {gInterfaceGfx_UltraBall, 384, GFX_TAG_ULTRABALL}, - {gInterfaceGfx_MasterBall, 384, GFX_TAG_MASTERBALL}, - {gInterfaceGfx_NetBall, 384, GFX_TAG_NETBALL}, - {gInterfaceGfx_DiveBall, 384, GFX_TAG_DIVEBALL}, - {gInterfaceGfx_NestBall, 384, GFX_TAG_NESTBALL}, - {gInterfaceGfx_RepeatBall, 384, GFX_TAG_REPEATBALL}, - {gInterfaceGfx_TimerBall, 384, GFX_TAG_TIMERBALL}, - {gInterfaceGfx_LuxuryBall, 384, GFX_TAG_LUXURYBALL}, - {gInterfaceGfx_PremierBall, 384, GFX_TAG_PREMIERBALL}, -}; - -static const struct CompressedSpritePalette sBallSpritePalettes[] = -{ - {gInterfacePal_PokeBall, GFX_TAG_POKEBALL}, - {gInterfacePal_GreatBall, GFX_TAG_GREATBALL}, - {gInterfacePal_SafariBall, GFX_TAG_SAFARIBALL}, - {gInterfacePal_UltraBall, GFX_TAG_ULTRABALL}, - {gInterfacePal_MasterBall, GFX_TAG_MASTERBALL}, - {gInterfacePal_NetBall, GFX_TAG_NETBALL}, - {gInterfacePal_DiveBall, GFX_TAG_DIVEBALL}, - {gInterfacePal_NestBall, GFX_TAG_NESTBALL}, - {gInterfacePal_RepeatBall, GFX_TAG_REPEATBALL}, - {gInterfacePal_TimerBall, GFX_TAG_TIMERBALL}, - {gInterfacePal_LuxuryBall, GFX_TAG_LUXURYBALL}, - {gInterfacePal_PremierBall, GFX_TAG_PREMIERBALL}, -}; - -static const struct OamData sBallOamData = -{ - .y = 0, - .affineMode = 3, - .objMode = 0, - .mosaic = 0, - .bpp = 0, - .shape = 0, - .x = 0, - .matrixNum = 0, - .size = 1, - .tileNum = 0, - .priority = 2, - .paletteNum = 0, - .affineParam = 0, -}; - -static const union AnimCmd sBallAnimSeq3[] = -{ - ANIMCMD_FRAME(0, 5), - ANIMCMD_JUMP(0), -}; - -static const union AnimCmd sBallAnimSeq5[] = -{ - ANIMCMD_FRAME(4, 1), - ANIMCMD_JUMP(0), -}; - -static const union AnimCmd sBallAnimSeq4[] = -{ - ANIMCMD_FRAME(8, 5), - ANIMCMD_JUMP(0), -}; - -static const union AnimCmd sBallAnimSeq6[] = -{ - ANIMCMD_FRAME(12, 1), - ANIMCMD_JUMP(0), -}; - -static const union AnimCmd sBallAnimSeq0[] = -{ - ANIMCMD_FRAME(0, 1), - ANIMCMD_END, -}; - -static const union AnimCmd sBallAnimSeq1[] = -{ - ANIMCMD_FRAME(4, 5), - ANIMCMD_FRAME(8, 5), - ANIMCMD_END, -}; - -static const union AnimCmd sBallAnimSeq2[] = -{ - ANIMCMD_FRAME(4, 5), - ANIMCMD_FRAME(0, 5), - ANIMCMD_END, -}; - -static const union AnimCmd *const sBallAnimSequences[] = -{ - sBallAnimSeq0, - sBallAnimSeq1, - sBallAnimSeq2, - - // unused? - sBallAnimSeq3, - sBallAnimSeq4, - sBallAnimSeq5, - sBallAnimSeq6, -}; - -static const union AffineAnimCmd sBallAffineAnimSeq0[] = -{ - AFFINEANIMCMD_FRAME(0, 0, 0, 1), - AFFINEANIMCMD_JUMP(0), -}; - -static const union AffineAnimCmd sBallAffineAnimSeq1[] = -{ - AFFINEANIMCMD_FRAME(0, 0, -3, 1), - AFFINEANIMCMD_JUMP(0), -}; - -static const union AffineAnimCmd sBallAffineAnimSeq2[] = -{ - AFFINEANIMCMD_FRAME(0, 0, 3, 1), - AFFINEANIMCMD_JUMP(0), -}; - -static const union AffineAnimCmd sBallAffineAnimSeq3[] = -{ - AFFINEANIMCMD_FRAME(256, 256, 0, 0), - AFFINEANIMCMD_END, -}; - -static const union AffineAnimCmd sBallAffineAnimSeq4[] = -{ - AFFINEANIMCMD_FRAME(0, 0, 25, 1), - AFFINEANIMCMD_JUMP(0), -}; - -static const union AffineAnimCmd *const sBallAffineAnimSequences[] = -{ - sBallAffineAnimSeq0, - sBallAffineAnimSeq1, - sBallAffineAnimSeq2, - sBallAffineAnimSeq3, - sBallAffineAnimSeq4, -}; - -static void objc_0804ABD4(struct Sprite *sprite); -const struct SpriteTemplate gBallSpriteTemplates[] = -{ - { - .tileTag = GFX_TAG_POKEBALL, - .paletteTag = GFX_TAG_POKEBALL, - .oam = &sBallOamData, - .anims = sBallAnimSequences, - .images = NULL, - .affineAnims = sBallAffineAnimSequences, - .callback = objc_0804ABD4, - }, - { - .tileTag = GFX_TAG_GREATBALL, - .paletteTag = GFX_TAG_GREATBALL, - .oam = &sBallOamData, - .anims = sBallAnimSequences, - .images = NULL, - .affineAnims = sBallAffineAnimSequences, - .callback = objc_0804ABD4, - }, - { - .tileTag = GFX_TAG_SAFARIBALL, - .paletteTag = GFX_TAG_SAFARIBALL, - .oam = &sBallOamData, - .anims = sBallAnimSequences, - .images = NULL, - .affineAnims = sBallAffineAnimSequences, - .callback = objc_0804ABD4, - }, - { - .tileTag = GFX_TAG_ULTRABALL, - .paletteTag = GFX_TAG_ULTRABALL, - .oam = &sBallOamData, - .anims = sBallAnimSequences, - .images = NULL, - .affineAnims = sBallAffineAnimSequences, - .callback = objc_0804ABD4, - }, - { - .tileTag = GFX_TAG_MASTERBALL, - .paletteTag = GFX_TAG_MASTERBALL, - .oam = &sBallOamData, - .anims = sBallAnimSequences, - .images = NULL, - .affineAnims = sBallAffineAnimSequences, - .callback = objc_0804ABD4, - }, - { - .tileTag = GFX_TAG_NETBALL, - .paletteTag = GFX_TAG_NETBALL, - .oam = &sBallOamData, - .anims = sBallAnimSequences, - .images = NULL, - .affineAnims = sBallAffineAnimSequences, - .callback = objc_0804ABD4, - }, - { - .tileTag = GFX_TAG_DIVEBALL, - .paletteTag = GFX_TAG_DIVEBALL, - .oam = &sBallOamData, - .anims = sBallAnimSequences, - .images = NULL, - .affineAnims = sBallAffineAnimSequences, - .callback = objc_0804ABD4, - }, - { - .tileTag = GFX_TAG_NESTBALL, - .paletteTag = GFX_TAG_NESTBALL, - .oam = &sBallOamData, - .anims = sBallAnimSequences, - .images = NULL, - .affineAnims = sBallAffineAnimSequences, - .callback = objc_0804ABD4, - }, - { - .tileTag = GFX_TAG_REPEATBALL, - .paletteTag = GFX_TAG_REPEATBALL, - .oam = &sBallOamData, - .anims = sBallAnimSequences, - .images = NULL, - .affineAnims = sBallAffineAnimSequences, - .callback = objc_0804ABD4, - }, - { - .tileTag = GFX_TAG_TIMERBALL, - .paletteTag = GFX_TAG_TIMERBALL, - .oam = &sBallOamData, - .anims = sBallAnimSequences, - .images = NULL, - .affineAnims = sBallAffineAnimSequences, - .callback = objc_0804ABD4, - }, - { - .tileTag = GFX_TAG_LUXURYBALL, - .paletteTag = GFX_TAG_LUXURYBALL, - .oam = &sBallOamData, - .anims = sBallAnimSequences, - .images = NULL, - .affineAnims = sBallAffineAnimSequences, - .callback = objc_0804ABD4, - }, - { - .tileTag = GFX_TAG_PREMIERBALL, - .paletteTag = GFX_TAG_PREMIERBALL, - .oam = &sBallOamData, - .anims = sBallAnimSequences, - .images = NULL, - .affineAnims = sBallAffineAnimSequences, - .callback = objc_0804ABD4, - }, -}; - -extern void InitAnimArcTranslation(); -extern bool8 TranslateAnimArc(struct Sprite *); - -static void SendOutMonAnimation(u8); -static void sub_80466E8(struct Sprite *); -static void sub_80466F4(struct Sprite *); -static void sub_8046760(struct Sprite *); -static void sub_80467F8(struct Sprite *); -static void sub_804684C(struct Sprite *); -static void sub_8046944(struct Sprite *); -static void sub_8046984(struct Sprite *); -static void sub_8046C78(struct Sprite *); -static void sub_8046E7C(struct Sprite *); -static void sub_8046E9C(struct Sprite *); -static void sub_8046FBC(struct Sprite *); -static void SendOutPlayerMonAnimation_Step0(struct Sprite *); -static void SendOutPlayerMonAnimation_Step1(struct Sprite *); -static void SendOutMonAnimation_Delay(struct Sprite *); -static void SendOutOpponentMonAnimation_Step0(struct Sprite *); -static void sub_80473D0(struct Sprite *); -static void sub_804748C(struct Sprite *); -static void sub_8047638(struct Sprite *); -static void sub_80476E0(struct Sprite *); -static void sub_8047754(struct Sprite *); -static void sub_804780C(struct Sprite *); -static void sub_8047830(struct Sprite *); -static void oamc_804BEB4(struct Sprite *); -static u16 GetBattlerBall(u8); - -u8 StartSendOutMonAnimation(u16 a, u8 side) -{ - u8 taskId; - - gDoingBattleAnim = 1; - ewram17810[gActiveBattler].unk0_3 = 1; - taskId = CreateTask(SendOutMonAnimation, 5); - gTasks[taskId].data[1] = a; - gTasks[taskId].data[2] = side; - gTasks[taskId].data[3] = gActiveBattler; - return 0; -} - -static void SendOutMonAnimation(u8 taskId) -{ - bool8 debug = FALSE; - u16 side; - u8 battler; - u16 ball; - u8 ballIndex; - u8 spriteId; - - if (gTasks[taskId].data[0] == 0) - { - gTasks[taskId].data[0]++; - return; - } - - side = gTasks[taskId].data[2]; - battler = gTasks[taskId].data[3]; - if (GetBattlerSide(battler) != B_SIDE_PLAYER) - ball = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_POKEBALL); - else - ball = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_POKEBALL); - - ballIndex = ball_number_to_ball_processing_index(ball); - LoadBallGraphics(ballIndex); - spriteId = CreateSprite(&gBallSpriteTemplates[ballIndex], 32, 80, 29); - gSprites[spriteId].data[0] = 0x80; - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].data[7] = side; - - switch (side) - { - case 0xFF: // Player's side - gBankTarget = battler; - gSprites[spriteId].pos1.x = 24; - gSprites[spriteId].pos1.y = 68; - gSprites[spriteId].callback = SendOutPlayerMonAnimation_Step0; - break; - case 0xFE: // Opponent's side - gSprites[spriteId].pos1.x = GetBattlerSpriteCoord(battler, 0); - gSprites[spriteId].pos1.y = GetBattlerSpriteCoord(battler, 1) + 24; - gBankTarget = battler; - gSprites[spriteId].data[0] = 0; - gSprites[spriteId].callback = SendOutOpponentMonAnimation_Step0; - break; - default: - gBankTarget = GetBattlerAtPosition(1); - debug = TRUE; - break; - } - - gSprites[spriteId].data[6] = gBankTarget; - if (!debug) - { - DestroyTask(taskId); - return; - } - - gSprites[spriteId].data[0] = 0x22; - gSprites[spriteId].data[2] = GetBattlerSpriteCoord(gBankTarget, 0); - gSprites[spriteId].data[4] = GetBattlerSpriteCoord(gBankTarget, 1) - 16; - gSprites[spriteId].data[5] = -40; - InitAnimArcTranslation(&gSprites[spriteId]); - gSprites[spriteId].oam.affineParam = taskId; - gTasks[taskId].data[4] = gBankTarget; - gTasks[taskId].func = TaskDummy; - PlaySE(SE_NAGERU); -} - -static void objc_0804ABD4(struct Sprite *sprite) -{ - if (TranslateAnimArc(sprite)) - { - u8 taskId = sprite->oam.affineParam; - u8 r5 = gTasks[taskId].data[4]; - u8 r8 = gTasks[taskId].data[2]; - u32 r4; // not sure of this type - - StartSpriteAnim(sprite, 1); - sprite->affineAnimPaused = TRUE; - sprite->pos1.x += sprite->pos2.x; - sprite->pos1.y += sprite->pos2.y; - sprite->pos2.x = 0; - sprite->pos2.y = 0; - sprite->data[5] = 0; - r4 = ball_number_to_ball_processing_index(GetBattlerBall(r5)); - AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 0x1C, r4); - sprite->data[0] = sub_8141314(0, r5, 14, r4); - sprite->data[6] = r5; - sprite->data[7] = r8; - DestroyTask(taskId); - sprite->callback = sub_80466E8; - } -} - -static void sub_80466E8(struct Sprite *sprite) -{ - sprite->callback = sub_80466F4; -} - -static void sub_80466F4(struct Sprite *sprite) -{ - sprite->data[5]++; - if (sprite->data[5] == 10) - { - sprite->data[5] = 0; - sprite->callback = sub_8046760; - StartSpriteAffineAnim(&gSprites[gBankSpriteIds[sprite->data[6]]], 2); - AnimateSprite(&gSprites[gBankSpriteIds[sprite->data[6]]]); - gSprites[gBankSpriteIds[sprite->data[6]]].data[1] = 0; - } -} - -static void sub_8046760(struct Sprite *sprite) -{ - sprite->data[5]++; - if (sprite->data[5] == 11) - PlaySE(SE_SUIKOMU); - if (gSprites[gBankSpriteIds[sprite->data[6]]].affineAnimEnded) - { - StartSpriteAnim(sprite, 2); - gSprites[gBankSpriteIds[sprite->data[6]]].invisible = TRUE; - sprite->data[5] = 0; - sprite->callback = sub_80467F8; - } - else - { - gSprites[gBankSpriteIds[sprite->data[6]]].data[1] += 0x60; - gSprites[gBankSpriteIds[sprite->data[6]]].pos2.y = -gSprites[gBankSpriteIds[sprite->data[6]]].data[1] >> 8; - } -} - -static void sub_80467F8(struct Sprite *sprite) -{ - if (sprite->animEnded) - { - sprite->data[5]++; - if (sprite->data[5] == 1) - { - sprite->data[3] = 0; - sprite->data[4] = 32; - sprite->data[5] = 0; - sprite->pos1.y += Cos(0, 32); - sprite->pos2.y = -Cos(0, sprite->data[4]); - sprite->callback = sub_804684C; - } - } -} - -static void sub_804684C(struct Sprite *sprite) -{ - bool8 r5 = FALSE; - - switch (sprite->data[3] & 0xFF) - { - case 0: - sprite->pos2.y = -Cos(sprite->data[5], sprite->data[4]); - sprite->data[5] += 4 + (sprite->data[3] >> 8); - if (sprite->data[5] >= 64) - { - sprite->data[4] -= 10; - sprite->data[3] += 0x101; - if (sprite->data[3] >> 8 == 4) - r5 = TRUE; - switch (sprite->data[3] >> 8) - { - case 1: - PlaySE(SE_KON); - break; - case 2: - PlaySE(SE_KON2); - break; - case 3: - PlaySE(SE_KON3); - break; - default: - PlaySE(SE_KON4); - break; - } - } - break; - case 1: - sprite->pos2.y = -Cos(sprite->data[5], sprite->data[4]); - sprite->data[5] -= 4 + (sprite->data[3] >> 8); - if (sprite->data[5] <= 0) - { - sprite->data[5] = 0; - sprite->data[3] &= 0xFF00; - } - break; - } - if (r5) - { - sprite->data[3] = 0; - sprite->pos1.y += Cos(64, 32); - sprite->pos2.y = 0; - if (sprite->data[7] == 0) - { - sprite->callback = sub_8046C78; - } - else - { - sprite->callback = sub_8046944; - sprite->data[4] = 1; - sprite->data[5] = 0; - } - } -} - -static void sub_8046944(struct Sprite *sprite) -{ - sprite->data[3]++; - if (sprite->data[3] == 31) - { - sprite->data[3] = 0; - sprite->affineAnimPaused = TRUE; - StartSpriteAffineAnim(sprite, 1); - sprite->callback = sub_8046984; - PlaySE(SE_BOWA); - } -} - -static void sub_8046984(struct Sprite *sprite) -{ - switch (sprite->data[3] & 0xFF) - { - case 0: - case 2: - sprite->pos2.x += sprite->data[4]; - sprite->data[5] += sprite->data[4]; - sprite->affineAnimPaused = FALSE; - if (sprite->data[5] > 3 || sprite->data[5] < -3) - { - sprite->data[3]++; - sprite->data[5] = 0; - } - break; - case 1: - sprite->data[5]++; - if (sprite->data[5] == 1) - { - sprite->data[5] = 0; - sprite->data[4] = -sprite->data[4]; - sprite->data[3]++; - sprite->affineAnimPaused = FALSE; - if (sprite->data[4] < 0) - ChangeSpriteAffineAnim(sprite, 2); - else - ChangeSpriteAffineAnim(sprite, 1); - } - else - { - sprite->affineAnimPaused = TRUE; - } - break; - case 3: - sprite->data[3] += 0x100; - if (sprite->data[3] >> 8 == sprite->data[7]) - { - sprite->callback = sub_8046C78; - } - else - { - if (sprite->data[7] == 4 && sprite->data[3] >> 8 == 3) - { - sprite->callback = sub_8046E7C; - sprite->affineAnimPaused = TRUE; - } - else - { - sprite->data[3]++; - sprite->affineAnimPaused = TRUE; - } - } - break; - case 4: - default: - sprite->data[5]++; - if (sprite->data[5] == 31) - { - sprite->data[5] = 0; - sprite->data[3] &= 0xFF00; - StartSpriteAffineAnim(sprite, 3); - if (sprite->data[4] < 0) - StartSpriteAffineAnim(sprite, 2); - else - StartSpriteAffineAnim(sprite, 1); - PlaySE(SE_BOWA); - } - break; - } -} - -static void sub_8046AD0(u8 taskId) -{ - u8 r6 = gTasks[taskId].data[2]; - u8 r3 = gTasks[taskId].data[1]; - u16 species = gTasks[taskId].data[0]; - - switch (gTasks[taskId].data[15]) - { - case 0: - default: - if (gTasks[taskId].data[8] < 3) - gTasks[taskId].data[8]++; - else - gTasks[taskId].data[15] = r6 + 1; - break; - case 1: - PlayCry1(species, r3); - DestroyTask(taskId); - break; - case 2: - StopCryAndClearCrySongs(); - gTasks[taskId].data[10] = 3; - gTasks[taskId].data[15] = 20; - break; - case 20: - if (gTasks[taskId].data[10] != 0) - { - gTasks[taskId].data[10]--; - break; - } - PlayCry4(species, r3, 1); - DestroyTask(taskId); - break; - case 3: - gTasks[taskId].data[10] = 6; - gTasks[taskId].data[15] = 30; - break; - case 30: - if (gTasks[taskId].data[10] != 0) - { - gTasks[taskId].data[10]--; - break; - } - gTasks[taskId].data[15]++; - // fall through - case 31: - if (!IsCryPlayingOrClearCrySongs()) - { - StopCryAndClearCrySongs(); - gTasks[taskId].data[10] = 3; - gTasks[taskId].data[15]++; - } - break; - case 32: - if (gTasks[taskId].data[10] != 0) - { - gTasks[taskId].data[10]--; - break; - } - PlayCry4(species, r3, 0); - DestroyTask(taskId); - break; - } -} - -static void sub_8046C78(struct Sprite *sprite) -{ - int ballIndex; - u8 battler = sprite->data[6]; - - StartSpriteAnim(sprite, 1); - ballIndex = ball_number_to_ball_processing_index(GetBattlerBall(battler)); - AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 28, ballIndex); - sprite->data[0] = sub_8141314(1, sprite->data[6], 14, ballIndex); - sprite->callback = sub_8046E9C; - if (gMain.inBattle) - { - struct Pokemon *mon; - u16 species; - s8 cryPanning; - u16 cryBehavior; - u8 taskId; - - if (GetBattlerSide(battler) != 0) - { - mon = &gEnemyParty[gBattlerPartyIndexes[battler]]; - cryPanning = 25; - } - else - { - mon = &gPlayerParty[gBattlerPartyIndexes[battler]]; - cryPanning = -25; - } - - species = GetMonData(mon, MON_DATA_SPECIES); - if ((battler == GetBattlerAtPosition(0) || battler == GetBattlerAtPosition(1)) - && IsDoubleBattle() && ewram17840.unk9_0) - { - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (IsBGMPlaying()) - m4aMPlayStop(&gMPlay_BGM); - } - else - { - m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 128); - } - } - - if (!IsDoubleBattle() || !ewram17840.unk9_0) - cryBehavior = 0; - else if (battler == GetBattlerAtPosition(0) || battler == GetBattlerAtPosition(1)) - cryBehavior = 1; - else - cryBehavior = 2; - - taskId = CreateTask(sub_8046AD0, 3); - gTasks[taskId].data[0] = species; - gTasks[taskId].data[1] = cryPanning; - gTasks[taskId].data[2] = cryBehavior; - gTasks[taskId].data[15] = 0; - } - - StartSpriteAffineAnim(&gSprites[gBankSpriteIds[sprite->data[6]]], 1); - AnimateSprite(&gSprites[gBankSpriteIds[sprite->data[6]]]); - gSprites[gBankSpriteIds[sprite->data[6]]].data[1] = 0x1000; -} - -static void sub_8046E7C(struct Sprite *sprite) -{ - sprite->animPaused = TRUE; - sprite->callback = sub_8046FBC; - sprite->data[3] = 0; - sprite->data[4] = 0; - sprite->data[5] = 0; -} - -static void sub_8046E9C(struct Sprite *sprite) -{ - bool8 r7 = FALSE; - u8 r4 = sprite->data[6]; - - gSprites[gBankSpriteIds[r4]].invisible = FALSE; - if (sprite->animEnded) - sprite->invisible = TRUE; - if (gSprites[gBankSpriteIds[r4]].affineAnimEnded) - { - StartSpriteAffineAnim(&gSprites[gBankSpriteIds[r4]], 0); - r7 = TRUE; - } - else - { - gSprites[gBankSpriteIds[r4]].data[1] -= 288; - gSprites[gBankSpriteIds[r4]].pos2.y = gSprites[gBankSpriteIds[r4]].data[1] >> 8; - } - if (sprite->animEnded && r7) - { - s32 i; - u32 r3; - - gSprites[gBankSpriteIds[r4]].pos2.y = 0; - gDoingBattleAnim = 0; - ewram17810[r4].unk0_3 = 0; - FreeSpriteOamMatrix(sprite); - DestroySprite(sprite); - for (r3 = 0, i = 0; i < 4; i++) - { - if (ewram17810[i].unk0_3 == 0) - r3++; - } - if (r3 == 4) - { - for (i = 0; i < 12; i++) - FreeBallGraphics(i); - } - } -} - -static void sub_8046FBC(struct Sprite *sprite) -{ - u8 r7 = sprite->data[6]; - - sprite->data[4]++; - if (sprite->data[4] == 40) - { - return; - } - else if (sprite->data[4] == 95) - { - gDoingBattleAnim = 0; - m4aMPlayAllStop(); - PlaySE(MUS_FANFA5); - } - else if (sprite->data[4] == 315) - { - FreeOamMatrix(gSprites[gBankSpriteIds[sprite->data[6]]].oam.matrixNum); - DestroySprite(&gSprites[gBankSpriteIds[sprite->data[6]]]); - DestroySpriteAndFreeResources(sprite); - if (gMain.inBattle) - ewram17810[r7].unk0_3 = 0; - } -} - -static void SendOutPlayerMonAnimation_Step0(struct Sprite *sprite) -{ - sprite->data[0] = 25; - sprite->data[2] = GetBattlerSpriteCoord(sprite->data[6], 2); - sprite->data[4] = GetBattlerSpriteCoord(sprite->data[6], 3) + 24; - sprite->data[5] = -30; - sprite->oam.affineParam = sprite->data[6]; - InitAnimArcTranslation(sprite); - sprite->callback = SendOutPlayerMonAnimation_Step1; -} - -#define HIBYTE(x) (((x) >> 8) & 0xFF) - -static void SendOutPlayerMonAnimation_Step1(struct Sprite *sprite) -{ - u32 r6; - u32 r7; - - if (HIBYTE(sprite->data[7]) >= 35 && HIBYTE(sprite->data[7]) < 80) - { - s16 r4; - - if ((sprite->oam.affineParam & 0xFF00) == 0) - { - r6 = sprite->data[1] & 1; - r7 = sprite->data[2] & 1; - sprite->data[1] = ((sprite->data[1] / 3) & ~1) | r6; - sprite->data[2] = ((sprite->data[2] / 3) & ~1) | r7; - StartSpriteAffineAnim(sprite, 4); - } - - r4 = sprite->data[0]; - TranslateAnimLinear(sprite); - sprite->data[7] += sprite->data[6] / 3; - sprite->pos2.y += Sin(HIBYTE(sprite->data[7]), sprite->data[5]); - sprite->oam.affineParam += 0x100; - if ((sprite->oam.affineParam >> 8) % 3 != 0) - sprite->data[0] = r4; - else - sprite->data[0] = r4 - 1; - - if (HIBYTE(sprite->data[7]) >= 80) - { - r6 = sprite->data[1] & 1; - r7 = sprite->data[2] & 1; - sprite->data[1] = ((sprite->data[1] * 3) & ~1) | r6; - sprite->data[2] = ((sprite->data[2] * 3) & ~1) | r7; - } - } - else - { - if (TranslateAnimArc(sprite)) - { - sprite->pos1.x += sprite->pos2.x; - sprite->pos1.y += sprite->pos2.y; - sprite->pos2.y = 0; - sprite->pos2.x = 0; - sprite->data[6] = sprite->oam.affineParam & 0xFF; - sprite->data[0] = 0; - if (IsDoubleBattle() && ewram17840.unk9_0 && sprite->data[6] == GetBattlerAtPosition(2)) - sprite->callback = SendOutMonAnimation_Delay; - else - sprite->callback = sub_8046C78; - - StartSpriteAffineAnim(sprite, 0); - } - } -} - -static void SendOutMonAnimation_Delay(struct Sprite *sprite) -{ - if (sprite->data[0]++ > 24) - { - sprite->data[0] = 0; - sprite->callback = sub_8046C78; - } -} - -static void SendOutOpponentMonAnimation_Step0(struct Sprite *sprite) -{ - sprite->data[0]++; - if (sprite->data[0] > 15) - { - sprite->data[0] = 0; - if (IsDoubleBattle() && ewram17840.unk9_0 && sprite->data[6] == GetBattlerAtPosition(3)) - sprite->callback = SendOutMonAnimation_Delay; - else - sprite->callback = sub_8046C78; - } -} - -static u8 sub_80472B0(u8 a, u8 b, u8 c, u8 d) -{ - return AnimateBallOpenParticles(a, b, c, d, 0); -} - -static u8 sub_80472D8(u8 a, u8 b, u32 c) -{ - return sub_8141314(a, b, c, 0); -} - -void CreatePokeballSprite(u8 a, u8 b, u8 x, u8 y, u8 e, u8 f, u8 g, u32 h) -{ - u8 spriteId; - - LoadCompressedObjectPic(&sBallSpriteSheets[0]); - LoadCompressedObjectPalette(&sBallSpritePalettes[0]); - spriteId = CreateSprite(&gBallSpriteTemplates[0], x, y, f); - gSprites[spriteId].data[0] = a; - gSprites[spriteId].data[5] = gSprites[a].pos1.x; - gSprites[spriteId].data[6] = gSprites[a].pos1.y; - gSprites[a].pos1.x = x; - gSprites[a].pos1.y = y; - gSprites[spriteId].data[1] = g; - gSprites[spriteId].data[2] = b; - gSprites[spriteId].data[3] = h; - gSprites[spriteId].data[4] = h >> 16; - gSprites[spriteId].oam.priority = e; - gSprites[spriteId].callback = sub_80473D0; - gSprites[a].invisible = TRUE; -} - -static void sub_80473D0(struct Sprite *sprite) -{ - if (sprite->data[1] == 0) - { - u8 r5; - u8 r7 = sprite->data[0]; - u8 r8 = sprite->data[2]; - u32 r4 = (u16)sprite->data[3] | ((u16)sprite->data[4] << 16); - - if (sprite->subpriority != 0) - r5 = sprite->subpriority - 1; - else - r5 = 0; - StartSpriteAnim(sprite, 1); - sub_80472B0(sprite->pos1.x, sprite->pos1.y - 5, sprite->oam.priority, r5); - sprite->data[1] = sub_80472D8(1, r8, r4); - sprite->callback = sub_804748C; - gSprites[r7].invisible = FALSE; - StartSpriteAffineAnim(&gSprites[r7], 1); - AnimateSprite(&gSprites[r7]); - gSprites[r7].data[1] = 0x1000; - sprite->data[7] = 0; - } - else - { - sprite->data[1]--; - } -} - -static void sub_804748C(struct Sprite *sprite) -{ - bool8 r12 = FALSE; - bool8 r6 = FALSE; - u8 r3 = sprite->data[0]; - u16 var1; - u16 var2; - - if (sprite->animEnded) - sprite->invisible = TRUE; - if (gSprites[r3].affineAnimEnded) - { - StartSpriteAffineAnim(&gSprites[r3], 0); - r12 = TRUE; - } - var1 = (sprite->data[5] - sprite->pos1.x) * sprite->data[7] / 128 + sprite->pos1.x; - var2 = (sprite->data[6] - sprite->pos1.y) * sprite->data[7] / 128 + sprite->pos1.y; - gSprites[r3].pos1.x = var1; - gSprites[r3].pos1.y = var2; - if (sprite->data[7] < 128) - { - s16 sine = -(gSineTable[(u8)sprite->data[7]] / 8); - - sprite->data[7] += 4; - gSprites[r3].pos2.x = sine; - gSprites[r3].pos2.y = sine; - } - else - { - gSprites[r3].pos1.x = sprite->data[5]; - gSprites[r3].pos1.y = sprite->data[6]; - gSprites[r3].pos2.x = 0; - gSprites[r3].pos2.y = 0; - r6 = TRUE; - } - if (sprite->animEnded && r12 && r6) - DestroySpriteAndFreeResources(sprite); -} - -u8 sub_8047580(u8 a, u8 b, u8 x, u8 y, u8 e, u8 f, u8 g, u32 h) -{ - u8 spriteId; - - LoadCompressedObjectPic(&sBallSpriteSheets[0]); - LoadCompressedObjectPalette(&sBallSpritePalettes[0]); - spriteId = CreateSprite(&gBallSpriteTemplates[0], x, y, f); - gSprites[spriteId].data[0] = a; - gSprites[spriteId].data[1] = g; - gSprites[spriteId].data[2] = b; - gSprites[spriteId].data[3] = h; - gSprites[spriteId].data[4] = h >> 16; - gSprites[spriteId].oam.priority = e; - gSprites[spriteId].callback = sub_8047638; - return spriteId; -} - -static void sub_8047638(struct Sprite *sprite) -{ - if (sprite->data[1] == 0) - { - u8 r6; - u8 r7 = sprite->data[0]; - u8 r8 = sprite->data[2]; - u32 r5 = (u16)sprite->data[3] | ((u16)sprite->data[4] << 16); - - if (sprite->subpriority != 0) - r6 = sprite->subpriority - 1; - else - r6 = 0; - StartSpriteAnim(sprite, 1); - sub_80472B0(sprite->pos1.x, sprite->pos1.y - 5, sprite->oam.priority, r6); - sprite->data[1] = sub_80472D8(1, r8, r5); - sprite->callback = sub_80476E0; - StartSpriteAffineAnim(&gSprites[r7], 2); - AnimateSprite(&gSprites[r7]); - gSprites[r7].data[1] = 0; - } - else - { - sprite->data[1]--; - } -} - -static void sub_80476E0(struct Sprite *sprite) -{ - u8 r1; - - sprite->data[5]++; - if (sprite->data[5] == 11) - PlaySE(SE_SUIKOMU); - r1 = sprite->data[0]; - if (gSprites[r1].affineAnimEnded) - { - StartSpriteAnim(sprite, 2); - gSprites[r1].invisible = TRUE; - sprite->data[5] = 0; - sprite->callback = sub_8047754; - } - else - { - gSprites[r1].data[1] += 96; - gSprites[r1].pos2.y = -gSprites[r1].data[1] >> 8; - } -} - -static void sub_8047754(struct Sprite *sprite) -{ - if (sprite->animEnded) - sprite->callback = SpriteCallbackDummy; -} - -void obj_delete_and_free_associated_resources_(struct Sprite *sprite) -{ - DestroySpriteAndFreeResources(sprite); -} - -void sub_804777C(u8 a) -{ - struct Sprite *sprite = &gSprites[gHealthboxIDs[a]]; - - sprite->data[0] = 5; - sprite->data[1] = 0; - sprite->pos2.x = 0x73; - sprite->pos2.y = 0; - sprite->callback = sub_8047830; - if (GetBattlerSide(a) != 0) - { - sprite->data[0] = -sprite->data[0]; - sprite->data[1] = -sprite->data[1]; - sprite->pos2.x = -sprite->pos2.x; - sprite->pos2.y = -sprite->pos2.y; - } - gSprites[sprite->data[5]].callback(&gSprites[sprite->data[5]]); - if (GetBattlerPosition(a) == 2) - sprite->callback = sub_804780C; -} - -static void sub_804780C(struct Sprite *sprite) -{ - sprite->data[1]++; - if (sprite->data[1] == 20) - { - sprite->data[1] = 0; - sprite->callback = sub_8047830; - } -} - -static void sub_8047830(struct Sprite *sprite) -{ - sprite->pos2.x -= sprite->data[0]; - sprite->pos2.y -= sprite->data[1]; - if (sprite->pos2.x == 0 && sprite->pos2.y == 0) - sprite->callback = SpriteCallbackDummy; -} - -void sub_8047858(u8 a) -{ - u8 spriteId; - - spriteId = CreateInvisibleSpriteWithCallback(oamc_804BEB4); - gSprites[spriteId].data[0] = 1; - gSprites[spriteId].data[1] = gHealthboxIDs[a]; - gSprites[spriteId].callback = oamc_804BEB4; -} - -static void oamc_804BEB4(struct Sprite *sprite) -{ - u8 r1 = sprite->data[1]; - - gSprites[r1].pos2.y = sprite->data[0]; - sprite->data[0] = -sprite->data[0]; - sprite->data[2]++; - if (sprite->data[2] == 21) - { - gSprites[r1].pos2.x = 0; - gSprites[r1].pos2.y = 0; - DestroySprite(sprite); - } -} - -void LoadBallGraphics(u8 ballIndex) -{ - u16 tileStart; - - if (GetSpriteTileStartByTag(sBallSpriteSheets[ballIndex].tag) == 0xFFFF) - { - LoadCompressedObjectPic(&sBallSpriteSheets[ballIndex]); - LoadCompressedObjectPalette(&sBallSpritePalettes[ballIndex]); - } - - switch (ballIndex) - { - case 6: - case 10: - case 11: - break; - default: - tileStart = GetSpriteTileStartByTag(sBallSpriteSheets[ballIndex].tag); - LZDecompressVram(gUnknown_08D030D0, (void *)(VRAM + 0x10100 + tileStart * 32)); - break; - } -} - -void FreeBallGraphics(u8 ballIndex) -{ - FreeSpriteTilesByTag(sBallSpriteSheets[ballIndex].tag); - FreeSpritePaletteByTag(sBallSpritePalettes[ballIndex].tag); -} - -static u16 GetBattlerBall(u8 battler) -{ - if (GetBattlerSide(battler) == B_SIDE_PLAYER) - return GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_POKEBALL); - else - return GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_POKEBALL); -} diff --git a/src/battle/post_battle_event_funcs.c b/src/battle/post_battle_event_funcs.c deleted file mode 100644 index d0fbbec85..000000000 --- a/src/battle/post_battle_event_funcs.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "global.h" -#include "event_data.h" -#include "hall_of_fame.h" -#include "load_save.h" -#include "main.h" -#include "pokemon.h" -#include "overworld.h" -#include "script_pokemon_80C4.h" -#include "constants/heal_locations.h" - -extern u8 gUnknown_02039324; - -int GameClear(void) -{ - int i; - bool32 ribbonGet; - - ScrSpecial_HealPlayerParty(); - - if (FlagGet(FLAG_SYS_GAME_CLEAR) == TRUE) - { - gUnknown_02039324 = 1; - } - else - { - gUnknown_02039324 = 0; - FlagSet(FLAG_SYS_GAME_CLEAR); - } - - if (!GetGameStat(GAME_STAT_FIRST_HOF_PLAY_TIME)) - SetGameStat(GAME_STAT_FIRST_HOF_PLAY_TIME, (gSaveBlock2.playTimeHours << 16) | (gSaveBlock2.playTimeMinutes << 8) | gSaveBlock2.playTimeSeconds); - - SetSecretBase2Field_9(); - - if (gSaveBlock2.playerGender == MALE) - sub_80537CC(HEAL_LOCATION_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F); - else - sub_80537CC(HEAL_LOCATION_LITTLEROOT_TOWN_MAYS_HOUSE_2F); - - ribbonGet = FALSE; - - for (i = 0; i < 6; i++) - { - u8 val; - u8 *ptr = &val; - if (GetMonData(&gPlayerParty[i], MON_DATA_SANITY_BIT2) - && !GetMonData(&gPlayerParty[i], MON_DATA_SANITY_BIT3) - && !GetMonData(&gPlayerParty[i], MON_DATA_CHAMPION_RIBBON)) - { - *ptr = 1; - SetMonData(&gPlayerParty[i], MON_DATA_CHAMPION_RIBBON, ptr); - ribbonGet = TRUE; - } - } - - if (ribbonGet == TRUE) - { - IncrementGameStat(GAME_STAT_RECEIVED_RIBBONS); - FlagSet(FLAG_SYS_RIBBON_GET); - } - - SetMainCallback2(sub_8141F90); - return 0; -} - -int sp0C8_whiteout_maybe(void) -{ - SetMainCallback2(CB2_WhiteOut); - return 0; -} diff --git a/src/battle/reshow_battle_screen.c b/src/battle/reshow_battle_screen.c deleted file mode 100644 index 712ec3ea8..000000000 --- a/src/battle/reshow_battle_screen.c +++ /dev/null @@ -1,316 +0,0 @@ -#include "global.h" -#include "battle.h" -#include "battle_anim.h" -#include "palette.h" -#include "main.h" -#include "scanline_effect.h" -#include "text.h" -#include "rom_8077ABC.h" -#include "data2.h" -#include "ewram.h" - -extern struct SpriteTemplate gUnknown_02024E8C; -extern struct Window gUnknown_03004210; -extern u8 gReservedSpritePaletteCount; -extern u8 gActionSelectionCursor[4]; -extern u8 gBankInMenu; -extern u16 gBattlerPartyIndexes[4]; -extern u8 gBattlersCount; -extern u16 gBattleTypeFlags; -extern u8 gBankSpriteIds[4]; -extern u8 gBattleMonForms[4]; -extern u8 gHealthboxIDs[4]; - -bool8 LoadChosenBattleElement(u8 a0); -bool8 sub_8031C30(u8 a0); -void sub_8031EE8(void); -void sub_80327CC(void); -void sub_8032984(u8 a, u16 b); -void sub_800FCD4(void); -void BattleLoadOpponentMonSprite(struct Pokemon *, u8 bank); -void BattleLoadPlayerMonSprite(struct Pokemon *, u8 bank); -void BattleLoadSubstituteSprite(u8 bank, u8 b); -void LoadPlayerTrainerBankSprite(u16 a0, u8 bank); -u8 sub_8077F7C(u8 bank); -u8 sub_8077F68(u8 bank); -void nullsub_11(u8 healthboxID, u8 a1); -void sub_8043DB0(u8 bank); -u8 battle_make_oam_normal_battle(u8 bank); -u8 battle_make_oam_safari_battle(void); -void sub_8045A5C(u8 healthboxID, struct Pokemon*, u8); -void sub_8043F44(u8 bank); -void sub_8043DFC(u8 healthboxID); - -// this file's functions -static void CB2_ReshowBattleScreenAfterMenu(void); -static bool8 LoadAppropiateBankSprite(u8 bank); -static void sub_807B184(u8 bank); -static void sub_807B508(u8 bank); -static void sub_807B06C(void); - -void nullsub_14(void) -{ - -} - -void ReshowBattleScreenAfterMenu(void) -{ - gPaletteFade.bufferTransferDisabled = 1; - SetHBlankCallback(0); - SetVBlankCallback(0); - REG_MOSAIC = 0; - gReshowState = 0; - gHelperState = 0; - SetMainCallback2(CB2_ReshowBattleScreenAfterMenu); -} - -static void CB2_ReshowBattleScreenAfterMenu(void) -{ - switch (gReshowState) - { - case 0: - ScanlineEffect_Clear(); - Text_LoadWindowTemplate(&gWindowTemplate_81E6C58); - ResetPaletteFade(); - Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58); - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gBattle_BG1_X = 0; - gBattle_BG1_Y = 0; - gBattle_BG2_X = 0; - gBattle_BG2_Y = 0; - gBattle_BG3_X = 0; - gBattle_BG3_Y = 0; - break; - case 1: - { - const u32 zero = 0; - CpuFastSet(&zero, (void*) VRAM, 0x1006000); - } - break; - case 2: - if (!LoadChosenBattleElement(gHelperState)) - { - gHelperState++; - gReshowState--; - } - else - gHelperState = 0; - break; - case 3: - ResetSpriteData(); - break; - case 4: - FreeAllSpritePalettes(); - gReservedSpritePaletteCount = 4; - break; - case 5: - sub_8031EE8(); - break; - case 6: - if (sub_8031C30(gHelperState)) - gHelperState = 0; - else - { - gHelperState++; - gReshowState--; - } - break; - case 7: - if (!LoadAppropiateBankSprite(0)) - gReshowState--; - break; - case 8: - if (!LoadAppropiateBankSprite(1)) - gReshowState--; - break; - case 9: - if (!LoadAppropiateBankSprite(2)) - gReshowState--; - break; - case 10: - if (!LoadAppropiateBankSprite(3)) - gReshowState--; - break; - case 11: - sub_807B184(0); - break; - case 12: - sub_807B184(1); - break; - case 13: - sub_807B184(2); - break; - case 14: - sub_807B184(3); - break; - case 15: - sub_807B508(0); - break; - case 16: - sub_807B508(1); - break; - case 17: - sub_807B508(2); - break; - case 18: - sub_807B508(3); - break; - case 19: - { - u8 opponentBank; - u16 species; - - sub_80327CC(); - - opponentBank = GetBattlerAtPosition(1); - species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[opponentBank]], MON_DATA_SPECIES); - sub_8032984(opponentBank, species); - - if (IsDoubleBattle()) - { - opponentBank = GetBattlerAtPosition(3); - species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[opponentBank]], MON_DATA_SPECIES); - sub_8032984(opponentBank, species); - } - sub_802E3E4(gActionSelectionCursor[gBankInMenu], 0); - } - break; - default: - SetHBlankCallback(sub_800FCD4); - SetVBlankCallback(sub_800FCFC); - sub_807B06C(); - BeginHardwarePaletteFade(0xFF, 0, 0x10, 0, 1); - gPaletteFade.bufferTransferDisabled = 0; - SetMainCallback2(BattleMainCB2); - break; - } - gReshowState++; -} - -static void sub_807B06C(void) -{ - sub_800D6D4(); - ((vBgCnt *)®_BG1CNT)->charBaseBlock = 0; - ((vBgCnt *)®_BG2CNT)->charBaseBlock = 0; -} - -static bool8 LoadAppropiateBankSprite(u8 bank) -{ - if (bank < gBattlersCount) - { - if (GetBattlerSide(bank)) - { - if (!ewram17800[bank].substituteSprite) - BattleLoadOpponentMonSprite(&gEnemyParty[gBattlerPartyIndexes[bank]], bank); - else - BattleLoadSubstituteSprite(bank, 0); - } - else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0) - LoadPlayerTrainerBankSprite(gSaveBlock2.playerGender, 0); - else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && bank == 0) - LoadPlayerTrainerBankSprite(2, 0); - else if (!ewram17800[bank].substituteSprite) - BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[bank]], bank); - else - BattleLoadSubstituteSprite(bank, 0); - - gHelperState = 0; - } - return 1; -} - -static void sub_807B184(u8 bank) -{ - if (bank < gBattlersCount) - { - u8 posY; - - if (ewram17800[bank].substituteSprite) - posY = sub_8077F7C(bank); - else - posY = sub_8077F68(bank); - if (GetBattlerSide(bank)) - { - if (GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_HP) == 0) - return; - GetMonSpriteTemplate_803C56C(GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES), GetBattlerPosition(bank)); - gBankSpriteIds[bank] = CreateSprite(&gUnknown_02024E8C, GetBattlerSpriteCoord(bank, 2), posY, GetBattlerSubpriority(bank)); - gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; - gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; - gSprites[gBankSpriteIds[bank]].data[0] = bank; - gSprites[gBankSpriteIds[bank]].data[2] = GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES); - StartSpriteAnim(&gSprites[gBankSpriteIds[bank]], gBattleMonForms[bank]); - } - else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0) - { - GetMonSpriteTemplate_803C5A0(gSaveBlock2.playerGender, GetBattlerPosition(0)); - gBankSpriteIds[bank] = CreateSprite(&gUnknown_02024E8C, 0x50, - (8 - gTrainerBackPicCoords[gSaveBlock2.playerGender].coords) * 4 + 80, - GetBattlerSubpriority(0)); - gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; - gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; - gSprites[gBankSpriteIds[bank]].data[0] = bank; - } - else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && bank == 0) - { - GetMonSpriteTemplate_803C5A0(2, GetBattlerPosition(0)); - gBankSpriteIds[bank] = CreateSprite(&gUnknown_02024E8C, 0x50, - (8 - gTrainerBackPicCoords[2].coords) * 4 + 80, - GetBattlerSubpriority(0)); - gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; - gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; - gSprites[gBankSpriteIds[bank]].data[0] = bank; - } - else - { - if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_HP) == 0) - return; - GetMonSpriteTemplate_803C56C(GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES), GetBattlerPosition(bank)); - gBankSpriteIds[bank] = CreateSprite(&gUnknown_02024E8C, GetBattlerSpriteCoord(bank, 2), posY, GetBattlerSubpriority(bank)); - gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; - gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; - gSprites[gBankSpriteIds[bank]].data[0] = bank; - gSprites[gBankSpriteIds[bank]].data[2] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES); - StartSpriteAnim(&gSprites[gBankSpriteIds[bank]], gBattleMonForms[bank]); - } - gSprites[gBankSpriteIds[bank]].invisible = ewram17800[bank].invisible; - } -} - -static void sub_807B508(u8 bank) -{ - if (bank < gBattlersCount) - { - u8 healthboxID; - if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0) - healthboxID = battle_make_oam_safari_battle(); - else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && bank == 0) - return; - else - healthboxID = battle_make_oam_normal_battle(bank); - gHealthboxIDs[bank] = healthboxID; - sub_8043F44(bank); - sub_8043DFC(healthboxID); - if (GetBattlerSide(bank)) - sub_8045A5C(gHealthboxIDs[bank], &gEnemyParty[gBattlerPartyIndexes[bank]], 0); - else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) - sub_8045A5C(gHealthboxIDs[bank], &gPlayerParty[gBattlerPartyIndexes[bank]], 10); - else - sub_8045A5C(gHealthboxIDs[bank], &gPlayerParty[gBattlerPartyIndexes[bank]], 0); - if (GetBattlerPosition(bank) == 3 || GetBattlerPosition(bank) == 2) - nullsub_11(gHealthboxIDs[bank], 1); - else - nullsub_11(gHealthboxIDs[bank], 0); - if (GetBattlerSide(bank)) - { - if (GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_HP) == 0) - sub_8043DB0(healthboxID); - } - else if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) - { - if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_HP) == 0) - sub_8043DB0(healthboxID); - } - } -} diff --git a/src/battle/smokescreen.c b/src/battle/smokescreen.c deleted file mode 100644 index dc2887007..000000000 --- a/src/battle/smokescreen.c +++ /dev/null @@ -1,73 +0,0 @@ -#include "global.h" -#include "data2.h" -#include "decompress.h" -#include "sprite.h" -#include "util.h" - - -static void sub_8046388(struct Sprite *); - - -u8 sub_8046234(s16 x, s16 y, u8 a3) -{ - u8 mainSpriteId; - u8 spriteId1, spriteId2, spriteId3, spriteId4; - struct Sprite *mainSprite; - - if (GetSpriteTileStartByTag(gUnknown_081FAEA4.tag) == 0xFFFF) - { - LoadCompressedObjectPic(&gUnknown_081FAEA4); - LoadCompressedObjectPalette(&gUnknown_081FAEAC); - } - - mainSpriteId = CreateInvisibleSpriteWithCallback(sub_8046388); - mainSprite = &gSprites[mainSpriteId]; - mainSprite->data[1] = a3; - - spriteId1 = CreateSprite(&gSpriteTemplate_81FAF0C, x - 16, y - 16, 2); - gSprites[spriteId1].data[0] = mainSpriteId; - mainSprite->data[0]++; - AnimateSprite(&gSprites[spriteId1]); - - spriteId2 = CreateSprite(&gSpriteTemplate_81FAF0C, x, y - 16, 2); - gSprites[spriteId2].data[0] = mainSpriteId; - mainSprite->data[0]++; - StartSpriteAnim(&gSprites[spriteId2], 1); - AnimateSprite(&gSprites[spriteId2]); - - spriteId3 = CreateSprite(&gSpriteTemplate_81FAF0C, x - 16, y, 2); - gSprites[spriteId3].data[0] = mainSpriteId; - mainSprite->data[0]++; - StartSpriteAnim(&gSprites[spriteId3], 2); - AnimateSprite(&gSprites[spriteId3]); - - spriteId4 = CreateSprite(&gSpriteTemplate_81FAF0C, x, y, 2); - gSprites[spriteId4].data[0] = mainSpriteId; - mainSprite->data[0]++; - StartSpriteAnim(&gSprites[spriteId4], 3); - AnimateSprite(&gSprites[spriteId4]); - - return mainSpriteId; -} - -static void sub_8046388(struct Sprite *sprite) -{ - if (!sprite->data[0]) - { - FreeSpriteTilesByTag(gUnknown_081FAEA4.tag); - FreeSpritePaletteByTag(gUnknown_081FAEAC.tag); - if (!sprite->data[1]) - DestroySprite(sprite); - else - sprite->callback = SpriteCallbackDummy; - } -} - -void sub_80463CC(struct Sprite *sprite) -{ - if (sprite->animEnded) - { - gSprites[sprite->data[0]].data[0]--; - DestroySprite(sprite); - } -} diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c new file mode 100644 index 000000000..57fb479e9 --- /dev/null +++ b/src/battle_ai_script_commands.c @@ -0,0 +1,2157 @@ +#include "global.h" +#include "battle_ai_script_commands.h" +#include "constants/abilities.h" +#include "battle.h" +#include "constants/battle_move_effects.h" +#include "data2.h" +#include "item.h" +#include "constants/moves.h" +#include "pokemon.h" +#include "random.h" +#include "rom_8077ABC.h" +#include "constants/species.h" +#include "util.h" +#include "ewram.h" + +extern u8 gUnknown_02023A14_50; +extern u32 gUnknown_02023A14_4C; +extern u16 gBattleTypeFlags; +extern u16 gBattleWeather; +extern u8 gActiveBattler; +extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; +extern u16 gCurrentMove; +extern int gBattleMoveDamage; +extern u8 gBankAttacker; +extern u8 gBankTarget; +extern u8 gAbsentBattlerFlags; +extern u8 gMoveResultFlags; +extern u16 gDynamicBasePower; +extern u16 gLastUsedMove[MAX_BATTLERS_COUNT]; +extern u32 gStatuses3[MAX_BATTLERS_COUNT]; +extern u16 gSideAffecting[2]; +extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; +extern u8 gCritMultiplier; +extern u16 gTrainerBattleOpponent; +extern u8 *BattleAIs[]; + +enum +{ + WEATHER_TYPE_SUN, + WEATHER_TYPE_RAIN, + WEATHER_TYPE_SANDSTORM, + WEATHER_TYPE_HAIL, +}; + +/* +gAIScriptPtr is a pointer to the next battle AI cmd command to read. +when a command finishes processing, gAIScriptPtr is incremented by +the number of bytes that the current command had reserved for arguments +in order to read the next command correctly. refer to battle_ai_scripts.s for the +AI scripts. +*/ +EWRAM_DATA u8 *gAIScriptPtr = NULL; + +static void BattleAICmd_if_random_less_than(void); +static void BattleAICmd_if_random_greater_than(void); +static void BattleAICmd_if_random_equal(void); +static void BattleAICmd_if_random_not_equal(void); +static void BattleAICmd_score(void); +static void BattleAICmd_if_hp_less_than(void); +static void BattleAICmd_if_hp_more_than(void); +static void BattleAICmd_if_hp_equal(void); +static void BattleAICmd_if_hp_not_equal(void); +static void BattleAICmd_if_status(void); +static void BattleAICmd_if_not_status(void); +static void BattleAICmd_if_status2(void); +static void BattleAICmd_if_not_status2(void); +static void BattleAICmd_if_status3(void); +static void BattleAICmd_if_not_status3(void); +static void BattleAICmd_if_status4(void); +static void BattleAICmd_if_not_status4(void); +static void BattleAICmd_if_less_than(void); +static void BattleAICmd_if_more_than(void); +static void BattleAICmd_if_equal(void); +static void BattleAICmd_if_not_equal(void); +static void BattleAICmd_if_less_than_32(void); +static void BattleAICmd_if_more_than_32(void); +static void BattleAICmd_if_equal_32(void); +static void BattleAICmd_if_not_equal_32(void); +static void BattleAICmd_if_move(void); +static void BattleAICmd_if_not_move(void); +static void BattleAICmd_if_in_bytes(void); +static void BattleAICmd_if_not_in_bytes(void); +static void BattleAICmd_if_in_words(void); +static void BattleAICmd_if_not_in_words(void); +static void BattleAICmd_if_user_can_damage(void); +static void BattleAICmd_if_user_cant_damage(void); +static void BattleAICmd_get_turn_count(void); +static void BattleAICmd_get_type(void); +static void BattleAICmd_get_move_power(void); +static void BattleAICmd_is_most_powerful_move(void); +static void BattleAICmd_get_move(void); +static void BattleAICmd_if_arg_equal(void); +static void BattleAICmd_if_arg_not_equal(void); +static void BattleAICmd_if_would_go_first(void); +static void BattleAICmd_if_would_not_go_first(void); +static void BattleAICmd_nullsub_2A(void); +static void BattleAICmd_nullsub_2B(void); +static void BattleAICmd_count_alive_pokemon(void); +static void BattleAICmd_get_considered_move(void); +static void BattleAICmd_get_considered_move_effect(void); +static void BattleAICmd_get_ability(void); +static void BattleAICmd_get_highest_possible_damage(void); +static void BattleAICmd_if_damage_bonus(void); +static void BattleAICmd_nullsub_32(void); +static void BattleAICmd_nullsub_33(void); +static void BattleAICmd_if_status_in_party(void); +static void BattleAICmd_if_status_not_in_party(void); +static void BattleAICmd_get_weather(void); +static void BattleAICmd_if_effect(void); +static void BattleAICmd_if_not_effect(void); +static void BattleAICmd_if_stat_level_less_than(void); +static void BattleAICmd_if_stat_level_more_than(void); +static void BattleAICmd_if_stat_level_equal(void); +static void BattleAICmd_if_stat_level_not_equal(void); +static void BattleAICmd_if_can_faint(void); +static void BattleAICmd_if_cant_faint(void); +static void BattleAICmd_if_has_move(void); +static void BattleAICmd_if_dont_have_move(void); +static void BattleAICmd_if_move_effect(void); +static void BattleAICmd_if_not_move_effect(void); +static void BattleAICmd_if_last_move_did_damage(void); +static void BattleAICmd_if_encored(void); +static void BattleAICmd_flee(void); +static void BattleAICmd_if_random_100(void); +static void BattleAICmd_watch(void); +static void BattleAICmd_get_hold_effect(void); +static void BattleAICmd_get_gender(void); +static void BattleAICmd_is_first_turn(void); +static void BattleAICmd_get_stockpile_count(void); +static void BattleAICmd_is_double_battle(void); +static void BattleAICmd_get_used_item(void); +static void BattleAICmd_get_move_type_from_result(void); +static void BattleAICmd_get_move_power_from_result(void); +static void BattleAICmd_get_move_effect_from_result(void); +static void BattleAICmd_get_protect_count(void); +static void BattleAICmd_nullsub_52(void); +static void BattleAICmd_nullsub_53(void); +static void BattleAICmd_nullsub_54(void); +static void BattleAICmd_nullsub_55(void); +static void BattleAICmd_nullsub_56(void); +static void BattleAICmd_nullsub_57(void); +static void BattleAICmd_call(void); +static void BattleAICmd_jump(void); +static void BattleAICmd_end(void); +static void BattleAICmd_if_level_compare(void); +static void BattleAICmd_if_taunted(void); +static void BattleAICmd_if_not_taunted(void); + +typedef void (*BattleAICmdFunc)(void); + +static const BattleAICmdFunc sBattleAICmdTable[] = +{ + BattleAICmd_if_random_less_than, // 0x0 + BattleAICmd_if_random_greater_than, // 0x1 + BattleAICmd_if_random_equal, // 0x2 + BattleAICmd_if_random_not_equal, // 0x3 + BattleAICmd_score, // 0x4 + BattleAICmd_if_hp_less_than, // 0x5 + BattleAICmd_if_hp_more_than, // 0x6 + BattleAICmd_if_hp_equal, // 0x7 + BattleAICmd_if_hp_not_equal, // 0x8 + BattleAICmd_if_status, // 0x9 + BattleAICmd_if_not_status, // 0xA + BattleAICmd_if_status2, // 0xB + BattleAICmd_if_not_status2, // 0xC + BattleAICmd_if_status3, // 0xD + BattleAICmd_if_not_status3, // 0xE + BattleAICmd_if_status4, // 0xF + BattleAICmd_if_not_status4, // 0x10 + BattleAICmd_if_less_than, // 0x11 + BattleAICmd_if_more_than, // 0x12 + BattleAICmd_if_equal, // 0x13 + BattleAICmd_if_not_equal, // 0x14 + BattleAICmd_if_less_than_32, // 0x15 + BattleAICmd_if_more_than_32, // 0x16 + BattleAICmd_if_equal_32, // 0x17 + BattleAICmd_if_not_equal_32, // 0x18 + BattleAICmd_if_move, // 0x19 + BattleAICmd_if_not_move, // 0x1A + BattleAICmd_if_in_bytes, // 0x1B + BattleAICmd_if_not_in_bytes, // 0x1C + BattleAICmd_if_in_words, // 0x1D + BattleAICmd_if_not_in_words, // 0x1E + BattleAICmd_if_user_can_damage, // 0x1F + BattleAICmd_if_user_cant_damage, // 0x20 + BattleAICmd_get_turn_count, // 0x21 + BattleAICmd_get_type, // 0x22 + BattleAICmd_get_move_power, // 0x23 + BattleAICmd_is_most_powerful_move, // 0x24 + BattleAICmd_get_move, // 0x25 + BattleAICmd_if_arg_equal, // 0x26 + BattleAICmd_if_arg_not_equal, // 0x27 + BattleAICmd_if_would_go_first, // 0x28 + BattleAICmd_if_would_not_go_first, // 0x29 + BattleAICmd_nullsub_2A, // 0x2A + BattleAICmd_nullsub_2B, // 0x2B + BattleAICmd_count_alive_pokemon, // 0x2C + BattleAICmd_get_considered_move, // 0x2D + BattleAICmd_get_considered_move_effect, // 0x2E + BattleAICmd_get_ability, // 0x2F + BattleAICmd_get_highest_possible_damage, // 0x30 + BattleAICmd_if_damage_bonus, // 0x31 + BattleAICmd_nullsub_32, // 0x32 + BattleAICmd_nullsub_33, // 0x33 + BattleAICmd_if_status_in_party, // 0x34 + BattleAICmd_if_status_not_in_party, // 0x35 + BattleAICmd_get_weather, // 0x36 + BattleAICmd_if_effect, // 0x37 + BattleAICmd_if_not_effect, // 0x38 + BattleAICmd_if_stat_level_less_than, // 0x39 + BattleAICmd_if_stat_level_more_than, // 0x3A + BattleAICmd_if_stat_level_equal, // 0x3B + BattleAICmd_if_stat_level_not_equal, // 0x3C + BattleAICmd_if_can_faint, // 0x3D + BattleAICmd_if_cant_faint, // 0x3E + BattleAICmd_if_has_move, // 0x3F + BattleAICmd_if_dont_have_move, // 0x40 + BattleAICmd_if_move_effect, // 0x41 + BattleAICmd_if_not_move_effect, // 0x42 + BattleAICmd_if_last_move_did_damage, // 0x43 + BattleAICmd_if_encored, // 0x44 + BattleAICmd_flee, // 0x45 + BattleAICmd_if_random_100, // 0x46 + BattleAICmd_watch, // 0x47 + BattleAICmd_get_hold_effect, // 0x48 + BattleAICmd_get_gender, // 0x49 + BattleAICmd_is_first_turn, // 0x4A + BattleAICmd_get_stockpile_count, // 0x4B + BattleAICmd_is_double_battle, // 0x4C + BattleAICmd_get_used_item, // 0x4D + BattleAICmd_get_move_type_from_result, // 0x4E + BattleAICmd_get_move_power_from_result, // 0x4F + BattleAICmd_get_move_effect_from_result, // 0x50 + BattleAICmd_get_protect_count, // 0x51 + BattleAICmd_nullsub_52, // 0x52 + BattleAICmd_nullsub_53, // 0x53 + BattleAICmd_nullsub_54, // 0x54 + BattleAICmd_nullsub_55, // 0x55 + BattleAICmd_nullsub_56, // 0x56 + BattleAICmd_nullsub_57, // 0x57 + BattleAICmd_call, // 0x58 + BattleAICmd_jump, // 0x59 + BattleAICmd_end, // 0x5A + BattleAICmd_if_level_compare, // 0x5B + BattleAICmd_if_taunted, // 0x5C + BattleAICmd_if_not_taunted, // 0x5D +}; + +#ifdef NONMATCHING +static +#endif +const u16 sDiscouragedPowerfulMoveEffects[] = +{ + EFFECT_EXPLOSION, + EFFECT_DREAM_EATER, + EFFECT_RAZOR_WIND, + EFFECT_SKY_ATTACK, + EFFECT_RECHARGE, + EFFECT_SKULL_BASH, + EFFECT_SOLARBEAM, + EFFECT_SPIT_UP, + EFFECT_FOCUS_PUNCH, + EFFECT_SUPERPOWER, + EFFECT_ERUPTION, + EFFECT_OVERHEAT, + 0xFFFF +}; + +// if the AI is a Link battle, safari, battle tower, or ereader, it will ignore considering item uses. +void BattleAI_HandleItemUseBeforeAISetup(void) +{ + s32 i; + u8 *data; + + MEMSET_ALT(AI_BATTLE_HISTORY, 0, sizeof(struct BattleHistory), i, data); + + if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) + && gTrainerBattleOpponent != 0x400 + && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_SAFARI | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER))) + { + for (i = 0; i < MAX_TRAINER_ITEMS; i++) + { + if (gTrainers[gTrainerBattleOpponent].items[i] != 0) + { + AI_BATTLE_HISTORY->trainerItems[AI_BATTLE_HISTORY->numItems] = gTrainers[gTrainerBattleOpponent].items[i]; + AI_BATTLE_HISTORY->numItems++; + } + } + } + + BattleAI_SetupAIData(); +} + +void BattleAI_SetupAIData(void) +{ + s32 i; + u8 limitations; + u8 *data; + + // clear AI data and set default move score to 100. strange that they didn't use memset here. + MEMSET_ALT(AI_THINKING_STRUCT, 0, sizeof(struct AI_ThinkingStruct), i, data); + + for (i = 0; i < MAX_MON_MOVES; i++) + AI_THINKING_STRUCT->score[i] = 100; + + limitations = CheckMoveLimitations(gActiveBattler, 0, 0xFF); + + // do not consider moves the AI cannot select + // also, roll simulated RNG for moves that have a degree of + // randomness. + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (gBitTable[i] & limitations) + AI_THINKING_STRUCT->score[i] = 0; + + AI_THINKING_STRUCT->simulatedRNG[i] = 100 - (Random() % 16); + } + + // clear AI stack. + AI_STACK->size = 0; + gBankAttacker = gActiveBattler; + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + gBankTarget = Random() & 2; // just pick somebody to target. + + if (gAbsentBattlerFlags & gBitTable[gBankTarget]) + gBankTarget ^= 2; + } + else + gBankTarget = gActiveBattler ^ 1; + + // special AI flag cases. + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + AI_THINKING_STRUCT->aiFlags = 0x40000000; + else if (gBattleTypeFlags & BATTLE_TYPE_ROAMER) + AI_THINKING_STRUCT->aiFlags = 0x20000000; + else if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) + AI_THINKING_STRUCT->aiFlags = 0x80000000; +#ifdef GERMAN + else if (gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER) || gTrainerBattleOpponent == SECRET_BASE_OPPONENT) + AI_THINKING_STRUCT->aiFlags = 7; +#endif + else // otherwise, just set aiFlags to whatever flags the trainer has set in their data. + AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent].aiFlags; +#if DEBUG + if (gUnknown_02023A14_50 & 1) + AI_THINKING_STRUCT->aiFlags = gUnknown_02023A14_4C; +#endif +} + +u8 BattleAI_GetAIActionToUse(void) +{ + u8 currentMoveArray[MAX_MON_MOVES]; + u8 consideredMoveArray[MAX_MON_MOVES]; + u8 numOfBestMoves; + s32 i; + + sub_810745C(); + while (AI_THINKING_STRUCT->aiFlags != 0) + { + if (AI_THINKING_STRUCT->aiFlags & 1) + { + AI_THINKING_STRUCT->aiState = BATTLEAI_SETTING_UP; + BattleAI_DoAIProcessing(); + } + AI_THINKING_STRUCT->aiFlags >>= 1; + AI_THINKING_STRUCT->aiLogicId++; + AI_THINKING_STRUCT->movesetIndex = 0; + } + + // special flee or watch cases for safari. + if (AI_THINKING_STRUCT->aiAction & (AI_ACTION_FLEE)) // flee + return 4; + if (AI_THINKING_STRUCT->aiAction & (AI_ACTION_WATCH)) // watch + return 5; + + numOfBestMoves = 1; + currentMoveArray[0] = AI_THINKING_STRUCT->score[0]; + consideredMoveArray[0] = 0; + + for (i = 1; i < MAX_MON_MOVES; i++) + { + if (currentMoveArray[0] < AI_THINKING_STRUCT->score[i]) + { + numOfBestMoves = 1; + currentMoveArray[0] = AI_THINKING_STRUCT->score[i]; + consideredMoveArray[0] = i; + } + if (currentMoveArray[0] == AI_THINKING_STRUCT->score[i]) + { + currentMoveArray[numOfBestMoves] = AI_THINKING_STRUCT->score[i]; + consideredMoveArray[numOfBestMoves++] = i; + } + } + + return consideredMoveArray[Random() % numOfBestMoves]; // break any ties that exist. +} + +void BattleAI_DoAIProcessing(void) +{ + while (AI_THINKING_STRUCT->aiState != BATTLEAI_FINISHED) + { + switch (AI_THINKING_STRUCT->aiState) + { + case BATTLEAI_DO_NOT_PROCESS: //Needed to match. + break; + case BATTLEAI_SETTING_UP: + gAIScriptPtr = BattleAIs[AI_THINKING_STRUCT->aiLogicId]; // set the AI ptr. + if (gBattleMons[gBankAttacker].pp[AI_THINKING_STRUCT->movesetIndex] == 0) + { + AI_THINKING_STRUCT->moveConsidered = MOVE_NONE; // don't consider a move you have 0 PP for, idiot. + } + else + { + AI_THINKING_STRUCT->moveConsidered = gBattleMons[gBankAttacker].moves[AI_THINKING_STRUCT->movesetIndex]; + } + AI_THINKING_STRUCT->aiState++; + break; + case BATTLEAI_PROCESSING: + if (AI_THINKING_STRUCT->moveConsidered != MOVE_NONE) + sBattleAICmdTable[*gAIScriptPtr](); // run AI command. + else + { + AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = 0; // definitely do not consider any move that has 0 PP. + AI_THINKING_STRUCT->aiAction |= AI_ACTION_DONE; + } + if (AI_THINKING_STRUCT->aiAction & AI_ACTION_DONE) + { + AI_THINKING_STRUCT->movesetIndex++; + if (AI_THINKING_STRUCT->movesetIndex < MAX_MON_MOVES && (AI_THINKING_STRUCT->aiAction & AI_ACTION_DO_NOT_ATTACK) == 0) + AI_THINKING_STRUCT->aiState = BATTLEAI_SETTING_UP; // as long as their are more moves to process, keep setting this to setup state. + else + AI_THINKING_STRUCT->aiState++; // done processing. + AI_THINKING_STRUCT->aiAction &= (AI_ACTION_FLEE | AI_ACTION_WATCH | AI_ACTION_DO_NOT_ATTACK | + AI_ACTION_UNK5 | AI_ACTION_UNK6 | AI_ACTION_UNK7 | AI_ACTION_UNK8); // disable AI_ACTION_DONE. + } + break; + } + } +} + +void sub_810745C(void) +{ + s32 i; + + for (i = 0; i < 8; i++) + { + if (AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i] == 0) + { + AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i] = gLastUsedMove[gBankTarget]; + return; + } + } +} + +void unref_sub_81074A0(u8 a) +{ + s32 i; + + for (i = 0; i < 8; i++) + AI_BATTLE_HISTORY->usedMoves[a / 2][i] = 0; +} + +void RecordAbilityBattle(u8 a, u8 b) +{ + if (GetBattlerSide(a) == 0) + AI_BATTLE_HISTORY->abilities[GetBattlerPosition(a) & 1] = b; +} + +void RecordItemBattle(u8 a, u8 b) +{ + if (GetBattlerSide(a) == 0) + AI_BATTLE_HISTORY->itemEffects[GetBattlerPosition(a) & 1] = b; +} + +static void BattleAICmd_if_random_less_than(void) +{ + if (Random() % 256 < gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_random_greater_than(void) +{ + if (Random() % 256 > gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_random_equal(void) +{ + if (Random() % 256 == gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_random_not_equal(void) +{ + if (Random() % 256 != gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_score(void) +{ + AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] += gAIScriptPtr[1]; // add the result to the array of the move consider's score. + + if (AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] < 0) // if the score is negative, flatten it to 0. + AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = 0; + + gAIScriptPtr += 2; // AI return. +} + +static void BattleAICmd_if_hp_less_than(void) +{ + u16 index; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) < gAIScriptPtr[2]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_hp_more_than(void) +{ + u16 index; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) > gAIScriptPtr[2]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_hp_equal(void) +{ + u16 index; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) == gAIScriptPtr[2]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_hp_not_equal(void) +{ + u16 index; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + if ((u32)(100 * gBattleMons[index].hp / gBattleMons[index].maxHP) != gAIScriptPtr[2]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_status(void) +{ + u16 index; + u32 arg; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + arg = T1_READ_32(gAIScriptPtr + 2); + + if ((gBattleMons[index].status1 & arg) != 0) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_not_status(void) +{ + u16 index; + u32 arg; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + arg = T1_READ_32(gAIScriptPtr + 2); + + if ((gBattleMons[index].status1 & arg) == 0) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_status2(void) +{ + u16 index; + u32 arg; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + arg = T1_READ_32(gAIScriptPtr + 2); + + if ((gBattleMons[index].status2 & arg) != 0) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_not_status2(void) +{ + u16 index; + u32 arg; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + arg = T1_READ_32(gAIScriptPtr + 2); + + if ((gBattleMons[index].status2 & arg) == 0) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_status3(void) +{ + u16 index; + u32 arg; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + arg = T1_READ_32(gAIScriptPtr + 2); + + if ((gStatuses3[index] & arg) != 0) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_not_status3(void) +{ + u16 index; + u32 arg; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + arg = T1_READ_32(gAIScriptPtr + 2); + + if ((gStatuses3[index] & arg) == 0) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_status4(void) +{ + u16 index; + u32 arg1, arg2; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + arg1 = GetBattlerPosition(index) & 1; + arg2 = T1_READ_32(gAIScriptPtr + 2); + + if ((gSideAffecting[arg1] & arg2) != 0) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_not_status4(void) +{ + u16 index; + u32 arg1, arg2; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + arg1 = GetBattlerPosition(index) & 1; + arg2 = T1_READ_32(gAIScriptPtr + 2); + + if ((gSideAffecting[arg1] & arg2) == 0) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); + else + gAIScriptPtr += 10; +} + +static void BattleAICmd_if_less_than(void) +{ + if (AI_THINKING_STRUCT->funcResult < gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_more_than(void) +{ + if (AI_THINKING_STRUCT->funcResult > gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_equal(void) +{ + if (AI_THINKING_STRUCT->funcResult == gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_not_equal(void) +{ + if (AI_THINKING_STRUCT->funcResult != gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_less_than_32(void) +{ + u8 *temp = T1_READ_PTR(gAIScriptPtr + 1); + + if (AI_THINKING_STRUCT->funcResult < *temp) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); + else + gAIScriptPtr += 9; +} + +static void BattleAICmd_if_more_than_32(void) +{ + u8 *temp = T1_READ_PTR(gAIScriptPtr + 1); + + if (AI_THINKING_STRUCT->funcResult > *temp) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); + else + gAIScriptPtr += 9; +} + +static void BattleAICmd_if_equal_32(void) +{ + u8 *temp = T1_READ_PTR(gAIScriptPtr + 1); + + if (AI_THINKING_STRUCT->funcResult == *temp) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); + else + gAIScriptPtr += 9; +} + +static void BattleAICmd_if_not_equal_32(void) +{ + u8 *temp = T1_READ_PTR(gAIScriptPtr + 1); + + if (AI_THINKING_STRUCT->funcResult != *temp) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); + else + gAIScriptPtr += 9; +} + +static void BattleAICmd_if_move(void) +{ + u16 move = T1_READ_16(gAIScriptPtr + 1); + + if (AI_THINKING_STRUCT->moveConsidered == move) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_not_move(void) +{ + u16 move = T1_READ_16(gAIScriptPtr + 1); + + if (AI_THINKING_STRUCT->moveConsidered != move) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_in_bytes(void) +{ + u8 *ptr = T1_READ_PTR(gAIScriptPtr + 1); + + while (*ptr != 0xFF) + { + if (AI_THINKING_STRUCT->funcResult == *ptr) + { + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); + return; + } + ptr++; + } + gAIScriptPtr += 9; +} + +static void BattleAICmd_if_not_in_bytes(void) +{ + u8 *ptr = T1_READ_PTR(gAIScriptPtr + 1); + + while (*ptr != 0xFF) + { + if (AI_THINKING_STRUCT->funcResult == *ptr) + { + gAIScriptPtr += 9; + return; + } + ptr++; + } + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); +} + +static void BattleAICmd_if_in_words(void) +{ + u16 *ptr = (u16 *)T1_READ_PTR(gAIScriptPtr + 1); + + while (*ptr != 0xFFFF) + { + if (AI_THINKING_STRUCT->funcResult == *ptr) + { + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); + return; + } + ptr++; + } + gAIScriptPtr += 9; +} + +static void BattleAICmd_if_not_in_words(void) +{ + u16 *ptr = (u16 *)T1_READ_PTR(gAIScriptPtr + 1); + + while (*ptr != 0xFFFF) + { + if (AI_THINKING_STRUCT->funcResult == *ptr) + { + gAIScriptPtr += 9; + return; + } + ptr++; + } + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); +} + +static void BattleAICmd_if_user_can_damage(void) +{ + s32 i; + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (gBattleMons[gBankAttacker].moves[i] != 0 + && gBattleMoves[gBattleMons[gBankAttacker].moves[i]].power != 0) + break; + } + if (i == MAX_MON_MOVES) + gAIScriptPtr += 5; + else + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); +} + +static void BattleAICmd_if_user_cant_damage(void) +{ + s32 i; + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (gBattleMons[gBankAttacker].moves[i] != 0 + && gBattleMoves[gBattleMons[gBankAttacker].moves[i]].power != 0) + break; + } + if (i != MAX_MON_MOVES) + gAIScriptPtr += 5; + else + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); +} + +static void BattleAICmd_get_turn_count(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleResults.battleTurnCounter; + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_type(void) +{ + switch (gAIScriptPtr[1]) + { + case 1: // player primary type + AI_THINKING_STRUCT->funcResult = gBattleMons[gBankAttacker].type1; + break; + case 0: // enemy primary type + AI_THINKING_STRUCT->funcResult = gBattleMons[gBankTarget].type1; + break; + case 3: // player secondary type + AI_THINKING_STRUCT->funcResult = gBattleMons[gBankAttacker].type2; + break; + case 2: // enemy secondary type + AI_THINKING_STRUCT->funcResult = gBattleMons[gBankTarget].type2; + break; + case 4: // type of move being pointed to + AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].type; + break; + } + gAIScriptPtr += 2; +} + +static void BattleAICmd_get_move_power(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power; + gAIScriptPtr += 1; +} + +#ifdef NONMATCHING +static void BattleAICmd_is_most_powerful_move(void) +{ + int i, j; + s32 damages[MAX_MON_MOVES]; + + for (i = 0; sDiscouragedPowerfulMoveEffects[i] != 0xFFFF; i++) + if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect == sDiscouragedPowerfulMoveEffects[i]) + break; + + if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power > 1 + && sDiscouragedPowerfulMoveEffects[i] == 0xFFFF) + { + gDynamicBasePower = 0; + eDynamicMoveType = 0; + eDmgMultiplier = 1; + gMoveResultFlags = 0; + gCritMultiplier = 1; + + for (i = 0; i < MAX_MON_MOVES; i++) + { + for (j = 0; sDiscouragedPowerfulMoveEffects[j] != 0xFFFF; j++) + { // _08108276 + if (gBattleMoves[gBattleMons[gBankAttacker].moves[i]].effect == sDiscouragedPowerfulMoveEffects[j]) + break; + } + + // _081082BA + if (gBattleMons[gBankAttacker].moves[i] + && sDiscouragedPowerfulMoveEffects[j] == 0xFFFF + && gBattleMoves[gBattleMons[gBankAttacker].moves[i]].power > 1) + { + gCurrentMove = gBattleMons[gBankAttacker].moves[i]; + AI_CalcDmg(gBankAttacker, gBankTarget); + TypeCalc(gCurrentMove, gBankAttacker, gBankTarget); + damages[i] = (gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[i]) / 100; + + if (damages[i] == 0) // moves always do at least 1 damage. + damages[i] = 1; + } + else + { + damages[i] = 0; + } + } + + for (i = 0; i < MAX_MON_MOVES; i++) + if (damages[i] > damages[AI_THINKING_STRUCT->movesetIndex]) + break; + + if (i == MAX_MON_MOVES) + AI_THINKING_STRUCT->funcResult = 2; + else + AI_THINKING_STRUCT->funcResult = 1; + } + else + { + AI_THINKING_STRUCT->funcResult = 0; + } + + gAIScriptPtr += 1; +} +#else +NAKED +static void BattleAICmd_is_most_powerful_move(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x14\n\ + movs r3, 0\n\ + ldr r0, _08108328 @ =sDiscouragedPowerfulMoveEffects\n\ + ldrh r1, [r0]\n\ + ldr r4, _0810832C @ =0x0000ffff\n\ + ldr r6, _08108330 @ =gBattleMoves\n\ + ldr r5, _08108334 @ =gSharedMem + 0x16800\n\ + cmp r1, r4\n\ + beq _0810822E\n\ + ldrh r1, [r5, 0x2]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldrb r2, [r0]\n\ + ldr r1, _08108328 @ =sDiscouragedPowerfulMoveEffects\n\ +_0810821E:\n\ + ldrh r0, [r1]\n\ + cmp r2, r0\n\ + beq _0810822E\n\ + adds r1, 0x2\n\ + adds r3, 0x1\n\ + ldrh r0, [r1]\n\ + cmp r0, r4\n\ + bne _0810821E\n\ +_0810822E:\n\ + ldrh r0, [r5, 0x2]\n\ + lsls r1, r0, 1\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + adds r1, r6\n\ + ldrb r0, [r1, 0x1]\n\ + cmp r0, 0x1\n\ + bhi _08108240\n\ + b _081083B2\n\ +_08108240:\n\ + lsls r0, r3, 1\n\ + ldr r1, _08108328 @ =sDiscouragedPowerfulMoveEffects\n\ + adds r0, r1\n\ + ldrh r3, [r0]\n\ + ldr r0, _0810832C @ =0x0000ffff\n\ + cmp r3, r0\n\ + beq _08108250\n\ + b _081083B2\n\ +_08108250:\n\ + ldr r0, _08108338 @ =gDynamicBasePower\n\ + movs r1, 0\n\ + strh r1, [r0]\n\ + ldr r2, _0810833C @ =0xfffff81c\n\ + adds r0, r5, r2\n\ + strb r1, [r0]\n\ + adds r2, 0x3\n\ + adds r0, r5, r2\n\ + movs r2, 0x1\n\ + strb r2, [r0]\n\ + ldr r0, _08108340 @ =gMoveResultFlags\n\ + strb r1, [r0]\n\ + ldr r0, _08108344 @ =gCritMultiplier\n\ + strb r2, [r0]\n\ + movs r6, 0\n\ + mov r9, r3\n\ + ldr r0, _08108328 @ =sDiscouragedPowerfulMoveEffects\n\ + ldrh r0, [r0]\n\ + str r0, [sp, 0x10]\n\ +_08108276:\n\ + movs r3, 0\n\ + ldr r5, _08108348 @ =gBattleMons\n\ + lsls r4, r6, 1\n\ + ldr r7, _0810834C @ =gBankAttacker\n\ + lsls r1, r6, 2\n\ + mov r8, r1\n\ + adds r2, r6, 0x1\n\ + mov r10, r2\n\ + ldr r0, [sp, 0x10]\n\ + cmp r0, r9\n\ + beq _081082BA\n\ + ldr r2, _08108330 @ =gBattleMoves\n\ + ldrb r1, [r7]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r4, r0\n\ + adds r1, r5, 0\n\ + adds r1, 0xC\n\ + adds r0, r1\n\ + ldrh r1, [r0]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r2, [r0]\n\ + ldr r1, _08108328 @ =sDiscouragedPowerfulMoveEffects\n\ +_081082AA:\n\ + ldrh r0, [r1]\n\ + cmp r2, r0\n\ + beq _081082BA\n\ + adds r1, 0x2\n\ + adds r3, 0x1\n\ + ldrh r0, [r1]\n\ + cmp r0, r9\n\ + bne _081082AA\n\ +_081082BA:\n\ + ldrb r1, [r7]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r4, r0\n\ + adds r1, r5, 0\n\ + adds r1, 0xC\n\ + adds r1, r0, r1\n\ + ldrh r0, [r1]\n\ + cmp r0, 0\n\ + beq _0810835C\n\ + lsls r0, r3, 1\n\ + ldr r2, _08108328 @ =sDiscouragedPowerfulMoveEffects\n\ + adds r0, r2\n\ + ldrh r0, [r0]\n\ + cmp r0, r9\n\ + bne _0810835C\n\ + ldr r0, _08108330 @ =gBattleMoves\n\ + ldrh r2, [r1]\n\ + lsls r1, r2, 1\n\ + adds r1, r2\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + cmp r0, 0x1\n\ + bls _0810835C\n\ + ldr r5, _08108350 @ =gCurrentMove\n\ + strh r2, [r5]\n\ + ldrb r0, [r7]\n\ + ldr r4, _08108354 @ =gBankTarget\n\ + ldrb r1, [r4]\n\ + bl AI_CalcDmg\n\ + ldrh r0, [r5]\n\ + ldrb r1, [r7]\n\ + ldrb r2, [r4]\n\ + bl TypeCalc\n\ + mov r4, sp\n\ + add r4, r8\n\ + ldr r2, _08108358 @ =gBattleMoveDamage\n\ + ldr r0, _08108334 @ =gSharedMem + 0x16800\n\ + adds r0, 0x18\n\ + adds r0, r6, r0\n\ + ldrb r1, [r0]\n\ + ldr r0, [r2]\n\ + muls r0, r1\n\ + movs r1, 0x64\n\ + bl __divsi3\n\ + str r0, [r4]\n\ + cmp r0, 0\n\ + bne _08108364\n\ + movs r0, 0x1\n\ + str r0, [r4]\n\ + b _08108364\n\ + .align 2, 0\n\ +_08108328: .4byte sDiscouragedPowerfulMoveEffects\n\ +_0810832C: .4byte 0x0000ffff\n\ +_08108330: .4byte gBattleMoves\n\ +_08108334: .4byte gSharedMem + 0x16800\n\ +_08108338: .4byte gDynamicBasePower\n\ +_0810833C: .4byte 0xfffff81c\n\ +_08108340: .4byte gMoveResultFlags\n\ +_08108344: .4byte gCritMultiplier\n\ +_08108348: .4byte gBattleMons\n\ +_0810834C: .4byte gBankAttacker\n\ +_08108350: .4byte gCurrentMove\n\ +_08108354: .4byte gBankTarget\n\ +_08108358: .4byte gBattleMoveDamage\n\ +_0810835C:\n\ + mov r1, sp\n\ + add r1, r8\n\ + movs r0, 0\n\ + str r0, [r1]\n\ +_08108364:\n\ + mov r6, r10\n\ + cmp r6, 0x3\n\ + ble _08108276\n\ + movs r6, 0\n\ + ldr r1, _081083A4 @ =gSharedMem + 0x16800\n\ + ldrb r0, [r1, 0x1]\n\ + lsls r0, 2\n\ + add r0, sp\n\ + ldr r2, [sp]\n\ + ldr r0, [r0]\n\ + adds r5, r1, 0\n\ + ldr r4, _081083A8 @ =gAIScriptPtr\n\ + cmp r2, r0\n\ + bgt _0810839A\n\ + adds r3, r5, 0\n\ + mov r2, sp\n\ +_08108384:\n\ + adds r2, 0x4\n\ + adds r6, 0x1\n\ + cmp r6, 0x3\n\ + bgt _0810839A\n\ + ldrb r0, [r3, 0x1]\n\ + lsls r0, 2\n\ + add r0, sp\n\ + ldr r1, [r2]\n\ + ldr r0, [r0]\n\ + cmp r1, r0\n\ + ble _08108384\n\ +_0810839A:\n\ + cmp r6, 0x4\n\ + bne _081083AC\n\ + movs r0, 0x2\n\ + str r0, [r5, 0x8]\n\ + b _081083B8\n\ + .align 2, 0\n\ +_081083A4: .4byte gSharedMem + 0x16800\n\ +_081083A8: .4byte gAIScriptPtr\n\ +_081083AC:\n\ + movs r0, 0x1\n\ + str r0, [r5, 0x8]\n\ + b _081083B8\n\ +_081083B2:\n\ + movs r0, 0\n\ + str r0, [r5, 0x8]\n\ + ldr r4, _081083D0 @ =gAIScriptPtr\n\ +_081083B8:\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + str r0, [r4]\n\ + add sp, 0x14\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_081083D0: .4byte gAIScriptPtr\n\ + .syntax divided\n"); +} +#endif // NONMATCHING + +static void BattleAICmd_get_move(void) +{ + if (gAIScriptPtr[1] == USER) + AI_THINKING_STRUCT->funcResult = gLastUsedMove[gBankAttacker]; + else + AI_THINKING_STRUCT->funcResult = gLastUsedMove[gBankTarget]; + + gAIScriptPtr += 2; +} + +static void BattleAICmd_if_arg_equal(void) +{ + if (gAIScriptPtr[1] == AI_THINKING_STRUCT->funcResult) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_arg_not_equal(void) +{ + if (gAIScriptPtr[1] != AI_THINKING_STRUCT->funcResult) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_would_go_first(void) +{ + if (GetWhoStrikesFirst(gBankAttacker, gBankTarget, TRUE) == gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_would_not_go_first(void) +{ + if (GetWhoStrikesFirst(gBankAttacker, gBankTarget, TRUE) != gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_nullsub_2A(void) +{ +} + +static void BattleAICmd_nullsub_2B(void) +{ +} + +static void BattleAICmd_count_alive_pokemon(void) +{ + struct Pokemon *party; + int i; + u8 index; + u8 var, var2; + + AI_THINKING_STRUCT->funcResult = 0; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + if (GetBattlerSide(index) == 0) + party = gPlayerParty; + else + party = gEnemyParty; + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + u32 status; + var = gBattlerPartyIndexes[index]; + status = GetBattlerPosition(index) ^ 2; + var2 = gBattlerPartyIndexes[GetBattlerAtPosition(status)]; + } + else + { + var = gBattlerPartyIndexes[index]; + var2 = gBattlerPartyIndexes[index]; + } + + for (i = 0; i < 6; i++) + { + if (i != var && i != var2 + && GetMonData(&party[i], MON_DATA_HP) != 0 + && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_NONE + && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG) + { + AI_THINKING_STRUCT->funcResult++; + } + } + + gAIScriptPtr += 2; +} + +static void BattleAICmd_get_considered_move(void) +{ + AI_THINKING_STRUCT->funcResult = AI_THINKING_STRUCT->moveConsidered; + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_considered_move_effect(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect; + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_ability(void) +{ + u8 index; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + if (GetBattlerSide(index) == TARGET) + { + u16 side = GetBattlerPosition(index) & 1; + + if (AI_BATTLE_HISTORY->abilities[side] != 0) + { + AI_THINKING_STRUCT->funcResult = AI_BATTLE_HISTORY->abilities[side]; + gAIScriptPtr += 2; + return; + } + + // abilities that prevent fleeing. + if (gBattleMons[index].ability == ABILITY_SHADOW_TAG + || gBattleMons[index].ability == ABILITY_MAGNET_PULL + || gBattleMons[index].ability == ABILITY_ARENA_TRAP) + { + AI_THINKING_STRUCT->funcResult = gBattleMons[index].ability; + gAIScriptPtr += 2; + return; + } + + if (gBaseStats[gBattleMons[index].species].ability1 != ABILITY_NONE) + { + if (gBaseStats[gBattleMons[index].species].ability2 != ABILITY_NONE) + { + // AI has no knowledge of opponent, so it guesses which ability. + if (Random() % 2) + { + AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability1; + } + else + { + AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability2; + } + } + else + { + AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability1; // it's definitely ability 1. + } + } + else + { + AI_THINKING_STRUCT->funcResult = gBaseStats[gBattleMons[index].species].ability2; // AI cant actually reach this part since every mon has at least 1 ability. + } + } + else + { + // The AI knows its own ability. + AI_THINKING_STRUCT->funcResult = gBattleMons[index].ability; + } + gAIScriptPtr += 2; +} + +static void BattleAICmd_get_highest_possible_damage(void) +{ + s32 i; + + gDynamicBasePower = 0; + gBattleStruct->dynamicMoveType = 0; + gBattleStruct->dmgMultiplier = 1; + gMoveResultFlags = 0; + gCritMultiplier = 1; + AI_THINKING_STRUCT->funcResult = 0; + + for (i = 0; i < MAX_MON_MOVES; i++) + { + gBattleMoveDamage = 40; + gCurrentMove = gBattleMons[gBankAttacker].moves[i]; + + if (gCurrentMove) + { + TypeCalc(gCurrentMove, gBankAttacker, gBankTarget); + + // reduce by 1/3. + if (gBattleMoveDamage == 120) + gBattleMoveDamage = 80; + if (gBattleMoveDamage == 240) + gBattleMoveDamage = 160; + if (gBattleMoveDamage == 30) + gBattleMoveDamage = 20; + if (gBattleMoveDamage == 15) + gBattleMoveDamage = 10; + + if (gMoveResultFlags & 8) // if it's a status move, it wont do anything. + gBattleMoveDamage = 0; + + if (AI_THINKING_STRUCT->funcResult < gBattleMoveDamage) + AI_THINKING_STRUCT->funcResult = gBattleMoveDamage; + } + } + gAIScriptPtr += 1; +} + +static void BattleAICmd_if_damage_bonus(void) +{ + u8 damageVar; + + gDynamicBasePower = 0; + gBattleStruct->dynamicMoveType = 0; + gBattleStruct->dmgMultiplier = 1; + gMoveResultFlags = 0; + gCritMultiplier = 1; + + gBattleMoveDamage = 40; + gCurrentMove = AI_THINKING_STRUCT->moveConsidered; + + TypeCalc(gCurrentMove, gBankAttacker, gBankTarget); + + if (gBattleMoveDamage == 120) + gBattleMoveDamage = 80; + if (gBattleMoveDamage == 240) + gBattleMoveDamage = 160; + if (gBattleMoveDamage == 30) + gBattleMoveDamage = 20; + if (gBattleMoveDamage == 15) + gBattleMoveDamage = 10; + + if (gMoveResultFlags & 8) + gBattleMoveDamage = 0; + + // store gBattleMoveDamage in a u8 variable because gAIScriptPtr[1] is a u8. + damageVar = gBattleMoveDamage; + + if (damageVar == gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_nullsub_32(void) +{ +} + +static void BattleAICmd_nullsub_33(void) +{ +} + +static void BattleAICmd_if_status_in_party(void) +{ + struct Pokemon *party; + struct Pokemon *partyPtr; + int i; + u32 statusToCompareTo; + + // for whatever reason, game freak put the party pointer into 2 variables instead of 1. it's possible at some point the switch encompassed the whole function and used each respective variable creating largely duplicate code. + switch (gAIScriptPtr[1]) + { + case 1: + party = partyPtr = gEnemyParty; + break; + default: + party = partyPtr = gPlayerParty; + break; + } + + statusToCompareTo = T1_READ_32(gAIScriptPtr + 2); + + for (i = 0; i < 6; i++) + { + u16 species = GetMonData(&party[i], MON_DATA_SPECIES); + u16 hp = GetMonData(&party[i], MON_DATA_HP); + u32 status = GetMonData(&party[i], MON_DATA_STATUS); + + if (species != SPECIES_NONE && species != SPECIES_EGG && hp != 0 && status == statusToCompareTo) + { + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); // WHAT. why is this being merged into the above switch + return; + } + } + + gAIScriptPtr += 10; +} + +// bugged, doesnt return properly. also unused +static void BattleAICmd_if_status_not_in_party(void) +{ + struct Pokemon *party; + struct Pokemon *partyPtr; + int i; + u32 statusToCompareTo; + + switch (gAIScriptPtr[1]) + { + case 1: + party = partyPtr = gEnemyParty; + break; + default: + party = partyPtr = gPlayerParty; + break; + } + + statusToCompareTo = T1_READ_32(gAIScriptPtr + 2); + + for (i = 0; i < 6; i++) + { + u16 species = GetMonData(&party[i], MON_DATA_SPECIES); + u16 hp = GetMonData(&party[i], MON_DATA_HP); + u32 status = GetMonData(&party[i], MON_DATA_STATUS); + + // everytime the status is found, the AI's logic jumps further and further past its intended destination. this results in a broken AI macro and is probably why it is unused. + if (species != SPECIES_NONE && species != SPECIES_EGG && hp != 0 && status == statusToCompareTo) + gAIScriptPtr += 10; // doesnt return? + } + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); +} + +static void BattleAICmd_get_weather(void) +{ + if (gBattleWeather & WEATHER_RAIN_ANY) + AI_THINKING_STRUCT->funcResult = WEATHER_TYPE_RAIN; + if (gBattleWeather & WEATHER_SANDSTORM_ANY) + AI_THINKING_STRUCT->funcResult = WEATHER_TYPE_SANDSTORM; + if (gBattleWeather & WEATHER_SUN_ANY) + AI_THINKING_STRUCT->funcResult = WEATHER_TYPE_SUN; + if (gBattleWeather & WEATHER_HAIL) + AI_THINKING_STRUCT->funcResult = WEATHER_TYPE_HAIL; + + gAIScriptPtr += 1; +} + +static void BattleAICmd_if_effect(void) +{ + if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect == gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_not_effect(void) +{ + if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect != gAIScriptPtr[1]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + else + gAIScriptPtr += 6; +} + +static void BattleAICmd_if_stat_level_less_than(void) +{ + u32 party; + + if (gAIScriptPtr[1] == USER) + party = gBankAttacker; + else + party = gBankTarget; + + if (gBattleMons[party].statStages[gAIScriptPtr[2]] < gAIScriptPtr[3]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); + else + gAIScriptPtr += 8; +} + +static void BattleAICmd_if_stat_level_more_than(void) +{ + u32 party; + + if (gAIScriptPtr[1] == USER) + party = gBankAttacker; + else + party = gBankTarget; + + if (gBattleMons[party].statStages[gAIScriptPtr[2]] > gAIScriptPtr[3]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); + else + gAIScriptPtr += 8; +} + +static void BattleAICmd_if_stat_level_equal(void) +{ + u32 party; + + if (gAIScriptPtr[1] == USER) + party = gBankAttacker; + else + party = gBankTarget; + + if (gBattleMons[party].statStages[gAIScriptPtr[2]] == gAIScriptPtr[3]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); + else + gAIScriptPtr += 8; +} + +static void BattleAICmd_if_stat_level_not_equal(void) +{ + u32 party; + + if (gAIScriptPtr[1] == USER) + party = gBankAttacker; + else + party = gBankTarget; + + if (gBattleMons[party].statStages[gAIScriptPtr[2]] != gAIScriptPtr[3]) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); + else + gAIScriptPtr += 8; +} + +static void BattleAICmd_if_can_faint(void) +{ + if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power < 2) + { + gAIScriptPtr += 5; + return; + } + + gDynamicBasePower = 0; + gBattleStruct->dynamicMoveType = 0; + gBattleStruct->dmgMultiplier = 1; + gMoveResultFlags = 0; + gCritMultiplier = 1; + gCurrentMove = AI_THINKING_STRUCT->moveConsidered; + AI_CalcDmg(gBankAttacker, gBankTarget); + TypeCalc(gCurrentMove, gBankAttacker, gBankTarget); + + gBattleMoveDamage = gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[AI_THINKING_STRUCT->movesetIndex] / 100; + + // moves always do at least 1 damage. + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + if (gBattleMons[gBankTarget].hp <= gBattleMoveDamage) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); + else + gAIScriptPtr += 5; +} + +static void BattleAICmd_if_cant_faint(void) +{ + if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power < 2) + { + gAIScriptPtr += 5; + return; + } + + gDynamicBasePower = 0; + gBattleStruct->dynamicMoveType = 0; + gBattleStruct->dmgMultiplier = 1; + gMoveResultFlags = 0; + gCritMultiplier = 1; + gCurrentMove = AI_THINKING_STRUCT->moveConsidered; + AI_CalcDmg(gBankAttacker, gBankTarget); + TypeCalc(gCurrentMove, gBankAttacker, gBankTarget); + + gBattleMoveDamage = gBattleMoveDamage * AI_THINKING_STRUCT->simulatedRNG[AI_THINKING_STRUCT->movesetIndex] / 100; + + // this macro is missing the damage 0 = 1 assumption. + + if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); + else + gAIScriptPtr += 5; +} + +static void BattleAICmd_if_has_move(void) +{ + int i; + u16 *temp_ptr = (u16 *)(gAIScriptPtr + 2); + + switch (gAIScriptPtr[1]) + { + case 1: + case 3: + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (gBattleMons[gBankAttacker].moves[i] == *temp_ptr) + break; + } + if (i == MAX_MON_MOVES) + gAIScriptPtr += 8; + else + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); + break; + case 0: + case 2: + for (i = 0; i < 8; i++) + { + if (AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i] == *temp_ptr) + break; + } + if (i == 8) + gAIScriptPtr += 8; + else + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); + break; + } +} + +static void BattleAICmd_if_dont_have_move(void) +{ + int i; + u16 *temp_ptr = (u16 *)(gAIScriptPtr + 2); + + switch (gAIScriptPtr[1]) + { + case 1: + case 3: + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (gBattleMons[gBankAttacker].moves[i] == *temp_ptr) + break; + } + if (i != MAX_MON_MOVES) + gAIScriptPtr += 8; + else + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); + break; + case 0: + case 2: + for (i = 0; i < 8; i++) + { + if (AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i] == *temp_ptr) + break; + } + if (i != 8) + gAIScriptPtr += 8; + else + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); + break; + } +} + +static void BattleAICmd_if_move_effect(void) +{ + int i; + + switch (gAIScriptPtr[1]) + { + case 1: + case 3: + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (gBattleMons[gBankAttacker].moves[i] != 0 && gBattleMoves[gBattleMons[gBankAttacker].moves[i]].effect == gAIScriptPtr[2]) + break; + } + if (i != MAX_MON_MOVES) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); + else + gAIScriptPtr += 7; + break; + case 0: + case 2: + for (i = 0; i < 8; i++) + { + if (gBattleMons[gBankAttacker].moves[i] != 0 && gBattleMoves[AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i]].effect == gAIScriptPtr[2]) + break; + } + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); + } +} + +static void BattleAICmd_if_not_move_effect(void) +{ + int i; + + switch (gAIScriptPtr[1]) + { + case 1: + case 3: + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (gBattleMons[gBankAttacker].moves[i] != 0 && gBattleMoves[gBattleMons[gBankAttacker].moves[i]].effect == gAIScriptPtr[2]) + break; + } + if (i != MAX_MON_MOVES) + gAIScriptPtr += 7; + else + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); + break; + case 0: + case 2: + for (i = 0; i < 8; i++) + { + if (AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i] != 0 && gBattleMoves[AI_BATTLE_HISTORY->usedMoves[gBankTarget >> 1][i]].effect == gAIScriptPtr[2]) + break; + } + gAIScriptPtr += 7; + } +} + +static void BattleAICmd_if_last_move_did_damage(void) +{ + u8 index; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + if (gAIScriptPtr[2] == 0) + { + if (gDisableStructs[index].disabledMove == 0) + { + gAIScriptPtr += 7; + return; + } + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); + return; + } + else if (gAIScriptPtr[2] != 1) // ignore the macro if its not 0 or 1. + { + gAIScriptPtr += 7; + return; + } + else if (gDisableStructs[index].encoredMove != 0) + { + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); + return; + } + gAIScriptPtr += 7; +} + +static void BattleAICmd_if_encored(void) +{ + switch (gAIScriptPtr[1]) + { + case 0: // _08109348 + if (gDisableStructs[gActiveBattler].disabledMove == AI_THINKING_STRUCT->moveConsidered) + { + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + return; + } + gAIScriptPtr += 6; + return; + case 1: // _08109370 + if (gDisableStructs[gActiveBattler].encoredMove == AI_THINKING_STRUCT->moveConsidered) + { + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + return; + } + gAIScriptPtr += 6; + return; + default: + gAIScriptPtr += 6; + return; + } +} + +static void BattleAICmd_flee(void) +{ + AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_FLEE | AI_ACTION_DO_NOT_ATTACK); // what matters is AI_ACTION_FLEE being enabled. +} + +static void BattleAICmd_if_random_100(void) +{ + u8 safariFleeRate = gBattleStruct->safariFleeRate * 5; // safari flee rate, from 0-20 + + if ((u8)(Random() % 100) < safariFleeRate) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); + else + gAIScriptPtr += 5; +} + +static void BattleAICmd_watch(void) +{ + AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_WATCH | AI_ACTION_DO_NOT_ATTACK); // what matters is AI_ACTION_WATCH being enabled. +} + +static void BattleAICmd_get_hold_effect(void) +{ + u8 index; + u16 side; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + if (GetBattlerSide(index) == 0) + { + side = (GetBattlerPosition(index) & 1); + AI_THINKING_STRUCT->funcResult = AI_BATTLE_HISTORY->itemEffects[side]; + } + else + AI_THINKING_STRUCT->funcResult = ItemId_GetHoldEffect(gBattleMons[index].item); + + gAIScriptPtr += 2; +} + +static void BattleAICmd_get_gender(void) +{ + u8 index; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + AI_THINKING_STRUCT->funcResult = GetGenderFromSpeciesAndPersonality(gBattleMons[index].species, gBattleMons[index].personality); + + gAIScriptPtr += 2; +} + +static void BattleAICmd_is_first_turn(void) +{ + u8 index; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + AI_THINKING_STRUCT->funcResult = gDisableStructs[index].isFirstTurn; + + gAIScriptPtr += 2; +} + +static void BattleAICmd_get_stockpile_count(void) +{ + u8 index; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + AI_THINKING_STRUCT->funcResult = gDisableStructs[index].stockpileCounter; + + gAIScriptPtr += 2; +} + +static void BattleAICmd_is_double_battle(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleTypeFlags & BATTLE_TYPE_DOUBLE; + + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_used_item(void) +{ + u8 index; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + AI_THINKING_STRUCT->funcResult = AI_ARRAY_160CC(index); + + gAIScriptPtr += 2; +} + +static void BattleAICmd_get_move_type_from_result(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].type; + + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_move_power_from_result(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].power; + + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_move_effect_from_result(void) +{ + AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].effect; + + gAIScriptPtr += 1; +} + +static void BattleAICmd_get_protect_count(void) +{ + u8 index; + + if (gAIScriptPtr[1] == USER) + index = gBankAttacker; + else + index = gBankTarget; + + AI_THINKING_STRUCT->funcResult = gDisableStructs[index].protectUses; + + gAIScriptPtr += 2; +} + +static void BattleAICmd_nullsub_52(void) +{ +} + +static void BattleAICmd_nullsub_53(void) +{ +} + +static void BattleAICmd_nullsub_54(void) +{ +} + +static void BattleAICmd_nullsub_55(void) +{ +} + +static void BattleAICmd_nullsub_56(void) +{ +} + +static void BattleAICmd_nullsub_57(void) +{ +} + +static void BattleAICmd_call(void) +{ + AIStackPushVar(gAIScriptPtr + 5); + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); +} + +static void BattleAICmd_jump(void) +{ + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); +} + +static void BattleAICmd_end(void) +{ + if (AIStackPop() == FALSE) + AI_THINKING_STRUCT->aiAction |= AI_ACTION_DONE; +} + +static void BattleAICmd_if_level_compare(void) +{ + switch (gAIScriptPtr[1]) + { + case 0: // greater than + if (gBattleMons[gBankAttacker].level > gBattleMons[gBankTarget].level) + { + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + return; + } + gAIScriptPtr += 6; + return; + case 1: // less than + if (gBattleMons[gBankAttacker].level < gBattleMons[gBankTarget].level) + { + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + return; + } + gAIScriptPtr += 6; + return; + case 2: // equal + if (gBattleMons[gBankAttacker].level == gBattleMons[gBankTarget].level) + { + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); + return; + } + gAIScriptPtr += 6; + return; + } +} + +static void BattleAICmd_if_taunted(void) +{ + if (gDisableStructs[gBankTarget].tauntTimer1 != 0) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); + else + gAIScriptPtr += 5; +} + +static void BattleAICmd_if_not_taunted(void) +{ + if (gDisableStructs[gBankTarget].tauntTimer1 == 0) + gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); + else + gAIScriptPtr += 5; +} + +void AIStackPushVar(u8 *var) +{ + AI_STACK->ptr[AI_STACK->size++] = var; +} + +// unused +void AIStackPushAIPtr(void) +{ + AI_STACK->ptr[AI_STACK->size++] = gAIScriptPtr; +} + +bool8 AIStackPop(void) +{ + if (AI_STACK->size != 0) + { + --AI_STACK->size; + gAIScriptPtr = AI_STACK->ptr[AI_STACK->size]; + return TRUE; + } + else + return FALSE; +} diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c new file mode 100644 index 000000000..4dd7614bf --- /dev/null +++ b/src/battle_ai_switch_items.c @@ -0,0 +1,1008 @@ +#include "global.h" +#include "battle.h" +#include "battle_ai_switch_items.h" +#include "battle_script_commands.h" +#include "data2.h" +#include "ewram.h" +#include "pokemon.h" +#include "random.h" +#include "rom_8077ABC.h" +#include "rom3.h" +#include "util.h" +#include "constants/abilities.h" +#include "constants/items.h" +#include "constants/moves.h" +#include "constants/species.h" + +extern u8 gUnknown_02023A14_50; + +extern u8 gLastHitBy[]; +extern u8 gActiveBattler; +extern u16 gBattleTypeFlags; +extern u8 gAbsentBattlerFlags; +extern s32 gBattleMoveDamage; +extern u8 gMoveResultFlags; +extern u16 gDynamicBasePower; +extern u8 gCritMultiplier; +extern u16 gBattlerPartyIndexes[]; +extern u16 gLastLandedMoves[]; +extern const u8 gTypeEffectiveness[]; +extern struct BattlePokemon gBattleMons[]; +extern u32 gStatuses3[MAX_BATTLERS_COUNT]; + +static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng); +static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent); +static bool8 ShouldUseItem(void); + + +static bool8 ShouldSwitchIfPerishSong(void) +{ + if (gStatuses3[gActiveBattler] & STATUS3_PERISH_SONG + && gDisableStructs[gActiveBattler].perishSongTimer1 == 0) + { + ewram160C8arr(GetBattlerPosition(gActiveBattler)) = 6; // gBattleStruct->AI_monToSwitchIntoId[GetBattlerPosition(gActiveBattler)] = 6; + Emitcmd33(1, 2, 0); + return TRUE; + } + + return FALSE; +} + +#ifdef NONMATCHING +static bool8 ShouldSwitchIfWonderGuard(void) +{ + u8 opposingBattler; + u8 moveFlags; + s32 i, j; + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + return FALSE; + + if (gBattleMons[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)].ability != ABILITY_WONDER_GUARD) + return FALSE; + + // check if pokemon has a super effective move + opposingBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + for (i = 0; i < 4; i++) + { + u16 move = gBattleMons[gActiveBattler].moves[i]; + if (move == MOVE_NONE) + continue; + + moveFlags = AI_TypeCalc(move, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability); + if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE) + return FALSE; + } + + // find a pokemon in the party that has a super effective move + for (i = 0; i < 6; i++) + { + if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0 + || GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE + || GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG + || i == gBattlerPartyIndexes[gActiveBattler]) + continue; + + GetMonData(&gEnemyParty[i], MON_DATA_SPECIES); // unused return value + GetMonData(&gEnemyParty[i], MON_DATA_ALT_ABILITY); // unused return value + + opposingBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + for (j = 0; j < 4; j++) + { + u16 move = GetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j); + if (move == MOVE_NONE) + continue; + + moveFlags = AI_TypeCalc(move, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability); + if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE && (Random() % 3) < 2) + { + // we found a mon + ewram160C8arr(GetBattlerPosition(gActiveBattler)) = i; // gBattleStruct->AI_monToSwitchIntoId[GetBattlerPosition(gActiveBattler)] = i; + Emitcmd33(1, B_ACTION_SWITCH, 0); + return TRUE; + } + } + } + + return FALSE; // at this point there is not a single pokemon in the party that has a super effective move against a pokemon with wonder guard +} +#else +NAKED +static bool8 ShouldSwitchIfWonderGuard(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r9\n\ + mov r6, r8\n\ + push {r6,r7}\n\ + ldr r0, _0803606C @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _080360A0\n\ + b _080361C8\n\ + .align 2, 0\n\ +_0803606C: .4byte gBattleTypeFlags\n\ +_08036070:\n\ + ldr r0, _08036094 @ =gActiveBattler\n\ + ldrb r0, [r0]\n\ + bl GetBattlerPosition\n\ + ldr r1, _08036098 @ =gSharedMem\n\ + lsls r0, 24\n\ + lsrs r0, 25\n\ + ldr r2, _0803609C @ =0x000160c8\n\ + adds r0, r2\n\ + adds r0, r1\n\ + strb r6, [r0]\n\ + movs r0, 0x1\n\ + movs r1, 0x2\n\ + movs r2, 0\n\ + bl Emitcmd33\n\ + movs r0, 0x1\n\ + b _080361CA\n\ + .align 2, 0\n\ +_08036094: .4byte gActiveBattler\n\ +_08036098: .4byte gSharedMem\n\ +_0803609C: .4byte 0x000160c8\n\ +_080360A0:\n\ + ldr r4, _080361D8 @ =gBattleMons\n\ + movs r0, 0\n\ + bl GetBattlerAtPosition\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + movs r1, 0x58\n\ + muls r0, r1\n\ + adds r0, r4\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x19\n\ + beq _080360BC\n\ + b _080361C8\n\ +_080360BC:\n\ + movs r0, 0\n\ + bl GetBattlerAtPosition\n\ + lsls r0, 24\n\ + lsrs r2, r0, 24\n\ + movs r6, 0\n\ + adds r7, r4, 0\n\ + movs r5, 0x58\n\ + adds r0, r2, 0\n\ + muls r0, r5\n\ + adds r4, r0, r7\n\ + movs r3, 0x20\n\ + adds r3, r4\n\ + mov r8, r3\n\ +_080360D8:\n\ + lsls r1, r6, 1\n\ + ldr r0, _080361DC @ =gActiveBattler\n\ + ldrb r0, [r0]\n\ + muls r0, r5\n\ + adds r1, r0\n\ + adds r0, r7, 0\n\ + adds r0, 0xC\n\ + adds r1, r0\n\ + ldrh r0, [r1]\n\ + cmp r0, 0\n\ + beq _08036104\n\ + ldrh r1, [r4]\n\ + mov r3, r8\n\ + ldrb r2, [r3]\n\ + bl AI_TypeCalc\n\ + lsls r0, 24\n\ + lsrs r1, r0, 24\n\ + movs r0, 0x2\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + bne _080361C8\n\ +_08036104:\n\ + adds r6, 0x1\n\ + cmp r6, 0x3\n\ + ble _080360D8\n\ + movs r6, 0\n\ + ldr r0, _080361E0 @ =gEnemyParty\n\ + mov r9, r0\n\ +_08036110:\n\ + movs r0, 0x64\n\ + adds r5, r6, 0\n\ + muls r5, r0\n\ + mov r2, r9\n\ + adds r4, r5, r2\n\ + adds r0, r4, 0\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _080361C2\n\ + adds r0, r4, 0\n\ + movs r1, 0x41\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _080361C2\n\ + adds r0, r4, 0\n\ + movs r1, 0x41\n\ + bl GetMonData\n\ + movs r1, 0xCE\n\ + lsls r1, 1\n\ + cmp r0, r1\n\ + beq _080361C2\n\ + ldr r1, _080361E4 @ =gBattlerPartyIndexes\n\ + ldr r0, _080361DC @ =gActiveBattler\n\ + ldrb r0, [r0]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + ldrh r0, [r0]\n\ + cmp r6, r0\n\ + beq _080361C2\n\ + adds r0, r4, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + adds r0, r4, 0\n\ + movs r1, 0x2E\n\ + bl GetMonData\n\ + movs r0, 0\n\ + bl GetBattlerAtPosition\n\ + lsls r0, 24\n\ + lsrs r2, r0, 24\n\ + movs r4, 0\n\ + mov r8, r5\n\ + ldr r1, _080361D8 @ =gBattleMons\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + adds r5, r0, r1\n\ + adds r7, r5, 0\n\ + adds r7, 0x20\n\ +_0803617C:\n\ + adds r1, r4, 0\n\ + adds r1, 0xD\n\ + mov r0, r8\n\ + add r0, r9\n\ + bl GetMonData\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r0, 0\n\ + beq _080361BC\n\ + ldrh r1, [r5]\n\ + ldrb r2, [r7]\n\ + bl AI_TypeCalc\n\ + lsls r0, 24\n\ + lsrs r1, r0, 24\n\ + movs r0, 0x2\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + beq _080361BC\n\ + bl Random\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0x3\n\ + bl __umodsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r0, 0x1\n\ + bhi _080361BC\n\ + b _08036070\n\ +_080361BC:\n\ + adds r4, 0x1\n\ + cmp r4, 0x3\n\ + ble _0803617C\n\ +_080361C2:\n\ + adds r6, 0x1\n\ + cmp r6, 0x5\n\ + ble _08036110\n\ +_080361C8:\n\ + movs r0, 0\n\ +_080361CA:\n\ + pop {r3,r4}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + pop {r4-r7}\n\ + pop {r1}\n\ + bx r1\n\ + .align 2, 0\n\ +_080361D8: .4byte gBattleMons\n\ +_080361DC: .4byte gActiveBattler\n\ +_080361E0: .4byte gEnemyParty\n\ +_080361E4: .4byte gBattlerPartyIndexes\n\ + .syntax divided\n"); +} +#endif // NONMATCHING + +static bool8 FindMonThatAbsorbsOpponentsMove(void) +{ + u8 battlerIn1, battlerIn2; + u8 absorbingTypeAbility; + s32 i; + + if (HasSuperEffectiveMoveAgainstOpponents(TRUE) && Random() % 3 != 0) + return FALSE; + if (gLastLandedMoves[gActiveBattler] == 0) + return FALSE; + if (gLastLandedMoves[gActiveBattler] == 0xFFFF) + return FALSE; + if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0) + return FALSE; + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + battlerIn1 = gActiveBattler; + if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))]) + battlerIn2 = gActiveBattler; + else + battlerIn2 = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))); + } + else + { + battlerIn1 = gActiveBattler; + battlerIn2 = gActiveBattler; + } + + if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_FIRE) + absorbingTypeAbility = ABILITY_FLASH_FIRE; + else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_WATER) + absorbingTypeAbility = ABILITY_WATER_ABSORB; + else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].type == TYPE_ELECTRIC) + absorbingTypeAbility = ABILITY_VOLT_ABSORB; + else + return FALSE; + + if (gBattleMons[gActiveBattler].ability == absorbingTypeAbility) + return FALSE; + + for (i = 0; i < 6; i++) + { + u16 species; + u8 monAbility; + + if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0) + continue; + if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE) + continue; + if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG) + continue; + if (i == gBattlerPartyIndexes[battlerIn1]) + continue; + if (i == gBattlerPartyIndexes[battlerIn2]) + continue; + if (i == ewram16068arr(battlerIn1)) + continue; + if (i == ewram16068arr(battlerIn2)) + continue; + + species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES); + if (GetMonData(&gEnemyParty[i], MON_DATA_ALT_ABILITY) != 0) + monAbility = gBaseStats[species].ability2; + else + monAbility = gBaseStats[species].ability1; + + if (absorbingTypeAbility == monAbility && Random() & 1) + { + // we found a mon + ewram160C8arr(GetBattlerPosition(gActiveBattler)) = i; + Emitcmd33(1, B_ACTION_SWITCH, 0); + return TRUE; + } + } + + return FALSE; +} + +static bool8 ShouldSwitchIfNaturalCure(void) +{ + if (!(gBattleMons[gActiveBattler].status1 & STATUS_SLEEP)) + return FALSE; + if (gBattleMons[gActiveBattler].ability != ABILITY_NATURAL_CURE) + return FALSE; + if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 2) + return FALSE; + + if ((gLastLandedMoves[gActiveBattler] == 0 || gLastLandedMoves[gActiveBattler] == 0xFFFF) && Random() & 1) + { + ewram160C8arr(GetBattlerPosition(gActiveBattler)) = 6; + Emitcmd33(1, B_ACTION_SWITCH, 0); + return TRUE; + } + else if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0 && Random() & 1) + { + ewram160C8arr(GetBattlerPosition(gActiveBattler)) = 6; + Emitcmd33(1, B_ACTION_SWITCH, 0); + return TRUE; + } + + if (FindMonWithFlagsAndSuperEffective(MOVE_RESULT_DOESNT_AFFECT_FOE, 1)) + return TRUE; + if (FindMonWithFlagsAndSuperEffective(MOVE_RESULT_NOT_VERY_EFFECTIVE, 1)) + return TRUE; + if (Random() & 1) + { + ewram160C8arr(GetBattlerPosition(gActiveBattler)) = 6; + Emitcmd33(1, B_ACTION_SWITCH, 0); + return TRUE; + } + + return FALSE; +} + +static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng) +{ + u8 opposingBattler; + s32 i; + u8 moveFlags; + u16 move; + + opposingBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + if (!(gAbsentBattlerFlags & gBitTable[opposingBattler])) + { + for (i = 0; i < 4; i++) + { + move = gBattleMons[gActiveBattler].moves[i]; + if (move == MOVE_NONE) + continue; + + moveFlags = AI_TypeCalc(move, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability); + if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE) + { + if (noRng) + return TRUE; + if (Random() % 10 != 0) + return TRUE; + } + } + } + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + return FALSE; + + opposingBattler = GetBattlerAtPosition(BATTLE_PARTNER(B_POSITION_PLAYER_LEFT)); + if (!(gAbsentBattlerFlags & gBitTable[opposingBattler])) + { + for (i = 0; i < 4; i++) + { + move = gBattleMons[gActiveBattler].moves[i]; + if (move == MOVE_NONE) + continue; + + moveFlags = AI_TypeCalc(move, gBattleMons[opposingBattler].species, gBattleMons[opposingBattler].ability); + if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE) + { + if (noRng) + return TRUE; + if (Random() % 10 != 0) + return TRUE; + } + } + } + + return FALSE; +} + +static bool8 AreStatsRaised(void) +{ + u8 buffedStatsValue = 0; + s32 i; + + for (i = 0; i < BATTLE_STATS_NO; i++) + { + if (gBattleMons[gActiveBattler].statStages[i] > 6) + buffedStatsValue += gBattleMons[gActiveBattler].statStages[i] - 6; + } + + return (buffedStatsValue > 3); +} + +static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent) +{ + u8 battlerIn1, battlerIn2; + s32 i, j; + u16 move; + u8 moveFlags; + + if (gLastLandedMoves[gActiveBattler] == 0) + return FALSE; + if (gLastLandedMoves[gActiveBattler] == 0xFFFF) + return FALSE; + if (gLastHitBy[gActiveBattler] == 0xFF) + return FALSE; + if (gBattleMoves[gLastLandedMoves[gActiveBattler]].power == 0) + return FALSE; + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + battlerIn1 = gActiveBattler; + if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))]) + battlerIn2 = gActiveBattler; + else + battlerIn2 = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler))); + } + else + { + battlerIn1 = gActiveBattler; + battlerIn2 = gActiveBattler; + } + + for (i = 0; i < 6; i++) + { + u16 species; + u8 monAbility; + + if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0) + continue; + if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE) + continue; + if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG) + continue; + if (i == gBattlerPartyIndexes[battlerIn1]) + continue; + if (i == gBattlerPartyIndexes[battlerIn2]) + continue; + if (i == ewram16068arr(battlerIn1)) + continue; + if (i == ewram16068arr(battlerIn2)) + continue; + + species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES); + if (GetMonData(&gEnemyParty[i], MON_DATA_ALT_ABILITY) != 0) + monAbility = gBaseStats[species].ability2; + else + monAbility = gBaseStats[species].ability1; + + moveFlags = AI_TypeCalc(gLastLandedMoves[gActiveBattler], species, monAbility); + if (moveFlags & flags) + { + battlerIn1 = gLastHitBy[gActiveBattler]; + + for (j = 0; j < 4; j++) + { + move = GetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j); + if (move == 0) + continue; + + moveFlags = AI_TypeCalc(move, gBattleMons[battlerIn1].species, gBattleMons[battlerIn1].ability); + if (moveFlags & MOVE_RESULT_SUPER_EFFECTIVE && Random() % moduloPercent == 0) + { + ewram160C8arr(GetBattlerPosition(gActiveBattler)) = i; + Emitcmd33(1, B_ACTION_SWITCH, 0); + return TRUE; + } + } + } + } + + return FALSE; +} + +static bool8 ShouldSwitch(void) +{ + u8 battlerIn1, battlerIn2; + s32 i; + s32 availableToSwitch; + + if (gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) + return FALSE; + if (gStatuses3[gActiveBattler] & STATUS3_ROOTED) + return FALSE; + if (AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBattler, ABILITY_SHADOW_TAG, 0, 0)) + return FALSE; + if (AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBattler, ABILITY_ARENA_TRAP, 0, 0)) + return FALSE; // misses the flying or levitate check + if (AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MAGNET_PULL, 0, 0)) + { + if (gBattleMons[gActiveBattler].type1 == TYPE_STEEL) + return FALSE; + if (gBattleMons[gActiveBattler].type2 == TYPE_STEEL) + return FALSE; + } + + availableToSwitch = 0; + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + battlerIn1 = gActiveBattler; + if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ BIT_FLANK)]) + battlerIn2 = gActiveBattler; + else + battlerIn2 = GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ BIT_FLANK); + } + else + { + battlerIn1 = gActiveBattler; + battlerIn2 = gActiveBattler; + } + + for (i = 0; i < 6; i++) + { + if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0) + continue; + if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_NONE) + continue; + if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG) + continue; + if (i == gBattlerPartyIndexes[battlerIn1]) + continue; + if (i == gBattlerPartyIndexes[battlerIn2]) + continue; + if (i == ewram16068arr(battlerIn1)) + continue; + if (i == ewram16068arr(battlerIn2)) + continue; + + availableToSwitch++; + } + + if (availableToSwitch == 0) + return FALSE; + if (ShouldSwitchIfPerishSong()) + return TRUE; + if (ShouldSwitchIfWonderGuard()) + return TRUE; + if (FindMonThatAbsorbsOpponentsMove()) + return TRUE; + if (ShouldSwitchIfNaturalCure()) + return TRUE; + if (HasSuperEffectiveMoveAgainstOpponents(FALSE)) + return FALSE; + if (AreStatsRaised()) + return FALSE; + if (FindMonWithFlagsAndSuperEffective(MOVE_RESULT_DOESNT_AFFECT_FOE, 2) + || FindMonWithFlagsAndSuperEffective(MOVE_RESULT_NOT_VERY_EFFECTIVE, 3)) + return TRUE; + + return FALSE; +} + +void AI_TrySwitchOrUseItem(void) +{ + u8 battlerIn1, battlerIn2; + + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + { + if (ShouldSwitch()) + { + if (ewram160C8arr(GetBattlerPosition(gActiveBattler)) == 6) + { + s32 monToSwitchId = GetMostSuitableMonToSwitchInto(); + if (monToSwitchId == 6) + { + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + battlerIn2 = battlerIn1; + } + else + { + battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + battlerIn2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); + } + + for (monToSwitchId = 0; monToSwitchId < 6; monToSwitchId++) + { + if (GetMonData(&gEnemyParty[monToSwitchId], MON_DATA_HP) == 0) + continue; + if (monToSwitchId == gBattlerPartyIndexes[battlerIn1]) + continue; + if (monToSwitchId == gBattlerPartyIndexes[battlerIn2]) + continue; + if (monToSwitchId == ewram16068arr(battlerIn1)) + continue; + if (monToSwitchId == ewram16068arr(battlerIn2)) + continue; + + break; + } + } + + ewram160C8arr(GetBattlerPosition(gActiveBattler)) = monToSwitchId; + } + + ewram16068arr(gActiveBattler) = ewram160C8arr(GetBattlerPosition(gActiveBattler)); + return; + } + else + { + #if DEBUG + if (!(gUnknown_02023A14_50 & 0x20) && ShouldUseItem()) + return; + #else + if (ShouldUseItem()) + return; + #endif + } + } + + Emitcmd33(1, B_ACTION_USE_MOVE, (gActiveBattler ^ BIT_SIDE) << 8); +} + +static void ModulateByTypeEffectiveness(u8 attackType, u8 defenseType1, u8 defenseType2, u8 *var) +{ + s32 i = 0; + + while (TYPE_EFFECT_ATK_TYPE(i) != TYPE_ENDTABLE) + { + if (TYPE_EFFECT_ATK_TYPE(i) == TYPE_FORESIGHT) + { + i += 3; + continue; + } + else if (TYPE_EFFECT_ATK_TYPE(i) == attackType) + { + // check type1 + if (TYPE_EFFECT_DEF_TYPE(i) == defenseType1) + *var = (*var * TYPE_EFFECT_MULTIPLIER(i)) / 10; + // check type2 + if (TYPE_EFFECT_DEF_TYPE(i) == defenseType2 && defenseType1 != defenseType2) + *var = (*var * TYPE_EFFECT_MULTIPLIER(i)) / 10; + } + i += 3; + } +} + +u8 GetMostSuitableMonToSwitchInto(void) +{ + u8 opposingBattler; + u8 bestDmg; // note : should be changed to s32 + u8 bestMonId; + u8 battlerIn1, battlerIn2; + s32 i, j; + u8 invalidMons; + u16 move; + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + battlerIn1 = gActiveBattler; + if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ BIT_FLANK)]) + battlerIn2 = gActiveBattler; + else + battlerIn2 = GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ BIT_FLANK); + + // UB: It considers the opponent only player's side even though it can battle alongside player; + opposingBattler = Random() & BIT_FLANK; + if (gAbsentBattlerFlags & gBitTable[opposingBattler]) + opposingBattler ^= BIT_FLANK; + } + else + { + opposingBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + battlerIn1 = gActiveBattler; + battlerIn2 = gActiveBattler; + } + + invalidMons = 0; + + while (invalidMons != 0x3F) // all mons are invalid + { + bestDmg = 0; + bestMonId = 6; + // find the mon which type is the most suitable offensively + for (i = 0; i < 6; i++) + { + u16 species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES); + if (species != SPECIES_NONE + && GetMonData(&gEnemyParty[i], MON_DATA_HP) != 0 + && !(gBitTable[i] & invalidMons) + && gBattlerPartyIndexes[battlerIn1] != i + && gBattlerPartyIndexes[battlerIn2] != i + && i != ewram16068arr(battlerIn1) + && i != ewram16068arr(battlerIn2)) + { + u8 type1 = gBaseStats[species].type1; + u8 type2 = gBaseStats[species].type2; + u8 typeDmg = 10; + ModulateByTypeEffectiveness(gBattleMons[opposingBattler].type1, type1, type2, &typeDmg); + ModulateByTypeEffectiveness(gBattleMons[opposingBattler].type2, type1, type2, &typeDmg); + if (bestDmg < typeDmg) + { + bestDmg = typeDmg; + bestMonId = i; + } + } + else + { + invalidMons |= gBitTable[i]; + } + } + + // ok, we know the mon has the right typing but does it have at least one super effective move? + if (bestMonId != 6) + { + for (i = 0; i < 4; i++) + { + move = GetMonData(&gEnemyParty[bestMonId], MON_DATA_MOVE1 + i); + if (move != MOVE_NONE && TypeCalc(move, gActiveBattler, opposingBattler) & MOVE_RESULT_SUPER_EFFECTIVE) + break; + } + + if (i != 4) + return bestMonId; // has both the typing and at least one super effective move + + invalidMons |= gBitTable[bestMonId]; // sorry buddy, we want something better + } + else + { + invalidMons = 0x3F; // no viable mon to switch + } + } + + gDynamicBasePower = 0; + gBattleStruct->dynamicMoveType = 0; + gBattleStruct->dmgMultiplier = 1; + gMoveResultFlags = 0; + gCritMultiplier = 1; + bestDmg = 0; + bestMonId = 6; + + // if we couldn't find the best mon in terms of typing, find the one that deals most damage + for (i = 0; i < 6; i++) + { + if ((u16)(GetMonData(&gEnemyParty[i], MON_DATA_SPECIES)) == SPECIES_NONE) + continue; + if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0) + continue; + if (gBattlerPartyIndexes[battlerIn1] == i) + continue; + if (gBattlerPartyIndexes[battlerIn2] == i) + continue; + if (i == ewram16068arr(battlerIn1)) + continue; + if (i == ewram16068arr(battlerIn2)) + continue; + + for (j = 0; j < 4; j++) + { + move = GetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j); + gBattleMoveDamage = 0; + if (move != MOVE_NONE && gBattleMoves[move].power != 1) + { + AI_CalcDmg(gActiveBattler, opposingBattler); + TypeCalc(move, gActiveBattler, opposingBattler); + } + if (bestDmg < gBattleMoveDamage) + { + bestDmg = gBattleMoveDamage; + bestMonId = i; + } + } + } + + return bestMonId; +} + +// TODO: use PokemonItemEffect struct instead of u8 once it's documented +static u8 GetAI_ItemType(u8 itemId, const u8 *itemEffect) // NOTE: should take u16 as item Id argument +{ + if (itemId == ITEM_FULL_RESTORE) + return AI_ITEM_FULL_RESTORE; + if (itemEffect[4] & 4) + return AI_ITEM_HEAL_HP; + if (itemEffect[3] & 0x3F) + return AI_ITEM_CURE_CONDITION; + if (itemEffect[0] & 0x3F || itemEffect[1] != 0 || itemEffect[2] != 0) + return AI_ITEM_X_STAT; + if (itemEffect[3] & 0x80) + return AI_ITEM_GUARD_SPECS; + + return AI_ITEM_NOT_RECOGNIZABLE; +} + +static bool8 ShouldUseItem(void) +{ + s32 i; + u8 validMons = 0; + bool8 shouldUse = FALSE; + + for (i = 0; i < 6; i++) + { + if (GetMonData(&gEnemyParty[i], MON_DATA_HP) != 0 + && GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) != SPECIES_NONE + && GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) != SPECIES_EGG) + { + validMons++; + } + } + + for (i = 0; i < 4; i++) + { + u16 item; + const u8 *itemEffects; + u8 paramOffset; + u8 battlerSide; + + if (i != 0 && validMons > (AI_BATTLE_HISTORY->numItems - i) + 1) + continue; + item = AI_BATTLE_HISTORY->trainerItems[i]; + if (item == ITEM_NONE) + continue; + if (gItemEffectTable[item - 13] == NULL) + continue; + + if (item == ITEM_ENIGMA_BERRY) + itemEffects = gSaveBlock1.enigmaBerry.itemEffect; + else + itemEffects = gItemEffectTable[item - 13]; + + ewram160D8(gActiveBattler) = GetAI_ItemType(item, itemEffects); + + switch (ewram160D8(gActiveBattler)) + { + case AI_ITEM_FULL_RESTORE: + if (gBattleMons[gActiveBattler].hp >= gBattleMons[gActiveBattler].maxHP / 4) + break; + if (gBattleMons[gActiveBattler].hp == 0) + break; + shouldUse = TRUE; + break; + case AI_ITEM_HEAL_HP: + paramOffset = GetItemEffectParamOffset(item, 4, 4); + if (paramOffset == 0) + break; + if (gBattleMons[gActiveBattler].hp == 0) + break; + if (gBattleMons[gActiveBattler].hp < gBattleMons[gActiveBattler].maxHP / 4 || gBattleMons[gActiveBattler].maxHP - gBattleMons[gActiveBattler].hp > itemEffects[paramOffset]) + shouldUse = TRUE; + break; + case AI_ITEM_CURE_CONDITION: + ewram160DA(gActiveBattler) = 0; + if (itemEffects[3] & 0x20 && gBattleMons[gActiveBattler].status1 & STATUS_SLEEP) + { + ewram160DA(gActiveBattler) |= 0x20; + shouldUse = TRUE; + } + if (itemEffects[3] & 0x10 && (gBattleMons[gActiveBattler].status1 & STATUS_POISON || gBattleMons[gActiveBattler].status1 & STATUS_TOXIC_POISON)) + { + ewram160DA(gActiveBattler) |= 0x10; + shouldUse = TRUE; + } + if (itemEffects[3] & 0x8 && gBattleMons[gActiveBattler].status1 & STATUS_BURN) + { + ewram160DA(gActiveBattler) |= 0x8; + shouldUse = TRUE; + } + if (itemEffects[3] & 0x4 && gBattleMons[gActiveBattler].status1 & STATUS_FREEZE) + { + ewram160DA(gActiveBattler) |= 0x4; + shouldUse = TRUE; + } + if (itemEffects[3] & 0x2 && gBattleMons[gActiveBattler].status1 & STATUS_PARALYSIS) + { + ewram160DA(gActiveBattler) |= 0x2; + shouldUse = TRUE; + } + if (itemEffects[3] & 0x1 && gBattleMons[gActiveBattler].status2 & STATUS2_CONFUSION) + { + ewram160DA(gActiveBattler) |= 0x1; + shouldUse = TRUE; + } + break; + case AI_ITEM_X_STAT: + ewram160DA(gActiveBattler) = 0; + if (gDisableStructs[gActiveBattler].isFirstTurn == 0) + break; + if (itemEffects[0] & 0xF) + ewram160DA(gActiveBattler) |= 0x1; + if (itemEffects[1] & 0xF0) + ewram160DA(gActiveBattler) |= 0x2; + if (itemEffects[1] & 0xF) + ewram160DA(gActiveBattler) |= 0x4; + if (itemEffects[2] & 0xF) + ewram160DA(gActiveBattler) |= 0x8; + if (itemEffects[2] & 0xF0) + ewram160DA(gActiveBattler) |= 0x20; + if (itemEffects[0] & 0x30) + ewram160DA(gActiveBattler) |= 0x80; + shouldUse = TRUE; + break; + case AI_ITEM_GUARD_SPECS: + battlerSide = GetBattlerSide(gActiveBattler); + if (gDisableStructs[gActiveBattler].isFirstTurn != 0 && gSideTimers[battlerSide].mistTimer == 0) + shouldUse = TRUE; + break; + case AI_ITEM_NOT_RECOGNIZABLE: + return FALSE; + } + + if (shouldUse) + { + Emitcmd33(1, B_ACTION_USE_ITEM, 0); + ewram160D4(gActiveBattler) = item; + AI_BATTLE_HISTORY->trainerItems[i] = 0; + return shouldUse; + } + } + + return FALSE; +} diff --git a/src/battle_anim.c b/src/battle_anim.c new file mode 100644 index 000000000..287d80ab1 --- /dev/null +++ b/src/battle_anim.c @@ -0,0 +1,3236 @@ +#include "global.h" +#include "battle_anim.h" +#include "battle.h" +#include "battle_anim_80CA710.h" +#include "battle_interface.h" +#include "contest.h" +#include "decompress.h" +#include "m4a.h" +#include "main.h" +#include "palette.h" +#include "rom_8077ABC.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "ewram.h" +#include "graphics.h" +#include "constants/battle_anim.h" +#include "constants/songs.h" + +const struct OamData gOamData_837DF24 = +{ + .affineMode = 0, + .objMode = 0, + .shape = 0, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837DF2C = +{ + .affineMode = 0, + .objMode = 0, + .shape = 0, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837DF34 = +{ + .affineMode = 0, + .objMode = 0, + .shape = 0, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837DF3C = +{ + .affineMode = 0, + .objMode = 0, + .shape = 0, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837DF44 = +{ + .affineMode = 0, + .objMode = 0, + .shape = 1, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837DF4C = +{ + .affineMode = 0, + .objMode = 0, + .shape = 1, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837DF54 = +{ + .affineMode = 0, + .objMode = 0, + .shape = 1, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837DF5C = +{ + .affineMode = 0, + .objMode = 0, + .shape = 1, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837DF64 = +{ + .affineMode = 0, + .objMode = 0, + .shape = 2, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837DF6C = +{ + .affineMode = 0, + .objMode = 0, + .shape = 2, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837DF74 = +{ + .affineMode = 0, + .objMode = 0, + .shape = 2, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837DF7C = +{ + .affineMode = 0, + .objMode = 0, + .shape = 2, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837DF84 = +{ + .affineMode = 1, + .objMode = 0, + .shape = 0, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837DF8C = +{ + .affineMode = 1, + .objMode = 0, + .shape = 0, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837DF94 = +{ + .affineMode = 1, + .objMode = 0, + .shape = 0, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837DF9C = +{ + .affineMode = 1, + .objMode = 0, + .shape = 0, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837DFA4 = +{ + .affineMode = 1, + .objMode = 0, + .shape = 1, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837DFAC = +{ + .affineMode = 1, + .objMode = 0, + .shape = 1, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837DFB4 = +{ + .affineMode = 1, + .objMode = 0, + .shape = 1, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837DFBC = +{ + .affineMode = 1, + .objMode = 0, + .shape = 1, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837DFC4 = +{ + .affineMode = 1, + .objMode = 0, + .shape = 2, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837DFCC = +{ + .affineMode = 1, + .objMode = 0, + .shape = 2, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837DFD4 = +{ + .affineMode = 1, + .objMode = 0, + .shape = 2, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837DFDC = +{ + .affineMode = 1, + .objMode = 0, + .shape = 2, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837DFE4 = +{ + .affineMode = 3, + .objMode = 0, + .shape = 0, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837DFEC = +{ + .affineMode = 3, + .objMode = 0, + .shape = 0, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837DFF4 = +{ + .affineMode = 3, + .objMode = 0, + .shape = 0, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837DFFC = +{ + .affineMode = 3, + .objMode = 0, + .shape = 0, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837D004 = +{ + .affineMode = 3, + .objMode = 0, + .shape = 1, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837D00C = +{ + .affineMode = 3, + .objMode = 0, + .shape = 1, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837E014 = +{ + .affineMode = 3, + .objMode = 0, + .shape = 1, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837E01C = +{ + .affineMode = 3, + .objMode = 0, + .shape = 1, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837E024 = +{ + .affineMode = 3, + .objMode = 0, + .shape = 2, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837E02C = +{ + .affineMode = 3, + .objMode = 0, + .shape = 2, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837E034 = +{ + .affineMode = 3, + .objMode = 0, + .shape = 2, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837E03C = +{ + .affineMode = 3, + .objMode = 0, + .shape = 2, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837E044 = +{ + .affineMode = 0, + .objMode = 1, + .shape = 0, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837E04C = +{ + .affineMode = 0, + .objMode = 1, + .shape = 0, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837E054 = +{ + .affineMode = 0, + .objMode = 1, + .shape = 0, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837E05C = +{ + .affineMode = 0, + .objMode = 1, + .shape = 0, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837E064 = +{ + .affineMode = 0, + .objMode = 1, + .shape = 1, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837E06C = +{ + .affineMode = 0, + .objMode = 1, + .shape = 1, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837E074 = +{ + .affineMode = 0, + .objMode = 1, + .shape = 1, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837E07C = +{ + .affineMode = 0, + .objMode = 1, + .shape = 1, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837E084 = +{ + .affineMode = 0, + .objMode = 1, + .shape = 2, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837E08C = +{ + .affineMode = 0, + .objMode = 1, + .shape = 2, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837E094 = +{ + .affineMode = 0, + .objMode = 1, + .shape = 2, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837E09C = +{ + .affineMode = 0, + .objMode = 1, + .shape = 2, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837E0A4 = +{ + .affineMode = 1, + .objMode = 1, + .shape = 0, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837E0AC = +{ + .affineMode = 1, + .objMode = 1, + .shape = 0, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837E0B4 = +{ + .affineMode = 1, + .objMode = 1, + .shape = 0, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837E0BC = +{ + .affineMode = 1, + .objMode = 1, + .shape = 0, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837E0C4 = +{ + .affineMode = 1, + .objMode = 1, + .shape = 1, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837E0CC = +{ + .affineMode = 1, + .objMode = 1, + .shape = 1, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837E0D4 = +{ + .affineMode = 1, + .objMode = 1, + .shape = 1, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837E0DC = +{ + .affineMode = 1, + .objMode = 1, + .shape = 1, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837E0E4 = +{ + .affineMode = 1, + .objMode = 1, + .shape = 2, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837E0EC = +{ + .affineMode = 1, + .objMode = 1, + .shape = 2, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837E0F4 = +{ + .affineMode = 1, + .objMode = 1, + .shape = 2, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837E0FC = +{ + .affineMode = 1, + .objMode = 1, + .shape = 2, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837E104 = +{ + .affineMode = 3, + .objMode = 1, + .shape = 0, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837E10C = +{ + .affineMode = 3, + .objMode = 1, + .shape = 0, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837E114 = +{ + .affineMode = 3, + .objMode = 1, + .shape = 0, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837E11C = +{ + .affineMode = 3, + .objMode = 1, + .shape = 0, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837E124 = +{ + .affineMode = 3, + .objMode = 1, + .shape = 1, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837E12C = +{ + .affineMode = 3, + .objMode = 1, + .shape = 1, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837E134 = +{ + .affineMode = 3, + .objMode = 1, + .shape = 1, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837E13C = +{ + .affineMode = 3, + .objMode = 1, + .shape = 1, + .size = 3, + .priority = 2, +}; + +const struct OamData gOamData_837E144 = +{ + .affineMode = 3, + .objMode = 1, + .shape = 2, + .size = 0, + .priority = 2, +}; + +const struct OamData gOamData_837E14C = +{ + .affineMode = 3, + .objMode = 1, + .shape = 2, + .size = 1, + .priority = 2, +}; + +const struct OamData gOamData_837E154 = +{ + .affineMode = 3, + .objMode = 1, + .shape = 2, + .size = 2, + .priority = 2, +}; + +const struct OamData gOamData_837E15C = +{ + .affineMode = 3, + .objMode = 1, + .shape = 2, + .size = 3, + .priority = 2, +}; + +const struct CompressedSpriteSheet gBattleAnimPicTable[] = +{ + { gBattleAnimSpriteSheet_000, 0x200, ANIM_TAG_BONE }, + { gBattleAnimSpriteSheet_001, 0x300, ANIM_TAG_SPARK }, + { gBattleAnimSpriteSheet_002, 0x200, ANIM_TAG_PENCIL }, + { gBattleAnimSpriteSheet_003, 0x100, ANIM_TAG_AIR_WAVE }, + { gBattleAnimSpriteSheet_004, 0x200, ANIM_TAG_UNUSED_ORB }, + { gBattleAnimSpriteSheet_005, 0x400, ANIM_TAG_SWORD }, + { gBattleAnimSpriteSheet_006, 0x180, ANIM_TAG_SEED }, + { gBattleAnimSpriteSheet_007, 0x800, ANIM_TAG_UNUSED_EXPLOSION }, + { gBattleAnimSpriteSheet_008, 0x20, ANIM_TAG_UNUSED_PINK_ORB }, + { gBattleAnimSpriteSheet_009, 0x400, ANIM_TAG_GUST }, + { gBattleAnimSpriteSheet_010, 0x1200, ANIM_TAG_ICE_CUBE }, + { gBattleAnimSpriteSheet_011, 0x180, ANIM_TAG_SPARK_2 }, + { gBattleAnimSpriteSheet_012, 0x80, ANIM_TAG_UNUSED_ORANGE }, + { gBattleAnimSpriteSheet_013, 0x80, ANIM_TAG_YELLOW_BALL }, + { gBattleAnimSpriteSheet_014, 0x280, ANIM_TAG_LOCK_ON }, + { gBattleAnimSpriteSheet_015, 0x80, ANIM_TAG_TIED_BAG }, + { gBattleAnimSpriteSheet_016, 0x100, ANIM_TAG_BLACK_SMOKE }, + { gBattleAnimSpriteSheet_017, 0x20, ANIM_TAG_BLACK_BALL }, + { gBattleAnimSpriteSheet_018, 0x80, ANIM_TAG_CONVERSION }, + { gBattleAnimSpriteSheet_019, 0x400, ANIM_TAG_UNUSED_GLASS }, + { gBattleAnimSpriteSheet_020, 0x200, ANIM_TAG_HORN_HIT }, + { gBattleAnimSpriteSheet_021, 0xA00, ANIM_TAG_UNUSED_HIT }, + { gBattleAnimSpriteSheet_021, 0xA00, ANIM_TAG_UNUSED_HIT_2 }, + { gBattleAnimSpriteSheet_023, 0x380, ANIM_TAG_UNUSED_BLUE_SHARDS }, + { gBattleAnimSpriteSheet_024, 0x300, ANIM_TAG_UNUSED_CLOSING_EYE }, + { gBattleAnimSpriteSheet_025, 0xA00, ANIM_TAG_UNUSED_WAVING_HAND }, + { gBattleAnimSpriteSheet_026, 0xA00, ANIM_TAG_UNUSED_HIT_DUPLICATE }, + { gBattleAnimSpriteSheet_027, 0xA00, ANIM_TAG_LEER }, + { gBattleAnimSpriteSheet_028, 0xA00, ANIM_TAG_UNUSED_BLUE_BURST }, + { gBattleAnimSpriteSheet_029, 0xA00, ANIM_TAG_SMALL_EMBER }, + { gBattleAnimSpriteSheet_030, 0xA00, ANIM_TAG_GRAY_SMOKE }, + { gBattleAnimSpriteSheet_031, 0xE00, ANIM_TAG_BLUE_STAR }, + { gBattleAnimSpriteSheet_032, 0x380, ANIM_TAG_UNUSED_BUBBLE_BURST }, + { gBattleAnimSpriteSheet_033, 0x1000, ANIM_TAG_FIRE }, + { gBattleAnimSpriteSheet_034, 0x800, ANIM_TAG_UNUSED_SPINNING_FIRE }, + { gBattleAnimSpriteSheet_035, 0xA00, ANIM_TAG_FIRE_PLUME }, + { gBattleAnimSpriteSheet_036, 0x800, ANIM_TAG_UNUSED_LIGHTNING }, + { gBattleAnimSpriteSheet_037, 0xA00, ANIM_TAG_LIGHTNING }, + { gBattleAnimSpriteSheet_038, 0xA00, ANIM_TAG_UNUSED_CLAW_SLASH }, + { gBattleAnimSpriteSheet_039, 0xA00, ANIM_TAG_CLAW_SLASH }, + { gBattleAnimSpriteSheet_040, 0xA00, ANIM_TAG_UNUSED_SCRATCH }, + { gBattleAnimSpriteSheet_041, 0xA00, ANIM_TAG_UNUSED_SCRATCH_2 }, + { gBattleAnimSpriteSheet_042, 0xA00, ANIM_TAG_UNUSED_BUBBLE_BURST_2 }, + { gBattleAnimSpriteSheet_043, 0xA00, ANIM_TAG_ICE_CHUNK }, + { gBattleAnimSpriteSheet_044, 0xA00, ANIM_TAG_UNUSED_GLASS_2 }, + { gBattleAnimSpriteSheet_045, 0xA00, ANIM_TAG_UNUSED_PINK_HEART }, + { gBattleAnimSpriteSheet_046, 0x1000, ANIM_TAG_UNUSED_SAP_DRIP }, + { gBattleAnimSpriteSheet_046, 0x1000, ANIM_TAG_UNUSED_SAP_DRIP_2 }, + { gBattleAnimSpriteSheet_048, 0x1000, ANIM_TAG_SPARKLE_1 }, + { gBattleAnimSpriteSheet_048, 0x1000, ANIM_TAG_SPARKLE_2 }, + { gBattleAnimSpriteSheet_050, 0x200, ANIM_TAG_HUMANOID_FOOT }, + { gBattleAnimSpriteSheet_051, 0x200, ANIM_TAG_UNUSED_MONSTER_FOOT }, + { gBattleAnimSpriteSheet_052, 0x200, ANIM_TAG_UNUSED_HUMANOID_HAND }, + { gBattleAnimSpriteSheet_053, 0x800, ANIM_TAG_NOISE_LINE }, + { gBattleAnimSpriteSheet_054, 0x80, ANIM_TAG_UNUSED_YELLOW_UNK }, + { gBattleAnimSpriteSheet_055, 0x200, ANIM_TAG_UNUSED_RED_FIST }, + { gBattleAnimSpriteSheet_056, 0x1000, ANIM_TAG_SLAM_HIT }, + { gBattleAnimSpriteSheet_057, 0x180, ANIM_TAG_UNUSED_RING }, + { gBattleAnimSpriteSheet_058, 0xC00, ANIM_TAG_ROCKS }, + { gBattleAnimSpriteSheet_059, 0x100, ANIM_TAG_UNUSED_Z }, + { gBattleAnimSpriteSheet_060, 0x40, ANIM_TAG_UNUSED_YELLOW_UNK_2 }, + { gBattleAnimSpriteSheet_061, 0x180, ANIM_TAG_UNUSED_AIR_SLASH }, + { gBattleAnimSpriteSheet_062, 0x800, ANIM_TAG_UNUSED_SPINNING_GREEN_ORBS }, + { gBattleAnimSpriteSheet_063, 0x480, ANIM_TAG_LEAF }, + { gBattleAnimSpriteSheet_064, 0x200, ANIM_TAG_FINGER }, + { gBattleAnimSpriteSheet_065, 0x200, ANIM_TAG_POISON_POWDER }, + { gBattleAnimSpriteSheet_066, 0x100, ANIM_TAG_UNUSED_BROWN_TRIANGLE }, + { gBattleAnimSpriteSheet_065, 0x200, ANIM_TAG_SLEEP_POWDER }, + { gBattleAnimSpriteSheet_065, 0x200, ANIM_TAG_STUN_SPORE }, + { gBattleAnimSpriteSheet_065, 0x200, ANIM_TAG_UNUSED_POWDER }, + { gBattleAnimSpriteSheet_070, 0x200, ANIM_TAG_SPARKLE_3 }, + { gBattleAnimSpriteSheet_071, 0xA00, ANIM_TAG_SPARKLE_4 }, + { gBattleAnimSpriteSheet_072, 0x300, ANIM_TAG_MUSIC_NOTES }, + { gBattleAnimSpriteSheet_073, 0x180, ANIM_TAG_DUCK }, + { gBattleAnimSpriteSheet_074, 0xA0, ANIM_TAG_MUD_SAND }, + { gBattleAnimSpriteSheet_075, 0x700, ANIM_TAG_ALERT }, + { gBattleAnimSpriteSheet_076, 0x400, ANIM_TAG_UNUSED_BLUE_FLAMES }, + { gBattleAnimSpriteSheet_077, 0x200, ANIM_TAG_UNUSED_BLUE_FLAMES_2 }, + { gBattleAnimSpriteSheet_078, 0x300, ANIM_TAG_UNUSED_SHOCK }, + { gBattleAnimSpriteSheet_079, 0xC00, ANIM_TAG_SHOCK }, + { gBattleAnimSpriteSheet_080, 0xA00, ANIM_TAG_UNUSED_BELL }, + { gBattleAnimSpriteSheet_081, 0x80, ANIM_TAG_UNUSED_PINK_GLOVE }, + { gBattleAnimSpriteSheet_082, 0x40, ANIM_TAG_UNUSED_BLUE_LINES }, + { gBattleAnimSpriteSheet_083, 0xE00, ANIM_TAG_UNUSED_IMPACT }, + { gBattleAnimSpriteSheet_084, 0xE00, ANIM_TAG_UNUSED_IMPACT_2 }, + { gBattleAnimSpriteSheet_085, 0x280, ANIM_TAG_UNUSED_RETICLE }, + { gBattleAnimSpriteSheet_086, 0x200, ANIM_TAG_BREATH }, + { gBattleAnimSpriteSheet_087, 0x80, ANIM_TAG_ANGER }, + { gBattleAnimSpriteSheet_088, 0xC0, ANIM_TAG_UNUSED_SNOWBALL }, + { gBattleAnimSpriteSheet_089, 0xA00, ANIM_TAG_UNUSED_VINE }, + { gBattleAnimSpriteSheet_090, 0x200, ANIM_TAG_UNUSED_SWORD }, + { gBattleAnimSpriteSheet_091, 0x180, ANIM_TAG_UNUSED_CLAPPING }, + { gBattleAnimSpriteSheet_092, 0x80, ANIM_TAG_UNUSED_RED_TUBE }, + { gBattleAnimSpriteSheet_093, 0x1000, ANIM_TAG_AMNESIA }, + { gBattleAnimSpriteSheet_094, 0xA00, ANIM_TAG_UNUSED_STRING }, + { gBattleAnimSpriteSheet_095, 0x180, ANIM_TAG_UNUSED_PENCIL }, + { gBattleAnimSpriteSheet_096, 0x380, ANIM_TAG_UNUSED_PETAL }, + { gBattleAnimSpriteSheet_097, 0xC00, ANIM_TAG_BENT_SPOON }, + { gBattleAnimSpriteSheet_098, 0x200, ANIM_TAG_UNUSED_WEB }, + { gBattleAnimSpriteSheet_099, 0x200, ANIM_TAG_MILK_BOTTLE }, + { gBattleAnimSpriteSheet_100, 0x200, ANIM_TAG_COIN }, + { gBattleAnimSpriteSheet_101, 0x200, ANIM_TAG_UNUSED_CRACKED_EGG }, + { gBattleAnimSpriteSheet_102, 0x400, ANIM_TAG_UNUSED_HATCHED_EGG }, + { gBattleAnimSpriteSheet_103, 0x80, ANIM_TAG_UNUSED_FRESH_EGG }, + { gBattleAnimSpriteSheet_104, 0x400, ANIM_TAG_UNUSED_FANGS }, + { gBattleAnimSpriteSheet_105, 0xC00, ANIM_TAG_UNUSED_EXPLOSION_2 }, + { gBattleAnimSpriteSheet_106, 0x200, ANIM_TAG_UNUSED_EXPLOSION_3 }, + { gBattleAnimSpriteSheet_107, 0x1000, ANIM_TAG_UNUSED_WATER_DROPLET }, + { gBattleAnimSpriteSheet_108, 0xA00, ANIM_TAG_UNUSED_WATER_DROPLET_2 }, + { gBattleAnimSpriteSheet_109, 0x20, ANIM_TAG_UNUSED_SEED }, + { gBattleAnimSpriteSheet_110, 0xE00, ANIM_TAG_UNUSED_SPROUT }, + { gBattleAnimSpriteSheet_111, 0x80, ANIM_TAG_UNUSED_RED_WAND }, + { gBattleAnimSpriteSheet_112, 0xA00, ANIM_TAG_UNUSED_PURPLE_GREEN_UNK }, + { gBattleAnimSpriteSheet_113, 0x400, ANIM_TAG_UNUSED_WATER_COLUMN }, + { gBattleAnimSpriteSheet_114, 0x200, ANIM_TAG_UNUSED_MUD_UNK }, + { gBattleAnimSpriteSheet_115, 0x700, ANIM_TAG_RAIN_DROPS }, + { gBattleAnimSpriteSheet_116, 0x800, ANIM_TAG_UNUSED_FURY_SWIPES }, + { gBattleAnimSpriteSheet_117, 0xA00, ANIM_TAG_UNUSED_VINE_2 }, + { gBattleAnimSpriteSheet_118, 0x600, ANIM_TAG_UNUSED_TEETH }, + { gBattleAnimSpriteSheet_119, 0x800, ANIM_TAG_UNUSED_BONE }, + { gBattleAnimSpriteSheet_120, 0x200, ANIM_TAG_UNUSED_WHITE_BAG }, + { gBattleAnimSpriteSheet_121, 0x40, ANIM_TAG_UNUSED_UNKNOWN }, + { gBattleAnimSpriteSheet_122, 0x180, ANIM_TAG_UNUSED_PURPLE_CORAL }, + { gBattleAnimSpriteSheet_123, 0x600, ANIM_TAG_UNUSED_PURPLE_DROPLET }, + { gBattleAnimSpriteSheet_124, 0x600, ANIM_TAG_UNUSED_SHOCK_2 }, + { gBattleAnimSpriteSheet_125, 0x200, ANIM_TAG_UNUSED_CLOSING_EYE_2 }, + { gBattleAnimSpriteSheet_126, 0x80, ANIM_TAG_UNUSED_METAL_BALL }, + { gBattleAnimSpriteSheet_127, 0x200, ANIM_TAG_UNUSED_MONSTER_DOLL }, + { gBattleAnimSpriteSheet_128, 0x800, ANIM_TAG_UNUSED_WHIRLWIND }, + { gBattleAnimSpriteSheet_129, 0x80, ANIM_TAG_UNUSED_WHIRLWIND_2 }, + { gBattleAnimSpriteSheet_130, 0xA00, ANIM_TAG_UNUSED_EXPLOSION_4 }, + { gBattleAnimSpriteSheet_131, 0x280, ANIM_TAG_UNUSED_EXPLOSION_5 }, + { gBattleAnimSpriteSheet_132, 0x280, ANIM_TAG_UNUSED_TONGUE }, + { gBattleAnimSpriteSheet_133, 0x100, ANIM_TAG_UNUSED_SMOKE }, + { gBattleAnimSpriteSheet_134, 0x200, ANIM_TAG_UNUSED_SMOKE_2 }, + { gBattleAnimSpriteSheet_135, 0x200, ANIM_TAG_IMPACT }, + { gBattleAnimSpriteSheet_136, 0x20, ANIM_TAG_CIRCLE_IMPACT }, + { gBattleAnimSpriteSheet_137, 0xA00, ANIM_TAG_SCRATCH }, + { gBattleAnimSpriteSheet_138, 0x800, ANIM_TAG_CUT }, + { gBattleAnimSpriteSheet_139, 0x800, ANIM_TAG_SHARP_TEETH }, + { gBattleAnimSpriteSheet_140, 0xC0, ANIM_TAG_RAINBOW_RINGS }, + { gBattleAnimSpriteSheet_141, 0x1C0, ANIM_TAG_ICE_CRYSTALS }, + { gBattleAnimSpriteSheet_142, 0x100, ANIM_TAG_ICE_SPIKES }, + { gBattleAnimSpriteSheet_143, 0x800, ANIM_TAG_HANDS_AND_FEET }, + { gBattleAnimSpriteSheet_144, 0x200, ANIM_TAG_MIST_CLOUD }, + { gBattleAnimSpriteSheet_145, 0x800, ANIM_TAG_CLAMP }, + { gBattleAnimSpriteSheet_146, 0x180, ANIM_TAG_BUBBLE }, + { gBattleAnimSpriteSheet_147, 0x180, ANIM_TAG_ORBS }, + { gBattleAnimSpriteSheet_148, 0x200, ANIM_TAG_WATER_IMPACT }, + { gBattleAnimSpriteSheet_149, 0x200, ANIM_TAG_WATER_ORB }, + { gBattleAnimSpriteSheet_150, 0x180, ANIM_TAG_POISON_BUBBLE }, + { gBattleAnimSpriteSheet_151, 0x400, ANIM_TAG_TOXIC_BUBBLE }, + { gBattleAnimSpriteSheet_152, 0x80, ANIM_TAG_SPIKES }, + { gBattleAnimSpriteSheet_153, 0x100, ANIM_TAG_HORN_HIT_2 }, + { gBattleAnimSpriteSheet_154, 0x100, ANIM_TAG_AIR_WAVE_2 }, + { gBattleAnimSpriteSheet_155, 0x140, ANIM_TAG_SMALL_BUBBLES }, + { gBattleAnimSpriteSheet_156, 0x800, ANIM_TAG_ROUND_SHADOW }, + { gBattleAnimSpriteSheet_157, 0x200, ANIM_TAG_SUNLIGHT }, + { gBattleAnimSpriteSheet_158, 0x100, ANIM_TAG_SPORE }, + { gBattleAnimSpriteSheet_159, 0xA0, ANIM_TAG_FLOWER }, + { gBattleAnimSpriteSheet_160, 0x100, ANIM_TAG_RAZOR_LEAF }, + { gBattleAnimSpriteSheet_161, 0x80, ANIM_TAG_NEEDLE }, + { gBattleAnimSpriteSheet_162, 0x300, ANIM_TAG_WHIRLWIND_LINES }, + { gBattleAnimSpriteSheet_163, 0x100, ANIM_TAG_GOLD_RING }, + { gBattleAnimSpriteSheet_163, 0x100, ANIM_TAG_PURPLE_RING }, + { gBattleAnimSpriteSheet_163, 0x100, ANIM_TAG_BLUE_RING }, + { gBattleAnimSpriteSheet_166, 0x800, ANIM_TAG_GREEN_LIGHT_WALL }, + { gBattleAnimSpriteSheet_166, 0x800, ANIM_TAG_BLUE_LIGHT_WALL }, + { gBattleAnimSpriteSheet_166, 0x800, ANIM_TAG_RED_LIGHT_WALL }, + { gBattleAnimSpriteSheet_166, 0x800, ANIM_TAG_GRAY_LIGHT_WALL }, + { gBattleAnimSpriteSheet_166, 0x800, ANIM_TAG_ORANGE_LIGHT_WALL }, + { gBattleAnimSpriteSheet_171, 0x80, ANIM_TAG_BLACK_BALL_2 }, + { gBattleAnimSpriteSheet_144, 0x200, ANIM_TAG_PURPLE_GAS_CLOUD }, + { gBattleAnimSpriteSheet_173, 0x200, ANIM_TAG_SPARK_H }, + { gBattleAnimSpriteSheet_174, 0x200, ANIM_TAG_YELLOW_STAR }, + { gBattleAnimSpriteSheet_175, 0x80, ANIM_TAG_LARGE_FRESH_EGG }, + { gBattleAnimSpriteSheet_176, 0x200, ANIM_TAG_SHADOW_BALL }, + { gBattleAnimSpriteSheet_177, 0x500, ANIM_TAG_LICK }, + { gBattleAnimSpriteSheet_178, 0x800, ANIM_TAG_UNUSED_VOID_LINES }, + { gBattleAnimSpriteSheet_179, 0x400, ANIM_TAG_STRING }, + { gBattleAnimSpriteSheet_180, 0x20, ANIM_TAG_STRING_DOT }, + { gBattleAnimSpriteSheet_181, 0x800, ANIM_TAG_WEB }, + { gBattleAnimSpriteSheet_182, 0x100, ANIM_TAG_UNUSED_LIGHTBULB }, + { gBattleAnimSpriteSheet_183, 0x800, ANIM_TAG_SLASH }, + { gBattleAnimSpriteSheet_184, 0x400, ANIM_TAG_FOCUS_ENERGY }, + { gBattleAnimSpriteSheet_185, 0xA00, ANIM_TAG_SPHERE_TO_CUBE }, + { gBattleAnimSpriteSheet_186, 0x1000, ANIM_TAG_TENDRILS }, + { gBattleAnimSpriteSheet_187, 0x800, ANIM_TAG_EYE }, + { gBattleAnimSpriteSheet_188, 0x400, ANIM_TAG_WHITE_SHADOW }, + { gBattleAnimSpriteSheet_189, 0x200, ANIM_TAG_TEAL_ALERT }, + { gBattleAnimSpriteSheet_190, 0x800, ANIM_TAG_OPENING_EYE }, + { gBattleAnimSpriteSheet_191, 0x800, ANIM_TAG_ROUND_WHITE_HALO }, + { gBattleAnimSpriteSheet_192, 0x800, ANIM_TAG_FANG_ATTACK }, + { gBattleAnimSpriteSheet_193, 0x200, ANIM_TAG_PURPLE_HAND_OUTLINE }, + { gBattleAnimSpriteSheet_194, 0x800, ANIM_TAG_MOON }, + { gBattleAnimSpriteSheet_195, 0x200, ANIM_TAG_SPARKLE_5 }, + { gBattleAnimSpriteSheet_196, 0x800, ANIM_TAG_SPIRAL }, + { gBattleAnimSpriteSheet_197, 0x200, ANIM_TAG_SNORE_Z }, + { gBattleAnimSpriteSheet_198, 0x800, ANIM_TAG_EXPLOSION }, + { gBattleAnimSpriteSheet_199, 0x400, ANIM_TAG_NAIL }, + { gBattleAnimSpriteSheet_200, 0x200, ANIM_TAG_GHOSTLY_SPIRIT }, + { gBattleAnimSpriteSheet_201, 0xA80, ANIM_TAG_WARM_ROCK }, + { gBattleAnimSpriteSheet_202, 0x600, ANIM_TAG_BREAKING_EGG }, + { gBattleAnimSpriteSheet_203, 0x800, ANIM_TAG_THIN_RING }, + { gBattleAnimSpriteSheet_204, 0x200, ANIM_TAG_UNUSED_PUNCH_IMPACT }, + { gBattleAnimSpriteSheet_205, 0x600, ANIM_TAG_BELL }, + { gBattleAnimSpriteSheet_206, 0x800, ANIM_TAG_MUSIC_NOTES_2 }, + { gBattleAnimSpriteSheet_207, 0x180, ANIM_TAG_SPEED_DUST }, + { gBattleAnimSpriteSheet_208, 0x800, ANIM_TAG_TORN_METAL }, + { gBattleAnimSpriteSheet_209, 0x800, ANIM_TAG_THOUGHT_BUBBLE }, + { gBattleAnimSpriteSheet_210, 0x80, ANIM_TAG_MAGENTA_HEART }, + { gBattleAnimSpriteSheet_211, 0x80, ANIM_TAG_ELECTRIC_ORBS }, + { gBattleAnimSpriteSheet_212, 0x800, ANIM_TAG_CIRCLE_OF_LIGHT }, + { gBattleAnimSpriteSheet_213, 0x800, ANIM_TAG_ELECTRICITY }, + { gBattleAnimSpriteSheet_214, 0x600, ANIM_TAG_FINGER_2 }, + { gBattleAnimSpriteSheet_215, 0x600, ANIM_TAG_MOVEMENT_WAVES }, + { gBattleAnimSpriteSheet_210, 0x80, ANIM_TAG_RED_HEART }, + { gBattleAnimSpriteSheet_217, 0x80, ANIM_TAG_RED_ORB }, + { gBattleAnimSpriteSheet_218, 0x180, ANIM_TAG_EYE_SPARKLE }, + { gBattleAnimSpriteSheet_210, 0x80, ANIM_TAG_PINK_HEART }, + { gBattleAnimSpriteSheet_220, 0x200, ANIM_TAG_ANGEL }, + { gBattleAnimSpriteSheet_221, 0x400, ANIM_TAG_DEVIL }, + { gBattleAnimSpriteSheet_222, 0xA00, ANIM_TAG_SWIPE }, + { gBattleAnimSpriteSheet_223, 0x800, ANIM_TAG_ROOTS }, + { gBattleAnimSpriteSheet_224, 0x200, ANIM_TAG_ITEM_BAG }, + { gBattleAnimSpriteSheet_225, 0x400, ANIM_TAG_JAGGED_MUSIC_NOTE }, + { gBattleAnimSpriteSheet_226, 0x80, ANIM_TAG_POKEBALL }, + { gBattleAnimSpriteSheet_227, 0x800, ANIM_TAG_SPOTLIGHT }, + { gBattleAnimSpriteSheet_228, 0x200, ANIM_TAG_LETTER_Z }, + { gBattleAnimSpriteSheet_229, 0x300, ANIM_TAG_RAPID_SPIN }, + { gBattleAnimSpriteSheet_230, 0x800, ANIM_TAG_TRI_FORCE_TRIANGLE }, + { gBattleAnimSpriteSheet_231, 0x380, ANIM_TAG_WISP_ORB }, + { gBattleAnimSpriteSheet_232, 0x800, ANIM_TAG_WISP_FIRE }, + { gBattleAnimSpriteSheet_233, 0xC0, ANIM_TAG_GOLD_STARS }, + { gBattleAnimSpriteSheet_234, 0x800, ANIM_TAG_ECLIPSING_ORB }, + { gBattleAnimSpriteSheet_235, 0x60, ANIM_TAG_GRAY_ORB }, + { gBattleAnimSpriteSheet_235, 0x60, ANIM_TAG_BLUE_ORB }, + { gBattleAnimSpriteSheet_235, 0x60, ANIM_TAG_RED_ORB_2 }, + { gBattleAnimSpriteSheet_238, 0x80, ANIM_TAG_PINK_PETAL }, + { gBattleAnimSpriteSheet_239, 0x180, ANIM_TAG_PAIN_SPLIT }, + { gBattleAnimSpriteSheet_240, 0x180, ANIM_TAG_CONFETTI }, + { gBattleAnimSpriteSheet_241, 0x200, ANIM_TAG_GREEN_STAR }, + { gBattleAnimSpriteSheet_242, 0x200, ANIM_TAG_PINK_CLOUD }, + { gBattleAnimSpriteSheet_243, 0x20, ANIM_TAG_SWEAT_DROP }, + { gBattleAnimSpriteSheet_244, 0x400, ANIM_TAG_GUARD_RING }, + { gBattleAnimSpriteSheet_245, 0x600, ANIM_TAG_PURPLE_SCRATCH }, + { gBattleAnimSpriteSheet_246, 0x1000, ANIM_TAG_PURPLE_SWIPE }, + { gBattleAnimSpriteSheet_247, 0x400, ANIM_TAG_TAG_HAND }, + { gBattleAnimSpriteSheet_248, 0x20, ANIM_TAG_SMALL_RED_EYE }, + { gBattleAnimSpriteSheet_249, 0x80, ANIM_TAG_HOLLOW_ORB }, + { gBattleAnimSpriteSheet_250, 0x800, ANIM_TAG_X_SIGN }, + { gBattleAnimSpriteSheet_251, 0x80, ANIM_TAG_BLUEGREEN_ORB }, + { gBattleAnimSpriteSheet_252, 0x200, ANIM_TAG_PAW_PRINT }, + { gBattleAnimSpriteSheet_253, 0x400, ANIM_TAG_PURPLE_FLAME }, + { gBattleAnimSpriteSheet_254, 0x200, ANIM_TAG_RED_BALL }, + { gBattleAnimSpriteSheet_255, 0x200, ANIM_TAG_SMELLINGSALT_EFFECT }, + { gBattleAnimSpriteSheet_256, 0x800, ANIM_TAG_METEOR }, + { gBattleAnimSpriteSheet_257, 0x280, ANIM_TAG_FLAT_ROCK }, + { gBattleAnimSpriteSheet_258, 0x200, ANIM_TAG_MAGNIFYING_GLASS }, + { gBattleAnimSpriteSheet_149, 0x200, ANIM_TAG_BROWN_ORB }, + { gBattleAnimSpriteSheet_260, 0x400, ANIM_TAG_METAL_SOUND_WAVES }, + { gBattleAnimSpriteSheet_261, 0x200, ANIM_TAG_FLYING_DIRT }, + { gBattleAnimSpriteSheet_262, 0x200, ANIM_TAG_ICICLE_SPEAR }, + { gBattleAnimSpriteSheet_263, 0x80, ANIM_TAG_HAIL }, + { gBattleAnimSpriteSheet_264, 0x20, ANIM_TAG_GLOWY_RED_ORB }, + { gBattleAnimSpriteSheet_264, 0x20, ANIM_TAG_GLOWY_GREEN_ORB }, + { gBattleAnimSpriteSheet_266, 0x80, ANIM_TAG_GREEN_SPIKE }, + { gBattleAnimSpriteSheet_212, 0x800, ANIM_TAG_WHITE_CIRCLE_OF_LIGHT }, + { gBattleAnimSpriteSheet_264, 0x20, ANIM_TAG_GLOWY_BLUE_ORB }, + { gBattleAnimSpriteSheet_269, 0x80, ANIM_TAG_UNUSED_RED_BRICK }, + { gBattleAnimSpriteSheet_270, 0x400, ANIM_TAG_WHITE_FEATHER }, + { gBattleAnimSpriteSheet_271, 0x80, ANIM_TAG_SPARKLE_6 }, + { gBattleAnimSpriteSheet_272, 0x800, ANIM_TAG_SPLASH }, + { gBattleAnimSpriteSheet_273, 0x20, ANIM_TAG_SWEAT_BEAD }, + { gBattleAnimSpriteSheet_274, 0x800, ANIM_TAG_UNUSED_GEM_1 }, + { gBattleAnimSpriteSheet_275, 0x800, ANIM_TAG_UNUSED_GEM_2 }, + { gBattleAnimSpriteSheet_276, 0x800, ANIM_TAG_UNUSED_GEM_3 }, + { gBattleAnimSpriteSheet_277, 0x1000, ANIM_TAG_SLAM_HIT_2 }, + { gBattleAnimSpriteSheet_278, 0x800, ANIM_TAG_RECYCLE }, + { gBattleAnimSpriteSheet_279, 0xA0, ANIM_TAG_UNUSED_RED_PARTICLES }, + { gBattleAnimSpriteSheet_280, 0x800, ANIM_TAG_PROTECT }, + { gBattleAnimSpriteSheet_281, 0x200, ANIM_TAG_DIRT_MOUND }, + { gBattleAnimSpriteSheet_282, 0x600, ANIM_TAG_SHOCK_3 }, + { gBattleAnimSpriteSheet_283, 0x200, ANIM_TAG_WEATHER_BALL }, + { gBattleAnimSpriteSheet_284, 0x800, ANIM_TAG_BIRD }, + { gBattleAnimSpriteSheet_285, 0x200, ANIM_TAG_CROSS_IMPACT }, + { gBattleAnimSpriteSheet_183, 0x800, ANIM_TAG_SLASH_2 }, + { gBattleAnimSpriteSheet_056, 0x1000, ANIM_TAG_WHIP_HIT }, + { gBattleAnimSpriteSheet_163, 0x100, ANIM_TAG_BLUE_RING_2 }, +}; + +const struct CompressedSpritePalette gBattleAnimPaletteTable[] = +{ + { gBattleAnimSpritePalette_000, ANIM_TAG_BONE }, + { gBattleAnimSpritePalette_001, ANIM_TAG_SPARK }, + { gBattleAnimSpritePalette_002, ANIM_TAG_PENCIL }, + { gBattleAnimSpritePalette_003, ANIM_TAG_AIR_WAVE }, + { gBattleAnimSpritePalette_004, ANIM_TAG_UNUSED_ORB }, + { gBattleAnimSpritePalette_005, ANIM_TAG_SWORD }, + { gBattleAnimSpritePalette_006, ANIM_TAG_SEED }, + { gBattleAnimSpritePalette_007, ANIM_TAG_UNUSED_EXPLOSION }, + { gBattleAnimSpritePalette_008, ANIM_TAG_UNUSED_PINK_ORB }, + { gBattleAnimSpritePalette_009, ANIM_TAG_GUST }, + { gBattleAnimSpritePalette_010, ANIM_TAG_ICE_CUBE }, + { gBattleAnimSpritePalette_011, ANIM_TAG_SPARK_2 }, + { gBattleAnimSpritePalette_012, ANIM_TAG_UNUSED_ORANGE }, + { gBattleAnimSpritePalette_013, ANIM_TAG_YELLOW_BALL }, + { gBattleAnimSpritePalette_014, ANIM_TAG_LOCK_ON }, + { gBattleAnimSpritePalette_015, ANIM_TAG_TIED_BAG }, + { gBattleAnimSpritePalette_016, ANIM_TAG_BLACK_SMOKE }, + { gBattleAnimSpritePalette_016, ANIM_TAG_BLACK_BALL }, + { gBattleAnimSpritePalette_018, ANIM_TAG_CONVERSION }, + { gBattleAnimSpritePalette_019, ANIM_TAG_UNUSED_GLASS }, + { gBattleAnimSpritePalette_020, ANIM_TAG_HORN_HIT }, + { gBattleAnimSpritePalette_021, ANIM_TAG_UNUSED_HIT }, + { gBattleAnimSpritePalette_022, ANIM_TAG_UNUSED_HIT_2 }, + { gBattleAnimSpritePalette_023, ANIM_TAG_UNUSED_BLUE_SHARDS }, + { gBattleAnimSpritePalette_024, ANIM_TAG_UNUSED_CLOSING_EYE }, + { gBattleAnimSpritePalette_025, ANIM_TAG_UNUSED_WAVING_HAND }, + { gBattleAnimSpritePalette_026, ANIM_TAG_UNUSED_HIT_DUPLICATE }, + { gBattleAnimSpritePalette_027, ANIM_TAG_LEER }, + { gBattleAnimSpritePalette_028, ANIM_TAG_UNUSED_BLUE_BURST }, + { gBattleAnimSpritePalette_029, ANIM_TAG_SMALL_EMBER }, + { gBattleAnimSpritePalette_030, ANIM_TAG_GRAY_SMOKE }, + { gBattleAnimSpritePalette_031, ANIM_TAG_BLUE_STAR }, + { gBattleAnimSpritePalette_032, ANIM_TAG_UNUSED_BUBBLE_BURST }, + { gBattleAnimSpritePalette_033, ANIM_TAG_FIRE }, + { gBattleAnimSpritePalette_033, ANIM_TAG_UNUSED_SPINNING_FIRE }, + { gBattleAnimSpritePalette_033, ANIM_TAG_FIRE_PLUME }, + { gBattleAnimSpritePalette_036, ANIM_TAG_UNUSED_LIGHTNING }, + { gBattleAnimSpritePalette_036, ANIM_TAG_LIGHTNING }, + { gBattleAnimSpritePalette_038, ANIM_TAG_UNUSED_CLAW_SLASH }, + { gBattleAnimSpritePalette_039, ANIM_TAG_CLAW_SLASH }, + { gBattleAnimSpritePalette_038, ANIM_TAG_UNUSED_SCRATCH }, + { gBattleAnimSpritePalette_038, ANIM_TAG_UNUSED_SCRATCH_2 }, + { gBattleAnimSpritePalette_042, ANIM_TAG_UNUSED_BUBBLE_BURST_2 }, + { gBattleAnimSpritePalette_043, ANIM_TAG_ICE_CHUNK }, + { gBattleAnimSpritePalette_044, ANIM_TAG_UNUSED_GLASS_2 }, + { gBattleAnimSpritePalette_045, ANIM_TAG_UNUSED_PINK_HEART }, + { gBattleAnimSpritePalette_046, ANIM_TAG_UNUSED_SAP_DRIP }, + { gBattleAnimSpritePalette_047, ANIM_TAG_UNUSED_SAP_DRIP }, + { gBattleAnimSpritePalette_048, ANIM_TAG_SPARKLE_1 }, + { gBattleAnimSpritePalette_049, ANIM_TAG_SPARKLE_2 }, + { gBattleAnimSpritePalette_050, ANIM_TAG_HUMANOID_FOOT }, + { gBattleAnimSpritePalette_050, ANIM_TAG_UNUSED_MONSTER_FOOT }, + { gBattleAnimSpritePalette_050, ANIM_TAG_UNUSED_HUMANOID_HAND }, + { gBattleAnimSpritePalette_026, ANIM_TAG_NOISE_LINE }, + { gBattleAnimSpritePalette_054, ANIM_TAG_UNUSED_YELLOW_UNK }, + { gBattleAnimSpritePalette_050, ANIM_TAG_UNUSED_RED_FIST }, + { gBattleAnimSpritePalette_056, ANIM_TAG_SLAM_HIT }, + { gBattleAnimSpritePalette_057, ANIM_TAG_UNUSED_RING }, + { gBattleAnimSpritePalette_058, ANIM_TAG_ROCKS }, + { gBattleAnimSpritePalette_059, ANIM_TAG_UNUSED_Z }, + { gBattleAnimSpritePalette_060, ANIM_TAG_UNUSED_YELLOW_UNK_2 }, + { gBattleAnimSpritePalette_061, ANIM_TAG_UNUSED_AIR_SLASH }, + { gBattleAnimSpritePalette_062, ANIM_TAG_UNUSED_SPINNING_GREEN_ORBS }, + { gBattleAnimSpritePalette_063, ANIM_TAG_LEAF }, + { gBattleAnimSpritePalette_064, ANIM_TAG_FINGER }, + { gBattleAnimSpritePalette_065, ANIM_TAG_POISON_POWDER }, + { gBattleAnimSpritePalette_066, ANIM_TAG_UNUSED_BROWN_TRIANGLE }, + { gBattleAnimSpritePalette_067, ANIM_TAG_SLEEP_POWDER }, + { gBattleAnimSpritePalette_068, ANIM_TAG_STUN_SPORE }, + { gBattleAnimSpritePalette_065, ANIM_TAG_UNUSED_POWDER }, + { gBattleAnimSpritePalette_070, ANIM_TAG_SPARKLE_3 }, + { gBattleAnimSpritePalette_070, ANIM_TAG_SPARKLE_4 }, + { gBattleAnimSpritePalette_072, ANIM_TAG_MUSIC_NOTES }, + { gBattleAnimSpritePalette_073, ANIM_TAG_DUCK }, + { gBattleAnimSpritePalette_074, ANIM_TAG_MUD_SAND }, + { gBattleAnimSpritePalette_075, ANIM_TAG_ALERT }, + { gBattleAnimSpritePalette_076, ANIM_TAG_UNUSED_BLUE_FLAMES }, + { gBattleAnimSpritePalette_076, ANIM_TAG_UNUSED_BLUE_FLAMES_2 }, + { gBattleAnimSpritePalette_078, ANIM_TAG_UNUSED_SHOCK }, + { gBattleAnimSpritePalette_078, ANIM_TAG_SHOCK }, + { gBattleAnimSpritePalette_080, ANIM_TAG_UNUSED_BELL }, + { gBattleAnimSpritePalette_081, ANIM_TAG_UNUSED_PINK_GLOVE }, + { gBattleAnimSpritePalette_082, ANIM_TAG_UNUSED_BLUE_LINES }, + { gBattleAnimSpritePalette_083, ANIM_TAG_UNUSED_IMPACT }, + { gBattleAnimSpritePalette_084, ANIM_TAG_UNUSED_IMPACT_2 }, + { gBattleAnimSpritePalette_085, ANIM_TAG_UNUSED_RETICLE }, + { gBattleAnimSpritePalette_086, ANIM_TAG_BREATH }, + { gBattleAnimSpritePalette_087, ANIM_TAG_ANGER }, + { gBattleAnimSpritePalette_088, ANIM_TAG_UNUSED_SNOWBALL }, + { gBattleAnimSpritePalette_089, ANIM_TAG_UNUSED_VINE }, + { gBattleAnimSpritePalette_090, ANIM_TAG_UNUSED_SWORD }, + { gBattleAnimSpritePalette_091, ANIM_TAG_UNUSED_CLAPPING }, + { gBattleAnimSpritePalette_092, ANIM_TAG_UNUSED_RED_TUBE }, + { gBattleAnimSpritePalette_093, ANIM_TAG_AMNESIA }, + { gBattleAnimSpritePalette_094, ANIM_TAG_UNUSED_STRING }, + { gBattleAnimSpritePalette_095, ANIM_TAG_UNUSED_PENCIL }, + { gBattleAnimSpritePalette_096, ANIM_TAG_UNUSED_PETAL }, + { gBattleAnimSpritePalette_097, ANIM_TAG_BENT_SPOON }, + { gBattleAnimSpritePalette_094, ANIM_TAG_UNUSED_WEB }, + { gBattleAnimSpritePalette_099, ANIM_TAG_MILK_BOTTLE }, + { gBattleAnimSpritePalette_100, ANIM_TAG_COIN }, + { gBattleAnimSpritePalette_101, ANIM_TAG_UNUSED_CRACKED_EGG }, + { gBattleAnimSpritePalette_101, ANIM_TAG_UNUSED_HATCHED_EGG }, + { gBattleAnimSpritePalette_103, ANIM_TAG_UNUSED_FRESH_EGG }, + { gBattleAnimSpritePalette_104, ANIM_TAG_UNUSED_FANGS }, + { gBattleAnimSpritePalette_105, ANIM_TAG_UNUSED_EXPLOSION_2 }, + { gBattleAnimSpritePalette_105, ANIM_TAG_UNUSED_EXPLOSION_3 }, + { gBattleAnimSpritePalette_107, ANIM_TAG_UNUSED_WATER_DROPLET }, + { gBattleAnimSpritePalette_107, ANIM_TAG_UNUSED_WATER_DROPLET_2 }, + { gBattleAnimSpritePalette_109, ANIM_TAG_UNUSED_SEED }, + { gBattleAnimSpritePalette_109, ANIM_TAG_UNUSED_SPROUT }, + { gBattleAnimSpritePalette_111, ANIM_TAG_UNUSED_RED_WAND }, + { gBattleAnimSpritePalette_112, ANIM_TAG_UNUSED_PURPLE_GREEN_UNK }, + { gBattleAnimSpritePalette_113, ANIM_TAG_UNUSED_WATER_COLUMN }, + { gBattleAnimSpritePalette_114, ANIM_TAG_UNUSED_MUD_UNK }, + { gBattleAnimSpritePalette_115, ANIM_TAG_RAIN_DROPS }, + { gBattleAnimSpritePalette_116, ANIM_TAG_UNUSED_FURY_SWIPES }, + { gBattleAnimSpritePalette_117, ANIM_TAG_UNUSED_VINE_2 }, + { gBattleAnimSpritePalette_118, ANIM_TAG_UNUSED_TEETH }, + { gBattleAnimSpritePalette_119, ANIM_TAG_UNUSED_BONE }, + { gBattleAnimSpritePalette_120, ANIM_TAG_UNUSED_WHITE_BAG }, + { gBattleAnimSpritePalette_121, ANIM_TAG_UNUSED_UNKNOWN }, + { gBattleAnimSpritePalette_122, ANIM_TAG_UNUSED_PURPLE_CORAL }, + { gBattleAnimSpritePalette_122, ANIM_TAG_UNUSED_PURPLE_DROPLET }, + { gBattleAnimSpritePalette_124, ANIM_TAG_UNUSED_SHOCK_2 }, + { gBattleAnimSpritePalette_125, ANIM_TAG_UNUSED_CLOSING_EYE_2 }, + { gBattleAnimSpritePalette_126, ANIM_TAG_UNUSED_METAL_BALL }, + { gBattleAnimSpritePalette_127, ANIM_TAG_UNUSED_MONSTER_DOLL }, + { gBattleAnimSpritePalette_128, ANIM_TAG_UNUSED_WHIRLWIND }, + { gBattleAnimSpritePalette_128, ANIM_TAG_UNUSED_WHIRLWIND_2 }, + { gBattleAnimSpritePalette_130, ANIM_TAG_UNUSED_EXPLOSION_4 }, + { gBattleAnimSpritePalette_130, ANIM_TAG_UNUSED_EXPLOSION_5 }, + { gBattleAnimSpritePalette_132, ANIM_TAG_UNUSED_TONGUE }, + { gBattleAnimSpritePalette_133, ANIM_TAG_UNUSED_SMOKE }, + { gBattleAnimSpritePalette_133, ANIM_TAG_UNUSED_SMOKE_2 }, + { gBattleAnimSpritePalette_135, ANIM_TAG_IMPACT }, + { gBattleAnimSpritePalette_136, ANIM_TAG_CIRCLE_IMPACT }, + { gBattleAnimSpritePalette_135, ANIM_TAG_SCRATCH }, + { gBattleAnimSpritePalette_135, ANIM_TAG_CUT }, + { gBattleAnimSpritePalette_139, ANIM_TAG_SHARP_TEETH }, + { gBattleAnimSpritePalette_140, ANIM_TAG_RAINBOW_RINGS }, + { gBattleAnimSpritePalette_141, ANIM_TAG_ICE_CRYSTALS }, + { gBattleAnimSpritePalette_141, ANIM_TAG_ICE_SPIKES }, + { gBattleAnimSpritePalette_143, ANIM_TAG_HANDS_AND_FEET }, + { gBattleAnimSpritePalette_144, ANIM_TAG_MIST_CLOUD }, + { gBattleAnimSpritePalette_139, ANIM_TAG_CLAMP }, + { gBattleAnimSpritePalette_115, ANIM_TAG_BUBBLE }, + { gBattleAnimSpritePalette_147, ANIM_TAG_ORBS }, + { gBattleAnimSpritePalette_148, ANIM_TAG_WATER_IMPACT }, + { gBattleAnimSpritePalette_148, ANIM_TAG_WATER_ORB }, + { gBattleAnimSpritePalette_150, ANIM_TAG_POISON_BUBBLE }, + { gBattleAnimSpritePalette_150, ANIM_TAG_TOXIC_BUBBLE }, + { gBattleAnimSpritePalette_152, ANIM_TAG_SPIKES }, + { gBattleAnimSpritePalette_153, ANIM_TAG_HORN_HIT_2 }, + { gBattleAnimSpritePalette_154, ANIM_TAG_AIR_WAVE_2 }, + { gBattleAnimSpritePalette_155, ANIM_TAG_SMALL_BUBBLES }, + { gBattleAnimSpritePalette_156, ANIM_TAG_ROUND_SHADOW }, + { gBattleAnimSpritePalette_157, ANIM_TAG_SUNLIGHT }, + { gBattleAnimSpritePalette_158, ANIM_TAG_SPORE }, + { gBattleAnimSpritePalette_159, ANIM_TAG_FLOWER }, + { gBattleAnimSpritePalette_160, ANIM_TAG_RAZOR_LEAF }, + { gBattleAnimSpritePalette_161, ANIM_TAG_NEEDLE }, + { gBattleAnimSpritePalette_162, ANIM_TAG_WHIRLWIND_LINES }, + { gBattleAnimSpritePalette_163, ANIM_TAG_GOLD_RING }, + { gBattleAnimSpritePalette_164, ANIM_TAG_PURPLE_RING }, + { gBattleAnimSpritePalette_165, ANIM_TAG_BLUE_RING }, + { gBattleAnimSpritePalette_166, ANIM_TAG_GREEN_LIGHT_WALL }, + { gBattleAnimSpritePalette_167, ANIM_TAG_BLUE_LIGHT_WALL }, + { gBattleAnimSpritePalette_168, ANIM_TAG_RED_LIGHT_WALL }, + { gBattleAnimSpritePalette_169, ANIM_TAG_GRAY_LIGHT_WALL }, + { gBattleAnimSpritePalette_170, ANIM_TAG_ORANGE_LIGHT_WALL }, + { gBattleAnimSpritePalette_171, ANIM_TAG_BLACK_BALL_2 }, + { gBattleAnimSpritePalette_172, ANIM_TAG_PURPLE_GAS_CLOUD }, + { gBattleAnimSpritePalette_001, ANIM_TAG_SPARK_H }, + { gBattleAnimSpritePalette_174, ANIM_TAG_YELLOW_STAR }, + { gBattleAnimSpritePalette_175, ANIM_TAG_LARGE_FRESH_EGG }, + { gBattleAnimSpritePalette_176, ANIM_TAG_SHADOW_BALL }, + { gBattleAnimSpritePalette_177, ANIM_TAG_LICK }, + { gBattleAnimSpritePalette_178, ANIM_TAG_UNUSED_VOID_LINES }, + { gBattleAnimSpritePalette_179, ANIM_TAG_STRING }, + { gBattleAnimSpritePalette_179, ANIM_TAG_STRING_DOT }, + { gBattleAnimSpritePalette_179, ANIM_TAG_WEB }, + { gBattleAnimSpritePalette_182, ANIM_TAG_UNUSED_LIGHTBULB }, + { gBattleAnimSpritePalette_183, ANIM_TAG_SLASH }, + { gBattleAnimSpritePalette_184, ANIM_TAG_FOCUS_ENERGY }, + { gBattleAnimSpritePalette_185, ANIM_TAG_SPHERE_TO_CUBE }, + { gBattleAnimSpritePalette_186, ANIM_TAG_TENDRILS }, + { gBattleAnimSpritePalette_187, ANIM_TAG_EYE }, + { gBattleAnimSpritePalette_188, ANIM_TAG_WHITE_SHADOW }, + { gBattleAnimSpritePalette_189, ANIM_TAG_TEAL_ALERT }, + { gBattleAnimSpritePalette_190, ANIM_TAG_OPENING_EYE }, + { gBattleAnimSpritePalette_191, ANIM_TAG_ROUND_WHITE_HALO }, + { gBattleAnimSpritePalette_192, ANIM_TAG_FANG_ATTACK }, + { gBattleAnimSpritePalette_193, ANIM_TAG_PURPLE_HAND_OUTLINE }, + { gBattleAnimSpritePalette_194, ANIM_TAG_MOON }, + { gBattleAnimSpritePalette_195, ANIM_TAG_SPARKLE_5 }, + { gBattleAnimSpritePalette_196, ANIM_TAG_SPIRAL }, + { gBattleAnimSpritePalette_197, ANIM_TAG_SNORE_Z }, + { gBattleAnimSpritePalette_198, ANIM_TAG_EXPLOSION }, + { gBattleAnimSpritePalette_199, ANIM_TAG_NAIL }, + { gBattleAnimSpritePalette_200, ANIM_TAG_GHOSTLY_SPIRIT }, + { gBattleAnimSpritePalette_201, ANIM_TAG_WARM_ROCK }, + { gBattleAnimSpritePalette_202, ANIM_TAG_BREAKING_EGG }, + { gBattleAnimSpritePalette_203, ANIM_TAG_THIN_RING }, + { gBattleAnimSpritePalette_204, ANIM_TAG_UNUSED_PUNCH_IMPACT }, + { gBattleAnimSpritePalette_205, ANIM_TAG_BELL }, + { gBattleAnimSpritePalette_206, ANIM_TAG_MUSIC_NOTES_2 }, + { gBattleAnimSpritePalette_207, ANIM_TAG_SPEED_DUST }, + { gBattleAnimSpritePalette_167, ANIM_TAG_TORN_METAL }, + { gBattleAnimSpritePalette_209, ANIM_TAG_THOUGHT_BUBBLE }, + { gBattleAnimSpritePalette_210, ANIM_TAG_MAGENTA_HEART }, + { gBattleAnimSpritePalette_211, ANIM_TAG_ELECTRIC_ORBS }, + { gBattleAnimSpritePalette_211, ANIM_TAG_CIRCLE_OF_LIGHT }, + { gBattleAnimSpritePalette_211, ANIM_TAG_ELECTRICITY }, + { gBattleAnimSpritePalette_064, ANIM_TAG_FINGER_2 }, + { gBattleAnimSpritePalette_215, ANIM_TAG_MOVEMENT_WAVES }, + { gBattleAnimSpritePalette_216, ANIM_TAG_RED_HEART }, + { gBattleAnimSpritePalette_217, ANIM_TAG_RED_ORB }, + { gBattleAnimSpritePalette_218, ANIM_TAG_EYE_SPARKLE }, + { gBattleAnimSpritePalette_219, ANIM_TAG_PINK_HEART }, + { gBattleAnimSpritePalette_220, ANIM_TAG_ANGEL }, + { gBattleAnimSpritePalette_221, ANIM_TAG_DEVIL }, + { gBattleAnimSpritePalette_222, ANIM_TAG_SWIPE }, + { gBattleAnimSpritePalette_223, ANIM_TAG_ROOTS }, + { gBattleAnimSpritePalette_224, ANIM_TAG_ITEM_BAG }, + { gBattleAnimSpritePalette_225, ANIM_TAG_JAGGED_MUSIC_NOTE }, + { gBattleAnimSpritePalette_226, ANIM_TAG_POKEBALL }, + { gBattleAnimSpritePalette_226, ANIM_TAG_SPOTLIGHT }, + { gBattleAnimSpritePalette_228, ANIM_TAG_LETTER_Z }, + { gBattleAnimSpritePalette_229, ANIM_TAG_RAPID_SPIN }, + { gBattleAnimSpritePalette_230, ANIM_TAG_TRI_FORCE_TRIANGLE }, + { gBattleAnimSpritePalette_231, ANIM_TAG_WISP_ORB }, + { gBattleAnimSpritePalette_231, ANIM_TAG_WISP_FIRE }, + { gBattleAnimSpritePalette_233, ANIM_TAG_GOLD_STARS }, + { gBattleAnimSpritePalette_234, ANIM_TAG_ECLIPSING_ORB }, + { gBattleAnimSpritePalette_235, ANIM_TAG_GRAY_ORB }, + { gBattleAnimSpritePalette_236, ANIM_TAG_BLUE_ORB }, + { gBattleAnimSpritePalette_237, ANIM_TAG_RED_ORB_2 }, + { gBattleAnimSpritePalette_238, ANIM_TAG_PINK_PETAL }, + { gBattleAnimSpritePalette_239, ANIM_TAG_PAIN_SPLIT }, + { gBattleAnimSpritePalette_240, ANIM_TAG_CONFETTI }, + { gBattleAnimSpritePalette_241, ANIM_TAG_GREEN_STAR }, + { gBattleAnimSpritePalette_242, ANIM_TAG_PINK_CLOUD }, + { gBattleAnimSpritePalette_243, ANIM_TAG_SWEAT_DROP }, + { gBattleAnimSpritePalette_244, ANIM_TAG_GUARD_RING }, + { gBattleAnimSpritePalette_245, ANIM_TAG_PURPLE_SCRATCH }, + { gBattleAnimSpritePalette_245, ANIM_TAG_PURPLE_SWIPE }, + { gBattleAnimSpritePalette_064, ANIM_TAG_TAG_HAND }, + { gBattleAnimSpritePalette_248, ANIM_TAG_SMALL_RED_EYE }, + { gBattleAnimSpritePalette_249, ANIM_TAG_HOLLOW_ORB }, + { gBattleAnimSpritePalette_249, ANIM_TAG_X_SIGN }, + { gBattleAnimSpritePalette_251, ANIM_TAG_BLUEGREEN_ORB }, + { gBattleAnimSpritePalette_252, ANIM_TAG_PAW_PRINT }, + { gBattleAnimSpritePalette_253, ANIM_TAG_PURPLE_FLAME }, + { gBattleAnimSpritePalette_254, ANIM_TAG_RED_BALL }, + { gBattleAnimSpritePalette_255, ANIM_TAG_SMELLINGSALT_EFFECT }, + { gBattleAnimSpritePalette_256, ANIM_TAG_METEOR }, + { gBattleAnimSpritePalette_257, ANIM_TAG_FLAT_ROCK }, + { gBattleAnimSpritePalette_258, ANIM_TAG_MAGNIFYING_GLASS }, + { gBattleAnimSpritePalette_259, ANIM_TAG_BROWN_ORB }, + { gBattleAnimSpritePalette_260, ANIM_TAG_METAL_SOUND_WAVES }, + { gBattleAnimSpritePalette_261, ANIM_TAG_FLYING_DIRT }, + { gBattleAnimSpritePalette_262, ANIM_TAG_ICICLE_SPEAR }, + { gBattleAnimSpritePalette_263, ANIM_TAG_HAIL }, + { gBattleAnimSpritePalette_264, ANIM_TAG_GLOWY_RED_ORB }, + { gBattleAnimSpritePalette_265, ANIM_TAG_GLOWY_GREEN_ORB }, + { gBattleAnimSpritePalette_266, ANIM_TAG_GREEN_SPIKE }, + { gBattleAnimSpritePalette_267, ANIM_TAG_WHITE_CIRCLE_OF_LIGHT }, + { gBattleAnimSpritePalette_268, ANIM_TAG_GLOWY_BLUE_ORB }, + { gBattleAnimSpritePalette_269, ANIM_TAG_UNUSED_RED_BRICK }, + { gBattleAnimSpritePalette_270, ANIM_TAG_WHITE_FEATHER }, + { gBattleAnimSpritePalette_271, ANIM_TAG_SPARKLE_6 }, + { gBattleAnimSpritePalette_272, ANIM_TAG_SPLASH }, + { gBattleAnimSpritePalette_272, ANIM_TAG_SWEAT_BEAD }, + { gBattleAnimSpritePalette_274, ANIM_TAG_UNUSED_GEM_1 }, + { gBattleAnimSpritePalette_274, ANIM_TAG_UNUSED_GEM_2 }, + { gBattleAnimSpritePalette_274, ANIM_TAG_UNUSED_GEM_3 }, + { gBattleAnimSpritePalette_277, ANIM_TAG_SLAM_HIT_2 }, + { gBattleAnimSpritePalette_278, ANIM_TAG_RECYCLE }, + { gBattleAnimSpritePalette_279, ANIM_TAG_UNUSED_RED_PARTICLES }, + { gBattleAnimSpritePalette_280, ANIM_TAG_PROTECT }, + { gBattleAnimSpritePalette_281, ANIM_TAG_DIRT_MOUND }, + { gBattleAnimSpritePalette_282, ANIM_TAG_SHOCK_3 }, + { gBattleAnimSpritePalette_283, ANIM_TAG_WEATHER_BALL }, + { gBattleAnimSpritePalette_284, ANIM_TAG_BIRD }, + { gBattleAnimSpritePalette_285, ANIM_TAG_CROSS_IMPACT }, + { gBattleAnimSpritePalette_286, ANIM_TAG_SLASH_2 }, + { gBattleAnimSpritePalette_287, ANIM_TAG_WHIP_HIT }, + { gBattleAnimSpritePalette_288, ANIM_TAG_BLUE_RING_2 }, +}; + +const struct BattleAnimBackground gBattleAnimBackgroundTable[] = +{ + &gBattleAnimBackgroundImage_00, &gBattleAnimBackgroundPalette_00, &gBattleAnimBackgroundTilemap_00, + &gBattleAnimBackgroundImage_00, &gBattleAnimBackgroundPalette_00, &gBattleAnimBackgroundTilemap_00, + &gBattleAnimBackgroundImage_02, &gBattleAnimBackgroundPalette_02, &gBattleAnimBackgroundTilemap_02, + &gBattleAnimBackgroundImage_03, &gBattleAnimBackgroundPalette_03, &gBattleAnimBackgroundTilemap_03, + &gBattleAnimBackgroundImage_04, &gBattleAnimBackgroundPalette_04, &gBattleAnimBackgroundTilemap_04, + &gBattleAnimBackgroundImage_04, &gBattleAnimBackgroundPalette_04, &gBattleAnimBackgroundTilemap_05, + &gBattleAnimBackgroundImage_04, &gBattleAnimBackgroundPalette_04, &gBattleAnimBackgroundTilemap_06, + &gBattleAnimBackgroundImage_07, &gBattleAnimBackgroundPalette_07, &gBattleAnimBackgroundTilemap_07, + &gBattleAnimBackgroundImage_07, &gBattleAnimBackgroundPalette_07, &gBattleAnimBackgroundTilemap_08, + &gBattleAnimBackgroundImage_09, &gBattleAnimBackgroundPalette_09, &gBattleAnimBackgroundTilemap_09, + &gBattleAnimBackgroundImage_09, &gBattleAnimBackgroundPalette_09, &gBattleAnimBackgroundTilemap_10, + &gBattleAnimBackgroundImage_11, &gBattleAnimBackgroundPalette_11, &gBattleAnimBackgroundTilemap_11, + &gBattleAnimBackgroundImage_12, &gBattleAnimBackgroundPalette_12, &gBattleAnimBackgroundTilemap_12, + &gBattleAnimBackgroundImage_12, &gBattleAnimBackgroundPalette_12, &gBattleAnimBackgroundTilemap_13, + &gBattleAnimBackgroundImage_12, &gBattleAnimBackgroundPalette_12, &gBattleAnimBackgroundTilemap_14, + &gBattleAnimBackgroundImage_15, &gBattleAnimBackgroundPalette_15, &gBattleAnimBackgroundTilemap_15, + &gBattleAnimBackgroundImage_16, &gBattleAnimBackgroundPalette_16, &gBattleAnimBackgroundTilemap_16, + &gBattleAnimBackgroundImage_17, &gBattleAnimBackgroundPalette_17, &gBattleAnimBackgroundTilemap_17, + &gBattleAnimBackgroundImage_07, &gBattleAnimBackgroundPalette_18, &gBattleAnimBackgroundTilemap_07, + &gBattleAnimBackgroundImage_07, &gBattleAnimBackgroundPalette_18, &gBattleAnimBackgroundTilemap_08, + &gBattleAnimBackgroundImage_20, &gBattleAnimBackgroundPalette_20, &gBattleAnimBackgroundTilemap_20, + &gBattleAnimBackgroundImage_21, &gBattleAnimBackgroundPalette_21, &gBattleAnimBackgroundTilemap_21, + &gBattleAnimBackgroundImage_09, &gBattleAnimBackgroundPalette_22, &gBattleAnimBackgroundTilemap_09, + &gBattleAnimBackgroundImage_09, &gBattleAnimBackgroundPalette_22, &gBattleAnimBackgroundTilemap_10, + &gBattleAnimBackgroundImage_04, &gBattleAnimBackgroundPalette_24, &gBattleAnimBackgroundTilemap_04, + &gBattleAnimBackgroundImage_04, &gBattleAnimBackgroundPalette_24, &gBattleAnimBackgroundTilemap_05, + &gBattleAnimBackgroundImage_04, &gBattleAnimBackgroundPalette_24, &gBattleAnimBackgroundTilemap_06, +}; + +extern u16 gBattlerPartyIndexes[4]; +extern u8 gBankSpriteIds[]; +extern u8 gBankAttacker; +extern u8 gBankTarget; + +// sBattleAnimScriptPtr is a pointer to the next set of battle script commands. +EWRAM_DATA const u8 *sBattleAnimScriptPtr = NULL; +EWRAM_DATA const u8 *gBattleAnimScriptRetAddr = NULL; +EWRAM_DATA void (*gAnimScriptCallback)(void) = NULL; +EWRAM_DATA s8 gAnimFramesToWait = 0; +EWRAM_DATA u8 gAnimScriptActive = FALSE; +EWRAM_DATA u8 gAnimVisualTaskCount = 0; +EWRAM_DATA u8 gAnimSoundTaskCount = 0; +EWRAM_DATA struct DisableStruct *gAnimDisableStructPtr = NULL; +EWRAM_DATA s32 gAnimMoveDmg = 0; +EWRAM_DATA u16 gAnimMovePower = 0; +EWRAM_DATA u8 gAnimFriendship = 0; +EWRAM_DATA u16 gWeatherMoveAnim = 0; +EWRAM_DATA u8 gMonAnimTaskIdArray[2] = {0}; +EWRAM_DATA u8 gAnimMoveTurn = 0; +EWRAM_DATA u8 sAnimBackgroundFadeState = 0; +EWRAM_DATA u16 sAnimMoveIndex = 0; // set but unused. +EWRAM_DATA u8 gBattleAnimAttacker = 0; +EWRAM_DATA u8 gBattleAnimTarget = 0; +EWRAM_DATA u16 gAnimSpeciesByBanks[4] = {0}; +EWRAM_DATA u8 gUnknown_0202F7D2 = 0; // some global pan variable + +u16 gSoundAnimFramesToWait; +s16 gBattleAnimArgs[ANIM_ARGS_COUNT]; +u16 gAnimSpriteIndexArray[ANIM_SPRITE_INDEX_COUNT]; + +extern struct MusicPlayerInfo gMPlay_BGM; +extern struct MusicPlayerInfo gMPlay_SE1; +extern struct MusicPlayerInfo gMPlay_SE2; + +extern const u16 gSingingMoves[]; +extern const u8 *const gBattleAnims_Moves[]; + +static void RunAnimScriptCommand(void); +static void ScriptCmd_loadspritegfx(void); +static void ScriptCmd_unloadspritegfx(void); +static void ScriptCmd_createsprite(void); +static void ScriptCmd_createvisualtask(void); +static void ScriptCmd_delay(void); +static void ScriptCmd_waitforvisualfinish(void); +static void ScriptCmd_hang1(void); +static void ScriptCmd_hang2(void); +static void ScriptCmd_end(void); +static void ScriptCmd_playse(void); +static void ScriptCmd_monbg(void); +static void sub_8076380(void); +static void task_pA_ma0A_obj_to_bg_pal(u8); +static void ScriptCmd_clearmonbg(void); +static void sub_807672C(u8); +static void ScriptCmd_monbg_22(void); +static void ScriptCmd_clearmonbg_23(void); +static void sub_80769A4(u8); +static void ScriptCmd_setalpha(void); +static void ScriptCmd_setbldcnt(void); +static void ScriptCmd_blendoff(void); +static void ScriptCmd_call(void); +static void ScriptCmd_return(void); +static void ScriptCmd_setarg(void); +static void ScriptCmd_choosetwoturnanim(void); +static void ScriptCmd_jumpifmoveturn(void); +static void ScriptCmd_jump(void); +static void ScriptCmd_fadetobg(void); +static void ScriptCmd_fadetobgfromset(void); +static void Task_FadeToBg(u8); +static void LoadMoveBg(u16); +static void LoadDefaultBg(void); +static void ScriptCmd_restorebg(void); +static void ScriptCmd_waitbgfadeout(void); +static void ScriptCmd_waitbgfadein(void); +static void ScriptCmd_changebg(void); +static void ScriptCmd_playsewithpan(void); +static void ScriptCmd_setpan(void); +static void ScriptCmd_panse_1B(void); +static void Task_PanFromInitialToTarget(u8); +static void ScriptCmd_panse_26(void); +static void ScriptCmd_panse_27(void); +static void ScriptCmd_loopsewithpan(void); +static void Task_LoopAndPlaySE(u8); +static void ScriptCmd_waitplaysewithpan(void); +static void Task_WaitAndPlaySE(u8); +static void ScriptCmd_createsoundtask(void); +static void ScriptCmd_waitsound(void); +static void ScriptCmd_jumpargeq(void); +static void ScriptCmd_jumpifcontest(void); +static void ScriptCmd_monbgprio_28(void); +static void ScriptCmd_monbgprio_29(void); +static void ScriptCmd_monbgprio_2A(void); +static void ScriptCmd_invisible(void); +static void ScriptCmd_visible(void); +static void ScriptCmd_doublebattle_2D(void); +static void ScriptCmd_doublebattle_2E(void); +static void ScriptCmd_stopsound(void); + +static void (*const sScriptCmdTable[])(void) = { + ScriptCmd_loadspritegfx, + ScriptCmd_unloadspritegfx, + ScriptCmd_createsprite, + ScriptCmd_createvisualtask, + ScriptCmd_delay, + ScriptCmd_waitforvisualfinish, + ScriptCmd_hang1, + ScriptCmd_hang2, + ScriptCmd_end, + ScriptCmd_playse, + ScriptCmd_monbg, + ScriptCmd_clearmonbg, + ScriptCmd_setalpha, + ScriptCmd_blendoff, + ScriptCmd_call, + ScriptCmd_return, + ScriptCmd_setarg, + ScriptCmd_choosetwoturnanim, + ScriptCmd_jumpifmoveturn, + ScriptCmd_jump, + ScriptCmd_fadetobg, + ScriptCmd_restorebg, + ScriptCmd_waitbgfadeout, + ScriptCmd_waitbgfadein, + ScriptCmd_changebg, + ScriptCmd_playsewithpan, + ScriptCmd_setpan, + ScriptCmd_panse_1B, + ScriptCmd_loopsewithpan, + ScriptCmd_waitplaysewithpan, + ScriptCmd_setbldcnt, + ScriptCmd_createsoundtask, + ScriptCmd_waitsound, + ScriptCmd_jumpargeq, + ScriptCmd_monbg_22, + ScriptCmd_clearmonbg_23, + ScriptCmd_jumpifcontest, + ScriptCmd_fadetobgfromset, + ScriptCmd_panse_26, + ScriptCmd_panse_27, + ScriptCmd_monbgprio_28, + ScriptCmd_monbgprio_29, + ScriptCmd_monbgprio_2A, + ScriptCmd_invisible, + ScriptCmd_visible, + ScriptCmd_doublebattle_2D, + ScriptCmd_doublebattle_2E, + ScriptCmd_stopsound, +}; + +void ClearBattleAnimationVars(void) +{ + s32 i; + + gAnimFramesToWait = 0; + gAnimScriptActive = FALSE; + gAnimVisualTaskCount = 0; + gAnimSoundTaskCount = 0; + gAnimDisableStructPtr = NULL; + gAnimMoveDmg = 0; + gAnimMovePower = 0; + gAnimFriendship = 0; + + // clear index array. + for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++) + gAnimSpriteIndexArray[i] |= 0xFFFF; + + // clear anim args. + for (i = 0; i < ANIM_ARGS_COUNT; i++) + gBattleAnimArgs[i] = 0; + + gMonAnimTaskIdArray[0] = 0xFF; + gMonAnimTaskIdArray[1] = 0xFF; + gAnimMoveTurn = 0; + sAnimBackgroundFadeState = 0; + sAnimMoveIndex = 0; + gBattleAnimAttacker = 0; + gBattleAnimTarget = 0; + gUnknown_0202F7D2 = 0; +} + +void DoMoveAnim(u16 move) +{ + gBattleAnimAttacker = gBankAttacker; + gBattleAnimTarget = gBankTarget; + LaunchBattleAnimation(gBattleAnims_Moves, move, TRUE); +} + +void LaunchBattleAnimation(const u8 *const moveAnims[], u16 move, u8 isMoveAnim) +{ + s32 i; + + if (!IsContest()) + { + UpdateBattlerSpritePriorities(); + UpdateOamPriorityInAllHealthboxes(0); + for (i = 0; i < 4; i++) + { + if (GetBattlerSide(i) != 0) + gAnimSpeciesByBanks[i] = GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES); + else + gAnimSpeciesByBanks[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES); + } + } + else + { + for (i = 0; i < 4; i++) + gAnimSpeciesByBanks[i] = EWRAM_19348[0]; + } + + if (isMoveAnim == 0) + sAnimMoveIndex = 0; + else + sAnimMoveIndex = move; + + for (i = 0; i < ANIM_ARGS_COUNT; i++) + gBattleAnimArgs[i] = 0; + + gMonAnimTaskIdArray[0] = 0xFF; + gMonAnimTaskIdArray[1] = 0xFF; + sBattleAnimScriptPtr = moveAnims[move]; + gAnimScriptActive = TRUE; + gAnimFramesToWait = 0; + gAnimScriptCallback = RunAnimScriptCommand; + + for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++) + gAnimSpriteIndexArray[i] |= 0xFFFF; + + if (isMoveAnim) + { + for (i = 0; gSingingMoves[i] != 0xFFFF; i++) + { + if (move == gSingingMoves[i]) + { + // Lower the volume for the short song that gets played. + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 128); + break; + } + } + } + + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + gBattle_WIN1H = 0; + gBattle_WIN1V = 0; +} + +void DestroyAnimSprite(struct Sprite *sprite) +{ + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); + gAnimVisualTaskCount--; +} + +void DestroyAnimVisualTask(u8 taskId) +{ + DestroyTask(taskId); + gAnimVisualTaskCount--; +} + +void DestroyAnimSoundTask(u8 taskId) +{ + DestroyTask(taskId); + gAnimSoundTaskCount--; +} + +static void AddSpriteIndex(u16 index) +{ + s32 i; + + for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++) + { + if (gAnimSpriteIndexArray[i] == 0xFFFF) + { + gAnimSpriteIndexArray[i] = index; + return; + } + } +} + +static void ClearSpriteIndex(u16 index) +{ + s32 i; + + for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++) + { + if (gAnimSpriteIndexArray[i] == index) + { + gAnimSpriteIndexArray[i] |= 0xFFFF; + return; + } + } +} + +static void WaitAnimFrameCount(void) +{ + if (gAnimFramesToWait <= 0) + { + gAnimScriptCallback = RunAnimScriptCommand; + gAnimFramesToWait = 0; + } + else + { + gAnimFramesToWait--; + } +} + +static void RunAnimScriptCommand(void) +{ + do + { + sScriptCmdTable[T1_READ_8(sBattleAnimScriptPtr)](); + } while (gAnimFramesToWait == 0 && gAnimScriptActive); +} + +// Loads sprite graphics used in a move into memory. +// arg 0: gfx ANIM_TAG +static void ScriptCmd_loadspritegfx(void) +{ + u16 tag; + + sBattleAnimScriptPtr++; + tag = T1_READ_16(sBattleAnimScriptPtr); + LoadCompressedObjectPic(&gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(tag)]); + LoadCompressedObjectPalette(&gBattleAnimPaletteTable[GET_TRUE_SPRITE_INDEX(tag)]); + sBattleAnimScriptPtr += 2; + AddSpriteIndex(GET_TRUE_SPRITE_INDEX(tag)); + gAnimFramesToWait = 1; + gAnimScriptCallback = WaitAnimFrameCount; +} + +// Frees sprite graphics from memory when move animation no longer needs them. +// arg0: gfx ANIM_TAG +static void ScriptCmd_unloadspritegfx(void) +{ + u16 tag; + + sBattleAnimScriptPtr++; + tag = T1_READ_16(sBattleAnimScriptPtr); + FreeSpriteTilesByTag(gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(tag)].tag); + FreeSpritePaletteByTag(gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(tag)].tag); + sBattleAnimScriptPtr += 2; + ClearSpriteIndex(GET_TRUE_SPRITE_INDEX(tag)); +} + +// Creates a sprite from the given sprite template. +// arg0: SpriteTemplate +// arg1: s16[] gBattleAnimArgs +static void ScriptCmd_createsprite(void) +{ + s32 i; + const struct SpriteTemplate *template; + u8 argVar; + u8 argsCount; + s16 subpriority; + + sBattleAnimScriptPtr++; + template = (const struct SpriteTemplate *)(T2_READ_32(sBattleAnimScriptPtr)); + sBattleAnimScriptPtr += 4; + + argVar = T1_READ_8(sBattleAnimScriptPtr); + sBattleAnimScriptPtr++; + + argsCount = T1_READ_8(sBattleAnimScriptPtr); + sBattleAnimScriptPtr++; + for (i = 0; i < argsCount; i++) + { + gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr); + sBattleAnimScriptPtr += 2; + } + + if (argVar & 0x80) + { + argVar ^= 0x80; + if (argVar >= 0x40) + argVar -= 0x40; + else + argVar *= -1; + + subpriority = GetBattlerSubpriority(gBattleAnimTarget) + (s8)(argVar); + } + else + { + if (argVar >= 0x40) + argVar -= 0x40; + else + argVar *= -1; + + subpriority = GetBattlerSubpriority(gBattleAnimAttacker) + (s8)(argVar); + } + + if (subpriority < 3) + subpriority = 3; + + CreateSpriteAndAnimate(template, GetBattlerSpriteCoord(gBattleAnimTarget, 2), GetBattlerSpriteCoord(gBattleAnimTarget, 3), subpriority); + gAnimVisualTaskCount++; +} + +// Initializes an animation task. +// arg0: AnimTask function +// arg1: s16[] arguments +static void ScriptCmd_createvisualtask(void) +{ + TaskFunc taskFunc; + u8 taskPriority; + u8 taskId; + u8 numArgs; + s32 i; + + sBattleAnimScriptPtr++; + + taskFunc = (TaskFunc)T2_READ_32(sBattleAnimScriptPtr); + sBattleAnimScriptPtr += 4; + + taskPriority = T1_READ_8(sBattleAnimScriptPtr); + sBattleAnimScriptPtr++; + + numArgs = T1_READ_8(sBattleAnimScriptPtr); + sBattleAnimScriptPtr++; + + for (i = 0; i < numArgs; i++) + { + gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr); + sBattleAnimScriptPtr += 2; + } + + taskId = CreateTask(taskFunc, taskPriority); + taskFunc(taskId); + gAnimVisualTaskCount++; +} + +// Creates a visual delay. +// arg0: number of frames to wait. +static void ScriptCmd_delay(void) +{ + sBattleAnimScriptPtr++; + gAnimFramesToWait = T1_READ_8(sBattleAnimScriptPtr); + if (gAnimFramesToWait == 0) + gAnimFramesToWait = -1; + sBattleAnimScriptPtr++; + gAnimScriptCallback = WaitAnimFrameCount; +} + +// Wait for visual tasks to finish. +static void ScriptCmd_waitforvisualfinish(void) +{ + if (gAnimVisualTaskCount == 0) + { + sBattleAnimScriptPtr++; + gAnimFramesToWait = 0; + } + else + { + gAnimFramesToWait = 1; + } +} + +static void ScriptCmd_hang1(void) +{ +} + +static void ScriptCmd_hang2(void) +{ +} + +// Marks the end of an animation. Finishes the anims, tasks, and sound effects. +// started during an animaiton. +static void ScriptCmd_end(void) +{ + s32 i; + bool32 continuousAnim = FALSE; + + // keep waiting as long as there is animations to be done. + if (gAnimVisualTaskCount != 0 || gAnimSoundTaskCount != 0 + || gMonAnimTaskIdArray[0] != 0xFF || gMonAnimTaskIdArray[1] != 0xFF) + { + gSoundAnimFramesToWait = 0; + gAnimFramesToWait = 1; + return; + } + + // finish the sound effects. + if (IsSEPlaying()) + { + if (++gSoundAnimFramesToWait <= 90) // wait 90 frames, then halt the sound effect. + { + gAnimFramesToWait = 1; + return; + } + else + { + m4aMPlayStop(&gMPlay_SE1); + m4aMPlayStop(&gMPlay_SE2); + } + } + + // the SE has halted, so set the SE Frame Counter to 0 and continue. + gSoundAnimFramesToWait = 0; + + for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++) + { + if (gAnimSpriteIndexArray[i] != 0xFFFF) + { + FreeSpriteTilesByTag(gBattleAnimPicTable[gAnimSpriteIndexArray[i]].tag); + FreeSpritePaletteByTag(gBattleAnimPicTable[gAnimSpriteIndexArray[i]].tag); + gAnimSpriteIndexArray[i] |= 0xFFFF; // set terminator. + } + } + + if (!continuousAnim) // may have been used for debug? + { + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 256); + if (IsContest() == 0) + { + UpdateBattlerSpritePriorities(); + UpdateOamPriorityInAllHealthboxes(1); + } + gAnimScriptActive = FALSE; + } +} + +// Plays a sound effect. +// arg0: sound effect ID +static void ScriptCmd_playse(void) +{ + sBattleAnimScriptPtr++; + PlaySE(T1_READ_16(sBattleAnimScriptPtr)); + sBattleAnimScriptPtr += 2; +} + +// +// arg0: battler +static void ScriptCmd_monbg(void) +{ + u8 animBank; + u8 bank; + u8 identity; + bool8 toBG_2; + u16 spriteId; + u8 taskId; + + sBattleAnimScriptPtr++; + animBank = T1_READ_8(sBattleAnimScriptPtr); + if (animBank == ANIM_BATTLER_ATTACKER) + animBank = ANIM_BATTLER_ATK_PARTNER; + else if (animBank == ANIM_BATTLER_TARGET) + animBank = ANIM_BATTLER_DEF_PARTNER; + + if (animBank == ANIM_BATTLER_ATTACKER || animBank == ANIM_BATTLER_ATK_PARTNER) + bank = gBattleAnimAttacker; + else + bank = gBattleAnimTarget; + + if (IsAnimBankSpriteVisible(bank)) + { + identity = GetBattlerPosition(bank); + identity += 0xFF; + if (identity <= 1 || IsContest() != 0) + toBG_2 = 0; + else + toBG_2 = 1; + + MoveBattlerSpriteToBG(bank, toBG_2); + spriteId = gBankSpriteIds[bank]; + taskId = CreateTask(task_pA_ma0A_obj_to_bg_pal, 10); + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].data[1] = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x; + gTasks[taskId].data[2] = gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y; + if (toBG_2 == 0) + { + gTasks[taskId].data[3] = gBattle_BG1_X; + gTasks[taskId].data[4] = gBattle_BG1_Y; + } + else + { + gTasks[taskId].data[3] = gBattle_BG2_X; + gTasks[taskId].data[4] = gBattle_BG2_Y; + } + gTasks[taskId].data[5] = toBG_2; + gTasks[taskId].data[6] = bank; + gMonAnimTaskIdArray[0] = taskId; + + } + + bank ^= 2; + if (animBank >= ANIM_BATTLER_ATK_PARTNER && IsAnimBankSpriteVisible(bank)) + { + identity = GetBattlerPosition(bank); + identity += 0xFF; + if (identity <= 1 || IsContest() != 0) + toBG_2 = 0; + else + toBG_2 = 1; + MoveBattlerSpriteToBG(bank, toBG_2); + spriteId = gBankSpriteIds[bank]; + taskId = CreateTask(task_pA_ma0A_obj_to_bg_pal, 10); + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].data[1] = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x; + gTasks[taskId].data[2] = gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y; + if (toBG_2 == 0) + { + gTasks[taskId].data[3] = gBattle_BG1_X; + gTasks[taskId].data[4] = gBattle_BG1_Y; + } + else + { + gTasks[taskId].data[3] = gBattle_BG2_X; + gTasks[taskId].data[4] = gBattle_BG2_Y; + } + + gTasks[taskId].data[5] = toBG_2; + gTasks[taskId].data[6] = bank; + gMonAnimTaskIdArray[1] = taskId; + } + + sBattleAnimScriptPtr++; +} + +bool8 IsAnimBankSpriteVisible(u8 bank) +{ + if (IsContest()) + { + if (bank == gBattleAnimAttacker) + return TRUE; + else + return FALSE; + } + if (!IsBankSpritePresent(bank)) + return FALSE; + if (IsContest()) + return TRUE; // this line wont ever be reached. + if (!(EWRAM_17800[bank].unk0 & 1) || !gSprites[gBankSpriteIds[bank]].invisible) + return TRUE; + + return FALSE; +} + +void MoveBattlerSpriteToBG(u8 bank, u8 toBG_2) +{ + u8 spriteId; + + if (toBG_2 == 0) + { + volatile u8 pointlessZero; + struct UnknownStruct2 s; + u8 r2; + + sub_8078914(&s); + DmaFill32Large(3, 0, s.unk0, 0x2000, 0x1000); + pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? + pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? + DmaFill16Defvars(3, 0xFF, (void *)s.unk4, 0x1000); + + REG_BG1CNT_BITFIELD.priority = 2; + REG_BG1CNT_BITFIELD.screenSize = 1; + REG_BG1CNT_BITFIELD.areaOverflowMode = 0; + + spriteId = gBankSpriteIds[bank]; + gBattle_BG1_X = -(gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x) + 32; + if (IsContest() != 0 && IsSpeciesNotUnown(EWRAM_19348[0]) != 0) + gBattle_BG1_X--; + gBattle_BG1_Y = -(gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y) + 32; + gSprites[gBankSpriteIds[bank]].invisible = TRUE; + + REG_BG1HOFS = gBattle_BG1_X; + REG_BG1VOFS = gBattle_BG1_Y; + + LoadPalette(gPlttBufferUnfaded + 0x100 + bank * 16, s.unk8 * 16, 32); + DmaCopy32Defvars(3, gPlttBufferUnfaded + 0x100 + bank * 16, (u16 *)PLTT + s.unk8 * 16, 32); + + if (IsContest() != 0) + r2 = 0; + else + r2 = GetBattlerPosition(bank); + sub_80E4EF8(0, 0, r2, s.unk8, (u32)s.unk0, (((s32)s.unk4 - VRAM) / 2048), REG_BG1CNT_BITFIELD.charBaseBlock); + if (IsContest() != 0) + sub_8076380(); + } + else + { + volatile u8 pointlessZero; + + DmaFill32Large(3, 0, (void *)(VRAM + 0x6000), 0x2000, 0x1000); + pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? + pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? + DmaFill32Defvars(3, 0, (void *)(VRAM + 0xF000), 0x800); + + REG_BG2CNT_BITFIELD.priority = 2; + REG_BG2CNT_BITFIELD.screenSize = 1; + REG_BG2CNT_BITFIELD.areaOverflowMode = 0; + + spriteId = gBankSpriteIds[bank]; + gBattle_BG2_X = -(gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x) + 32; + gBattle_BG2_Y = -(gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y) + 32; + gSprites[gBankSpriteIds[bank]].invisible = TRUE; + + REG_BG2HOFS = gBattle_BG2_X; + REG_BG2VOFS = gBattle_BG2_Y; + + LoadPalette(gPlttBufferUnfaded + 0x100 + bank * 16, 0x90, 32); + DmaCopy32Defvars(3, gPlttBufferUnfaded + 0x100 + bank * 16, (void *)(PLTT + 0x120), 32); + + sub_80E4EF8(0, 0, GetBattlerPosition(bank), 9, 0x6000, 0x1E, REG_BG2CNT_BITFIELD.charBaseBlock); + } +} + +static void sub_8076380(void) +{ + int i; + int j; + struct UnknownStruct2 s; + u16 *ptr; + + if (IsSpeciesNotUnown(EWRAM_19348[0])) + { + sub_8078914(&s); + ptr = s.unk4; + for (i = 0; i < 8; i++) + { + for (j = 0; j < 4; j++) + { + u16 temp = ptr[j + i * 32]; + + ptr[j + i * 32] = ptr[7 - j + i * 32]; + ptr[7 - j + i * 32] = temp; + } + } + for (i = 0; i < 8; i++) + { + for (j = 0; j < 8; j++) + ptr[j + i * 32] ^= 0x400; + } + } +} + +void sub_80763FC(u16 a, u16 *b, u32 c, u8 d) +{ + u8 i; + u8 j; + u32 r9; + + if (d == 0) + r9 = 32; + else + r9 = 64; + a <<= 12; + for (i = 0; i < r9; i++) + { + for (j = 0; j < 32; j++) + b[j + i * 32] = ((b[j + i * 32] & 0xFFF) | a) + c; + } +} + +void sub_8076464(u8 a) +{ + volatile u8 pointlessZero; + struct UnknownStruct2 s; + + sub_8078914(&s); + if (a == 0 || IsContest() != 0) + { + DmaFill32Large(3, 0, s.unk0, 0x2000, 0x1000); + pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? + pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? + DmaFill32Defvars(3, 0, s.unk4, 0x800); + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + } + else + { + DmaFill32Large(3, 0, (void *)(VRAM + 0x6000), 0x2000, 0x1000); + pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? + pointlessZero = 0; // is there a stubbed out Dma macro here that left the 0 load in? + DmaFill32Defvars(3, 0, (void *)(VRAM + 0xF000), 0x800); + gBattle_BG2_X = 0; + gBattle_BG2_Y = 0; + } +} + +static void task_pA_ma0A_obj_to_bg_pal(u8 taskId) +{ + u8 spriteId, palIndex; + s16 x, y; + struct UnknownStruct2 s; + + spriteId = gTasks[taskId].data[0]; + palIndex = gTasks[taskId].data[6]; + sub_8078914(&s); + x = gTasks[taskId].data[1] - (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x); + y = gTasks[taskId].data[2] - (gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y); + + if (gTasks[taskId].data[5] == 0) + { + gBattle_BG1_X = x + gTasks[taskId].data[3]; + gBattle_BG1_Y = y + gTasks[taskId].data[4]; + DmaCopy32Defvars(3, gPlttBufferFaded + 0x100 + palIndex * 16, gPlttBufferFaded + 0x100 + s.unk8 * 16 - 256, 32); + } + else + { + gBattle_BG2_X = x + gTasks[taskId].data[3]; + gBattle_BG2_Y = y + gTasks[taskId].data[4]; + DmaCopy32Defvars(3, gPlttBufferFaded + 0x100 + palIndex * 16, gPlttBufferFaded + 0x100 - 112, 32); + } +} + +static void ScriptCmd_clearmonbg(void) +{ + u8 animBankId; + u8 bank; + u8 taskId; + + sBattleAnimScriptPtr++; + animBankId = T1_READ_8(sBattleAnimScriptPtr); + + if (animBankId == ANIM_BATTLER_ATTACKER) + animBankId = ANIM_BATTLER_ATK_PARTNER; + else if (animBankId == ANIM_BATTLER_TARGET) + animBankId = ANIM_BATTLER_DEF_PARTNER; + + if (animBankId == ANIM_BATTLER_ATTACKER || animBankId == ANIM_BATTLER_ATK_PARTNER) + bank = gBattleAnimAttacker; + else + bank = gBattleAnimTarget; + + if (gMonAnimTaskIdArray[0] != 0xFF) + gSprites[gBankSpriteIds[bank]].invisible = FALSE; + if (animBankId > 1 && gMonAnimTaskIdArray[1] != 0xFF) + gSprites[gBankSpriteIds[bank ^ 2]].invisible = FALSE; + else + animBankId = 0; + + taskId = CreateTask(sub_807672C, 5); + gTasks[taskId].data[0] = animBankId; + gTasks[taskId].data[2] = bank; + sBattleAnimScriptPtr++; +} + +static void sub_807672C(u8 taskId) +{ + u8 identity; + u8 to_BG2; + + gTasks[taskId].data[1]++; + if (gTasks[taskId].data[1] != 1) + { + identity = GetBattlerPosition(gTasks[taskId].data[2]); + identity += 0xFF; + if (identity <= 1 || IsContest() != 0) + to_BG2 = 0; + else + to_BG2 = 1; + if (gMonAnimTaskIdArray[0] != 0xFF) + { + sub_8076464(to_BG2); + DestroyTask(gMonAnimTaskIdArray[0]); + gMonAnimTaskIdArray[0] = 0xFF; + } + if (gTasks[taskId].data[0] > 1) + { + sub_8076464(to_BG2 ^ 1); + DestroyTask(gMonAnimTaskIdArray[1]); + gMonAnimTaskIdArray[1] = 0xFF; + } + DestroyTask(taskId); + } +} + +static void ScriptCmd_monbg_22(void) +{ + u8 animBankId; + u8 bank; + u8 identity; + u8 r1; + + sBattleAnimScriptPtr++; + animBankId = T1_READ_8(sBattleAnimScriptPtr); + + if (animBankId == ANIM_BATTLER_ATTACKER) + animBankId = ANIM_BATTLER_ATK_PARTNER; + else if (animBankId == ANIM_BATTLER_TARGET) + animBankId = ANIM_BATTLER_DEF_PARTNER; + + if (animBankId == ANIM_BATTLER_ATTACKER || animBankId == ANIM_BATTLER_ATK_PARTNER) + bank = gBattleAnimAttacker; + else + bank = gBattleAnimTarget; + + if (IsAnimBankSpriteVisible(bank)) + { + identity = GetBattlerPosition(bank); + identity += 0xFF; + if (identity <= 1 || IsContest() != 0) + r1 = 0; + else + r1 = 1; + MoveBattlerSpriteToBG(bank, r1); + gSprites[gBankSpriteIds[bank]].invisible = FALSE; + } + + bank ^= 2; + if (animBankId > ANIM_BATTLER_TARGET && IsAnimBankSpriteVisible(bank)) + { + identity = GetBattlerPosition(bank); + identity += 0xFF; + if (identity <= 1 || IsContest() != 0) + r1 = 0; + else + r1 = 1; + MoveBattlerSpriteToBG(bank, r1); + gSprites[gBankSpriteIds[bank]].invisible = FALSE; + } + sBattleAnimScriptPtr++; +} + +static void ScriptCmd_clearmonbg_23(void) +{ + u8 animBankId; + u8 bank; + u8 taskId; + + sBattleAnimScriptPtr++; + animBankId = T1_READ_8(sBattleAnimScriptPtr); + + if (animBankId == ANIM_BATTLER_ATTACKER) + animBankId = ANIM_BATTLER_ATK_PARTNER; + else if (animBankId == ANIM_BATTLER_TARGET) + animBankId = ANIM_BATTLER_DEF_PARTNER; + + if (animBankId == ANIM_BATTLER_ATTACKER || animBankId == ANIM_BATTLER_ATK_PARTNER) + bank = gBattleAnimAttacker; + else + bank = gBattleAnimTarget; + + if (IsAnimBankSpriteVisible(bank)) + gSprites[gBankSpriteIds[bank]].invisible = FALSE; + if (animBankId > 1 && IsAnimBankSpriteVisible(bank ^ 2)) + gSprites[gBankSpriteIds[bank ^ 2]].invisible = FALSE; + else + animBankId = 0; + + taskId = CreateTask(sub_80769A4, 5); + gTasks[taskId].data[0] = animBankId; + gTasks[taskId].data[2] = bank; + + sBattleAnimScriptPtr++; +} + +static void sub_80769A4(u8 taskId) +{ + u8 identity; + u8 bank; + u8 toBG_2; + + gTasks[taskId].data[1]++; + if (gTasks[taskId].data[1] != 1) + { + bank = gTasks[taskId].data[2]; + identity = GetBattlerPosition(bank); + identity += 0xFF; + if (identity <= 1 || IsContest() != 0) + toBG_2 = 0; + else + toBG_2 = 1; + if (IsAnimBankSpriteVisible(bank)) + sub_8076464(toBG_2); + if (gTasks[taskId].data[0] > 1 && IsAnimBankSpriteVisible(bank ^ 2)) + sub_8076464(toBG_2 ^ 1); + DestroyTask(taskId); + } +} + +// Sets transparency of sprite. +// arg0: sprite alpha value +// arg1: background alpha value +static void ScriptCmd_setalpha(void) +{ + u16 spriteAlpha, bgAlpha; + + sBattleAnimScriptPtr++; + spriteAlpha = *(sBattleAnimScriptPtr++); + bgAlpha = *(sBattleAnimScriptPtr++) << 8; + REG_BLDCNT = BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_EFFECT_BLEND; + REG_BLDALPHA = spriteAlpha | bgAlpha; +} + +static void ScriptCmd_setbldcnt(void) +{ + u16 half1, half2; + + sBattleAnimScriptPtr++; + half1 = *(sBattleAnimScriptPtr++); + half2 = *(sBattleAnimScriptPtr++) << 8; + REG_BLDCNT = half1 | half2; +} + +// Turns off alpha blending / semi transparency. +static void ScriptCmd_blendoff(void) +{ + sBattleAnimScriptPtr++; + REG_BLDCNT = 0; + REG_BLDALPHA = 0; +} + +// Calls another animation by resetting sBattleAnimScriptPtr. +// arg0: Function +static void ScriptCmd_call(void) +{ + sBattleAnimScriptPtr++; + gBattleAnimScriptRetAddr = sBattleAnimScriptPtr + 4; + sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr); +} + +// Returns to the function that called this. +static void ScriptCmd_return(void) +{ + sBattleAnimScriptPtr = gBattleAnimScriptRetAddr; +} + +// Sets a value into gBattleAnimArgs[8] +// arg0: index / arg number +// arg1: value to set +static void ScriptCmd_setarg(void) +{ + const u8 *addr = sBattleAnimScriptPtr; + u16 value; + u8 argId; + + sBattleAnimScriptPtr++; + argId = T1_READ_8(sBattleAnimScriptPtr); + sBattleAnimScriptPtr++; + value = T1_READ_16(sBattleAnimScriptPtr); + sBattleAnimScriptPtr = addr + 4; + gBattleAnimArgs[argId] = value; +} + +// Flips between the first and second step of a move with two turns. +// arg0: first turn animation +// arg1: second turn animation +static void ScriptCmd_choosetwoturnanim(void) +{ + sBattleAnimScriptPtr++; + if (gAnimMoveTurn & 1) + sBattleAnimScriptPtr += 4; + sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr); +} + +// Jump to specified step of multi turn moves. +// arg0: move turn +// arg1: turn animation +static void ScriptCmd_jumpifmoveturn(void) +{ + u8 toCheck; + + sBattleAnimScriptPtr++; + toCheck = T1_READ_8(sBattleAnimScriptPtr); + sBattleAnimScriptPtr++; + + if (toCheck == gAnimMoveTurn) + { + sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr); + } + else + { + sBattleAnimScriptPtr += 4; + } +} + +// Jump to another animation. +// arg0: new animation +static void ScriptCmd_jump(void) +{ + sBattleAnimScriptPtr++; + sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr); +} + +bool8 IsContest(void) +{ + if (!gMain.inBattle) + return TRUE; + else + return FALSE; +} + +#define tBackgroundId data[0] +#define tState data[10] + +// Fades the screen and sets new background image. +// arg0: background ID +static void ScriptCmd_fadetobg(void) +{ + u8 backgroundId; + u8 taskId; + + sBattleAnimScriptPtr++; + backgroundId = T1_READ_8(sBattleAnimScriptPtr); + sBattleAnimScriptPtr++; + taskId = CreateTask(Task_FadeToBg, 5); + gTasks[taskId].tBackgroundId = backgroundId; + sAnimBackgroundFadeState = 1; +} + +// Fades to background image based on context of move (contest, battle) +// arg0: opponent background image ID +// arg1: player background image ID +// arg2: contest background image ID +static void ScriptCmd_fadetobgfromset(void) +{ + u8 bg1, bg2, bg3; + u8 taskId; + + sBattleAnimScriptPtr++; + bg1 = sBattleAnimScriptPtr[0]; + bg2 = sBattleAnimScriptPtr[1]; + bg3 = sBattleAnimScriptPtr[2]; + sBattleAnimScriptPtr += 3; + taskId = CreateTask(Task_FadeToBg, 5); + + if (IsContest()) + gTasks[taskId].tBackgroundId = bg3; + else if (GetBattlerSide(gBattleAnimTarget) == 0) + gTasks[taskId].tBackgroundId = bg2; + else + gTasks[taskId].tBackgroundId = bg1; + + sAnimBackgroundFadeState = 1; +} + +static void Task_FadeToBg(u8 taskId) +{ + if (gTasks[taskId].tState == 0) + { + BeginHardwarePaletteFade(0xE8, 0, 0, 16, 0); + gTasks[taskId].tState++; + return; + } + if (gPaletteFade.active) + return; + if (gTasks[taskId].tState == 1) + { + gTasks[taskId].tState++; + sAnimBackgroundFadeState = 2; + } + else if (gTasks[taskId].tState == 2) + { + s16 bgId = (u16)gTasks[taskId].tBackgroundId; + + if (bgId == -1) + LoadDefaultBg(); + else + LoadMoveBg(bgId); + + BeginHardwarePaletteFade(0xE8, 0, 16, 0, 1); + gTasks[taskId].tState++; + return; + } + if (gPaletteFade.active) + return; + if (gTasks[taskId].tState == 3) + { + DestroyTask(taskId); + sAnimBackgroundFadeState = 0; + } +} + +static void LoadMoveBg(u16 bgId) +{ + if (IsContest()) + { + void *tilemap = gBattleAnimBackgroundTable[bgId].tilemap; + + LZDecompressWram(tilemap, IsContest() ? EWRAM_14800 : EWRAM_18000); + sub_80763FC(sub_80789BC(), IsContest() ? EWRAM_14800 : EWRAM_18000, 0x100, 0); + DmaCopy32Defvars(3, IsContest() ? EWRAM_14800 : EWRAM_18000, (void *)(VRAM + 0xD000), 0x800); + LZDecompressVram(gBattleAnimBackgroundTable[bgId].image, (void *)(VRAM + 0x2000)); + LoadCompressedPalette(gBattleAnimBackgroundTable[bgId].palette, sub_80789BC() * 16, 32); + } + else + { + LZDecompressVram(gBattleAnimBackgroundTable[bgId].tilemap, (void *)(VRAM + 0xD000)); + LZDecompressVram(gBattleAnimBackgroundTable[bgId].image, (void *)(VRAM + 0x8000)); + LoadCompressedPalette(gBattleAnimBackgroundTable[bgId].palette, 32, 32); + } +} + +static void LoadDefaultBg(void) +{ + if (IsContest()) + LoadContestBgAfterMoveAnim(); + else + DrawMainBattleBackground(); +} + +// Restores default background image. +static void ScriptCmd_restorebg(void) +{ + u8 taskId; + + sBattleAnimScriptPtr++; + taskId = CreateTask(Task_FadeToBg, 5); + gTasks[taskId].tBackgroundId = 0xFFFF; + sAnimBackgroundFadeState = 1; +} + +#undef tBackgroundId +#undef tState + +// Wait for background image fade out to compete. +static void ScriptCmd_waitbgfadeout(void) +{ + if (sAnimBackgroundFadeState == 2) + { + sBattleAnimScriptPtr++; + gAnimFramesToWait = 0; + } + else + { + gAnimFramesToWait = 1; + } +} + +// Wait for background image fade in to compete. +static void ScriptCmd_waitbgfadein(void) +{ + if (sAnimBackgroundFadeState == 0) + { + sBattleAnimScriptPtr++; + gAnimFramesToWait = 0; + } + else + { + gAnimFramesToWait = 1; + } +} + +// Change background. +// arg0: background image ID +static void ScriptCmd_changebg(void) +{ + sBattleAnimScriptPtr++; + LoadMoveBg(T1_READ_8(sBattleAnimScriptPtr)); + sBattleAnimScriptPtr++; +} + +//Weird control flow +/* +s8 BattleAnimAdjustPanning(s8 a) +{ + if (!IsContest() && (EWRAM_17810[gBattleAnimAttacker].unk0 & 0x10)) + { + a = GetBattlerSide(gBattleAnimAttacker) ? SOUND_PAN_ATTACKER : SOUND_PAN_TARGET; + } + //_08076FDC + else + { + if (IsContest()) + { + if (gBattleAnimAttacker == gBattleAnimTarget && gBattleAnimAttacker == 2 + && a == SOUND_PAN_TARGET) + { + //jump to _0807707A + if (a < SOUND_PAN_ATTACKER_NEG) + a = SOUND_PAN_ATTACKER; + return a; + } + } + //_08077004 + else + { + if (GetBattlerSide(gBattleAnimAttacker) == 0) + { + if (GetBattlerSide(gBattleAnimTarget) == 0) + } + //_08077042 + else + { + + } + //_0807706C + } + } + //_0807706E +} +*/ +NAKED +s8 BattleAnimAdjustPanning(s8 a) +{ + asm(".syntax unified\n\ + push {r4,lr}\n\ + lsls r0, 24\n\ + lsrs r4, r0, 24\n\ + bl IsContest\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _08076FDC\n\ + ldr r0, _08076FD4 @ =gBattleAnimAttacker\n\ + ldrb r2, [r0]\n\ + lsls r0, r2, 1\n\ + adds r0, r2\n\ + lsls r0, 2\n\ + ldr r1, _08076FD8 @ =gSharedMem + 0x17810\n\ + adds r0, r1\n\ + ldrb r1, [r0]\n\ + movs r0, 0x10\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08076FDC\n\ + adds r0, r2, 0\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + movs r4, 0xC0\n\ + cmp r0, 0\n\ + beq _0807706E\n\ + movs r4, 0x3F\n\ + b _0807706E\n\ + .align 2, 0\n\ +_08076FD4: .4byte gBattleAnimAttacker\n\ +_08076FD8: .4byte gSharedMem + 0x17810\n\ +_08076FDC:\n\ + bl IsContest\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08077004\n\ + ldr r0, _08076FFC @ =gBattleAnimAttacker\n\ + ldr r1, _08077000 @ =gBattleAnimTarget\n\ + ldrb r0, [r0]\n\ + ldrb r1, [r1]\n\ + cmp r0, r1\n\ + bne _08077068\n\ + cmp r0, 0x2\n\ + bne _08077068\n\ + cmp r4, 0x3F\n\ + beq _0807707A\n\ + b _08077068\n\ + .align 2, 0\n\ +_08076FFC: .4byte gBattleAnimAttacker\n\ +_08077000: .4byte gBattleAnimTarget\n\ +_08077004:\n\ + ldr r0, _0807702C @ =gBattleAnimAttacker\n\ + ldrb r0, [r0]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _08077042\n\ + ldr r0, _08077030 @ =gBattleAnimTarget\n\ + ldrb r0, [r0]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _0807706E\n\ + lsls r0, r4, 24\n\ + asrs r1, r0, 24\n\ + cmp r1, 0x3F\n\ + bne _08077034\n\ + movs r4, 0xC0\n\ + b _0807706E\n\ + .align 2, 0\n\ +_0807702C: .4byte gBattleAnimAttacker\n\ +_08077030: .4byte gBattleAnimTarget\n\ +_08077034:\n\ + movs r0, 0x40\n\ + negs r0, r0\n\ + cmp r1, r0\n\ + beq _0807706E\n\ + negs r0, r1\n\ + lsls r0, 24\n\ + b _0807706C\n\ +_08077042:\n\ + ldr r0, _08077064 @ =gBattleAnimTarget\n\ + ldrb r0, [r0]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x1\n\ + bne _08077068\n\ + lsls r0, r4, 24\n\ + asrs r0, 24\n\ + movs r1, 0x40\n\ + negs r1, r1\n\ + cmp r0, r1\n\ + bne _0807706E\n\ + movs r4, 0x3F\n\ + b _0807706E\n\ + .align 2, 0\n\ +_08077064: .4byte gBattleAnimTarget\n\ +_08077068:\n\ + lsls r0, r4, 24\n\ + negs r0, r0\n\ +_0807706C:\n\ + lsrs r4, r0, 24\n\ +_0807706E:\n\ + lsls r0, r4, 24\n\ + asrs r0, 24\n\ + cmp r0, 0x3F\n\ + ble _0807707A\n\ + movs r4, 0x3F\n\ + b _08077088\n\ +_0807707A:\n\ + lsls r0, r4, 24\n\ + asrs r0, 24\n\ + movs r1, 0x40\n\ + negs r1, r1\n\ + cmp r0, r1\n\ + bge _08077088\n\ + movs r4, 0xC0\n\ +_08077088:\n\ + lsls r0, r4, 24\n\ + asrs r0, 24\n\ + pop {r4}\n\ + pop {r1}\n\ + bx r1\n\ + .syntax divided\n"); +} + +s8 BattleAnimAdjustPanning2(s8 pan) +{ + if (!IsContest() && (EWRAM_17810[gBattleAnimAttacker].unk0 & 0x10)) + { + if (GetBattlerSide(gBattleAnimAttacker) != 0) + pan = SOUND_PAN_TARGET; + else + pan = SOUND_PAN_ATTACKER; + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) != 0 || IsContest() != 0) + pan = -pan; + } + return pan; +} + +s16 sub_8077104(s16 newPan, int oldPan) +{ + s16 var = newPan; + + if (var > SOUND_PAN_TARGET) + var = SOUND_PAN_TARGET; + else if (var < SOUND_PAN_ATTACKER_NEG) + var = SOUND_PAN_ATTACKER_NEG; + return var; +} + +s16 CalculatePanIncrement(s16 sourcePan, s16 targetPan, s16 incrementPan) +{ + u16 ret; + + if (sourcePan < targetPan) + ret = ((incrementPan < 0) ? -incrementPan : incrementPan); + else if (sourcePan > targetPan) + ret = -((incrementPan < 0) ? -incrementPan : incrementPan); + else + ret = 0; + + return ret; +} + +static void ScriptCmd_playsewithpan(void) +{ + u16 soundId; + s8 pan; + + sBattleAnimScriptPtr++; + soundId = T1_READ_16(sBattleAnimScriptPtr); + pan = T1_READ_8(sBattleAnimScriptPtr + 2); + PlaySE12WithPanning(soundId, BattleAnimAdjustPanning(pan)); + sBattleAnimScriptPtr += 3; +} + +static void ScriptCmd_setpan(void) +{ + s8 pan; + + sBattleAnimScriptPtr++; + pan = T1_READ_8(sBattleAnimScriptPtr); + SE12PanpotControl(BattleAnimAdjustPanning(pan)); + sBattleAnimScriptPtr++; +} + +#define tInitialPan data[0] +#define tTargetPan data[1] +#define tIncrementPan data[2] +#define tFramesToWait data[3] +#define tCurrentPan data[4] +#define tFrameCounter data[8] + +static void ScriptCmd_panse_1B(void) +{ + u16 songNum; + s8 currentPanArg, incrementPan, incrementPanArg, currentPan, targetPan; + u8 framesToWait; + u8 taskId; + + sBattleAnimScriptPtr++; + songNum = T1_READ_16(sBattleAnimScriptPtr); + currentPanArg = T1_READ_8(sBattleAnimScriptPtr + 2); + incrementPan = T1_READ_8(sBattleAnimScriptPtr + 3); + incrementPanArg = T1_READ_8(sBattleAnimScriptPtr + 4); + framesToWait = T1_READ_8(sBattleAnimScriptPtr + 5); + + currentPan = BattleAnimAdjustPanning(currentPanArg); + targetPan = BattleAnimAdjustPanning(incrementPan); + incrementPan = CalculatePanIncrement(currentPan, targetPan, incrementPanArg); + taskId = CreateTask(Task_PanFromInitialToTarget, 1); + gTasks[taskId].tInitialPan = currentPan; + gTasks[taskId].tTargetPan = targetPan; + gTasks[taskId].tIncrementPan = incrementPan; + gTasks[taskId].tFramesToWait = framesToWait; + gTasks[taskId].tCurrentPan = currentPan; + + PlaySE12WithPanning(songNum, currentPan); + + gAnimSoundTaskCount++; + sBattleAnimScriptPtr += 6; +} + +void Task_PanFromInitialToTarget(u8 taskId) +{ + bool32 destroyTask = FALSE; + if (gTasks[taskId].tFrameCounter++ >= gTasks[taskId].tFramesToWait) + { + s16 pan; + s16 initialPanning, targetPanning, currentPan, incrementPan; + + gTasks[taskId].tFrameCounter = 0; + initialPanning = gTasks[taskId].tInitialPan; + targetPanning = gTasks[taskId].tTargetPan; + currentPan = gTasks[taskId].tCurrentPan; + incrementPan = gTasks[taskId].tIncrementPan; + pan = currentPan + incrementPan; + gTasks[taskId].tCurrentPan = pan; + + if (incrementPan == 0) // If we're not incrementing, just cancel the task immediately + { + destroyTask = TRUE; + } + else if (initialPanning < targetPanning) // Panning increasing + { + if (pan >= targetPanning) // Target reached + destroyTask = TRUE; + } + else // Panning decreasing + { + if (pan <= targetPanning) // Target reached + destroyTask = TRUE; + } + + if (destroyTask) + { + pan = targetPanning; + DestroyTask(taskId); + gAnimSoundTaskCount--; + } + + SE12PanpotControl(pan); + } +} + +static void ScriptCmd_panse_26(void) +{ + u16 songId; + s8 currentPan, targetPan, incrementPan; + u8 framesToWait; + u8 taskId; + + sBattleAnimScriptPtr++; + songId = T1_READ_16(sBattleAnimScriptPtr); + currentPan = T1_READ_8(sBattleAnimScriptPtr + 2); + targetPan = T1_READ_8(sBattleAnimScriptPtr + 3); + incrementPan = T1_READ_8(sBattleAnimScriptPtr + 4); + framesToWait = T1_READ_8(sBattleAnimScriptPtr + 5); + + taskId = CreateTask(Task_PanFromInitialToTarget, 1); + gTasks[taskId].tInitialPan = currentPan; + gTasks[taskId].tTargetPan = targetPan; + gTasks[taskId].tIncrementPan = incrementPan; + gTasks[taskId].tFramesToWait = framesToWait; + gTasks[taskId].tCurrentPan = currentPan; + + PlaySE12WithPanning(songId, currentPan); + + gAnimSoundTaskCount++; + sBattleAnimScriptPtr += 6; +} + +static void ScriptCmd_panse_27(void) +{ + u16 songId; + u8 targetPanArg, incrementPanArg, currentPan, currentPanArg; + s8 targetPan, incrementPan, framesToWait; + u8 taskId; + + sBattleAnimScriptPtr++; + songId = T1_READ_16(sBattleAnimScriptPtr); + currentPanArg = T1_READ_8(sBattleAnimScriptPtr + 2); + targetPanArg = T1_READ_8(sBattleAnimScriptPtr + 3); + incrementPanArg = T1_READ_8(sBattleAnimScriptPtr + 4); + currentPan = T1_READ_8(sBattleAnimScriptPtr + 5); + + targetPan = BattleAnimAdjustPanning2(currentPanArg); + incrementPan = BattleAnimAdjustPanning2(targetPanArg); + framesToWait = BattleAnimAdjustPanning2(incrementPanArg); + + taskId = CreateTask(Task_PanFromInitialToTarget, 1); + gTasks[taskId].data[0] = targetPan; + gTasks[taskId].data[1] = incrementPan; + gTasks[taskId].data[2] = framesToWait; + gTasks[taskId].data[3] = currentPan; + gTasks[taskId].data[4] = targetPan; + + PlaySE12WithPanning(songId, targetPan); + + gAnimSoundTaskCount++; + sBattleAnimScriptPtr += 6; +} + +#undef tInitialPan +#undef tTargetPan +#undef tIncrementPan +#undef tFramesToWait +#undef tCurrentPan +#undef tFrameCounter + +#define tSongId data[0] +#define tPanning data[1] +#define tFramesToWait data[2] +#define tNumberOfPlays data[3] +#define tFrameCounter data[8] + +static void ScriptCmd_loopsewithpan(void) +{ + u16 songId; + s8 panningArg, panning; + u8 framesToWait, numberOfPlays; + u8 taskId; + + sBattleAnimScriptPtr++; + songId = T1_READ_16(sBattleAnimScriptPtr); + panningArg = T1_READ_8(sBattleAnimScriptPtr + 2); + framesToWait = T1_READ_8(sBattleAnimScriptPtr + 3); + numberOfPlays = T1_READ_8(sBattleAnimScriptPtr + 4); + panning = BattleAnimAdjustPanning(panningArg); + + taskId = CreateTask(Task_LoopAndPlaySE, 1); + gTasks[taskId].tSongId = songId; + gTasks[taskId].tPanning = panning; + gTasks[taskId].tFramesToWait = framesToWait; + gTasks[taskId].tNumberOfPlays = numberOfPlays; + gTasks[taskId].tFrameCounter = framesToWait; + gTasks[taskId].func(taskId); + + gAnimSoundTaskCount++; + sBattleAnimScriptPtr += 5; +} + +static void Task_LoopAndPlaySE(u8 taskId) +{ + if (gTasks[taskId].tFrameCounter++ >= gTasks[taskId].tFramesToWait) + { + u16 songId; + s8 panning; + u8 numberOfPlays; + + gTasks[taskId].tFrameCounter = 0; + songId = gTasks[taskId].tSongId; + panning = gTasks[taskId].tPanning; + numberOfPlays = --gTasks[taskId].tNumberOfPlays; + PlaySE12WithPanning(songId, panning); + if (numberOfPlays == 0) + { + DestroyTask(taskId); + gAnimSoundTaskCount--; + } + } +} + +#undef tSongId +#undef tPanning +#undef tFramesToWait +#undef tNumberOfPlays +#undef tFrameCounter + +#define tSongId data[0] +#define tPanning data[1] +#define tFramesToWait data[2] + +static void ScriptCmd_waitplaysewithpan(void) +{ + u16 songId; + s8 panningArg, panning; + u8 framesToWait; + u8 taskId; + + sBattleAnimScriptPtr++; + songId = T1_READ_16(sBattleAnimScriptPtr); + panningArg = T1_READ_8(sBattleAnimScriptPtr + 2); + framesToWait = T1_READ_8(sBattleAnimScriptPtr + 3); + panning = BattleAnimAdjustPanning(panningArg); + + taskId = CreateTask(Task_WaitAndPlaySE, 1); + gTasks[taskId].tSongId = songId; + gTasks[taskId].tPanning = panning; + gTasks[taskId].tFramesToWait = framesToWait; + + gAnimSoundTaskCount++; + sBattleAnimScriptPtr += 4; +} + +static void Task_WaitAndPlaySE(u8 taskId) +{ + if (gTasks[taskId].tFramesToWait-- <= 0) + { + PlaySE12WithPanning(gTasks[taskId].tSongId, gTasks[taskId].tPanning); + DestroyTask(taskId); + gAnimSoundTaskCount--; + } +} + +#undef tSongId +#undef tPanning +#undef tFramesToWait + +// Creates a sound task. +// arg0: sound task function +// arg1: s16[] gBattleAnimArgs +static void ScriptCmd_createsoundtask(void) +{ + TaskFunc func; + u8 numArgs, taskId; + s32 i; + + sBattleAnimScriptPtr++; + func = (TaskFunc)T2_READ_32(sBattleAnimScriptPtr); + sBattleAnimScriptPtr += 4; + numArgs = T1_READ_8(sBattleAnimScriptPtr); + sBattleAnimScriptPtr++; + for (i = 0; i < numArgs; i++) + { + gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr); + sBattleAnimScriptPtr += 2; + } + taskId = CreateTask(func, 1); + func(taskId); + gAnimSoundTaskCount++; +} + +// Wait for sound effect to end. +static void ScriptCmd_waitsound(void) +{ + if (gAnimSoundTaskCount != 0) + { + gSoundAnimFramesToWait = 0; + gAnimFramesToWait = 1; + } + else if (IsSEPlaying()) + { + if (++gSoundAnimFramesToWait > 90) + { + m4aMPlayStop(&gMPlay_SE1); + m4aMPlayStop(&gMPlay_SE2); + gSoundAnimFramesToWait = 0; + } + else + { + gAnimFramesToWait = 1; + } + } + else + { + gSoundAnimFramesToWait = 0; + sBattleAnimScriptPtr++; + gAnimFramesToWait = 0; + } +} + +// Jump to animation based on gBattleAnimArgs[index] value. +// arg0: gBattleAnimArgs[] argument index +// arg1: value +// arg2: animation script +static void ScriptCmd_jumpargeq(void) +{ + u8 argId; + s16 valueToCheck; + + sBattleAnimScriptPtr++; + argId = T1_READ_8(sBattleAnimScriptPtr); + valueToCheck = T1_READ_16(sBattleAnimScriptPtr + 1); + + if (valueToCheck == gBattleAnimArgs[argId]) + sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr + 3); + else + sBattleAnimScriptPtr += 7; +} + +// If using move in contest, go to specific animation script. +// arg0: animation script +static void ScriptCmd_jumpifcontest(void) +{ + sBattleAnimScriptPtr++; + if (IsContest()) + sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr); + else + sBattleAnimScriptPtr += 4; +} + +static void ScriptCmd_monbgprio_28(void) +{ + u8 wantedBank; + u8 bank; + u8 bankIdentity; + + wantedBank = T1_READ_8(sBattleAnimScriptPtr + 1); + sBattleAnimScriptPtr += 2; + + if (wantedBank != 0) + bank = gBattleAnimTarget; + else + bank = gBattleAnimAttacker; + + bankIdentity = GetBattlerPosition(bank); + if (!IsContest() && (bankIdentity == 0 || bankIdentity == 3)) + { + REG_BG1CNT_BITFIELD.priority = 1; + REG_BG2CNT_BITFIELD.priority = 2; + } +} + +static void ScriptCmd_monbgprio_29(void) +{ + sBattleAnimScriptPtr++; + if (!IsContest()) + { + REG_BG1CNT_BITFIELD.priority = 1; + REG_BG2CNT_BITFIELD.priority = 2; + } +} + +static void ScriptCmd_monbgprio_2A(void) +{ + u8 wantedBank; + u8 bankIdentity; + u8 bank; + + wantedBank = T1_READ_8(sBattleAnimScriptPtr + 1); + sBattleAnimScriptPtr += 2; + if (GetBattlerSide(gBattleAnimAttacker) != GetBattlerSide(gBattleAnimTarget)) + { + if (wantedBank != 0) + bank = gBattleAnimTarget; + else + bank = gBattleAnimAttacker; + bankIdentity = GetBattlerPosition(bank); + if (!IsContest() && (bankIdentity == 0 || bankIdentity == 3)) + { + REG_BG1CNT_BITFIELD.priority = 1; + REG_BG2CNT_BITFIELD.priority = 2; + } + } +} + +// Sets sprite to be invisible. +// arg0: battler sprite ID +static void ScriptCmd_invisible(void) +{ + u8 spriteId; + + spriteId = GetAnimBattlerSpriteId(T1_READ_8(sBattleAnimScriptPtr + 1)); + if (spriteId != 0xFF) + gSprites[spriteId].invisible = TRUE; + + sBattleAnimScriptPtr += 2; +} + +// Sets aprite to be visible. +// arg0: battler sprite ID +static void ScriptCmd_visible(void) +{ + u8 spriteId; + + spriteId = GetAnimBattlerSpriteId(T1_READ_8(sBattleAnimScriptPtr + 1)); + if (spriteId != 0xFF) + gSprites[spriteId].invisible = FALSE; + + sBattleAnimScriptPtr += 2; +} + +static void ScriptCmd_doublebattle_2D(void) +{ + u8 wantedBank; + u8 r4; + u8 spriteId; + + wantedBank = T1_READ_8(sBattleAnimScriptPtr + 1); + sBattleAnimScriptPtr += 2; + if (!IsContest() && IsDoubleBattle() + && GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget)) + { + if (wantedBank == 0) + { + r4 = GetBattlerPosition_permutated(gBattleAnimAttacker); + spriteId = GetAnimBattlerSpriteId(0); + } + else + { + r4 = GetBattlerPosition_permutated(gBattleAnimTarget); + spriteId = GetAnimBattlerSpriteId(1); + } + if (spriteId != 0xFF) + { + gSprites[spriteId].invisible = FALSE; + if (r4 == 2) + gSprites[spriteId].oam.priority = 3; + if (r4 == 1) + sub_8076464(0); + else + sub_8076464(1); + } + } +} + +static void ScriptCmd_doublebattle_2E(void) +{ + u8 wantedBank; + u8 r4; + u8 spriteId; + + wantedBank = T1_READ_8(sBattleAnimScriptPtr + 1); + sBattleAnimScriptPtr += 2; + if (!IsContest() && IsDoubleBattle() + && GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget)) + { + if (wantedBank == 0) + { + r4 = GetBattlerPosition_permutated(gBattleAnimAttacker); + spriteId = GetAnimBattlerSpriteId(0); + } + else + { + r4 = GetBattlerPosition_permutated(gBattleAnimTarget); + spriteId = GetAnimBattlerSpriteId(1); + } + if (spriteId != 0xFF && r4 == 2) + { + gSprites[spriteId].oam.priority = 2; + } + } +} + +// Cease playing sounds. +static void ScriptCmd_stopsound(void) +{ + m4aMPlayStop(&gMPlay_SE1); + m4aMPlayStop(&gMPlay_SE2); + sBattleAnimScriptPtr++; +} diff --git a/src/battle_anim_effects_3.c b/src/battle_anim_effects_3.c new file mode 100644 index 000000000..90e7d8e2c --- /dev/null +++ b/src/battle_anim_effects_3.c @@ -0,0 +1,6065 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "blend_palette.h" +#include "contest.h" +#include "data2.h" +#include "decompress.h" +#include "ewram.h" +#include "palette.h" +#include "random.h" +#include "rom_8077ABC.h" +#include "scanline_effect.h" +#include "sound.h" +#include "trig.h" +#include "constants/songs.h" +#include "constants/species.h" + +extern s16 gBattleAnimArgs[]; +extern u8 gBattleAnimAttacker; +extern u8 gBattleAnimTarget; +extern u8 gAnimVisualTaskCount; +extern u8 gAnimFriendship; +extern s32 gAnimMoveDmg; +extern u16 gBattle_WIN0H; +extern u16 gBattle_WIN0V; +extern u16 gBattle_WIN1H; +extern u16 gBattle_WIN1V; +extern u16 gBattle_BG1_X; +extern u16 gBattle_BG1_Y; +extern u16 gBattle_BG2_X; +extern u16 gBattle_BG2_Y; +extern u16 gWeatherMoveAnim; + +extern const struct SpriteTemplate gBattleAnimSpriteTemplate_83D7220; +extern const union AffineAnimCmd *const gSpriteAffineAnimTable_81E7C18[]; +extern const union AffineAnimCmd *const gSpriteAffineAnimTable_81E7BEC[]; +extern const u32 gUnknown_08D2AA98[]; +extern const u32 gUnknown_08D2A9E0[]; +extern const u16 gUnknown_08D2AA80[]; +extern const u8 gUnknown_08D2E014[]; +extern const u8 gUnknown_08D2E170[]; +extern const u16 gUnknown_08D2E150[]; +extern u8 gBattleMonForms[]; +extern u8 gBankSpriteIds[]; +extern u16 gBattlerPartyIndexes[]; + +extern u8 sub_8046234(s16 x, s16 y, u8 a3); +extern void sub_80DA48C(struct Sprite *); +extern void sub_80E3C4C(u8 taskId, int unused, u16 arg2, u8 battler1, u8 arg4, u8 arg5, u8 arg6, u8 arg7, const u8 *arg8, const u8 *arg9, const u16 *palette); + +static void sub_812C184(struct Sprite *sprite); +static void sub_812C268(struct Sprite *sprite); +static void sub_812C2A4(struct Sprite *sprite); +static void sub_812C380(struct Sprite *sprite); +static void sub_812C40C(struct Sprite *sprite); +static void sub_812C450(struct Sprite *sprite); +static void sub_812C4FC(struct Sprite *sprite); +static void sub_812C588(u8 taskId); +static void sub_812C64C(u8 taskId); +static void sub_812C798(struct Sprite *sprite); +static void sub_812C7C8(struct Sprite *sprite); +static void sub_812CA04(struct Sprite *sprite); +static void sub_812CAD0(struct Sprite *sprite); +static void sub_812CBB4(struct Sprite *sprite); +static void sub_812CD64(struct Sprite *sprite); +static void sub_812CEF0(u8 taskId); +static void sub_812D06C(u8 taskId); +static void sub_812D254(struct Sprite *sprite); +static void sub_812D4EC(struct Sprite *sprite); +static void sub_812D5E8(struct Sprite *sprite); +static void sub_812DFEC(struct Sprite *sprite); +static void sub_812E09C(struct Sprite *sprite); +static void sub_812E0F8(struct Sprite *sprite); +static void sub_812E638(u8 taskId); +static void sub_812E7F0(struct Sprite *sprite); +static void sub_812E8B4(u8 taskId); +static void sub_812ED24(struct Sprite *sprite); +static void sub_812EE00(struct Sprite *sprite); +static void sub_812EEEC(struct Sprite *sprite); +static void AnimTask_RolePlaySilhouetteStep1(u8 taskId); +static void sub_812F290(u8 taskId); +static void sub_812F474(u8 taskId); +static void sub_812F76C(u8 taskId); +static void sub_812F8DC(struct Sprite *sprite); +static void sub_812FE20(u8 taskId); +static void sub_812FEB8(u8, bool8); +static void sub_813003C(u8 taskId); +static void sub_81301B4(struct Sprite *sprite); +static void sub_81302E4(u8 taskId); +static void sub_8130424(s16, s16, s16, s16, u8, u8, s16*, s16*); +static void sub_81306A4(u8 taskId); +static void sub_813085C(struct Sprite *sprite); +static void sub_8130970(u8 taskId); +static void sub_8130A94(struct Sprite *sprite); +static void sub_8130B38(struct Sprite *sprite); +static void sub_8130DBC(u8 taskId); +static void sub_8130FE0(struct Sprite *sprite); +static void sub_8131408(u8 taskId); +static void sub_81315C8(struct Sprite *sprite); +static void sub_8131810(u8 taskId); +static void sub_8131838(struct Sprite *sprite); +static void sub_812C144(struct Sprite *sprite); +static void sub_812C220(struct Sprite *sprite); +static void sub_812C2BC(struct Sprite *sprite); +static void sub_812C358(struct Sprite *sprite); +static void sub_812C720(struct Sprite *sprite); +static void sub_812C80C(struct Sprite *sprite); +static void sub_812C848(struct Sprite *sprite); +static void sub_812C908(struct Sprite *sprite); +static void sub_812C990(struct Sprite *sprite); +static void sub_812CAFC(struct Sprite *sprite); +static void sub_812CC28(struct Sprite *sprite); +static void sub_812CCE8(struct Sprite *sprite); +static void sub_812D294(struct Sprite *sprite); +static void sub_812D3AC(struct Sprite *sprite); +static void sub_812D4B4(struct Sprite *sprite); +static void sub_812D588(struct Sprite *sprite); +static void sub_812DEAC(struct Sprite *sprite); +static void sub_812D724(struct Sprite *sprite); +static void sub_812E4F0(struct Sprite *sprite); +static void sub_812E7A0(struct Sprite *sprite); +static void sub_812EA4C(struct Sprite *sprite); +static void sub_812EC78(struct Sprite *sprite); +static void sub_812ED84(struct Sprite *sprite); +static void sub_812EEA4(struct Sprite *sprite); +static void sub_812F88C(struct Sprite *sprite); +static void sub_812F948(struct Sprite *sprite); +static void sub_812FF94(struct Sprite *sprite); +static void sub_81300F4(struct Sprite *sprite); +static void sub_81304DC(struct Sprite *sprite); +static void sub_813051C(struct Sprite *sprite); +static void sub_81307B0(struct Sprite *sprite); +static void sub_8130A2C(struct Sprite *sprite); +static void sub_8130AEC(struct Sprite *sprite); +static void sub_8130F5C(struct Sprite *sprite); +static void sub_8131264(struct Sprite *sprite); +extern void sub_80D1FDC(struct Sprite *sprite);// kiss_fountain.c +static void sub_8131564(struct Sprite *sprite); +static void AnimTask_TeeterDanceMovementStep(u8); + +/*static*/ void sub_8131EB8(struct Sprite *sprite);// rest not yet decompiled +void AnimKnockOffStrike(struct Sprite *sprite); +void AnimRecycle(struct Sprite *sprite); +static void AnimRecycleStep(struct Sprite *sprite); +static void AnimTask_SlackOffSquishStep(u8 taskId); + +const union AnimCmd gSpriteAnim_8402164[] = +{ + ANIMCMD_FRAME(0 , 4), + ANIMCMD_FRAME(16, 4), + ANIMCMD_FRAME(32, 4), + ANIMCMD_FRAME(48, 4), + ANIMCMD_FRAME(64, 4), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_840217C[] = +{ + gSpriteAnim_8402164, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402180 = +{ + .tileTag = ANIM_TAG_SCRATCH, + .paletteTag = ANIM_TAG_SCRATCH, + .oam = &gOamData_837E054, + .anims = gSpriteAnimTable_840217C, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80793C4, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402198 = +{ + .tileTag = ANIM_TAG_BLACK_SMOKE, + .paletteTag = ANIM_TAG_BLACK_SMOKE, + .oam = &gOamData_837DF54, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812C144, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84021B0 = +{ + .tileTag = ANIM_TAG_BLACK_BALL, + .paletteTag = ANIM_TAG_BLACK_BALL, + .oam = &gOamData_837DF24, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80794A8, +}; + +const union AnimCmd gSpriteAnim_84021C8[] = +{ + ANIMCMD_FRAME(0, 40), + ANIMCMD_FRAME(16, 8), + ANIMCMD_FRAME(32, 40), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_84021D8[] = +{ + gSpriteAnim_84021C8, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84021DC = +{ + .tileTag = ANIM_TAG_OPENING_EYE, + .paletteTag = ANIM_TAG_OPENING_EYE, + .oam = &gOamData_837DF34, + .anims = gSpriteAnimTable_84021D8, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80793C4, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84021F4 = +{ + .tileTag = ANIM_TAG_ROUND_WHITE_HALO, + .paletteTag = ANIM_TAG_ROUND_WHITE_HALO, + .oam = &gOamData_837E05C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812C220, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_840220C = +{ + .tileTag = ANIM_TAG_TEAL_ALERT, + .paletteTag = ANIM_TAG_TEAL_ALERT, + .oam = &gOamData_837DF94, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812C2BC, +}; + +const union AffineAnimCmd gSpriteAffineAnim_8402224[] = +{ + AFFINEANIMCMD_FRAME(0x180, 0x180, 0, 0), + AFFINEANIMCMD_FRAME(0xFFE0, 0x18, 0, 5), + AFFINEANIMCMD_FRAME(0x18, 0xFFE0, 0, 5), + AFFINEANIMCMD_JUMP(1), +}; + +const union AffineAnimCmd gSpriteAffineAnim_8402244[] = +{ + AFFINEANIMCMD_FRAME(0x30, 0x30, 0, 0), + AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 6), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gSpriteAffineAnimTable_840225C[] = +{ + gSpriteAffineAnim_8402224, + gSpriteAffineAnim_8402244, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402264 = +{ + .tileTag = ANIM_TAG_EYE, + .paletteTag = ANIM_TAG_EYE, + .oam = &gOamData_837E11C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_840225C, + .callback = sub_812C358, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_840227C = +{ + .tileTag = ANIM_TAG_SPIKES, + .paletteTag = ANIM_TAG_SPIKES, + .oam = &gOamData_837DF2C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812C720, +}; + +const union AnimCmd gSpriteAnim_8402294[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(16, 3), + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(48, 3), + ANIMCMD_FRAME(64, 3), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_84022AC[] = +{ + gSpriteAnim_8402294, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84022B0 = +{ + .tileTag = ANIM_TAG_LEER, + .paletteTag = ANIM_TAG_LEER, + .oam = &gOamData_837DF34, + .anims = gSpriteAnimTable_84022AC, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812C80C, +}; + +const union AnimCmd gSpriteAnim_84022C8[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_84022D0[] = +{ + gSpriteAnim_84022C8, +}; + +const union AffineAnimCmd gSpriteAffineAnim_84022D4[] = +{ + AFFINEANIMCMD_FRAME(0xFFF9, 0xFFF9, -3, 16), + AFFINEANIMCMD_FRAME(0x7, 0x7, 3, 16), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gSpriteAffineAnimTable_84022EC[] = +{ + gSpriteAffineAnim_84022D4, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84022F0 = +{ + .tileTag = ANIM_TAG_LETTER_Z, + .paletteTag = ANIM_TAG_LETTER_Z, + .oam = &gOamData_837DF94, + .anims = gSpriteAnimTable_84022D0, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_84022EC, + .callback = sub_812C848, +}; + +const union AnimCmd gSpriteAnim_8402308[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_FRAME(16, 16), + ANIMCMD_FRAME(32, 4), + ANIMCMD_FRAME(48, 4), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_840231C[] = +{ + gSpriteAnim_8402308, +}; + +const union AffineAnimCmd gSpriteAffineAnim_8402320[] = +{ + AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0), + AFFINEANIMCMD_FRAME(0xFFE0, 0xFFE0, 0, 8), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gSpriteAffineAnimTable_8402338[] = +{ + gSpriteAffineAnim_8402320, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_840233C = +{ + .tileTag = ANIM_TAG_FANG_ATTACK, + .paletteTag = ANIM_TAG_FANG_ATTACK, + .oam = &gOamData_837DFF4, + .anims = gSpriteAnimTable_840231C, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_8402338, + .callback = sub_812C908, +}; + +const union AffineAnimCmd gSpriteAffineAnim_8402354[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x180, 0, 0), + AFFINEANIMCMD_FRAME(0x10, 0x0, 0, 20), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gSpriteAffineAnim_840236C[] = +{ + AFFINEANIMCMD_FRAME(0x140, 0x180, 0, 0), + AFFINEANIMCMD_FRAME(0xFFF0, 0x0, 0, 19), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gSpriteAffineAnimTable_8402384[] = +{ + gSpriteAffineAnim_8402354, + gSpriteAffineAnim_840236C, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_840238C = +{ + .tileTag = ANIM_TAG_SPOTLIGHT, + .paletteTag = ANIM_TAG_SPOTLIGHT, + .oam = &gOamData_837DFFC, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_8402384, + .callback = sub_812C990, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84023A4 = +{ + .tileTag = ANIM_TAG_TAG_HAND, + .paletteTag = ANIM_TAG_TAG_HAND, + .oam = &gOamData_837DF34, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812CAFC, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84023BC = +{ + .tileTag = ANIM_TAG_TAG_HAND, + .paletteTag = ANIM_TAG_TAG_HAND, + .oam = &gOamData_837DF34, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812CC28, +}; + +const union AnimCmd gSpriteAnim_84023D4[] = +{ + ANIMCMD_FRAME(0, 2), + ANIMCMD_FRAME(8, 2), + ANIMCMD_FRAME(16, 2), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd *const gSpriteAnimTable_84023E4[] = +{ + gSpriteAnim_84023D4, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84023E8 = +{ + .tileTag = ANIM_TAG_RAPID_SPIN, + .paletteTag = ANIM_TAG_RAPID_SPIN, + .oam = &gOamData_837DF54, + .anims = gSpriteAnimTable_84023E4, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812CCE8, +}; + +const union AffineAnimCmd gUnknown_08402400[] = +{ + AFFINEANIMCMD_FRAME(-12, 8, 0, 4), + AFFINEANIMCMD_FRAME(20, -20, 0, 4), + AFFINEANIMCMD_FRAME(-8, 12, 0, 4), + AFFINEANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_8402420[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_8402428[] = +{ + gSpriteAnim_8402420, +}; + +const union AffineAnimCmd gSpriteAffineAnim_840242C[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, 5, 40), + AFFINEANIMCMD_FRAME(0x0, 0x0, 10, 10), + AFFINEANIMCMD_FRAME(0x0, 0x0, 15, 10), + AFFINEANIMCMD_FRAME(0x0, 0x0, 20, 40), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gSpriteAffineAnimTable_8402454[] = +{ + gSpriteAffineAnim_840242C, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402458 = +{ + .tileTag = ANIM_TAG_TRI_FORCE_TRIANGLE, + .paletteTag = ANIM_TAG_TRI_FORCE_TRIANGLE, + .oam = &gOamData_837DFFC, + .anims = gSpriteAnimTable_8402428, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_8402454, + .callback = sub_812D294, +}; + +const union AnimCmd gSpriteAnim_8402470[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(16, 3), + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(48, 3), + ANIMCMD_FRAME(32, 3, .hFlip = TRUE), + ANIMCMD_FRAME(16, 3, .hFlip = TRUE), + ANIMCMD_FRAME(0, 3, .hFlip = TRUE), + ANIMCMD_LOOP(1), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_8402494[] = +{ + gSpriteAnim_8402470, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402498 = +{ + .tileTag = ANIM_TAG_ECLIPSING_ORB, + .paletteTag = ANIM_TAG_ECLIPSING_ORB, + .oam = &gOamData_837DF34, + .anims = gSpriteAnimTable_8402494, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80793C4, +}; + +const union AffineAnimCmd gUnknown_084024B0[] = +{ + AFFINEANIMCMD_FRAME(-12, 20, 0, 8), + AFFINEANIMCMD_FRAME(12, -20, 0, 8), + AFFINEANIMCMD_LOOP(2), + AFFINEANIMCMD_END, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84024D0 = +{ + .tileTag = ANIM_TAG_POKEBALL, + .paletteTag = ANIM_TAG_POKEBALL, + .oam = &gOamData_837DF2C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812D3AC, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84024E8 = +{ + .tileTag = ANIM_TAG_GOLD_STARS, + .paletteTag = ANIM_TAG_GOLD_STARS, + .oam = &gOamData_837DF2C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812D4B4, +}; + +const struct SpriteTemplate gSpriteTemplate_8402500 = +{ + .tileTag = ANIM_TAG_GOLD_STARS, + .paletteTag = ANIM_TAG_GOLD_STARS, + .oam = &gOamData_837DF24, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812D588, +}; + +const union AffineAnimCmd gUnknown_08402518[] = +{ + AFFINEANIMCMD_FRAME(8, -8, 0, 12), + AFFINEANIMCMD_FRAME(-16, 16, 0, 12), + AFFINEANIMCMD_FRAME(8, -8, 0, 12), + AFFINEANIMCMD_LOOP(1), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gUnknown_08402540[] = +{ + AFFINEANIMCMD_FRAME(0, 6, 0, 20), + AFFINEANIMCMD_FRAME(0, 0, 0, 20), + AFFINEANIMCMD_FRAME(0, -18, 0, 6), + AFFINEANIMCMD_FRAME(-18, -18, 0, 3), + AFFINEANIMCMD_FRAME(0, 0, 0, 15), + AFFINEANIMCMD_FRAME(4, 4, 0, 13), + AFFINEANIMCMD_END, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402578 = +{ + .tileTag = ANIM_TAG_BLUE_ORB, + .paletteTag = ANIM_TAG_BLUE_ORB, + .oam = &gOamData_837DF24, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812D724, +}; + +const union AffineAnimCmd gUnknown_08402590[] = +{ + AFFINEANIMCMD_FRAME(0, 6, 0, 20), + AFFINEANIMCMD_FRAME(0, 0, 0, 20), + AFFINEANIMCMD_FRAME(7, -30, 0, 6), + AFFINEANIMCMD_FRAME(0, 0, 0, 20), + AFFINEANIMCMD_FRAME(-2, 3, 0, 20), + AFFINEANIMCMD_END, +}; + +const s8 gUnknown_084025C0[] = +{ + 0xE8, + 0x18, + 0xFC, + 0x00, +}; + +const union AnimCmd gSpriteAnim_84025C4[] = +{ + ANIMCMD_FRAME(0, 6), + ANIMCMD_FRAME(4, 6), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gSpriteAnim_84025D0[] = +{ + ANIMCMD_FRAME(8, 6), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_84025D8[] = +{ + ANIMCMD_FRAME(12, 6), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_84025E0[] = +{ + gSpriteAnim_84025C4, + gSpriteAnim_84025D0, + gSpriteAnim_84025D8, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84025EC = +{ + .tileTag = ANIM_TAG_GREEN_STAR, + .paletteTag = ANIM_TAG_GREEN_STAR, + .oam = &gOamData_837DF2C, + .anims = gSpriteAnimTable_84025E0, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812DEAC, +}; + +const s8 gUnknown_08402604[] = +{ + 0x78, + 0x50, + 0x28, + 0x00, +}; + +const u8 gUnknown_08402608[] = +{ + 0, + 0, + 0, + 0, + 50, +}; + +const union AffineAnimCmd gUnknown_08402610[] = +{ + AFFINEANIMCMD_FRAME(0, -15, 0, 7), + AFFINEANIMCMD_FRAME(0, 15, 0, 7), + AFFINEANIMCMD_LOOP(2), + AFFINEANIMCMD_END, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402630 = +{ + .tileTag = ANIM_TAG_ANGER, + .paletteTag = ANIM_TAG_ANGER, + .oam = &gOamData_837DF2C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812E4F0, +}; + +const union AnimCmd gSpriteAnim_8402648[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_FRAME(1, 8), + ANIMCMD_FRAME(2, 8), + ANIMCMD_FRAME(3, 8), + ANIMCMD_FRAME(3, 8, .vFlip = TRUE), + ANIMCMD_FRAME(2, 8, .vFlip = TRUE), + ANIMCMD_FRAME(0, 8, .vFlip = TRUE), + ANIMCMD_FRAME(1, 8, .vFlip = TRUE), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gSpriteAnim_840266C[] = +{ + ANIMCMD_FRAME(0, 8, .hFlip = TRUE), + ANIMCMD_FRAME(1, 8, .hFlip = TRUE), + ANIMCMD_FRAME(2, 8, .hFlip = TRUE), + ANIMCMD_FRAME(3, 8, .hFlip = TRUE), + ANIMCMD_FRAME(3, 8, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(2, 8, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(0, 8, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_FRAME(1, 8, .vFlip = TRUE, .hFlip = TRUE), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gSpriteAnim_8402690[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_8402698[] = +{ + gSpriteAnim_8402648, + gSpriteAnim_840266C, + gSpriteAnim_8402690, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84026A4 = +{ + .tileTag = ANIM_TAG_PINK_PETAL, + .paletteTag = ANIM_TAG_PINK_PETAL, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_8402698, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812E7A0, +}; + +const u16 gUnknown_4026BC[] = INCBIN_U16("graphics/unknown/unknown_4026BC.gbapal"); + +const union AnimCmd gSpriteAnim_84026DC[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_FRAME(4, 9), + ANIMCMD_FRAME(8, 5), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_84026EC[] = +{ + gSpriteAnim_84026DC, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84026F0 = +{ + .tileTag = ANIM_TAG_PAIN_SPLIT, + .paletteTag = ANIM_TAG_PAIN_SPLIT, + .oam = &gOamData_837DF2C, + .anims = gSpriteAnimTable_84026EC, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812EA4C, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402708 = +{ + .tileTag = ANIM_TAG_CONFETTI, + .paletteTag = ANIM_TAG_CONFETTI, + .oam = &gOamData_837DF24, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812EC78, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402720 = +{ + .tileTag = ANIM_TAG_SPOTLIGHT, + .paletteTag = ANIM_TAG_SPOTLIGHT, + .oam = &gOamData_837DFFC, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_8402384, + .callback = sub_812ED84, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402738 = +{ + .tileTag = ANIM_TAG_BLUE_ORB, + .paletteTag = ANIM_TAG_BLUE_ORB, + .oam = &gOamData_837DF24, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812EEA4, +}; + +const union AffineAnimCmd gUnknown_08402750[] = +{ + AFFINEANIMCMD_FRAME(16, 0, 0, 4), + AFFINEANIMCMD_FRAME(0, -3, 0, 16), + AFFINEANIMCMD_FRAME(4, 0, 0, 4), + AFFINEANIMCMD_FRAME(0, 0, 0, 24), + AFFINEANIMCMD_FRAME(-5, 3, 0, 16), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gSpriteAffineAnim_8402780[] = +{ + AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), + AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 8), + AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd gSpriteAffineAnim_84027A0[] = +{ + AFFINEANIMCMD_FRAME(0xC0, 0xC0, 0, 0), + AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8), + AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 8), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd gSpriteAffineAnim_84027C0[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8), + AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 8), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gSpriteAffineAnimTable_84027E0[] = +{ + gSpriteAffineAnim_8402780, + gSpriteAffineAnim_84027A0, + gSpriteAffineAnim_84027C0, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84027EC = +{ + .tileTag = ANIM_TAG_PINK_CLOUD, + .paletteTag = ANIM_TAG_PINK_CLOUD, + .oam = &gOamData_837DF94, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_84027E0, + .callback = sub_812F88C, +}; + +const union AffineAnimCmd gSpriteAffineAnim_8402804[] = +{ + AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), + AFFINEANIMCMD_FRAME(0xFFFC, 0xFFFA, 0, 16), + AFFINEANIMCMD_FRAME(0x4, 0x6, 0, 16), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd gSpriteAffineAnim_8402824[] = +{ + AFFINEANIMCMD_FRAME(0xC0, 0xC0, 0, 0), + AFFINEANIMCMD_FRAME(0x4, 0x6, 0, 16), + AFFINEANIMCMD_FRAME(0xFFFC, 0xFFFA, 0, 16), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd gSpriteAffineAnim_8402844[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0x4, 0x6, 0, 16), + AFFINEANIMCMD_FRAME(0xFFFC, 0xFFFA, 0, 16), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd gSpriteAffineAnim_8402864[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0x8, 0xA, 0, 30), + AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF6, 0, 16), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gSpriteAffineAnimTable_8402884[] = +{ + gSpriteAffineAnim_8402804, + gSpriteAffineAnim_8402824, + gSpriteAffineAnim_8402844, + gSpriteAffineAnim_8402864, +}; + +//arg[0]: frame (0-3) +//arg[1]: x +//arg[2]: y +//arg[3]: ??? (time on screen?) +const struct SpriteTemplate gPinkSmokeTemplate = +{ + .tileTag = ANIM_TAG_PINK_CLOUD, + .paletteTag = ANIM_TAG_PINK_CLOUD, + .oam = &gOamData_837DFF4, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_8402884, + .callback = sub_812F948, +}; + +const union AffineAnimCmd gUnknown_084028AC[] = +{ + AFFINEANIMCMD_FRAME(-16, 16, 0, 6), + AFFINEANIMCMD_FRAME(16, -16, 0, 12), + AFFINEANIMCMD_FRAME(-16, 16, 0, 6), + AFFINEANIMCMD_END, +}; + +const struct SpriteTemplate gSpriteTemplate_84028CC = +{ + .tileTag = ANIM_TAG_SWEAT_DROP, + .paletteTag = ANIM_TAG_SWEAT_DROP, + .oam = &gOamData_837DF24, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_812FF94, +}; + +const u16 gUnknown_084028E4[] = INCBIN_U16("graphics/battle_anims/sprites/effect.gbapal"); + +const union AnimCmd gSpriteAnim_8402914[] = +{ + ANIMCMD_FRAME(0, 3), + ANIMCMD_FRAME(16, 3), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gSpriteAnim_8402920[] = +{ + ANIMCMD_FRAME(32, 3), + ANIMCMD_FRAME(48, 3), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd *const gSpriteAnimTable_840292C[] = +{ + gSpriteAnim_8402914, + gSpriteAnim_8402920, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402934 = +{ + .tileTag = ANIM_TAG_NOISE_LINE, + .paletteTag = ANIM_TAG_NOISE_LINE, + .oam = &gOamData_837DF34, + .anims = gSpriteAnimTable_840292C, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_81300F4, +}; + +const struct SpriteTemplate gSpriteTemplate_840294C = +{ + .tileTag = ANIM_TAG_SMALL_RED_EYE, + .paletteTag = ANIM_TAG_SMALL_RED_EYE, + .oam = &gOamData_837DF24, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_81304DC, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402964 = +{ + .tileTag = ANIM_TAG_PAW_PRINT, + .paletteTag = ANIM_TAG_PAW_PRINT, + .oam = &gOamData_837DF34, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_813051C, +}; + +const union AffineAnimCmd gSpriteAffineAnim_840297C[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 24), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gSpriteAffineAnim_840298C[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, -64, 0), + AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 24), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gSpriteAffineAnimTable_84029A4[] = +{ + gSpriteAffineAnim_840297C, + gSpriteAffineAnim_840298C, +}; + +const struct SpriteTemplate gSpriteTemplate_84029AC = +{ + .tileTag = ANIM_TAG_RED_BALL, + .paletteTag = ANIM_TAG_RED_BALL, + .oam = &gOamData_837DF94, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_84029A4, + .callback = SpriteCallbackDummy, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84029C4 = +{ + .tileTag = ANIM_TAG_TAG_HAND, + .paletteTag = ANIM_TAG_TAG_HAND, + .oam = &gOamData_837DF34, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_81307B0, +}; + +const union AffineAnimCmd gUnknown_084029DC[] = +{ + AFFINEANIMCMD_FRAME(0, -16, 0, 6), + AFFINEANIMCMD_FRAME(0, 16, 0, 6), + AFFINEANIMCMD_END,//0 +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_84029F4 = +{ + .tileTag = ANIM_TAG_SMELLINGSALT_EFFECT, + .paletteTag = ANIM_TAG_SMELLINGSALT_EFFECT, + .oam = &gOamData_837DF34, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8130A2C, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402A0C = +{ + .tileTag = ANIM_TAG_TAG_HAND, + .paletteTag = ANIM_TAG_TAG_HAND, + .oam = &gOamData_837DF34, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8130AEC, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402A24 = +{ + .tileTag = ANIM_TAG_MAGNIFYING_GLASS, + .paletteTag = ANIM_TAG_MAGNIFYING_GLASS, + .oam = &gOamData_837E054, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8130F5C, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402A3C = +{ + .tileTag = ANIM_TAG_GOLD_STARS, + .paletteTag = ANIM_TAG_GOLD_STARS, + .oam = &gOamData_837DF2C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8131264, +}; + +const struct SpriteTemplate gSpriteTemplate_8402A54 = +{ + .tileTag = ANIM_TAG_GOLD_STARS, + .paletteTag = ANIM_TAG_GOLD_STARS, + .oam = &gOamData_837DF2C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80D1FDC, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402A6C = +{ + .tileTag = ANIM_TAG_X_SIGN, + .paletteTag = ANIM_TAG_X_SIGN, + .oam = &gOamData_837DF3C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8131564, +}; + +const struct SpriteTemplate gSpriteTemplate_8402A84 = +{ + .tileTag = ANIM_TAG_ITEM_BAG, + .paletteTag = ANIM_TAG_ITEM_BAG, + .oam = &gOamData_837DF34, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8131EB8, +}; + +const union AnimCmd gSpriteAnim_8402A9C[] = +{ + ANIMCMD_FRAME(0, 4), + ANIMCMD_FRAME(64, 4), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_8402AA8[] = +{ + gSpriteAnim_8402A9C, +}; + +const union AffineAnimCmd gSpriteAffineAnim_8402AAC[] = +{ + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 8), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd gSpriteAffineAnim_8402AC4[] = +{ + AFFINEANIMCMD_FRAME(0xFF00, 0x100, 0, 0), + AFFINEANIMCMD_FRAME(0x0, 0x0, 4, 8), + AFFINEANIMCMD_END, +}; + +const union AffineAnimCmd *const gSpriteAffineAnimTable_8402ADC[] = +{ + gSpriteAffineAnim_8402AAC, + gSpriteAffineAnim_8402AC4, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402AE4 = +{ + .tileTag = ANIM_TAG_SLAM_HIT_2, + .paletteTag = ANIM_TAG_SLAM_HIT_2, + .oam = &gOamData_837DF9C, + .anims = gSpriteAnimTable_8402AA8, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_8402ADC, + .callback = AnimKnockOffStrike, +}; + +const union AffineAnimCmd gSpriteAffineAnim_8402AFC[] = +{ + AFFINEANIMCMD_FRAME(0x0, 0x0, -4, 64), + AFFINEANIMCMD_JUMP(0), +}; + +const union AffineAnimCmd *const gSpriteAffineAnimTable_8402B0C[] = +{ + gSpriteAffineAnim_8402AFC, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_8402B10 = +{ + .tileTag = ANIM_TAG_RECYCLE, + .paletteTag = ANIM_TAG_RECYCLE, + .oam = &gOamData_837E0BC, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_8402B0C, + .callback = AnimRecycle, +}; + +const union AffineAnimCmd gSlackOffSquishAffineAnimCmds[] = +{ + AFFINEANIMCMD_FRAME(0, 16, 0, 4), + AFFINEANIMCMD_FRAME(-2, 0, 0, 8), + AFFINEANIMCMD_FRAME(0, 4, 0, 4), + AFFINEANIMCMD_FRAME(0, 0, 0, 24), + AFFINEANIMCMD_FRAME(1, -5, 0, 16), + AFFINEANIMCMD_END, +}; + +static void sub_812C144(struct Sprite *sprite) +{ + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + + if (gBattleAnimArgs[3] == 0) + sprite->data[0] = gBattleAnimArgs[2]; + else + sprite->data[0] = -gBattleAnimArgs[2]; + + sprite->data[1] = gBattleAnimArgs[4]; + sprite->callback = sub_812C184; +} + +static void sub_812C184(struct Sprite *sprite) +{ + if (sprite->data[1] > 0) + { + sprite->pos2.x = sprite->data[2] >> 8; + sprite->data[2] += sprite->data[0]; + sprite->invisible ^= 1; + sprite->data[1]--; + } + else + { + DestroyAnimSprite(sprite); + } +} + +void sub_812C1D0(u8 taskId) +{ + sub_8046234( + GetBattlerSpriteCoord(gBattleAnimTarget, 2) + 8, + GetBattlerSpriteCoord(gBattleAnimTarget, 3) + 8, + 0); + DestroyAnimVisualTask(taskId); + +} + +static void sub_812C220(struct Sprite *sprite) +{ + sprite->data[0] = 90; + sprite->callback = WaitAnimForDuration; + sprite->data[1] = 7; + StoreSpriteCallbackInData(sprite, sub_812C268); + REG_BLDCNT = 0x3F40; + REG_BLDALPHA = ((16 - sprite->data[1]) << 8) | sprite->data[1]; +} + +static void sub_812C268(struct Sprite *sprite) +{ + REG_BLDALPHA = ((16 - sprite->data[1]) << 8) | sprite->data[1]; + if (--sprite->data[1] < 0) + { + sprite->invisible = 1; + sprite->callback = sub_812C2A4; + } +} + +static void sub_812C2A4(struct Sprite *sprite) +{ + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + DestroyAnimSprite(sprite); +} + +static void sub_812C2BC(struct Sprite *sprite) +{ + u16 rotation; + u8 x = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + u8 y = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + + sub_8078764(sprite, TRUE); + + rotation = ArcTan2Neg(sprite->pos1.x - x, sprite->pos1.y - y); + rotation += 0x6000; + if (IsContest()) + rotation += 0x4000; + + sub_8078FDC(sprite, 0, 0x100, 0x100, rotation); + + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[2] = x; + sprite->data[4] = y; + sprite->callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); +} + +static void sub_812C358(struct Sprite *sprite) +{ + REG_BLDCNT = 0x3F40; + REG_BLDALPHA = 0x1000; + sprite->data[0] = 4; + sprite->callback = sub_812C380; +} + +static void sub_812C380(struct Sprite *sprite) +{ + REG_BLDALPHA = ((16 - sprite->data[0]) << 8) | sprite->data[0]; + + if (sprite->data[1]) + sprite->data[0]--; + else + sprite->data[0]++; + + if (sprite->data[0] == 15 || sprite->data[0] == 4) + sprite->data[1] ^= 1; + + if (sprite->data[2]++ > 70) + { + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + StartSpriteAffineAnim(sprite, 1); + sprite->data[2] = 0; + sprite->invisible = 1; + sprite->affineAnimPaused = 1; + sprite->callback = sub_812C40C; + } +} + +static void sub_812C40C(struct Sprite *sprite) +{ + if (sprite->data[2]++ > 9) + { + sprite->invisible = 0; + sprite->affineAnimPaused = 0; + if (sprite->affineAnimEnded) + sprite->callback = sub_812C450; + } +} + +static void sub_812C450(struct Sprite *sprite) +{ + switch (sprite->data[3]) + { + case 0: + case 1: + sprite->pos2.x = 1; + sprite->pos2.y = 0; + break; + case 2: + case 3: + sprite->pos2.x = -1; + sprite->pos2.y = 0; + break; + case 4: + case 5: + sprite->pos2.x = 0; + sprite->pos2.y = 1; + break; + case 6: + default: + sprite->pos2.x = 0; + sprite->pos2.y = -1; + break; + } + + if (++sprite->data[3] > 7) + sprite->data[3] = 0; + + if (sprite->data[4]++ > 15) + { + sprite->data[0] = 16; + sprite->data[1] = 0; + REG_BLDCNT = 0x3F40; + REG_BLDALPHA = sprite->data[0]; + sprite->callback = sub_812C4FC; + } +} + +static void sub_812C4FC(struct Sprite *sprite) +{ + REG_BLDALPHA = ((16 - sprite->data[0]) << 8) | sprite->data[0]; + + if (sprite->data[1]++ > 1) + { + sprite->data[0]--; + sprite->data[1] = 0; + } + + if (sprite->data[0] == 0) + sprite->invisible = 1; + + if (sprite->data[0] < 0) + { + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + DestroyAnimSprite(sprite); + } +} + +void sub_812C560(u8 taskId) +{ + gTasks[taskId].func = sub_812C588; + gAnimVisualTaskCount--; +} + +static void sub_812C588(u8 taskId) +{ + int i; + u16 lastColor; + u8 paletteIndex = sub_80789BC(); + + if (++gTasks[taskId].data[5] == 4) + { + lastColor = gPlttBufferFaded[paletteIndex * 16 + 11]; + for (i = 10; i > 0; i--) + gPlttBufferFaded[paletteIndex * 16 + i + 1] = gPlttBufferFaded[paletteIndex * 16 + i]; + + gPlttBufferFaded[paletteIndex * 16 + 1] = lastColor; + gTasks[taskId].data[5] = 0; + } + + if ((u16)gBattleAnimArgs[7] == 0xFFFF) + DestroyTask(taskId); +} + +void sub_812C624(u8 taskId) +{ + gTasks[taskId].func = sub_812C64C; + gAnimVisualTaskCount--; +} + +static void sub_812C64C(u8 taskId) +{ + int i; + u16 lastColor; + u8 paletteIndex = sub_80789BC(); + + if (++gTasks[taskId].data[5] == 4) + { + lastColor = gPlttBufferFaded[paletteIndex * 16 + 11]; + for (i = 10; i > 0; i--) + gPlttBufferFaded[paletteIndex * 16 + i + 1] = gPlttBufferFaded[paletteIndex * 16 + i]; + gPlttBufferFaded[paletteIndex * 16 + 1] = lastColor; + + lastColor = gPlttBufferUnfaded[paletteIndex * 16 + 11]; + for (i = 10; i > 0; i--) + gPlttBufferUnfaded[paletteIndex * 16 + i + 1] = gPlttBufferUnfaded[paletteIndex * 16 + i]; + gPlttBufferUnfaded[paletteIndex * 16 + 1] = lastColor; + + gTasks[taskId].data[5] = 0; + } + + if ((u16)gBattleAnimArgs[7] == 0xFFFF) + DestroyTask(taskId); +} + +static void sub_812C720(struct Sprite *sprite) +{ + u16 x; + u16 y; + + InitAnimSpritePos(sprite, 1); + SetAverageBattlerPositions(gBattleAnimTarget, 0, &x, &y); + + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = x + gBattleAnimArgs[2]; + sprite->data[4] = y + gBattleAnimArgs[3]; + sprite->data[5] = -50; + + InitAnimArcTranslation(sprite); + sprite->callback = sub_812C798; +} + +static void sub_812C798(struct Sprite *sprite) +{ + if (TranslateAnimArc(sprite)) + { + sprite->data[0] = 30; + sprite->data[1] = 0; + sprite->callback = WaitAnimForDuration; + StoreSpriteCallbackInData(sprite, sub_812C7C8); + } +} + +static void sub_812C7C8(struct Sprite *sprite) +{ + if (sprite->data[1] & 1) + sprite->invisible ^= 1; + + if (++sprite->data[1] == 16) + DestroyAnimSprite(sprite); +} + +static void sub_812C80C(struct Sprite *sprite) +{ + sub_8078650(sprite); + sub_807867C(sprite, gBattleAnimArgs[0]); + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->callback = sub_8078600; + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); +} + +// This is likely fakematching due to some strange type casting behavior. +static void sub_812C848(struct Sprite *sprite) +{ + int var0; + int var1; + if (sprite->data[0] == 0) + { + sub_8078650(sprite); + sub_807867C(sprite, gBattleAnimArgs[0]); + + if (!IsContest()) + { + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + sprite->data[1] = gBattleAnimArgs[2]; + sprite->data[2] = gBattleAnimArgs[3]; + } + else + { + var1 = -gBattleAnimArgs[2]; + sprite->data[1] = var1; + var1 = -gBattleAnimArgs[3]; + sprite->data[2] = var1; + } + } + else + { + var1 = -gBattleAnimArgs[2]; + sprite->data[1] = var1; + sprite->data[2] = gBattleAnimArgs[3]; + } + } + + sprite->data[0]++; + var0 = (sprite->data[0] * 20) & 0xFF; + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + sprite->pos2.x = (sprite->data[3] + (s32)((u32)sprite->data[3] >> 31)) >> 1; + sprite->pos2.y = Sin(var0 & 0xFF, 5) + ((s32)(sprite->data[4] + ((u32)sprite->data[4] >> 31)) >> 1); + + if ((u16)(sprite->pos1.x + sprite->pos2.x) > 240) + DestroyAnimSprite(sprite); +} + +static void sub_812C908(struct Sprite *sprite) +{ + if (sprite->animEnded) + DestroyAnimSprite(sprite); +} + +void sub_812C924(u8 taskId) +{ + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT) + gBattleAnimArgs[7] = 0; + else + gBattleAnimArgs[7] = 1; + + DestroyAnimVisualTask(taskId); +} + +void sub_812C960(u8 taskId) +{ + if (gAnimMoveDmg > 0) + gBattleAnimArgs[7] = 0; + else + gBattleAnimArgs[7] = 1; + + DestroyAnimVisualTask(taskId); +} + +static void sub_812C990(struct Sprite *sprite) +{ + REG_WINOUT = 0x1F3F; + REG_DISPCNT |= DISPCNT_OBJWIN_ON; + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + REG_WIN0H = 0; + REG_WIN0V = 0; + + sub_8078764(sprite, FALSE); + + sprite->oam.objMode = ST_OAM_OBJ_WINDOW; + sprite->invisible = 1; + sprite->callback = sub_812CA04; +} + +static void sub_812CA04(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + sprite->invisible = 0; + if (sprite->affineAnimEnded) + sprite->data[0]++; + break; + case 1: + case 3: + sprite->data[1] += 117; + sprite->pos2.x = sprite->data[1] >> 8; + if (++sprite->data[2] == 21) + { + sprite->data[2] = 0; + sprite->data[0]++; + } + break; + case 2: + sprite->data[1] -= 117; + sprite->pos2.x = sprite->data[1] >> 8; + if (++sprite->data[2] == 41) + { + sprite->data[2] = 0; + sprite->data[0]++; + } + break; + case 4: + ChangeSpriteAffineAnim(sprite, 1); + sprite->data[0]++; + break; + case 5: + if (sprite->affineAnimEnded) + { + sprite->invisible = 1; + sprite->callback = sub_812CAD0; + } + break; + } +} + +static void sub_812CAD0(struct Sprite *sprite) +{ + REG_WINOUT = 0x3F3F; + REG_DISPCNT ^= DISPCNT_OBJWIN_ON; + DestroyAnimSprite(sprite); +} + +static void sub_812CAFC(struct Sprite *sprite) +{ + if (gBattleAnimArgs[3] == 0) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); + } + + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->oam.tileNum += 16; + + if (gBattleAnimArgs[2] == 0) + { + sprite->oam.matrixNum = 8; + sprite->pos2.x = -12; + sprite->data[1] = 2; + } + else + { + sprite->pos2.x = 12; + sprite->data[1] = -2; + } + + sprite->data[0] = gBattleAnimArgs[4]; + + if (sprite->data[3] != 255) + sprite->data[3] = gBattleAnimArgs[2]; + + sprite->callback = sub_812CBB4; +} + +static void sub_812CBB4(struct Sprite *sprite) +{ + if (sprite->data[2] == 0) + { + sprite->pos2.x += sprite->data[1]; + if (sprite->pos2.x == 0) + { + sprite->data[2]++; + if (sprite->data[3] == 0) + { + PlaySE1WithPanning(222, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER_NEG)); + } + } + } + else + { + sprite->pos2.x -= sprite->data[1]; + if (abs(sprite->pos2.x) == 12) + { + sprite->data[0]--; + sprite->data[2]--; + } + + } + + if (sprite->data[0] == 0) + DestroyAnimSprite(sprite); +} + +static void sub_812CC28(struct Sprite *sprite) +{ + sprite->oam.objMode = ST_OAM_OBJ_WINDOW; + sprite->data[3] = 255; + sub_812CAFC(sprite); +} + +void sub_812CC44(u8 taskId) +{ + if (IsContest()) + { + REG_WININ = 0x1F3F; + gBattle_WIN1H = 0x98F0; + gBattle_WIN1V = 0x00A0; + REG_WIN1H = gBattle_WIN0H; + REG_WIN1V = gBattle_WIN0V; + } + + DestroyAnimVisualTask(taskId); +} + +void sub_812CCA8(u8 taskId) +{ + if (IsContest()) + { + REG_WININ = 0x3F3F; + gBattle_WIN1H = 0; + gBattle_WIN1V = 0; + } + + DestroyAnimVisualTask(taskId); +} + +static void sub_812CCE8(struct Sprite *sprite) +{ + int var0; + if (gBattleAnimArgs[0] == 0) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0) + gBattleAnimArgs[1]; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); + } + else + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0) + gBattleAnimArgs[1]; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1); + } + + sprite->pos2.y = gBattleAnimArgs[2]; + var0 = 0; + if (sprite->pos2.y > gBattleAnimArgs[3]) + var0 = 1; + + sprite->data[0] = var0; + sprite->data[1] = 0; + sprite->data[2] = gBattleAnimArgs[4]; + sprite->data[3] = gBattleAnimArgs[5]; + sprite->data[4] = gBattleAnimArgs[3]; + sprite->callback = sub_812CD64; +} + +static void sub_812CD64(struct Sprite *sprite) +{ + sprite->data[1] = (sprite->data[1] + sprite->data[2]) & 0xFF; + sprite->pos2.x = gSineTable[sprite->data[1]] >> 4; + sprite->pos2.y += sprite->data[3]; + + if (sprite->data[0]) + { + if (sprite->pos2.y < sprite->data[4]) + DestroyAnimSprite(sprite); + } + else + { + if (sprite->pos2.y > sprite->data[4]) + DestroyAnimSprite(sprite); + } +} + +void sub_812CDC8(u8 taskId) +{ + s16 var0; + u8 toBG2; + s16 var2; + int var3; + int var4; + s16 i; + struct ScanlineEffectParams scanlineParams; + struct Task *task = &gTasks[taskId]; + + if (gBattleAnimArgs[0] == 0) + { + var0 = sub_8077FC0(gBattleAnimAttacker); + toBG2 = GetBattlerPosition_permutated(gBattleAnimAttacker); + } + else + { + var0 = sub_8077FC0(gBattleAnimTarget); + toBG2 = GetBattlerPosition_permutated(gBattleAnimTarget); + } + + task->data[0] = var0 + 36; + task->data[1] = task->data[0]; + task->data[2] = var0 - 33; + if (task->data[2] < 0) + task->data[2] = 0; + + task->data[3] = task->data[0]; + task->data[4] = 8; + task->data[5] = gBattleAnimArgs[1]; + task->data[6] = 0; + task->data[7] = 0; + + if (toBG2 == 1) + { + var3 = gBattle_BG1_X; + task->data[8] = var3; + var4 = var3 + 240; + } + else + { + var3 = gBattle_BG2_X; + task->data[8] = var3; + var4 = var3 + 240; + } + + task->data[9] = var4; + task->data[10] = gBattleAnimArgs[2]; + + if (gBattleAnimArgs[2] == 0) + { + task->data[11] = var4; + var2 = task->data[8]; + } + else + { + task->data[11] = var3; + var2 = task->data[9]; + } + + task->data[15] = 0; + + i = task->data[2]; + while (i <= task->data[3]) + { + gScanlineEffectRegBuffers[0][i] = var2; + gScanlineEffectRegBuffers[1][i] = var2; + i++; + } + + if (toBG2 == 1) + scanlineParams.dmaDest = ®_BG1HOFS; + else + scanlineParams.dmaDest = ®_BG2HOFS; + + scanlineParams.dmaControl = 0xA2600001; + scanlineParams.initState = 1; + scanlineParams.unused9 = 0; + ScanlineEffect_SetParams(scanlineParams); + + task->func = sub_812CEF0; +} + +static void sub_812CEF0(u8 taskId) +{ + s16 i; + struct Task *task = &gTasks[taskId]; + + task->data[0] -= task->data[5]; + if (task->data[0] < task->data[2]) + task->data[0] = task->data[2]; + + if (task->data[4] == 0) + { + task->data[1] -= task->data[5]; + if (task->data[1] < task->data[2]) + { + task->data[1] = task->data[2]; + task->data[15] = 1; + } + } + else + { + task->data[4]--; + } + + if (++task->data[6] > 1) + { + task->data[6] = 0; + task->data[7] = task->data[7] == 0 ? 1 : 0; + + if (task->data[7]) + task->data[12] = task->data[8]; + else + task->data[12] = task->data[9]; + } + + i = task->data[0]; + while (i < task->data[1]) + { + gScanlineEffectRegBuffers[0][i] = task->data[12]; + gScanlineEffectRegBuffers[1][i] = task->data[12]; + i++; + } + + i = task->data[1]; + while (i <= task->data[3]) + { + gScanlineEffectRegBuffers[0][i] = task->data[11]; + gScanlineEffectRegBuffers[1][i] = task->data[11]; + i++; + } + + if (task->data[15]) + { + if (task->data[10]) + gScanlineEffect.state = 3; + + DestroyAnimVisualTask(taskId); + } +} + +void sub_812D008(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + task->data[3] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + task->data[4] = 32; + task->data[5] = -20; + task->data[6] = 0; + task->data[15] = GetAnimBattlerSpriteId(0); + task->func = sub_812D06C; +} + +static void sub_812D06C(u8 taskId) +{ + int var0, var1; + s16 x, y; + u16 i, j; + u8 spriteId; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + var0 = task->data[2]; + if (task->data[1] & 1) + { + var1 = task->data[4]; + x = var0 - var1; + } + else + { + var1 = task->data[4]; + x = var0 + var1; + } + + y = task->data[3] + task->data[5]; + spriteId = CreateSprite(&gBattleAnimSpriteTemplate_83D7220, x, y, 6 - task->data[1]); + PlaySE12WithPanning(186, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER_NEG)); + + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].hFlip = task->data[1] & 1; + gSprites[spriteId].callback = SpriteCallbackDummy; + } + + if (task->data[1] & 1) + { + task->data[4] -= 6; + task->data[5] -= 6; + } + + PrepareAffineAnimInTaskData(task, task->data[15], gUnknown_08402400); + task->data[1]++; + task->data[0] = 1; + break; + case 1: + if (RunAffineAnimFromTaskData(task) == 0) + { + if (task->data[1] == 6) + { + task->data[6] = 8; + task->data[0] = 3; + } + else + { + if (task->data[1] <= 2) + task->data[6] = 10; + else + task->data[6] = 0; + + task->data[0] = 2; + } + } + break; + case 2: + if (task->data[6] != 0) + task->data[6]--; + else + task->data[0] = 0; + break; + case 3: + if (task->data[6] != 0) + task->data[6]--; + else + task->data[0] = 4; + break; + case 4: + for (i = 0, j = 0; i < MAX_SPRITES; i++) + { + if (gSprites[i].template == &gBattleAnimSpriteTemplate_83D7220) + { + gSprites[i].data[0] = taskId; + gSprites[i].data[1] = 6; + StartSpriteAnim(&gSprites[i], 2); + gSprites[i].callback = sub_812D254; + + if (++j == 6) + break; + } + } + + task->data[6] = j; + task->data[0] = 5; + break; + case 5: + if (task->data[6] == 0) + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_812D254(struct Sprite *sprite) +{ + if (sprite->animEnded) + { + gTasks[sprite->data[0]].data[sprite->data[1]]--; + DestroySprite(sprite); + } +} + +static void sub_812D294(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + InitAnimSpritePos(sprite, 0); + + sprite->data[0]++; + if (sprite->data[0] < 40) + { + u16 var = sprite->data[0]; + if ((var & 1) == 0) + sprite->invisible = 1; + else + sprite->invisible = 0; + } + + if (sprite->data[0] > 30) + sprite->invisible = 0; + + if (sprite->data[0] == 61) + { + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + sprite->data[0] = 20; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + sprite->callback = StartAnimLinearTranslation; + } +} + +void sub_812D350(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + case 0: + PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(0), &gUnknown_084024B0); + gTasks[taskId].data[0]++; + break; + case 1: + if (RunAffineAnimFromTaskData(&gTasks[taskId]) == 0) + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_812D3AC(struct Sprite *sprite) +{ + u8 spriteId = GetAnimBattlerSpriteId(0); + + switch (sprite->data[0]) + { + case 0: + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + PrepareBattlerSpriteForRotScale(spriteId, 0); + sprite->data[1] = 256; + sprite->data[2] = 256; + sprite->data[0]++; + break; + case 1: + sprite->data[1] += 96; + sprite->data[2] -= 26; + obj_id_set_rotscale(spriteId, sprite->data[1], sprite->data[2], 0); + + if (++sprite->data[3] == 5) + sprite->data[0]++; + // fall through + case 2: + sprite->data[1] += 96; + sprite->data[2] += 48; + obj_id_set_rotscale(spriteId, sprite->data[1], sprite->data[2], 0); + + if (++sprite->data[3] == 9) + { + sprite->data[3] = 0; + gSprites[spriteId].invisible = 1; + sub_8078F40(spriteId); + sprite->data[0]++; + } + break; + case 3: + sprite->pos2.y -= 6; + if (sprite->pos1.y + sprite->pos2.y < -32) + DestroyAnimSprite(sprite); + break; + } +} + +static void sub_812D4B4(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->pos1.x = -16; + else + sprite->pos1.x = 256; + + sprite->pos1.y = 0; + sprite->callback = sub_812D4EC; +} + +static void sub_812D4EC(struct Sprite *sprite) +{ + u32 newX; + + sprite->data[0] += 72; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->pos2.x = sprite->data[0] >> 4; + else + sprite->pos2.x = -(sprite->data[0] >> 4); + + sprite->data[1] += 16; + sprite->pos2.y += sprite->data[1] >> 8; + + if (++sprite->data[2] % 3 == 0) + { + CreateSpriteAndAnimate( + &gSpriteTemplate_8402500, + sprite->pos1.x + sprite->pos2.x, + sprite->pos1.y + sprite->pos2.y, + sprite->subpriority + 1); + } + + newX = sprite->pos1.x + sprite->pos2.x + 32; + if (newX > 304) + DestroyAnimSprite(sprite); +} + +static void sub_812D588(struct Sprite *sprite) +{ + u8 rand; + s8 y; + + rand = Random() & 3; + if (rand == 0) + sprite->oam.tileNum += 4; + else + sprite->oam.tileNum += 5; + + y = Random() & 7; + if (y > 3) + y = -y; + + sprite->pos2.y = y; + sprite->callback = sub_812D5E8; +} + +static void sub_812D5E8(struct Sprite *sprite) +{ + if (++sprite->data[0] < 30) + { + if (++sprite->data[1] == 2) + { + sprite->invisible ^= 1; + sprite->data[1] = 0; + } + } + else + { + if (sprite->data[1] == 2) + sprite->invisible = 0; + + if (sprite->data[1] == 3) + { + sprite->invisible = 1; + sprite->data[1] = -1; + } + + sprite->data[1]++; + } + + if (sprite->data[0] > 60) + DestroySprite(sprite); +} + +void sub_812D674(u8 taskId) +{ + if (gTasks[taskId].data[0] == 0) + { + PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(0), &gUnknown_08402518); + gTasks[taskId].data[0]++; + } + else + { + if (RunAffineAnimFromTaskData(&gTasks[taskId]) == 0) + DestroyAnimVisualTask(taskId); + } +} + +void sub_812D6CC(u8 taskId) +{ + if (gTasks[taskId].data[0] == 0) + { + PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(0), &gUnknown_08402540); + gTasks[taskId].data[0]++; + } + else + { + if (RunAffineAnimFromTaskData(&gTasks[taskId]) == 0) + DestroyAnimVisualTask(taskId); + } +} + +static void sub_812D724(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + InitAnimSpritePos(sprite, 0); + sprite->data[1] = 0x900; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->data[0]++; + break; + case 1: + sprite->pos2.y -= sprite->data[1] >> 8; + sprite->data[1] -= 96; + if (sprite->pos1.y + sprite->pos2.y > sprite->data[2]) + DestroyAnimSprite(sprite); + break; + } +} + +void sub_812D790(u8 taskId) +{ + if (gTasks[taskId].data[0] == 0) + { + PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(0), &gUnknown_08402590); + gTasks[taskId].data[0]++; + } + else + { + if (RunAffineAnimFromTaskData(&gTasks[taskId]) == 0) + DestroyAnimVisualTask(taskId); + } +} + +void sub_812D7E8(u8 taskId) +{ + int i, j; + u8 position; + struct Struct_sub_8078914 subStruct; + u8 *dest; + u8 *src; + u16 *field_4; + u16 *ptr; + u16 stretch; + + switch (gTasks[taskId].data[0]) + { + case 0: + REG_MOSAIC = 0; + if (GetBattlerPosition_permutated(gBattleAnimAttacker) == 1) + REG_BG1CNT_BITFIELD.mosaic = 1; + else + REG_BG2CNT_BITFIELD.mosaic = 1; + + gTasks[taskId].data[10] = gBattleAnimArgs[0]; + gTasks[taskId].data[0]++; + break; + case 1: + if (gTasks[taskId].data[2]++ > 1) + { + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[1]++; + stretch = gTasks[taskId].data[1]; + REG_MOSAIC = (stretch << 4) | stretch; + if (stretch == 15) + gTasks[taskId].data[0]++; + } + break; + case 2: + sub_8031FC4(gBattleAnimAttacker, gBattleAnimTarget, gTasks[taskId].data[10]); + sub_8078954(&subStruct, gBattleAnimAttacker); + + if (IsContest()) + position = 0; + else + position = GetBattlerPosition(gBattleAnimAttacker); + + dest = gUnknown_081FAF4C[position] + (gBattleMonForms[gBattleAnimAttacker] << 11); + src = subStruct.field_0; + DmaCopy32(3, dest, src, 0x800); + + if (IsContest()) + { + if (IsSpeciesNotUnown(EWRAM_19348[0]) != IsSpeciesNotUnown(EWRAM_19348[1])) + { + field_4 = (u16 *)subStruct.field_4; + for (i = 0; i < 8; i++) + { + for (j = 0; j < 4; j++) + { + u16 temp = field_4[j + i * 0x20]; + field_4[j + i * 0x20] = field_4[(7 - j) + i * 0x20]; + field_4[(7 - j) + i * 0x20] = temp; + } + } + + for (i = 0; i < 8; i++) + { + for (j = 0; j < 8; j++) + { + field_4[j + i * 0x20] ^= 0x400; + } + } + } + + ptr = EWRAM_19348; + if (IsSpeciesNotUnown(ptr[1])) + gSprites[gBankSpriteIds[gBattleAnimAttacker]].affineAnims = gSpriteAffineAnimTable_81E7C18; + else + gSprites[gBankSpriteIds[gBattleAnimAttacker]].affineAnims = gSpriteAffineAnimTable_81E7BEC; + + StartSpriteAffineAnim(&gSprites[gBankSpriteIds[gBattleAnimAttacker]], 0); + } + + gTasks[taskId].data[0]++; + break; + case 3: + if (gTasks[taskId].data[2]++ > 1) + { + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[1]--; + stretch = gTasks[taskId].data[1]; + REG_MOSAIC = (stretch << 4) | stretch; + + if (stretch == 0) + gTasks[taskId].data[0]++; + } + break; + case 4: + REG_MOSAIC = 0; + if (GetBattlerPosition_permutated(gBattleAnimAttacker) == 1) + REG_BG1CNT_BITFIELD.mosaic = 0; + else + REG_BG2CNT_BITFIELD.mosaic = 0; + + if (!IsContest()) + { + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) + { + if (gTasks[taskId].data[10] == 0) + sub_8032984(gBattleAnimAttacker, eTransformStatuses[gBattleAnimAttacker].species); + } + } + + DestroyAnimVisualTask(taskId); + break; + } +} + +void c3_80DFBE4(u8 taskId) +{ + gBattleAnimArgs[7] = gSprites[gBankSpriteIds[gBattleAnimAttacker]].invisible; + DestroyAnimVisualTask(taskId); +} + +void sub_812DB58(u8 taskId) +{ + sub_8031FC4(gBattleAnimAttacker, gBattleAnimTarget, 1); + DestroyAnimVisualTask(taskId); +} + +void sub_812DB84(u8 taskId) +{ + struct Struct_sub_8078914 subStruct; + + switch (gTasks[taskId].data[0]) + { + case 0: + REG_BLDCNT = BLDCNT_TGT2_BD | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 + | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1; + REG_BLDALPHA = 0x1000; + REG_BG1CNT_BITFIELD.screenSize = 0; + REG_BG1CNT_BITFIELD.priority = 1; + if (!IsContest()) + REG_BG1CNT_BITFIELD.charBaseBlock = 1; + + sub_8078914(&subStruct); + DmaClear32(3, subStruct.field_4, 0x1000); + LZDecompressVram(gUnknown_08D2AA98, subStruct.field_4); + LZDecompressVram(gUnknown_08D2A9E0, subStruct.field_0); + LoadCompressedPalette(gUnknown_08D2AA80, subStruct.field_8 * 16, 32); + if (IsContest()) + { + sub_80763FC(subStruct.field_8, (u16 *)subStruct.field_4, 0, 0); + gBattle_BG1_X = -56; + gBattle_BG1_Y = 0; + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattle_BG1_X = -135; + else + gBattle_BG1_X = -10; + + gBattle_BG1_Y = 0; + } + + gTasks[taskId].data[10] = gBattle_BG1_X; + gTasks[taskId].data[11] = gBattle_BG1_Y; + + gTasks[taskId].data[0]++; + PlaySE12WithPanning(SE_W234, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER_NEG)); + break; + case 1: + if (gTasks[taskId].data[4]++ > 0) + { + gTasks[taskId].data[4] = 0; + if (++gTasks[taskId].data[1] > 12) + gTasks[taskId].data[1] = 12; + + REG_BLDALPHA = ((16 - gTasks[taskId].data[1]) << 8) | gTasks[taskId].data[1]; + + if (gTasks[taskId].data[1] == 12) + gTasks[taskId].data[0]++; + } + break; + case 2: + if (--gTasks[taskId].data[1] < 0) + gTasks[taskId].data[1] = 0; + + REG_BLDALPHA = ((16 - gTasks[taskId].data[1]) << 8) | gTasks[taskId].data[1]; + + if (gTasks[taskId].data[1] == 0) + { + gBattle_BG1_X = gUnknown_084025C0[gTasks[taskId].data[2]] + gTasks[taskId].data[10]; + if (++gTasks[taskId].data[2] == 4) + gTasks[taskId].data[0] = 4; + else + gTasks[taskId].data[0] = 3; + } + break; + case 3: + if (++gTasks[taskId].data[3] == 4) + { + gTasks[taskId].data[3] = 0; + gTasks[taskId].data[0] = 1; + PlaySE12WithPanning(SE_W234, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER_NEG)); + } + break; + case 4: + sub_8078914(&subStruct); + DmaFill32Large(3, 0, subStruct.field_0, 0x2000, 0x1000); + DmaClear32(3, subStruct.field_4, 0x800); + + if (!IsContest()) + REG_BG1CNT_BITFIELD.charBaseBlock = 0; + + REG_BG1CNT_BITFIELD.priority = 1; + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_812DEAC(struct Sprite *sprite) +{ + s16 var0; + u8 spriteId1; + u8 spriteId2; + + var0 = Random(); + var0 &= 0x3F; + if (var0 > 31) + var0 = 32 - var0; + + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0) + var0; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + 32; + sprite->data[1] = gBattleAnimArgs[0]; + sprite->data[2] = gBattleAnimArgs[1]; + + spriteId1 = CreateSprite(&gBattleAnimSpriteTemplate_84025EC, sprite->pos1.x, sprite->pos1.y, sprite->subpriority + 1); + spriteId2 = CreateSprite(&gBattleAnimSpriteTemplate_84025EC, sprite->pos1.x, sprite->pos1.y, sprite->subpriority + 1); + StartSpriteAnim(&gSprites[spriteId1], 1); + StartSpriteAnim(&gSprites[spriteId2], 2); + + gSprites[spriteId1].data[1] = gBattleAnimArgs[0]; + gSprites[spriteId1].data[2] = gBattleAnimArgs[1]; + gSprites[spriteId2].data[1] = gBattleAnimArgs[0]; + gSprites[spriteId2].data[2] = gBattleAnimArgs[1]; + gSprites[spriteId1].data[7] = -1; + gSprites[spriteId2].data[7] = -1; + gSprites[spriteId1].invisible = 1; + gSprites[spriteId2].invisible = 1; + gSprites[spriteId1].callback = sub_812E0F8; + gSprites[spriteId2].callback = sub_812E0F8; + + sprite->data[6] = spriteId1; + sprite->data[7] = spriteId2; + sprite->callback = sub_812DFEC; +} + +static void sub_812DFEC(struct Sprite *sprite) +{ + int var0; + s8 var1; + + var0 = (u16)sprite->data[2] + (u16)sprite->data[3]; + var1 = var0 >> 8; + sprite->pos2.y -= var1; + sprite->data[3] = var0 & 0xFF; + if (sprite->data[4] == 0 && sprite->pos2.y < -8) + { + gSprites[sprite->data[6]].invisible = 0; + sprite->data[4]++; + } + + if (sprite->data[4] == 1 && sprite->pos2.y < -16) + { + gSprites[sprite->data[7]].invisible = 0; + sprite->data[4]++; + } + + if (--sprite->data[1] == -1) + { + sprite->invisible = 1; + sprite->callback = sub_812E09C; + } +} + +static void sub_812E09C(struct Sprite *sprite) +{ + if (gSprites[sprite->data[6]].callback == SpriteCallbackDummy + && gSprites[sprite->data[7]].callback == SpriteCallbackDummy) + { + DestroySprite(&gSprites[sprite->data[6]]); + DestroySprite(&gSprites[sprite->data[7]]); + DestroyAnimSprite(sprite); + } +} + +static void sub_812E0F8(struct Sprite *sprite) +{ + u16 d2; + register u16 d3 asm("r1"); + int var0; + s8 var1; + + if (!sprite->invisible) + { + d2 = sprite->data[2]; + d3 = sprite->data[3]; + var0 = d2 + d3; + var1 = var0 >> 8; + sprite->pos2.y -= var1; + sprite->data[3] = var0 & 0xFF; + if (--sprite->data[1] == -1) + { + sprite->invisible = 1; + sprite->callback = SpriteCallbackDummy; + } + } +} + +void sub_812E14C(u8 taskId) +{ + struct Struct_sub_8078914 subStruct; + + switch (gTasks[taskId].data[0]) + { + case 0: + REG_BLDCNT = BLDCNT_TGT2_BD | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BG0 | BLDCNT_TGT2_BG1 + | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT1_BG1; + REG_BLDALPHA = 0xD03; + REG_BG1CNT_BITFIELD.screenSize = 0; + REG_BG1CNT_BITFIELD.priority = 1; + + if (!IsContest()) + REG_BG1CNT_BITFIELD.charBaseBlock = 1; + + sub_8078914(&subStruct); + DmaClear32(3, subStruct.field_4, 0x1000); + LZDecompressVram(gUnknown_08D2AA98, subStruct.field_4); + LZDecompressVram(gUnknown_08D2A9E0, subStruct.field_0); + LoadCompressedPalette(gUnknown_08D2AA80, subStruct.field_8 * 16, 32); + + if (IsContest()) + { + sub_80763FC(subStruct.field_8, (u16 *)subStruct.field_4, 0, 0); + gBattle_BG1_X = -56; + gBattle_BG1_Y = 0; + } + else + { + u8 position = GetBattlerPosition(gBattleAnimTarget); + if (IsDoubleBattle() == TRUE) + { + if (position == B_POSITION_OPPONENT_LEFT) + gBattle_BG1_X = -155; + if (position == B_POSITION_OPPONENT_RIGHT) + gBattle_BG1_X = -115; + if (position == B_POSITION_PLAYER_LEFT) + gBattle_BG1_X = 14; + if (position == B_POSITION_PLAYER_RIGHT) + gBattle_BG1_X = -20; + } + else + { + if (position == B_POSITION_OPPONENT_LEFT) + gBattle_BG1_X = -135; + if (position == B_POSITION_PLAYER_LEFT) + gBattle_BG1_X = -10; + } + + gBattle_BG1_Y = 0; + } + + gTasks[taskId].data[10] = gBattle_BG1_X; + gTasks[taskId].data[11] = gBattle_BG1_Y; + gTasks[taskId].data[0]++; + break; + case 1: + gTasks[taskId].data[3] = 0; + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT) + gBattle_BG1_X = gTasks[taskId].data[10] + gUnknown_08402604[gTasks[taskId].data[2]]; + else + gBattle_BG1_X = gTasks[taskId].data[10] - gUnknown_08402604[gTasks[taskId].data[2]]; + + if (++gTasks[taskId].data[2] == 5) + gTasks[taskId].data[0] = 5; + else + gTasks[taskId].data[0]++; + break; + case 2: + if (--gTasks[taskId].data[1] <= 4) + gTasks[taskId].data[1] = 5; + + REG_BLDALPHA = (gTasks[taskId].data[1] << 8) | 3; + if (gTasks[taskId].data[1] == 5) + gTasks[taskId].data[0]++; + break; + case 3: + if (++gTasks[taskId].data[3] > gUnknown_08402608[gTasks[taskId].data[2]]) + gTasks[taskId].data[0]++; + break; + case 4: + if (++gTasks[taskId].data[1] > 13) + gTasks[taskId].data[1] = 13; + + REG_BLDALPHA = (gTasks[taskId].data[1] << 8) | 3; + if (gTasks[taskId].data[1] == 13) + gTasks[taskId].data[0] = 1; + break; + case 5: + sub_8078914(&subStruct); + DmaClear32(3, subStruct.field_4, 0x800); + + if (!IsContest()) + REG_BG1CNT_BITFIELD.charBaseBlock = 0; + + REG_BG1CNT_BITFIELD.priority = 1; + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + DestroyAnimVisualTask(taskId); + break; + } +} + +void sub_812E498(u8 taskId) +{ + if (gTasks[taskId].data[0] == 0) + { + PrepareAffineAnimInTaskData(&gTasks[taskId], GetAnimBattlerSpriteId(0), &gUnknown_08402610); + gTasks[taskId].data[0]++; + } + else + { + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + { + DestroyAnimVisualTask(taskId); + } + } +} + +static void sub_812E4F0(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + InitAnimSpritePos(sprite, 0); + sprite->data[0]++; + } + else if (sprite->data[0]++ > 20) + { + sprite->data[1] += 160; + sprite->data[2] += 128; + + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->pos2.x = -(sprite->data[1] >> 8); + else + sprite->pos2.x = sprite->data[1] >> 8; + + sprite->pos2.y += sprite->data[2] >> 8; + if (sprite->pos2.y > 64) + DestroyAnimSprite(sprite); + } +} + +void sub_812E568(u8 taskId) +{ + u8 side; + struct Task *task = &gTasks[taskId]; + + if (gBattleAnimArgs[1] == 0) + { + DestroyAnimVisualTask(taskId); + return; + } + + if (gBattleAnimArgs[2] < 0) + gBattleAnimArgs[2] = 0; + if (gBattleAnimArgs[2] > 2) + gBattleAnimArgs[2] = 2; + + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 8 - (2 * gBattleAnimArgs[2]); + task->data[4] = 0x100 + (gBattleAnimArgs[2] * 128); + task->data[5] = gBattleAnimArgs[2] + 2; + task->data[6] = gBattleAnimArgs[1] - 1; + task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + + if (gBattleAnimArgs[0] == 0) + side = GetBattlerSide(gBattleAnimAttacker); + else + side = GetBattlerSide(gBattleAnimTarget); + + if (side == B_SIDE_OPPONENT) + { + task->data[4] *= -1; + task->data[5] *= -1; + } + + PrepareBattlerSpriteForRotScale(task->data[15], 0); + task->func = sub_812E638; +} + +static void sub_812E638(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + gSprites[task->data[15]].pos2.x += task->data[5]; + task->data[2] -= task->data[4]; + obj_id_set_rotscale(task->data[15], 0x100, 0x100, task->data[2]); + sub_8078F9C(task->data[15]); + if (++task->data[1] >= task->data[3]) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 1: + gSprites[task->data[15]].pos2.x -= task->data[5]; + task->data[2] += task->data[4]; + obj_id_set_rotscale(task->data[15], 0x100, 0x100, task->data[2]); + sub_8078F9C(task->data[15]); + if (++task->data[1] >= task->data[3] * 2) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 2: + gSprites[task->data[15]].pos2.x += task->data[5]; + task->data[2] -= task->data[4]; + obj_id_set_rotscale(task->data[15], 0x100, 0x100, task->data[2]); + sub_8078F9C(task->data[15]); + if (++task->data[1] >= task->data[3]) + { + if (task->data[6]) + { + task->data[6]--; + task->data[1] = 0; + task->data[0] = 0; + } + else + { + task->data[0]++; + } + } + break; + case 3: + sub_8078F40(task->data[15]); + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_812E7A0(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + sprite->pos1.x = 0; + sprite->pos1.y = gBattleAnimArgs[0]; + } + else + { + sprite->pos1.x = 240; + sprite->pos1.y = gBattleAnimArgs[0] - 30; + } + + sprite->data[2] = gBattleAnimArgs[2]; + StartSpriteAnim(sprite, gBattleAnimArgs[1]); + sprite->callback = sub_812E7F0; +} + +static void sub_812E7F0(struct Sprite *sprite) +{ + sprite->data[0] += 3; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + sprite->pos1.x += 5; + sprite->pos1.y -= 1; + + if (sprite->pos1.x > 240) + DestroyAnimSprite(sprite); + + sprite->pos2.y = Sin(sprite->data[0] & 0xFF, 16); + } + else + { + sprite->pos1.x -= 5; + sprite->pos1.y += 1; + + if (sprite->pos1.x < 0) + DestroyAnimSprite(sprite); + + sprite->pos2.y = Cos(sprite->data[0] & 0xFF, 16); + } +} + +void sub_812E860(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 0; + task->data[12] = 0x20; + task->data[13] = 0x40; + task->data[14] = 0x800; + task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + + PrepareBattlerSpriteForRotScale(task->data[15], 0); + task->func = sub_812E8B4; +} + +static void sub_812E8B4(u8 taskId) +{ + int temp; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + task->data[2] += 0x200; + if (task->data[2] >= task->data[14]) + { + s16 diff = task->data[14] - task->data[2]; + s16 div = diff / (task->data[14] * 2); + s16 mod = diff % (task->data[14] * 2); + + if ((div & 1) == 0) + { + task->data[2] = task->data[14] - mod; + task->data[0] = 1; + } + else + { + task->data[2] = mod - task->data[14]; + } + } + break; + case 1: + task->data[2] -= 0x200; + if (task->data[2] <= -task->data[14]) + { + s16 diff = task->data[14] - task->data[2]; + s16 div = diff / (task->data[14] * 2); + s16 mod = diff % (task->data[14] * 2); + + if ((1 & div) == 0) + { + task->data[2] = mod - task->data[14]; + task->data[0] = 0; + } + else + { + task->data[2] = task->data[14] - mod; + } + } + break; + case 2: + sub_8078F40(task->data[15]); + DestroyAnimVisualTask(taskId); + return; + } + + obj_id_set_rotscale(task->data[15], 0x100, 0x100, task->data[2]); + sub_8078F9C(task->data[15]); + gSprites[task->data[15]].pos2.x = -(((temp = task->data[2]) >= 0 ? task->data[2] : temp + 63) >> 6); + + if (++task->data[1] > 8) + { + if (task->data[12]) + { + task->data[12]--; + task->data[14] -= task->data[13]; + if (task->data[14] < 16) + task->data[14] = 16; + } + else + { + task->data[0] = 2; + } + } +} + +static void sub_812EA4C(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + if (gBattleAnimArgs[2] == 0) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + } + + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[1] = 0x80; + sprite->data[2] = 0x300; + sprite->data[3] = gBattleAnimArgs[1]; + sprite->data[0]++; + } + else + { + sprite->pos2.x = sprite->data[1] >> 8; + sprite->pos2.y += sprite->data[2] >> 8; + if (sprite->data[4] == 0 && sprite->pos2.y > -sprite->data[3]) + { + sprite->data[4] = 1; + sprite->data[2] = (-sprite->data[2] / 3) * 2; + } + + sprite->data[1] += 192; + sprite->data[2] += 128; + if (sprite->animEnded) + DestroyAnimSprite(sprite); + } +} + +void sub_812EB10(u8 taskId) +{ + u8 spriteId; + + if (gTasks[taskId].data[0] == 0) + { + if (gBattleAnimArgs[0] == 0) + gTasks[taskId].data[11] = gBattleAnimAttacker; + else + gTasks[taskId].data[11] = gBattleAnimTarget; + + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + gTasks[taskId].data[10] = spriteId; + PrepareBattlerSpriteForRotScale(spriteId, 0); + + switch (gBattleAnimArgs[1]) + { + case 0: + obj_id_set_rotscale(spriteId, 0xE0, 0x140, 0); + sub_8079A64(spriteId); + break; + case 1: + obj_id_set_rotscale(spriteId, 0xD0, 0x130, 0xF00); + sub_8079A64(spriteId); + if (IsContest() || GetBattlerSide(gTasks[taskId].data[11]) == B_SIDE_PLAYER) + gSprites[spriteId].pos2.y += 16; + break; + case 2: + obj_id_set_rotscale(spriteId, 0xD0, 0x130, 0xF100); + sub_8079A64(spriteId); + if (IsContest() || GetBattlerSide(gTasks[taskId].data[11]) == B_SIDE_PLAYER) + gSprites[spriteId].pos2.y += 16; + break; + } + + gSprites[spriteId].pos2.x = 2; + gTasks[taskId].data[0]++; + } + else + { + spriteId = gTasks[taskId].data[10]; + if (++gTasks[taskId].data[2] == 3) + { + gTasks[taskId].data[2] = 0; + gSprites[spriteId].pos2.x = -gSprites[spriteId].pos2.x; + } + + if (++gTasks[taskId].data[1] == 13) + { + sub_8078F40(spriteId); + gSprites[spriteId].pos2.x = 0; + gSprites[spriteId].pos2.y = 0; + DestroyAnimVisualTask(taskId); + } + } +} + +static void sub_812EC78(struct Sprite *sprite) +{ + u8 tileOffset; + int rand1; + int rand2; + + tileOffset = Random() % 12; + sprite->oam.tileNum += tileOffset; + rand1 = Random() & 0x1FF; + rand2 = Random() & 0xFF; + + if (rand1 & 1) + sprite->data[0] = 0x5E0 + rand1; + else + sprite->data[0] = 0x5E0 - rand1; + + if (rand2 & 1) + sprite->data[1] = 0x480 + rand2; + else + sprite->data[1] = 0x480 - rand2; + + sprite->data[2] = gBattleAnimArgs[0]; + if (sprite->data[2] == 0) + sprite->pos1.x = -8; + else + sprite->pos1.x = 248; + + sprite->pos1.y = 104; + sprite->callback = sub_812ED24; +} + +static void sub_812ED24(struct Sprite *sprite) +{ + if (sprite->data[2] == 0) + { + sprite->pos2.x += sprite->data[0] >> 8; + sprite->pos2.y -= sprite->data[1] >> 8; + } + else + { + sprite->pos2.x -= sprite->data[0] >> 8; + sprite->pos2.y -= sprite->data[1] >> 8; + } + + sprite->data[0] -= 22; + sprite->data[1] -= 48; + if (sprite->data[0] < 0) + sprite->data[0] = 0; + + if (++sprite->data[3] == 31) + DestroyAnimSprite(sprite); +} + +static void sub_812ED84(struct Sprite *sprite) +{ + REG_WINOUT = 0x1F3F; + REG_DISPCNT |= DISPCNT_OBJWIN_ON; + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + REG_WIN0H = 0; + REG_WIN0V = 0; + + sprite->data[0] = gBattleAnimArgs[2]; + sub_8078764(sprite, FALSE); + sprite->oam.objMode = ST_OAM_OBJ_WINDOW; + sprite->invisible = 1; + sprite->callback = sub_812EE00; +} + +static void sub_812EE00(struct Sprite *sprite) +{ + switch (sprite->data[1]) + { + case 0: + sprite->invisible = 0; + if (sprite->affineAnimEnded) + sprite->data[1]++; + break; + case 1: + if (--sprite->data[0] == 0) + { + ChangeSpriteAffineAnim(sprite, 1); + sprite->data[1]++; + } + break; + case 2: + if (sprite->affineAnimEnded) + { + sprite->invisible = 1; + sprite->data[1]++; + } + break; + case 3: + REG_WINOUT = 0x3F3F; + REG_DISPCNT ^= DISPCNT_OBJWIN_ON; + DestroyAnimSprite(sprite); + break; + } +} + +static void sub_812EEA4(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->data[0] = gBattleAnimArgs[0]; + sprite->data[1] = gBattleAnimArgs[1]; + sprite->callback = sub_812EEEC; + sprite->callback(sprite); +} + +static void sub_812EEEC(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->data[1], sprite->data[2] >> 8); + sprite->pos2.y = Cos(sprite->data[1], sprite->data[3] >> 8); + sprite->data[1] = (sprite->data[1] + 9) & 0xFF; + + if ((u16)sprite->data[1] < 64 || sprite->data[1] > 195) + sprite->subpriority = GetBattlerSubpriority(gBattleAnimAttacker) - 1; + else + sprite->subpriority = GetBattlerSubpriority(gBattleAnimAttacker) + 1; + + if (sprite->data[5] == 0) + { + sprite->data[2] += 0x400; + sprite->data[3] += 0x100; + sprite->data[4]++; + if (sprite->data[4] == sprite->data[0]) + { + sprite->data[4] = 0; + sprite->data[5] = 1; + } + } + else if (sprite->data[5] == 1) + { + sprite->data[2] -= 0x400; + sprite->data[3] -= 0x100; + sprite->data[4]++; + if (sprite->data[4] == sprite->data[0]) + DestroyAnimSprite(sprite); + } +} + +// Copies the target mon's sprite, and makes a white silhouette that shrinks away. +void AnimTask_RolePlaySilhouette(u8 taskId) +{ + u8 isBackPic; + u32 personality; + u32 otId; + u16 species; + s16 xOffset; + u32 priority; + u8 spriteId; + s16 coord1, coord2; + + GetAnimBattlerSpriteId(ANIM_BATTLER_ATTACKER); + if (IsContest()) + { + isBackPic = 1; + personality = eWRAM_19348Struct->personality; + otId = eWRAM_19348Struct->otId; + species = eWRAM_19348Struct->species; + xOffset = 20; + priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker); + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + isBackPic = 0; + personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY); + otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID); + if (eTransformStatuses[gBattleAnimTarget].species == SPECIES_NONE) + { + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES); + else + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES); + } + else + { + species = eTransformStatuses[gBattleAnimTarget].species; + } + + xOffset = 20; + priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker); + } + else + { + isBackPic = 1; + personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_PERSONALITY); + otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_OT_ID); + if (eTransformStatuses[gBattleAnimTarget].species == SPECIES_NONE) + { + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES); + else + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimTarget]], MON_DATA_SPECIES); + } + else + { + species = eTransformStatuses[gBattleAnimTarget].species; + } + + xOffset = -20; + priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker); + } + } + + coord1 = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + coord2 = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); + spriteId = sub_8079F44(species, isBackPic, 0, coord1 + xOffset, coord2, 5, personality, otId); + + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].oam.objMode = ST_OAM_OBJ_BLEND; + FillPalette(RGB_WHITE, (gSprites[spriteId].oam.paletteNum << 4) + 0x100, 32); + gSprites[spriteId].oam.priority = priority; + REG_BLDCNT = BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL; + REG_BLDALPHA = BLDALPHA_BLEND(gTasks[taskId].data[1], 16 - gTasks[taskId].data[1]); + + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].func = AnimTask_RolePlaySilhouetteStep1; +} + +static void AnimTask_RolePlaySilhouetteStep1(u8 taskId) +{ + if (gTasks[taskId].data[10]++ > 1) + { + gTasks[taskId].data[10] = 0; + gTasks[taskId].data[1]++; + REG_BLDALPHA = ((16 - gTasks[taskId].data[1]) << 8) | gTasks[taskId].data[1]; + if (gTasks[taskId].data[1] == 10) + { + gTasks[taskId].data[10] = 256; + gTasks[taskId].data[11] = 256; + gTasks[taskId].func = sub_812F290; + } + } +} + +static void sub_812F290(u8 taskId) +{ + u8 spriteId = gTasks[taskId].data[0]; + gTasks[taskId].data[10] -= 16; + gTasks[taskId].data[11] += 128; + gSprites[spriteId].oam.affineMode |= 2; + sub_8078FDC(&gSprites[spriteId], 1, gTasks[taskId].data[10], gTasks[taskId].data[11], 0); + if (++gTasks[taskId].data[12] == 9) + { + sub_8079098(&gSprites[spriteId]); + DestroySpriteAndFreeResources_(&gSprites[spriteId]); + gTasks[taskId].func = sub_8078634; + } +} + +void sub_812F314(u8 taskId) +{ + u8 battler; + u16 bgX, bgY; + s16 y, i; + struct ScanlineEffectParams scanlineParams; + struct Task *task = &gTasks[taskId]; + + if (gBattleAnimArgs[0] == 0) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 16; + task->data[4] = 0; + task->data[5] = battler; + task->data[6] = 32; + task->data[7] = 0; + task->data[8] = 24; + + if (GetBattlerSide(battler) == B_SIDE_OPPONENT) + task->data[8] *= -1; + + task->data[13] = sub_8077FC0(battler) - 34; + if (task->data[13] < 0) + task->data[13] = 0; + + task->data[14] = task->data[13] + 66; + task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + if (GetBattlerPosition_permutated(battler) == 1) + { + scanlineParams.dmaDest = ®_BG1HOFS; + REG_BLDCNT = 0x3F42; + bgX = gBattle_BG1_X; + bgY = gBattle_BG1_Y; + } + else + { + scanlineParams.dmaDest = ®_BG2HOFS; + REG_BLDCNT = 0x3F44; + bgX = gBattle_BG2_X; + bgY = gBattle_BG2_Y; + } + + for (y = 0, i = 0; y < 160; y++, i += 2) + { + gScanlineEffectRegBuffers[0][i] = bgX; + gScanlineEffectRegBuffers[1][i] = bgX; + gScanlineEffectRegBuffers[0][i + 1] = bgY; + gScanlineEffectRegBuffers[1][i + 1] = bgY; + } + + scanlineParams.dmaControl = 0xA6600001; + scanlineParams.initState = 1; + scanlineParams.unused9 = 0; + ScanlineEffect_SetParams(scanlineParams); + task->func = sub_812F474; +} + +static void sub_812F474(u8 taskId) +{ + struct Task *task; + s16 var1; + s16 var2; + s16 bgX, bgY; + s16 offset; + s16 var0; + s16 i; + s16 sineIndex; + s16 var3; + + task = &gTasks[taskId]; + if (GetBattlerPosition_permutated(task->data[5]) == 1) + { + bgX = gBattle_BG1_X; + bgY = gBattle_BG1_Y; + } + else + { + bgX = gBattle_BG2_X; + bgY = gBattle_BG2_Y; + } + + switch (task->data[0]) + { + case 0: + offset = task->data[14] * 2; + var1 = 0; + var2 = 0; + i = 0; + task->data[1] = (task->data[1] + 2) & 0xFF; + sineIndex = task->data[1]; + task->data[9] = 0x7E0 / task->data[6]; + task->data[10] = -((task->data[7] * 2) / task->data[9]); + task->data[11] = task->data[7]; + var3 = task->data[11] >> 5; + task->data[12] = var3; + var0 = task->data[14]; + while (var0 > task->data[13]) + { + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][offset + 1] = (i - var2) + bgY; + gScanlineEffectRegBuffers[gScanlineEffect.srcBuffer][offset] = bgX + var3 + (gSineTable[sineIndex] >> 5); + sineIndex = (sineIndex + 10) & 0xFF; + task->data[11] += task->data[10]; + var3 = task->data[11] >> 5; + task->data[12] = var3; + + i++; + offset -= 2; + var1 += task->data[6]; + var2 = var1 >> 5; + var0--; + } + + var0 *= 2; + while (var0 >= 0) + { + gScanlineEffectRegBuffers[0][var0] = bgX + 240; + gScanlineEffectRegBuffers[1][var0] = bgX + 240; + var0 -= 2; + } + + if (++task->data[6] > 63) + { + task->data[6] = 64; + task->data[2]++; + if (task->data[2] & 1) + task->data[3]--; + else + task->data[4]++; + + REG_BLDALPHA = (task->data[4] << 8) | task->data[3]; + if (task->data[3] == 0 && task->data[4] == 16) + { + task->data[2] = 0; + task->data[3] = 0; + task->data[0]++; + } + } + else + { + task->data[7] += task->data[8]; + } + break; + case 1: + if (++task->data[2] > 12) + { + gScanlineEffect.state = 3; + task->data[2] = 0; + task->data[0]++; + } + break; + case 2: + task->data[2]++; + if (task->data[2] & 1) + task->data[3]++; + else + task->data[4]--; + + REG_BLDALPHA = (task->data[4] << 8) | task->data[3]; + if (task->data[3] == 16 && task->data[4] == 0) + { + task->data[2] = 0; + task->data[3] = 0; + task->data[0]++; + } + break; + case 3: + DestroyAnimVisualTask(taskId); + break; + } +} + +void sub_812F724(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + task->data[0] = 0; + task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + PrepareAffineAnimInTaskData(&gTasks[taskId], task->data[15], &gUnknown_08402750); + task->func = sub_812F76C; +} + +static void sub_812F76C(u8 taskId) +{ + u16 var0; + + struct Task *task = &gTasks[taskId]; + var0 = task->data[0]; + task->data[0]++; + var0 -= 20; + if (var0 < 23) + { + if (++task->data[1] > 1) + { + task->data[1] = 0; + task->data[2]++; + if (task->data[2] & 1) + gSprites[task->data[15]].pos2.x = 1; + else + gSprites[task->data[15]].pos2.x = -1; + } + } + else + { + gSprites[task->data[15]].pos2.x = 0; + } + + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + DestroyAnimVisualTask(taskId); +} + +static void sub_812F804(struct Sprite *sprite, s16 b, s16 c, s16 d, s16 e, u16 f) +{ + sprite->pos1.x = b; + sprite->pos1.y = c; + sprite->data[4] = b << 4; + sprite->data[5] = c << 4; + sprite->data[6] = ((d - b) << 4) / f; + sprite->data[7] = ((e - c) << 4) / f; +} + +void sub_812F86C(struct Sprite *sprite) +{ + sprite->data[4] += sprite->data[6]; + sprite->data[5] += sprite->data[7]; + sprite->pos1.x = sprite->data[4] >> 4; + sprite->pos1.y = sprite->data[5] >> 4; +} + +static void sub_812F88C(struct Sprite *sprite) +{ + s16 x = sprite->pos1.x; + s16 y = sprite->pos1.y; + + sub_8078650(sprite); + StartSpriteAffineAnim(sprite, gBattleAnimArgs[0]); + sub_812F804(sprite, sprite->pos1.x, sprite->pos1.y, x, y, 64); + sprite->data[0] = 0; + sprite->callback = sub_812F8DC; +} + +static void sub_812F8DC(struct Sprite *sprite) +{ + int index; + + sprite->data[0]++; + index = (sprite->data[0] * 8) & 0xFF; + sub_812F86C(sprite); + sprite->pos2.y = Sin(index, 8); + if (sprite->data[0] > 58) + { + if (++sprite->data[1] > 1) + { + sprite->data[1] = 0; + sprite->data[2]++; + sprite->invisible = sprite->data[2] & 1; + if (sprite->data[2] > 3) + DestroySpriteAndMatrix(sprite); + } + } +} + +static void sub_812F948(struct Sprite *sprite) +{ + sprite->data[0] = gBattleAnimArgs[3]; + StartSpriteAffineAnim(sprite, gBattleAnimArgs[0]); + if (GetBattlerSide(gBattleAnimTarget) != B_SIDE_PLAYER) + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + gBattleAnimArgs[1]; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) + gBattleAnimArgs[2]; + sprite->callback = sub_80DA48C; +} + +static void sub_812F9B0(u8 taskId) +{ + u16 var0 = 0; + u16 var1 = 0; + + gTasks[taskId].data[0]--; + if ((gTasks[taskId].data[6] & 0x8000) && (--gTasks[taskId].data[1] == -1)) + { + if (gTasks[taskId].data[9] == 0) + { + gTasks[taskId].data[9] = gTasks[taskId].data[4]; + gTasks[taskId].data[4] = -gTasks[taskId].data[4]; + } + else + { + gTasks[taskId].data[9] = 0; + } + + if (gTasks[taskId].data[10] == 0) + { + gTasks[taskId].data[10] = gTasks[taskId].data[5]; + gTasks[taskId].data[5] = -gTasks[taskId].data[5]; + } + else + { + gTasks[taskId].data[10] = 0; + } + + gTasks[taskId].data[1] = gTasks[taskId].data[13]; + } + + var0 = gTasks[taskId].data[7]; + var1 = gTasks[taskId].data[8]; + if (gTasks[taskId].data[2] & 0x8000) + gSprites[gTasks[taskId].data[15]].pos2.x = gTasks[taskId].data[9] - (var0 >> 8); + else + gSprites[gTasks[taskId].data[15]].pos2.x = gTasks[taskId].data[9] + (var0 >> 8); + + if (gTasks[taskId].data[3] & 0x8000) + gSprites[gTasks[taskId].data[15]].pos2.y = gTasks[taskId].data[10] - (var1 >> 8); + else + gSprites[gTasks[taskId].data[15]].pos2.y = gTasks[taskId].data[10] + (var1 >> 8); + + if (gTasks[taskId].data[0] < 1) + { + DestroyTask(taskId); + gAnimVisualTaskCount--; + } +} + +static void sub_812FAF8(u8 taskId) +{ + u16 var0 = 0; + u16 var1 = 0; + + gTasks[taskId].data[0]--; + if ((gTasks[taskId].data[6] & 0x8000) && (--gTasks[taskId].data[1] == -1)) + { + if (gTasks[taskId].data[9] == 0) + { + gTasks[taskId].data[9] = gTasks[taskId].data[4]; + gTasks[taskId].data[4] = -gTasks[taskId].data[4]; + } + else + { + gTasks[taskId].data[9] = var0; + } + + if (gTasks[taskId].data[10] == 0) + { + gTasks[taskId].data[10] = gTasks[taskId].data[5]; + gTasks[taskId].data[5] = -gTasks[taskId].data[5]; + } + else + { + gTasks[taskId].data[10] = 0; + } + + gTasks[taskId].data[1] = gTasks[taskId].data[13]; + } + + var0 = (gTasks[taskId].data[2] & 0x7FFF) + gTasks[taskId].data[7]; + var1 = (gTasks[taskId].data[3] & 0x7FFF) + gTasks[taskId].data[8]; + if (gTasks[taskId].data[2] & 0x8000) + gSprites[gTasks[taskId].data[15]].pos2.x = gTasks[taskId].data[9] - (var0 >> 8); + else + gSprites[gTasks[taskId].data[15]].pos2.x = gTasks[taskId].data[9] + (var0 >> 8); + + if (gTasks[taskId].data[3] & 0x8000) + gSprites[gTasks[taskId].data[15]].pos2.y = gTasks[taskId].data[10] - (var1 >> 8); + else + gSprites[gTasks[taskId].data[15]].pos2.y = gTasks[taskId].data[10] + (var1 >> 8); + + gTasks[taskId].data[7] = var0; + gTasks[taskId].data[8] = var1; + if (gTasks[taskId].data[0] < 1) + { + gTasks[taskId].data[0] = 30; + gTasks[taskId].data[13] = 0; + gTasks[taskId].func = sub_812F9B0; + } +} + +void sub_812FC68(u8 taskId) +{ + gTasks[taskId].data[15] = gBankSpriteIds[gBattleAnimAttacker]; + gTasks[taskId].data[14] = gBattleAnimArgs[0]; + gTasks[taskId].data[0] = gBattleAnimArgs[0]; + gTasks[taskId].data[13] = gBattleAnimArgs[6]; + if (gBattleAnimArgs[3]) + gTasks[taskId].data[6] = gTasks[taskId].data[6] | -0x8000; + + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + gTasks[taskId].data[2] = gBattleAnimArgs[1]; + gTasks[taskId].data[3] = gBattleAnimArgs[2]; + } + else + { + if (gBattleAnimArgs[1] & 0x8000) + gTasks[taskId].data[2] = gBattleAnimArgs[1] & 0x7FFF; + else + gTasks[taskId].data[2] = gBattleAnimArgs[1] | -0x8000; + + if (gBattleAnimArgs[2] & 0x8000) + gTasks[taskId].data[3] = gBattleAnimArgs[2] & 0x7FFF; + else + gTasks[taskId].data[3] = gBattleAnimArgs[2] | -0x8000; + } + + gTasks[taskId].data[8] = 0; + gTasks[taskId].data[7] = 0; + gTasks[taskId].data[4] = gBattleAnimArgs[4]; + gTasks[taskId].data[5] = gBattleAnimArgs[5]; + gTasks[taskId].func = sub_812FAF8; +} + +void sub_812FD7C(u8 taskId) +{ + u8 battler; + struct Task *task = &gTasks[taskId]; + + if (gBattleAnimArgs[1] == 0) + DestroyAnimVisualTask(taskId); + + task->data[0] = 0; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = gBattleAnimArgs[1]; + if (gBattleAnimArgs[0] == 0) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + + task->data[4] = GetBattlerSpriteCoord(battler, 0); + task->data[5] = GetBattlerSpriteCoord(battler, 1); + task->data[6] = GetBattlerSubpriority(battler); + task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + PrepareAffineAnimInTaskData(task, task->data[15], &gUnknown_084028AC); + task->func = sub_812FE20; +} + +static void sub_812FE20(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] == 6) + sub_812FEB8(taskId, TRUE); + + if (task->data[1] == 18) + sub_812FEB8(taskId, FALSE); + + if (!RunAffineAnimFromTaskData(task)) + { + if (--task->data[3] == 0) + { + task->data[0]++; + } + else + { + task->data[1] = 0; + PrepareAffineAnimInTaskData(task, task->data[15], &gUnknown_084028AC); + } + } + break; + case 1: + if (task->data[2] == 0) + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_812FEB8(u8 taskId, bool8 arg1) +{ + u8 i; + s8 xOffset, yOffset; + struct Task *task; + s16 xCoords[4]; + s16 yCoords[2]; + + task = &gTasks[taskId]; + if (!arg1) + { + xOffset = 18; + yOffset = -20; + } + else + { + xOffset = 30; + yOffset = 20; + } + + xCoords[0] = task->data[4] - xOffset; + xCoords[1] = task->data[4] - xOffset - 4; + xCoords[2] = task->data[4] + xOffset; + xCoords[3] = task->data[4] + xOffset + 4; + yCoords[0] = task->data[5] + yOffset; + yCoords[1] = task->data[5] + yOffset + 6; + + for (i = 0; i < 4; i++) + { + u8 spriteId = CreateSprite(&gSpriteTemplate_84028CC, xCoords[i], yCoords[i & 1], task->data[6] - 5); + if (spriteId != MAX_SPRITES) + { + gSprites[spriteId].data[0] = 0; + gSprites[spriteId].data[1] = i < 2 ? -2 : 2; + gSprites[spriteId].data[2] = -1; + gSprites[spriteId].data[3] = taskId; + gSprites[spriteId].data[4] = 2; + task->data[2]++; + } + } +} + +static void sub_812FF94(struct Sprite *sprite) +{ + sprite->pos1.x += sprite->data[1]; + sprite->pos1.y += sprite->data[2]; + if (++sprite->data[0] > 6) + { + gTasks[sprite->data[3]].data[sprite->data[4]]--; + DestroySprite(sprite); + } +} + +void sub_812FFE4(u8 taskId) +{ + u8 spriteId; + + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + gTasks[taskId].data[2] = 0x100 + gSprites[spriteId].oam.paletteNum * 16; + gTasks[taskId].func = sub_813003C; +} + +static void sub_813003C(u8 taskId) +{ + if (gTasks[taskId].data[1]) + { + BlendPalette(gTasks[taskId].data[2], 16, 8, gUnknown_084028E4[gTasks[taskId].data[0]]); + if (++gTasks[taskId].data[0] > 23) + gTasks[taskId].data[0] = 0; + + gTasks[taskId].data[1]--; + } + else + { + BlendPalette(gTasks[taskId].data[2], 16, 0, RGB(0, 0, 0)); + DestroyAnimVisualTask(taskId); + } +} + +void sub_81300A4(u8 taskId) +{ + sub_80E3C4C( + taskId, + 0, + 0x1A0, + gBattleAnimAttacker, + gBattleAnimArgs[0], + 10, + 2, + 30, + gUnknown_08D2E014, + gUnknown_08D2E170, + gUnknown_08D2E150); +} + +static void sub_81300F4(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) + gBattleAnimArgs[0] = -gBattleAnimArgs[0]; + + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0) + gBattleAnimArgs[0]; + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + gBattleAnimArgs[1]; + if (gBattleAnimArgs[2] == 0) + { + sprite->data[0] = 640; + sprite->data[1] = -640; + } + else if (gBattleAnimArgs[2] == 1) + { + sprite->vFlip = 1; + sprite->data[0] = 640; + sprite->data[1] = 640; + } + else + { + StartSpriteAnim(sprite, 1); + sprite->data[0] = 640; + } + + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + sprite->data[0] = -sprite->data[0]; + sprite->hFlip = 1; + } + + sprite->callback = sub_81301B4; +} + +static void sub_81301B4(struct Sprite *sprite) +{ + sprite->data[6] += sprite->data[0]; + sprite->data[7] += sprite->data[1]; + sprite->pos2.x = sprite->data[6] >> 8; + sprite->pos2.y = sprite->data[7] >> 8; + if (++sprite->data[5] == 14) + DestroyAnimSprite(sprite); +} + +void sub_81301EC(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (IsContest()) + { + task->data[5] = 8; + task->data[6] = 3; + task->data[7] = 1; + } + else + { + task->data[5] = 12; + task->data[6] = 3; + task->data[7] = 0; + } + + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + task->data[11] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) + GetBattlerSpriteCoordAttr(gBattleAnimAttacker, 0) / 4; + else + task->data[11] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2) - GetBattlerSpriteCoordAttr(gBattleAnimAttacker, 0) / 4; + + task->data[12] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3) - GetBattlerSpriteCoordAttr(gBattleAnimAttacker, 0) / 4; + task->data[13] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + task->data[14] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + task->func = sub_81302E4; +} + +static void sub_81302E4(u8 taskId) +{ + u8 i; + s16 x, y; + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] > 3) + { + task->data[1] = 0; + sub_8130424( + task->data[11], + task->data[12], + task->data[13], + task->data[14], + task->data[5], + task->data[2], + &x, + &y); + + for (i = 0; i < 2; i++) + { + u8 spriteId = CreateSprite(&gSpriteTemplate_840294C, x, y, 35); + if (spriteId != MAX_SPRITES) + { + if (task->data[7] == 0) + { + if (i == 0) + gSprites[spriteId].pos2.x = gSprites[spriteId].pos2.y = -task->data[6]; + else + gSprites[spriteId].pos2.x = gSprites[spriteId].pos2.y = task->data[6]; + } + else + { + if (i == 0) + { + gSprites[spriteId].pos2.x = -task->data[6]; + gSprites[spriteId].pos2.y = task->data[6]; + } + else + { + gSprites[spriteId].pos2.x = task->data[6]; + gSprites[spriteId].pos2.y = -task->data[6]; + } + } + + gSprites[spriteId].data[0] = 0; + gSprites[spriteId].data[1] = taskId; + gSprites[spriteId].data[2] = 10; + task->data[10]++; + } + } + + if (task->data[2] == task->data[5]) + task->data[0]++; + + task->data[2]++; + } + break; + case 1: + if (task->data[10] == 0) + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_8130424(s16 arg0, s16 arg1, s16 arg2, s16 arg3, u8 arg4, u8 arg5, s16 *x, s16 *y) +{ + int x2; + int y2; + + if (arg5 == 0) + { + *x = arg0; + *y = arg1; + return; + } + + if (arg5 >= arg4) + { + *x = arg2; + *y = arg3; + return; + } + + arg4--; + x2 = (arg0 << 8) + arg5 * (((arg2 - arg0) << 8) / arg4); + y2 = (arg1 << 8) + arg5 * (((arg3 - arg1) << 8) / arg4); + *x = x2 >> 8; + *y = y2 >> 8; +} + +static void sub_81304DC(struct Sprite *sprite) +{ + if (++sprite->data[0] > 36) + { + gTasks[sprite->data[1]].data[sprite->data[2]]--; + DestroySprite(sprite); + } +} + +static void sub_813051C(struct Sprite *sprite) +{ + sprite->pos1.x = gBattleAnimArgs[0]; + sprite->pos1.y = gBattleAnimArgs[1]; + sprite->data[2] = gBattleAnimArgs[2]; + sprite->data[4] = gBattleAnimArgs[3]; + sprite->data[0] = gBattleAnimArgs[4]; + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); + sprite->callback = sub_8078CC0; +} + +void sub_8130554(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + task->data[11] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + task->data[12] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + task->data[13] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + task->data[14] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + GetBattlerSpriteCoordAttr(gBattleAnimTarget, 0) / 4; + task->data[15] = CreateSprite(&gSpriteTemplate_84029AC, task->data[11], task->data[12], GetBattlerSubpriority(gBattleAnimTarget) - 5); + if (task->data[15] != MAX_SPRITES) + { + gSprites[task->data[15]].data[0] = 16; + gSprites[task->data[15]].data[2] = task->data[13]; + gSprites[task->data[15]].data[4] = task->data[14]; + gSprites[task->data[15]].data[5] = -32; + InitAnimArcTranslation(&gSprites[task->data[15]]); + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) + StartSpriteAffineAnim(&gSprites[task->data[15]], 1); + + task->func = sub_81306A4; + } + else + { + DestroyAnimVisualTask(taskId); + } +} + +static void sub_81306A4(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] > 1) + { + task->data[1] = 0; + TranslateAnimArc(&gSprites[task->data[15]]); + if (++task->data[2] > 7) + task->data[0]++; + } + break; + case 1: + if (TranslateAnimArc(&gSprites[task->data[15]])) + { + task->data[1] = 0; + task->data[2] = 0; + task->data[0]++; + } + break; + case 2: + if (++task->data[1] > 1) + { + task->data[1] = 0; + task->data[2]++; + gSprites[task->data[15]].invisible = task->data[2] & 1; + if (task->data[2] == 16) + { + FreeOamMatrix(gSprites[task->data[15]].oam.matrixNum); + DestroySprite(&gSprites[task->data[15]]); + task->data[0]++; + } + } + break; + case 3: + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_81307B0(struct Sprite *sprite) +{ + u8 battler; + + if (gBattleAnimArgs[0] == 0) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + + sprite->oam.tileNum += 16; + sprite->data[6] = gBattleAnimArgs[2]; + sprite->data[7] = gBattleAnimArgs[1] == 0 ? -1 : 1; + sprite->pos1.y = GetBattlerSpriteCoord(battler, 3); + if (gBattleAnimArgs[1] == 0) + { + sprite->oam.matrixNum |= 0x8; + sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, 4) - 8; + } + else + { + sprite->pos1.x = GetBattlerSpriteCoordAttr(battler, 5) + 8; + } + + sprite->callback = sub_813085C; +} + +static void sub_813085C(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + if (++sprite->data[1] > 1) + { + sprite->data[1] = 0; + sprite->pos2.x += sprite->data[7]; + if (++sprite->data[2] == 12) + sprite->data[0]++; + } + break; + case 1: + if (++sprite->data[1] == 8) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 2: + sprite->pos2.x -= sprite->data[7] * 4; + if (++sprite->data[1] == 6) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 3: + sprite->pos2.x += sprite->data[7] * 3; + if (++sprite->data[1] == 8) + { + if (--sprite->data[6]) + { + sprite->data[1] = 0; + sprite->data[0]--; + } + else + { + DestroyAnimSprite(sprite); + } + } + break; + } +} + +void sub_8130918(u8 taskId) +{ + if (gBattleAnimArgs[0] == 0) + { + DestroyAnimVisualTask(taskId); + } + else + { + gTasks[taskId].data[0] = gBattleAnimArgs[1]; + gTasks[taskId].data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + PrepareAffineAnimInTaskData(&gTasks[taskId], gTasks[taskId].data[15], &gUnknown_084029DC); + gTasks[taskId].func = sub_8130970; + } +} + +static void sub_8130970(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (++task->data[1] > 1) + { + task->data[1] = 0; + if (!(task->data[2] & 1)) + gSprites[task->data[15]].pos2.x = 2; + else + gSprites[task->data[15]].pos2.x = -2; + } + + if (!RunAffineAnimFromTaskData(task)) + { + gSprites[task->data[15]].pos2.x = 0; + if (--task->data[0]) + { + PrepareAffineAnimInTaskData(&gTasks[taskId], gTasks[taskId].data[15], &gUnknown_084029DC); + task->data[1] = 0; + task->data[2] = 0; + } + else + { + DestroyAnimVisualTask(taskId); + } + } +} + +static void sub_8130A2C(struct Sprite *sprite) +{ + if (gBattleAnimArgs[0] == 0) + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, 2); + } + else + { + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->pos1.y = GetBattlerSpriteCoordAttr(gBattleAnimTarget, 2); + } + + if (sprite->pos1.y < 8) + sprite->pos1.y = 8; + + sprite->data[0] = 0; + sprite->data[1] = gBattleAnimArgs[1]; + sprite->data[2] = 0; + sprite->data[3] = gBattleAnimArgs[2]; + sprite->callback = sub_8130A94; +} + +static void sub_8130A94(struct Sprite *sprite) +{ + if (++sprite->data[0] >= sprite->data[1]) + { + sprite->data[0] = 0; + sprite->data[2] = (sprite->data[2] + 1) & 1; + sprite->invisible = sprite->data[2]; + if (sprite->data[2] && --sprite->data[3] == 0) + DestroyAnimSprite(sprite); + } +} + +static void sub_8130AEC(struct Sprite *sprite) +{ + if (gBattleAnimArgs[0] == 0) + { + sprite->oam.matrixNum |= 0x8; + sprite->pos1.x = 100; + sprite->data[7] = 1; + } + else + { + sprite->pos1.x = 140; + sprite->data[7] = -1; + } + + sprite->pos1.y = 56; + sprite->callback = sub_8130B38; +} + +static void sub_8130B38(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + sprite->pos1.y -= sprite->data[7] * 2; + if (sprite->data[1] & 1) + sprite->pos1.x -= sprite->data[7] * 2; + + if (++sprite->data[1] == 9) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 1: + if (++sprite->data[1] == 4) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 2: + sprite->data[1]++; + sprite->pos1.y += sprite->data[7] * 3; + sprite->pos2.x = sprite->data[7] * (gSineTable[sprite->data[1] * 10] >> 3); + if (sprite->data[1] == 12) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 3: + if (++sprite->data[1] == 2) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 4: + sprite->data[1]++; + sprite->pos1.y -= sprite->data[7] * 3; + sprite->pos2.x = sprite->data[7] * (gSineTable[sprite->data[1] * 10] >> 3); + if (sprite->data[1] == 12) + sprite->data[0]++; + break; + case 5: + sprite->data[1]++; + sprite->pos1.y += sprite->data[7] * 3; + sprite->pos2.x = sprite->data[7] * (gSineTable[sprite->data[1] * 10] >> 3); + if (sprite->data[1] == 15) + sprite->oam.tileNum += 16; + + if (sprite->data[1] == 18) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 6: + sprite->pos1.x += sprite->data[7] * 6; + if (++sprite->data[1] == 9) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 7: + sprite->pos1.x += sprite->data[7] * 2; + if (++sprite->data[1] == 1) + { + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 8: + sprite->pos1.x -= sprite->data[7] * 3; + if (++sprite->data[1] == 5) + DestroyAnimSprite(sprite); + break; + } +} + +void sub_8130D20(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + task->data[15] = GetAnimBattlerSpriteId(0); + if (!IsContest()) + { + if (IsDoubleBattle() == TRUE) + { + int x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + int y = GetBattlerSpriteCoord(gBattleAnimAttacker ^ 2, 0); + if (x > y) + task->data[14] = 1; + else + task->data[14] = -1; + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + task->data[14] = -1; + else + task->data[14] = 1; + } + } + else + { + task->data[14] = 1; + } + + task->func = sub_8130DBC; +} + +static void sub_8130DBC(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + switch (task->data[0]) + { + case 0: + if (++task->data[1] == 13) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 1: + gSprites[task->data[15]].pos2.x -= task->data[14] * 3; + if (++task->data[1] == 6) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 2: + gSprites[task->data[15]].pos2.x += task->data[14] * 3; + if (++task->data[1] == 6) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 3: + if (++task->data[1] == 2) + { + task->data[1] = 0; + if (task->data[2] == 0) + { + task->data[2]++; + task->data[0] = 1; + } + else + { + task->data[0]++; + } + } + break; + case 4: + gSprites[task->data[15]].pos2.x += task->data[14]; + if (++task->data[1] == 3) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 5: + if (++task->data[1] == 6) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 6: + gSprites[task->data[15]].pos2.x -= task->data[14] * 4; + if (++task->data[1] == 5) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 7: + gSprites[task->data[15]].pos2.x += task->data[14] * 4; + if (++task->data[1] == 5) + { + task->data[1] = 0; + task->data[0]++; + } + break; + case 8: + gSprites[task->data[15]].pos2.x = 0; + DestroyAnimVisualTask(taskId); + break; + } +} + +static void sub_8130F5C(struct Sprite *sprite) +{ + if (gBattleAnimArgs[0] == 0) + { + InitAnimSpritePos(sprite, 1); + sprite->data[7] = gBattleAnimAttacker; + } + else + { + sprite->data[7] = gBattleAnimTarget; + } + + if (GetBattlerSide(sprite->data[7]) == B_SIDE_OPPONENT) + sprite->oam.matrixNum = 8; + + sprite->oam.priority = GetBattlerSpriteBGPriority(sprite->data[7]); + sprite->oam.objMode = ST_OAM_OBJ_BLEND; + sprite->callback = sub_8130FE0; +} + +static void sub_8130FE0(struct Sprite *sprite) +{ + u16 x, y; + + switch (sprite->data[5]) + { + case 0: + switch (sprite->data[6]) + { + default: + sprite->data[6] = 0; + case 0: + case 4: + x = GetBattlerSpriteCoordAttr(sprite->data[7], 5) - 4; + y = GetBattlerSpriteCoordAttr(sprite->data[7], 3) - 4; + break; + case 1: + x = GetBattlerSpriteCoordAttr(sprite->data[7], 5) - 4; + y = GetBattlerSpriteCoordAttr(sprite->data[7], 2) + 4; + break; + case 2: + x = GetBattlerSpriteCoordAttr(sprite->data[7], 4) + 4; + y = GetBattlerSpriteCoordAttr(sprite->data[7], 3) - 4; + break; + case 3: + x = GetBattlerSpriteCoordAttr(sprite->data[7], 4) + 4; + y = GetBattlerSpriteCoordAttr(sprite->data[7], 2) - 4; + break; + case 5: + x = GetBattlerSpriteCoord(sprite->data[7], 2); + y = GetBattlerSpriteCoord(sprite->data[7], 3); + break; + } + + if (sprite->data[6] == 4) + sprite->data[0] = 24; + else if (sprite->data[6] == 5) + sprite->data[0] = 6; + else + sprite->data[0] = 12; + + sprite->data[1] = sprite->pos1.x; + sprite->data[2] = x; + sprite->data[3] = sprite->pos1.y; + sprite->data[4] = y; + InitAnimLinearTranslation(sprite); + sprite->data[5]++; + break; + case 1: + if (TranslateAnimLinear(sprite)) + { + switch (sprite->data[6]) + { + default: + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + sprite->data[0] = 0; + sprite->data[5]++; + sprite->data[6]++; + break; + case 4: + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + sprite->data[5] = 0; + sprite->data[6]++; + break; + case 5: + sprite->data[0] = 0; + sprite->data[1] = 16; + sprite->data[2] = 0; + sprite->data[5] = 3; + break; + } + } + break; + case 2: + if (++sprite->data[0] == 4) + sprite->data[5] = 0; + break; + case 3: + if (!(sprite->data[0] & 1)) + sprite->data[1]--; + else + sprite->data[2]++; + + REG_BLDALPHA = (sprite->data[2] << 8) | sprite->data[1]; + if (++sprite->data[0] == 32) + { + sprite->invisible = 1; + sprite->data[5]++; + } + break; + case 4: + DestroyAnimSprite(sprite); + break; + } +} + +static void sub_81311E4(struct Sprite *sprite) +{ + sprite->pos2.x = ((sprite->data[2] - sprite->data[0]) * sprite->data[5]) / sprite->data[4]; + sprite->pos2.y = ((sprite->data[3] - sprite->data[1]) * sprite->data[5]) / sprite->data[4]; + if (!(sprite->data[5] & 1)) + { + CreateSprite( + &gSpriteTemplate_8402500, + sprite->pos1.x + sprite->pos2.x, + sprite->pos1.y + sprite->pos2.y, 5); + } + + if (sprite->data[5] == sprite->data[4]) + DestroyAnimSprite(sprite); + + sprite->data[5]++; +} + +static void sub_8131264(struct Sprite *sprite) +{ + GetBattlerSpriteCoord(gBattleAnimTarget, 2); // unused local variable + GetBattlerSpriteCoord(gBattleAnimTarget, 3); // unused local variable + + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER || IsContest()) + { + sprite->data[0] = sprite->pos1.x - gBattleAnimArgs[0]; + sprite->data[2] = sprite->pos1.x - gBattleAnimArgs[2]; + } + else + { + sprite->data[0] = sprite->pos1.x + gBattleAnimArgs[0]; + sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2]; + } + + sprite->data[1] = sprite->pos1.y + gBattleAnimArgs[1]; + sprite->data[3] = sprite->pos1.y + gBattleAnimArgs[3]; + sprite->data[4] = gBattleAnimArgs[4]; + sprite->pos1.x = sprite->data[0]; + sprite->pos1.y = sprite->data[1]; + sprite->callback = sub_81311E4; +} + +void sub_81312E4(u8 taskId) +{ + int i; + u8 spriteId = GetAnimBattlerSpriteId(0); + + if (gTasks[taskId].data[0] == 0) + { + PrepareBattlerSpriteForRotScale(spriteId, 0); + gTasks[taskId].data[1] = 0x100; + gTasks[taskId].data[2] = 0x100; + gTasks[taskId].data[0]++; + } + else if (gTasks[taskId].data[0] == 1) + { + gTasks[taskId].data[1] += 0x60; + gTasks[taskId].data[2] -= 0xD; + obj_id_set_rotscale(spriteId, gTasks[taskId].data[1], gTasks[taskId].data[2], 0); + if (++gTasks[taskId].data[3] == 9) + { + gTasks[taskId].data[3] = 0; + sub_8078F40(spriteId); + gSprites[spriteId].invisible = 1; + gTasks[taskId].data[0]++; + } + } + else + { + refresh_graphics_maybe(gBattleAnimAttacker, 0, spriteId); + if (IsContest()) + { + gSprites[gBankSpriteIds[gBattleAnimAttacker]].affineAnims = gSpriteAffineAnimTable_81E7C18; + StartSpriteAffineAnim(&gSprites[gBankSpriteIds[gBattleAnimAttacker]], 0); + } + + for (i = 0; i < 16; i++) + gTasks[taskId].data[i] = 0; + + gTasks[taskId].func = sub_8131408; + } +} + +static void sub_8131408(u8 taskId) +{ + u8 spriteId = GetAnimBattlerSpriteId(0); + + switch (gTasks[taskId].data[0]) + { + case 0: + gSprites[spriteId].pos2.y = -200; + gSprites[spriteId].pos2.x = 200; + gSprites[spriteId].invisible = 0; + gTasks[taskId].data[10] = 0; + gTasks[taskId].data[0]++; + break; + case 1: + gTasks[taskId].data[10] += 112; + gSprites[spriteId].pos2.y += gTasks[taskId].data[10] >> 8; + if (gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y >= -32) + gSprites[spriteId].pos2.x = 0; + + if (gSprites[spriteId].pos2.y > 0) + gSprites[spriteId].pos2.y = 0; + + if (gSprites[spriteId].pos2.y == 0) + { + PlaySE12WithPanning(SE_W145B, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER_NEG)); + gTasks[taskId].data[10] -= 0x800; + gTasks[taskId].data[0]++; + } + break; + case 2: + gTasks[taskId].data[10] -= 112; + if (gTasks[taskId].data[10] < 0) + gTasks[taskId].data[10] = 0; + + gSprites[spriteId].pos2.y -= gTasks[taskId].data[10] >> 8; + if (gTasks[taskId].data[10] == 0) + gTasks[taskId].data[0]++; + break; + case 3: + gTasks[taskId].data[10] += 112; + gSprites[spriteId].pos2.y += gTasks[taskId].data[10] >> 8; + if (gSprites[spriteId].pos2.y > 0) + gSprites[spriteId].pos2.y = 0; + + if (gSprites[spriteId].pos2.y == 0) + { + PlaySE12WithPanning(SE_W145B, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER_NEG)); + DestroyAnimVisualTask(taskId); + } + break; + } +} + +static void sub_8131564(struct Sprite *sprite) +{ + s16 y2; + + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + { + sprite->subpriority = GetBattlerSubpriority(gBattleAnimTarget) - 2; + y2 = -144; + } + else + { + sprite->subpriority = GetBattlerSubpriority(gBattleAnimTarget) + 2; + y2 = -96; + } + + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + sprite->pos2.y = y2; + sprite->callback = sub_81315C8; +} + +static void sub_81315C8(struct Sprite *sprite) +{ + switch (sprite->data[0]) + { + case 0: + sprite->pos2.y += 10; + if (sprite->pos2.y >= 0) + { + PlaySE12WithPanning(SE_W166, BattleAnimAdjustPanning(SOUND_PAN_TARGET)); + sprite->pos2.y = 0; + sprite->data[0]++; + } + break; + case 1: + sprite->data[1] += 4; + sprite->pos2.y = -(gSineTable[sprite->data[1]] >> 3); + if (sprite->data[1] > 127) + { + PlaySE12WithPanning(SE_W166, BattleAnimAdjustPanning(SOUND_PAN_TARGET)); + sprite->data[1] = 0; + sprite->pos2.y = 0; + sprite->data[0]++; + } + break; + case 2: + sprite->data[1] += 6; + sprite->pos2.y = -(gSineTable[sprite->data[1]] >> 4); + if (sprite->data[1] > 127) + { + sprite->data[1] = 0; + sprite->pos2.y = 0; + sprite->data[0]++; + } + break; + case 3: + if (++sprite->data[1] > 8) + { + PlaySE12WithPanning(SE_W043, BattleAnimAdjustPanning(SOUND_PAN_TARGET)); + sprite->data[1] = 0; + sprite->data[0]++; + } + break; + case 4: + if (++sprite->data[1] > 8) + { + sprite->data[1] = 0; + sprite->data[2]++; + sprite->invisible = sprite->data[2] & 1; + if (sprite->data[2] == 7) + DestroyAnimSprite(sprite); + } + break; + } +} + +void sub_81316F8(u8 taskId) +{ + s16 spriteId1, spriteId2; + + if (IsContest()) + { + DestroyAnimVisualTask(taskId); + return; + } + + spriteId1 = duplicate_obj_of_side_rel2move_in_transparent_mode(1); + if (spriteId1 < 0) + { + DestroyAnimVisualTask(taskId); + return; + } + + spriteId2 = duplicate_obj_of_side_rel2move_in_transparent_mode(1); + if (spriteId2 < 0) + { + obj_delete_but_dont_free_vram(&gSprites[spriteId1]); + DestroyAnimVisualTask(taskId); + return; + } + + gSprites[spriteId2].pos2.x += 24; + gSprites[spriteId1].pos2.x -= 24; + gSprites[spriteId2].data[0] = 0; + gSprites[spriteId1].data[0] = 0; + gSprites[spriteId2].data[1] = 0; + gSprites[spriteId1].data[1] = 0; + gSprites[spriteId2].data[2] = 0; + gSprites[spriteId1].data[2] = 0; + gSprites[spriteId2].data[3] = 16; + gSprites[spriteId1].data[3] = -16; + gSprites[spriteId2].data[4] = 0; + gSprites[spriteId1].data[4] = 128; + gSprites[spriteId2].data[5] = 24; + gSprites[spriteId1].data[5] = 24; + gSprites[spriteId2].data[6] = taskId; + gSprites[spriteId1].data[6] = taskId; + gSprites[spriteId2].data[7] = 0; + gSprites[spriteId1].data[7] = 0; + gTasks[taskId].data[0] = 2; + gSprites[spriteId2].invisible = 0; + gSprites[spriteId1].invisible = 1; + gSprites[spriteId2].oam.objMode = ST_OAM_OBJ_NORMAL; + gSprites[spriteId1].oam.objMode = ST_OAM_OBJ_NORMAL; + gSprites[spriteId2].callback = sub_8131838; + gSprites[spriteId1].callback = sub_8131838; + gTasks[taskId].func = sub_8131810; +} + +static void sub_8131810(u8 taskId) +{ + if (gTasks[taskId].data[0] == 0) + DestroyAnimVisualTask(taskId); +} + +static void sub_8131838(struct Sprite *sprite) +{ + if (++sprite->data[1] > 1) + { + sprite->data[1] = 0; + sprite->invisible ^= 1; + } + + sprite->data[4] = (sprite->data[4] + sprite->data[3]) & 0xFF; + sprite->pos2.x = Cos(sprite->data[4], sprite->data[5]); + switch (sprite->data[0]) + { + case 0: + if (++sprite->data[2] == 60) + { + sprite->data[2] = 0; + sprite->data[0]++; + } + break; + case 1: + if (++sprite->data[2] > 0) + { + sprite->data[2] = 0; + sprite->data[5] -= 2; + if (sprite->data[5] < 0) + { + gTasks[sprite->data[6]].data[sprite->data[7]]--; + obj_delete_but_dont_free_vram(sprite); + } + } + break; + } +} + +void AnimTask_GetReturnPowerLevel(u8 taskId) +{ + gBattleAnimArgs[7] = 0; + if (gAnimFriendship < 60) + gBattleAnimArgs[7] = 0; + if (gAnimFriendship > 60 && gAnimFriendship < 92) + gBattleAnimArgs[7] = 1; + if (gAnimFriendship > 91 && gAnimFriendship < 201) + gBattleAnimArgs[7] = 2; + if (gAnimFriendship > 200) + gBattleAnimArgs[7] = 3; + + DestroyAnimVisualTask(taskId); +} + +#ifdef NONMATCHING +// Makes the mon run out of screen, run past the opposing mon, and return to its original position. +// No args. +void AnimTask_SnatchOpposingMonMove(u8 taskId) +{ + u8 spriteId, spriteId2; + u32 personality; + u32 otId; + u16 species; + u8 subpriority; + u8 isBackPic; + s16 x; + + switch (gTasks[taskId].data[0]) + { + case 0: + spriteId = GetAnimBattlerSpriteId(ANIM_BATTLER_ATTACKER); + gTasks[taskId].data[1] += 0x800; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + gSprites[spriteId].pos2.x += (gTasks[taskId].data[1] >> 8); + else + gSprites[spriteId].pos2.x -= (gTasks[taskId].data[1] >> 8); + + gTasks[taskId].data[1] &= 0xFF; + x = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x; + if ((u16)(x + 32) > 304) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + } + break; + case 1: + if (IsContest()) + { + personality = eWRAM_19348Struct->personality; + otId = eWRAM_19348Struct->otId; + species = eWRAM_19348Struct->species; + subpriority = GetBattlerSubpriority(gBattleAnimAttacker); + isBackPic = 0; + x = -32; + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_PERSONALITY); + otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_OT_ID); + if (eTransformStatuses[gBattleAnimTarget].species == SPECIES_NONE) + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES); + else + species = eTransformStatuses[gBattleAnimTarget].species; + + subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_BATTLER_TARGET)].subpriority + 1; + isBackPic = 0; + x = 272; + } + else + { + personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_PERSONALITY); + otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_OT_ID); + if (eTransformStatuses[gBattleAnimTarget].species == SPECIES_NONE) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES); + else + species = eTransformStatuses[gBattleAnimTarget].species; + + subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_BATTLER_TARGET)].subpriority - 1; + isBackPic = 1; + x = -32; + } + } + + spriteId2 = sub_8079F44(species, isBackPic, 0, x, GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y), subpriority, personality, otId); + if (eTransformStatuses[gBattleAnimTarget].species != SPECIES_NONE) + BlendPalette((gSprites[spriteId2].oam.paletteNum * 16) | 0x100, 16, 6, RGB_WHITE); + + gTasks[taskId].data[15] = spriteId2; + gTasks[taskId].data[0]++; + break; + case 2: + spriteId2 = gTasks[taskId].data[15]; + gTasks[taskId].data[1] += 0x800; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + gSprites[spriteId2].pos2.x -= (gTasks[taskId].data[1] >> 8); + else + gSprites[spriteId2].pos2.x += (gTasks[taskId].data[1] >> 8); + + gTasks[taskId].data[1] &= 0xFF; + x = gSprites[spriteId2].pos1.x + gSprites[spriteId2].pos2.x; + if (gTasks[taskId].data[14] == 0) + { + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + if (x < GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X)) + { + gTasks[taskId].data[14]++; + gBattleAnimArgs[7] = 0xFFFF; + } + } + else + { + if (x > GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X)) + { + gTasks[taskId].data[14]++; + gBattleAnimArgs[7] = 0xFFFF; + } + } + } + + if ((u16)(x + 32) > 304) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + } + break; + case 3: + spriteId = GetAnimBattlerSpriteId(ANIM_BATTLER_ATTACKER); + spriteId2 = gTasks[taskId].data[15]; + DestroySpriteAndFreeResources_(&gSprites[spriteId2]); + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + gSprites[spriteId].pos2.x = -gSprites[spriteId].pos1.x - 32; + else + gSprites[spriteId].pos2.x = 272 - gSprites[spriteId].pos1.x; + + gTasks[taskId].data[0]++; + break; + case 4: + spriteId = GetAnimBattlerSpriteId(ANIM_BATTLER_ATTACKER); + gTasks[taskId].data[1] += 0x800; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + { + gSprites[spriteId].pos2.x += (gTasks[taskId].data[1] >> 8); + if (gSprites[spriteId].pos2.x + gSprites[spriteId].pos1.x >= GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X)) + gSprites[spriteId].pos2.x = 0; + } + else + { + gSprites[spriteId].pos2.x -= (gTasks[taskId].data[1] >> 8); + if (gSprites[spriteId].pos2.x + gSprites[spriteId].pos1.x <= GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X)) + gSprites[spriteId].pos2.x = 0; + } + + gTasks[taskId].data[1] = (u8)gTasks[taskId].data[1]; + if (gSprites[spriteId].pos2.x == 0) + DestroyAnimVisualTask(taskId); + break; + } +} +#else +NAKED +void AnimTask_SnatchOpposingMonMove(u8 taskId) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x14\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r8, r0\n\ + ldr r1, _08131974 @ =gTasks\n\ + lsls r0, 2\n\ + add r0, r8\n\ + lsls r0, 3\n\ + adds r0, r1\n\ + movs r1, 0x8\n\ + ldrsh r0, [r0, r1]\n\ + cmp r0, 0x4\n\ + bls _0813196A\n\ + b _08131EA0\n\ +_0813196A:\n\ + lsls r0, 2\n\ + ldr r1, _08131978 @ =_0813197C\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .align 2, 0\n\ +_08131974: .4byte gTasks\n\ +_08131978: .4byte _0813197C\n\ + .align 2, 0\n\ +_0813197C:\n\ + .4byte _08131990\n\ + .4byte _08131A44\n\ + .4byte _08131C20\n\ + .4byte _08131D40\n\ + .4byte _08131DC4\n\ +_08131990:\n\ + movs r0, 0\n\ + bl GetAnimBattlerSpriteId\n\ + lsls r0, 24\n\ + lsrs r7, r0, 24\n\ + ldr r1, _081319DC @ =gTasks\n\ + mov r2, r8\n\ + lsls r4, r2, 2\n\ + adds r0, r4, r2\n\ + lsls r0, 3\n\ + adds r6, r0, r1\n\ + movs r3, 0x80\n\ + lsls r3, 4\n\ + adds r0, r3, 0\n\ + ldrh r1, [r6, 0xA]\n\ + adds r0, r1\n\ + strh r0, [r6, 0xA]\n\ + ldr r0, _081319E0 @ =gBattleAnimAttacker\n\ + ldrb r0, [r0]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + mov r9, r4\n\ + cmp r0, 0\n\ + bne _081319E8\n\ + ldr r2, _081319E4 @ =gSprites\n\ + lsls r3, r7, 4\n\ + adds r1, r3, r7\n\ + lsls r1, 2\n\ + adds r1, r2\n\ + ldrh r0, [r6, 0xA]\n\ + lsls r0, 16\n\ + asrs r0, 24\n\ + ldrh r4, [r1, 0x24]\n\ + adds r0, r4\n\ + strh r0, [r1, 0x24]\n\ + b _08131A02\n\ + .align 2, 0\n\ +_081319DC: .4byte gTasks\n\ +_081319E0: .4byte gBattleAnimAttacker\n\ +_081319E4: .4byte gSprites\n\ +_081319E8:\n\ + ldr r3, _08131A3C @ =gSprites\n\ + lsls r4, r7, 4\n\ + adds r2, r4, r7\n\ + lsls r2, 2\n\ + adds r2, r3\n\ + ldrh r1, [r6, 0xA]\n\ + lsls r1, 16\n\ + asrs r1, 24\n\ + ldrh r0, [r2, 0x24]\n\ + subs r0, r1\n\ + strh r0, [r2, 0x24]\n\ + adds r2, r3, 0\n\ + adds r3, r4, 0\n\ +_08131A02:\n\ + ldr r1, _08131A40 @ =gTasks\n\ + mov r0, r9\n\ + add r0, r8\n\ + lsls r0, 3\n\ + adds r4, r0, r1\n\ + ldrb r0, [r4, 0xA]\n\ + strh r0, [r4, 0xA]\n\ + adds r1, r3, r7\n\ + lsls r1, 2\n\ + adds r1, r2\n\ + ldrh r0, [r1, 0x24]\n\ + ldrh r1, [r1, 0x20]\n\ + adds r0, r1\n\ + lsls r0, 16\n\ + movs r1, 0x80\n\ + lsls r1, 14\n\ + adds r0, r1\n\ + movs r1, 0x98\n\ + lsls r1, 17\n\ + cmp r0, r1\n\ + bhi _08131A2E\n\ + b _08131EA0\n\ +_08131A2E:\n\ + movs r0, 0\n\ + strh r0, [r4, 0xA]\n\ + ldrh r0, [r4, 0x8]\n\ + adds r0, 0x1\n\ + strh r0, [r4, 0x8]\n\ + b _08131EA0\n\ + .align 2, 0\n\ +_08131A3C: .4byte gSprites\n\ +_08131A40: .4byte gTasks\n\ +_08131A44:\n\ + bl IsContest\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08131A74\n\ + ldr r0, _08131A6C @ =gSharedMem + 0x19348\n\ + ldr r2, [r0, 0x8]\n\ + mov r10, r2\n\ + ldr r3, [r0, 0xC]\n\ + mov r9, r3\n\ + ldrh r5, [r0]\n\ + ldr r0, _08131A70 @ =gBattleAnimAttacker\n\ + ldrb r0, [r0]\n\ + bl GetBattlerSubpriority\n\ + lsls r0, 24\n\ + lsrs r4, r0, 24\n\ + movs r7, 0\n\ + b _08131B92\n\ + .align 2, 0\n\ +_08131A6C: .4byte gSharedMem + 0x19348\n\ +_08131A70: .4byte gBattleAnimAttacker\n\ +_08131A74:\n\ + ldr r4, _08131AD4 @ =gBattleAnimAttacker\n\ + ldrb r0, [r4]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _08131B10\n\ + ldr r7, _08131AD8 @ =gBattlerPartyIndexes\n\ + ldrb r0, [r4]\n\ + lsls r0, 1\n\ + adds r0, r7\n\ + ldrh r0, [r0]\n\ + movs r6, 0x64\n\ + muls r0, r6\n\ + ldr r5, _08131ADC @ =gPlayerParty\n\ + adds r0, r5\n\ + movs r1, 0\n\ + bl GetMonData\n\ + mov r10, r0\n\ + ldrb r0, [r4]\n\ + lsls r0, 1\n\ + adds r0, r7\n\ + ldrh r0, [r0]\n\ + muls r0, r6\n\ + adds r0, r5\n\ + movs r1, 0x1\n\ + bl GetMonData\n\ + mov r9, r0\n\ + ldrb r2, [r4]\n\ + lsls r1, r2, 2\n\ + ldr r0, _08131AE0 @ =gSharedMem + 0x17800\n\ + adds r1, r0\n\ + ldrh r0, [r1, 0x2]\n\ + cmp r0, 0\n\ + bne _08131AE4\n\ + lsls r0, r2, 1\n\ + adds r0, r7\n\ + ldrh r0, [r0]\n\ + muls r0, r6\n\ + adds r0, r5\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + lsls r0, 16\n\ + lsrs r5, r0, 16\n\ + b _08131AE6\n\ + .align 2, 0\n\ +_08131AD4: .4byte gBattleAnimAttacker\n\ +_08131AD8: .4byte gBattlerPartyIndexes\n\ +_08131ADC: .4byte gPlayerParty\n\ +_08131AE0: .4byte gSharedMem + 0x17800\n\ +_08131AE4:\n\ + ldrh r5, [r1, 0x2]\n\ +_08131AE6:\n\ + movs r0, 0x1\n\ + bl GetAnimBattlerSpriteId\n\ + ldr r2, _08131B0C @ =gSprites\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + lsls r1, r0, 4\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + adds r1, r2\n\ + adds r1, 0x43\n\ + ldrb r0, [r1]\n\ + adds r0, 0x1\n\ + lsls r0, 24\n\ + lsrs r4, r0, 24\n\ + movs r7, 0\n\ + movs r6, 0x88\n\ + lsls r6, 1\n\ + b _08131B94\n\ + .align 2, 0\n\ +_08131B0C: .4byte gSprites\n\ +_08131B10:\n\ + ldr r7, _08131B64 @ =gBattlerPartyIndexes\n\ + ldrb r0, [r4]\n\ + lsls r0, 1\n\ + adds r0, r7\n\ + ldrh r0, [r0]\n\ + movs r6, 0x64\n\ + muls r0, r6\n\ + ldr r5, _08131B68 @ =gEnemyParty\n\ + adds r0, r5\n\ + movs r1, 0\n\ + bl GetMonData\n\ + mov r10, r0\n\ + ldrb r0, [r4]\n\ + lsls r0, 1\n\ + adds r0, r7\n\ + ldrh r0, [r0]\n\ + muls r0, r6\n\ + adds r0, r5\n\ + movs r1, 0x1\n\ + bl GetMonData\n\ + mov r9, r0\n\ + ldrb r2, [r4]\n\ + lsls r1, r2, 2\n\ + ldr r0, _08131B6C @ =gSharedMem + 0x17800\n\ + adds r1, r0\n\ + ldrh r0, [r1, 0x2]\n\ + cmp r0, 0\n\ + bne _08131B70\n\ + lsls r0, r2, 1\n\ + adds r0, r7\n\ + ldrh r0, [r0]\n\ + muls r0, r6\n\ + adds r0, r5\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + lsls r0, 16\n\ + lsrs r5, r0, 16\n\ + b _08131B72\n\ + .align 2, 0\n\ +_08131B64: .4byte gBattlerPartyIndexes\n\ +_08131B68: .4byte gEnemyParty\n\ +_08131B6C: .4byte gSharedMem + 0x17800\n\ +_08131B70:\n\ + ldrh r5, [r1, 0x2]\n\ +_08131B72:\n\ + movs r0, 0x1\n\ + bl GetAnimBattlerSpriteId\n\ + ldr r2, _08131C04 @ =gSprites\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + lsls r1, r0, 4\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + adds r1, r2\n\ + adds r1, 0x43\n\ + ldrb r0, [r1]\n\ + subs r0, 0x1\n\ + lsls r0, 24\n\ + lsrs r4, r0, 24\n\ + movs r7, 0x1\n\ +_08131B92:\n\ + ldr r6, _08131C08 @ =0x0000ffe0\n\ +_08131B94:\n\ + ldr r0, _08131C0C @ =gBattleAnimTarget\n\ + ldrb r0, [r0]\n\ + movs r1, 0x1\n\ + bl GetBattlerSpriteCoord\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + lsls r3, r6, 16\n\ + asrs r3, 16\n\ + str r0, [sp]\n\ + str r4, [sp, 0x4]\n\ + mov r4, r10\n\ + str r4, [sp, 0x8]\n\ + mov r0, r9\n\ + str r0, [sp, 0xC]\n\ + adds r0, r5, 0\n\ + adds r1, r7, 0\n\ + movs r2, 0\n\ + bl sub_8079F44\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + ldr r0, _08131C10 @ =gBattleAnimAttacker\n\ + ldrb r0, [r0]\n\ + lsls r0, 2\n\ + ldr r1, _08131C14 @ =gSharedMem + 0x17800\n\ + adds r0, r1\n\ + ldrh r0, [r0, 0x2]\n\ + cmp r0, 0\n\ + beq _08131BF2\n\ + ldr r1, _08131C04 @ =gSprites\n\ + lsls r0, r5, 4\n\ + adds r0, r5\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x5]\n\ + lsrs r0, 4\n\ + lsls r0, 4\n\ + movs r2, 0x80\n\ + lsls r2, 1\n\ + adds r1, r2, 0\n\ + orrs r0, r1\n\ + ldr r3, _08131C18 @ =0x00007fff\n\ + movs r1, 0x10\n\ + movs r2, 0x6\n\ + bl BlendPalette\n\ +_08131BF2:\n\ + ldr r0, _08131C1C @ =gTasks\n\ + mov r3, r8\n\ + lsls r1, r3, 2\n\ + add r1, r8\n\ + lsls r1, 3\n\ + adds r1, r0\n\ + strh r5, [r1, 0x26]\n\ + b _08131DB6\n\ + .align 2, 0\n\ +_08131C04: .4byte gSprites\n\ +_08131C08: .4byte 0x0000ffe0\n\ +_08131C0C: .4byte gBattleAnimTarget\n\ +_08131C10: .4byte gBattleAnimAttacker\n\ +_08131C14: .4byte gSharedMem + 0x17800\n\ +_08131C18: .4byte 0x00007fff\n\ +_08131C1C: .4byte gTasks\n\ +_08131C20:\n\ + ldr r1, _08131C6C @ =gTasks\n\ + mov r0, r8\n\ + lsls r4, r0, 2\n\ + adds r0, r4, r0\n\ + lsls r0, 3\n\ + adds r6, r0, r1\n\ + ldrh r0, [r6, 0x26]\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + movs r1, 0x80\n\ + lsls r1, 4\n\ + adds r0, r1, 0\n\ + ldrh r2, [r6, 0xA]\n\ + adds r0, r2\n\ + strh r0, [r6, 0xA]\n\ + ldr r0, _08131C70 @ =gBattleAnimAttacker\n\ + ldrb r0, [r0]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + mov r9, r4\n\ + cmp r0, 0\n\ + bne _08131C78\n\ + ldr r3, _08131C74 @ =gSprites\n\ + lsls r4, r5, 4\n\ + adds r2, r4, r5\n\ + lsls r2, 2\n\ + adds r2, r3\n\ + ldrh r1, [r6, 0xA]\n\ + lsls r1, 16\n\ + asrs r1, 24\n\ + ldrh r0, [r2, 0x24]\n\ + subs r0, r1\n\ + strh r0, [r2, 0x24]\n\ + adds r2, r3, 0\n\ + adds r3, r4, 0\n\ + b _08131C8E\n\ + .align 2, 0\n\ +_08131C6C: .4byte gTasks\n\ +_08131C70: .4byte gBattleAnimAttacker\n\ +_08131C74: .4byte gSprites\n\ +_08131C78:\n\ + ldr r2, _08131CDC @ =gSprites\n\ + lsls r3, r5, 4\n\ + adds r1, r3, r5\n\ + lsls r1, 2\n\ + adds r1, r2\n\ + ldrh r0, [r6, 0xA]\n\ + lsls r0, 16\n\ + asrs r0, 24\n\ + ldrh r4, [r1, 0x24]\n\ + adds r0, r4\n\ + strh r0, [r1, 0x24]\n\ +_08131C8E:\n\ + ldr r1, _08131CE0 @ =gTasks\n\ + mov r0, r9\n\ + add r0, r8\n\ + lsls r0, 3\n\ + adds r6, r0, r1\n\ + ldrb r0, [r6, 0xA]\n\ + strh r0, [r6, 0xA]\n\ + adds r1, r3, r5\n\ + lsls r1, 2\n\ + adds r1, r2\n\ + ldrh r0, [r1, 0x24]\n\ + ldrh r1, [r1, 0x20]\n\ + adds r0, r1\n\ + lsls r0, 16\n\ + lsrs r5, r0, 16\n\ + movs r1, 0x24\n\ + ldrsh r0, [r6, r1]\n\ + cmp r0, 0\n\ + bne _08131D0E\n\ + ldr r0, _08131CE4 @ =gBattleAnimAttacker\n\ + ldrb r0, [r0]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _08131CEC\n\ + lsls r4, r5, 16\n\ + asrs r4, 16\n\ + ldr r0, _08131CE8 @ =gBattleAnimTarget\n\ + ldrb r0, [r0]\n\ + movs r1, 0\n\ + bl GetBattlerSpriteCoord\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r4, r0\n\ + bge _08131D0E\n\ + b _08131D02\n\ + .align 2, 0\n\ +_08131CDC: .4byte gSprites\n\ +_08131CE0: .4byte gTasks\n\ +_08131CE4: .4byte gBattleAnimAttacker\n\ +_08131CE8: .4byte gBattleAnimTarget\n\ +_08131CEC:\n\ + lsls r4, r5, 16\n\ + asrs r4, 16\n\ + ldr r0, _08131D30 @ =gBattleAnimTarget\n\ + ldrb r0, [r0]\n\ + movs r1, 0\n\ + bl GetBattlerSpriteCoord\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r4, r0\n\ + ble _08131D0E\n\ +_08131D02:\n\ + ldrh r0, [r6, 0x24]\n\ + adds r0, 0x1\n\ + strh r0, [r6, 0x24]\n\ + ldr r1, _08131D34 @ =gBattleAnimArgs\n\ + ldr r0, _08131D38 @ =0x0000ffff\n\ + strh r0, [r1, 0xE]\n\ +_08131D0E:\n\ + lsls r0, r5, 16\n\ + movs r2, 0x80\n\ + lsls r2, 14\n\ + adds r0, r2\n\ + movs r1, 0x98\n\ + lsls r1, 17\n\ + cmp r0, r1\n\ + bhi _08131D20\n\ + b _08131EA0\n\ +_08131D20:\n\ + ldr r0, _08131D3C @ =gTasks\n\ + mov r1, r9\n\ + add r1, r8\n\ + lsls r1, 3\n\ + adds r1, r0\n\ + movs r0, 0\n\ + strh r0, [r1, 0xA]\n\ + b _08131DB6\n\ + .align 2, 0\n\ +_08131D30: .4byte gBattleAnimTarget\n\ +_08131D34: .4byte gBattleAnimArgs\n\ +_08131D38: .4byte 0x0000ffff\n\ +_08131D3C: .4byte gTasks\n\ +_08131D40:\n\ + movs r0, 0\n\ + bl GetAnimBattlerSpriteId\n\ + lsls r0, 24\n\ + lsrs r7, r0, 24\n\ + ldr r1, _08131D8C @ =gTasks\n\ + mov r3, r8\n\ + lsls r4, r3, 2\n\ + adds r0, r4, r3\n\ + lsls r0, 3\n\ + adds r0, r1\n\ + ldrh r0, [r0, 0x26]\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + lsls r0, r5, 4\n\ + adds r0, r5\n\ + lsls r0, 2\n\ + ldr r5, _08131D90 @ =gSprites\n\ + adds r0, r5\n\ + bl DestroySpriteAndFreeResources_\n\ + ldr r0, _08131D94 @ =gBattleAnimAttacker\n\ + ldrb r0, [r0]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + mov r9, r4\n\ + cmp r0, 0\n\ + bne _08131D98\n\ + lsls r1, r7, 4\n\ + adds r1, r7\n\ + lsls r1, 2\n\ + adds r1, r5\n\ + ldrh r0, [r1, 0x20]\n\ + negs r0, r0\n\ + subs r0, 0x20\n\ + strh r0, [r1, 0x24]\n\ + b _08131DAC\n\ + .align 2, 0\n\ +_08131D8C: .4byte gTasks\n\ +_08131D90: .4byte gSprites\n\ +_08131D94: .4byte gBattleAnimAttacker\n\ +_08131D98:\n\ + lsls r0, r7, 4\n\ + adds r0, r7\n\ + lsls r0, 2\n\ + adds r0, r5\n\ + ldrh r2, [r0, 0x20]\n\ + movs r4, 0x88\n\ + lsls r4, 1\n\ + adds r1, r4, 0\n\ + subs r1, r2\n\ + strh r1, [r0, 0x24]\n\ +_08131DAC:\n\ + ldr r0, _08131DC0 @ =gTasks\n\ + mov r1, r9\n\ + add r1, r8\n\ + lsls r1, 3\n\ + adds r1, r0\n\ +_08131DB6:\n\ + ldrh r0, [r1, 0x8]\n\ + adds r0, 0x1\n\ + strh r0, [r1, 0x8]\n\ + b _08131EA0\n\ + .align 2, 0\n\ +_08131DC0: .4byte gTasks\n\ +_08131DC4:\n\ + movs r0, 0\n\ + bl GetAnimBattlerSpriteId\n\ + lsls r0, 24\n\ + lsrs r7, r0, 24\n\ + ldr r1, _08131E38 @ =gTasks\n\ + mov r0, r8\n\ + lsls r4, r0, 2\n\ + adds r0, r4, r0\n\ + lsls r0, 3\n\ + adds r2, r0, r1\n\ + movs r1, 0x80\n\ + lsls r1, 4\n\ + adds r0, r1, 0\n\ + ldrh r3, [r2, 0xA]\n\ + adds r0, r3\n\ + strh r0, [r2, 0xA]\n\ + ldr r0, _08131E3C @ =gBattleAnimAttacker\n\ + mov r10, r0\n\ + ldrb r0, [r0]\n\ + str r2, [sp, 0x10]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + mov r9, r4\n\ + ldr r2, [sp, 0x10]\n\ + cmp r0, 0\n\ + bne _08131E44\n\ + ldr r1, _08131E40 @ =gSprites\n\ + lsls r5, r7, 4\n\ + adds r0, r5, r7\n\ + lsls r0, 2\n\ + adds r6, r0, r1\n\ + ldrh r0, [r2, 0xA]\n\ + lsls r0, 16\n\ + asrs r0, 24\n\ + ldrh r1, [r6, 0x24]\n\ + adds r0, r1\n\ + strh r0, [r6, 0x24]\n\ + movs r2, 0x24\n\ + ldrsh r4, [r6, r2]\n\ + movs r3, 0x20\n\ + ldrsh r0, [r6, r3]\n\ + adds r4, r0\n\ + mov r1, r10\n\ + ldrb r0, [r1]\n\ + movs r1, 0\n\ + bl GetBattlerSpriteCoord\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + adds r3, r5, 0\n\ + cmp r4, r0\n\ + blt _08131E7C\n\ + movs r2, 0\n\ + strh r2, [r6, 0x24]\n\ + b _08131E7C\n\ + .align 2, 0\n\ +_08131E38: .4byte gTasks\n\ +_08131E3C: .4byte gBattleAnimAttacker\n\ +_08131E40: .4byte gSprites\n\ +_08131E44:\n\ + ldr r1, _08131EB0 @ =gSprites\n\ + lsls r5, r7, 4\n\ + adds r0, r5, r7\n\ + lsls r0, 2\n\ + adds r6, r0, r1\n\ + ldrh r1, [r2, 0xA]\n\ + lsls r1, 16\n\ + asrs r1, 24\n\ + ldrh r0, [r6, 0x24]\n\ + subs r0, r1\n\ + strh r0, [r6, 0x24]\n\ + movs r3, 0x24\n\ + ldrsh r4, [r6, r3]\n\ + movs r1, 0x20\n\ + ldrsh r0, [r6, r1]\n\ + adds r4, r0\n\ + mov r2, r10\n\ + ldrb r0, [r2]\n\ + movs r1, 0\n\ + bl GetBattlerSpriteCoord\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + adds r3, r5, 0\n\ + cmp r4, r0\n\ + bgt _08131E7C\n\ + movs r4, 0\n\ + strh r4, [r6, 0x24]\n\ +_08131E7C:\n\ + ldr r1, _08131EB4 @ =gTasks\n\ + mov r0, r9\n\ + add r0, r8\n\ + lsls r0, 3\n\ + adds r0, r1\n\ + ldrb r1, [r0, 0xA]\n\ + strh r1, [r0, 0xA]\n\ + ldr r1, _08131EB0 @ =gSprites\n\ + adds r0, r3, r7\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + movs r1, 0x24\n\ + ldrsh r0, [r0, r1]\n\ + cmp r0, 0\n\ + bne _08131EA0\n\ + mov r0, r8\n\ + bl DestroyAnimVisualTask\n\ +_08131EA0:\n\ + add sp, 0x14\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08131EB0: .4byte gSprites\n\ +_08131EB4: .4byte gTasks\n\ + .syntax divided"); +} +#endif // NONMATCHING + +void sub_8131EB8(struct Sprite *sprite) +{ + switch (sprite->data[7]) + { + case 0: + if (gBattleAnimArgs[7] == -1) + { + PlaySE12WithPanning(SE_W233, BattleAnimAdjustPanning(63)); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 16; + sprite->data[0] = -32; + sprite->data[7]++; + sprite->invisible = 0; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT && !IsContest()) + sprite->subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_BATTLER_TARGET)].subpriority - 1; + } + else + { + sprite->invisible = 1; + } + break; + case 1: + sprite->pos2.y = Sin(sprite->data[1], sprite->data[0]); + sprite->data[1] += 5; + if (sprite->data[1] > 0x7F) + { + sprite->data[0] = sprite->data[0] / 2; + sprite->data[3]++; + sprite->data[1] -= 0x7F; + } + + sprite->data[2] += 0x100; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + sprite->pos2.x -= (sprite->data[2] >> 8); + else + sprite->pos2.x += (sprite->data[2] >> 8); + + sprite->data[2] &= 0xFF; + if (sprite->data[3] == 2) + DestroyAnimSprite(sprite); + break; + } +} + +// Quickly moves the mon towards its partner and back. +// No args. +void AnimTask_SnatchPartnerMove(u8 taskId) +{ + s16 attackerX, targetX; + u8 spriteId; + + switch (gTasks[taskId].data[15]) + { + case 0: + attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X); + targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X); + gTasks[taskId].data[0] = 6; + if (attackerX > targetX) + gTasks[taskId].data[0] *= -1; + + gTasks[taskId].data[1] = attackerX; + gTasks[taskId].data[2] = targetX; + gTasks[taskId].data[15]++; + break; + case 1: + spriteId = gBankSpriteIds[gBattleAnimAttacker]; + gSprites[spriteId].pos2.x += gTasks[taskId].data[0]; + if (gTasks[taskId].data[0] > 0) + { + if (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x >= gTasks[taskId].data[2]) + gTasks[taskId].data[15]++; + } + else + { + if (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x <= gTasks[taskId].data[2]) + gTasks[taskId].data[15]++; + } + break; + case 2: + gTasks[taskId].data[0] *= -1; + gTasks[taskId].data[15]++; + break; + case 3: + spriteId = gBankSpriteIds[gBattleAnimAttacker]; + gSprites[spriteId].pos2.x += gTasks[taskId].data[0]; + if (gTasks[taskId].data[0] < 0) + { + if (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x <= gTasks[taskId].data[1]) + gTasks[taskId].data[15]++; + } + else + { + if (gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x >= gTasks[taskId].data[1]) + gTasks[taskId].data[15]++; + } + break; + case 4: + default: + spriteId = gBankSpriteIds[gBattleAnimAttacker]; + gSprites[spriteId].pos2.x = 0; + DestroyAnimVisualTask(taskId); + break; + } +} + +// Moves the mon's sprite back and forth in an unpredictable swaying motion. +// No args. +void AnimTask_TeeterDanceMovement(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + task->data[3] = GetAnimBattlerSpriteId(ANIM_BATTLER_ATTACKER); + task->data[4] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER ? 1 : -1; + task->data[6] = gSprites[task->data[3]].pos1.y; + task->data[5] = gSprites[task->data[3]].pos1.x; + task->data[9] = 0; + task->data[11] = 0; + task->data[10] = 1; + task->data[12] = 0; + task->func = AnimTask_TeeterDanceMovementStep; +} + +static void AnimTask_TeeterDanceMovementStep(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + switch (task->data[0]) + { + case 0: + task->data[11] += 8; + task->data[11] &= 0xFF; + gSprites[task->data[3]].pos2.x = gSineTable[task->data[11]] >> 5; + task->data[9] += 2; + task->data[9] &= 0xFF; + gSprites[task->data[3]].pos1.x = (gSineTable[task->data[9]] >> 3) * task->data[4] + task->data[5]; + if (task->data[9] == 0) + { + gSprites[task->data[3]].pos1.x = task->data[5]; + task->data[0]++; + } + break; + case 1: + task->data[11] += 8; + task->data[11] &= 0xFF; + gSprites[task->data[3]].pos2.x = gSineTable[task->data[11]] >> 5; + if (task->data[11] == 0) + { + gSprites[task->data[3]].pos2.x = 0; + task->data[0]++; + } + break; + case 2: + DestroyAnimVisualTask(taskId); + break; + } +} + +static void AnimKnockOffStrikeStep(struct Sprite *sprite) +{ + // These two cases are identical. + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + { + sprite->data[1] += sprite->data[0]; + sprite->data[1] &= 0xFF; + } + else + { + sprite->data[1] += sprite->data[0]; + sprite->data[1] &= 0xFF; + } + + sprite->pos2.x = Cos(sprite->data[1], 20); + sprite->pos2.y = Sin(sprite->data[1], 20); + if (sprite->animEnded) + DestroyAnimSprite(sprite); + + sprite->data[2]++; +} + +// Animates a strike that swipes downard at the target mon. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +void AnimKnockOffStrike(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + { + sprite->pos1.x -= gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = -11; + sprite->data[1] = 192; + StartSpriteAffineAnim(sprite, 1); + } + else + { + sprite->data[0] = 11; + sprite->data[1] = 192; + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + } + + sprite->callback = AnimKnockOffStrikeStep; +} + +// Gradually fades a rotating recyle arrow sprite in and back out. +// No args. +void AnimRecycle(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + sprite->pos1.y = GetBattlerSpriteCoordAttr(gBattleAnimAttacker, BATTLER_COORD_ATTR_TOP); + if (sprite->pos1.y < 16) + sprite->pos1.y = 16; + + sprite->data[6] = 0; + sprite->data[7] = 16; + sprite->callback = AnimRecycleStep; + REG_BLDALPHA = BLDALPHA_BLEND(sprite->data[6], sprite->data[7]); +} + +static void AnimRecycleStep(struct Sprite *sprite) +{ + switch (sprite->data[2]) + { + case 0: + if (++sprite->data[0] > 1) + { + sprite->data[0] = 0; + if (!(sprite->data[1] & 1)) + { + if (sprite->data[6] < 16) + sprite->data[6]++; + } + else + { + if (sprite->data[7] != 0) + sprite->data[7]--; + } + + sprite->data[1]++; + REG_BLDALPHA = BLDALPHA_BLEND(sprite->data[6], sprite->data[7]); + if (sprite->data[7] == 0) + sprite->data[2]++; + } + break; + case 1: + if (++sprite->data[0] == 10) + { + sprite->data[0] = 0; + sprite->data[1] = 0; + sprite->data[2]++; + } + break; + case 2: + if (++sprite->data[0] > 1) + { + sprite->data[0] = 0; + if (!(sprite->data[1] & 1)) + { + if (sprite->data[6] != 0) + sprite->data[6]--; + } + else + { + if (sprite->data[7] < 16) + sprite->data[7]++; + } + + sprite->data[1]++; + REG_BLDALPHA = BLDALPHA_BLEND(sprite->data[6], sprite->data[7]); + if (sprite->data[7] == 16) + sprite->data[2]++; + } + break; + case 3: + DestroySpriteAndMatrix(sprite); + break; + } +} + +void AnimTask_GetWeather(u8 taskId) +{ + gBattleAnimArgs[7] = ANIM_WEATHER_NONE; + if (gWeatherMoveAnim & WEATHER_SUN_ANY) + gBattleAnimArgs[7] = ANIM_WEATHER_SUN; + else if (gWeatherMoveAnim & WEATHER_RAIN_ANY) + gBattleAnimArgs[7] = ANIM_WEATHER_RAIN; + else if (gWeatherMoveAnim & WEATHER_SANDSTORM_ANY) + gBattleAnimArgs[7] = ANIM_WEATHER_SANDSTORM; + else if (gWeatherMoveAnim & WEATHER_HAIL_ANY) + gBattleAnimArgs[7] = ANIM_WEATHER_HAIL; + + DestroyAnimVisualTask(taskId); +} + +// Squishes the mon sprite vertically, and shakes it back and forth. +// arg 0: which battler +void AnimTask_SlackOffSquish(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + task->data[0] = 0; + task->data[15] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + PrepareAffineAnimInTaskData(task, task->data[15], gSlackOffSquishAffineAnimCmds); + task->func = AnimTask_SlackOffSquishStep; +} + +static void AnimTask_SlackOffSquishStep(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + gTasks[taskId].data[0]++; + if (gTasks[taskId].data[0] > 16 && gTasks[taskId].data[0] < 40) + { + if (++task->data[1] > 2) + { + task->data[1] = 0; + task->data[2]++; + if (!(task->data[2] & 1)) + gSprites[task->data[15]].pos2.x = -1; + else + gSprites[task->data[15]].pos2.x = 1; + } + } + else + { + gSprites[task->data[15]].pos2.x = 0; + } + + if (!RunAffineAnimFromTaskData(&gTasks[taskId])) + DestroyAnimVisualTask(taskId); +} \ No newline at end of file diff --git a/src/battle_anim_mon_movement.c b/src/battle_anim_mon_movement.c new file mode 100644 index 000000000..5e713a3a7 --- /dev/null +++ b/src/battle_anim_mon_movement.c @@ -0,0 +1,1072 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "rom_8077ABC.h" +#include "sprite.h" +#include "task.h" +#include "trig.h" + +#define SPRITE gSprites[TASK.data[0]] + +extern s16 gBattleAnimArgs[8]; + +extern u8 gBankSpriteIds[]; +extern s32 gAnimMoveDmg; +extern u16 gAnimMovePower; +extern u8 gBattleAnimAttacker; +extern u8 gBattleAnimTarget; + +static void AnimTask_ShakeMonStep(u8 taskId); +static void AnimTask_ShakeMon2Step(u8 taskId); +static void AnimTask_ShakeMonInPlaceStep(u8 taskId); +static void AnimTask_ShakeAndSinkMonStep(u8 taskId); +static void sub_80A8488(u8 taskId); +static void DoHorizontalLunge(struct Sprite *sprite); +static void ReverseHorizontalLungeDirection(struct Sprite *sprite); +static void DoVerticalDip(struct Sprite *sprite); +static void ReverseVerticalDipDirection(struct Sprite* sprite); +static void SlideMonToOriginalPos(struct Sprite *sprite); +static void SlideMonToOriginalPosStep(struct Sprite *sprite); +static void SlideMonToOffset(struct Sprite *sprite); +static void sub_80A8818(struct Sprite *sprite); +static void sub_80A88F0(struct Sprite *sprite); +static void AnimTask_WindUpLungePart1(u8 taskId); +static void AnimTask_WindUpLungePart2(u8 taskId); +static void AnimTask_SwayMonStep(u8 taskId); +static void AnimTask_ScaleMonAndRestoreStep(u8 taskId); +static void sub_80A8FD8(u8 taskId); +static void sub_80A913C(u8 taskId); + +const struct SpriteTemplate gHorizontalLungeSpriteTemplate = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = DoHorizontalLunge, +}; + +const struct SpriteTemplate gVerticalDipSpriteTemplate = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = DoVerticalDip, +}; + +const struct SpriteTemplate gSlideMonToOriginalPosSpriteTemplate = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SlideMonToOriginalPos, +}; + +const struct SpriteTemplate gSlideMonToOffsetSpriteTemplate = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SlideMonToOffset, +}; + +const struct SpriteTemplate gBattleAnimSpriteTemplate_83C2010 = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80A8818, +}; + +// Task to facilitate simple shaking of a pokemon's picture in battle. +// The shaking alternates between the original position and the target position. +// arg 0: anim battler +// arg 1: x pixel offset +// arg 2: y pixel offset +// arg 3: num times to shake +// arg 4: frame delay +void AnimTask_ShakeMon(u8 taskId) +{ + u8 spriteId; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + if (spriteId == 0xff) + { + DestroyAnimVisualTask(taskId); + return; + } + gSprites[spriteId].pos2.x = gBattleAnimArgs[1]; + gSprites[spriteId].pos2.y = gBattleAnimArgs[2]; + TASK.data[0] = spriteId; + TASK.data[1] = gBattleAnimArgs[3]; + TASK.data[2] = gBattleAnimArgs[4]; + TASK.data[3] = gBattleAnimArgs[4]; + TASK.data[4] = gBattleAnimArgs[1]; + TASK.data[5] = gBattleAnimArgs[2]; + TASK.func = AnimTask_ShakeMonStep; + AnimTask_ShakeMonStep(taskId); +} + +static void AnimTask_ShakeMonStep(u8 taskId) +{ + if (TASK.data[3] == 0) + { + if (SPRITE.pos2.x == 0) + { + SPRITE.pos2.x = TASK.data[4]; + } + else + { + SPRITE.pos2.x = 0; + } + if (SPRITE.pos2.y == 0) + { + SPRITE.pos2.y = TASK.data[5]; + } + else + { + SPRITE.pos2.y = 0; + } + TASK.data[3] = TASK.data[2]; + if (--TASK.data[1] == 0) + { + SPRITE.pos2.x = 0; + SPRITE.pos2.y = 0; + DestroyAnimVisualTask(taskId); + return; + } + } + else + { + TASK.data[3]--; + } +} + +// Task to facilitate simple shaking of a pokemon's picture in battle. +// The shaking alternates between the positive and negative versions of the specified pixel offsets. +// arg 0: anim battler +// arg 1: x pixel offset +// arg 2: y pixel offset +// arg 3: num times to shake +// arg 4: frame delay +void AnimTask_ShakeMon2(u8 taskId) +{ + u8 sprite; + bool8 destroy; + u8 side; + destroy = FALSE; + if (gBattleAnimArgs[0] < 4) + { + sprite = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + if (sprite == 0xff) + { + DestroyAnimVisualTask(taskId); + return; + } + } + else if (gBattleAnimArgs[0] != 8) + { + switch (gBattleAnimArgs[0]) + { + case 4: + side = GetBattlerAtPosition(0); + break; + case 5: + side = GetBattlerAtPosition(2); + break; + case 6: + side = GetBattlerAtPosition(1); + break; + case 7: + default: + side = GetBattlerAtPosition(3); + break; + } + + if (IsAnimBankSpriteVisible(side) == FALSE) + destroy = TRUE; + + sprite = gBankSpriteIds[side]; + } + else + { + sprite = gBankSpriteIds[gBattleAnimAttacker]; + } + + if (destroy) + { + DestroyAnimVisualTask(taskId); + return; + } + + gSprites[sprite].pos2.x = gBattleAnimArgs[1]; + gSprites[sprite].pos2.y = gBattleAnimArgs[2]; + TASK.data[0] = sprite; + TASK.data[1] = gBattleAnimArgs[3]; + TASK.data[2] = gBattleAnimArgs[4]; + TASK.data[3] = gBattleAnimArgs[4]; + TASK.data[4] = gBattleAnimArgs[1]; + TASK.data[5] = gBattleAnimArgs[2]; + TASK.func = AnimTask_ShakeMon2Step; + TASK.func(taskId); +} + +static void AnimTask_ShakeMon2Step(u8 taskId) +{ + if (TASK.data[3] == 0) + { + if (SPRITE.pos2.x == TASK.data[4]) + SPRITE.pos2.x = -TASK.data[4]; + else + SPRITE.pos2.x = TASK.data[4]; + + if (SPRITE.pos2.y == TASK.data[5]) + SPRITE.pos2.y = -TASK.data[5]; + else + SPRITE.pos2.y = TASK.data[5]; + + TASK.data[3] = TASK.data[2]; + if (--TASK.data[1] == 0) + { + SPRITE.pos2.x = 0; + SPRITE.pos2.y = 0; + DestroyAnimVisualTask(taskId); + return; + } + } + else + { + TASK.data[3]--; + } +} + +// Task to facilitate simple shaking of a pokemon's picture in battle. +// The shaking alternates between the positive and negative versions of the specified pixel offsets +// with respect to the current location of the mon's picture. +// arg 0: battler +// arg 1: x offset +// arg 2: y offset +// arg 3: num shakes +// arg 4: delay +void AnimTask_ShakeMonInPlace(u8 taskId) +{ + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + if (spriteId == 0xff) + { + DestroyAnimVisualTask(taskId); + return; + } + + gSprites[spriteId].pos2.x += gBattleAnimArgs[1]; + gSprites[spriteId].pos2.y += gBattleAnimArgs[2]; + TASK.data[0] = spriteId; + TASK.data[1] = 0; + TASK.data[2] = gBattleAnimArgs[3]; + TASK.data[3] = 0; + TASK.data[4] = gBattleAnimArgs[4]; + TASK.data[5] = gBattleAnimArgs[1] * 2; + TASK.data[6] = gBattleAnimArgs[2] * 2; + TASK.func = AnimTask_ShakeMonInPlaceStep; + TASK.func(taskId); +} + +static void AnimTask_ShakeMonInPlaceStep(u8 taskId) +{ + if (TASK.data[3] == 0) + { + if (TASK.data[1] & 1) + { + SPRITE.pos2.x += TASK.data[5]; + SPRITE.pos2.y += TASK.data[6]; + } + else + { + SPRITE.pos2.x -= TASK.data[5]; + SPRITE.pos2.y -= TASK.data[6]; + } + TASK.data[3] = TASK.data[4]; + if (++TASK.data[1] >= TASK.data[2]) + { + if (TASK.data[1] & 1) + { + SPRITE.pos2.x += TASK.data[5] / 2; + SPRITE.pos2.y += TASK.data[6] / 2; + } + else + { + SPRITE.pos2.x -= TASK.data[5] / 2; + SPRITE.pos2.y -= TASK.data[6] / 2; + } + DestroyAnimVisualTask(taskId); + return; + } + } + else + { + TASK.data[3]--; + } +} + +// Shakes a mon bg horizontally and moves it downward linearly. +// arg 0: battler +// arg 1: x offset +// arg 2: frame delay between each movement +// arg 3: downward speed (subpixel) +// arg 4: duration +void AnimTask_ShakeAndSinkMon(u8 taskId) +{ + u8 sprite = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + gSprites[sprite].pos2.x = gBattleAnimArgs[1]; + TASK.data[0] = sprite; + TASK.data[1] = gBattleAnimArgs[1]; + TASK.data[2] = gBattleAnimArgs[2]; + TASK.data[3] = gBattleAnimArgs[3]; + TASK.data[4] = gBattleAnimArgs[4]; + TASK.func = AnimTask_ShakeAndSinkMonStep; + TASK.func(taskId); +} + +static void AnimTask_ShakeAndSinkMonStep(u8 taskId) +{ + s16 x; + u8 sprite; + sprite = TASK.data[0]; + x = TASK.data[1]; + if (TASK.data[2] == TASK.data[8]++) + { + TASK.data[8] = 0; + if (gSprites[sprite].pos2.x == x) + x = -x; + + gSprites[sprite].pos2.x += x; + } + + TASK.data[1] = x; + TASK.data[9] += TASK.data[3]; + gSprites[sprite].pos2.y = TASK.data[9] >> 8; + if (--TASK.data[4] == 0) + { + DestroyAnimVisualTask(taskId); + return; + } +} + +// Moves a mon bg picture along an elliptical path that begins +// and ends at the mon's origin location. +// arg 0: battler +// arg 1: ellipse width +// arg 2: ellipse height +// arg 3: num loops +// arg 4: speed (valid values are 0-5) +void AnimTask_TranslateMonElliptical(u8 taskId) +{ + u8 i; + u8 spriteId; + u8 wavePeriod; + + wavePeriod = 1; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + if (gBattleAnimArgs[4] > 5) + gBattleAnimArgs[4] = 5; + + for (i = 0; i < gBattleAnimArgs[4]; i++) + { + wavePeriod <<= 1; + } + + TASK.data[0] = spriteId; + TASK.data[1] = gBattleAnimArgs[1]; + TASK.data[2] = gBattleAnimArgs[2]; + TASK.data[3] = gBattleAnimArgs[3]; + TASK.data[4] = wavePeriod; + TASK.func = sub_80A8488; + TASK.func(taskId); +} + +static void sub_80A8488(u8 taskId) +{ + u8 spriteId = TASK.data[0]; + gSprites[spriteId].pos2.x = Sin(TASK.data[5], TASK.data[1]); + gSprites[spriteId].pos2.y = -Cos(TASK.data[5], TASK.data[2]); + gSprites[spriteId].pos2.y += TASK.data[2]; + TASK.data[5] += TASK.data[4]; + TASK.data[5] &= 0xff; + + if (TASK.data[5] == 0) + TASK.data[3]--; + + if (TASK.data[3] == 0) + { + gSprites[spriteId].pos2.x = 0; + gSprites[spriteId].pos2.y = 0; + DestroyAnimVisualTask(taskId); + return; + } +} + +// Moves a mon bg picture along an elliptical path that begins +// and ends at the mon's origin location. Reverses the direction +// of the path if it's not on the player's side of the battle. +// arg 0: battler +// arg 1: ellipse width +// arg 2: ellipse height +// arg 3: num loops +// arg 4: speed (valid values are 0-5) +void AnimTask_TranslateMonEllipticalRespectSide(u8 taskId) +{ + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + + AnimTask_TranslateMonElliptical(taskId); +} + +// Performs a simple horizontal lunge, where the mon moves +// horizontally, and then moves back in the opposite direction. +// arg 0: duration of single lunge direction +// arg 1: x pixel delta that is applied each frame +static void DoHorizontalLunge(struct Sprite *sprite) +{ + sprite->invisible = TRUE; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->data[1] = -gBattleAnimArgs[1]; + else + sprite->data[1] = gBattleAnimArgs[1]; + + sprite->data[0] = gBattleAnimArgs[0]; + sprite->data[2] = 0; + sprite->data[3] = gBankSpriteIds[gBattleAnimAttacker]; + sprite->data[4] = gBattleAnimArgs[0]; + StoreSpriteCallbackInData(sprite, ReverseHorizontalLungeDirection); + sprite->callback = TranslateMonBGUntil; +} + +static void ReverseHorizontalLungeDirection(struct Sprite *sprite) +{ + sprite->data[0] = sprite->data[4]; + sprite->data[1] = -sprite->data[1]; + sprite->callback = TranslateMonBGUntil; + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); +} + +// Performs a simple vertical dipping motion, where moves vertically, and then +// moves back in the opposite direction. +// arg 0: duration of single dip direction +// arg 1: y pixel delta that is applied each frame +// arg 2: battler +static void DoVerticalDip(struct Sprite *sprite) +{ + u8 spriteId; + sprite->invisible = TRUE; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]); + sprite->data[0] = gBattleAnimArgs[0]; + sprite->data[1] = 0; + sprite->data[2] = gBattleAnimArgs[1]; + sprite->data[3] = spriteId; + sprite->data[4] = gBattleAnimArgs[0]; + StoreSpriteCallbackInData(sprite, ReverseVerticalDipDirection); + sprite->callback = TranslateMonBGUntil; +} + +static void ReverseVerticalDipDirection(struct Sprite *sprite) +{ + sprite->data[0] = sprite->data[4]; + sprite->data[2] = -sprite->data[2]; + sprite->callback = TranslateMonBGUntil; + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); +} + +// Linearly slides a mon's bg picture back to its original sprite position. +// The sprite parameter is a dummy sprite used for facilitating the movement with its callback. +// arg 0: 1 = target or 0 = attacker +// arg 1: direction (0 = horizontal and vertical, 1 = horizontal only, 2 = vertical only) +// arg 2: duration +static void SlideMonToOriginalPos(struct Sprite *sprite) +{ + int something; + int monSpriteId; + if (!gBattleAnimArgs[0]) + monSpriteId = gBankSpriteIds[gBattleAnimAttacker]; + else + monSpriteId = gBankSpriteIds[gBattleAnimTarget]; + + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gSprites[monSpriteId].pos1.x + gSprites[monSpriteId].pos2.x; + sprite->data[2] = gSprites[monSpriteId].pos1.x; + sprite->data[3] = gSprites[monSpriteId].pos1.y + gSprites[monSpriteId].pos2.y; + sprite->data[4] = gSprites[monSpriteId].pos1.y; + something = 0; + InitSpriteDataForLinearTranslation(sprite); + sprite->data[3] = something; + sprite->data[4] = something; + sprite->data[5] = gSprites[monSpriteId].pos2.x; + sprite->data[6] = gSprites[monSpriteId].pos2.y; + sprite->invisible = TRUE; + + if (gBattleAnimArgs[1] == 1) + sprite->data[2] = something; + else if (gBattleAnimArgs[1] == 2) + sprite->data[1] = something; + + sprite->data[7] = gBattleAnimArgs[1]; + sprite->data[7] |= monSpriteId << 8; + sprite->callback = SlideMonToOriginalPosStep; +} + +static void SlideMonToOriginalPosStep(struct Sprite *sprite) +{ + s8 monSpriteId; + u8 lo; + struct Sprite *monSprite; + + lo = sprite->data[7] & 0xff; + monSpriteId = sprite->data[7] >> 8; + monSprite = &gSprites[monSpriteId]; + if (sprite->data[0] == 0) + { + if (lo < 2) + monSprite->pos2.x = 0; + + if (lo == 2 || lo == 0) + monSprite->pos2.y = 0; + + DestroyAnimSprite(sprite); + } + else + { + sprite->data[0]--; + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + monSprite->pos2.x = (s8)(sprite->data[3] >> 8) + sprite->data[5]; + monSprite->pos2.y = (s8)(sprite->data[4] >> 8) + sprite->data[6]; + } +} + +// Linearly translates a mon to a target offset. The horizontal offset +// is mirrored for the opponent's pokemon, and the vertical offset +// is only mirrored if arg 3 is set to 1. +// arg 0: 0 = attacker, 1 = target +// arg 1: target x pixel offset +// arg 2: target y pixel offset +// arg 3: mirror vertical translation for opposite battle side +// arg 4: duration +static void SlideMonToOffset(struct Sprite *sprite) +{ + u8 battler; + u8 monSpriteId; + if (!gBattleAnimArgs[0]) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + + monSpriteId = gBankSpriteIds[battler]; + if (GetBattlerSide(battler) != B_SIDE_PLAYER) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + if (gBattleAnimArgs[3] == 1) + { + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + } + } + + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[1] = gSprites[monSpriteId].pos1.x; + sprite->data[2] = gSprites[monSpriteId].pos1.x + gBattleAnimArgs[1]; + sprite->data[3] = gSprites[monSpriteId].pos1.y; + sprite->data[4] = gSprites[monSpriteId].pos1.y + gBattleAnimArgs[2]; + InitSpriteDataForLinearTranslation(sprite); + sprite->data[3] = 0; + sprite->data[4] = 0; + sprite->data[5] = monSpriteId; + sprite->invisible = TRUE; + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); + sprite->callback = TranslateMonBGSubPixelUntil; +} + +static void sub_80A8818(struct Sprite *sprite) +{ + u8 spriteId; + u8 v1; + sprite->invisible = TRUE; + if (!gBattleAnimArgs[0]) + { + v1 = gBattleAnimAttacker; + } + else + { + v1 = gBattleAnimTarget; + } + spriteId = gBankSpriteIds[v1]; + if (GetBattlerSide(v1)) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + if (gBattleAnimArgs[3] == 1) + { + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + } + } + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[1] = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x; + sprite->data[2] = sprite->data[1] + gBattleAnimArgs[1]; + sprite->data[3] = gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y; + sprite->data[4] = sprite->data[3] + gBattleAnimArgs[2]; + InitSpriteDataForLinearTranslation(sprite); + sprite->data[3] = gSprites[spriteId].pos2.x << 8; + sprite->data[4] = gSprites[spriteId].pos2.y << 8; + sprite->data[5] = spriteId; + sprite->data[6] = gBattleAnimArgs[5]; + if (!gBattleAnimArgs[5]) + { + StoreSpriteCallbackInData(sprite, DestroyAnimSprite); + } + else + { + StoreSpriteCallbackInData(sprite, sub_80A88F0); + } + sprite->callback = TranslateMonBGSubPixelUntil; +} + + +static void sub_80A88F0(struct Sprite *sprite) +{ + gSprites[sprite->data[5]].pos2.x = 0; + gSprites[sprite->data[5]].pos2.y = 0; + DestroyAnimSprite(sprite); +} + +// Task to facilitate a two-part translation animation, in which the sprite +// is first translated in an arc to one position. Then, it "lunges" to a target +// x offset. Used in TAKE_DOWN, for example. +// arg 0: anim bank +// arg 1: horizontal speed (subpixel) +// arg 2: wave amplitude +// arg 3: first duration +// arg 4: delay before starting lunge +// arg 5: target x offset for lunge +// arg 6: lunge duration +void AnimTask_WindUpLunge(u8 taskId) +{ + s16 wavePeriod = 0x8000 / gBattleAnimArgs[3]; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + gBattleAnimArgs[5] = -gBattleAnimArgs[5]; + } + TASK.data[0] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + TASK.data[1] = (gBattleAnimArgs[1] << 8) / gBattleAnimArgs[3]; + TASK.data[2] = gBattleAnimArgs[2]; + TASK.data[3] = gBattleAnimArgs[3]; + TASK.data[4] = gBattleAnimArgs[4]; + TASK.data[5] = (gBattleAnimArgs[5] << 8) / gBattleAnimArgs[6]; + TASK.data[6] = gBattleAnimArgs[6]; + TASK.data[7] = wavePeriod; + TASK.func = AnimTask_WindUpLungePart1; +} + +static void AnimTask_WindUpLungePart1(u8 taskId) +{ + u8 spriteId; + spriteId = TASK.data[0]; + TASK.data[11] += TASK.data[1]; + gSprites[spriteId].pos2.x = TASK.data[11] >> 8; + gSprites[spriteId].pos2.y = Sin((u8)(TASK.data[10] >> 8), TASK.data[2]); + TASK.data[10] += TASK.data[7]; + if (--TASK.data[3] == 0) + { + TASK.func = AnimTask_WindUpLungePart2; + } +} + +static void AnimTask_WindUpLungePart2(u8 taskId) +{ + u8 spriteId; + if (TASK.data[4] > 0) + { + TASK.data[4]--; + } + else + { + spriteId = TASK.data[0]; + TASK.data[12] += TASK.data[5]; + gSprites[spriteId].pos2.x = (TASK.data[12] >> 8) + (TASK.data[11] >> 8); + if (--TASK.data[6] == 0) + { + DestroyAnimVisualTask(taskId); + return; + } + } +} + +static void sub_80A8B3C(u8 taskId); + +void sub_80A8A80(u8 taskId) +{ + u8 spriteId; + switch (gBattleAnimArgs[0]) + { + case 0: + case 1: + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + break; + case 2: + if (!IsAnimBankSpriteVisible(gBattleAnimAttacker ^ 2)) + { + DestroyAnimVisualTask(taskId); + return; + } + spriteId = gBankSpriteIds[gBattleAnimAttacker ^ 2]; + break; + case 3: + if (!IsAnimBankSpriteVisible(gBattleAnimTarget ^ 2)) + { + DestroyAnimVisualTask(taskId); + return; + } + spriteId = gBankSpriteIds[gBattleAnimTarget ^ 2]; + break; + default: + DestroyAnimVisualTask(taskId); + return; + } + TASK.data[0] = spriteId; + if (GetBattlerSide(gBattleAnimTarget)) + { + TASK.data[1] = gBattleAnimArgs[1]; + } + else + { + TASK.data[1] = -gBattleAnimArgs[1]; + } + TASK.func = sub_80A8B3C; +} + +static void sub_80A8B3C(u8 taskId) +{ + u8 spriteId = TASK.data[0]; + gSprites[spriteId].pos2.x += TASK.data[1]; + if (gSprites[spriteId].pos2.x + gSprites[spriteId].pos1.x + 0x20 > 0x130u) + { + DestroyAnimVisualTask(taskId); + return; + } +} + +// Task that facilitates translating the mon bg picture back and forth +// in a swaying motion (uses Sine wave). It can sway either horizontally +// or vertically, but not both. +// arg 0: direction (0 = horizontal, 1 = vertical) +// arg 1: wave amplitude +// arg 2: wave period +// arg 3: num sways +// arg 4: which mon (0 = attacker, 1`= target) +void AnimTask_SwayMon(u8 taskId) +{ + u8 spriteId; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[4]); + TASK.data[0] = gBattleAnimArgs[0]; + TASK.data[1] = gBattleAnimArgs[1]; + TASK.data[2] = gBattleAnimArgs[2]; + TASK.data[3] = gBattleAnimArgs[3]; + TASK.data[4] = spriteId; + + if (gBattleAnimArgs[4] == 0) + TASK.data[5] = gBattleAnimAttacker; + else + TASK.data[5] = gBattleAnimTarget; + + TASK.data[12] = 1; + TASK.func = AnimTask_SwayMonStep; +} + +static void AnimTask_SwayMonStep(u8 taskId) +{ + s16 sineValue; + u8 spriteId; + int waveIndex; + u16 sineIndex; + + spriteId = TASK.data[4]; + sineIndex = TASK.data[10] + TASK.data[2]; + TASK.data[10] = sineIndex; + waveIndex = sineIndex >> 8; + sineValue = Sin(waveIndex, TASK.data[1]); + + if (TASK.data[0] == 0) + { + gSprites[spriteId].pos2.x = sineValue; + } + else + { + if (GetBattlerSide(TASK.data[5]) == B_SIDE_PLAYER) + { + gSprites[spriteId].pos2.y = (sineValue >= 0) ? sineValue : -sineValue; + } + else + { + gSprites[spriteId].pos2.y = (sineValue >= 0) ? -sineValue : sineValue; + } + } + + if (((waveIndex >= 0x80u) && (TASK.data[11] == 0) && (TASK.data[12] == 1)) + || ((waveIndex < 0x7fu) && (TASK.data[11] == 1) && (TASK.data[12] == 0))) + { + TASK.data[11] ^= 1; + TASK.data[12] ^= 1; + if (--TASK.data[3] == 0) + { + gSprites[spriteId].pos2.x = 0; + gSprites[spriteId].pos2.y = 0; + DestroyAnimVisualTask(taskId); + return; + } + } +} + +// Scales a mon's sprite, and then scales back to its original dimensions. +// arg 0: x scale delta +// arg 1: y scale delta +// arg 2: duration +// arg 3: anim bank +// arg 4: sprite object mode +void AnimTask_ScaleMonAndRestore(u8 taskId) +{ + u8 spriteId; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[3]); + PrepareBattlerSpriteForRotScale(spriteId, gBattleAnimArgs[4]); + TASK.data[0] = gBattleAnimArgs[0]; + TASK.data[1] = gBattleAnimArgs[1]; + TASK.data[2] = gBattleAnimArgs[2]; + TASK.data[3] = gBattleAnimArgs[2]; + TASK.data[4] = spriteId; + TASK.data[10] = 0x100; + TASK.data[11] = 0x100; + TASK.func = AnimTask_ScaleMonAndRestoreStep; +} + +static void AnimTask_ScaleMonAndRestoreStep(u8 taskId) +{ + u8 spriteId; + TASK.data[10] += TASK.data[0]; + TASK.data[11] += TASK.data[1]; + spriteId = TASK.data[4]; + obj_id_set_rotscale(spriteId, TASK.data[10], TASK.data[11], 0); + if (--TASK.data[2] == 0) + { + if (TASK.data[3] > 0) + { + TASK.data[0] = -TASK.data[0]; + TASK.data[1] = -TASK.data[1]; + TASK.data[2] = TASK.data[3]; + TASK.data[3] = 0; + } + else + { + sub_8078F40(spriteId); + DestroyAnimVisualTask(taskId); + return; + } + } +} + +void sub_80A8E04(u8 taskId) +{ + u8 spriteId; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]); + PrepareBattlerSpriteForRotScale(spriteId, 0); + TASK.data[1] = 0; + TASK.data[2] = gBattleAnimArgs[0]; + if (gBattleAnimArgs[3] != 1) + { + TASK.data[3] = 0; + } + else + { + TASK.data[3] = gBattleAnimArgs[0] * gBattleAnimArgs[1]; + } + TASK.data[4] = gBattleAnimArgs[1]; + TASK.data[5] = spriteId; + TASK.data[6] = gBattleAnimArgs[3]; + if (IsContest()) + { + TASK.data[7] = 1; + } + else + { + if (gBattleAnimArgs[2] == 0) + { + TASK.data[7] = !GetBattlerSide(gBattleAnimAttacker); + } + else + { + TASK.data[7] = !GetBattlerSide(gBattleAnimTarget); + } + } + if (TASK.data[7]) + { + if (!IsContest()) + { + TASK.data[3] *= -1; + TASK.data[4] *= -1; + } + } + TASK.func = sub_80A8FD8; +} + +void sub_80A8EFC(u8 taskId) +{ + u8 spriteId; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]); + PrepareBattlerSpriteForRotScale(spriteId, 0); + TASK.data[1] = 0; + TASK.data[2] = gBattleAnimArgs[0]; + if (gBattleAnimArgs[2] == 0) + { + if (GetBattlerSide(gBattleAnimAttacker)) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + } + } + else + { + if (GetBattlerSide(gBattleAnimTarget)) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + } + } + if (gBattleAnimArgs[3] != 1) + { + TASK.data[3] = 0; + } + else + { + TASK.data[3] = gBattleAnimArgs[0] * gBattleAnimArgs[1]; + } + TASK.data[4] = gBattleAnimArgs[1]; + TASK.data[5] = spriteId; + TASK.data[6] = gBattleAnimArgs[3]; + TASK.data[7] = 1; + TASK.data[3] *= -1; + TASK.data[4] *= -1; + TASK.func = sub_80A8FD8; +} + +static void sub_80A8FD8(u8 taskId) +{ + TASK.data[3] += TASK.data[4]; + obj_id_set_rotscale(TASK.data[5], 0x100, 0x100, TASK.data[3]); + if (TASK.data[7]) + { + sub_8078F9C(TASK.data[5]); + } + if (++TASK.data[1] >= TASK.data[2]) + { + switch (TASK.data[6]) + { + case 1: + sub_8078F40(TASK.data[5]); + case 0: + default: + DestroyAnimVisualTask(taskId); + return; + case 2: + TASK.data[1] = 0; + TASK.data[4] *= -1; + TASK.data[6] = 1; + break; + } + } +} + +void sub_80A9058(u8 taskId) +{ + if (!gBattleAnimArgs[0]) + { + TASK.data[15] = gAnimMovePower / 12; + if (TASK.data[15] < 1) + { + TASK.data[15] = 1; + } + if (TASK.data[15] > 16) + { + TASK.data[15] = 16; + } + } + else + { + TASK.data[15] = gAnimMoveDmg / 12; + if (TASK.data[15] < 1) + { + TASK.data[15] = 1; + } + if (TASK.data[15] > 16) + { + TASK.data[15] = 16; + } + } + TASK.data[14] = TASK.data[15] / 2; + TASK.data[13] = TASK.data[14] + (TASK.data[15] & 1); + TASK.data[12] = 0; + TASK.data[10] = gBattleAnimArgs[3]; + TASK.data[11] = gBattleAnimArgs[4]; + TASK.data[7] = GetAnimBattlerSpriteId(1); + TASK.data[8] = gSprites[TASK.data[7]].pos2.x; + TASK.data[9] = gSprites[TASK.data[7]].pos2.y; + TASK.data[0] = 0; + TASK.data[1] = gBattleAnimArgs[1]; + TASK.data[2] = gBattleAnimArgs[2]; + TASK.func = sub_80A913C; +} + +static void sub_80A913C(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + if (++task->data[0] > task->data[1]) + { + task->data[0] = 0; + task->data[12] = (task->data[12] + 1) & 1; + if (task->data[10]) + { + if (task->data[12]) + { + gSprites[task->data[7]].pos2.x = task->data[8] + task->data[13]; + } + else + { + gSprites[task->data[7]].pos2.x = task->data[8] - task->data[14]; + } + } + if (task->data[11]) + { + if (task->data[12]) + { + gSprites[task->data[7]].pos2.y = task->data[15]; + } + else + { + gSprites[task->data[7]].pos2.y = 0; + } + } + if (!--task->data[2]) + { + gSprites[task->data[7]].pos2.x = 0; + gSprites[task->data[7]].pos2.y = 0; + DestroyAnimVisualTask(taskId); + return; + } + } +} diff --git a/src/battle_anim_special.c b/src/battle_anim_special.c new file mode 100755 index 000000000..7d158f671 --- /dev/null +++ b/src/battle_anim_special.c @@ -0,0 +1,2170 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "battle_anim_special.h" +#include "battle_interface.h" +#include "blend_palette.h" +#include "decompress.h" +#include "ewram.h" +#include "m4a.h" +#include "main.h" +#include "palette.h" +#include "pokeball.h" +#include "rom_8077ABC.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "trig.h" +#include "util.h" +#include "constants/items.h" +#include "constants/songs.h" + +extern int gUnknown_03005F0C; +extern u16 gUnknown_03005F10; +extern u16 gUnknown_03005F14; + +extern s16 gBattleAnimArgs[]; +extern u8 gBattleAnimAttacker; +extern u8 gBattleAnimTarget; +extern u8 gHealthboxIDs[]; +extern u8 gBankSpriteIds[]; +extern u16 gBattlerPartyIndexes[]; +extern u16 gLastUsedItem; +extern u8 gDoingBattleAnim; +extern u8 gEffectBank; + +extern const u8 gUnknown_08D2EE48[]; +extern const u8 gUnknown_08D2EDFC[]; +extern const u16 gUnknown_08D2E150[]; +extern const struct SpriteTemplate gSpriteTemplates_840B3B4[]; +extern const struct SpriteTemplate gSpriteTemplate_8402500; +extern const struct SpriteTemplate gBattleAnimSpriteTemplate_84024E8; +extern const struct CompressedSpriteSheet gBattleAnimPicTable[]; +extern const struct CompressedSpritePalette gBattleAnimPaletteTable[]; + +static void sub_813F300(u8 taskId); +static void sub_813F6CC(u8 taskId); +static void sub_813FD34(u8 taskId); +static void sub_813FD90(struct Sprite *sprite); +static void sub_813FB7C(u8 taskId); +static void sub_813FCBC(u8 taskId); +static void sub_813FDC0(struct Sprite *sprite); +static void sub_813FE70(struct Sprite *sprite); +static void sub_81407B8(struct Sprite *sprite); +static void sub_813FEC8(struct Sprite *sprite); +static void sub_8140014(struct Sprite *sprite); +static void sub_8140058(struct Sprite *sprite); +static void sub_8140410(struct Sprite *sprite); +static void sub_8140158(struct Sprite *sprite); +static void sub_81401A0(struct Sprite *sprite); +static void sub_8140434(struct Sprite *sprite); +static void sub_81405F4(struct Sprite *sprite); +static void sub_8140454(struct Sprite *sprite); +static void sub_81404E4(struct Sprite *sprite); +static void sub_81405C8(struct Sprite *sprite); +static void sub_81406BC(struct Sprite *sprite); +static void sub_81407F4(struct Sprite *sprite); +static void PokeBallOpenParticleAnimation_Step1(struct Sprite *sprite); +static void PokeBallOpenParticleAnimation_Step2(struct Sprite *sprite); +static void DestroyBallOpenAnimationParticle(struct Sprite *sprite); +static void FanOutBallOpenParticles_Step1(struct Sprite *sprite); +static void RepeatBallOpenParticleAnimation_Step1(struct Sprite *sprite); +static void PremierBallOpenParticleAnimation_Step1(struct Sprite *sprite); +static void sub_81413DC(u8 taskId); +static void sub_814146C(u8 taskId); +static void sub_81414BC(u8 taskId); +static void sub_814191C(u8 taskId); +static void sub_8141B20(struct Sprite *sprite); +static void sub_8141B74(struct Sprite *sprite); +static void sub_8141AD8(u8 taskId); +static void sub_8141CBC(struct Sprite *sprite); +static void sub_8141CF4(struct Sprite *sprite); +static void sub_8141D20(struct Sprite *sprite); + +extern const u8 gBattleAnimSpriteSheet_Particles[]; +const struct CompressedSpriteSheet gBallOpenParticleSpritesheets[] = +{ + {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6EC}, + {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6ED}, + {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6EE}, + {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6EF}, + {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F0}, + {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F1}, + {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F2}, + {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F3}, + {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F4}, + {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F5}, + {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F6}, + {gBattleAnimSpriteSheet_Particles, 0x100, 0xD6F7}, +}; + +extern const u8 gBattleAnimSpritePalette_136[]; +const struct CompressedSpritePalette gBallOpenParticlePalettes[] = +{ + {gBattleAnimSpritePalette_136, 0xD6EC}, + {gBattleAnimSpritePalette_136, 0xD6ED}, + {gBattleAnimSpritePalette_136, 0xD6EE}, + {gBattleAnimSpritePalette_136, 0xD6EF}, + {gBattleAnimSpritePalette_136, 0xD6F0}, + {gBattleAnimSpritePalette_136, 0xD6F1}, + {gBattleAnimSpritePalette_136, 0xD6F2}, + {gBattleAnimSpritePalette_136, 0xD6F3}, + {gBattleAnimSpritePalette_136, 0xD6F4}, + {gBattleAnimSpritePalette_136, 0xD6F5}, + {gBattleAnimSpritePalette_136, 0xD6F6}, + {gBattleAnimSpritePalette_136, 0xD6F7}, +}; + +const union AnimCmd gSpriteAnim_840B318[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_FRAME(1, 1), + ANIMCMD_FRAME(2, 1), + ANIMCMD_FRAME(0, 1, .hFlip = TRUE), + ANIMCMD_FRAME(2, 1), + ANIMCMD_FRAME(1, 1), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gSpriteAnim_840B334[] = +{ + ANIMCMD_FRAME(3, 1), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_840B33C[] = +{ + ANIMCMD_FRAME(4, 1), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_840B344[] = +{ + ANIMCMD_FRAME(5, 1), + ANIMCMD_END, +}; + +const union AnimCmd gSpriteAnim_840B34C[] = +{ + ANIMCMD_FRAME(6, 4), + ANIMCMD_FRAME(7, 4), + ANIMCMD_JUMP(0), +}; + +const union AnimCmd gSpriteAnim_840B358[] = +{ + ANIMCMD_FRAME(7, 4), + ANIMCMD_END, +}; + +const union AnimCmd *const gSpriteAnimTable_840B360[] = +{ + gSpriteAnim_840B318, + gSpriteAnim_840B334, + gSpriteAnim_840B33C, + gSpriteAnim_840B344, + gSpriteAnim_840B34C, + gSpriteAnim_840B358, +}; + +const u8 gBallOpenParticleAnimNums[] = +{ + 0, + 0, + 0, + 5, + 1, + 2, + 2, + 3, + 5, + 5, + 4, + 4, +}; + +void PokeBallOpenParticleAnimation(u8); +void GreatBallOpenParticleAnimation(u8); +void SafariBallOpenParticleAnimation(u8); +void UltraBallOpenParticleAnimation(u8); +void MasterBallOpenParticleAnimation(u8); +void SafariBallOpenParticleAnimation(u8); +void DiveBallOpenParticleAnimation(u8); +void UltraBallOpenParticleAnimation(u8); +void RepeatBallOpenParticleAnimation(u8); +void TimerBallOpenParticleAnimation(u8); +void GreatBallOpenParticleAnimation(u8); +void PremierBallOpenParticleAnimation(u8); + +const TaskFunc gBallOpenParticleAnimationFuncs[] = +{ + PokeBallOpenParticleAnimation, + GreatBallOpenParticleAnimation, + SafariBallOpenParticleAnimation, + UltraBallOpenParticleAnimation, + MasterBallOpenParticleAnimation, + SafariBallOpenParticleAnimation, + DiveBallOpenParticleAnimation, + UltraBallOpenParticleAnimation, + RepeatBallOpenParticleAnimation, + TimerBallOpenParticleAnimation, + GreatBallOpenParticleAnimation, + PremierBallOpenParticleAnimation, +}; + +const struct SpriteTemplate gSpriteTemplates_840B3B4[] = +{ + { + .tileTag = 55020, + .paletteTag = 55020, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_840B360, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55021, + .paletteTag = 55021, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_840B360, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55022, + .paletteTag = 55022, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_840B360, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55023, + .paletteTag = 55023, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_840B360, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55024, + .paletteTag = 55024, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_840B360, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55025, + .paletteTag = 55025, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_840B360, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55026, + .paletteTag = 55026, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_840B360, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55027, + .paletteTag = 55027, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_840B360, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55028, + .paletteTag = 55028, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_840B360, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55029, + .paletteTag = 55029, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_840B360, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55030, + .paletteTag = 55030, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_840B360, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55031, + .paletteTag = 55031, + .oam = &gOamData_837DF24, + .anims = gSpriteAnimTable_840B360, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, +}; + +const u16 gUnknown_0840B4D4[] = +{ + 0x7ADF, + 0x7AF0, + 0x53D7, + 0x3FFF, + 0x7297, + 0x67F5, + 0x7B2C, + 0x2B7E, + 0x431F, + 0x7BDD, + 0x2A3F, + 0x293F, + 0x0000, + 0x0201, + 0x0403, + 0x0101, + 0x0100, + 0x0503, + 0x0506, + 0x0004, +}; + +static void sub_8141C30(struct Sprite *sprite); +const struct SpriteTemplate gBattleAnimSpriteTemplate_840B4FC = +{ + .tileTag = ANIM_TAG_UNUSED_RED_BRICK, + .paletteTag = ANIM_TAG_UNUSED_RED_BRICK, + .oam = &gOamData_837DF2C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8141C30, +}; + +void unref_sub_813F0F4(u8 taskId) +{ + struct Struct_sub_8078914 subStruct; + u8 healthBoxSpriteId; + u8 battler; + u8 spriteId1, spriteId2, spriteId3, spriteId4; + + battler = gBattleAnimAttacker; + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + REG_WININ = 0x3F3F; + REG_WINOUT = 0x3F3D; + REG_DISPCNT |= DISPCNT_OBJWIN_ON; + REG_BLDCNT = 0x3F42; + REG_BLDALPHA = 0x1000; + REG_BG1CNT_BITFIELD.priority = 0; + REG_BG1CNT_BITFIELD.screenSize = 0; + REG_BG1CNT_BITFIELD.areaOverflowMode = 1; + REG_BG1CNT_BITFIELD.charBaseBlock = 1; + + healthBoxSpriteId = gHealthboxIDs[battler]; + spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam; + spriteId2 = gSprites[healthBoxSpriteId].data[5]; + spriteId3 = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy); + spriteId4 = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy); + gSprites[healthBoxSpriteId].oam.priority = 1; + gSprites[spriteId1].oam.priority = 1; + gSprites[spriteId2].oam.priority = 1; + gSprites[spriteId3] = gSprites[healthBoxSpriteId]; + gSprites[spriteId4] = gSprites[spriteId1]; + gSprites[spriteId3].oam.objMode = ST_OAM_OBJ_WINDOW; + gSprites[spriteId4].oam.objMode = ST_OAM_OBJ_WINDOW; + gSprites[spriteId3].callback = SpriteCallbackDummy; + gSprites[spriteId4].callback = SpriteCallbackDummy; + + sub_8078914(&subStruct); + DmaFill32Defvars(3, 0, subStruct.field_4, 0x1000); + LZDecompressVram(&gUnknown_08D2EE48, subStruct.field_4); + LZDecompressVram(&gUnknown_08D2EDFC, subStruct.field_0); + LoadCompressedPalette(gUnknown_08D2E150, subStruct.field_8 << 4, 32); + + gBattle_BG1_X = -gSprites[spriteId3].pos1.x + 32; + gBattle_BG1_Y = -gSprites[spriteId3].pos1.y - 32; + gTasks[taskId].data[1] = 640; + gTasks[taskId].data[0] = spriteId3; + gTasks[taskId].data[2] = spriteId4; + gTasks[taskId].func = sub_813F300; +} + +static void sub_813F300(u8 taskId) +{ + struct Struct_sub_8078914 subStruct; + u8 spriteId1, spriteId2; + u8 battler; + + battler = gBattleAnimAttacker; + gTasks[taskId].data[13] += gTasks[taskId].data[1]; + gBattle_BG1_Y += (u16)gTasks[taskId].data[13] >> 8; + gTasks[taskId].data[13] &= 0xFF; + + switch (gTasks[taskId].data[15]) + { + case 0: + if (gTasks[taskId].data[11]++ > 1) + { + gTasks[taskId].data[11] = 0; + gTasks[taskId].data[12]++; + REG_BLDALPHA = ((16 - gTasks[taskId].data[12]) << 8) | gTasks[taskId].data[12]; + if (gTasks[taskId].data[12] == 8) + gTasks[taskId].data[15]++; + } + break; + case 1: + if (++gTasks[taskId].data[10] == 30) + gTasks[taskId].data[15]++; + break; + case 2: + if (gTasks[taskId].data[11]++ > 1) + { + gTasks[taskId].data[11] = 0; + gTasks[taskId].data[12]--; + REG_BLDALPHA = ((16 - gTasks[taskId].data[12]) << 8) | gTasks[taskId].data[12]; + if (gTasks[taskId].data[12] == 0) + { + sub_8076464(0); + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + REG_WININ = 0x3F3F; + REG_WINOUT = 0x3F3F; + if (!IsContest()) + REG_BG1CNT_BITFIELD.charBaseBlock = 0; + + REG_DISPCNT ^= DISPCNT_OBJWIN_ON; + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + DestroySprite(&gSprites[gTasks[taskId].data[0]]); + DestroySprite(&gSprites[gTasks[taskId].data[2]]); + sub_8078914(&subStruct); + DmaFill32Defvars(3, 0, subStruct.field_4, 0x800); + REG_BG1CNT_BITFIELD.areaOverflowMode = 0; + spriteId1 = gSprites[gHealthboxIDs[battler]].oam.affineParam; + spriteId2 = gSprites[gHealthboxIDs[battler]].data[5]; + gSprites[gHealthboxIDs[battler]].oam.priority = 1; + gSprites[spriteId1].oam.priority = 1; + gSprites[spriteId2].oam.priority = 1; + DestroyAnimVisualTask(taskId); + } + } + break; + } +} + +void sub_813F4EC(u8 taskId) +{ + u8 healthBoxSpriteId; + u8 spriteId1, spriteId2; + u8 paletteNum1, paletteNum2; + u16 offset1, offset2; + + healthBoxSpriteId = gHealthboxIDs[gBattleAnimAttacker]; + spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam; + spriteId2 = gSprites[healthBoxSpriteId].data[5]; + paletteNum1 = AllocSpritePalette(0xD709); + paletteNum2 = AllocSpritePalette(0xD70A); + + offset1 = (gSprites[healthBoxSpriteId].oam.paletteNum * 16) + 0x100; + offset2 = (gSprites[spriteId2].oam.paletteNum * 16) + 0x100; + LoadPalette(&gPlttBufferUnfaded[offset1], paletteNum1 * 16 + 0x100, 0x20); + LoadPalette(&gPlttBufferUnfaded[offset2], paletteNum2 * 16 + 0x100, 0x20); + + gSprites[healthBoxSpriteId].oam.paletteNum = paletteNum1; + gSprites[spriteId1].oam.paletteNum = paletteNum1; + gSprites[spriteId2].oam.paletteNum = paletteNum2; + DestroyAnimVisualTask(taskId); +} + +void sub_813F5E8(u8 taskId) +{ + u8 healthBoxSpriteId; + u8 spriteId1, spriteId2; + u8 paletteIndex1, paletteIndex2; + + healthBoxSpriteId = gHealthboxIDs[gBattleAnimAttacker]; + spriteId1 = gSprites[healthBoxSpriteId].oam.affineParam; + spriteId2 = gSprites[healthBoxSpriteId].data[5]; + + FreeSpritePaletteByTag(0xD709); + FreeSpritePaletteByTag(0xD70A); + paletteIndex1 = IndexOfSpritePaletteTag(0xD6FF); + paletteIndex2 = IndexOfSpritePaletteTag(0xD704); + gSprites[healthBoxSpriteId].oam.paletteNum = paletteIndex1; + gSprites[spriteId1].oam.paletteNum = paletteIndex1; + gSprites[spriteId2].oam.paletteNum = paletteIndex2; + + DestroyAnimVisualTask(taskId); +} + +void sub_813F6A0(u8 taskId) +{ + gTasks[taskId].data[10] = gBattleAnimArgs[0]; + gTasks[taskId].data[11] = gBattleAnimArgs[1]; + gTasks[taskId].func = sub_813F6CC; +} + +static void sub_813F6CC(u8 taskId) +{ + u8 paletteNum; + int paletteOffset, colorOffset; + + gTasks[taskId].data[0]++; + if (gTasks[taskId].data[0]++ >= gTasks[taskId].data[11]) + { + gTasks[taskId].data[0] = 0; + paletteNum = IndexOfSpritePaletteTag(0xD709); + colorOffset = gTasks[taskId].data[10] == 0 ? 6 : 2; + switch (gTasks[taskId].data[1]) + { + case 0: + gTasks[taskId].data[2] += 2; + if (gTasks[taskId].data[2] > 16) + gTasks[taskId].data[2] = 16; + + paletteOffset = paletteNum * 16 + 0x100; + BlendPalette(paletteOffset + colorOffset, 1, gTasks[taskId].data[2], RGB(20, 27, 31)); + if (gTasks[taskId].data[2] == 16) + gTasks[taskId].data[1]++; + break; + case 1: + gTasks[taskId].data[2] -= 2; + if (gTasks[taskId].data[2] < 0) + gTasks[taskId].data[2] = 0; + + paletteOffset = paletteNum * 16 + 0x100; + BlendPalette(paletteOffset + colorOffset, 1, gTasks[taskId].data[2], RGB(20, 27, 31)); + if (gTasks[taskId].data[2] == 0) + DestroyAnimVisualTask(taskId); + break; + } + } +} + +void sub_813F798(u8 taskId) +{ + u8 spriteId; + + spriteId = gBankSpriteIds[gBattleAnimAttacker]; + switch (gTasks[taskId].data[0]) + { + case 0: + PrepareBattlerSpriteForRotScale(spriteId, 0); + gTasks[taskId].data[10] = 0x100; + gTasks[taskId].data[0]++; + break; + case 1: + gTasks[taskId].data[10] += 0x30; + obj_id_set_rotscale(spriteId, gTasks[taskId].data[10], gTasks[taskId].data[10], 0); + sub_8079A64(spriteId); + if (gTasks[taskId].data[10] >= 0x2D0) + gTasks[taskId].data[0]++; + break; + case 2: + sub_8078F40(spriteId); + gSprites[spriteId].invisible = 1; + DestroyAnimVisualTask(taskId); + break; + } +} + +void sub_813F844(u8 taskId) +{ + u8 spriteId; + u16 ball; + u8 ballIndex; + u8 x, y; + u8 priority, subpriority; + u32 selectedPalettes; + + spriteId = gBankSpriteIds[gBattleAnimAttacker]; + if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER) + ball = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_POKEBALL); + else + ball = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_POKEBALL); + + ballIndex = ball_number_to_ball_processing_index(ball); + switch (gTasks[taskId].data[0]) + { + case 0: + x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1); + priority = gSprites[spriteId].oam.priority; + subpriority = gSprites[spriteId].subpriority; + gTasks[taskId].data[10] = AnimateBallOpenParticles(x, y + 32, priority, subpriority, ballIndex); + selectedPalettes = sub_80791A8(1, 0, 0, 0, 0, 0, 0); + gTasks[taskId].data[11] = sub_8141314(0, gBattleAnimAttacker, selectedPalettes, ballIndex); + gTasks[taskId].data[0]++; + break; + case 1: + if (!gTasks[gTasks[taskId].data[10]].isActive && !gTasks[gTasks[taskId].data[11]].isActive) + DestroyAnimVisualTask(taskId); + break; + } +} + +void sub_813F990(u8 taskId) +{ + u8 ballIndex = ball_number_to_ball_processing_index(gLastUsedItem); + LoadBallGraphics(ballIndex); + DestroyAnimVisualTask(taskId); +} + +void sub_813F9B8(u8 taskId) +{ + u8 ballIndex = ball_number_to_ball_processing_index(gLastUsedItem); + FreeBallGraphics(ballIndex); + DestroyAnimVisualTask(taskId); +} + +void sub_813F9E0(u8 taskId) +{ + if (ewram17840.unk8 == 5) + gBattleAnimArgs[7] = -1; + else + gBattleAnimArgs[7] = 0; + + DestroyAnimVisualTask(taskId); +} + +u8 ball_number_to_ball_processing_index(u16 ballItem) +{ + switch (ballItem) + { + case ITEM_MASTER_BALL: + return 4; + case ITEM_ULTRA_BALL: + return 3; + case ITEM_GREAT_BALL: + return 1; + case ITEM_SAFARI_BALL: + return 2; + case ITEM_NET_BALL: + return 5; + case ITEM_DIVE_BALL: + return 6; + case ITEM_NEST_BALL: + return 7; + case ITEM_REPEAT_BALL: + return 8; + case ITEM_TIMER_BALL: + return 9; + case ITEM_LUXURY_BALL: + return 10; + case ITEM_PREMIER_BALL: + return 11; + case ITEM_POKE_BALL: + default: + return 0; + } +} + +void sub_813FA94(u8 taskId) +{ + u8 ballIndex; + u8 spriteId; + + ballIndex = ball_number_to_ball_processing_index(gLastUsedItem); + spriteId = CreateSprite(&gBallSpriteTemplates[ballIndex], 32, 80, 29); + gSprites[spriteId].data[0] = 34; + gSprites[spriteId].data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, 0); + gSprites[spriteId].data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 1) - 16; + gSprites[spriteId].callback = sub_813FD90; + ewram17840.unk9_1 = gSprites[gBankSpriteIds[gBattleAnimTarget]].invisible; + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].func = sub_813FB7C; +} + +static void sub_813FB7C(u8 taskId) +{ + u8 spriteId = gTasks[taskId].data[0]; + if ((u16)gSprites[spriteId].data[0] == 0xFFFF) + DestroyAnimVisualTask(taskId); +} + +void sub_813FBB8(u8 taskId) +{ + int x, y; + u8 ballIndex; + u8 subpriority; + u8 spriteId; + + if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) + { + x = 32; + y = 11; + } + else + { + x = 23; + y = 5; + } + + ballIndex = ball_number_to_ball_processing_index(gLastUsedItem); + subpriority = GetBattlerSubpriority(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)) + 1; + spriteId = CreateSprite(&gBallSpriteTemplates[ballIndex], x + 32, y | 80, subpriority); + gSprites[spriteId].data[0] = 34; + gSprites[spriteId].data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, 0); + gSprites[spriteId].data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 1) - 16; + gSprites[spriteId].callback = SpriteCallbackDummy; + StartSpriteAnim(&gSprites[gBankSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]], 1); + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].func = sub_813FCBC; +} + +static void sub_813FCBC(u8 taskId) +{ + if (gSprites[gBankSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]].animCmdIndex == 1) + { + PlaySE12WithPanning(SE_NAGERU, 0); + gSprites[gTasks[taskId].data[0]].callback = sub_813FD90; + CreateTask(sub_813FD34, 10); + gTasks[taskId].func = sub_813FB7C; + } +} + +static void sub_813FD34(u8 taskId) +{ + if (gSprites[gBankSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]].animEnded) + { + StartSpriteAnim(&gSprites[gBankSpriteIds[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]], 0); + DestroyTask(taskId); + } +} + +static void sub_813FD90(struct Sprite *sprite) +{ + u16 temp = sprite->data[1]; + u16 temp2 = sprite->data[2]; + sprite->data[1] = sprite->pos1.x; + sprite->data[2] = temp; + sprite->data[3] = sprite->pos1.y; + sprite->data[4] = temp2; + sprite->data[5] = -40; + InitAnimArcTranslation(sprite); + sprite->callback = sub_813FDC0; +} + +static void sub_813FDC0(struct Sprite *sprite) +{ + int i; + u8 ballIndex; + int ballIndex2; // extra var needed to match + + if (TranslateAnimArc(sprite)) + { + if (ewram17840.unk8 == 5) + { + sprite->callback = sub_81407B8; + } + else + { + StartSpriteAnim(sprite, 1); + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + + for (i = 0; i < 8; i++) + { + sprite->data[i] = 0; + } + + sprite->data[5] = 0; + sprite->callback = sub_813FE70; + ballIndex = ball_number_to_ball_processing_index(gLastUsedItem); + ballIndex2 = ballIndex; + if (ballIndex2 > 11) + return; + if (ballIndex2 < 0) + return; + + AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 28, ballIndex); + sub_8141314(0, gBattleAnimTarget, 14, ballIndex); + } + } +} + +static void sub_813FE70(struct Sprite *sprite) +{ + if (++sprite->data[5] == 10) + { + sprite->data[5] = CreateTask(TaskDummy, 50); + sprite->callback = sub_813FEC8; + gSprites[gBankSpriteIds[gBattleAnimTarget]].data[1] = 0; + } +} + +static void sub_813FEC8(struct Sprite *sprite) +{ + u8 spriteId; + u8 taskId; + + spriteId = gBankSpriteIds[gBattleAnimTarget]; + taskId = sprite->data[5]; + + if (++gTasks[taskId].data[1] == 11) + PlaySE(SE_SUIKOMU); + + switch (gTasks[taskId].data[0]) + { + case 0: + PrepareBattlerSpriteForRotScale(spriteId, 0); + gTasks[taskId].data[10] = 256; + gUnknown_03005F0C = 28; + gUnknown_03005F14 = (gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y) - (sprite->pos1.y + sprite->pos2.y); + gUnknown_03005F10 = (u32)(gUnknown_03005F14 * 256) / 28; + gTasks[taskId].data[2] = gUnknown_03005F10; + gTasks[taskId].data[0]++; + break; + case 1: + gTasks[taskId].data[10] += 0x20; + obj_id_set_rotscale(spriteId, gTasks[taskId].data[10], gTasks[taskId].data[10], 0); + gTasks[taskId].data[3] += gTasks[taskId].data[2]; + gSprites[spriteId].pos2.y = -gTasks[taskId].data[3] >> 8; + if (gTasks[taskId].data[10] >= 0x480) + gTasks[taskId].data[0]++; + break; + case 2: + sub_8078F40(spriteId); + gSprites[spriteId].invisible = 1; + gTasks[taskId].data[0]++; + break; + default: + if (gTasks[taskId].data[1] > 10) + { + DestroyTask(taskId); + StartSpriteAnim(sprite, 2); + sprite->data[5] = 0; + sprite->callback = sub_8140014; + } + break; + } +} + +static void sub_8140014(struct Sprite *sprite) +{ + int angle; + + if (sprite->animEnded) + { + sprite->data[3] = 0; + sprite->data[4] = 32; + sprite->data[5] = 0; + angle = 0; + sprite->pos1.y += Cos(angle, 32); + sprite->pos2.y = -Cos(angle, sprite->data[4]); + sprite->callback = sub_8140058; + } +} + +static void sub_8140058(struct Sprite *sprite) +{ + bool8 lastBounce; + int bounceCount; + + lastBounce = 0; + + switch (sprite->data[3] & 0xFF) + { + case 0: + sprite->pos2.y = -Cos(sprite->data[5], sprite->data[4]); + sprite->data[5] += (sprite->data[3] >> 8) + 4; + if (sprite->data[5] >= 64) + { + sprite->data[4] -= 10; + sprite->data[3] += 257; + + bounceCount = sprite->data[3] >> 8; + if (bounceCount == 4) + lastBounce = 1; + + // Play a different sound effect for each pokeball bounce. + switch (bounceCount) + { + case 1: + PlaySE(SE_KON); + break; + case 2: + PlaySE(SE_KON2); + break; + case 3: + PlaySE(SE_KON3); + break; + default: + PlaySE(SE_KON4); + break; + } + } + break; + case 1: + sprite->pos2.y = -Cos(sprite->data[5], sprite->data[4]); + sprite->data[5] -= (sprite->data[3] >> 8) + 4; + if (sprite->data[5] <= 0) + { + sprite->data[5] = 0; + sprite->data[3] &= -0x100; + } + break; + } + + if (lastBounce) + { + sprite->data[3] = 0; + sprite->pos1.y += Cos(64, 32); + sprite->pos2.y = 0; + if (ewram17840.unk8 == 0) + { + sprite->data[5] = 0; + sprite->callback = sub_8140410; + } + else + { + sprite->callback = sub_8140158; + sprite->data[4] = 1; + sprite->data[5] = 0; + } + } +} + +static void sub_8140158(struct Sprite *sprite) +{ + if (++sprite->data[3] == 31) + { + sprite->data[3] = 0; + sprite->affineAnimPaused = 1; + StartSpriteAffineAnim(sprite, 1); + ewram17840.unkC = 0; + sprite->callback = sub_81401A0; + PlaySE(SE_BOWA); + } +} + +static void sub_81401A0(struct Sprite *sprite) +{ + s8 state; + u16 var0; + + switch (sprite->data[3] & 0xFF) + { + case 0: + if ((s16)ewram17840.unkC > 0xFF) + { + sprite->pos2.x += sprite->data[4]; + ewram17840.unkC &= 0xFF; + } + else + { + ewram17840.unkC += 0xB0; + } + + sprite->data[5]++; + sprite->affineAnimPaused = 0; + var0 = sprite->data[5] + 7; + if (var0 > 14) + { + ewram17840.unkC = 0; + sprite->data[3]++; + sprite->data[5] = 0; + } + break; + case 1: + if (++sprite->data[5] == 1) + { + sprite->data[5] = 0; + sprite->data[4] = -sprite->data[4]; + sprite->data[3]++; + sprite->affineAnimPaused = 0; + if (sprite->data[4] < 0) + ChangeSpriteAffineAnim(sprite, 2); + else + ChangeSpriteAffineAnim(sprite, 1); + } + else + { + sprite->affineAnimPaused = 1; + } + break; + case 2: + if ((s16)ewram17840.unkC > 0xFF) + { + sprite->pos2.x += sprite->data[4]; + ewram17840.unkC &= 0xFF; + } + else + { + ewram17840.unkC += 0xB0; + } + + sprite->data[5]++; + sprite->affineAnimPaused = 0; + var0 = sprite->data[5] + 12; + if (var0 > 24) + { + ewram17840.unkC = 0; + sprite->data[3]++; + sprite->data[5] = 0; + } + break; + case 3: + if (sprite->data[5]++ < 0) + { + sprite->affineAnimPaused = 1; + break; + } + + sprite->data[5] = 0; + sprite->data[4] = -sprite->data[4]; + sprite->data[3]++; + sprite->affineAnimPaused = 0; + if (sprite->data[4] < 0) + ChangeSpriteAffineAnim(sprite, 2); + else + ChangeSpriteAffineAnim(sprite, 1); + // fall through + case 4: + if ((s16)ewram17840.unkC > 0xFF) + { + sprite->pos2.x += sprite->data[4]; + ewram17840.unkC &= 0xFF; + } + else + { + ewram17840.unkC += 0xB0; + } + + sprite->data[5]++; + sprite->affineAnimPaused = 0; + var0 = sprite->data[5] + 4; + if (var0 > 8) + { + ewram17840.unkC = 0; + sprite->data[3]++; + sprite->data[5] = 0; + sprite->data[4] = -sprite->data[4]; + } + break; + case 5: + sprite->data[3] += 0x100; + state = sprite->data[3] >> 8; + if (state == ewram17840.unk8) + { + sprite->affineAnimPaused = 1; + sprite->callback = sub_8140410; + } + else + { + if (ewram17840.unk8 == 4 && state == 3) + { + sprite->callback = sub_8140434; + sprite->affineAnimPaused = 1; + } + else + { + sprite->data[3]++; + sprite->affineAnimPaused = 1; + } + } + break; + case 6: + default: + if (++sprite->data[5] == 31) + { + sprite->data[5] = 0; + sprite->data[3] &= -0x100; + StartSpriteAffineAnim(sprite, 3); + if (sprite->data[4] < 0) + StartSpriteAffineAnim(sprite, 2); + else + StartSpriteAffineAnim(sprite, 1); + + PlaySE(SE_BOWA); + } + break; + } +} + +static void sub_8140410(struct Sprite *sprite) +{ + if (++sprite->data[5] == 31) + { + sprite->data[5] = 0; + sprite->callback = sub_81405F4; + } +} + +static void sub_8140434(struct Sprite *sprite) +{ + sprite->animPaused = 1; + sprite->callback = sub_8140454; + sprite->data[3] = 0; + sprite->data[4] = 0; + sprite->data[5] = 0; +} + +static void sub_8140454(struct Sprite *sprite) +{ + u8 *battler = &gBattleAnimTarget; + + sprite->data[4]++; + if (sprite->data[4] == 40) + return; + + if (sprite->data[4] == 95) + { + gDoingBattleAnim = 0; + UpdateOamPriorityInAllHealthboxes(1); + m4aMPlayAllStop(); + PlaySE(MUS_FANFA5); + } + else if (sprite->data[4] == 315) + { + FreeOamMatrix(gSprites[gBankSpriteIds[*battler]].oam.matrixNum); + DestroySprite(&gSprites[gBankSpriteIds[*battler]]); + sprite->data[0] = 0; + sprite->callback = sub_81404E4; + } +} + +static void sub_81404E4(struct Sprite *sprite) +{ + u8 paletteIndex; + + switch (sprite->data[0]) + { + case 0: + sprite->data[1] = 0; + sprite->data[2] = 0; + sprite->oam.objMode = ST_OAM_OBJ_BLEND; + REG_BLDCNT = 0x3F40; + REG_BLDALPHA = 0x0010; + paletteIndex = IndexOfSpritePaletteTag(sprite->template->paletteTag); + BeginNormalPaletteFade(1 << (paletteIndex + 0x10), 0, 0, 16, RGB(31, 31, 31)); + sprite->data[0]++; + break; + case 1: + if (sprite->data[1]++ > 0) + { + sprite->data[1] = 0; + sprite->data[2]++; + REG_BLDALPHA = (sprite->data[2] << 8) | (16 - sprite->data[2]); + if (sprite->data[2] == 16) + sprite->data[0]++; + } + break; + case 2: + sprite->invisible = 1; + sprite->data[0]++; + break; + default: + if (!gPaletteFade.active) + { + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + sprite->data[0] = 0; + sprite->callback = sub_81405C8; + } + break; + } +} + +static void sub_81405C8(struct Sprite *sprite) +{ + if (sprite->data[0] == 0) + { + sprite->data[0] = -1; + } + else + { + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); + } +} + +// fakematching. I think the return type of ball_number_to_ball_processing_index() +// is wrong because of the weird required casting. +static void sub_81405F4(struct Sprite *sprite) +{ + u8 ballIndex; + int ballIndex2; // extra var needed to match + + StartSpriteAnim(sprite, 1); + StartSpriteAffineAnim(sprite, 0); + sprite->callback = sub_81406BC; + + ballIndex = ball_number_to_ball_processing_index(gLastUsedItem); + ballIndex2 = ballIndex; + if (ballIndex2 > 11) + goto LABEL; + if (ballIndex2 < 0) + goto LABEL; + + AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 28, ballIndex); + sub_8141314(1, gBattleAnimTarget, 14, ballIndex); + + LABEL: + gSprites[gBankSpriteIds[gBattleAnimTarget]].invisible = 0; + StartSpriteAffineAnim(&gSprites[gBankSpriteIds[gBattleAnimTarget]], 1); + AnimateSprite(&gSprites[gBankSpriteIds[gBattleAnimTarget]]); + gSprites[gBankSpriteIds[gBattleAnimTarget]].data[1] = 0x1000; +} + +static void sub_81406BC(struct Sprite *sprite) +{ + int next = FALSE; + + if (sprite->animEnded) + sprite->invisible = 1; + + if (gSprites[gBankSpriteIds[gBattleAnimTarget]].affineAnimEnded) + { + StartSpriteAffineAnim(&gSprites[gBankSpriteIds[gBattleAnimTarget]], 0); + next = TRUE; + } + else + { + gSprites[gBankSpriteIds[gBattleAnimTarget]].data[1] -= 288; + gSprites[gBankSpriteIds[gBattleAnimTarget]].pos2.y = gSprites[gBankSpriteIds[gBattleAnimTarget]].data[1] >> 8; + } + + if (sprite->animEnded && next) + { + gSprites[gBankSpriteIds[gBattleAnimTarget]].pos2.y = 0; + gSprites[gBankSpriteIds[gBattleAnimTarget]].invisible = ewram17840.unk9_1; + sprite->data[0] = 0; + sprite->callback = sub_81405C8; + gDoingBattleAnim = 0; + UpdateOamPriorityInAllHealthboxes(1); + } +} + +static void sub_81407B8(struct Sprite *sprite) +{ + int i; + + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + for (i = 0; i < 6; i++) + sprite->data[i] = 0; + + sprite->callback = sub_81407F4; +} + +#ifdef NONMATCHING +// there is some weird typing going on with var0 and var1. +static void sub_81407F4(struct Sprite *sprite) +{ + s16 var0, var1; + + var0 = sprite->data[0] + 0x800; + var1 = sprite->data[1] + 0x680; + sprite->pos2.x -= var1 >> 8; + sprite->pos2.y += var0 >> 8; + sprite->data[0] = var0 & 0xFF; + sprite->data[1] = var1 & 0xFF; + + if (sprite->pos1.y + sprite->pos2.y > 160 + || sprite->pos1.x + sprite->pos2.x < -8) + { + sprite->data[0] = 0; + sprite->callback = sub_81405C8; + gDoingBattleAnim = 0; + UpdateOamPriorityInAllHealthboxes(1); + } +} +#else +NAKED +static void sub_81407F4(struct Sprite *sprite) +{ + asm(".syntax unified\n\ + push {r4,lr}\n\ + adds r4, r0, 0\n\ + movs r0, 0x80\n\ + lsls r0, 4\n\ + adds r2, r0, 0\n\ + ldrh r1, [r4, 0x2E]\n\ + adds r2, r1\n\ + movs r0, 0xD0\n\ + lsls r0, 3\n\ + adds r3, r0, 0\n\ + ldrh r1, [r4, 0x30]\n\ + adds r3, r1\n\ + lsls r1, r3, 16\n\ + asrs r1, 24\n\ + ldrh r0, [r4, 0x24]\n\ + subs r0, r1\n\ + strh r0, [r4, 0x24]\n\ + lsls r0, r2, 16\n\ + asrs r0, 24\n\ + ldrh r1, [r4, 0x26]\n\ + adds r0, r1\n\ + strh r0, [r4, 0x26]\n\ + movs r0, 0xFF\n\ + ands r2, r0\n\ + strh r2, [r4, 0x2E]\n\ + ands r3, r0\n\ + strh r3, [r4, 0x30]\n\ + movs r2, 0x22\n\ + ldrsh r0, [r4, r2]\n\ + movs r2, 0x26\n\ + ldrsh r1, [r4, r2]\n\ + adds r0, r1\n\ + cmp r0, 0xA0\n\ + bgt _0814084A\n\ + movs r1, 0x20\n\ + ldrsh r0, [r4, r1]\n\ + movs r2, 0x24\n\ + ldrsh r1, [r4, r2]\n\ + adds r0, r1\n\ + movs r1, 0x8\n\ + negs r1, r1\n\ + cmp r0, r1\n\ + bge _0814085E\n\ +_0814084A:\n\ + movs r0, 0\n\ + strh r0, [r4, 0x2E]\n\ + ldr r0, _08140864 @ =sub_81405C8\n\ + str r0, [r4, 0x1C]\n\ + ldr r1, _08140868 @ =gDoingBattleAnim\n\ + movs r0, 0\n\ + strb r0, [r1]\n\ + movs r0, 0x1\n\ + bl UpdateOamPriorityInAllHealthboxes\n\ +_0814085E:\n\ + pop {r4}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08140864: .4byte sub_81405C8\n\ +_08140868: .4byte gDoingBattleAnim\n\ + .syntax divided\n"); +} +#endif // NONMATCHING + +u8 AnimateBallOpenParticles(u8 x, u8 y, u8 priority, u8 subpriority, u8 ballIndex) +{ + u8 taskId; + + if (GetSpriteTileStartByTag(gBallOpenParticleSpritesheets[ballIndex].tag) == 0xFFFF) + { + LoadCompressedObjectPic(&gBallOpenParticleSpritesheets[ballIndex]); + LoadCompressedObjectPalette(&gBallOpenParticlePalettes[ballIndex]); + } + + taskId = CreateTask(gBallOpenParticleAnimationFuncs[ballIndex], 5); + gTasks[taskId].data[1] = x; + gTasks[taskId].data[2] = y; + gTasks[taskId].data[3] = priority; + gTasks[taskId].data[4] = subpriority; + gTasks[taskId].data[15] = ballIndex; + PlaySE(SE_BOWA2); + if (gMain.inBattle) + ewram17840.unkA++; + + return taskId; +} + +void PokeBallOpenParticleAnimation(u8 taskId) +{ + u8 spriteId; + u8 x, y; + u8 priority, subpriority; + u8 ballIndex; + u8 var0; + + ballIndex = gTasks[taskId].data[15]; + if (gTasks[taskId].data[0] < 16) + { + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); + StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); + gSprites[spriteId].callback = PokeBallOpenParticleAnimation_Step1; + gSprites[spriteId].oam.priority = priority; + + var0 = (u8)gTasks[taskId].data[0]; + if (var0 >= 8) + var0 -= 8; + + gSprites[spriteId].data[0] = var0 * 32; + if (gTasks[taskId].data[0] == 15) + { + gSprites[spriteId].data[7] = 1; + DestroyTask(taskId); + return; + } + } + + gTasks[taskId].data[0]++; +} + +static void PokeBallOpenParticleAnimation_Step1(struct Sprite *sprite) +{ + if (sprite->data[1] == 0) + sprite->callback = PokeBallOpenParticleAnimation_Step2; + else + sprite->data[1]--; +} + +static void PokeBallOpenParticleAnimation_Step2(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], sprite->data[1]); + sprite->data[1] += 2; + if (sprite->data[1] == 50) + DestroyBallOpenAnimationParticle(sprite); +} + +void TimerBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballIndex; + u8 spriteId; + + ballIndex = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); + StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); + gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 32; + gSprites[spriteId].data[4] = 10; + gSprites[spriteId].data[5] = 2; + gSprites[spriteId].data[6] = 1; + } + + gSprites[spriteId].data[7] = 1; + DestroyTask(taskId); +} + +void DiveBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballIndex; + u8 spriteId; + + ballIndex = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); + StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); + gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 32; + gSprites[spriteId].data[4] = 10; + gSprites[spriteId].data[5] = 1; + gSprites[spriteId].data[6] = 2; + } + + gSprites[spriteId].data[7] = 1; + DestroyTask(taskId); +} + +void SafariBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballIndex; + u8 spriteId; + + ballIndex = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); + StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); + gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 32; + gSprites[spriteId].data[4] = 4; + gSprites[spriteId].data[5] = 1; + gSprites[spriteId].data[6] = 1; + } + + gSprites[spriteId].data[7] = 1; + DestroyTask(taskId); +} + +void UltraBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballIndex; + u8 spriteId; + + ballIndex = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 10; i++) + { + spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); + StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); + gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 25; + gSprites[spriteId].data[4] = 5; + gSprites[spriteId].data[5] = 1; + gSprites[spriteId].data[6] = 1; + } + + gSprites[spriteId].data[7] = 1; + DestroyTask(taskId); +} + +void GreatBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballIndex; + u8 spriteId; + + if (gTasks[taskId].data[7]) + { + gTasks[taskId].data[7]--; + } + else + { + ballIndex = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); + StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); + gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 32; + gSprites[spriteId].data[4] = 8; + gSprites[spriteId].data[5] = 2; + gSprites[spriteId].data[6] = 2; + } + + gTasks[taskId].data[7] = 8; + if (++gTasks[taskId].data[0] == 2) + { + gSprites[spriteId].data[7] = 1; + DestroyTask(taskId); + } + } +} + +static void FanOutBallOpenParticles_Step1(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], sprite->data[2]); + sprite->data[0] = (sprite->data[0] + sprite->data[4]) & 0xFF; + sprite->data[1] += sprite->data[5]; + sprite->data[2] += sprite->data[6]; + if (++sprite->data[3] == 51) + DestroyBallOpenAnimationParticle(sprite); +} + +void RepeatBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballIndex; + u8 spriteId; + + ballIndex = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 12; i++) + { + spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); + StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); + gSprites[spriteId].callback = RepeatBallOpenParticleAnimation_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 21; + } + + gSprites[spriteId].data[7] = 1; + DestroyTask(taskId); +} + +static void RepeatBallOpenParticleAnimation_Step1(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], Sin(sprite->data[0], sprite->data[2])); + sprite->data[0] = (sprite->data[0] + 6) & 0xFF; + sprite->data[1]++; + sprite->data[2]++; + if (++sprite->data[3] == 51) + DestroyBallOpenAnimationParticle(sprite); +} + +void MasterBallOpenParticleAnimation(u8 taskId) +{ + u8 i, j; + u8 x, y, priority, subpriority, ballIndex; + u8 spriteId; + + ballIndex = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (j = 0; j < 2; j++) + { + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); + StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); + gSprites[spriteId].callback = FanOutBallOpenParticles_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 32; + gSprites[spriteId].data[4] = 8; + + if (j == 0) + { + gSprites[spriteId].data[5] = 2; + gSprites[spriteId].data[6] = 1; + } + else + { + gSprites[spriteId].data[5] = 1; + gSprites[spriteId].data[6] = 2; + } + } + } + + gSprites[spriteId].data[7] = 1; + DestroyTask(taskId); +} + +void PremierBallOpenParticleAnimation(u8 taskId) +{ + u8 i; + u8 x, y, priority, subpriority, ballIndex; + u8 spriteId; + + ballIndex = gTasks[taskId].data[15]; + x = gTasks[taskId].data[1]; + y = gTasks[taskId].data[2]; + priority = gTasks[taskId].data[3]; + subpriority = gTasks[taskId].data[4]; + + for (i = 0; i < 8; i++) + { + spriteId = CreateSprite(&gSpriteTemplates_840B3B4[ballIndex], x, y, subpriority); + StartSpriteAnim(&gSprites[spriteId], gBallOpenParticleAnimNums[ballIndex]); + gSprites[spriteId].callback = PremierBallOpenParticleAnimation_Step1; + gSprites[spriteId].oam.priority = priority; + gSprites[spriteId].data[0] = i * 32; + } + + gSprites[spriteId].data[7] = 1; + DestroyTask(taskId); +} + +static void PremierBallOpenParticleAnimation_Step1(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], Sin(sprite->data[0] & 0x3F, sprite->data[2])); + sprite->data[0] = (sprite->data[0] + 10) & 0xFF; + sprite->data[1]++; + sprite->data[2]++; + if (++sprite->data[3] == 51) + DestroyBallOpenAnimationParticle(sprite); +} + +static void DestroyBallOpenAnimationParticle(struct Sprite *sprite) +{ + int i; + int temp; + + if (!gMain.inBattle) + { + temp = sprite->data[7]; // temp var needed to match + if (temp == 1) + DestroySpriteAndFreeResources(sprite); + else + DestroySprite(sprite); + } + else if (sprite->data[7] == 1) + { + if (--ewram17840.unkA == 0) + { + for (i = 0; i < 12; i++) + { + FreeSpriteTilesByTag(gBallOpenParticleSpritesheets[i].tag); + FreeSpritePaletteByTag(gBallOpenParticlePalettes[i].tag); + } + + DestroySprite(sprite); + } + else + DestroySprite(sprite); + } + else + DestroySprite(sprite); +} + +u8 sub_8141314(u8 arg0, u8 battler, u32 selectedPalettes, u8 ballIndex) +{ + u8 taskId; + + taskId = CreateTask(sub_81413DC, 5); + gTasks[taskId].data[15] = ballIndex; + gTasks[taskId].data[3] = battler; + gTasks[taskId].data[10] = selectedPalettes; + gTasks[taskId].data[11] = selectedPalettes >> 16; + + if (!arg0) + { + BlendPalette(battler * 16 + 0x100, 16, 0, gUnknown_0840B4D4[ballIndex]); + gTasks[taskId].data[1] = 1; + } + else + { + BlendPalette(battler * 16 + 0x100, 16, 16, gUnknown_0840B4D4[ballIndex]); + gTasks[taskId].data[0] = 16; + gTasks[taskId].data[1] = -1; + gTasks[taskId].func = sub_814146C; + } + + BeginNormalPaletteFade(selectedPalettes, 0, 0, 16, RGB(31, 31, 31)); + return taskId; +} + +static void sub_81413DC(u8 taskId) +{ + u8 ballIndex = gTasks[taskId].data[15]; + + if (gTasks[taskId].data[2] <= 16) + { + BlendPalette(gTasks[taskId].data[3] * 16 + 0x100, 16, gTasks[taskId].data[0], gUnknown_0840B4D4[ballIndex]); + gTasks[taskId].data[0] += gTasks[taskId].data[1]; + gTasks[taskId].data[2]++; + } + else if (!gPaletteFade.active) + { + u32 selectedPalettes = (u16)gTasks[taskId].data[10] | ((u16)gTasks[taskId].data[11] << 16); + BeginNormalPaletteFade(selectedPalettes, 0, 16, 0, RGB(31, 31, 31)); + DestroyTask(taskId); + } +} + +static void sub_814146C(u8 taskId) +{ + if (!gPaletteFade.active) + { + u32 selectedPalettes = (u16)gTasks[taskId].data[10] | ((u16)gTasks[taskId].data[11] << 16); + BeginNormalPaletteFade(selectedPalettes, 0, 16, 0, RGB(31, 31, 31)); + gTasks[taskId].func = sub_81414BC; + } +} + +static void sub_81414BC(u8 taskId) +{ + u8 ballIndex = gTasks[taskId].data[15]; + + if (gTasks[taskId].data[2] <= 16) + { + BlendPalette(gTasks[taskId].data[3] * 16 + 0x100, 16, gTasks[taskId].data[0], gUnknown_0840B4D4[ballIndex]); + gTasks[taskId].data[0] += gTasks[taskId].data[1]; + gTasks[taskId].data[2]++; + } + else + { + DestroyTask(taskId); + } +} + +void sub_814151C(u8 taskId) +{ + u8 spriteId; + u32 x; + u32 done; + + done = FALSE; + spriteId = gBankSpriteIds[gBattleAnimAttacker]; + switch (gTasks[taskId].data[10]) + { + case 0: + gTasks[taskId].data[11] = gBattleAnimArgs[0]; + gTasks[taskId].data[0] += 0x500; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gSprites[spriteId].pos2.x += gTasks[taskId].data[0] >> 8; + else + gSprites[spriteId].pos2.x -= gTasks[taskId].data[0] >> 8; + + gTasks[taskId].data[0] &= 0xFF; + x = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x + 32; + if (x > 304) + gTasks[taskId].data[10]++; + break; + case 1: + refresh_graphics_maybe(gBattleAnimAttacker, gTasks[taskId].data[11], spriteId); + gTasks[taskId].data[10]++; + break; + case 2: + gTasks[taskId].data[0] += 0x500; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gSprites[spriteId].pos2.x -= gTasks[taskId].data[0] >> 8; + else + gSprites[spriteId].pos2.x += gTasks[taskId].data[0] >> 8; + + gTasks[taskId].data[0] &= 0xFF; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + if (gSprites[spriteId].pos2.x <= 0) + { + gSprites[spriteId].pos2.x = 0; + // done = FALSE; // fakematching--can't get the tail merge correct + goto DONE; + } + } + else + { + if (gSprites[spriteId].pos2.x >= 0) + { + gSprites[spriteId].pos2.x = 0; + done = TRUE; + } + } + + if (done) + { + DONE: + DestroyAnimVisualTask(taskId); + } + break; + } +} + +void sub_81416C4(u8 taskId) +{ + u8 spriteId; + + switch (gTasks[taskId].data[15]) + { + case 0: + if (GetBattlerPosition_permutated(gBattleAnimAttacker) == 1) + REG_BLDCNT = 0x3F42; + else + REG_BLDCNT = 0x3F44; + + REG_BLDALPHA = 0x0010; + gTasks[taskId].data[15]++; + break; + case 1: + if (gTasks[taskId].data[1]++ > 1) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + REG_BLDALPHA = (gTasks[taskId].data[0] << 8) | (16 - gTasks[taskId].data[0]); + if (gTasks[taskId].data[0] == 16) + gTasks[taskId].data[15]++; + } + break; + case 2: + spriteId = gBankSpriteIds[gBattleAnimAttacker]; + DmaClear32(3, (void *)OBJ_VRAM0 + gSprites[spriteId].oam.tileNum * TILE_SIZE_4BPP, 0x800); + sub_80324E0(gBattleAnimAttacker); + DestroyAnimVisualTask(taskId); + break; + } +} + +void sub_81417D8(u8 taskId) +{ + gBattleAnimArgs[7] = ewram17800[gBattleAnimAttacker].substituteSprite; + DestroyAnimVisualTask(taskId); +} + +void sub_8141808(u8 taskId) +{ + gBattleAnimTarget = gEffectBank; + DestroyAnimVisualTask(taskId); +} + +void sub_8141828(u8 battler, struct Pokemon *mon) +{ + int isShiny; + u32 otId, personality; + u32 shinyValue; + u8 taskId1, taskId2; + + isShiny = 0; + ewram17810[battler].unk0_7 = 1; + otId = GetMonData(mon, MON_DATA_OT_ID); + personality = GetMonData(mon, MON_DATA_PERSONALITY); + + if (IsAnimBankSpriteVisible(battler)) + { + shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality); + if (shinyValue < 8) + isShiny = TRUE; + + if (isShiny) + { + if (GetSpriteTileStartByTag(0x27F9) == 0xFFFF) + { + LoadCompressedObjectPic(&gBattleAnimPicTable[233]); + LoadCompressedObjectPalette(&gBattleAnimPaletteTable[233]); + } + + taskId1 = CreateTask(sub_814191C, 10); + taskId2 = CreateTask(sub_814191C, 10); + gTasks[taskId1].data[0] = battler; + gTasks[taskId2].data[0] = battler; + gTasks[taskId1].data[1] = 0; + gTasks[taskId2].data[1] = 1; + return; + } + } + + ewram17810[battler].unk1_0 = 1; +} + +static void sub_814191C(u8 taskId) +{ + u8 battler; + u8 x, y; + u8 spriteId; + u16 counter; + s16 state; + u8 pan; + + if (gTasks[taskId].data[13] < 60) + { + gTasks[taskId].data[13]++; + return; + } + + if (ewram17840.unkA) + return; + + counter = gTasks[taskId].data[10]++; + if (counter & 3) + return; + + battler = gTasks[taskId].data[0]; + x = GetBattlerSpriteCoord(battler, 0); + y = GetBattlerSpriteCoord(battler, 1); + state = gTasks[taskId].data[11]; + if (state == 0) + { + spriteId = CreateSprite(&gBattleAnimSpriteTemplate_84024E8, x, y, 5); + } + else if (state >= 0 && gTasks[taskId].data[11] < 4) + { + spriteId = CreateSprite(&gSpriteTemplate_8402500, x, y, 5); + gSprites[spriteId].oam.tileNum += 4; + } + else + { + spriteId = CreateSprite(&gSpriteTemplate_8402500, x, y, 5); + gSprites[spriteId].oam.tileNum += 5; + } + + if (gTasks[taskId].data[1] == 0) + { + gSprites[spriteId].callback = sub_8141B20; + } + else + { + gSprites[spriteId].callback = sub_8141B74; + gSprites[spriteId].pos2.x = -32; + gSprites[spriteId].pos2.y = 32; + gSprites[spriteId].invisible = 1; + if (gTasks[taskId].data[11] == 0) + { + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + pan = 192; + else + pan = 63; + + PlaySE12WithPanning(SE_REAPOKE, pan); + } + } + + gSprites[spriteId].data[0] = taskId; + gTasks[taskId].data[11]++; + gTasks[taskId].data[12]++; + if (gTasks[taskId].data[11] == 5) + gTasks[taskId].func = sub_8141AD8; +} + +static void sub_8141AD8(u8 taskId) +{ + u8 battler; + + if (gTasks[taskId].data[12] == 0) + { + if (gTasks[taskId].data[1] == 1) + { + battler = gTasks[taskId].data[0]; + ewram17810[battler].unk1_0 = 1; + } + + DestroyTask(taskId); + } +} + +static void sub_8141B20(struct Sprite *sprite) +{ + sprite->pos2.x = Sin(sprite->data[1], 24); + sprite->pos2.y = Cos(sprite->data[1], 24); + sprite->data[1] += 12; + if (sprite->data[1] > 0xFF) + { + gTasks[sprite->data[0]].data[12]--; + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); + } +} + +static void sub_8141B74(struct Sprite *sprite) +{ + if (sprite->data[1] < 4) + { + sprite->data[1]++; + } + else + { + sprite->invisible = 0; + sprite->pos2.x += 5; + sprite->pos2.y -= 5; + if (sprite->pos2.x > 32) + { + gTasks[sprite->data[0]].data[12]--; + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); + } + } +} + +void sub_8141BD4(u8 taskId) +{ + u8 paletteIndex; + + LoadCompressedObjectPic(&gBattleAnimPicTable[269]); + LoadCompressedObjectPalette(&gBattleAnimPaletteTable[269]); + paletteIndex = IndexOfSpritePaletteTag(0x281D); // unused + DestroyAnimVisualTask(taskId); +} + +void sub_8141C08(u8 taskId) +{ + FreeSpriteTilesByTag(0x281D); + FreeSpritePaletteByTag(0x281D); + DestroyAnimVisualTask(taskId); +} + +static void sub_8141C30(struct Sprite *sprite) +{ + InitAnimSpritePos(sprite, 0); + sprite->data[0] = 30; + sprite->data[2] = GetBattlerSpriteCoord(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), 0) + gBattleAnimArgs[2]; + sprite->data[4] = GetBattlerSpriteCoord(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), 1) + gBattleAnimArgs[3]; + sprite->data[5] = -32; + InitAnimArcTranslation(sprite); + StartSpriteAnim(&gSprites[gBankSpriteIds[gBattleAnimAttacker]], 1); + sprite->callback = sub_8141CBC; +} + +static void sub_8141CBC(struct Sprite *sprite) +{ + if (gSprites[gBankSpriteIds[gBattleAnimAttacker]].animCmdIndex == 1) + sprite->callback = sub_8141CF4; +} + +static void sub_8141CF4(struct Sprite *sprite) +{ + if (TranslateAnimArc(sprite)) + { + sprite->data[0] = 0; + sprite->invisible = 1; + sprite->callback = sub_8141D20; + } +} + +static void sub_8141D20(struct Sprite *sprite) +{ + if (gSprites[gBankSpriteIds[gBattleAnimAttacker]].animEnded) + { + if (++sprite->data[0] > 0) + { + StartSpriteAnim(&gSprites[gBankSpriteIds[gBattleAnimAttacker]], 0); + DestroyAnimSprite(sprite); + } + } +} + +void sub_8141D7C(u8 taskId) +{ + gBattleAnimAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + gBattleAnimTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + DestroyAnimVisualTask(taskId); +} + +void sub_8141DAC(u8 taskId) +{ + if (ewram17840.unk0 == 83) + gBattleAnimArgs[0] = 1; + else if (ewram17840.unk0 == 250) + gBattleAnimArgs[0] = 2; + else if (ewram17840.unk0 == 128) + gBattleAnimArgs[0] = 3; + else if (ewram17840.unk0 == 328) + gBattleAnimArgs[0] = 4; + else + gBattleAnimArgs[0] = 0; + + DestroyAnimVisualTask(taskId); +} + +void sub_8141E10(u8 taskId) +{ + gBattleAnimAttacker = ewram17840.unk0; + gBattleAnimTarget = ewram17840.unk0 >> 8; + DestroyAnimVisualTask(taskId); +} diff --git a/src/battle_anim_status_effects.c b/src/battle_anim_status_effects.c new file mode 100644 index 000000000..90e6ce38c --- /dev/null +++ b/src/battle_anim_status_effects.c @@ -0,0 +1,354 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "blend_palette.h" +#include "decompress.h" +#include "palette.h" +#include "sprite.h" +#include "task.h" +#include "trig.h" +#include "ewram.h" + +extern u8 gBattleAnimAttacker; +extern u8 gBattleAnimTarget; +extern bool8 gAnimScriptActive; +extern void (*gAnimScriptCallback)(void); +extern s16 gBattleAnimArgs[]; +extern u8 gBattleAnimTarget; +extern u8 gBankSpriteIds[]; +extern const struct CompressedSpriteSheet gBattleAnimPicTable[]; +extern const struct CompressedSpritePalette gBattleAnimPaletteTable[]; +extern const u8 *const gBattleAnims_StatusConditions[]; +extern const struct OamData gOamData_837E05C; +extern const struct OamData gOamData_837DF24; + +extern u8 GetBattlerSpriteCoord(u8, u8); +extern void sub_80E32E0(u8); + + +static const struct Subsprite gSubspriteTable_83931B8[] = +{ + {.x = -16, .y = -16, .shape = ST_OAM_SQUARE, .size = 3, .tileOffset = 0, .priority = 2}, + {.x = -16, .y = 48, .shape = ST_OAM_H_RECTANGLE, .size = 3, .tileOffset = 64, .priority = 2}, + {.x = 48, .y = -16, .shape = ST_OAM_V_RECTANGLE, .size = 3, .tileOffset = 96, .priority = 2}, + {.x = 48, .y = 48, .shape = ST_OAM_SQUARE, .size = 2, .tileOffset = 128, .priority = 2}, +}; + +static const struct SubspriteTable gSubspriteTables_83931D8[] = +{ + {ARRAY_COUNT(gSubspriteTable_83931B8), gSubspriteTable_83931B8}, +}; + +static const struct SpriteTemplate gSpriteTemplate_83931E0 = +{ + .tileTag = ANIM_TAG_ICE_CUBE, + .paletteTag = ANIM_TAG_ICE_CUBE, + .oam = &gOamData_837E05C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +static void sub_807B870(struct Sprite *); +static const struct SpriteTemplate gSpriteTemplate_83931F8 = +{ + .tileTag = ANIM_TAG_CIRCLE_IMPACT, + .paletteTag = ANIM_TAG_CIRCLE_IMPACT, + .oam = &gOamData_837DF24, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_807B870, +}; + +static void sub_807B7E0(u8); +static void sub_807B8A4(struct Sprite *); +static void sub_807B9D8(u8); +static void sub_807BA24(u8); +static void sub_807BAD4(u8); +static void sub_807BB24(u8); +static void sub_807BDAC(u8); + +u8 unref_sub_807B69C(u8 a, u8 b) +{ + u8 spriteId1 = gBankSpriteIds[a]; + u8 taskId = CreateTask(sub_807B7E0, 10); + u8 spriteId2; + u8 i; + + LoadCompressedObjectPic(&gBattleAnimPicTable[136]); + LoadCompressedObjectPalette(&gBattleAnimPaletteTable[136]); + gTasks[taskId].data[0] = a; + if (b != 0) + { + gTasks[taskId].data[1] = 0x1F; + for (i = 0; i < 10; i++) + { + spriteId2 = CreateSprite(&gSpriteTemplate_83931F8, gSprites[spriteId1].pos1.x, gSprites[spriteId1].pos1.y + 32, 0); + gSprites[spriteId2].data[0] = i * 51; + gSprites[spriteId2].data[1] = -256; + gSprites[spriteId2].invisible = TRUE; + if (i > 4) + gSprites[spriteId2].data[6] = 21; + } + } + else + { + gTasks[taskId].data[1] = 0x7C00; + for (i = 0; i < 10; i++) + { + spriteId2 = CreateSprite(&gSpriteTemplate_83931F8, gSprites[spriteId1].pos1.x, gSprites[spriteId1].pos1.y - 32, 0); + gSprites[spriteId2].data[0] = i * 51; + gSprites[spriteId2].data[1] = 256; + gSprites[spriteId2].invisible = TRUE; + if (i > 4) + gSprites[spriteId2].data[6] = 21; + } + } + gSprites[spriteId2].data[7] = 1; + return taskId; +} + +static void sub_807B7E0(u8 taskId) +{ + if (gTasks[taskId].data[2] == 2) + { + gTasks[taskId].data[2] = 0; + BlendPalette(0x100 + gTasks[taskId].data[0] * 16, 16, gTasks[taskId].data[4], gTasks[taskId].data[1]); + if (gTasks[taskId].data[5] == 0) + { + gTasks[taskId].data[4]++; + if (gTasks[taskId].data[4] > 8) + gTasks[taskId].data[5] ^= 1; + } + else + { + u16 var = gTasks[taskId].data[4]; + + gTasks[taskId].data[4]--; + if (gTasks[taskId].data[4] < 0) + { + gTasks[taskId].data[4] = var; + gTasks[taskId].data[5] ^= 1; + gTasks[taskId].data[3]++; + if (gTasks[taskId].data[3] == 2) + DestroyTask(taskId); + } + } + } + else + { + gTasks[taskId].data[2]++; + } +} + +static void sub_807B870(struct Sprite *sprite) +{ + if (sprite->data[6] == 0) + { + sprite->invisible = FALSE; + sprite->callback = sub_807B8A4; + sub_807B8A4(sprite); + } + else + { + sprite->data[6] --; + } +} + +static void sub_807B8A4(struct Sprite *sprite) +{ + sprite->pos2.x = Cos(sprite->data[0], 32); + sprite->pos2.y = Sin(sprite->data[0], 8); + if (sprite->data[0] < 128) + sprite->subpriority = 29; + else + sprite->subpriority = 31; + sprite->data[0] = (sprite->data[0] + 8) & 0xFF; + sprite->data[5] += sprite->data[1]; + sprite->pos2.y += sprite->data[5] >> 8; + sprite->data[2]++; + if (sprite->data[2] == 52) + { + if (sprite->data[7] != 0) + DestroySpriteAndFreeResources(sprite); + else + DestroySprite(sprite); + } +} + +void sub_807B920(u8 taskId) +{ + s16 x = GetBattlerSpriteCoord(gBattleAnimTarget, 2) - 32; + s16 y = GetBattlerSpriteCoord(gBattleAnimTarget, 3) - 36; + u8 spriteId; + + if (IsContest()) + x -= 6; + REG_BLDCNT = 0x3F40; + REG_BLDALPHA = 0x1000; + spriteId = CreateSprite(&gSpriteTemplate_83931E0, x, y, 4); + SetSubspriteTables(&gSprites[spriteId], gSubspriteTables_83931D8); + gTasks[taskId].data[15] = spriteId; + gTasks[taskId].func = sub_807B9D8; +} + +static void sub_807B9D8(u8 taskId) +{ + gTasks[taskId].data[1]++; + if (gTasks[taskId].data[1] == 10) + { + gTasks[taskId].func = sub_807BA24; + gTasks[taskId].data[1] = 0; + } + else + { + u8 var = gTasks[taskId].data[1]; + + REG_BLDALPHA = ((16 - var) << 8) | var; + } +} + +static void sub_807BA24(u8 taskId) +{ + u8 r2 = IndexOfSpritePaletteTag(0x271A); + + if (gTasks[taskId].data[1]++ > 13) + { + gTasks[taskId].data[2]++; + if (gTasks[taskId].data[2] == 3) + { + u16 temp; + + temp = gPlttBufferFaded[0x100 + r2 * 16 + 13]; + gPlttBufferFaded[0x100 + r2 * 16 + 13] = gPlttBufferFaded[0x100 + r2 * 16 + 14]; + gPlttBufferFaded[0x100 + r2 * 16 + 14] = gPlttBufferFaded[0x100 + r2 * 16 + 15]; + gPlttBufferFaded[0x100 + r2 * 16 + 15] = temp; + + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[3]++; + if (gTasks[taskId].data[3] == 3) + { + gTasks[taskId].data[3] = 0; + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[4]++; + if (gTasks[taskId].data[4] == 2) + { + gTasks[taskId].data[1] = 9; + gTasks[taskId].func = sub_807BAD4; + } + } + } + } +} + +static void sub_807BAD4(u8 taskId) +{ + gTasks[taskId].data[1]--; + if (gTasks[taskId].data[1] == -1) + { + gTasks[taskId].func = sub_807BB24; + gTasks[taskId].data[1] = 0; + } + else + { + u8 var = gTasks[taskId].data[1]; + + REG_BLDALPHA = ((16 - var) << 8) | var; + } +} + +static void sub_807BB24(u8 taskId) +{ + gTasks[taskId].data[1]++; + if (gTasks[taskId].data[1] == 37) + { + u8 spriteId = gTasks[taskId].data[15]; + + FreeSpriteOamMatrix(&gSprites[spriteId]); + DestroySprite(&gSprites[spriteId]); + } + else if (gTasks[taskId].data[1] == 39) + { + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + DestroyAnimVisualTask(taskId); + } +} + +void sub_807BB88(u8 taskId) +{ + s16 r5; + s16 r2; + s16 r3 = 0; + + switch (ewram17840.unk0) + { + case 15: r5 = 0; r2 = 0; break; + case 16: r5 = 0; r2 = 1; break; + case 17: r5 = 0; r2 = 3; break; + case 18: r5 = 0; r2 = 5; break; + case 19: r5 = 0; r2 = 6; break; + case 20: r5 = 0; r2 = 2; break; + case 21: r5 = 0; r2 = 4; break; + case 22: r5 = 1; r2 = 0; break; + case 23: r5 = 1; r2 = 1; break; + case 24: r5 = 1; r2 = 3; break; + case 25: r5 = 1; r2 = 5; break; + case 26: r5 = 1; r2 = 6; break; + case 27: r5 = 1; r2 = 2; break; + case 28: r5 = 1; r2 = 4; break; + case 39: r5 = 0; r2 = 0; r3 = 1; break; + case 40: r5 = 0; r2 = 1; r3 = 1; break; + case 41: r5 = 0; r2 = 3; r3 = 1; break; + case 42: r5 = 0; r2 = 5; r3 = 1; break; + case 43: r5 = 0; r2 = 6; r3 = 1; break; + case 44: r5 = 0; r2 = 2; r3 = 1; break; + case 45: r5 = 0; r2 = 4; r3 = 1; break; + case 46: r5 = 1; r2 = 0; r3 = 1; break; + case 47: r5 = 1; r2 = 1; r3 = 1; break; + case 48: r5 = 1; r2 = 3; r3 = 1; break; + case 49: r5 = 1; r2 = 5; r3 = 1; break; + case 50: r5 = 1; r2 = 6; r3 = 1; break; + case 51: r5 = 1; r2 = 2; r3 = 1; break; + case 52: r5 = 1; r2 = 4; r3 = 1; break; + case 55: r5 = 0; r2 = 0xFF; r3 = 0; break; + case 56: r5 = 0; r2 = 0xFF; r3 = 1; break; + case 57: r5 = 1; r2 = 0xFF; r3 = 0; break; + case 58: r5 = 1; r2 = 0xFF; r3 = 1; break; + + default: + DestroyAnimVisualTask(taskId); + return; + } + + gBattleAnimArgs[0] = r5; + gBattleAnimArgs[1] = r2; + gBattleAnimArgs[2] = 0; + gBattleAnimArgs[3] = 0; + gBattleAnimArgs[4] = r3; + gTasks[taskId].func = sub_80E32E0; + sub_80E32E0(taskId); +} + +void move_anim_start_t2(u8 a, u8 b) +{ + u8 taskId; + + gBattleAnimAttacker = a; + gBattleAnimTarget = a; + LaunchBattleAnimation(gBattleAnims_StatusConditions, b, 0); + taskId = CreateTask(sub_807BDAC, 10); + gTasks[taskId].data[0] = a; +} + +static void sub_807BDAC(u8 taskId) +{ + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + ewram17810[gTasks[taskId].data[0]].unk0_4 = 0; + DestroyTask(taskId); + } +} diff --git a/src/battle_bg.c b/src/battle_bg.c new file mode 100644 index 000000000..4928708e0 --- /dev/null +++ b/src/battle_bg.c @@ -0,0 +1,864 @@ +#include "global.h" +#include "battle.h" +#include "decompress.h" +#include "ewram.h" +#include "graphics.h" +#include "link.h" +#include "main.h" +#include "palette.h" +#include "task.h" +#include "text.h" +#include "text_window.h" +#include "trainer.h" +#include "trig.h" +#include "sound.h" +#include "constants/map_types.h" +#include "constants/songs.h" + + +extern u16 gBattleTypeFlags; +extern u8 gBattleOutcome; + +extern struct Window gUnknown_03004210; + +extern u8 BattleText_Win[]; +extern u8 BattleText_Loss[]; +extern u8 BattleText_Tie[]; + +extern void sub_8032A38(void); + +#define GetCurrentMapBattleScene sav1_map_get_battletype +//extern u8 GetCurrentMapBattleScene(void); + +extern const u8 gGameVersion; +extern u16 gBattleTypeFlags; +extern struct Trainer gTrainers[]; +extern u16 gTrainerBattleOpponent; + +extern u8 gBattleTerrain; + +extern u16 gBattleTerrainPalette_Groudon[]; +extern u16 gBattleTerrainPalette_Kyogre[]; +extern u16 gBattleTerrainPalette_BuildingLeader[]; +extern u16 gBattleTerrainPalette_StadiumSteven[]; +extern u16 gBattleTerrainPalette_BuildingGym[]; +extern u16 gBattleTerrainPalette_StadiumMagma[]; +extern u16 gBattleTerrainPalette_StadiumAqua[]; +extern u16 gBattleTerrainPalette_StadiumSidney[]; +extern u16 gBattleTerrainPalette_StadiumPhoebe[]; +extern u16 gBattleTerrainPalette_StadiumGlacia[]; +extern u16 gBattleTerrainPalette_StadiumDrake[]; +extern u16 gBattleTerrainPalette_BattleTower[]; + +extern u8 gVersusFrameGfx[]; +extern u16 gVersusFrameTilemap[]; +extern u16 gVersusFramePal[]; + +extern u16 gBattle_BG1_X; +extern u16 gBattle_BG1_Y; +extern u16 gBattle_BG2_X; +extern u16 gBattle_BG2_Y; + +extern u8 sav1_map_get_battletype(void); + +struct LinkResultWindow { + struct Window *window; + u16 offset; + u8 left; + u8 top; + u8 *dest; +}; + +#define gLinkResultWindows gUnknown_081F9680 +extern const struct LinkResultWindow gLinkResultWindows[]; + +extern struct SpriteTemplate gSpriteTemplate_81F96D0; + +const struct OamData gOamData_81F952C = { + .affineMode = ST_OAM_AFFINE_DOUBLE, + .size = 3 +}; + +const struct OamData gOamData_81F9534 = { + .affineMode = ST_OAM_AFFINE_DOUBLE, + .size = 3, + .tileNum = 64 +}; + +const union AffineAnimCmd gSpriteAffineAnim_81F953C[] = { + AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), + AFFINEANIMCMD_END +}; + +const union AffineAnimCmd gSpriteAffineAnim_81F954C[] = { + AFFINEANIMCMD_FRAME(0x80, 0x80, 0, 0), + AFFINEANIMCMD_FRAME(0x18, 0x18, 0, -128), + AFFINEANIMCMD_FRAME(0x18, 0x18, 0, -128), + AFFINEANIMCMD_END +}; + +const union AffineAnimCmd *const gSpriteAffineAnimTable_81F956C[] = { + gSpriteAffineAnim_81F953C, + gSpriteAffineAnim_81F954C +}; + +const struct SpriteTemplate gSpriteTemplate_81F9574 = { + .tileTag = 10000, + .paletteTag = 10000, + .oam = &gOamData_81F952C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_81F956C, + .callback = nullsub_36 +}; + +const struct SpriteTemplate gSpriteTemplate_81F958C = { + .tileTag = 10000, + .paletteTag = 10000, + .oam = &gOamData_81F9534, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gSpriteAffineAnimTable_81F956C, + .callback = nullsub_36 +}; + +extern const u8 gUnknown_08E5DC2C[]; + +const struct CompressedSpriteSheet gUnknown_081F95A4[] = { + {gUnknown_08E5DC2C, 4096, 0x2710}, +}; + +struct BattleBackground +{ + const void *tileset; + const void *tilemap; + const void *entryTileset; + const void *entryTilemap; + const void *palette; +}; + +const struct BattleBackground gBattleTerrainTable[] = { +{ + .tileset = gBattleTerrainTiles_TallGrass, + .tilemap = gBattleTerrainTilemap_TallGrass, + .entryTileset = gBattleTerrainAnimTiles_TallGrass, + .entryTilemap = gBattleTerrainAnimTilemap_TallGrass, + .palette = gBattleTerrainPalette_TallGrass +}, +{ + .tileset = gBattleTerrainTiles_LongGrass, + .tilemap = gBattleTerrainTilemap_LongGrass, + .entryTileset = gBattleTerrainAnimTiles_LongGrass, + .entryTilemap = gBattleTerrainAnimTilemap_LongGrass, + .palette = gBattleTerrainPalette_LongGrass +}, +{ + .tileset = gBattleTerrainTiles_Sand, + .tilemap = gBattleTerrainTilemap_Sand, + .entryTileset = gBattleTerrainAnimTiles_Sand, + .entryTilemap = gBattleTerrainAnimTilemap_Sand, + .palette = gBattleTerrainPalette_Sand +}, +{ + .tileset = gBattleTerrainTiles_Underwater, + .tilemap = gBattleTerrainTilemap_Underwater, + .entryTileset = gBattleTerrainAnimTiles_Underwater, + .entryTilemap = gBattleTerrainAnimTilemap_Underwater, + .palette = gBattleTerrainPalette_Underwater +}, +{ + .tileset = gBattleTerrainTiles_Water, + .tilemap = gBattleTerrainTilemap_Water, + .entryTileset = gBattleTerrainAnimTiles_Water, + .entryTilemap = gBattleTerrainAnimTilemap_Water, + .palette = gBattleTerrainPalette_Water +}, +{ + .tileset = gBattleTerrainTiles_PondWater, + .tilemap = gBattleTerrainTilemap_PondWater, + .entryTileset = gBattleTerrainAnimTiles_PondWater, + .entryTilemap = gBattleTerrainAnimTilemap_PondWater, + .palette = gBattleTerrainPalette_PondWater +}, +{ + .tileset = gBattleTerrainTiles_Rock, + .tilemap = gBattleTerrainTilemap_Rock, + .entryTileset = gBattleTerrainAnimTiles_Rock, + .entryTilemap = gBattleTerrainAnimTilemap_Rock, + .palette = gBattleTerrainPalette_Rock +}, +{ + .tileset = gBattleTerrainTiles_Cave, + .tilemap = gBattleTerrainTilemap_Cave, + .entryTileset = gBattleTerrainAnimTiles_Cave, + .entryTilemap = gBattleTerrainAnimTilemap_Cave, + .palette = gBattleTerrainPalette_Cave +}, +{ + .tileset = gBattleTerrainTiles_Building, + .tilemap = gBattleTerrainTilemap_Building, + .entryTileset = gBattleTerrainAnimTiles_Building, + .entryTilemap = gBattleTerrainAnimTilemap_Building, + .palette = gBattleTerrainPalette_Building +}, +{ + .tileset = gBattleTerrainTiles_Building, + .tilemap = gBattleTerrainTilemap_Building, + .entryTileset = gBattleTerrainAnimTiles_Building, + .entryTilemap = gBattleTerrainAnimTilemap_Building, + .palette = gBattleTerrainPalette_Plain + } +}; + +static void sub_800D6C4(void); + +void debug_sub_800D684(void) +{ + u8 spriteId; + ResetSpriteData(); + spriteId = CreateSprite(&gSpriteTemplate_81F96D0, 0, 0, 0); + gSprites[spriteId].invisible = TRUE; + SetMainCallback2(sub_800D6C4); +} + +static void sub_800D6C4(void) +{ + AnimateSprites(); + BuildOamBuffer(); +} + +void sub_800D6D4(void) +{ + u16 ime = REG_IME; + REG_IME = 0; + REG_IE |= INTR_FLAG_VBLANK; + REG_IME = ime; + REG_DISPSTAT = DISPSTAT_VBLANK_INTR; + REG_BG0CNT = 0x9800; + REG_BG1CNT = 0x9c04; + REG_BG2CNT = 0x5e05; + REG_BG3CNT = 0x5a0b; + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + REG_BLDY = 0; + REG_DISPCNT = 0xbf40; +} + +void ApplyPlayerChosenFrameToBattleMenu(void) +{ + TextWindow_SetBaseTileNum(0x12); + TextWindow_LoadStdFrameGraphicsOverridePal(&gUnknown_03004210, 1); + TextWindow_SetBaseTileNum(0x22); + TextWindow_LoadStdFrameGraphicsOverridePal(&gUnknown_03004210, 1); + gPlttBufferUnfaded[92] = 0x7fe0; + gPlttBufferUnfaded[93] = 0x2529; + gPlttBufferUnfaded[94] = 0x7fff; + gPlttBufferUnfaded[95] = 0x675a; + CpuSet(&gPlttBufferUnfaded[92], &gPlttBufferFaded[92], 4); + sub_8032A38(); +} + +void DrawMainBattleBackground(void) +{ + if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER /*| BATTLE_TYPE_x2000000*/)) + { + LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_BattleTower, 0x20, 0x60); + } + else if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) + { + if (gGameVersion == VERSION_RUBY) + { + LZDecompressVram(gBattleTerrainTiles_Cave, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Cave, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_Groudon, 0x20, 0x60); + } + else + { + LZDecompressVram(gBattleTerrainTiles_Water, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Water, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_Kyogre, 0x20, 0x60); + } + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + { + u8 trainerClass = gTrainers[gTrainerBattleOpponent].trainerClass; + if (trainerClass == TRAINER_CLASS_LEADER) + { + LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_BuildingLeader, 0x20, 0x60); + return; + } + else if (trainerClass == TRAINER_CLASS_CHAMPION) + { + LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_StadiumSteven, 0x20, 0x60); + return; + } + } + + switch (GetCurrentMapBattleScene()) + { + case MAP_BATTLE_SCENE_NORMAL: + LZDecompressVram(gBattleTerrainTable[gBattleTerrain].tileset, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTable[gBattleTerrain].tilemap, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainTable[gBattleTerrain].palette, 0x20, 0x60); + break; + case MAP_BATTLE_SCENE_GYM: + LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_BuildingGym, 0x20, 0x60); + break; + case MAP_BATTLE_SCENE_MAGMA: + LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_StadiumMagma, 0x20, 0x60); + break; + case MAP_BATTLE_SCENE_AQUA: + LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_StadiumAqua, 0x20, 0x60); + break; + case MAP_BATTLE_SCENE_SIDNEY: + LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_StadiumSidney, 0x20, 0x60); + break; + case MAP_BATTLE_SCENE_PHOEBE: + LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_StadiumPhoebe, 0x20, 0x60); + break; + case MAP_BATTLE_SCENE_GLACIA: + LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_StadiumGlacia, 0x20, 0x60); + break; + case MAP_BATTLE_SCENE_DRAKE: + LZDecompressVram(gBattleTerrainTiles_Stadium, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_StadiumDrake, 0x20, 0x60); + break; + case MAP_BATTLE_SCENE_BATTLE_TOWER: + LZDecompressVram(gBattleTerrainTiles_Building, (void*)(VRAM + 0x8000)); + LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(VRAM + 0xD000)); + LoadCompressedPalette(gBattleTerrainPalette_BattleTower, 0x20, 0x60); + break; + } + } +} + +void LoadBattleTextboxAndBackground(void) +{ + LZDecompressVram(gBattleTextboxTiles, (void*)(BG_VRAM)); + CpuSet(gBattleTextboxTilemap, (void *)(VRAM + 0xC000), 0x800); + LoadCompressedPalette(gBattleTextboxPalette, 0, 0x40); + ApplyPlayerChosenFrameToBattleMenu(); + DrawMainBattleBackground(); + + #if DEBUG + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + debug_sub_8008218((void*)(VRAM + 0x600), 0, (void*)(VRAM + 0xC000), 1); + debug_sub_8008264(257, 3, 1, 3, 1); + debug_sub_8008264(257, 3, 21, 3, 1); + debug_sub_8008264(257, 3, 41, 3, 1); + } + #endif +} + +static void sub_800DAF8(u8 taskId, u8 windowId, u8 *dest) +{ + int i; + u16 r4 = 0; + u16 src[6]; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { + if (gTasks[taskId].data[5]) { + switch (windowId) { + case 0: + r4 = gTasks[taskId].data[3] & 0x3f; + break; + case 1: + r4 = (gTasks[taskId].data[4] & 0xfc0) >> 6; + break; + case 2: + r4 = (gTasks[taskId].data[3] & 0xfc0) >> 6; + break; + case 3: + r4 = gTasks[taskId].data[4] & 0x3f; + break; + } + } else { + switch (windowId) { + case 0: + r4 = gTasks[taskId].data[3] & 0x3f; + break; + case 1: + r4 = gTasks[taskId].data[4] & 0x3f; + break; + case 2: + r4 = (gTasks[taskId].data[3] & 0xfc0) >> 6; + break; + case 3: + r4 = (gTasks[taskId].data[4] & 0xfc0) >> 6; + break; + } + } + for (i = 0; i < 3; i++) { + src[i] = ((r4 & (3 << (i * 2))) >> (i * 2)) + 0x6001; + } + CpuSet(src, dest, 3); + } else { + if (windowId == gBattleStruct->linkPlayerIndex) { + r4 = gTasks[taskId].data[3]; + } else { + r4 = gTasks[taskId].data[4]; + } + for (i = 0; i < 6; i++) { + src[i] = ((r4 & (3 << (i * 2))) >> (i * 2)) + 0x6001; + } + CpuSet(src, dest, 6); + } +} + + +#if ENGLISH +#define LEFT_MESSAGE_X 6 +#define RIGHT_MESSAGE_X 21 +#define TILE_OFFSET_LOSS 168 +#elif GERMAN +#define LEFT_MESSAGE_X 5 +#define RIGHT_MESSAGE_X 20 +#define TILE_OFFSET_LOSS 172 +#endif +#define TILE_OFFSET_WIN 160 +#define CENTER_MESSAGE_X 13 +#define MESSAGE_Y 2 + +#define PRINT_MESSAGE(text, tileDataStartOffset, x) \ +{ \ + Text_InitWindow(&gUnknown_03004210, text, tileDataStartOffset, x, MESSAGE_Y); \ + Text_PrintWindow8002F44(&gUnknown_03004210); \ +} + +#define PRINT_MESSAGE_LEFT(text, tileDataStartOffset) PRINT_MESSAGE(text, tileDataStartOffset, LEFT_MESSAGE_X) +#define PRINT_MESSAGE_RIGHT(text, tileDataStartOffset) PRINT_MESSAGE(text, tileDataStartOffset, RIGHT_MESSAGE_X) + +static void PrintLinkBattleWinLossTie(void) +{ + + if (gBattleOutcome == 3) + { + PRINT_MESSAGE(BattleText_Tie, TILE_OFFSET_WIN, CENTER_MESSAGE_X); + return; + } + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + // Double battle? + + if (gBattleOutcome == 1) + { + + // lp_field_18 = player position? + switch (gLinkPlayers[gBattleStruct->linkPlayerIndex].lp_field_18) + { + case 0: + case 2: + PRINT_MESSAGE_LEFT(BattleText_Win, TILE_OFFSET_WIN); + PRINT_MESSAGE_RIGHT(BattleText_Loss, TILE_OFFSET_LOSS); + return; + + case 1: + case 3: + PRINT_MESSAGE_RIGHT(BattleText_Win, TILE_OFFSET_WIN) + PRINT_MESSAGE_LEFT(BattleText_Loss, TILE_OFFSET_LOSS) + return; + } + } + else + { + + switch (gLinkPlayers[gBattleStruct->linkPlayerIndex].lp_field_18) + { + case 1: + case 3: + PRINT_MESSAGE_LEFT(BattleText_Win, TILE_OFFSET_WIN); + PRINT_MESSAGE_RIGHT(BattleText_Loss, TILE_OFFSET_LOSS); + return; + + case 0: + case 2: + PRINT_MESSAGE_RIGHT(BattleText_Win, TILE_OFFSET_WIN); + PRINT_MESSAGE_LEFT(BattleText_Loss, TILE_OFFSET_LOSS); + return; + } + } + + return; + } + + + if (gBattleOutcome == 1) + { + if (gLinkPlayers[gBattleStruct->linkPlayerIndex].lp_field_18 != 0) + { + PRINT_MESSAGE_RIGHT(BattleText_Win, TILE_OFFSET_WIN); + PRINT_MESSAGE_LEFT(BattleText_Loss, TILE_OFFSET_LOSS); + } + else + { + PRINT_MESSAGE_LEFT(BattleText_Win, TILE_OFFSET_WIN); + PRINT_MESSAGE_RIGHT(BattleText_Loss, TILE_OFFSET_LOSS); + } + } + else + { + if (gLinkPlayers[gBattleStruct->linkPlayerIndex].lp_field_18 != 0) + { + PRINT_MESSAGE_LEFT(BattleText_Win, TILE_OFFSET_WIN); + PRINT_MESSAGE_RIGHT(BattleText_Loss, TILE_OFFSET_LOSS); + } + else + { + PRINT_MESSAGE_RIGHT(BattleText_Win, TILE_OFFSET_WIN); + PRINT_MESSAGE_LEFT(BattleText_Loss, TILE_OFFSET_LOSS); + } + } +} + + +void sub_800DE30(u8 taskId) +{ + u8 palette; + int i; + + switch (gTasks[taskId].data[0]) { + + case 0: + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { + for (i = 0; i < 4; i++) { + u8 windowId = (gLinkPlayers[i].lp_field_18 & 3); + Text_InitWindow8002E4C( + gLinkResultWindows[windowId].window, + gLinkPlayers[i].name, + gLinkResultWindows[windowId].offset, + gLinkResultWindows[windowId].left, + gLinkResultWindows[windowId].top, + 1); + Text_PrintWindow8002F44(gLinkResultWindows[windowId].window); + sub_800DAF8(taskId, windowId, gLinkResultWindows[windowId].dest); + } + } else { + u8 windowId = 4; + + u8 playerId = gBattleStruct->linkPlayerIndex; + u8 opponentId = gBattleStruct->linkPlayerIndex ^ 1; + if (gLinkPlayers[playerId].lp_field_18) { + opponentId = gBattleStruct->linkPlayerIndex; + playerId = gBattleStruct->linkPlayerIndex ^ 1; + } + + Text_InitWindow8002E4C( + gLinkResultWindows[windowId].window, + gLinkPlayers[playerId].name, + gLinkResultWindows[windowId].offset, + gLinkResultWindows[windowId].left, + gLinkResultWindows[windowId].top, + 1); + Text_PrintWindow8002F44(gLinkResultWindows[windowId].window); + sub_800DAF8(taskId, playerId, gLinkResultWindows[windowId].dest); + + Text_InitWindow8002E4C( + gLinkResultWindows[windowId + 1].window, + gLinkPlayers[opponentId].name, + gLinkResultWindows[windowId + 1].offset, + gLinkResultWindows[windowId + 1].left, + gLinkResultWindows[windowId + 1].top, + 1); + Text_PrintWindow8002F44(gLinkResultWindows[windowId + 1].window); + sub_800DAF8(taskId, opponentId, gLinkResultWindows[windowId + 1].dest); + } + gTasks[taskId].data[0]++; + break; + + case 1: + palette = AllocSpritePalette(10000); + gPlttBufferUnfaded[palette * 16 + 0x10f] = gPlttBufferFaded[palette * 16 + 0x10f] = 0x7fff; + gBattleStruct->unk1608A = CreateSprite(&gSpriteTemplate_81F9574, 108, 80, 0); + gBattleStruct->unk1608B = CreateSprite(&gSpriteTemplate_81F958C, 132, 80, 0); + gSprites[gBattleStruct->unk1608A].invisible = TRUE; + gSprites[gBattleStruct->unk1608B].invisible = TRUE; + gTasks[taskId].data[0]++; + break; + + case 2: + if (gTasks[taskId].data[5]) { + gBattle_BG1_X = (-20) - (Sin2(gTasks[taskId].data[1]) / 32); + gBattle_BG2_X = (-140) - (Sin2(gTasks[taskId].data[2]) / 32); + gBattle_BG1_Y = -36; + gBattle_BG2_Y = -36; + } else { + gBattle_BG1_X = (-20) - (Sin2(gTasks[taskId].data[1]) / 32); + gBattle_BG1_Y = (-164) + (Cos2(gTasks[taskId].data[1]) / 32); + gBattle_BG2_X = (-140) - (Sin2(gTasks[taskId].data[2]) / 32); + gBattle_BG2_Y = (-164) + (Cos2(gTasks[taskId].data[2]) / 32); + } + if (gTasks[taskId].data[2]) { + gTasks[taskId].data[2] -= 2; + gTasks[taskId].data[1] += 2; + } else { + if (gTasks[taskId].data[5]) { + PrintLinkBattleWinLossTie(); + } + PlaySE(SE_W231); + DestroyTask(taskId); + gSprites[gBattleStruct->unk1608A].invisible = FALSE; + gSprites[gBattleStruct->unk1608B].invisible = FALSE; + gSprites[gBattleStruct->unk1608B].oam.tileNum += 0x40; + gSprites[gBattleStruct->unk1608A].data[0] = 0; + gSprites[gBattleStruct->unk1608B].data[0] = 1; + gSprites[gBattleStruct->unk1608A].data[1] = gSprites[gBattleStruct->unk1608A].pos1.x; + gSprites[gBattleStruct->unk1608B].data[1] = gSprites[gBattleStruct->unk1608B].pos1.x; + gSprites[gBattleStruct->unk1608A].data[2] = 0; + gSprites[gBattleStruct->unk1608B].data[2] = 0; + } + break; + } +} + +void LoadBattleEntryBackground(void) { + if (gBattleTypeFlags & BATTLE_TYPE_LINK) { + LZDecompressVram(gVersusFrameGfx, (void *)0x6004000); + LZDecompressVram(gVersusFrameTilemap, (void *)0x600e000); + LZDecompressVram(gVersusFrameTilemap, (void *)0x600f000); + LZDecompressVram(gUnknown_08E5DC2C, (void *)0x6010000); + LoadCompressedPalette(gVersusFramePal, 0x60, 0x20); + REG_BG1CNT = 0x5c04; + REG_WININ = 0x36; + REG_WINOUT = 0x36; + gBattle_BG1_Y = 0xff5c; + gBattle_BG2_Y = 0xff5c; + LoadCompressedObjectPic(gUnknown_081F95A4); + return; + } else if (gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK)) { + LZDecompressVram(gBattleTerrainAnimTiles_Building, (void *)0x6004000); + LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void *)0x600e000); + return; + } else if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) { + if (gGameVersion == VERSION_RUBY) { + LZDecompressVram(gBattleTerrainAnimTiles_Cave, (void *)0x6004000); + LZDecompressVram(gBattleTerrainAnimTilemap_Cave, (void *)0x600e000); + return; + } else { + LZDecompressVram(gBattleTerrainAnimTiles_Underwater, (void *)0x6004000); + LZDecompressVram(gBattleTerrainAnimTilemap_Underwater, (void *)0x600e000); + return; + } + } else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) { + if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x19) { + LZDecompressVram(gBattleTerrainAnimTiles_Building, (void *)0x6004000); + LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void *)0x600e000); + return; + } else if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x20) { + LZDecompressVram(gBattleTerrainAnimTiles_Building, (void *)0x6004000); + LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void *)0x600e000); + return; + } + } + if (sav1_map_get_battletype() == 0) { + LZDecompressVram(gBattleTerrainTable[gBattleTerrain].entryTileset, (void *)0x6004000); + LZDecompressVram(gBattleTerrainTable[gBattleTerrain].entryTilemap, (void *)0x600e000); + return; + } + LZDecompressVram(gBattleTerrainAnimTiles_Building, (void *)0x6004000); + LZDecompressVram(gBattleTerrainAnimTilemap_Building, (void *)0x600e000); +} + +int LoadChosenBattleElement(u8 type) { + int ret = 0; + switch (type) { + case 0: + LZDecompressVram(&gBattleTextboxTiles, (void *)0x6000000); + break; + case 1: + CpuCopy16(gBattleTextboxTilemap, (void *)0x600c000, 0x1000); + break; + case 2: + LoadCompressedPalette(gBattleTextboxPalette, 0, 0x40); + break; + case 3: // tiles + if (!(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK))) { + if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) { + if (gGameVersion == VERSION_RUBY) { + LZDecompressVram(gBattleTerrainTiles_Cave, (void *)0x6008000); + break; + } else { + LZDecompressVram(gBattleTerrainTiles_Water, (void *)0x6008000); + break; + } + } else { + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) { + if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x19) { + LZDecompressVram(gBattleTerrainTiles_Building, (void *)0x6008000); + break; + } else if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x20) { + LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); + break; + } + } + switch (sav1_map_get_battletype()) { + case 0: + LZDecompressVram(gBattleTerrainTable[gBattleTerrain].tileset, (void *)0x6008000); + break; + case 2: + LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); + break; + case 3: + LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); + break; + case 4: + LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); + break; + case 5: + LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); + break; + case 6: + LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); + break; + case 7: + LZDecompressVram(gBattleTerrainTiles_Stadium, (void *)0x6008000); + break; + case 1: + case 8: + LZDecompressVram(gBattleTerrainTiles_Building, (void *)0x6008000); + break; + } + break; + } + } else { + LZDecompressVram(gBattleTerrainTiles_Building, (void *)0x6008000); + break; + } + case 4: // tilemap + if (!(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK))) { + if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) { + if (gGameVersion == 2) { + LZDecompressVram(gBattleTerrainTilemap_Cave, (void *)0x600d000); + break; + } else { + LZDecompressVram(gBattleTerrainTilemap_Water, (void *)0x600d000); + break; + } + } else { + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) { + if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x19) { + LZDecompressVram(gBattleTerrainTilemap_Building, (void *)0x600d000); + break; + } else if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x20) { + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); + break; + } + } + switch (sav1_map_get_battletype()) { + case 0: + LZDecompressVram(gBattleTerrainTable[gBattleTerrain].tilemap, (void *)0x600d000); + break; + case 2: + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); + break; + case 3: + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); + break; + case 4: + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); + break; + case 5: + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); + break; + case 6: + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); + break; + case 7: + LZDecompressVram(gBattleTerrainTilemap_Stadium, (void *)0x600d000); + break; + case 1: + case 8: + LZDecompressVram(gBattleTerrainTilemap_Building, (void *)0x600d000); + break; + } + break; + } + } else { + LZDecompressVram(gBattleTerrainTilemap_Building, (void *)0x600d000); + break; + } + case 5: // palette + if (!(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK))) { + if (gBattleTypeFlags & BATTLE_TYPE_KYOGRE_GROUDON) { + if (gGameVersion == 2) { + LoadCompressedPalette(gBattleTerrainPalette_Groudon, 0x20, 0x60); + break; + } else { + LoadCompressedPalette(gBattleTerrainPalette_Kyogre, 0x20, 0x60); + break; + } + } else { + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) { + if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x19) { + LoadCompressedPalette(gBattleTerrainPalette_BuildingLeader, 0x20, 0x60); + break; + } else if (gTrainers[gTrainerBattleOpponent].trainerClass == 0x20) { + LoadCompressedPalette(gBattleTerrainPalette_StadiumSteven, 0x20, 0x60); + break; + } + } + switch (sav1_map_get_battletype()) { + case 0: + LoadCompressedPalette(gBattleTerrainTable[gBattleTerrain].palette, 0x20, 0x60); + break; + case 1: + LoadCompressedPalette(gBattleTerrainPalette_BuildingGym, 0x20, 0x60); + break; + case 2: + LoadCompressedPalette(gBattleTerrainPalette_StadiumMagma, 0x20, 0x60); + break; + case 3: + LoadCompressedPalette(gBattleTerrainPalette_StadiumAqua, 0x20, 0x60); + break; + case 4: + LoadCompressedPalette(gBattleTerrainPalette_StadiumSidney, 0x20, 0x60); + break; + case 5: + LoadCompressedPalette(gBattleTerrainPalette_StadiumPhoebe, 0x20, 0x60); + break; + case 6: + LoadCompressedPalette(gBattleTerrainPalette_StadiumGlacia, 0x20, 0x60); + break; + case 7: + LoadCompressedPalette(gBattleTerrainPalette_StadiumDrake, 0x20, 0x60); + break; + case 8: + LoadCompressedPalette(gBattleTerrainPalette_BattleTower, 0x20, 0x60); + break; + } + break; + } + } else { + LoadCompressedPalette(gBattleTerrainPalette_BattleTower, 0x20, 0x60); + break; + } + case 6: + ApplyPlayerChosenFrameToBattleMenu(); + break; + default: + ret = 1; + } + return ret; +} diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c new file mode 100644 index 000000000..d514935cf --- /dev/null +++ b/src/battle_controller_link_opponent.c @@ -0,0 +1,1778 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "battle_anim_special.h" +#include "battle_interface.h" +#include "data2.h" +#include "link.h" +#include "m4a.h" +#include "main.h" +#include "palette.h" +#include "rom_8077ABC.h" +#include "rom3.h" +#include "constants/songs.h" +#include "sound.h" +#include "sprite.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "util.h" +#include "ewram.h" + +struct MovePpInfo +{ + u16 moves[4]; + u8 pp[4]; + u8 ppBonuses; +}; + +extern u8 gActiveBattler; +extern u8 gBattleBufferA[][0x200]; +extern u8 gBankSpriteIds[]; +extern u16 gBattlerPartyIndexes[]; +extern u8 gHealthboxIDs[]; +extern u16 gBattleTypeFlags; +extern u8 gBattleMonForms[]; +extern void (*gBattleBankFunc[])(void); +extern s32 gAnimMoveDmg; +extern u16 gAnimMovePower; +extern u8 gAnimFriendship; +extern u16 gWeatherMoveAnim; +extern u32 gTransformedPersonalities[]; +extern u8 gAnimScriptActive; +extern void (*gAnimScriptCallback)(void); +extern u8 gDisplayedStringBattle[]; +extern bool8 gDoingBattleAnim; +extern u8 gBattleOutcome; +extern u16 gUnknown_02024DE8; +extern u8 gUnknown_02024E68[]; +extern struct SpriteTemplate gUnknown_02024E8C; +extern u8 gAnimMoveTurn; +extern struct Window gUnknown_03004210; +extern u8 gUnknown_0300434C[]; +extern u32 gBattleExecBuffer; +extern MainCallback gPreBattleCallback1; +extern struct MusicPlayerInfo gMPlay_BGM; + +extern u8 sub_8077F68(); +extern u8 GetBattlerSubpriority(); +extern u8 GetBattlerPosition(u8); +extern void BattleLoadOpponentMonSprite(struct Pokemon *, u8); +extern void sub_8037A74(void); +extern void sub_8032984(u8, u16); +extern void sub_8037E30(void); +extern void sub_80312F0(struct Sprite *); +extern u8 StartSendOutMonAnimation(); +extern void sub_8032A08(); +extern void sub_8043DB0(); +extern void sub_8037BBC(void); +extern s32 sub_803FC34(u16); +extern void sub_8031A6C(u16, u8); +extern void sub_80313A0(struct Sprite *); +extern void sub_803757C(void); +extern void oamt_add_pos2_onto_pos1(); +extern void StoreSpriteCallbackInData(); +extern void StartAnimLinearTranslation(struct Sprite *); +extern void sub_80375B4(void); +extern void sub_8010384(struct Sprite *); +extern void sub_8037B78(void); +extern u8 sub_8031720(); +extern bool8 mplay_80342A4(u8); +extern void DoMoveAnim(); +extern void sub_80326EC(); +extern void sub_8031F24(void); +extern void sub_80324BC(); +extern void BufferStringBattle(); +extern void sub_8037C2C(void); +extern void sub_8043D84(); +extern void sub_8037B24(void); +extern void sub_8045A5C(); +extern void sub_8037FAC(void); +extern void move_anim_start_t2_for_situation(); +extern void dp01t_0F_4_move_anim(void); +extern void sub_8047858(); +extern u8 GetBattlerSide(u8); +extern void StartBattleIntroAnim(); +extern void sub_803A3A8(struct Sprite *); +extern void sub_8044CA0(u8); +extern void nullsub_47(void); +extern bool8 IsDoubleBattle(void); +extern void sub_8037840(void); +extern void sub_8031B74(); +extern u8 IsBankSpritePresent(); +extern u8 move_anim_start_t3(); +extern void sub_8037FD8(void); +extern void sub_8037F34(void); +extern void LinkOpponentBufferExecCompleted(void); +extern void sub_804777C(); + +// this file's functions + +u32 dp01_getattr_by_ch1_for_player_pokemon__(u8, u8 *); +void sub_803752C(void); +void sub_8037D2C(void); +void sub_8038900(u8); +void sub_8039430(u8, u8); +void sub_8039648(void); +void sub_8039B64(void); +void sub_803A2C4(u8); +void sub_803A4E0(void); + +void LinkOpponentHandleGetAttributes(void); +void LinkOpponentHandlecmd1(void); +void LinkOpponentHandleSetAttributes(void); +void LinkOpponentHandlecmd3(void); +void LinkOpponentHandleLoadPokeSprite(void); +void LinkOpponentHandleSendOutPoke(void); +void LinkOpponentHandleReturnPokeToBall(void); +void LinkOpponentHandleTrainerThrow(void); +void LinkOpponentHandleTrainerSlide(void); +void LinkOpponentHandleTrainerSlideBack(void); +void LinkOpponentHandlecmd10(void); +void LinkOpponentHandlecmd11(void); +void LinkOpponentHandlecmd12(void); +void LinkOpponentHandleBallThrow(void); +void LinkOpponentHandlePuase(void); +void LinkOpponentHandleMoveAnimation(void); +void LinkOpponentHandlePrintString(void); +void LinkOpponentHandlePrintStringPlayerOnly(void); +void LinkOpponentHandlecmd18(void); +void LinkOpponentHandlecmd19(void); +void LinkOpponentHandlecmd20(void); +void LinkOpponentHandleOpenBag(void); +void LinkOpponentHandlecmd22(void); +void LinkOpponentHandlecmd23(void); +void LinkOpponentHandleHealthBarUpdate(void); +void LinkOpponentHandleExpBarUpdate(void); +void LinkOpponentHandleStatusIconUpdate(void); +void LinkOpponentHandleStatusAnimation(void); +void LinkOpponentHandleStatusXor(void); +void LinkOpponentHandlecmd29(void); +void LinkOpponentHandleDMATransfer(void); +void LinkOpponentHandlecmd31(void); +void LinkOpponentHandlecmd32(void); +void LinkOpponentHandlecmd33(void); +void LinkOpponentHandlecmd34(void); +void LinkOpponentHandlecmd35(void); +void LinkOpponentHandlecmd36(void); +void LinkOpponentHandlecmd37(void); +void LinkOpponentHandlecmd38(void); +void LinkOpponentHandlecmd39(void); +void LinkOpponentHandlecmd40(void); +void LinkOpponentHandleHitAnimation(void); +void LinkOpponentHandlecmd42(void); +void LinkOpponentHandleEffectivenessSound(void); +void LinkOpponentHandlecmd44(void); +void LinkOpponentHandleFaintingCry(void); +void LinkOpponentHandleIntroSlide(void); +void LinkOpponentHandleTrainerBallThrow(void); +void LinkOpponentHandlecmd48(void); +void LinkOpponentHandlecmd49(void); +void LinkOpponentHandlecmd50(void); +void LinkOpponentHandleSpriteInvisibility(void); +void LinkOpponentHandleBattleAnimation(void); +void LinkOpponentHandleLinkStandbyMsg(void); +void LinkOpponentHandleResetActionMoveSelection(void); +void LinkOpponentHandlecmd55(void); +void LinkOpponentHandlecmd56(void); + +// const data + +typedef void (*BattleBufferCmd) (void); +const BattleBufferCmd gLinkOpponentBufferCommands[] = +{ + LinkOpponentHandleGetAttributes, + LinkOpponentHandlecmd1, + LinkOpponentHandleSetAttributes, + LinkOpponentHandlecmd3, + LinkOpponentHandleLoadPokeSprite, + LinkOpponentHandleSendOutPoke, + LinkOpponentHandleReturnPokeToBall, + LinkOpponentHandleTrainerThrow, + LinkOpponentHandleTrainerSlide, + LinkOpponentHandleTrainerSlideBack, + LinkOpponentHandlecmd10, + LinkOpponentHandlecmd11, + LinkOpponentHandlecmd12, + LinkOpponentHandleBallThrow, + LinkOpponentHandlePuase, + LinkOpponentHandleMoveAnimation, + LinkOpponentHandlePrintString, + LinkOpponentHandlePrintStringPlayerOnly, + LinkOpponentHandlecmd18, + LinkOpponentHandlecmd19, + LinkOpponentHandlecmd20, + LinkOpponentHandleOpenBag, + LinkOpponentHandlecmd22, + LinkOpponentHandlecmd23, + LinkOpponentHandleHealthBarUpdate, + LinkOpponentHandleExpBarUpdate, + LinkOpponentHandleStatusIconUpdate, + LinkOpponentHandleStatusAnimation, + LinkOpponentHandleStatusXor, + LinkOpponentHandlecmd29, + LinkOpponentHandleDMATransfer, + LinkOpponentHandlecmd31, + LinkOpponentHandlecmd32, + LinkOpponentHandlecmd33, + LinkOpponentHandlecmd34, + LinkOpponentHandlecmd35, + LinkOpponentHandlecmd36, + LinkOpponentHandlecmd37, + LinkOpponentHandlecmd38, + LinkOpponentHandlecmd39, + LinkOpponentHandlecmd40, + LinkOpponentHandleHitAnimation, + LinkOpponentHandlecmd42, + LinkOpponentHandleEffectivenessSound, + LinkOpponentHandlecmd44, + LinkOpponentHandleFaintingCry, + LinkOpponentHandleIntroSlide, + LinkOpponentHandleTrainerBallThrow, + LinkOpponentHandlecmd48, + LinkOpponentHandlecmd49, + LinkOpponentHandlecmd50, + LinkOpponentHandleSpriteInvisibility, + LinkOpponentHandleBattleAnimation, + LinkOpponentHandleLinkStandbyMsg, + LinkOpponentHandleResetActionMoveSelection, + LinkOpponentHandlecmd55, + LinkOpponentHandlecmd56 +}; + +// code + +void nullsub_47(void) +{ +} + +void SetBankFuncToLinkOpponentBufferRunCommand(void) +{ + gBattleBankFunc[gActiveBattler] = sub_803752C; +} + +void sub_803752C(void) +{ + if (gBattleExecBuffer & gBitTable[gActiveBattler]) + { + if (gBattleBufferA[gActiveBattler][0] <= 0x38) + gLinkOpponentBufferCommands[gBattleBufferA[gActiveBattler][0]](); + else + LinkOpponentBufferExecCompleted(); + } +} + +void sub_803757C(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + LinkOpponentBufferExecCompleted(); +} + +void sub_80375B4(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + { + sub_8031B74(gSprites[gBankSpriteIds[gActiveBattler]].oam.affineParam); + gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum = gSprites[gBankSpriteIds[gActiveBattler]].data[5]; + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + LinkOpponentBufferExecCompleted(); + } +} + +void sub_8037644(void) +{ + if ((--ewram17810[gActiveBattler].unk9) == 0xFF) + { + ewram17810[gActiveBattler].unk9 = 0; + LinkOpponentBufferExecCompleted(); + } +} + +void sub_8037680(void) +{ + bool8 r6 = FALSE; + + if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) + { + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) + r6 = TRUE; + } + else + { + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxIDs[gActiveBattler ^ 2]].callback == SpriteCallbackDummy) + r6 = TRUE; + } + if (IsCryPlayingOrClearCrySongs()) + r6 = FALSE; + + if (r6) + { + if (GetBattlerPosition(gActiveBattler) == 1) + { + if (!ewram17810[gActiveBattler].unk1_0 || !ewram17810[gActiveBattler ^ 2].unk1_0) + return; + ewram17810[gActiveBattler].unk0_7 = 0; + ewram17810[gActiveBattler].unk1_0 = 0; + ewram17810[gActiveBattler ^ 2].unk0_7 = 0; + ewram17810[gActiveBattler ^ 2].unk1_0 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + } + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (GetBattlerPosition(gActiveBattler) == 1) + m4aMPlayContinue(&gMPlay_BGM); + } + else + { + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 256); + } + ewram17810[gActiveBattler].unk9 = 3; + gBattleBankFunc[gActiveBattler] = sub_8037644; + } +} + +void sub_8037840(void) +{ + if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) + sub_8141828(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + if (!ewram17810[gActiveBattler ^ 2].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_7) + sub_8141828(gActiveBattler ^ 2, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ 2]]); + if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_3) + { + if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) && GetBattlerPosition(gActiveBattler) == 3) + { + if (++ewram17810[gActiveBattler].unk9 == 1) + return; + ewram17810[gActiveBattler].unk9 = 0; + } + if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler ^ 2]]); + sub_8045A5C( + gHealthboxIDs[gActiveBattler ^ 2], + &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], + 0); + sub_804777C(gActiveBattler ^ 2); + sub_8043DFC(gHealthboxIDs[gActiveBattler ^ 2]); + sub_8032984( + gActiveBattler ^ 2, + GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], MON_DATA_SPECIES)); + } + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); + sub_8045A5C( + gHealthboxIDs[gActiveBattler], + &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], + 0); + sub_804777C(gActiveBattler); + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + sub_8032984( + gActiveBattler, + GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + + ewram17840.unk9_0 = 0; + gBattleBankFunc[gActiveBattler] = sub_8037680; + } +} + +void sub_8037A74(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].animEnded == TRUE + && gSprites[gBankSpriteIds[gActiveBattler]].pos2.x == 0) + { + if (!ewram17810[gActiveBattler].unk0_7) + { + sub_8141828(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + return; + } + if (ewram17810[gActiveBattler].unk1_0) + { + ewram17810[gActiveBattler].unk0_7 = 0; + ewram17810[gActiveBattler].unk1_0 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + LinkOpponentBufferExecCompleted(); + return; + } + } +} + +void sub_8037B24(void) +{ + s16 r4 = sub_8045C78(gActiveBattler, gHealthboxIDs[gActiveBattler], 0, 0); + + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + if (r4 != -1) + sub_80440EC(gHealthboxIDs[gActiveBattler], r4, 0); + else + LinkOpponentBufferExecCompleted(); +} + +void sub_8037B78(void) +{ + if (!gSprites[gBankSpriteIds[gActiveBattler]].inUse) + { + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + LinkOpponentBufferExecCompleted(); + } +} + +void sub_8037BBC(void) +{ + if (!ewram17810[gActiveBattler].unk0_6) + { + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + sub_8032A08(gActiveBattler); + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + LinkOpponentBufferExecCompleted(); + } +} + +void sub_8037C2C(void) +{ + if (gUnknown_03004210.state == 0) + LinkOpponentBufferExecCompleted(); +} + +void dp01t_0F_4_move_anim(void) +{ + u8 spriteId = gBankSpriteIds[gActiveBattler]; + + if (gSprites[spriteId].data[1] == 32) + { + gSprites[spriteId].data[1] = 0; + gSprites[spriteId].invisible = FALSE; + gDoingBattleAnim = 0; + LinkOpponentBufferExecCompleted(); + } + else + { + if (((u16)gSprites[spriteId].data[1] % 4) == 0) + gSprites[spriteId].invisible ^= 1; + gSprites[spriteId].data[1]++; + } +} + +void sub_8037CC0(void) +{ + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) + { + if (ewram17800[gActiveBattler].substituteSprite) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); + gBattleBankFunc[gActiveBattler] = sub_8037D2C; + } +} + +void sub_8037D2C(void) +{ + if (!ewram17810[gActiveBattler].unk0_6) + { + CreateTask(c3_0802FDF4, 10); + LinkOpponentBufferExecCompleted(); + } +} + +void sub_8037D64(void) +{ + if (ewram17810[gActiveBattler].unk1_0) + { + ewram17810[gActiveBattler].unk0_7 = 0; + ewram17810[gActiveBattler].unk1_0 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 0); + sub_8045A5C( + gHealthboxIDs[gActiveBattler], + &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], + 0); + sub_804777C(gActiveBattler); + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + sub_8031F88(gActiveBattler); + gBattleBankFunc[gActiveBattler] = sub_8037CC0; + } +} + +void sub_8037E30(void) +{ + if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) + sub_8141828(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + if (gSprites[gUnknown_0300434C[gActiveBattler]].callback == SpriteCallbackDummy + && !ewram17810[gActiveBattler].unk0_3) + { + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); + sub_8032984(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + gBattleBankFunc[gActiveBattler] = sub_8037D64; + } +} + +void sub_8037EF0(void) +{ + if (gReceivedRemoteLinkPlayers == 0) + { + m4aSongNumStop(SE_HINSI); + gMain.inBattle = FALSE; + gMain.callback1 = gPreBattleCallback1; + SetMainCallback2(c2_8011A1C); + } +} + +void sub_8037F34(void) +{ + if (!gPaletteFade.active) + { + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + sub_800832C(); + gBattleBankFunc[gActiveBattler] = sub_8037EF0; + } + else + { + m4aSongNumStop(SE_HINSI); + gMain.inBattle = FALSE; + gMain.callback1 = gPreBattleCallback1; + SetMainCallback2(gMain.savedCallback); + } + } +} + +void sub_8037FAC(void) +{ + if (!ewram17810[gActiveBattler].unk0_4) + LinkOpponentBufferExecCompleted(); +} + +void sub_8037FD8(void) +{ + if (!ewram17810[gActiveBattler].unk0_5) + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentBufferExecCompleted(void) +{ + gBattleBankFunc[gActiveBattler] = sub_803752C; + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + u8 playerId = GetMultiplayerId(); + + PrepareBufferDataTransferLink(2, 4, &playerId); + gBattleBufferA[gActiveBattler][0] = 0x38; + } + else + { + gBattleExecBuffer &= ~gBitTable[gActiveBattler]; + } +} + +void LinkOpponentHandleGetAttributes(void) +{ + u8 buffer[0x100]; + u32 r6 = 0; + u8 r4; + s32 i; + + if (gBattleBufferA[gActiveBattler][2] == 0) + { + r6 = dp01_getattr_by_ch1_for_player_pokemon__(gBattlerPartyIndexes[gActiveBattler], buffer); + } + else + { + r4 = gBattleBufferA[gActiveBattler][2]; + for (i = 0; i < 6; i++) + { + if (r4 & 1) + r6 += dp01_getattr_by_ch1_for_player_pokemon__(i, buffer + r6); + r4 >>= 1; + } + } + Emitcmd29(1, r6, buffer); + LinkOpponentBufferExecCompleted(); +} + +u32 dp01_getattr_by_ch1_for_player_pokemon__(u8 a, u8 *buffer) +{ + struct BattlePokemon battlePokemon; + struct MovePpInfo moveData; + u8 nickname[20]; + u8 *src; + s16 data16; + u32 data32; + s32 size = 0; + + switch (gBattleBufferA[gActiveBattler][1]) + { + case 0: + battlePokemon.species = GetMonData(&gEnemyParty[a], MON_DATA_SPECIES); + battlePokemon.item = GetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM); + for (size = 0; size < 4; size++) + { + battlePokemon.moves[size] = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + size); + battlePokemon.pp[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size); + } + battlePokemon.ppBonuses = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES); + battlePokemon.friendship = GetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP); + battlePokemon.experience = GetMonData(&gEnemyParty[a], MON_DATA_EXP); + battlePokemon.hpIV = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV); + battlePokemon.attackIV = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV); + battlePokemon.defenseIV = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV); + battlePokemon.speedIV = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV); + battlePokemon.spAttackIV = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV); + battlePokemon.spDefenseIV = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV); + battlePokemon.personality = GetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY); + battlePokemon.status1 = GetMonData(&gEnemyParty[a], MON_DATA_STATUS); + battlePokemon.level = GetMonData(&gEnemyParty[a], MON_DATA_LEVEL); + battlePokemon.hp = GetMonData(&gEnemyParty[a], MON_DATA_HP); + battlePokemon.maxHP = GetMonData(&gEnemyParty[a], MON_DATA_MAX_HP); + battlePokemon.attack = GetMonData(&gEnemyParty[a], MON_DATA_ATK); + battlePokemon.defense = GetMonData(&gEnemyParty[a], MON_DATA_DEF); + battlePokemon.speed = GetMonData(&gEnemyParty[a], MON_DATA_SPEED); + battlePokemon.spAttack = GetMonData(&gEnemyParty[a], MON_DATA_SPATK); + battlePokemon.spDefense = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF); + battlePokemon.isEgg = GetMonData(&gEnemyParty[a], MON_DATA_IS_EGG); + battlePokemon.altAbility = GetMonData(&gEnemyParty[a], MON_DATA_ALT_ABILITY); + battlePokemon.otId = GetMonData(&gEnemyParty[a], MON_DATA_OT_ID); + GetMonData(&gEnemyParty[a], MON_DATA_NICKNAME, nickname); + StringCopy10(battlePokemon.nickname, nickname); + GetMonData(&gEnemyParty[a], MON_DATA_OT_NAME, battlePokemon.otName); + + MEMCPY_ALT(&battlePokemon, buffer, sizeof(battlePokemon), size, src); + break; + case 1: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPECIES); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 2: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 3: + for (size = 0; size < 4; size++) + { + moveData.moves[size] = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + size); + moveData.pp[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size); + } + moveData.ppBonuses = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES); + MEMCPY_ALT(&moveData, buffer, sizeof(moveData), size, src); + break; + case 4: + case 5: + case 6: + case 7: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 8: + for (size = 0; size < 4; size++) + buffer[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size); + buffer[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES); + size++; + break; + case 9: + case 10: + case 11: + case 12: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9); + size = 1; + break; + case 17: + data32 = GetMonData(&gEnemyParty[a], MON_DATA_OT_ID); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + size = 3; + break; + case 18: + data32 = GetMonData(&gEnemyParty[a], MON_DATA_EXP); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + size = 3; + break; + case 19: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_EV); + size = 1; + break; + case 20: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_EV); + size = 1; + break; + case 21: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_EV); + size = 1; + break; + case 22: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_EV); + size = 1; + break; + case 23: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_EV); + size = 1; + break; + case 24: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_EV); + size = 1; + break; + case 25: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP); + size = 1; + break; + case 26: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_POKERUS); + size = 1; + break; + case 27: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_LOCATION); + size = 1; + break; + case 28: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_LEVEL); + size = 1; + break; + case 29: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_GAME); + size = 1; + break; + case 30: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_POKEBALL); + size = 1; + break; + case 31: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV); + buffer[1] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV); + buffer[2] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV); + buffer[3] = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV); + buffer[4] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV); + buffer[5] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV); + size = 6; + break; + case 32: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV); + size = 1; + break; + case 33: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV); + size = 1; + break; + case 34: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV); + size = 1; + break; + case 35: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV); + size = 1; + break; + case 36: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV); + size = 1; + break; + case 37: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV); + size = 1; + break; + case 38: + data32 = GetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + buffer[3] = (data32 & 0xFF000000) >> 24; + size = 4; + break; + case 39: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_CHECKSUM); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 40: + data32 = GetMonData(&gEnemyParty[a], MON_DATA_STATUS); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + buffer[3] = (data32 & 0xFF000000) >> 24; + size = 4; + break; + case 41: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_LEVEL); + size = 1; + break; + case 42: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_HP); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 43: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_MAX_HP); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 44: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_ATK); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 45: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_DEF); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 46: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPEED); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 47: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPATK); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 48: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 49: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_COOL); + size = 1; + break; + case 50: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_BEAUTY); + size = 1; + break; + case 51: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_CUTE); + size = 1; + break; + case 52: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SMART); + size = 1; + break; + case 53: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_TOUGH); + size = 1; + break; + case 54: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SHEEN); + size = 1; + break; + case 55: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_COOL_RIBBON); + size = 1; + break; + case 56: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_BEAUTY_RIBBON); + size = 1; + break; + case 57: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_CUTE_RIBBON); + size = 1; + break; + case 58: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SMART_RIBBON); + size = 1; + break; + case 59: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_TOUGH_RIBBON); + size = 1; + break; + } + return size; +} + +void LinkOpponentHandlecmd1(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleSetAttributes(void) +{ + u8 i; + u8 r4; + + if (gBattleBufferA[gActiveBattler][2] == 0) + { + sub_8038900(gBattlerPartyIndexes[gActiveBattler]); + } + else + { + r4 = gBattleBufferA[gActiveBattler][2]; + for (i = 0; i < 6; i++) + { + if (r4 & 1) + sub_8038900(i); + r4 >>= 1; + } + } + LinkOpponentBufferExecCompleted(); +} + +void sub_8038900(u8 a) +{ + struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBattler][3]; + struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBattler][3]; + s32 i; + + switch (gBattleBufferA[gActiveBattler][1]) + { + case 0: + { + u8 iv; + + SetMonData(&gEnemyParty[a], MON_DATA_SPECIES, &battlePokemon->species); + SetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM, &battlePokemon->item); + for (i = 0; i < 4; i++) + { + SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); + SetMonData(&gEnemyParty[a], MON_DATA_PP1 + i, &battlePokemon->pp[i]); + } + SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); + SetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); + SetMonData(&gEnemyParty[a], MON_DATA_EXP, &battlePokemon->experience); + iv = battlePokemon->hpIV; + SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &iv); + iv = battlePokemon->attackIV; + SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &iv); + iv = battlePokemon->defenseIV; + SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &iv); + iv = battlePokemon->speedIV; + SetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV, &iv); + iv = battlePokemon->spAttackIV; + SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &iv); + iv = battlePokemon->spDefenseIV; + SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &iv); + SetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY, &battlePokemon->personality); + SetMonData(&gEnemyParty[a], MON_DATA_STATUS, &battlePokemon->status1); + SetMonData(&gEnemyParty[a], MON_DATA_LEVEL, &battlePokemon->level); + SetMonData(&gEnemyParty[a], MON_DATA_HP, &battlePokemon->hp); + SetMonData(&gEnemyParty[a], MON_DATA_MAX_HP, &battlePokemon->maxHP); + SetMonData(&gEnemyParty[a], MON_DATA_ATK, &battlePokemon->attack); + SetMonData(&gEnemyParty[a], MON_DATA_DEF, &battlePokemon->defense); + SetMonData(&gEnemyParty[a], MON_DATA_SPEED, &battlePokemon->speed); + SetMonData(&gEnemyParty[a], MON_DATA_SPATK, &battlePokemon->spAttack); + SetMonData(&gEnemyParty[a], MON_DATA_SPDEF, &battlePokemon->spDefense); + } + break; + case 1: + SetMonData(&gEnemyParty[a], MON_DATA_SPECIES, &gBattleBufferA[gActiveBattler][3]); + break; + case 2: + SetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]); + break; + case 3: + for (i = 0; i < 4; i++) + { + SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + i, &moveData->moves[i]); + SetMonData(&gEnemyParty[a], MON_DATA_PP1 + i, &moveData->pp[i]); + } + SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &moveData->ppBonuses); + break; + case 4: + case 5: + case 6: + case 7: + SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4, &gBattleBufferA[gActiveBattler][3]); + break; + case 8: + SetMonData(&gEnemyParty[a], MON_DATA_PP1, &gBattleBufferA[gActiveBattler][3]); + SetMonData(&gEnemyParty[a], MON_DATA_PP2, &gBattleBufferA[gActiveBattler][4]); + SetMonData(&gEnemyParty[a], MON_DATA_PP3, &gBattleBufferA[gActiveBattler][5]); + SetMonData(&gEnemyParty[a], MON_DATA_PP4, &gBattleBufferA[gActiveBattler][6]); + SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBattler][7]); + break; + case 9: + case 10: + case 11: + case 12: + SetMonData(&gEnemyParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9, &gBattleBufferA[gActiveBattler][3]); + break; + case 17: + SetMonData(&gEnemyParty[a], MON_DATA_OT_ID, &gBattleBufferA[gActiveBattler][3]); + break; + case 18: + SetMonData(&gEnemyParty[a], MON_DATA_EXP, &gBattleBufferA[gActiveBattler][3]); + break; + case 19: + SetMonData(&gEnemyParty[a], MON_DATA_HP_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 20: + SetMonData(&gEnemyParty[a], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 21: + SetMonData(&gEnemyParty[a], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 22: + SetMonData(&gEnemyParty[a], MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 23: + SetMonData(&gEnemyParty[a], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 24: + SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 25: + SetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBattler][3]); + break; + case 26: + SetMonData(&gEnemyParty[a], MON_DATA_POKERUS, &gBattleBufferA[gActiveBattler][3]); + break; + case 27: + SetMonData(&gEnemyParty[a], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBattler][3]); + break; + case 28: + SetMonData(&gEnemyParty[a], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBattler][3]); + break; + case 29: + SetMonData(&gEnemyParty[a], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBattler][3]); + break; + case 30: + SetMonData(&gEnemyParty[a], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBattler][3]); + break; + case 31: + SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); + SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][4]); + SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][5]); + SetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][6]); + SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][7]); + SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][8]); + break; + case 32: + SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 33: + SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 34: + SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 35: + SetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 36: + SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 37: + SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 38: + SetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBattler][3]); + break; + case 39: + SetMonData(&gEnemyParty[a], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBattler][3]); + break; + case 40: + SetMonData(&gEnemyParty[a], MON_DATA_STATUS, &gBattleBufferA[gActiveBattler][3]); + break; + case 41: + SetMonData(&gEnemyParty[a], MON_DATA_LEVEL, &gBattleBufferA[gActiveBattler][3]); + break; + case 42: + SetMonData(&gEnemyParty[a], MON_DATA_HP, &gBattleBufferA[gActiveBattler][3]); + break; + case 43: + SetMonData(&gEnemyParty[a], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBattler][3]); + break; + case 44: + SetMonData(&gEnemyParty[a], MON_DATA_ATK, &gBattleBufferA[gActiveBattler][3]); + break; + case 45: + SetMonData(&gEnemyParty[a], MON_DATA_DEF, &gBattleBufferA[gActiveBattler][3]); + break; + case 46: + SetMonData(&gEnemyParty[a], MON_DATA_SPEED, &gBattleBufferA[gActiveBattler][3]); + break; + case 47: + SetMonData(&gEnemyParty[a], MON_DATA_SPATK, &gBattleBufferA[gActiveBattler][3]); + break; + case 48: + SetMonData(&gEnemyParty[a], MON_DATA_SPDEF, &gBattleBufferA[gActiveBattler][3]); + break; + case 49: + SetMonData(&gEnemyParty[a], MON_DATA_COOL, &gBattleBufferA[gActiveBattler][3]); + break; + case 50: + SetMonData(&gEnemyParty[a], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBattler][3]); + break; + case 51: + SetMonData(&gEnemyParty[a], MON_DATA_CUTE, &gBattleBufferA[gActiveBattler][3]); + break; + case 52: + SetMonData(&gEnemyParty[a], MON_DATA_SMART, &gBattleBufferA[gActiveBattler][3]); + break; + case 53: + SetMonData(&gEnemyParty[a], MON_DATA_TOUGH, &gBattleBufferA[gActiveBattler][3]); + break; + case 54: + SetMonData(&gEnemyParty[a], MON_DATA_SHEEN, &gBattleBufferA[gActiveBattler][3]); + break; + case 55: + SetMonData(&gEnemyParty[a], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 56: + SetMonData(&gEnemyParty[a], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 57: + SetMonData(&gEnemyParty[a], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 58: + SetMonData(&gEnemyParty[a], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 59: + SetMonData(&gEnemyParty[a], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + } +} + +void LinkOpponentHandlecmd3(void) +{ + u8 *dst; + u8 i; + + MEMSET_ALT(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1], + gBattleBufferA[gActiveBattler][3 + i], gBattleBufferA[gActiveBattler][2], i, dst); + + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleLoadPokeSprite(void) +{ + u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); + + BattleLoadOpponentMonSprite(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(gActiveBattler)); + gBankSpriteIds[gActiveBattler] = CreateSprite( + &gUnknown_02024E8C, + GetBattlerSpriteCoord(gActiveBattler, 2), + sub_8077F68(gActiveBattler), + GetBattlerSubpriority(gActiveBattler)); + gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -240; + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = gActiveBattler; + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; + StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], gBattleMonForms[gActiveBattler]); + sub_8032984(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + gBattleBankFunc[gActiveBattler] = sub_8037A74; +} + +void LinkOpponentHandleSendOutPoke(void) +{ + gBattlerPartyIndexes[gActiveBattler] = gBattleBufferA[gActiveBattler][1]; + sub_8039430(gActiveBattler, gBattleBufferA[gActiveBattler][2]); + gBattleBankFunc[gActiveBattler] = sub_8037E30; +} + +void sub_8039430(u8 a, u8 b) +{ + u16 species; + + sub_8032AA8(a, b); + gBattlerPartyIndexes[a] = gBattleBufferA[a][1]; + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[a]], MON_DATA_SPECIES); + gUnknown_0300434C[a] = CreateInvisibleSpriteWithCallback(sub_80312F0); + BattleLoadOpponentMonSprite(&gEnemyParty[gBattlerPartyIndexes[a]], a); + GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(a)); + gBankSpriteIds[a] = CreateSprite( + &gUnknown_02024E8C, + GetBattlerSpriteCoord(a, 2), + sub_8077F68(a), + GetBattlerSubpriority(a)); + gSprites[gUnknown_0300434C[a]].data[1] = gBankSpriteIds[a]; + gSprites[gBankSpriteIds[a]].data[0] = a; + gSprites[gBankSpriteIds[a]].data[2] = species; + gSprites[gBankSpriteIds[a]].oam.paletteNum = a; + StartSpriteAnim(&gSprites[gBankSpriteIds[a]], gBattleMonForms[a]); + gSprites[gBankSpriteIds[a]].invisible = TRUE; + gSprites[gBankSpriteIds[a]].callback = SpriteCallbackDummy; + gSprites[gUnknown_0300434C[a]].data[0] = StartSendOutMonAnimation(0, 0xFE); +} + +void LinkOpponentHandleReturnPokeToBall(void) +{ + if (gBattleBufferA[gActiveBattler][1] == 0) + { + ewram17810[gActiveBattler].unk4 = 0; + gBattleBankFunc[gActiveBattler] = sub_8039648; + } + else + { + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + sub_8032A08(gActiveBattler); + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + LinkOpponentBufferExecCompleted(); + } +} + +void sub_8039648(void) +{ + switch (ewram17810[gActiveBattler].unk4) + { + case 0: + if (ewram17800[gActiveBattler].substituteSprite) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + ewram17810[gActiveBattler].unk4 = 1; + break; + case 1: + if (!ewram17810[gActiveBattler].unk0_6) + { + ewram17810[gActiveBattler].unk4 = 0; + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 2); + gBattleBankFunc[gActiveBattler] = sub_8037BBC; + } + break; + } +} + +void LinkOpponentHandleTrainerThrow(void) +{ + s16 xOffset; + u32 gender; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (GetBattlerPosition(gActiveBattler) & 2) + xOffset = -16; + else + xOffset = 16; + gender = gLinkPlayers[sub_803FC34(gActiveBattler)].gender; + } + else + { + xOffset = 0; + gender = gLinkPlayers[GetMultiplayerId() ^ 1].gender; + } + sub_8031A6C(gender, gActiveBattler); + GetMonSpriteTemplate_803C5A0(gender, GetBattlerPosition(gActiveBattler)); + gBankSpriteIds[gActiveBattler] = CreateSprite( + &gUnknown_02024E8C, + 176 + xOffset, 40 + 4 * (8 - gTrainerFrontPicCoords[gender].coords), + GetBattlerSubpriority(gActiveBattler)); + gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -240; + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 2; + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[gender].tag); + gSprites[gBankSpriteIds[gActiveBattler]].data[5] = gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum; + gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum = GetSpriteTileStartByTag(gTrainerFrontPicTable[gender].tag); + gSprites[gBankSpriteIds[gActiveBattler]].oam.affineParam = gender; + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; + gBattleBankFunc[gActiveBattler] = sub_803757C; +} + +void LinkOpponentHandleTrainerSlide(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleTrainerSlideBack(void) +{ + oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 35; + gSprites[gBankSpriteIds[gActiveBattler]].data[2] = 280; + gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; + gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], SpriteCallbackDummy); + gBattleBankFunc[gActiveBattler] = sub_80375B4; +} + +void LinkOpponentHandlecmd10(void) +{ + if (ewram17810[gActiveBattler].unk4 == 0) + { + if (ewram17800[gActiveBattler].substituteSprite) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + ewram17810[gActiveBattler].unk4++; + } + else if (!ewram17810[gActiveBattler].unk0_6) + { + ewram17810[gActiveBattler].unk4 = 0; + PlaySE12WithPanning(SE_POKE_DEAD, 63); + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_8010384; + gBattleBankFunc[gActiveBattler] = sub_8037B78; + } +} + +void LinkOpponentHandlecmd11(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd12(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleBallThrow(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlePuase(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleMoveAnimation(void) +{ + if (!mplay_80342A4(gActiveBattler)) + { + u32 r0 = gBattleBufferA[gActiveBattler][1] + | (gBattleBufferA[gActiveBattler][2] << 8); + + gAnimMoveTurn = gBattleBufferA[gActiveBattler][3]; + gAnimMovePower = gBattleBufferA[gActiveBattler][4] + | (gBattleBufferA[gActiveBattler][5] << 8); + gAnimMoveDmg = gBattleBufferA[gActiveBattler][6] + | (gBattleBufferA[gActiveBattler][7] << 8) + | (gBattleBufferA[gActiveBattler][8] << 16) + | (gBattleBufferA[gActiveBattler][9] << 24); + gAnimFriendship = gBattleBufferA[gActiveBattler][10]; + gWeatherMoveAnim = gBattleBufferA[gActiveBattler][12] + | (gBattleBufferA[gActiveBattler][13] << 8); + gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBattler][16]; + gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; + + // Dead code. sub_8031720 always returns 0. + if (sub_8031720(r0, gAnimMoveTurn) != 0) + { + LinkOpponentBufferExecCompleted(); + } + else + { + ewram17810[gActiveBattler].unk4 = 0; + gBattleBankFunc[gActiveBattler] = sub_8039B64; + } + } +} + +void sub_8039B64(void) +{ + u16 r4 = gBattleBufferA[gActiveBattler][1] + | (gBattleBufferA[gActiveBattler][2] << 8); + u8 r7 = gBattleBufferA[gActiveBattler][11]; + + switch (ewram17810[gActiveBattler].unk4) + { + case 0: + if (ewram17800[gActiveBattler].substituteSprite && !ewram17800[gActiveBattler].unk0_3) + { + ewram17800[gActiveBattler].unk0_3 = 1; + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + } + ewram17810[gActiveBattler].unk4 = 1; + break; + case 1: + if (!ewram17810[gActiveBattler].unk0_6) + { + sub_80326EC(0); + DoMoveAnim(r4); + ewram17810[gActiveBattler].unk4 = 2; + } + break; + case 2: + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + sub_80326EC(1); + if ((ewram17800[gActiveBattler].substituteSprite) && r7 <= 1) + { + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); + ewram17800[gActiveBattler].unk0_3 = 0; + } + ewram17810[gActiveBattler].unk4 = 3; + } + break; + case 3: + if (!ewram17810[gActiveBattler].unk0_6) + { + sub_8031F24(); + sub_80324BC( + gActiveBattler, + gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + ewram17810[gActiveBattler].unk4 = 0; + LinkOpponentBufferExecCompleted(); + } + break; + } +} + +void LinkOpponentHandlePrintString(void) +{ + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + BufferStringBattle(*(u16 *)&gBattleBufferA[gActiveBattler][2]); + Text_InitWindow8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15); + gBattleBankFunc[gActiveBattler] = sub_8037C2C; +} + +void LinkOpponentHandlePrintStringPlayerOnly(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd18(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd19(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd20(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleOpenBag(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd22(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd23(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleHealthBarUpdate(void) +{ + s16 r7; + + load_gfxc_health_bar(0); + r7 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + if (r7 != 0x7FFF) + { + u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); + u32 hp = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); + + sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, hp, r7); + } + else + { + u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); + + sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, 0, r7); + } + gBattleBankFunc[gActiveBattler] = sub_8037B24; +} + +void LinkOpponentHandleExpBarUpdate(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleStatusIconUpdate(void) +{ + if (mplay_80342A4(gActiveBattler) == 0) + { + sub_8045A5C(gHealthboxIDs[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], 9); + ewram17810[gActiveBattler].unk0_4 = 0; + gBattleBankFunc[gActiveBattler] = sub_8037FAC; + } +} + +void LinkOpponentHandleStatusAnimation(void) +{ + if (mplay_80342A4(gActiveBattler) == 0) + { + move_anim_start_t2_for_situation( + gBattleBufferA[gActiveBattler][1], + gBattleBufferA[gActiveBattler][2] + | (gBattleBufferA[gActiveBattler][3] << 8) + | (gBattleBufferA[gActiveBattler][4] << 16) + | (gBattleBufferA[gActiveBattler][5] << 24)); + gBattleBankFunc[gActiveBattler] = sub_8037FAC; + } +} + +void LinkOpponentHandleStatusXor(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd29(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleDMATransfer(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd31(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd32(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd33(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd34(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd35(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd36(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd37(void) +{ + gUnknown_020238C8.unk0_0 = 0; + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd38(void) +{ + gUnknown_020238C8.unk0_0 = gBattleBufferA[gActiveBattler][1]; + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd39(void) +{ + gUnknown_020238C8.unk0_7 = 0; + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd40(void) +{ + gUnknown_020238C8.unk0_7 ^= 1; + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleHitAnimation(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].invisible == TRUE) + { + LinkOpponentBufferExecCompleted(); + } + else + { + gDoingBattleAnim = TRUE; + gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; + sub_8047858(gActiveBattler); + gBattleBankFunc[gActiveBattler] = dp01t_0F_4_move_anim; + } +} + +void LinkOpponentHandlecmd42(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleEffectivenessSound(void) +{ + s8 pan; + + if (GetBattlerSide(gActiveBattler) == 0) + pan = -64; + else + pan = 63; + PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan); + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd44(void) +{ + PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleFaintingCry(void) +{ + PlayCry3( + GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES), + 25, 5); + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleIntroSlide(void) +{ + StartBattleIntroAnim(gBattleBufferA[gActiveBattler][1]); + gUnknown_02024DE8 |= 1; + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleTrainerBallThrow(void) +{ + u8 taskId; + + oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 35; + gSprites[gBankSpriteIds[gActiveBattler]].data[2] = 280; + gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; + gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], sub_803A3A8); + taskId = CreateTask(sub_803A2C4, 5); + gTasks[taskId].data[0] = gActiveBattler; + if (ewram17810[gActiveBattler].unk0_0) + gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; + ewram17840.unk9_0 = 1; + gBattleBankFunc[gActiveBattler] = nullsub_47; +} + +void sub_803A2C4(u8 taskId) +{ + u8 r9; + + r9 = gActiveBattler; + gActiveBattler = gTasks[taskId].data[0]; + if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_8039430(gActiveBattler, 0); + } + else + { + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_8039430(gActiveBattler, 0); + gActiveBattler ^= 2; + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_8039430(gActiveBattler, 0); + gActiveBattler ^= 2; + } + gBattleBankFunc[gActiveBattler] = sub_8037840; + gActiveBattler = r9; + DestroyTask(taskId); +} + +void sub_803A3A8(struct Sprite *sprite) +{ + sub_8031B74(sprite->oam.affineParam); + sprite->oam.tileNum = sprite->data[5]; + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); +} + +void LinkOpponentHandlecmd48(void) +{ + if (gBattleBufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == 0) + { + LinkOpponentBufferExecCompleted(); + return; + } + + ewram17810[gActiveBattler].unk0_0 = 1; + if (gBattleBufferA[gActiveBattler][2] != 0) + { + if (ewram17810[gActiveBattler].unk1_1 < 2) + { + ewram17810[gActiveBattler].unk1_1++; + return; + } + else + { + ewram17810[gActiveBattler].unk1_1 = 0; + } + } + gUnknown_02024E68[gActiveBattler] = sub_8044804( + gActiveBattler, + (struct BattleInterfaceStruct2 *)&gBattleBufferA[gActiveBattler][4], + gBattleBufferA[gActiveBattler][1], + gBattleBufferA[gActiveBattler][2]); + ewram17810[gActiveBattler].unk5 = 0; + if (gBattleBufferA[gActiveBattler][2] != 0) + ewram17810[gActiveBattler].unk5 = 0x5D; + gBattleBankFunc[gActiveBattler] = sub_803A4E0; +} + +void sub_803A4E0(void) +{ + if (ewram17810[gActiveBattler].unk5++ >= 93) + { + ewram17810[gActiveBattler].unk5 = 0; + LinkOpponentBufferExecCompleted(); + } +} + +void LinkOpponentHandlecmd49(void) +{ + if (ewram17810[gActiveBattler].unk0_0) + gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd50(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleSpriteInvisibility(void) +{ + if (IsBankSpritePresent(gActiveBattler) != 0) + { + gSprites[gBankSpriteIds[gActiveBattler]].invisible = gBattleBufferA[gActiveBattler][1]; + sub_8031F88(gActiveBattler); + } + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleBattleAnimation(void) +{ + if (mplay_80342A4(gActiveBattler) == 0) + { + u8 r3 = gBattleBufferA[gActiveBattler][1]; + u16 r4 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + + if (move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, r3, r4) != 0) + LinkOpponentBufferExecCompleted(); + else + gBattleBankFunc[gActiveBattler] = sub_8037FD8; + } +} + +void LinkOpponentHandleLinkStandbyMsg(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandleResetActionMoveSelection(void) +{ + LinkOpponentBufferExecCompleted(); +} + +void LinkOpponentHandlecmd55(void) +{ + if (gBattleBufferA[gActiveBattler][1] == 3) + gBattleOutcome = gBattleBufferA[gActiveBattler][1]; + else + gBattleOutcome = gBattleBufferA[gActiveBattler][1] ^ 3; + FadeOutMapMusic(5); + BeginFastPaletteFade(3); + LinkOpponentBufferExecCompleted(); + gBattleBankFunc[gActiveBattler] = sub_8037F34; +} + +void LinkOpponentHandlecmd56(void) +{ +} diff --git a/src/battle_controller_link_partner.c b/src/battle_controller_link_partner.c new file mode 100644 index 000000000..5dbde3e83 --- /dev/null +++ b/src/battle_controller_link_partner.c @@ -0,0 +1,1714 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "battle_anim_special.h" +#include "battle_interface.h" +#include "data2.h" +#include "battle_811DA74.h" +#include "battle_anim_special.h" +#include "link.h" +#include "m4a.h" +#include "main.h" +#include "palette.h" +#include "pokeball.h" +#include "pokemon.h" +#include "rom3.h" +#include "rom_8077ABC.h" +#include "sound.h" +#include "constants/songs.h" +#include "sprite.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "util.h" +#include "ewram.h" + +struct MovePpInfo +{ + u16 moves[4]; + u8 pp[4]; + u8 ppBonuses; +}; + +extern u16 gBattleTypeFlags; +extern u8 gDisplayedStringBattle[]; +extern u8 gBattleBufferA[][0x200]; +extern u8 gActiveBattler; +extern u32 gBattleExecBuffer; +extern u16 gBattlerPartyIndexes[]; +extern u8 gBankSpriteIds[]; +extern u8 gBattleOutcome; +extern u16 gUnknown_02024DE8; +extern u8 gUnknown_02024E68[]; +extern u8 gDoingBattleAnim; +extern u32 gTransformedPersonalities[]; +extern struct SpriteTemplate gUnknown_02024E8C; +extern s32 gAnimMoveDmg; +extern u16 gAnimMovePower; +extern u8 gAnimFriendship; +extern u16 gWeatherMoveAnim; +extern u8 gAnimMoveTurn; +extern struct Window gUnknown_03004210; +extern MainCallback gPreBattleCallback1; +extern void (*gBattleBankFunc[])(void); +extern u8 gHealthboxIDs[]; +extern u8 gUnknown_0300434C[]; +extern u8 gBattleMonForms[]; +extern u8 gAnimScriptActive; +extern void (*gAnimScriptCallback)(void); + +extern u8 move_anim_start_t3(); +extern u8 IsBankSpritePresent(); +extern void sub_8044CA0(u8); +extern void sub_8030E38(struct Sprite *); +extern void StartBattleIntroAnim(); +extern void sub_8047858(); +extern void move_anim_start_t2_for_situation(); +extern void sub_8043D84(); +extern void BufferStringBattle(); +extern void sub_8031F24(void); +extern void sub_80326EC(); +extern void DoMoveAnim(); +extern void sub_80324BC(); +extern u8 sub_8031720(); +extern u8 mplay_80342A4(); +extern void oamt_add_pos2_onto_pos1(); +extern void StoreSpriteCallbackInData(); +extern void StartAnimLinearTranslation(struct Sprite *); +extern void sub_80105EC(struct Sprite *); +extern s32 sub_803FC34(u16); +extern void LoadPlayerTrainerBankSprite(); +extern void sub_80313A0(struct Sprite *); +extern u8 StartSendOutMonAnimation(); +extern void sub_80312F0(struct Sprite *); +extern u8 CreateInvisibleSpriteWithCallback(); +extern void BattleLoadPlayerMonSprite(); +extern u8 GetBattlerSpriteCoord(); +extern u8 sub_8077F68(); +extern u8 GetBattlerSubpriority(); +extern void nullsub_10(); +extern void sub_8045A5C(); +extern void sub_804777C(); +extern void sub_8043DFC(); +//extern s16 sub_8045C78(); +extern void sub_80440EC(); +extern void HandleLowHpMusicChange(); +extern void nullsub_9(u16); +extern void sub_8043DB0(); +extern void move_anim_start_t4(); +extern void c3_0802FDF4(u8); +extern void sub_8031F88(); +extern void c2_8011A1C(void); + +// this file's functions + +void LinkPartnerBufferRunCommand(void); +void sub_811E0A0(void); +void LinkPartnerBufferExecCompleted(void); +u32 dp01_getattr_by_ch1_for_player_pokemon(u8 a, u8 *b); +void sub_811EC68(u8); +void sub_811F864(u8, u8); +void sub_811FA5C(void); +void sub_811FF30(void); +void sub_812071C(u8); +void sub_81208E0(void); + +void LinkPartnerHandleGetAttributes(void); +void LinkPartnerHandlecmd1(void); +void LinkPartnerHandleSetAttributes(void); +void LinkPartnerHandlecmd3(void); +void LinkPartnerHandleLoadPokeSprite(void); +void LinkPartnerHandleSendOutPoke(void); +void LinkPartnerHandleReturnPokeToBall(void); +void LinkPartnerHandleTrainerThrow(void); +void LinkPartnerHandleTrainerSlide(void); +void LinkPartnerHandleTrainerSlideBack(void); +void LinkPartnerHandlecmd10(void); +void LinkPartnerHandlecmd11(void); +void LinkPartnerHandlecmd12(void); +void LinkPartnerHandleBallThrow(void); +void LinkPartnerHandlePuase(void); +void LinkPartnerHandleMoveAnimation(void); +void LinkPartnerHandlePrintString(void); +void LinkPartnerHandlePrintStringPlayerOnly(void); +void LinkPartnerHandlecmd18(void); +void LinkPartnerHandlecmd19(void); +void LinkPartnerHandlecmd20(void); +void LinkPartnerHandleOpenBag(void); +void LinkPartnerHandlecmd22(void); +void LinkPartnerHandlecmd23(void); +void LinkPartnerHandleHealthBarUpdate(void); +void LinkPartnerHandleExpBarUpdate(void); +void LinkPartnerHandleStatusIconUpdate(void); +void LinkPartnerHandleStatusAnimation(void); +void LinkPartnerHandleStatusXor(void); +void LinkPartnerHandlecmd29(void); +void LinkPartnerHandleDMATransfer(void); +void LinkPartnerHandlecmd31(void); +void LinkPartnerHandlecmd32(void); +void LinkPartnerHandlecmd33(void); +void LinkPartnerHandlecmd34(void); +void LinkPartnerHandlecmd35(void); +void LinkPartnerHandlecmd36(void); +void LinkPartnerHandlecmd37(void); +void LinkPartnerHandlecmd38(void); +void LinkPartnerHandlecmd39(void); +void LinkPartnerHandlecmd40(void); +void LinkPartnerHandleHitAnimation(void); +void LinkPartnerHandlecmd42(void); +void LinkPartnerHandleEffectivenessSound(void); +void LinkPartnerHandlecmd44(void); +void LinkPartnerHandleFaintingCry(void); +void LinkPartnerHandleIntroSlide(void); +void LinkPartnerHandleTrainerBallThrow(void); +void LinkPartnerHandlecmd48(void); +void LinkPartnerHandlecmd49(void); +void LinkPartnerHandlecmd50(void); +void LinkPartnerHandleSpriteInvisibility(void); +void LinkPartnerHandleBattleAnimation(void); +void LinkPartnerHandleLinkStandbyMsg(void); +void LinkPartnerHandleResetActionMoveSelection(void); +void LinkPartnerHandlecmd55(void); +void LinkPartnerHandlecmd56(void); + +// const data +typedef void (*BattleBufferCmd) (void); +static const BattleBufferCmd gLinkPartnerBufferCommands[] = +{ + LinkPartnerHandleGetAttributes, + LinkPartnerHandlecmd1, + LinkPartnerHandleSetAttributes, + LinkPartnerHandlecmd3, + LinkPartnerHandleLoadPokeSprite, + LinkPartnerHandleSendOutPoke, + LinkPartnerHandleReturnPokeToBall, + LinkPartnerHandleTrainerThrow, + LinkPartnerHandleTrainerSlide, + LinkPartnerHandleTrainerSlideBack, + LinkPartnerHandlecmd10, + LinkPartnerHandlecmd11, + LinkPartnerHandlecmd12, + LinkPartnerHandleBallThrow, + LinkPartnerHandlePuase, + LinkPartnerHandleMoveAnimation, + LinkPartnerHandlePrintString, + LinkPartnerHandlePrintStringPlayerOnly, + LinkPartnerHandlecmd18, + LinkPartnerHandlecmd19, + LinkPartnerHandlecmd20, + LinkPartnerHandleOpenBag, + LinkPartnerHandlecmd22, + LinkPartnerHandlecmd23, + LinkPartnerHandleHealthBarUpdate, + LinkPartnerHandleExpBarUpdate, + LinkPartnerHandleStatusIconUpdate, + LinkPartnerHandleStatusAnimation, + LinkPartnerHandleStatusXor, + LinkPartnerHandlecmd29, + LinkPartnerHandleDMATransfer, + LinkPartnerHandlecmd31, + LinkPartnerHandlecmd32, + LinkPartnerHandlecmd33, + LinkPartnerHandlecmd34, + LinkPartnerHandlecmd35, + LinkPartnerHandlecmd36, + LinkPartnerHandlecmd37, + LinkPartnerHandlecmd38, + LinkPartnerHandlecmd39, + LinkPartnerHandlecmd40, + LinkPartnerHandleHitAnimation, + LinkPartnerHandlecmd42, + LinkPartnerHandleEffectivenessSound, + LinkPartnerHandlecmd44, + LinkPartnerHandleFaintingCry, + LinkPartnerHandleIntroSlide, + LinkPartnerHandleTrainerBallThrow, + LinkPartnerHandlecmd48, + LinkPartnerHandlecmd49, + LinkPartnerHandlecmd50, + LinkPartnerHandleSpriteInvisibility, + LinkPartnerHandleBattleAnimation, + LinkPartnerHandleLinkStandbyMsg, + LinkPartnerHandleResetActionMoveSelection, + LinkPartnerHandlecmd55, + LinkPartnerHandlecmd56, +}; +// code starts here + +void nullsub_74(void) +{ +} + +void SetBankFuncToLinkPartnerBufferRunCommand(void) +{ + gBattleBankFunc[gActiveBattler] = LinkPartnerBufferRunCommand; +} + +void LinkPartnerBufferRunCommand(void) +{ + if (gBattleExecBuffer & gBitTable[gActiveBattler]) + { + if (gBattleBufferA[gActiveBattler][0] <= 0x38) + gLinkPartnerBufferCommands[gBattleBufferA[gActiveBattler][0]](); + else + LinkPartnerBufferExecCompleted(); + } +} + +void sub_811DAE4(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + LinkPartnerBufferExecCompleted(); +} + +void sub_811DB1C(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + { + nullsub_10(0); + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + LinkPartnerBufferExecCompleted(); + } +} + +void sub_811DB84(void) +{ + if ((--ewram17810[gActiveBattler].unk9) == 0xFF) + { + ewram17810[gActiveBattler].unk9 = 0; + LinkPartnerBufferExecCompleted(); + } +} + +void sub_811DBC0(void) +{ + bool8 r6 = FALSE; + + if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & 0x40))) + { + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) + r6 = TRUE; + } + else + { + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxIDs[gActiveBattler ^ 2]].callback == SpriteCallbackDummy) + r6 = TRUE; + } + if (IsCryPlayingOrClearCrySongs()) + r6 = FALSE; + if (r6) + { + ewram17810[gActiveBattler].unk9 = 3; + gBattleBankFunc[gActiveBattler] = sub_811DB84; + } +} + +void sub_811DCA0(void) +{ + u8 r2; + + if (!ewram17810[gActiveBattler].unk0_3) + { + // I couldn't get it to work as a bitfield here + r2 = *((u8 *)&ewram17810[gActiveBattler ^ 2]) & 8; + if (!r2 && (++ewram17810[gActiveBattler].unk9) != 1) + { + ewram17810[gActiveBattler].unk9 = r2; + if (IsDoubleBattle() && !(gBattleTypeFlags & 0x40)) + { + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler ^ 2]]); + sub_8045A5C(gHealthboxIDs[gActiveBattler ^ 2], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], 0); + sub_804777C(gActiveBattler ^ 2); + sub_8043DFC(gHealthboxIDs[gActiveBattler ^ 2]); + } + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); + sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 0); + sub_804777C(gActiveBattler); + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + (s8)ewram17810[4].unk9 &= ~1; + gBattleBankFunc[gActiveBattler] = sub_811DBC0; + } + } +} + +void sub_811DDE8(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].animEnded + && gSprites[gBankSpriteIds[gActiveBattler]].pos2.x == 0) + LinkPartnerBufferExecCompleted(); +} + +void bx_t3_healthbar_update(void) +{ + s16 r4; + + r4 = sub_8045C78(gActiveBattler, gHealthboxIDs[gActiveBattler], 0, 0); + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + if (r4 != -1) + { + sub_80440EC(gHealthboxIDs[gActiveBattler], r4, 0); + } + else + { + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + LinkPartnerBufferExecCompleted(); + } +} + +void sub_811DE98(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].pos1.y + gSprites[gBankSpriteIds[gActiveBattler]].pos2.y > 160) + { + nullsub_9(GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + FreeOamMatrix(gSprites[gBankSpriteIds[gActiveBattler]].oam.matrixNum); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + LinkPartnerBufferExecCompleted(); + } +} + +void sub_811DF34(void) +{ + if (!ewram17810[gActiveBattler].unk0_6) + { + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + LinkPartnerBufferExecCompleted(); + } +} + +void sub_811DFA0(void) +{ + if (gUnknown_03004210.state == 0) + LinkPartnerBufferExecCompleted(); +} + +void bx_blink_t3(void) +{ + u8 spriteId = gBankSpriteIds[gActiveBattler]; + if (gSprites[spriteId].data[1] == 32) + { + gSprites[spriteId].data[1] = 0; + gSprites[spriteId].invisible = FALSE; + gDoingBattleAnim = 0; + LinkPartnerBufferExecCompleted(); + } + else + { + if ((gSprites[spriteId].data[1] % 4) == 0) + { + gSprites[spriteId].invisible ^= 1; + } + gSprites[spriteId].data[1]++; + } +} + +void sub_811E034(void) +{ + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) + { + if (ewram17800[gActiveBattler].substituteSprite) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); + gBattleBankFunc[gActiveBattler] = sub_811E0A0; + } +} + +void sub_811E0A0(void) +{ + if (!ewram17810[gActiveBattler].unk0_6) + LinkPartnerBufferExecCompleted(); +} + +void sub_811E0CC(void) +{ + if (ewram17810[gActiveBattler].unk1_0) + { + ewram17810[gActiveBattler].unk0_7 = 0; + ewram17810[gActiveBattler].unk1_0 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + CreateTask(c3_0802FDF4, 10); + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 0); + sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 0); + sub_804777C(gActiveBattler); + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + sub_8031F88(gActiveBattler); + gBattleBankFunc[gActiveBattler] = sub_811E034; + } +} + +void sub_811E1BC(void) +{ + if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) + sub_8141828(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + if (gSprites[gUnknown_0300434C[gActiveBattler]].callback == SpriteCallbackDummy + && !ewram17810[gActiveBattler].unk0_3) + { + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); + gBattleBankFunc[gActiveBattler] = sub_811E0CC; + } +} + +void sub_811E258(void) +{ + if (gReceivedRemoteLinkPlayers == 0) + { + m4aSongNumStop(0x5A); + gMain.inBattle = FALSE; + gMain.callback1 = gPreBattleCallback1; + SetMainCallback2(c2_8011A1C); + } +} + +void sub_811E29C(void) +{ + if (!gPaletteFade.active) + { + if (gBattleTypeFlags & 2) + { + sub_800832C(); + gBattleBankFunc[gActiveBattler] = sub_811E258; + } + else + { + m4aSongNumStop(0x5A); + gMain.inBattle = FALSE; + gMain.callback1 = gPreBattleCallback1; + SetMainCallback2(gMain.savedCallback); + } + } +} + +void LinkPartnerBufferExecCompleted(void) +{ + u8 multiplayerId; + + gBattleBankFunc[gActiveBattler] = LinkPartnerBufferRunCommand; + if (gBattleTypeFlags & 2) + { + multiplayerId = GetMultiplayerId(); + PrepareBufferDataTransferLink(2, 4, &multiplayerId); + gBattleBufferA[gActiveBattler][0] = 0x38; + } + else + { + gBattleExecBuffer &= ~gBitTable[gActiveBattler]; + } +} + +void sub_811E38C(void) +{ + if (!ewram17810[gActiveBattler].unk0_4) + LinkPartnerBufferExecCompleted(); +} + +void sub_811E3B8(void) +{ + if (!ewram17810[gActiveBattler].unk0_5) + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleGetAttributes(void) +{ + u8 unk[256]; + int r6 = 0; + s32 i; + + if (gBattleBufferA[gActiveBattler][2] == 0) + { + r6 = dp01_getattr_by_ch1_for_player_pokemon(gBattlerPartyIndexes[gActiveBattler], unk); + } + else + { + u8 r4 = gBattleBufferA[gActiveBattler][2]; + + for (i = 0; i < 6; i++) + { + if (r4 & 1) + r6 += dp01_getattr_by_ch1_for_player_pokemon(i, unk + r6); + r4 >>= 1; + } + } + Emitcmd29(1, r6, unk); + LinkPartnerBufferExecCompleted(); +} + +// Duplicate of dp01_getattr_by_ch1_for_player_pokemon_ +u32 dp01_getattr_by_ch1_for_player_pokemon(u8 a, u8 *buffer) +{ + struct BattlePokemon battlePokemon; + struct MovePpInfo moveData; + u8 nickname[20]; + u8 *src; + s16 data16; + u32 data32; + s32 size = 0; + + switch (gBattleBufferA[gActiveBattler][1]) + { + case 0: + battlePokemon.species = GetMonData(&gPlayerParty[a], MON_DATA_SPECIES); + battlePokemon.item = GetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM); + for (size = 0; size < 4; size++) + { + battlePokemon.moves[size] = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + size); + battlePokemon.pp[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); + } + battlePokemon.ppBonuses = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); + battlePokemon.friendship = GetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP); + battlePokemon.experience = GetMonData(&gPlayerParty[a], MON_DATA_EXP); + battlePokemon.hpIV = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); + battlePokemon.attackIV = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); + battlePokemon.defenseIV = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); + battlePokemon.speedIV = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); + battlePokemon.spAttackIV = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); + battlePokemon.spDefenseIV = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); + battlePokemon.personality = GetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY); + battlePokemon.status1 = GetMonData(&gPlayerParty[a], MON_DATA_STATUS); + battlePokemon.level = GetMonData(&gPlayerParty[a], MON_DATA_LEVEL); + battlePokemon.hp = GetMonData(&gPlayerParty[a], MON_DATA_HP); + battlePokemon.maxHP = GetMonData(&gPlayerParty[a], MON_DATA_MAX_HP); + battlePokemon.attack = GetMonData(&gPlayerParty[a], MON_DATA_ATK); + battlePokemon.defense = GetMonData(&gPlayerParty[a], MON_DATA_DEF); + battlePokemon.speed = GetMonData(&gPlayerParty[a], MON_DATA_SPEED); + battlePokemon.spAttack = GetMonData(&gPlayerParty[a], MON_DATA_SPATK); + battlePokemon.spDefense = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF); + battlePokemon.isEgg = GetMonData(&gPlayerParty[a], MON_DATA_IS_EGG); + battlePokemon.altAbility = GetMonData(&gPlayerParty[a], MON_DATA_ALT_ABILITY); + battlePokemon.otId = GetMonData(&gPlayerParty[a], MON_DATA_OT_ID); + GetMonData(&gPlayerParty[a], MON_DATA_NICKNAME, nickname); + StringCopy10(battlePokemon.nickname, nickname); + GetMonData(&gPlayerParty[a], MON_DATA_OT_NAME, battlePokemon.otName); + MEMCPY_ALT(&battlePokemon, buffer, sizeof(battlePokemon), size, src); + break; + case 1: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPECIES); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 2: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 3: + for (size = 0; size < 4; size++) + { + moveData.moves[size] = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + size); + moveData.pp[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); + } + moveData.ppBonuses = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); + MEMCPY_ALT(&moveData, buffer, sizeof(moveData), size, src); + break; + case 4: + case 5: + case 6: + case 7: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 8: + for (size = 0; size < 4; size++) + buffer[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); + buffer[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); + size++; + break; + case 9: + case 10: + case 11: + case 12: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9); + size = 1; + break; + case 17: + data32 = GetMonData(&gPlayerParty[a], MON_DATA_OT_ID); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + size = 3; + break; + case 18: + data32 = GetMonData(&gPlayerParty[a], MON_DATA_EXP); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + size = 3; + break; + case 19: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_EV); + size = 1; + break; + case 20: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_EV); + size = 1; + break; + case 21: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_EV); + size = 1; + break; + case 22: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_EV); + size = 1; + break; + case 23: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_EV); + size = 1; + break; + case 24: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_EV); + size = 1; + break; + case 25: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP); + size = 1; + break; + case 26: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_POKERUS); + size = 1; + break; + case 27: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_LOCATION); + size = 1; + break; + case 28: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_LEVEL); + size = 1; + break; + case 29: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_GAME); + size = 1; + break; + case 30: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_POKEBALL); + size = 1; + break; + case 31: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); + buffer[1] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); + buffer[2] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); + buffer[3] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); + buffer[4] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); + buffer[5] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); + size = 6; + break; + case 32: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); + size = 1; + break; + case 33: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); + size = 1; + break; + case 34: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); + size = 1; + break; + case 35: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); + size = 1; + break; + case 36: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); + size = 1; + break; + case 37: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); + size = 1; + break; + case 38: + data32 = GetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + buffer[3] = (data32 & 0xFF000000) >> 24; + size = 4; + break; + case 39: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_CHECKSUM); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 40: + data32 = GetMonData(&gPlayerParty[a], MON_DATA_STATUS); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + buffer[3] = (data32 & 0xFF000000) >> 24; + size = 4; + break; + case 41: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_LEVEL); + size = 1; + break; + case 42: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_HP); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 43: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_MAX_HP); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 44: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_ATK); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 45: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_DEF); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 46: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPEED); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 47: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPATK); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 48: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 49: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_COOL); + size = 1; + break; + case 50: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_BEAUTY); + size = 1; + break; + case 51: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_CUTE); + size = 1; + break; + case 52: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SMART); + size = 1; + break; + case 53: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_TOUGH); + size = 1; + break; + case 54: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SHEEN); + size = 1; + break; + case 55: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_COOL_RIBBON); + size = 1; + break; + case 56: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_BEAUTY_RIBBON); + size = 1; + break; + case 57: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_CUTE_RIBBON); + size = 1; + break; + case 58: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SMART_RIBBON); + size = 1; + break; + case 59: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_TOUGH_RIBBON); + size = 1; + break; + } + return size; +} + +void LinkPartnerHandlecmd1(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleSetAttributes(void) +{ + u8 i; + u8 r4; + + if (gBattleBufferA[gActiveBattler][2] == 0) + { + sub_811EC68(gBattlerPartyIndexes[gActiveBattler]); + } + else + { + r4 = gBattleBufferA[gActiveBattler][2]; + for (i = 0; i < 6; i++) + { + if (r4 & 1) + sub_811EC68(i); + r4 >>= 1; + } + } + LinkPartnerBufferExecCompleted(); +} + +// Duplicate of dp01_setattr_by_ch1_for_player_pokemon +void sub_811EC68(u8 a) +{ + struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBattler][3]; + struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBattler][3]; + s32 i; + + switch (gBattleBufferA[gActiveBattler][1]) + { + case 0: + { + u8 iv; + + SetMonData(&gPlayerParty[a], MON_DATA_SPECIES, &battlePokemon->species); + SetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM, &battlePokemon->item); + for (i = 0; i < 4; i++) + { + SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); + SetMonData(&gPlayerParty[a], MON_DATA_PP1 + i, &battlePokemon->pp[i]); + } + SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); + SetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); + SetMonData(&gPlayerParty[a], MON_DATA_EXP, &battlePokemon->experience); + iv = battlePokemon->hpIV; + SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &iv); + iv = battlePokemon->attackIV; + SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &iv); + iv = battlePokemon->defenseIV; + SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &iv); + iv = battlePokemon->speedIV; + SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &iv); + iv = battlePokemon->spAttackIV; + SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &iv); + iv = battlePokemon->spDefenseIV; + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &iv); + SetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY, &battlePokemon->personality); + SetMonData(&gPlayerParty[a], MON_DATA_STATUS, &battlePokemon->status1); + SetMonData(&gPlayerParty[a], MON_DATA_LEVEL, &battlePokemon->level); + SetMonData(&gPlayerParty[a], MON_DATA_HP, &battlePokemon->hp); + SetMonData(&gPlayerParty[a], MON_DATA_MAX_HP, &battlePokemon->maxHP); + SetMonData(&gPlayerParty[a], MON_DATA_ATK, &battlePokemon->attack); + SetMonData(&gPlayerParty[a], MON_DATA_DEF, &battlePokemon->defense); + SetMonData(&gPlayerParty[a], MON_DATA_SPEED, &battlePokemon->speed); + SetMonData(&gPlayerParty[a], MON_DATA_SPATK, &battlePokemon->spAttack); + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF, &battlePokemon->spDefense); + } + break; + case 1: + SetMonData(&gPlayerParty[a], MON_DATA_SPECIES, &gBattleBufferA[gActiveBattler][3]); + break; + case 2: + SetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]); + break; + case 3: + for (i = 0; i < 4; i++) + { + SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + i, &moveData->moves[i]); + SetMonData(&gPlayerParty[a], MON_DATA_PP1 + i, &moveData->pp[i]); + } + SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &moveData->ppBonuses); + break; + case 4: + case 5: + case 6: + case 7: + SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4, &gBattleBufferA[gActiveBattler][3]); + break; + case 8: + SetMonData(&gPlayerParty[a], MON_DATA_PP1, &gBattleBufferA[gActiveBattler][3]); + SetMonData(&gPlayerParty[a], MON_DATA_PP2, &gBattleBufferA[gActiveBattler][4]); + SetMonData(&gPlayerParty[a], MON_DATA_PP3, &gBattleBufferA[gActiveBattler][5]); + SetMonData(&gPlayerParty[a], MON_DATA_PP4, &gBattleBufferA[gActiveBattler][6]); + SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBattler][7]); + break; + case 9: + case 10: + case 11: + case 12: + SetMonData(&gPlayerParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9, &gBattleBufferA[gActiveBattler][3]); + break; + case 17: + SetMonData(&gPlayerParty[a], MON_DATA_OT_ID, &gBattleBufferA[gActiveBattler][3]); + break; + case 18: + SetMonData(&gPlayerParty[a], MON_DATA_EXP, &gBattleBufferA[gActiveBattler][3]); + break; + case 19: + SetMonData(&gPlayerParty[a], MON_DATA_HP_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 20: + SetMonData(&gPlayerParty[a], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 21: + SetMonData(&gPlayerParty[a], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 22: + SetMonData(&gPlayerParty[a], MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 23: + SetMonData(&gPlayerParty[a], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 24: + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 25: + SetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBattler][3]); + break; + case 26: + SetMonData(&gPlayerParty[a], MON_DATA_POKERUS, &gBattleBufferA[gActiveBattler][3]); + break; + case 27: + SetMonData(&gPlayerParty[a], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBattler][3]); + break; + case 28: + SetMonData(&gPlayerParty[a], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBattler][3]); + break; + case 29: + SetMonData(&gPlayerParty[a], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBattler][3]); + break; + case 30: + SetMonData(&gPlayerParty[a], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBattler][3]); + break; + case 31: + SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); + SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][4]); + SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][5]); + SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][6]); + SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][7]); + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][8]); + break; + case 32: + SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 33: + SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 34: + SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 35: + SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 36: + SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 37: + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 38: + SetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBattler][3]); + break; + case 39: + SetMonData(&gPlayerParty[a], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBattler][3]); + break; + case 40: + SetMonData(&gPlayerParty[a], MON_DATA_STATUS, &gBattleBufferA[gActiveBattler][3]); + break; + case 41: + SetMonData(&gPlayerParty[a], MON_DATA_LEVEL, &gBattleBufferA[gActiveBattler][3]); + break; + case 42: + SetMonData(&gPlayerParty[a], MON_DATA_HP, &gBattleBufferA[gActiveBattler][3]); + break; + case 43: + SetMonData(&gPlayerParty[a], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBattler][3]); + break; + case 44: + SetMonData(&gPlayerParty[a], MON_DATA_ATK, &gBattleBufferA[gActiveBattler][3]); + break; + case 45: + SetMonData(&gPlayerParty[a], MON_DATA_DEF, &gBattleBufferA[gActiveBattler][3]); + break; + case 46: + SetMonData(&gPlayerParty[a], MON_DATA_SPEED, &gBattleBufferA[gActiveBattler][3]); + break; + case 47: + SetMonData(&gPlayerParty[a], MON_DATA_SPATK, &gBattleBufferA[gActiveBattler][3]); + break; + case 48: + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF, &gBattleBufferA[gActiveBattler][3]); + break; + case 49: + SetMonData(&gPlayerParty[a], MON_DATA_COOL, &gBattleBufferA[gActiveBattler][3]); + break; + case 50: + SetMonData(&gPlayerParty[a], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBattler][3]); + break; + case 51: + SetMonData(&gPlayerParty[a], MON_DATA_CUTE, &gBattleBufferA[gActiveBattler][3]); + break; + case 52: + SetMonData(&gPlayerParty[a], MON_DATA_SMART, &gBattleBufferA[gActiveBattler][3]); + break; + case 53: + SetMonData(&gPlayerParty[a], MON_DATA_TOUGH, &gBattleBufferA[gActiveBattler][3]); + break; + case 54: + SetMonData(&gPlayerParty[a], MON_DATA_SHEEN, &gBattleBufferA[gActiveBattler][3]); + break; + case 55: + SetMonData(&gPlayerParty[a], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 56: + SetMonData(&gPlayerParty[a], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 57: + SetMonData(&gPlayerParty[a], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 58: + SetMonData(&gPlayerParty[a], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 59: + SetMonData(&gPlayerParty[a], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + } + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); +} + +void LinkPartnerHandlecmd3(void) +{ + u8 *dst; + u8 i; + + MEMSET_ALT(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1], + gBattleBufferA[gActiveBattler][3 + i], gBattleBufferA[gActiveBattler][2], i, dst); + + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleLoadPokeSprite(void) +{ + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + GetMonSpriteTemplate_803C56C( + GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES), + GetBattlerPosition(gActiveBattler)); + gBankSpriteIds[gActiveBattler] = CreateSprite( + &gUnknown_02024E8C, + GetBattlerSpriteCoord(gActiveBattler, 2), + sub_8077F68(gActiveBattler), + GetBattlerSubpriority(gActiveBattler)); + gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -240; + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = gActiveBattler; + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; + StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], gBattleMonForms[gActiveBattler]); + gBattleBankFunc[gActiveBattler] = sub_811DDE8; +} + +void LinkPartnerHandleSendOutPoke(void) +{ + sub_8032AA8(gActiveBattler, gBattleBufferA[gActiveBattler][2]); + gBattlerPartyIndexes[gActiveBattler] = gBattleBufferA[gActiveBattler][1]; + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + sub_811F864(gActiveBattler, gBattleBufferA[gActiveBattler][2]); + gBattleBankFunc[gActiveBattler] = sub_811E1BC; +} + +void sub_811F864(u8 a, u8 b) +{ + u16 species; + + sub_8032AA8(a, b); + gBattlerPartyIndexes[a] = gBattleBufferA[a][1]; + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[a]], MON_DATA_SPECIES); + gUnknown_0300434C[a] = CreateInvisibleSpriteWithCallback(sub_80312F0); + GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(a)); + gBankSpriteIds[a] = CreateSprite( + &gUnknown_02024E8C, + GetBattlerSpriteCoord(a, 2), + sub_8077F68(a), + GetBattlerSubpriority(a)); + gSprites[gUnknown_0300434C[a]].data[1] = gBankSpriteIds[a]; + gSprites[gBankSpriteIds[a]].data[0] = a; + gSprites[gBankSpriteIds[a]].data[2] = species; + gSprites[gBankSpriteIds[a]].oam.paletteNum = a; + StartSpriteAnim(&gSprites[gBankSpriteIds[a]], gBattleMonForms[a]); + gSprites[gBankSpriteIds[a]].invisible = TRUE; + gSprites[gBankSpriteIds[a]].callback = SpriteCallbackDummy; + gSprites[gUnknown_0300434C[a]].data[0] = StartSendOutMonAnimation(0, 0xFF); +} + +void LinkPartnerHandleReturnPokeToBall(void) +{ + if (gBattleBufferA[gActiveBattler][1] == 0) + { + ewram17810[gActiveBattler].unk4 = 0; + gBattleBankFunc[gActiveBattler] = sub_811FA5C; + } + else + { + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + LinkPartnerBufferExecCompleted(); + } +} + +void sub_811FA5C(void) +{ + switch (ewram17810[gActiveBattler].unk4) + { + case 0: + if (ewram17800[gActiveBattler].substituteSprite) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + ewram17810[gActiveBattler].unk4 = 1; + break; + case 1: + if (!ewram17810[gActiveBattler].unk0_6) + { + ewram17810[gActiveBattler].unk4 = 0; + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 1); + gBattleBankFunc[gActiveBattler] = sub_811DF34; + } + break; + } +} + +void LinkPartnerHandleTrainerThrow(void) +{ + s16 xOffset; + u32 gender; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (GetBattlerPosition(gActiveBattler) & 2) + xOffset = 16; + else + xOffset = -16; + gender = gLinkPlayers[sub_803FC34(gActiveBattler)].gender; + } + else + { + xOffset = 0; + gender = gLinkPlayers[GetMultiplayerId() ^ 1].gender; + } + LoadPlayerTrainerBankSprite(gender, gActiveBattler); + GetMonSpriteTemplate_803C5A0(gender, GetBattlerPosition(gActiveBattler)); + gBankSpriteIds[gActiveBattler] = CreateSprite( + &gUnknown_02024E8C, + 80 + xOffset, 80 + 4 * (8 - gTrainerBackPicCoords[gender].coords), + GetBattlerSubpriority(gActiveBattler)); + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; + gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = 240; + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = -2; + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; + gBattleBankFunc[gActiveBattler] = sub_811DAE4; +} + +void LinkPartnerHandleTrainerSlide(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleTrainerSlideBack(void) +{ + oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 35; + gSprites[gBankSpriteIds[gActiveBattler]].data[2] = -40; + gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; + gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], SpriteCallbackDummy); + gBattleBankFunc[gActiveBattler] = sub_811DB1C; +} + +void LinkPartnerHandlecmd10(void) +{ + if (ewram17810[gActiveBattler].unk4 == 0) + { + if (ewram17800[gActiveBattler].substituteSprite) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + ewram17810[gActiveBattler].unk4++; + } + else if (!ewram17810[gActiveBattler].unk0_6) + { + ewram17810[gActiveBattler].unk4 = 0; + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + PlaySE12WithPanning(SE_POKE_DEAD, -64); + gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; + gSprites[gBankSpriteIds[gActiveBattler]].data[2] = 5; + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80105EC; + gBattleBankFunc[gActiveBattler] = sub_811DE98; + } +} + +void LinkPartnerHandlecmd11(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd12(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleBallThrow(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlePuase(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleMoveAnimation(void) +{ + if (!mplay_80342A4(gActiveBattler)) + { + u32 r0 = gBattleBufferA[gActiveBattler][1] + | (gBattleBufferA[gActiveBattler][2] << 8); + + gAnimMoveTurn = gBattleBufferA[gActiveBattler][3]; + gAnimMovePower = gBattleBufferA[gActiveBattler][4] + | (gBattleBufferA[gActiveBattler][5] << 8); + gAnimMoveDmg = gBattleBufferA[gActiveBattler][6] + | (gBattleBufferA[gActiveBattler][7] << 8) + | (gBattleBufferA[gActiveBattler][8] << 16) + | (gBattleBufferA[gActiveBattler][9] << 24); + gAnimFriendship = gBattleBufferA[gActiveBattler][10]; + gWeatherMoveAnim = gBattleBufferA[gActiveBattler][12] + | (gBattleBufferA[gActiveBattler][13] << 8); + gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBattler][16]; + gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; + + if (sub_8031720(r0, gAnimMoveTurn) != 0) + LinkPartnerBufferExecCompleted(); + else + { + ewram17810[gActiveBattler].unk4 = 0; + gBattleBankFunc[gActiveBattler] = sub_811FF30; + } + } +} + +void sub_811FF30(void) +{ + u16 r4 = gBattleBufferA[gActiveBattler][1] + | (gBattleBufferA[gActiveBattler][2] << 8); + u8 r7 = gBattleBufferA[gActiveBattler][11]; + + switch (ewram17810[gActiveBattler].unk4) + { + case 0: + if (ewram17800[gActiveBattler].substituteSprite && !ewram17800[gActiveBattler].unk0_3) + { + ewram17800[gActiveBattler].unk0_3 = 1; + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + } + ewram17810[gActiveBattler].unk4 = 1; + break; + case 1: + if (!ewram17810[gActiveBattler].unk0_6) + { + sub_80326EC(0); + DoMoveAnim(r4); + ewram17810[gActiveBattler].unk4 = 2; + } + break; + case 2: + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + sub_80326EC(1); + if ((ewram17800[gActiveBattler].substituteSprite) && r7 <= 1) + { + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); + ewram17800[gActiveBattler].unk0_3 = 0; + } + ewram17810[gActiveBattler].unk4 = 3; + } + break; + case 3: + if (!ewram17810[gActiveBattler].unk0_6) + { + sub_8031F24(); + sub_80324BC( + gActiveBattler, + gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + ewram17810[gActiveBattler].unk4 = 0; + LinkPartnerBufferExecCompleted(); + } + break; + } +} + +void LinkPartnerHandlePrintString(void) +{ + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + BufferStringBattle(*(u16 *)&gBattleBufferA[gActiveBattler][2]); + Text_InitWindow8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15); + gBattleBankFunc[gActiveBattler] = sub_811DFA0; +} + +void LinkPartnerHandlePrintStringPlayerOnly(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd18(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd19(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd20(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleOpenBag(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd22(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd23(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleHealthBarUpdate(void) +{ + s16 r7; + + load_gfxc_health_bar(0); + r7 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + if (r7 != 0x7FFF) + { + u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); + u32 hp = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); + + sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, hp, r7); + } + else + { + u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); + + sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, 0, r7); + } + gBattleBankFunc[gActiveBattler] = bx_t3_healthbar_update; +} + +void LinkPartnerHandleExpBarUpdate(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleStatusIconUpdate(void) +{ + if (mplay_80342A4(gActiveBattler) == 0) + { + sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 9); + ewram17810[gActiveBattler].unk0_4 = 0; + gBattleBankFunc[gActiveBattler] = sub_811E38C; + } +} + +void LinkPartnerHandleStatusAnimation(void) +{ + if (mplay_80342A4(gActiveBattler) == 0) + { + move_anim_start_t2_for_situation( + gBattleBufferA[gActiveBattler][1], + gBattleBufferA[gActiveBattler][2] + | (gBattleBufferA[gActiveBattler][3] << 8) + | (gBattleBufferA[gActiveBattler][4] << 16) + | (gBattleBufferA[gActiveBattler][5] << 24)); + gBattleBankFunc[gActiveBattler] = sub_811E38C; + } +} + +void LinkPartnerHandleStatusXor(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd29(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleDMATransfer(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd31(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd32(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd33(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd34(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd35(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd36(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd37(void) +{ + gUnknown_020238C8.unk0_0 = 0; + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd38(void) +{ + gUnknown_020238C8.unk0_0 = gBattleBufferA[gActiveBattler][1]; + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd39(void) +{ + gUnknown_020238C8.unk0_7 = 0; + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd40(void) +{ + gUnknown_020238C8.unk0_7 ^= 1; + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleHitAnimation(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].invisible == TRUE) + { + LinkPartnerBufferExecCompleted(); + } + else + { + gDoingBattleAnim = TRUE; + gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; + sub_8047858(gActiveBattler); + gBattleBankFunc[gActiveBattler] = bx_blink_t3; + } +} + +void LinkPartnerHandlecmd42(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleEffectivenessSound(void) +{ + s8 pan; + + if (GetBattlerSide(gActiveBattler) == 0) + pan = -64; + else + pan = 63; + PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan); + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd44(void) +{ + PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleFaintingCry(void) +{ + PlayCry3( + GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES), + -25, 5); + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleIntroSlide(void) +{ + StartBattleIntroAnim(gBattleBufferA[gActiveBattler][1]); + gUnknown_02024DE8 |= 1; + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleTrainerBallThrow(void) +{ + u8 r4; + u8 taskId; + + oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 50; + gSprites[gBankSpriteIds[gActiveBattler]].data[2] = -40; + gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; + gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; + gSprites[gBankSpriteIds[gActiveBattler]].data[5] = gActiveBattler; + StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], sub_8030E38); + StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 1); + r4 = AllocSpritePalette(0xD6F9); + LoadCompressedPalette( + gTrainerBackPicPaletteTable[gLinkPlayers[sub_803FC34(gActiveBattler)].gender].data, + 0x100 + r4 * 16, 0x20); + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = r4; + taskId = CreateTask(sub_812071C, 5); + gTasks[taskId].data[0] = gActiveBattler; + if (ewram17810[gActiveBattler].unk0_0) + gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; + ewram17840.unk9_0 = 1; + gBattleBankFunc[gActiveBattler] = nullsub_74; +} + +void sub_812071C(u8 taskId) +{ + u8 r9; + + if (gTasks[taskId].data[1] < 24) + { + gTasks[taskId].data[1]++; + return; + } + + r9 = gActiveBattler; + gActiveBattler = gTasks[taskId].data[0]; + if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_811F864(gActiveBattler, 0); + } + else + { + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_811F864(gActiveBattler, 0); + gActiveBattler ^= 2; + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + sub_811F864(gActiveBattler, 0); + gActiveBattler ^= 2; + } + gBattleBankFunc[gActiveBattler] = sub_811DCA0; + gActiveBattler = r9; + DestroyTask(taskId); +} + +void LinkPartnerHandlecmd48(void) +{ + if (gBattleBufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == 0) + { + LinkPartnerBufferExecCompleted(); + return; + } + + ewram17810[gActiveBattler].unk0_0 = 1; + gUnknown_02024E68[gActiveBattler] = sub_8044804( + gActiveBattler, + (struct BattleInterfaceStruct2 *)&gBattleBufferA[gActiveBattler][4], + gBattleBufferA[gActiveBattler][1], + gBattleBufferA[gActiveBattler][2]); + ewram17810[gActiveBattler].unk5 = 0; + if (gBattleBufferA[gActiveBattler][2] != 0) + ewram17810[gActiveBattler].unk5 = 0x5D; + gBattleBankFunc[gActiveBattler] = sub_81208E0; +} + +void sub_81208E0(void) +{ + if (ewram17810[gActiveBattler].unk5++ >= 93) + { + ewram17810[gActiveBattler].unk5 = 0; + LinkPartnerBufferExecCompleted(); + } +} + +void LinkPartnerHandlecmd49(void) +{ + if (ewram17810[gActiveBattler].unk0_0) + gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd50(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleSpriteInvisibility(void) +{ + if (IsBankSpritePresent(gActiveBattler) != 0) + { + gSprites[gBankSpriteIds[gActiveBattler]].invisible = gBattleBufferA[gActiveBattler][1]; + sub_8031F88(gActiveBattler); + } + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleBattleAnimation(void) +{ + if (mplay_80342A4(gActiveBattler) == 0) + { + u8 r3 = gBattleBufferA[gActiveBattler][1]; + u16 r4 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + + if (move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, r3, r4) != 0) + LinkPartnerBufferExecCompleted(); + else + gBattleBankFunc[gActiveBattler] = sub_811E3B8; + } +} + +void LinkPartnerHandleLinkStandbyMsg(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandleResetActionMoveSelection(void) +{ + LinkPartnerBufferExecCompleted(); +} + +void LinkPartnerHandlecmd55(void) +{ + gBattleOutcome = gBattleBufferA[gActiveBattler][1]; + FadeOutMapMusic(5); + BeginFastPaletteFade(3); + LinkPartnerBufferExecCompleted(); + gBattleBankFunc[gActiveBattler] = sub_811E29C; +} + +void LinkPartnerHandlecmd56(void) +{ +} diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c new file mode 100644 index 000000000..302f6a2f3 --- /dev/null +++ b/src/battle_controller_opponent.c @@ -0,0 +1,2369 @@ +#include "global.h" +#include "battle.h" +#include "battle_ai_switch_items.h" +#include "battle_anim.h" +#include "battle_interface.h" +#include "data2.h" +#include "battle_811DA74.h" +#include "battle_anim_special.h" +#include "battle_tower.h" +#include "link.h" +#include "m4a.h" +#include "main.h" +#include "palette.h" +#include "pokeball.h" +#include "pokemon.h" +#include "rom3.h" +#include "rom_8077ABC.h" +#include "sound.h" +#include "constants/songs.h" +#include "sprite.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "util.h" +#include "ewram.h" + +struct MovePpInfo +{ + u16 moves[4]; + u8 pp[4]; + u8 ppBonuses; +}; + +extern u8 gUnknown_02023A14_50; +extern u8 gActiveBattler; +extern u8 gBattleBufferA[][0x200]; +extern u16 gBattlerPartyIndexes[]; +extern u8 gBankSpriteIds[]; +extern u8 gBattleMonForms[]; +extern struct SpriteTemplate gUnknown_02024E8C; +extern void (*gBattleBankFunc[])(void); +extern u8 gUnknown_0300434C[]; +extern u8 gHealthboxIDs[]; +extern u16 gBattleTypeFlags; +extern u16 gTrainerBattleOpponent; +extern s32 gAnimMoveDmg; +extern u16 gAnimMovePower; +extern u8 gAnimFriendship; +extern u16 gWeatherMoveAnim; +extern u32 gTransformedPersonalities[]; +extern u8 gAnimMoveTurn; +extern u8 gAnimScriptActive; +extern void (*gAnimScriptCallback)(void); +extern struct Window gUnknown_03004210; +extern u8 gDisplayedStringBattle[]; +extern u8 gBankTarget; +extern u8 gAbsentBattlerFlags; +extern bool8 gDoingBattleAnim; +extern u16 gUnknown_02024DE8; +extern u8 gUnknown_02024E68[]; +extern MainCallback gPreBattleCallback1; +extern void (*const gOpponentBufferCommands[])(void); +extern struct MusicPlayerInfo gMPlay_SE1; +extern struct MusicPlayerInfo gMPlay_SE2; +extern struct MusicPlayerInfo gMPlay_BGM; +extern u32 gBattleExecBuffer; + +extern u8 GetBattlerSpriteCoord(); +extern u8 sub_8077F68(); +extern u8 GetBattlerSubpriority(); +extern void sub_8033018(void); +extern void BattleLoadOpponentMonSprite(); +extern u8 GetBattlerPosition(u8); +extern void sub_8032984(u8, u16); +extern void sub_80333D4(void); +extern void sub_80312F0(struct Sprite *); +extern u8 StartSendOutMonAnimation(); +extern void sub_8032A08(); +extern void sub_8043DB0(); +extern void sub_8033160(void); +extern u8 get_trainer_class_pic_index(void); +extern void sub_80313A0(struct Sprite *); +extern void sub_8032B4C(void); +extern void sub_8031A6C(u16, u8); +extern void sub_8032B84(void); +extern void StartAnimLinearTranslation(struct Sprite *); +extern void sub_8032BBC(void); +extern void oamt_add_pos2_onto_pos1(); +extern void StoreSpriteCallbackInData(); +extern void sub_803311C(void); +extern void sub_8010384(struct Sprite *); +extern bool8 mplay_80342A4(u8); +extern u8 sub_8031720(); +extern void DoMoveAnim(); +extern void sub_80326EC(); +extern void sub_8031F24(void); +extern void sub_80324BC(); +extern void BufferStringBattle(); +extern void sub_80331D0(void); +extern void AI_TrySwitchOrUseItem(void); +extern u8 GetBattlerAtPosition(u8); +extern void sub_80330C8(void); +extern void sub_8043D84(); +extern void sub_8045A5C(); +void sub_8033494(void); +extern void move_anim_start_t2_for_situation(); +extern void bx_blink_t7(void); +extern void sub_8047858(); +extern u8 GetBattlerSide(u8); +extern void StartBattleIntroAnim(); +extern void sub_8044CA0(u8); +extern void nullsub_45(void); +extern void sub_8031B74(); +extern bool8 IsDoubleBattle(void); +extern void sub_8032E2C(void); +extern u8 IsBankSpritePresent(); +extern u8 move_anim_start_t3(); +extern void sub_80334C0(void); + +// this file's functions + +void OpponentBufferExecCompleted(void); +void OpponentBufferRunCommand(void); +u32 sub_8033598(u8, u8 *); +void sub_8033E24(u8); +void sub_803495C(u8, u8); +void sub_8034B74(void); +void sub_8035238(void); +void sub_8035C10(struct Sprite *); +void sub_8035C44(u8); +void sub_8035E2C(void); +void sub_80332D0(void); + +void OpponentHandleGetAttributes(void); +void OpponentHandlecmd1(void); +void OpponentHandleSetAttributes(void); +void OpponentHandlecmd3(void); +void OpponentHandleLoadPokeSprite(void); +void OpponentHandleSendOutPoke(void); +void OpponentHandleReturnPokeToBall(void); +void OpponentHandleTrainerThrow(void); +void OpponentHandleTrainerSlide(void); +void OpponentHandleTrainerSlideBack(void); +void OpponentHandlecmd10(void); +void OpponentHandlecmd11(void); +void OpponentHandlecmd12(void); +void OpponentHandleBallThrow(void); +void OpponentHandlePuase(void); +void OpponentHandleMoveAnimation(void); +void OpponentHandlePrintString(void); +void OpponentHandlePrintStringPlayerOnly(void); +void OpponentHandlecmd18(void); +void OpponentHandlecmd19(void); +void OpponentHandlecmd20(void); +void OpponentHandleOpenBag(void); +void OpponentHandlecmd22(void); +void OpponentHandlecmd23(void); +void OpponentHandleHealthBarUpdate(void); +void OpponentHandleExpBarUpdate(void); +void OpponentHandleStatusIconUpdate(void); +void OpponentHandleStatusAnimation(void); +void OpponentHandleStatusXor(void); +void OpponentHandlecmd29(void); +void OpponentHandleDMATransfer(void); +void OpponentHandlecmd31(void); +void OpponentHandlecmd32(void); +void OpponentHandlecmd33(void); +void OpponentHandlecmd34(void); +void OpponentHandlecmd35(void); +void OpponentHandlecmd36(void); +void OpponentHandlecmd37(void); +void OpponentHandlecmd38(void); +void OpponentHandlecmd39(void); +void OpponentHandlecmd40(void); +void OpponentHandleHitAnimation(void); +void OpponentHandlecmd42(void); +void OpponentHandleEffectivenessSound(void); +void OpponentHandlecmd44(void); +void OpponentHandleFaintingCry(void); +void OpponentHandleIntroSlide(void); +void OpponentHandleTrainerBallThrow(void); +void OpponentHandlecmd48(void); +void OpponentHandlecmd49(void); +void OpponentHandlecmd50(void); +void OpponentHandleSpriteInvisibility(void); +void OpponentHandleBattleAnimation(void); +void OpponentHandleLinkStandbyMsg(void); +void OpponentHandleResetActionMoveSelection(void); +void OpponentHandlecmd55(void); +void OpponentHandlecmd56(void); + +// const data +typedef void (*BattleBufferCmd) (void); +static const BattleBufferCmd gOpponentBufferCommands[] = +{ + OpponentHandleGetAttributes, + OpponentHandlecmd1, + OpponentHandleSetAttributes, + OpponentHandlecmd3, + OpponentHandleLoadPokeSprite, + OpponentHandleSendOutPoke, + OpponentHandleReturnPokeToBall, + OpponentHandleTrainerThrow, + OpponentHandleTrainerSlide, + OpponentHandleTrainerSlideBack, + OpponentHandlecmd10, + OpponentHandlecmd11, + OpponentHandlecmd12, + OpponentHandleBallThrow, + OpponentHandlePuase, + OpponentHandleMoveAnimation, + OpponentHandlePrintString, + OpponentHandlePrintStringPlayerOnly, + OpponentHandlecmd18, + OpponentHandlecmd19, + OpponentHandlecmd20, + OpponentHandleOpenBag, + OpponentHandlecmd22, + OpponentHandlecmd23, + OpponentHandleHealthBarUpdate, + OpponentHandleExpBarUpdate, + OpponentHandleStatusIconUpdate, + OpponentHandleStatusAnimation, + OpponentHandleStatusXor, + OpponentHandlecmd29, + OpponentHandleDMATransfer, + OpponentHandlecmd31, + OpponentHandlecmd32, + OpponentHandlecmd33, + OpponentHandlecmd34, + OpponentHandlecmd35, + OpponentHandlecmd36, + OpponentHandlecmd37, + OpponentHandlecmd38, + OpponentHandlecmd39, + OpponentHandlecmd40, + OpponentHandleHitAnimation, + OpponentHandlecmd42, + OpponentHandleEffectivenessSound, + OpponentHandlecmd44, + OpponentHandleFaintingCry, + OpponentHandleIntroSlide, + OpponentHandleTrainerBallThrow, + OpponentHandlecmd48, + OpponentHandlecmd49, + OpponentHandlecmd50, + OpponentHandleSpriteInvisibility, + OpponentHandleBattleAnimation, + OpponentHandleLinkStandbyMsg, + OpponentHandleResetActionMoveSelection, + OpponentHandlecmd55, + OpponentHandlecmd56, +}; + +static const u8 sUnknownBytes[] = {0xB0, 0xB0, 0xC8, 0x98, 0x28, 0x28, 0x28, 0x20}; + +// code + +void nullsub_45(void) +{ +} + +void SetBankFuncToOpponentBufferRunCommand(void) +{ + gBattleBankFunc[gActiveBattler] = OpponentBufferRunCommand; +} + +void OpponentBufferRunCommand(void) +{ + if (gBattleExecBuffer & gBitTable[gActiveBattler]) + { + if (gBattleBufferA[gActiveBattler][0] <= 0x38) + gOpponentBufferCommands[gBattleBufferA[gActiveBattler][0]](); + else + OpponentBufferExecCompleted(); + } +} + +void sub_8032B4C(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + OpponentBufferExecCompleted(); +} + +// Duplicate of sub_8032B4C +void sub_8032B84(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + OpponentBufferExecCompleted(); +} + +void sub_8032BBC(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + { + sub_8031B74(gSprites[gBankSpriteIds[gActiveBattler]].oam.affineParam); + gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum = gSprites[gBankSpriteIds[gActiveBattler]].data[5]; + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + OpponentBufferExecCompleted(); + } +} + +void sub_8032C4C(void) +{ + if ((--ewram17810[gActiveBattler].unk9) == 0xFF) + { + ewram17810[gActiveBattler].unk9 = 0; + OpponentBufferExecCompleted(); + } +} + +void sub_8032C88(void) +{ + bool8 r6 = FALSE; + + if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) + { + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) + r6 = TRUE; + } + else + { + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxIDs[gActiveBattler ^ 2]].callback == SpriteCallbackDummy) + r6 = TRUE; + } + if (IsCryPlayingOrClearCrySongs()) + r6 = FALSE; + + if (r6 && ewram17810[gActiveBattler].unk1_0 && ewram17810[gActiveBattler ^ 2].unk1_0) + { + ewram17810[gActiveBattler].unk0_7 = 0; + ewram17810[gActiveBattler].unk1_0 = 0; + ewram17810[gActiveBattler ^ 2].unk0_7 = 0; + ewram17810[gActiveBattler ^ 2].unk1_0 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + m4aMPlayContinue(&gMPlay_BGM); + else + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 256); + ewram17810[gActiveBattler].unk9 = 3; + gBattleBankFunc[gActiveBattler] = sub_8032C4C; + } +} + +void sub_8032E2C(void) +{ + if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) + sub_8141828(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + if (!ewram17810[gActiveBattler ^ 2].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_7) + sub_8141828(gActiveBattler ^ 2, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ 2]]); + if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_3) + { + if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler ^ 2]]); + sub_8045A5C( + gHealthboxIDs[gActiveBattler ^ 2], + &gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], + 0); + sub_804777C(gActiveBattler ^ 2); + sub_8043DFC(gHealthboxIDs[gActiveBattler ^ 2]); + sub_8032984( + gActiveBattler ^ 2, + GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], MON_DATA_SPECIES)); + } + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); + sub_8045A5C( + gHealthboxIDs[gActiveBattler], + &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], + 0); + sub_804777C(gActiveBattler); + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + sub_8032984( + gActiveBattler, + GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + + ewram17840.unk9_0 = 0; + gBattleBankFunc[gActiveBattler] = sub_8032C88; + } +} + +void sub_8033018(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].animEnded == TRUE + && gSprites[gBankSpriteIds[gActiveBattler]].pos2.x == 0) + { + if (!ewram17810[gActiveBattler].unk0_7) + { + sub_8141828(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + return; + } + if (ewram17810[gActiveBattler].unk1_0) + { + ewram17810[gActiveBattler].unk0_7 = 0; + ewram17810[gActiveBattler].unk1_0 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + OpponentBufferExecCompleted(); + return; + } + } +} + +void sub_80330C8(void) +{ + s16 r4 = sub_8045C78(gActiveBattler, gHealthboxIDs[gActiveBattler], 0, 0); + + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + if (r4 != -1) + sub_80440EC(gHealthboxIDs[gActiveBattler], r4, 0); + else + OpponentBufferExecCompleted(); +} + +void sub_803311C(void) +{ + if (!gSprites[gBankSpriteIds[gActiveBattler]].inUse) + { + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + OpponentBufferExecCompleted(); + } +} + +void sub_8033160(void) +{ + if (!ewram17810[gActiveBattler].unk0_6) + { + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + sub_8032A08(gActiveBattler); + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + OpponentBufferExecCompleted(); + } +} + +void sub_80331D0(void) +{ + if (gUnknown_03004210.state == 0) + OpponentBufferExecCompleted(); +} + +void bx_blink_t7(void) +{ + u8 spriteId = gBankSpriteIds[gActiveBattler]; + + if (gSprites[spriteId].data[1] == 32) + { + gSprites[spriteId].data[1] = 0; + gSprites[spriteId].invisible = FALSE; + gDoingBattleAnim = 0; + OpponentBufferExecCompleted(); + } + else + { + if (((u16)gSprites[spriteId].data[1] % 4) == 0) + gSprites[spriteId].invisible ^= 1; + gSprites[spriteId].data[1]++; + } +} + +void sub_8033264(void) +{ + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) + { + if (ewram17800[gActiveBattler].substituteSprite) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); + gBattleBankFunc[gActiveBattler] = sub_80332D0; + } +} + +void sub_80332D0(void) +{ + if (!ewram17810[gActiveBattler].unk0_6) + { + CreateTask(c3_0802FDF4, 10); + OpponentBufferExecCompleted(); + } +} + +void sub_8033308(void) +{ + if (ewram17810[gActiveBattler].unk1_0) + { + ewram17810[gActiveBattler].unk0_7 = 0; + ewram17810[gActiveBattler].unk1_0 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 0); + sub_8045A5C( + gHealthboxIDs[gActiveBattler], + &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], + 0); + sub_804777C(gActiveBattler); + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + sub_8031F88(gActiveBattler); + gBattleBankFunc[gActiveBattler] = sub_8033264; + } +} + +void sub_80333D4(void) +{ + if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) + sub_8141828(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]); + if (gSprites[gUnknown_0300434C[gActiveBattler]].callback == SpriteCallbackDummy + && !ewram17810[gActiveBattler].unk0_3) + { + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); + sub_8032984(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + gBattleBankFunc[gActiveBattler] = sub_8033308; + } +} + +void sub_8033494(void) +{ + if (!ewram17810[gActiveBattler].unk0_4) + OpponentBufferExecCompleted(); +} + +void sub_80334C0(void) +{ + if (!ewram17810[gActiveBattler].unk0_5) + OpponentBufferExecCompleted(); +} + +void OpponentBufferExecCompleted(void) +{ + gBattleBankFunc[gActiveBattler] = OpponentBufferRunCommand; + gBattleExecBuffer &= ~gBitTable[gActiveBattler]; +} + +void OpponentHandleGetAttributes(void) +{ + u8 buffer[256]; + int r6 = 0; + s32 i; + + if (gBattleBufferA[gActiveBattler][2] == 0) + { + r6 = sub_8033598(gBattlerPartyIndexes[gActiveBattler], buffer); + } + else + { + u8 r4 = gBattleBufferA[gActiveBattler][2]; + + for (i = 0; i < 6; i++) + { + if (r4 & 1) + r6 += sub_8033598(i, buffer + r6); + r4 >>= 1; + } + } + Emitcmd29(1, r6, buffer); + OpponentBufferExecCompleted(); +} + +u32 sub_8033598(u8 a, u8 *buffer) +{ + struct BattlePokemon battlePokemon; + struct MovePpInfo moveData; + u8 nickname[20]; + u8 *src; + s16 data16; + u32 data32; + s32 size = 0; + + switch (gBattleBufferA[gActiveBattler][1]) + { + case 0: + battlePokemon.species = GetMonData(&gEnemyParty[a], MON_DATA_SPECIES); + battlePokemon.item = GetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM); + for (size = 0; size < 4; size++) + { + battlePokemon.moves[size] = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + size); + battlePokemon.pp[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size); + } + battlePokemon.ppBonuses = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES); + battlePokemon.friendship = GetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP); + battlePokemon.experience = GetMonData(&gEnemyParty[a], MON_DATA_EXP); + battlePokemon.hpIV = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV); + battlePokemon.attackIV = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV); + battlePokemon.defenseIV = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV); + battlePokemon.speedIV = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV); + battlePokemon.spAttackIV = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV); + battlePokemon.spDefenseIV = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV); + battlePokemon.personality = GetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY); + battlePokemon.status1 = GetMonData(&gEnemyParty[a], MON_DATA_STATUS); + battlePokemon.level = GetMonData(&gEnemyParty[a], MON_DATA_LEVEL); + battlePokemon.hp = GetMonData(&gEnemyParty[a], MON_DATA_HP); + battlePokemon.maxHP = GetMonData(&gEnemyParty[a], MON_DATA_MAX_HP); + battlePokemon.attack = GetMonData(&gEnemyParty[a], MON_DATA_ATK); + battlePokemon.defense = GetMonData(&gEnemyParty[a], MON_DATA_DEF); + battlePokemon.speed = GetMonData(&gEnemyParty[a], MON_DATA_SPEED); + battlePokemon.spAttack = GetMonData(&gEnemyParty[a], MON_DATA_SPATK); + battlePokemon.spDefense = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF); + battlePokemon.isEgg = GetMonData(&gEnemyParty[a], MON_DATA_IS_EGG); + battlePokemon.altAbility = GetMonData(&gEnemyParty[a], MON_DATA_ALT_ABILITY); + battlePokemon.otId = GetMonData(&gEnemyParty[a], MON_DATA_OT_ID); + GetMonData(&gEnemyParty[a], MON_DATA_NICKNAME, nickname); + StringCopy10(battlePokemon.nickname, nickname); + GetMonData(&gEnemyParty[a], MON_DATA_OT_NAME, battlePokemon.otName); + MEMCPY_ALT(&battlePokemon, buffer, sizeof(battlePokemon), size, src); + break; + case 1: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPECIES); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 2: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 3: + for (size = 0; size < 4; size++) + { + moveData.moves[size] = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + size); + moveData.pp[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size); + } + moveData.ppBonuses = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES); + MEMCPY_ALT(&moveData, buffer, sizeof(moveData), size, src); + break; + case 4: + case 5: + case 6: + case 7: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 8: + for (size = 0; size < 4; size++) + buffer[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + size); + buffer[size] = GetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES); + size++; + break; + case 9: + case 10: + case 11: + case 12: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9); + size = 1; + break; + case 17: + data32 = GetMonData(&gEnemyParty[a], MON_DATA_OT_ID); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + size = 3; + break; + case 18: + data32 = GetMonData(&gEnemyParty[a], MON_DATA_EXP); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + size = 3; + break; + case 19: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_EV); + size = 1; + break; + case 20: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_EV); + size = 1; + break; + case 21: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_EV); + size = 1; + break; + case 22: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_EV); + size = 1; + break; + case 23: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_EV); + size = 1; + break; + case 24: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_EV); + size = 1; + break; + case 25: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP); + size = 1; + break; + case 26: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_POKERUS); + size = 1; + break; + case 27: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_LOCATION); + size = 1; + break; + case 28: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_LEVEL); + size = 1; + break; + case 29: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_MET_GAME); + size = 1; + break; + case 30: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_POKEBALL); + size = 1; + break; + case 31: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV); + buffer[1] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV); + buffer[2] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV); + buffer[3] = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV); + buffer[4] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV); + buffer[5] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV); + size = 6; + break; + case 32: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_HP_IV); + size = 1; + break; + case 33: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_ATK_IV); + size = 1; + break; + case 34: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_DEF_IV); + size = 1; + break; + case 35: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV); + size = 1; + break; + case 36: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV); + size = 1; + break; + case 37: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV); + size = 1; + break; + case 38: + data32 = GetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + buffer[3] = (data32 & 0xFF000000) >> 24; + size = 4; + break; + case 39: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_CHECKSUM); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 40: + data32 = GetMonData(&gEnemyParty[a], MON_DATA_STATUS); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + buffer[3] = (data32 & 0xFF000000) >> 24; + size = 4; + break; + case 41: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_LEVEL); + size = 1; + break; + case 42: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_HP); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 43: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_MAX_HP); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 44: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_ATK); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 45: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_DEF); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 46: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPEED); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 47: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPATK); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 48: + data16 = GetMonData(&gEnemyParty[a], MON_DATA_SPDEF); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 49: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_COOL); + size = 1; + break; + case 50: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_BEAUTY); + size = 1; + break; + case 51: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_CUTE); + size = 1; + break; + case 52: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SMART); + size = 1; + break; + case 53: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_TOUGH); + size = 1; + break; + case 54: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SHEEN); + size = 1; + break; + case 55: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_COOL_RIBBON); + size = 1; + break; + case 56: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_BEAUTY_RIBBON); + size = 1; + break; + case 57: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_CUTE_RIBBON); + size = 1; + break; + case 58: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_SMART_RIBBON); + size = 1; + break; + case 59: + buffer[0] = GetMonData(&gEnemyParty[a], MON_DATA_TOUGH_RIBBON); + size = 1; + break; + } + return size; +} + +void OpponentHandlecmd1(void) +{ + struct BattlePokemon buffer; + u8 i; + // TODO: Maybe fix this. Integrating this into MEMSET_ALT is too hard. + u8 *src = (u8 *)&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1]; + u8 *dst; + + MEMSET_ALT(&buffer + gBattleBufferA[gActiveBattler][1], src[i], gBattleBufferA[gActiveBattler][2], i, dst); + Emitcmd29(1, gBattleBufferA[gActiveBattler][2], dst); + OpponentBufferExecCompleted(); +} + +void OpponentHandleSetAttributes(void) +{ + u8 i; + u8 r4; + + if (gBattleBufferA[gActiveBattler][2] == 0) + { + sub_8033E24(gBattlerPartyIndexes[gActiveBattler]); + } + else + { + r4 = gBattleBufferA[gActiveBattler][2]; + for (i = 0; i < 6; i++) + { + if (r4 & 1) + sub_8033E24(i); + r4 >>= 1; + } + } + OpponentBufferExecCompleted(); +} + +void sub_8033E24(u8 a) +{ + struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBattler][3]; + struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBattler][3]; + s32 i; + + switch (gBattleBufferA[gActiveBattler][1]) + { + case 0: + { + u8 iv; + + SetMonData(&gEnemyParty[a], MON_DATA_SPECIES, &battlePokemon->species); + SetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM, &battlePokemon->item); + for (i = 0; i < 4; i++) + { + SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); + SetMonData(&gEnemyParty[a], MON_DATA_PP1 + i, &battlePokemon->pp[i]); + } + SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); + SetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); + SetMonData(&gEnemyParty[a], MON_DATA_EXP, &battlePokemon->experience); + iv = battlePokemon->hpIV; + SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &iv); + iv = battlePokemon->attackIV; + SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &iv); + iv = battlePokemon->defenseIV; + SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &iv); + iv = battlePokemon->speedIV; + SetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV, &iv); + iv = battlePokemon->spAttackIV; + SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &iv); + iv = battlePokemon->spDefenseIV; + SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &iv); + SetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY, &battlePokemon->personality); + SetMonData(&gEnemyParty[a], MON_DATA_STATUS, &battlePokemon->status1); + SetMonData(&gEnemyParty[a], MON_DATA_LEVEL, &battlePokemon->level); + SetMonData(&gEnemyParty[a], MON_DATA_HP, &battlePokemon->hp); + SetMonData(&gEnemyParty[a], MON_DATA_MAX_HP, &battlePokemon->maxHP); + SetMonData(&gEnemyParty[a], MON_DATA_ATK, &battlePokemon->attack); + SetMonData(&gEnemyParty[a], MON_DATA_DEF, &battlePokemon->defense); + SetMonData(&gEnemyParty[a], MON_DATA_SPEED, &battlePokemon->speed); + SetMonData(&gEnemyParty[a], MON_DATA_SPATK, &battlePokemon->spAttack); + SetMonData(&gEnemyParty[a], MON_DATA_SPDEF, &battlePokemon->spDefense); + } + break; + case 1: + SetMonData(&gEnemyParty[a], MON_DATA_SPECIES, &gBattleBufferA[gActiveBattler][3]); + break; + case 2: + SetMonData(&gEnemyParty[a], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]); + break; + case 3: + for (i = 0; i < 4; i++) + { + SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + i, &moveData->moves[i]); + SetMonData(&gEnemyParty[a], MON_DATA_PP1 + i, &moveData->pp[i]); + } + SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &moveData->ppBonuses); + break; + case 4: + case 5: + case 6: + case 7: + SetMonData(&gEnemyParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4, &gBattleBufferA[gActiveBattler][3]); + break; + case 8: + SetMonData(&gEnemyParty[a], MON_DATA_PP1, &gBattleBufferA[gActiveBattler][3]); + SetMonData(&gEnemyParty[a], MON_DATA_PP2, &gBattleBufferA[gActiveBattler][4]); + SetMonData(&gEnemyParty[a], MON_DATA_PP3, &gBattleBufferA[gActiveBattler][5]); + SetMonData(&gEnemyParty[a], MON_DATA_PP4, &gBattleBufferA[gActiveBattler][6]); + SetMonData(&gEnemyParty[a], MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBattler][7]); + break; + case 9: + case 10: + case 11: + case 12: + SetMonData(&gEnemyParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9, &gBattleBufferA[gActiveBattler][3]); + break; + case 17: + SetMonData(&gEnemyParty[a], MON_DATA_OT_ID, &gBattleBufferA[gActiveBattler][3]); + break; + case 18: + SetMonData(&gEnemyParty[a], MON_DATA_EXP, &gBattleBufferA[gActiveBattler][3]); + break; + case 19: + SetMonData(&gEnemyParty[a], MON_DATA_HP_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 20: + SetMonData(&gEnemyParty[a], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 21: + SetMonData(&gEnemyParty[a], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 22: + SetMonData(&gEnemyParty[a], MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 23: + SetMonData(&gEnemyParty[a], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 24: + SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 25: + SetMonData(&gEnemyParty[a], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBattler][3]); + break; + case 26: + SetMonData(&gEnemyParty[a], MON_DATA_POKERUS, &gBattleBufferA[gActiveBattler][3]); + break; + case 27: + SetMonData(&gEnemyParty[a], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBattler][3]); + break; + case 28: + SetMonData(&gEnemyParty[a], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBattler][3]); + break; + case 29: + SetMonData(&gEnemyParty[a], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBattler][3]); + break; + case 30: + SetMonData(&gEnemyParty[a], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBattler][3]); + break; + case 31: + SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); + SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][4]); + SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][5]); + SetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][6]); + SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][7]); + SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][8]); + break; + case 32: + SetMonData(&gEnemyParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 33: + SetMonData(&gEnemyParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 34: + SetMonData(&gEnemyParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 35: + SetMonData(&gEnemyParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 36: + SetMonData(&gEnemyParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 37: + SetMonData(&gEnemyParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 38: + SetMonData(&gEnemyParty[a], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBattler][3]); + break; + case 39: + SetMonData(&gEnemyParty[a], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBattler][3]); + break; + case 40: + SetMonData(&gEnemyParty[a], MON_DATA_STATUS, &gBattleBufferA[gActiveBattler][3]); + break; + case 41: + SetMonData(&gEnemyParty[a], MON_DATA_LEVEL, &gBattleBufferA[gActiveBattler][3]); + break; + case 42: + SetMonData(&gEnemyParty[a], MON_DATA_HP, &gBattleBufferA[gActiveBattler][3]); + break; + case 43: + SetMonData(&gEnemyParty[a], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBattler][3]); + break; + case 44: + SetMonData(&gEnemyParty[a], MON_DATA_ATK, &gBattleBufferA[gActiveBattler][3]); + break; + case 45: + SetMonData(&gEnemyParty[a], MON_DATA_DEF, &gBattleBufferA[gActiveBattler][3]); + break; + case 46: + SetMonData(&gEnemyParty[a], MON_DATA_SPEED, &gBattleBufferA[gActiveBattler][3]); + break; + case 47: + SetMonData(&gEnemyParty[a], MON_DATA_SPATK, &gBattleBufferA[gActiveBattler][3]); + break; + case 48: + SetMonData(&gEnemyParty[a], MON_DATA_SPDEF, &gBattleBufferA[gActiveBattler][3]); + break; + case 49: + SetMonData(&gEnemyParty[a], MON_DATA_COOL, &gBattleBufferA[gActiveBattler][3]); + break; + case 50: + SetMonData(&gEnemyParty[a], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBattler][3]); + break; + case 51: + SetMonData(&gEnemyParty[a], MON_DATA_CUTE, &gBattleBufferA[gActiveBattler][3]); + break; + case 52: + SetMonData(&gEnemyParty[a], MON_DATA_SMART, &gBattleBufferA[gActiveBattler][3]); + break; + case 53: + SetMonData(&gEnemyParty[a], MON_DATA_TOUGH, &gBattleBufferA[gActiveBattler][3]); + break; + case 54: + SetMonData(&gEnemyParty[a], MON_DATA_SHEEN, &gBattleBufferA[gActiveBattler][3]); + break; + case 55: + SetMonData(&gEnemyParty[a], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 56: + SetMonData(&gEnemyParty[a], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 57: + SetMonData(&gEnemyParty[a], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 58: + SetMonData(&gEnemyParty[a], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 59: + SetMonData(&gEnemyParty[a], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + } +} + +void OpponentHandlecmd3(void) +{ + u8 *dst; + u8 i; + + MEMSET_ALT(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][3 + i], + gBattleBufferA[gActiveBattler][2], i, dst); + OpponentBufferExecCompleted(); +} + +void OpponentHandleLoadPokeSprite(void) +{ + u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); + + BattleLoadOpponentMonSprite(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(gActiveBattler)); + gBankSpriteIds[gActiveBattler] = CreateSprite( + &gUnknown_02024E8C, + GetBattlerSpriteCoord(gActiveBattler, 2), + sub_8077F68(gActiveBattler), + GetBattlerSubpriority(gActiveBattler)); + gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -240; + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = gActiveBattler; + gSprites[gBankSpriteIds[gActiveBattler]].data[2] = species; + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; + StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], gBattleMonForms[gActiveBattler]); + sub_8032984(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES)); + gBattleBankFunc[gActiveBattler] = sub_8033018; +} + +void OpponentHandleSendOutPoke(void) +{ + gBattlerPartyIndexes[gActiveBattler] = gBattleBufferA[gActiveBattler][1]; + + sub_803495C(gActiveBattler, gBattleBufferA[gActiveBattler][2]); + gBattleBankFunc[gActiveBattler] = sub_80333D4; +} + +void sub_803495C(u8 a, u8 b) +{ + u16 species; + + sub_8032AA8(a, b); + gBattlerPartyIndexes[a] = gBattleBufferA[a][1]; + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[a]], MON_DATA_SPECIES); + gUnknown_0300434C[a] = CreateInvisibleSpriteWithCallback(sub_80312F0); + BattleLoadOpponentMonSprite(&gEnemyParty[gBattlerPartyIndexes[a]], a); + GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(a)); + gBankSpriteIds[a] = CreateSprite( + &gUnknown_02024E8C, + GetBattlerSpriteCoord(a, 2), + sub_8077F68(a), + GetBattlerSubpriority(a)); + gSprites[gBankSpriteIds[a]].data[0] = a; + gSprites[gBankSpriteIds[a]].data[2] = species; + gSprites[gUnknown_0300434C[a]].data[1] = gBankSpriteIds[a]; + gSprites[gBankSpriteIds[a]].oam.paletteNum = a; + StartSpriteAnim(&gSprites[gBankSpriteIds[a]], gBattleMonForms[a]); + gSprites[gBankSpriteIds[a]].invisible = TRUE; + gSprites[gBankSpriteIds[a]].callback = SpriteCallbackDummy; + gSprites[gUnknown_0300434C[a]].data[0] = StartSendOutMonAnimation(0, 0xFE); +} + +void OpponentHandleReturnPokeToBall(void) +{ + if (gBattleBufferA[gActiveBattler][1] == 0) + { + ewram17810[gActiveBattler].unk4 = 0; + gBattleBankFunc[gActiveBattler] = sub_8034B74; + } + else + { + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + sub_8032A08(gActiveBattler); + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + OpponentBufferExecCompleted(); + } +} + +void sub_8034B74(void) +{ + switch (ewram17810[gActiveBattler].unk4) + { + case 0: + if (ewram17800[gActiveBattler].substituteSprite) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + ewram17810[gActiveBattler].unk4 = 1; + break; + case 1: + if (!ewram17810[gActiveBattler].unk0_6) + { + ewram17810[gActiveBattler].unk4 = 0; + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 2); + gBattleBankFunc[gActiveBattler] = sub_8033160; + } + break; + } +} + +void OpponentHandleTrainerThrow(void) +{ + u32 trainerPicIndex; + +#if DEBUG + if (gUnknown_02023A14_50 & 0x10) + { + trainerPicIndex = gSharedMem[0x160A3]; + } + else +#endif + { + if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) + trainerPicIndex = GetSecretBaseTrainerPicIndex(); + else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + trainerPicIndex = get_trainer_class_pic_index(); + else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) + trainerPicIndex = GetEReaderTrainerPicIndex(); + else + trainerPicIndex = gTrainers[gTrainerBattleOpponent].trainerPic; + } + + sub_8031A6C(trainerPicIndex, gActiveBattler); + GetMonSpriteTemplate_803C5A0(trainerPicIndex, GetBattlerPosition(gActiveBattler)); + gBankSpriteIds[gActiveBattler] = CreateSprite( + &gUnknown_02024E8C, + 0xB0, + 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicIndex].coords), + GetBattlerSubpriority(gActiveBattler)); + gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -240; + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 2; + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicIndex].tag); + gSprites[gBankSpriteIds[gActiveBattler]].data[5] = gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum; + gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum = GetSpriteTileStartByTag(gTrainerFrontPicTable[trainerPicIndex].tag); + gSprites[gBankSpriteIds[gActiveBattler]].oam.affineParam = trainerPicIndex; + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; + gBattleBankFunc[gActiveBattler] = sub_8032B4C; +} + +void OpponentHandleTrainerSlide(void) +{ + u32 trainerPicIndex; + + if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) + trainerPicIndex = GetSecretBaseTrainerPicIndex(); + else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + trainerPicIndex = get_trainer_class_pic_index(); + else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) + trainerPicIndex = GetEReaderTrainerPicIndex(); + else + trainerPicIndex = gTrainers[gTrainerBattleOpponent].trainerPic; + + sub_8031A6C(trainerPicIndex, gActiveBattler); + GetMonSpriteTemplate_803C5A0(trainerPicIndex, GetBattlerPosition(gActiveBattler)); + gBankSpriteIds[gActiveBattler] = CreateSprite( + &gUnknown_02024E8C, + 0xB0, + 40 + 4 * (8 - gTrainerFrontPicCoords[trainerPicIndex].coords), + 0x1E); + gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = 96; + gSprites[gBankSpriteIds[gActiveBattler]].pos1.x += 32; + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = -2; + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[trainerPicIndex].tag); + gSprites[gBankSpriteIds[gActiveBattler]].data[5] = gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum; + gSprites[gBankSpriteIds[gActiveBattler]].oam.tileNum = GetSpriteTileStartByTag(gTrainerFrontPicTable[trainerPicIndex].tag); + gSprites[gBankSpriteIds[gActiveBattler]].oam.affineParam = trainerPicIndex; + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; + gBattleBankFunc[gActiveBattler] = sub_8032B84; +} + +void OpponentHandleTrainerSlideBack(void) +{ + oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 35; + gSprites[gBankSpriteIds[gActiveBattler]].data[2] = 280; + gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; + gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], SpriteCallbackDummy); + gBattleBankFunc[gActiveBattler] = sub_8032BBC; +} + +void OpponentHandlecmd10(void) +{ + if (ewram17810[gActiveBattler].unk4 == 0) + { + if (ewram17800[gActiveBattler].substituteSprite) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + ewram17810[gActiveBattler].unk4++; + } + else if (!ewram17810[gActiveBattler].unk0_6) + { + ewram17810[gActiveBattler].unk4 = 0; + PlaySE12WithPanning(SE_POKE_DEAD, 63); + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_8010384; + gBattleBankFunc[gActiveBattler] = sub_803311C; + } +} + +void OpponentHandlecmd11(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd12(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleBallThrow(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlePuase(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleMoveAnimation(void) +{ + if (!mplay_80342A4(gActiveBattler)) + { + u32 r0 = gBattleBufferA[gActiveBattler][1] + | (gBattleBufferA[gActiveBattler][2] << 8); + + gAnimMoveTurn = gBattleBufferA[gActiveBattler][3]; + gAnimMovePower = gBattleBufferA[gActiveBattler][4] + | (gBattleBufferA[gActiveBattler][5] << 8); + gAnimMoveDmg = gBattleBufferA[gActiveBattler][6] + | (gBattleBufferA[gActiveBattler][7] << 8) + | (gBattleBufferA[gActiveBattler][8] << 16) + | (gBattleBufferA[gActiveBattler][9] << 24); + gAnimFriendship = gBattleBufferA[gActiveBattler][10]; + gWeatherMoveAnim = gBattleBufferA[gActiveBattler][12] + | (gBattleBufferA[gActiveBattler][13] << 8); + gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBattler][16]; + gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; + + // Dead code. sub_8031720 always returns 0. + if (sub_8031720(r0, gAnimMoveTurn) != 0) + { + OpponentBufferExecCompleted(); + } + else + { + ewram17810[gActiveBattler].unk4 = 0; + gBattleBankFunc[gActiveBattler] = sub_8035238; + } + } +} + +void sub_8035238(void) +{ + u16 r4 = gBattleBufferA[gActiveBattler][1] + | (gBattleBufferA[gActiveBattler][2] << 8); + u8 r7 = gBattleBufferA[gActiveBattler][11]; + + switch (ewram17810[gActiveBattler].unk4) + { + case 0: + if (ewram17800[gActiveBattler].substituteSprite && !ewram17800[gActiveBattler].unk0_3) + { + ewram17800[gActiveBattler].unk0_3 = 1; + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + } + ewram17810[gActiveBattler].unk4 = 1; + break; + case 1: + if (!ewram17810[gActiveBattler].unk0_6) + { + sub_80326EC(0); + DoMoveAnim(r4); + ewram17810[gActiveBattler].unk4 = 2; + } + break; + case 2: + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + sub_80326EC(1); + if ((ewram17800[gActiveBattler].substituteSprite) && r7 <= 1) + { + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); + ewram17800[gActiveBattler].unk0_3 = 0; + } + ewram17810[gActiveBattler].unk4 = 3; + } + break; + case 3: + if (!ewram17810[gActiveBattler].unk0_6) + { + sub_8031F24(); + sub_80324BC( + gActiveBattler, + gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + ewram17810[gActiveBattler].unk4 = 0; + OpponentBufferExecCompleted(); + } + break; + } +} + +void OpponentHandlePrintString(void) +{ + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + BufferStringBattle(*(u16 *)&gBattleBufferA[gActiveBattler][2]); + Text_InitWindow8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15); + gBattleBankFunc[gActiveBattler] = sub_80331D0; +} + +void OpponentHandlePrintStringPlayerOnly(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd18(void) +{ + AI_TrySwitchOrUseItem(); + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd19(void) +{ + OpponentBufferExecCompleted(); +} + +#if DEBUG +NAKED +void OpponentHandlecmd20(void) +{ + asm("\ + push {r4, r5, r6, r7, lr}\n\ + mov r7, sl\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5, r6, r7}\n\ + ldr r6, ._549 @ gActiveBattler\n\ + ldrb r0, [r6]\n\ + lsl r0, r0, #0x9\n\ + ldr r1, ._549 + 4 @ gBattleBufferA\n\ + add r5, r0, r1\n\ + ldr r2, ._549 + 8 @ gUnknown_02023A14_50\n\ + ldrb r1, [r2]\n\ + mov r0, #0x4\n\ + and r0, r0, r1\n\ + mov sl, r6\n\ + cmp r0, #0\n\ + beq ._546 @cond_branch\n\ + ldr r0, ._549 + 12 @ gBattleMoves\n\ + mov r9, r0\n\ + ldr r1, ._549 + 16 @ \n\ + mov ip, r1\n\ + add r7, r6, #0\n\ + mov r0, #0x2\n\ + mov r8, r0\n\ + ldr r6, ._549 + 20 @ \n\ +._552:\n\ + ldrb r1, [r7]\n\ + mov r0, r8\n\ + and r0, r0, r1\n\ + lsl r0, r0, #0x18\n\ + lsr r0, r0, #0x19\n\ + add r0, r0, r6\n\ + mov r1, ip\n\ + add r3, r0, r1\n\ + ldrb r1, [r3]\n\ + lsl r0, r1, #0x1\n\ + add r0, r5, r0\n\ + ldrh r2, [r0]\n\ + add r4, r1, #0\n\ + cmp r2, #0\n\ + beq ._547 @cond_branch\n\ + add r0, r4, #1\n\ + strb r0, [r3]\n\ + b ._548\n\ +._550:\n\ + .align 2, 0\n\ +._549:\n\ + .word gActiveBattler\n\ + .word gBattleBufferA+4\n\ + .word gUnknown_02023A14_50\n\ + .word gBattleMoves\n\ + .word +0x2000000\n\ + .word 0x1609e\n\ +._547:\n\ + strb r2, [r3]\n\ +._548:\n\ + ldrb r0, [r7]\n\ + mov r1, r8\n\ + and r1, r1, r0\n\ + lsl r1, r1, #0x18\n\ + lsr r1, r1, #0x19\n\ + add r1, r1, r6\n\ + add r1, r1, ip\n\ + ldrb r0, [r1]\n\ + cmp r0, #0x3\n\ + bls ._551 @cond_branch\n\ + mov r0, #0x0\n\ + strb r0, [r1]\n\ +._551:\n\ + cmp r2, #0\n\ + beq ._552 @cond_branch\n\ + lsl r0, r2, #0x1\n\ + add r0, r0, r2\n\ + lsl r0, r0, #0x2\n\ + add r0, r0, r9\n\ + ldrb r3, [r0, #0x6]\n\ + mov r0, #0x12\n\ + and r0, r0, r3\n\ + cmp r0, #0\n\ + beq ._553 @cond_branch\n\ + mov r1, sl\n\ + ldrb r0, [r1]\n\ + b ._561\n\ +._553:\n\ + ldr r0, ._559 @ gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + mov r0, #0x1\n\ + and r0, r0, r1\n\ + cmp r0, #0\n\ + beq ._557 @cond_branch\n\ + ldr r0, ._559 + 4 @ gUnknown_02023A14_50\n\ + ldrb r1, [r0]\n\ + mov r5, #0x2\n\ + add r0, r5, #0\n\ + and r0, r0, r1\n\ + cmp r0, #0\n\ + beq ._556 @cond_branch\n\ + cmp r3, #0\n\ + bne ._557 @cond_branch\n\ + mov r1, sl\n\ + ldrb r0, [r1]\n\ + bl GetBattlerPosition\n\ + mov r1, #0x2\n\ + eor r0, r0, r1\n\ + lsl r0, r0, #0x18\n\ + lsr r0, r0, #0x18\n\ + b ._558\n\ +._560:\n\ + .align 2, 0\n\ +._559:\n\ + .word gBattleTypeFlags\n\ + .word gUnknown_02023A14_50\n\ +._556:\n\ + bl Random\n\ + add r1, r5, #0\n\ + and r1, r1, r0\n\ + lsl r1, r1, #0x10\n\ + lsr r0, r1, #0x10\n\ + b ._561\n\ +._557:\n\ + mov r0, #0x0\n\ +._558:\n\ + bl GetBattlerAtPosition\n\ + lsl r0, r0, #0x18\n\ + lsr r0, r0, #0x18\n\ +._561:\n\ + lsl r2, r0, #0x8\n\ + orr r2, r2, r4\n\ + mov r0, #0x1\n\ + mov r1, #0xa\n\ +._569:\n\ + bl Emitcmd33\n\ +._573:\n\ + bl OpponentBufferExecCompleted\n\ + b ._562\n\ +._546:\n\ + ldr r0, ._567 @ gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + mov r0, #0x93\n\ + lsl r0, r0, #0x3\n\ + and r0, r0, r1\n\ + cmp r0, #0\n\ + beq ._563 @cond_branch\n\ + bl BattleAI_SetupAIData\n\ + bl BattleAI_GetAIActionToUse\n\ + lsl r0, r0, #0x18\n\ + lsr r4, r0, #0x18\n\ + cmp r4, #0x4\n\ + beq ._564 @cond_branch\n\ + cmp r4, #0x5\n\ + bne ._565 @cond_branch\n\ + mov r0, #0x1\n\ + mov r1, #0x4\n\ + b ._566\n\ +._568:\n\ + .align 2, 0\n\ +._567:\n\ + .word gBattleTypeFlags\n\ +._564:\n\ + mov r0, #0x1\n\ + mov r1, #0x3\n\ +._566:\n\ + mov r2, #0x0\n\ + b ._569\n\ +._565:\n\ + ldr r3, ._574 @ gBattleMoves\n\ + lsl r0, r4, #0x1\n\ + add r2, r5, r0\n\ + ldrh r1, [r2]\n\ + lsl r0, r1, #0x1\n\ + add r0, r0, r1\n\ + lsl r0, r0, #0x2\n\ + add r0, r0, r3\n\ + ldrb r1, [r0, #0x6]\n\ + mov r0, #0x12\n\ + and r0, r0, r1\n\ + cmp r0, #0\n\ + beq ._570 @cond_branch\n\ + ldr r1, ._574 + 4 @ gBankTarget\n\ + ldrb r0, [r6]\n\ + strb r0, [r1]\n\ +._570:\n\ + ldrh r1, [r2]\n\ + lsl r0, r1, #0x1\n\ + add r0, r0, r1\n\ + lsl r0, r0, #0x2\n\ + add r0, r0, r3\n\ + ldrb r1, [r0, #0x6]\n\ + mov r0, #0x8\n\ + and r0, r0, r1\n\ + cmp r0, #0\n\ + beq ._572 @cond_branch\n\ + mov r0, #0x0\n\ + bl GetBattlerAtPosition\n\ + ldr r5, ._574 + 4 @ gBankTarget\n\ + strb r0, [r5]\n\ + ldr r0, ._574 + 8 @ gAbsentBattlerFlags\n\ + ldrb r1, [r0]\n\ + ldr r2, ._574 + 12 @ gBitTable\n\ + ldrb r0, [r5]\n\ + lsl r0, r0, #0x2\n\ + add r0, r0, r2\n\ + ldr r0, [r0]\n\ + and r1, r1, r0\n\ + cmp r1, #0\n\ + beq ._572 @cond_branch\n\ + mov r0, #0x2\n\ + bl GetBattlerAtPosition\n\ + strb r0, [r5]\n\ +._572:\n\ + ldr r0, ._574 + 4 @ gBankTarget\n\ + ldrb r2, [r0]\n\ + lsl r2, r2, #0x8\n\ + orr r2, r2, r4\n\ + mov r0, #0x1\n\ + mov r1, #0xa\n\ + bl Emitcmd33\n\ + b ._573\n\ +._575:\n\ + .align 2, 0\n\ +._574:\n\ + .word gBattleMoves\n\ + .word gBankTarget\n\ + .word gAbsentBattlerFlags\n\ + .word gBitTable\n\ +._563:\n\ + mov r6, #0x3\n\ +._576:\n\ + bl Random\n\ + add r4, r0, #0\n\ + and r4, r4, r6\n\ + lsl r0, r4, #0x1\n\ + add r0, r5, r0\n\ + ldrh r2, [r0]\n\ + cmp r2, #0\n\ + beq ._576 @cond_branch\n\ + ldr r1, ._579 @ gBattleMoves\n\ + lsl r0, r2, #0x1\n\ + add r0, r0, r2\n\ + lsl r0, r0, #0x2\n\ + add r0, r0, r1\n\ + ldrb r1, [r0, #0x6]\n\ + mov r0, #0x12\n\ + and r0, r0, r1\n\ + cmp r0, #0\n\ + beq ._577 @cond_branch\n\ + ldr r0, ._579 + 4 @ gActiveBattler\n\ + ldrb r2, [r0]\n\ + lsl r2, r2, #0x8\n\ + b ._578\n\ +._580:\n\ + .align 2, 0\n\ +._579:\n\ + .word gBattleMoves\n\ + .word gActiveBattler\n\ +._577:\n\ + ldr r0, ._583 @ gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + mov r0, #0x1\n\ + and r0, r0, r1\n\ + cmp r0, #0\n\ + beq ._581 @cond_branch\n\ + bl Random\n\ + mov r1, #0x2\n\ + and r1, r1, r0\n\ + lsl r1, r1, #0x18\n\ + lsr r1, r1, #0x18\n\ + add r0, r1, #0\n\ + bl GetBattlerAtPosition\n\ + add r2, r0, #0\n\ + lsl r2, r2, #0x18\n\ + lsr r2, r2, #0x10\n\ +._578:\n\ + orr r2, r2, r4\n\ + mov r0, #0x1\n\ + mov r1, #0xa\n\ + bl Emitcmd33\n\ + b ._582\n\ +._584:\n\ + .align 2, 0\n\ +._583:\n\ + .word gBattleTypeFlags\n\ +._581:\n\ + mov r0, #0x0\n\ + bl GetBattlerAtPosition\n\ + add r2, r0, #0\n\ + lsl r2, r2, #0x18\n\ + lsr r2, r2, #0x10\n\ + orr r2, r2, r4\n\ + mov r0, #0x1\n\ + mov r1, #0xa\n\ + bl Emitcmd33\n\ +._582:\n\ + bl OpponentBufferExecCompleted\n\ +._562:\n\ + pop {r3, r4, r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov sl, r5\n\ + pop {r4, r5, r6, r7}\n\ + pop {r0}\n\ + bx r0"); +} +#else +#ifdef NONMATCHING +void OpponentHandlecmd20(void) +{ + u16 r4; + // Needed to match closer + struct {u16 moves[4];} *r5 = (void *)&gBattleBufferA[gActiveBattler][4]; + + if (gBattleTypeFlags & 0x498) + { + BattleAI_SetupAIData(); + r4 = BattleAI_GetAIActionToUse(); + switch (r4) + { + case 5: + Emitcmd33(1, 4, 0); + break; + case 4: + Emitcmd33(1, 3, 0); + break; + default: + if (gBattleMoves[r5->moves[r4]].target & 0x12) + gBankTarget = gActiveBattler; + if (gBattleMoves[r5->moves[r4]].target & 8) + { + gBankTarget = GetBattlerAtPosition(0); + if (gAbsentBattlerFlags & gBitTable[gBankTarget]) + gBankTarget = GetBattlerAtPosition(2); + } + r4 |= gBankTarget << 8; + Emitcmd33(1, 10, r4); + break; + } + OpponentBufferExecCompleted(); + } + else + { + u16 r2; + + do + { + // Can't for the life of me get this to match. + r4 = Random() % 4; + r2 = r5->moves[r4]; + } while (r2 == 0); + + if (gBattleMoves[r2].target & 0x12) + { + r4 |= gActiveBattler << 8; + Emitcmd33(1, 10, r4); + } + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + u16 r2 = GetBattlerAtPosition(Random() & 2) << 8; + + Emitcmd33(1, 10, r4 | r2); + } + else + { + u16 r2 = GetBattlerAtPosition(0) << 8; + + Emitcmd33(1, 10, r4 | r2); + } + OpponentBufferExecCompleted(); + } +} +#else +NAKED +void OpponentHandlecmd20(void) +{ + asm(".syntax unified\n\ + push {r4-r6,lr}\n\ + ldr r6, _0803545C @ =gActiveBattler\n\ + ldrb r0, [r6]\n\ + lsls r0, 9\n\ + ldr r1, _08035460 @ =gBattleBufferA+4\n\ + adds r5, r0, r1\n\ + ldr r0, _08035464 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + movs r0, 0x93\n\ + lsls r0, 3\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _080354F8\n\ + bl BattleAI_SetupAIData\n\ + bl BattleAI_GetAIActionToUse\n\ + lsls r0, 24\n\ + lsrs r4, r0, 24\n\ + cmp r4, 0x4\n\ + beq _08035468\n\ + cmp r4, 0x5\n\ + bne _08035474\n\ + movs r0, 0x1\n\ + movs r1, 0x4\n\ + b _0803546C\n\ + .align 2, 0\n\ +_0803545C: .4byte gActiveBattler\n\ +_08035460: .4byte gBattleBufferA+4\n\ +_08035464: .4byte gBattleTypeFlags\n\ +_08035468:\n\ + movs r0, 0x1\n\ + movs r1, 0x3\n\ +_0803546C:\n\ + movs r2, 0\n\ + bl Emitcmd33\n\ + b _080354E0\n\ +_08035474:\n\ + ldr r3, _080354E8 @ =gBattleMoves\n\ + lsls r0, r4, 1\n\ + adds r2, r5, r0\n\ + ldrh r1, [r2]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r3\n\ + ldrb r1, [r0, 0x6]\n\ + movs r0, 0x12\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08035494\n\ + ldr r1, _080354EC @ =gBankTarget\n\ + ldrb r0, [r6]\n\ + strb r0, [r1]\n\ +_08035494:\n\ + ldrh r1, [r2]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r3\n\ + ldrb r1, [r0, 0x6]\n\ + movs r0, 0x8\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _080354CE\n\ + movs r0, 0\n\ + bl GetBattlerAtPosition\n\ + ldr r5, _080354EC @ =gBankTarget\n\ + strb r0, [r5]\n\ + ldr r0, _080354F0 @ =gAbsentBattlerFlags\n\ + ldrb r1, [r0]\n\ + ldr r2, _080354F4 @ =gBitTable\n\ + ldrb r0, [r5]\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldr r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + beq _080354CE\n\ + movs r0, 0x2\n\ + bl GetBattlerAtPosition\n\ + strb r0, [r5]\n\ +_080354CE:\n\ + ldr r0, _080354EC @ =gBankTarget\n\ + ldrb r0, [r0]\n\ + lsls r0, 8\n\ + orrs r4, r0\n\ + movs r0, 0x1\n\ + movs r1, 0xA\n\ + adds r2, r4, 0\n\ + bl Emitcmd33\n\ +_080354E0:\n\ + bl OpponentBufferExecCompleted\n\ + b _0803558A\n\ + .align 2, 0\n\ +_080354E8: .4byte gBattleMoves\n\ +_080354EC: .4byte gBankTarget\n\ +_080354F0: .4byte gAbsentBattlerFlags\n\ +_080354F4: .4byte gBitTable\n\ +_080354F8:\n\ + movs r6, 0x3\n\ +_080354FA:\n\ + bl Random\n\ + adds r4, r0, 0\n\ + ands r4, r6\n\ + lsls r0, r4, 1\n\ + adds r0, r5, r0\n\ + ldrh r2, [r0]\n\ + cmp r2, 0\n\ + beq _080354FA\n\ + ldr r1, _08035534 @ =gBattleMoves\n\ + lsls r0, r2, 1\n\ + adds r0, r2\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r1, [r0, 0x6]\n\ + movs r0, 0x12\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0803553C\n\ + ldr r0, _08035538 @ =gActiveBattler\n\ + ldrb r0, [r0]\n\ + lsls r0, 8\n\ + orrs r4, r0\n\ + movs r0, 0x1\n\ + movs r1, 0xA\n\ + adds r2, r4, 0\n\ + bl Emitcmd33\n\ + b _08035586\n\ + .align 2, 0\n\ +_08035534: .4byte gBattleMoves\n\ +_08035538: .4byte gActiveBattler\n\ +_0803553C:\n\ + ldr r0, _0803556C @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08035570\n\ + bl Random\n\ + movs r1, 0x2\n\ + ands r1, r0\n\ + lsls r1, 24\n\ + lsrs r1, 24\n\ + adds r0, r1, 0\n\ + bl GetBattlerAtPosition\n\ + adds r2, r0, 0\n\ + lsls r2, 24\n\ + lsrs r2, 16\n\ + orrs r2, r4\n\ + movs r0, 0x1\n\ + movs r1, 0xA\n\ + bl Emitcmd33\n\ + b _08035586\n\ + .align 2, 0\n\ +_0803556C: .4byte gBattleTypeFlags\n\ +_08035570:\n\ + movs r0, 0\n\ + bl GetBattlerAtPosition\n\ + adds r2, r0, 0\n\ + lsls r2, 24\n\ + lsrs r2, 16\n\ + orrs r2, r4\n\ + movs r0, 0x1\n\ + movs r1, 0xA\n\ + bl Emitcmd33\n\ +_08035586:\n\ + bl OpponentBufferExecCompleted\n\ +_0803558A:\n\ + pop {r4-r6}\n\ + pop {r0}\n\ + bx r0\n\ + .syntax divided\n"); +} +#endif +#endif + +void OpponentHandleOpenBag(void) +{ + // What is this? + Emitcmd35(1, ewram160D4(gActiveBattler)); + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd22(void) +{ + s32 r4; + + if (ewram160C8arr(GetBattlerPosition(gActiveBattler)) == 6) + { + u8 r6; + u8 r5; + + r4 = GetMostSuitableMonToSwitchInto(); + if (r4 == 6) + { + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + r5 = GetBattlerAtPosition(1); + r6 = r5; + } + else + { + r6 = GetBattlerAtPosition(1); + r5 = GetBattlerAtPosition(3); + } + for (r4 = 0; r4 < 6; r4++) + { + if (GetMonData(&gEnemyParty[r4], MON_DATA_HP) != 0 + && r4 != gBattlerPartyIndexes[r6] + && r4 != gBattlerPartyIndexes[r5]) + break; + } + } + } + else + { + r4 = ewram160C8arr(GetBattlerPosition(gActiveBattler)); + ewram160C8arr(GetBattlerPosition(gActiveBattler)) = 6; + } + ewram16068arr(gActiveBattler) = r4; + Emitcmd34(1, r4, 0); + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd23(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleHealthBarUpdate(void) +{ + s16 r7; + + load_gfxc_health_bar(0); + r7 = (gBattleBufferA[gActiveBattler][3] << 8) | gBattleBufferA[gActiveBattler][2]; + if (r7 != 0x7FFF) + { + u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); + u32 hp = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); + + sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, hp, r7); + } + else + { + u32 maxHP = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); + + sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, 0, r7); + } + gBattleBankFunc[gActiveBattler] = sub_80330C8; +} + +void OpponentHandleExpBarUpdate(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleStatusIconUpdate(void) +{ + if (mplay_80342A4(gActiveBattler) == 0) + { + sub_8045A5C(gHealthboxIDs[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], 9); + ewram17810[gActiveBattler].unk0_4 = 0; + gBattleBankFunc[gActiveBattler] = sub_8033494; + } +} + +void OpponentHandleStatusAnimation(void) +{ + if (mplay_80342A4(gActiveBattler) == 0) + { + move_anim_start_t2_for_situation( + gBattleBufferA[gActiveBattler][1], + gBattleBufferA[gActiveBattler][2] + | (gBattleBufferA[gActiveBattler][3] << 8) + | (gBattleBufferA[gActiveBattler][4] << 16) + | (gBattleBufferA[gActiveBattler][5] << 24)); + gBattleBankFunc[gActiveBattler] = sub_8033494; + } +} + +void OpponentHandleStatusXor(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd29(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleDMATransfer(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd31(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd32(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd33(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd34(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd35(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd36(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd37(void) +{ + gUnknown_020238C8.unk0_0 = 0; + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd38(void) +{ + gUnknown_020238C8.unk0_0 = gBattleBufferA[gActiveBattler][1]; + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd39(void) +{ + gUnknown_020238C8.unk0_7 = 0; + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd40(void) +{ + gUnknown_020238C8.unk0_7 ^= 1; + OpponentBufferExecCompleted(); +} + +void OpponentHandleHitAnimation(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].invisible == TRUE) + { + OpponentBufferExecCompleted(); + } + else + { + gDoingBattleAnim = TRUE; + gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; + sub_8047858(gActiveBattler); + gBattleBankFunc[gActiveBattler] = bx_blink_t7; + } +} + +void OpponentHandlecmd42(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleEffectivenessSound(void) +{ + s8 pan; + + if (GetBattlerSide(gActiveBattler) == 0) + pan = -64; + else + pan = 63; + PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan); + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd44(void) +{ + PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + OpponentBufferExecCompleted(); +} + +void OpponentHandleFaintingCry(void) +{ + PlayCry3( + GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES), + 25, 5); + OpponentBufferExecCompleted(); +} + +void OpponentHandleIntroSlide(void) +{ + StartBattleIntroAnim(gBattleBufferA[gActiveBattler][1]); + gUnknown_02024DE8 |= 1; + OpponentBufferExecCompleted(); +} + +void OpponentHandleTrainerBallThrow(void) +{ + u8 taskId; + + oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 35; + gSprites[gBankSpriteIds[gActiveBattler]].data[2] = 280; + gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; + gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], sub_8035C10); + taskId = CreateTask(sub_8035C44, 5); + gTasks[taskId].data[0] = gActiveBattler; + if (ewram17810[gActiveBattler].unk0_0) + gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; + ewram17840.unk9_0 = 1; + gBattleBankFunc[gActiveBattler] = nullsub_45; +} + +void sub_8035C10(struct Sprite *sprite) +{ + sub_8031B74(sprite->oam.affineParam); + sprite->oam.tileNum = sprite->data[5]; + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); +} + +void sub_8035C44(u8 taskId) +{ + u8 r9; + + r9 = gActiveBattler; + gActiveBattler = gTasks[taskId].data[0]; + if (!IsDoubleBattle() || (gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_803495C(gActiveBattler, 0); + } + else + { + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_803495C(gActiveBattler, 0); + gActiveBattler ^= 2; + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_803495C(gActiveBattler, 0); + gActiveBattler ^= 2; + } + gBattleBankFunc[gActiveBattler] = sub_8032E2C; + gActiveBattler = r9; + DestroyTask(taskId); +} + +void OpponentHandlecmd48(void) +{ + if (gBattleBufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == 0) + { + OpponentBufferExecCompleted(); + return; + } + + ewram17810[gActiveBattler].unk0_0 = 1; + if (gBattleBufferA[gActiveBattler][2] != 0) + { + if (ewram17810[gActiveBattler].unk1_1 < 2) + { + ewram17810[gActiveBattler].unk1_1++; + return; + } + else + { + ewram17810[gActiveBattler].unk1_1 = 0; + } + } + gUnknown_02024E68[gActiveBattler] = sub_8044804( + gActiveBattler, + (struct BattleInterfaceStruct2 *)&gBattleBufferA[gActiveBattler][4], + gBattleBufferA[gActiveBattler][1], + gBattleBufferA[gActiveBattler][2]); + ewram17810[gActiveBattler].unk5 = 0; + if (gBattleBufferA[gActiveBattler][2] != 0) + ewram17810[gActiveBattler].unk5 = 0x5D; + gBattleBankFunc[gActiveBattler] = sub_8035E2C; +} + +void sub_8035E2C(void) +{ + if (ewram17810[gActiveBattler].unk5++ >= 93) + { + ewram17810[gActiveBattler].unk5 = 0; + OpponentBufferExecCompleted(); + } +} + +void OpponentHandlecmd49(void) +{ + if (ewram17810[gActiveBattler].unk0_0) + gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd50(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleSpriteInvisibility(void) +{ + if (IsBankSpritePresent(gActiveBattler) != 0) + { + gSprites[gBankSpriteIds[gActiveBattler]].invisible = gBattleBufferA[gActiveBattler][1]; + sub_8031F88(gActiveBattler); + } + OpponentBufferExecCompleted(); +} + +void OpponentHandleBattleAnimation(void) +{ + if (mplay_80342A4(gActiveBattler) == 0) + { + u8 r3 = gBattleBufferA[gActiveBattler][1]; + u16 r4 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + + if (move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, r3, r4) != 0) + OpponentBufferExecCompleted(); + else + gBattleBankFunc[gActiveBattler] = sub_80334C0; + } +} + +void OpponentHandleLinkStandbyMsg(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandleResetActionMoveSelection(void) +{ + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd55(void) +{ + if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && !(gBattleTypeFlags & BATTLE_TYPE_WILD)) + { + gMain.inBattle = FALSE; + gMain.callback1 = gPreBattleCallback1; + SetMainCallback2(gMain.savedCallback); + } + OpponentBufferExecCompleted(); +} + +void OpponentHandlecmd56(void) +{ +} diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c new file mode 100644 index 000000000..9e9848a18 --- /dev/null +++ b/src/battle_controller_player.c @@ -0,0 +1,3239 @@ +#include "global.h" +#include "data2.h" +#include "battle.h" +#include "battle_anim.h" +#include "battle_anim_special.h" +#include "battle_interface.h" +#include "battle_message.h" +#include "item.h" +#include "constants/items.h" +#include "link.h" +#include "m4a.h" +#include "main.h" +#include "menu_cursor.h" +#include "constants/moves.h" +#include "palette.h" +#include "pokemon.h" +#include "rom3.h" +#include "constants/songs.h" +#include "sound.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "util.h" +#include "ewram.h" + +struct MovePpInfo +{ + u16 moves[4]; + u8 pp[4]; + u8 ppBonuses; +}; + +#if ENGLISH +#define SUB_803037C_TILE_DATA_OFFSET 440 +#elif GERMAN +#define SUB_803037C_TILE_DATA_OFFSET 444 +#endif + +extern struct Window gUnknown_03004210; + +extern void (*gBattleBankFunc[])(void); + +extern u8 gBankAttacker; +extern u8 gBankTarget; +extern u32 gOamMatrixAllocBitmap; +extern u8 gUnknown_020297ED; +extern u8 gActiveBattler; +extern u8 gActionSelectionCursor[]; +extern u8 gDisplayedStringBattle[]; +extern u8 gMoveSelectionCursor[]; +extern u8 gBattleBufferA[][0x200]; +extern u8 gBankInMenu; +extern u16 gBattlerPartyIndexes[]; +extern u8 gHealthboxIDs[]; +extern u8 gDoingBattleAnim; +extern u8 gBankSpriteIds[]; +extern u16 gBattleTypeFlags; +extern u8 gBattleOutcome; +extern void (*gAnimScriptCallback)(void); +extern bool8 gAnimScriptActive; +extern u16 gAnimMovePower; +extern s32 gAnimMoveDmg; +extern u8 gAnimFriendship; +extern u16 gWeatherMoveAnim; +extern u32 gTransformedPersonalities[]; +extern u8 gBattleMonForms[]; +extern u16 gUnknown_02024DE8; +extern u8 gUnknown_02024E68[]; +extern struct SpriteTemplate gUnknown_02024E8C; +extern u8 gAnimMoveTurn; +extern u8 gUnknown_02038470[]; +extern u8 gUnknown_03004344; +extern u8 gUnknown_0300434C[]; + +extern const u8 BattleText_OtherMenu[]; +extern const u8 BattleText_MenuOptions[]; +extern const u8 BattleText_PP[]; + +extern void sub_802C68C(void); +extern void sub_802E1B0(void); +extern void sub_802E220(); +extern void sub_802E2D4(); +extern void sub_802E004(void); +extern void sub_802DF30(void); +extern void BattleStopLowHpSound(void); +extern void PlayerBufferExecCompleted(void); +extern void bx_t1_healthbar_update(void); +extern void nullsub_91(void); +extern void sub_802D924(u8); +extern void sub_802E434(void); +extern bool8 mplay_80342A4(u8); +extern void move_anim_start_t2_for_situation(); +extern void bx_blink_t1(void); +extern void sub_8047858(); +extern u8 GetBattlerSide(u8); +extern void StartBattleIntroAnim(); +extern void oamt_add_pos2_onto_pos1(); +extern void StartAnimLinearTranslation(struct Sprite *); +extern void StoreSpriteCallbackInData(); +extern void BattleLoadPlayerMonSprite(); +extern bool8 IsDoubleBattle(void); +extern void sub_802D500(void); +extern bool8 IsBankSpritePresent(u8); +extern bool8 move_anim_start_t3(); +extern void sub_802E460(void); +extern void b_link_standby_message(void); +extern void sub_802D18C(void); +extern void sub_802DF18(void); +extern void BufferStringBattle(); +extern void sub_80326EC(); +extern void sub_8031F24(void); +extern void sub_80324BC(); +extern u8 sub_8031720(); +extern void bx_wait_t1(void); +extern u8 GetBattlerAtPosition(u8); +extern void sub_802DE10(void); +extern void sub_80105EC(struct Sprite *); +extern void sub_802D274(void); +extern void sub_802D23C(void); +extern u8 GetBattlerPosition(u8); +extern void LoadPlayerTrainerBankSprite(); +extern void sub_80313A0(struct Sprite *); +extern void sub_802D204(void); +extern u8 GetBattlerSubpriority(); +extern void sub_802DEAC(void); +extern void sub_80312F0(struct Sprite *); +extern u8 GetBattlerSpriteCoord(); +extern u8 sub_8077F68(); +extern u8 StartSendOutMonAnimation(); +extern void sub_802D798(void); +extern void bx_0802E404(void); +extern u8 gActiveBattler; +extern void (*gBattleBankFunc[])(void); +extern bool8 gDoingBattleAnim; +extern u16 gBattleTypeFlags; +extern u32 gBattleExecBuffer; +extern u8 gBattleBufferA[][0x200]; +extern u8 gBankSpriteIds[]; +extern u8 gActionSelectionCursor[]; +extern u8 gMoveSelectionCursor[]; +extern u8 gAbsentBattlerFlags; +extern u8 gUnknown_03004344; +extern u8 gBattlersCount; +extern u16 gBattlerPartyIndexes[]; +extern struct Window gUnknown_03004210; +extern const u8 BattleText_SwitchWhich[]; +extern u8 gUnknown_03004348; +extern struct BattlePokemon gBattleMons[]; +extern MainCallback gPreBattleCallback1; +extern u8 gHealthboxIDs[]; +extern struct MusicPlayerInfo gMPlay_BGM; +extern u8 gUnknown_0300434C[]; +extern u8 gUnknown_0202E8F4; +extern u8 gUnknown_0202E8F5; +extern u8 gUnknown_02038470[]; +extern u16 gSpecialVar_ItemId; +extern u8 gDisplayedStringBattle[]; +extern const u8 BattleText_LinkStandby[]; + +extern void dp11b_obj_instanciate(u8, u8, s8, s8); +extern u8 GetBattlerPosition(u8); +extern u8 GetBattlerAtPosition(u8); +extern void dp11b_obj_free(u8, u8); +extern void sub_8010520(struct Sprite *); +extern void sub_8010574(struct Sprite *); +extern bool8 IsDoubleBattle(); +extern void sub_804777C(); +extern void sub_8094E20(u8); +extern void nullsub_14(void); +extern void sub_80A6DCC(void); +extern void ReshowBattleScreenAfterMenu(void); + +void PlayerHandleGetAttributes(void); +void PlayerHandlecmd1(void); +void PlayerHandleSetAttributes(void); +void PlayerHandlecmd3(void); +void PlayerHandleLoadPokeSprite(void); +void PlayerHandleSendOutPoke(void); +void PlayerHandleReturnPokeToBall(void); +void PlayerHandleTrainerThrow(void); +void PlayerHandleTrainerSlide(void); +void PlayerHandleTrainerSlideBack(void); +void PlayerHandlecmd10(void); +void PlayerHandlecmd11(void); +void PlayerHandlecmd12(void); +void PlayerHandleBallThrow(void); +void PlayerHandlePuase(void); +void PlayerHandleMoveAnimation(void); +void PlayerHandlePrintString(void); +void PlayerHandlePrintStringPlayerOnly(void); +void PlayerHandlecmd18(void); +void PlayerHandlecmd19(void); +void PlayerHandlecmd20(void); +void PlayerHandleOpenBag(void); +void PlayerHandlecmd22(void); +void PlayerHandlecmd23(void); +void PlayerHandleHealthBarUpdate(void); +void PlayerHandleExpBarUpdate(void); +void PlayerHandleStatusIconUpdate(void); +void PlayerHandleStatusAnimation(void); +void PlayerHandleStatusXor(void); +void PlayerHandlecmd29(void); +void PlayerHandleDMATransfer(void); +void PlayerHandlecmd31(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 PlayerHandlecmd44(void); +void PlayerHandleFaintingCry(void); +void PlayerHandleIntroSlide(void); +void PlayerHandleTrainerBallThrow(void); +void PlayerHandlecmd48(void); +void PlayerHandlecmd49(void); +void PlayerHandlecmd50(void); +void PlayerHandleSpriteInvisibility(void); +void PlayerHandleBattleAnimation(void); +void PlayerHandleLinkStandbyMsg(void); +void PlayerHandleResetActionMoveSelection(void); +void PlayerHandlecmd55(void); +void PlayerHandlecmd56(void); + +const u8 gString_TurnJP[] = _("ターン"); + +void (*const gPlayerBufferCommands[])(void) = +{ + PlayerHandleGetAttributes, + PlayerHandlecmd1, + PlayerHandleSetAttributes, + PlayerHandlecmd3, + PlayerHandleLoadPokeSprite, + PlayerHandleSendOutPoke, + PlayerHandleReturnPokeToBall, + PlayerHandleTrainerThrow, + PlayerHandleTrainerSlide, + PlayerHandleTrainerSlideBack, + PlayerHandlecmd10, + PlayerHandlecmd11, + PlayerHandlecmd12, + PlayerHandleBallThrow, + PlayerHandlePuase, + PlayerHandleMoveAnimation, + PlayerHandlePrintString, + PlayerHandlePrintStringPlayerOnly, + PlayerHandlecmd18, + PlayerHandlecmd19, + PlayerHandlecmd20, + PlayerHandleOpenBag, + PlayerHandlecmd22, + PlayerHandlecmd23, + PlayerHandleHealthBarUpdate, + PlayerHandleExpBarUpdate, + PlayerHandleStatusIconUpdate, + PlayerHandleStatusAnimation, + PlayerHandleStatusXor, + PlayerHandlecmd29, + PlayerHandleDMATransfer, + PlayerHandlecmd31, + PlayerHandlecmd32, + PlayerHandlecmd33, + PlayerHandlecmd34, + PlayerHandlecmd35, + PlayerHandlecmd36, + PlayerHandlecmd37, + PlayerHandlecmd38, + PlayerHandlecmd39, + PlayerHandlecmd40, + PlayerHandleHitAnimation, + PlayerHandlecmd42, + PlayerHandleEffectivenessSound, + PlayerHandlecmd44, + PlayerHandleFaintingCry, + PlayerHandleIntroSlide, + PlayerHandleTrainerBallThrow, + PlayerHandlecmd48, + PlayerHandlecmd49, + PlayerHandlecmd50, + PlayerHandleSpriteInvisibility, + PlayerHandleBattleAnimation, + PlayerHandleLinkStandbyMsg, + PlayerHandleResetActionMoveSelection, + PlayerHandlecmd55, + PlayerHandlecmd56, +}; + +void PlayerBufferRunCommand(void); +void sub_802C2EC(void); +void sub_802C68C(void); +void sub_802CA60(void); +void sub_802D730(void); +void sub_802DA9C(u8); +void sub_802DB6C(u8); +void sub_802DCB0(u8); +void sub_802DD10(u8); +void sub_802DDC4(u8); +void sub_802DF88(void); +void sub_802E03C(void); +void sub_802E12C(s32, const u8 *); +void sub_802E1B0(void); +void sub_802E220(void); +void sub_802E2D4(void); +void sub_802E3B4(u8, int); +void nullsub_7(u8); +void b_link_standby_message(void); +u32 dp01_getattr_by_ch1_for_player_pokemon_(u8, u8 *); +void dp01_setattr_by_ch1_for_player_pokemon(u8); +void sub_802F934(u8, u8); +void sub_802FB2C(void); +void sub_8030190(void); +void sub_80304A8(void); +void sub_8030E38(struct Sprite *); +void task05_08033660(u8); +void sub_8031064(void); + +void nullsub_91(void) +{ +} + +void SetBankFuncToPlayerBufferRunCommand(void) +{ + gBattleBankFunc[gActiveBattler] = PlayerBufferRunCommand; + gDoingBattleAnim = FALSE; +} + +void PlayerBufferExecCompleted(void) +{ + gBattleBankFunc[gActiveBattler] = PlayerBufferRunCommand; + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + u8 playerId = GetMultiplayerId(); + + PrepareBufferDataTransferLink(2, 4, &playerId); + gBattleBufferA[gActiveBattler][0] = 0x38; + } + else + { + gBattleExecBuffer &= ~gBitTable[gActiveBattler]; + } +} + +void PlayerBufferRunCommand(void) +{ + if (gBattleExecBuffer & gBitTable[gActiveBattler]) + { + if (gBattleBufferA[gActiveBattler][0] < 0x39) + gPlayerBufferCommands[gBattleBufferA[gActiveBattler][0]](); + else + PlayerBufferExecCompleted(); + } +} + +void bx_0802E404(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].pos2.x == 0) + PlayerBufferExecCompleted(); +} + +void sub_802C098(void) +{ + u16 itemId = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + + dp11b_obj_instanciate(gActiveBattler, 1, 7, 1); + dp11b_obj_instanciate(gActiveBattler, 0, 7, 1); + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + DestroyMenuCursor(); + + // Useless switch statement. + switch (gActionSelectionCursor[gActiveBattler]) + { + case 0: + Emitcmd33(1, 0, 0); + break; + case 1: + Emitcmd33(1, 1, 0); + break; + case 2: + Emitcmd33(1, 2, 0); + break; + case 3: + Emitcmd33(1, 3, 0); + break; + } + PlayerBufferExecCompleted(); + } + else if (gMain.newKeys & DPAD_LEFT) + { + if (gActionSelectionCursor[gActiveBattler] & 1) + { + PlaySE(SE_SELECT); + nullsub_8(gActionSelectionCursor[gActiveBattler]); + gActionSelectionCursor[gActiveBattler] ^= 1; + sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); + } + } + else if (gMain.newKeys & DPAD_RIGHT) + { + if (!(gActionSelectionCursor[gActiveBattler] & 1)) + { + PlaySE(SE_SELECT); + nullsub_8(gActionSelectionCursor[gActiveBattler]); + gActionSelectionCursor[gActiveBattler] ^= 1; + sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); + } + } + else if (gMain.newKeys & DPAD_UP) + { + if (gActionSelectionCursor[gActiveBattler] & 2) + { + PlaySE(SE_SELECT); + nullsub_8(gActionSelectionCursor[gActiveBattler]); + gActionSelectionCursor[gActiveBattler] ^= 2; + sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); + } + } + else if (gMain.newKeys & DPAD_DOWN) + { + if (!(gActionSelectionCursor[gActiveBattler] & 2)) + { + PlaySE(SE_SELECT); + nullsub_8(gActionSelectionCursor[gActiveBattler]); + gActionSelectionCursor[gActiveBattler] ^= 2; + sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); + } + } + else if (gMain.newKeys & B_BUTTON) + { + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + && GetBattlerPosition(gActiveBattler) == 2 + && !(gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(0)]) + && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + if (gBattleBufferA[gActiveBattler][1] == 1) + { + // Add item to bag if it is a ball + if (itemId <= ITEM_PREMIER_BALL) + AddBagItem(itemId, 1); + else + return; + } + PlaySE(SE_SELECT); + Emitcmd33(1, 12, 0); + PlayerBufferExecCompleted(); + DestroyMenuCursor(); + } + } + else if (gMain.newKeys & START_BUTTON) + { + sub_804454C(); + } +} + +void unref_sub_802C2B8(void) +{ + dp11b_obj_free(gActiveBattler, 1); + dp11b_obj_free(gActiveBattler, 0); + gBattleBankFunc[gActiveBattler] = sub_802C2EC; +} + +// TODO: fix this function +void sub_802C2EC(void) +{ + u8 arr[4] = {0, 2, 3, 1}; + s32 i; + + dp11b_obj_instanciate(gUnknown_03004344, 1, 15, 1); + i = 0; + if (gBattlersCount != 0) + { + do + { + if (i != gUnknown_03004344) + dp11b_obj_free(i, 1); + i++; + } while (i < gBattlersCount); + } + if (gMain.newKeys & A_BUTTON) + { + DestroyMenuCursor(); + PlaySE(SE_SELECT); + gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010574; + Emitcmd33(1, 10, gMoveSelectionCursor[gActiveBattler] | (gUnknown_03004344 << 8)); + dp11b_obj_free(gUnknown_03004344, 1); + PlayerBufferExecCompleted(); + } + //_0802C3A8 + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010574; + gBattleBankFunc[gActiveBattler] = sub_802C68C; + dp11b_obj_instanciate(gActiveBattler, 1, 7, 1); + dp11b_obj_instanciate(gActiveBattler, 0, 7, 1); + dp11b_obj_free(gUnknown_03004344, 1); + } + else if (gMain.newKeys & 0x60) + { + PlaySE(SE_SELECT); + gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010574; + do + { + u8 var = GetBattlerPosition(gUnknown_03004344); + + for (i = 0; i < 4; i++) + { + if (var == arr[i]) + break; + } + do + { + i--; + if (i < 0) + i = 3; + gUnknown_03004344 = GetBattlerAtPosition(arr[i]); + } while(gUnknown_03004344 == gBattlersCount); + i = 0; + switch (GetBattlerPosition(gUnknown_03004344)) + { + case 0: + case 2: + if (gActiveBattler == gUnknown_03004344) + { + u32 moveId; + + asm("":::"memory"); + moveId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler]); + if (!(gBattleMoves[moveId].target & 2)) + break; + } + i++; + break; + case 1: + case 3: + i++; + } + //_0802C500 + if (gAbsentBattlerFlags & gBitTable[gUnknown_03004344]) + i = 0; + } while (i == 0); + gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010520; + } + //_0802C540 + else if (gMain.newKeys & 0x90) + { + PlaySE(SE_SELECT); + gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010574; + do + { + u8 var = GetBattlerPosition(gUnknown_03004344); + + for (i = 0; i < 4; i++) + { + if (var == arr[i]) + break; + } + do + { + i++; + if (i > 3) + i = 0; + gUnknown_03004344 = GetBattlerAtPosition(arr[i]); + } while (gUnknown_03004344 == gBattlersCount); + i = 0; + switch (GetBattlerPosition(gUnknown_03004344)) + { + case 0: + case 2: + if (gActiveBattler == gUnknown_03004344) + { + u32 moveId; + + asm("":::"memory"); + moveId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + gMoveSelectionCursor[gActiveBattler]); + if (!(gBattleMoves[moveId].target & 2)) + break; + } + i++; + break; + case 1: + case 3: + i++; + } + if (gAbsentBattlerFlags & gBitTable[gUnknown_03004344]) + i = 0; + } while (i == 0); + gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010520; + } +} + +struct ChooseMoveStruct +{ + u16 moves[4]; + u8 pp[4]; + u8 unkC[0x12-0xC]; + u8 unk12; + u8 effectStringId; + u8 filler14[0x20-0x14]; +}; + +const u8 gUnknown_081FAE80[] = _("{PALETTE 5}{COLOR_HIGHLIGHT_SHADOW WHITE LIGHT_BLUE WHITE2}"); + +void debug_sub_8030C24(void); + +void sub_802C68C(void) +{ + u32 r8 = 0; +#if DEBUG + u8 count = 0; +#endif + struct ChooseMoveStruct *r6 = (struct ChooseMoveStruct *)(gBattleBufferA[gActiveBattler] + 4); + + if (gMain.newKeys & A_BUTTON) + { + u32 r4; + + PlaySE(SE_SELECT); + + if (r6->moves[gMoveSelectionCursor[gActiveBattler]] == MOVE_CURSE) + r4 = (r6->unk12 != TYPE_GHOST && (r6->effectStringId ^ 7)) ? 0x10 : 0; + else + r4 = gBattleMoves[r6->moves[gMoveSelectionCursor[gActiveBattler]]].target; + + if (r4 & 0x10) + gUnknown_03004344 = gActiveBattler; + else + gUnknown_03004344 = GetBattlerAtPosition((GetBattlerPosition(gActiveBattler) & 1) ^ 1); + + if (gBattleBufferA[gActiveBattler][1] == 0) + { + if ((r4 & 2) && gBattleBufferA[gActiveBattler][2] == 0) + r8++; + } + else + { + if (!(r4 & 0x7D)) + r8++; + if (r6->pp[gMoveSelectionCursor[gActiveBattler]] == 0) + { + r8 = 0; + } + else if (!(r4 & 0x12) && CountAliveMons(0) <= 1) + { + gUnknown_03004344 = sub_803C434(gActiveBattler); + r8 = 0; + } + } + if (r8 == 0) + { + DestroyMenuCursor(); + Emitcmd33(1, 10, gMoveSelectionCursor[gActiveBattler] | (gUnknown_03004344 << 8)); + PlayerBufferExecCompleted(); + } + else + { + gBattleBankFunc[gActiveBattler] = sub_802C2EC; + if (r4 & 0x12) + gUnknown_03004344 = gActiveBattler; + else if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(1)]) + gUnknown_03004344 = GetBattlerAtPosition(3); + else + gUnknown_03004344 = GetBattlerAtPosition(1); + gSprites[gBankSpriteIds[gUnknown_03004344]].callback = sub_8010520; + } + } + else if (gMain.newKeys & B_BUTTON) + { + DestroyMenuCursor(); + PlaySE(SE_SELECT); + gBattle_BG0_X = 0; + gBattle_BG0_Y = 320; + Emitcmd33(1, 10, 0xFFFF); + PlayerBufferExecCompleted(); + } + else if (gMain.newKeys & DPAD_LEFT) + { + if (gMoveSelectionCursor[gActiveBattler] & 1) + { + nullsub_7(gMoveSelectionCursor[gActiveBattler]); + gMoveSelectionCursor[gActiveBattler] ^= 1; + PlaySE(SE_SELECT); + sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); + sub_802E220(); + sub_802E2D4(); + } + } + else if (gMain.newKeys & DPAD_RIGHT) + { + if (!(gMoveSelectionCursor[gActiveBattler] & 1) + && (gMoveSelectionCursor[gActiveBattler] ^ 1) < gUnknown_03004348) + { + nullsub_7(gMoveSelectionCursor[gActiveBattler]); + gMoveSelectionCursor[gActiveBattler] ^= 1; + PlaySE(SE_SELECT); + sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); + sub_802E220(); + sub_802E2D4(); + } + } + else if (gMain.newKeys & DPAD_UP) + { + if (gMoveSelectionCursor[gActiveBattler] & 2) + { + nullsub_7(gMoveSelectionCursor[gActiveBattler]); + gMoveSelectionCursor[gActiveBattler] ^= 2; + PlaySE(SE_SELECT); + sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); + sub_802E220(); + sub_802E2D4(); + } + } + else if (gMain.newKeys & DPAD_DOWN) + { + if (!(gMoveSelectionCursor[gActiveBattler] & 2) + && (gMoveSelectionCursor[gActiveBattler] ^ 2) < gUnknown_03004348) + { + nullsub_7(gMoveSelectionCursor[gActiveBattler]); + gMoveSelectionCursor[gActiveBattler] ^= 2; + PlaySE(SE_SELECT); + sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); + sub_802E220(); + sub_802E2D4(); + } + } + else if (gMain.newKeys & SELECT_BUTTON) + { + if (gUnknown_03004348 > 1 && !(gBattleTypeFlags & BATTLE_TYPE_LINK)) + { + sub_802E12C(gMoveSelectionCursor[gActiveBattler], gUnknown_081FAE80); + if (gMoveSelectionCursor[gActiveBattler] != 0) + gUnknown_03004344 = 0; + else + gUnknown_03004344 = gMoveSelectionCursor[gActiveBattler] + 1; + sub_802E3B4(gUnknown_03004344, 27); + Text_FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x37, 0x1C, 0x3A); + Text_InitWindow(&gUnknown_03004210, BattleText_SwitchWhich, 0x290, 0x17, 0x37); + Text_PrintWindow8002F44(&gUnknown_03004210); + gBattleBankFunc[gActiveBattler] = sub_802CA60; + } + } +#if DEBUG + else if (gUnknown_020297ED == 1 && (gMain.newKeys & START_BUTTON)) + { + const u8 *moveName; + s32 i; + + Text_FillWindowRect(&gUnknown_03004210, 0x1016, 1, 0x37, 16, 0x3A); + moveName = gMoveNames[GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1)]; + Text_InitWindowAndPrintText(&gUnknown_03004210, moveName, 0x100, 2, 0x37); + ConvertIntToDecimalStringN( + gDisplayedStringBattle, + GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1), + 2, 3); + Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 0x110, 10, 0x37); + Text_InitWindowAndPrintText(&gUnknown_03004210, gString_TurnJP, 0x116, 1, 0x39); + ConvertIntToDecimalStringN(gDisplayedStringBattle, gAnimMoveTurn, 2, 3); + Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 0x11C, 4, 0x39); + for (i = 0; i < 64; i++) + { + if (gSprites[i].inUse) + count++; + } + ConvertIntToDecimalStringN(gDisplayedStringBattle, count, 2, 2); + Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 0x122, 8, 0x39); + count = GetTaskCount(); + ConvertIntToDecimalStringN(gDisplayedStringBattle, count, 2, 2); + Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 0x126, 11, 0x39); + for (i = 0, count = 0; i < 32; i++) + { + if (gOamMatrixAllocBitmap & (1 << i)) + count++; + } + ConvertIntToDecimalStringN(gDisplayedStringBattle, count, 2, 2); + Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 0x12A, 14, 0x39); + gBattleBankFunc[gActiveBattler] = debug_sub_8030C24; + } +#endif +} + +extern const u8 BattleText_Format[]; + +void sub_802CA60(void) +{ + u8 perMovePPBonuses[4]; + struct + { + u16 moves[4]; + u8 pp[4]; + u8 filler18[8]; // what is this? + } sp0; + //struct ChooseMoveStruct sp0; + u8 totalPPBonuses; + + if (gMain.newKeys & (A_BUTTON | SELECT_BUTTON)) + { + PlaySE(SE_SELECT); + if (gMoveSelectionCursor[gActiveBattler] != gUnknown_03004344) + { + struct ChooseMoveStruct *r9 = (struct ChooseMoveStruct *)&gBattleBufferA[gActiveBattler][4]; + s32 i; + + i = r9->moves[gMoveSelectionCursor[gActiveBattler]]; + r9->moves[gMoveSelectionCursor[gActiveBattler]] = r9->moves[gUnknown_03004344]; + r9->moves[gUnknown_03004344] = i; + + i = r9->pp[gMoveSelectionCursor[gActiveBattler]]; + r9->pp[gMoveSelectionCursor[gActiveBattler]] = r9->pp[gUnknown_03004344]; + r9->pp[gUnknown_03004344] = i; + + i = r9->unkC[gMoveSelectionCursor[gActiveBattler]]; + r9->unkC[gMoveSelectionCursor[gActiveBattler]] = r9->unkC[gUnknown_03004344]; + r9->unkC[gUnknown_03004344] = i; + + if (gDisableStructs[gActiveBattler].unk18_b & gBitTable[gMoveSelectionCursor[gActiveBattler]]) + { + gDisableStructs[gActiveBattler].unk18_b &= ~gBitTable[gMoveSelectionCursor[gActiveBattler]]; + gDisableStructs[gActiveBattler].unk18_b |= gBitTable[gUnknown_03004344]; + } + + sub_802E1B0(); + + for (i = 0; i < 4; i++) + perMovePPBonuses[i] = (gBattleMons[gActiveBattler].ppBonuses & (3 << (i * 2))) >> (i * 2); + totalPPBonuses = perMovePPBonuses[gMoveSelectionCursor[gActiveBattler]]; + perMovePPBonuses[gMoveSelectionCursor[gActiveBattler]] = perMovePPBonuses[gUnknown_03004344]; + perMovePPBonuses[gUnknown_03004344] = totalPPBonuses; + + totalPPBonuses = 0; + for (i = 0; i < 4; i++) + totalPPBonuses |= perMovePPBonuses[i] << (i * 2); + gBattleMons[gActiveBattler].ppBonuses = totalPPBonuses; + + for (i = 0; i < 4; i++) + { + gBattleMons[gActiveBattler].moves[i] = r9->moves[i]; + gBattleMons[gActiveBattler].pp[i] = r9->pp[i]; + } + if (!(gBattleMons[gActiveBattler].status2 & 0x200000)) + { + for (i = 0; i < 4; i++) + { + sp0.moves[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + i); + sp0.pp[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_PP1 + i); + } + + totalPPBonuses = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_PP_BONUSES); + for (i = 0; i < 4; i++) + perMovePPBonuses[i] = (totalPPBonuses & (3 << (i * 2))) >> (i * 2); + + i = sp0.moves[gMoveSelectionCursor[gActiveBattler]]; + sp0.moves[gMoveSelectionCursor[gActiveBattler]] = sp0.moves[gUnknown_03004344]; + sp0.moves[gUnknown_03004344] = i; + + i = sp0.pp[gMoveSelectionCursor[gActiveBattler]]; + sp0.pp[gMoveSelectionCursor[gActiveBattler]] = sp0.pp[gUnknown_03004344]; + sp0.pp[gUnknown_03004344] = i; + + totalPPBonuses = perMovePPBonuses[gMoveSelectionCursor[gActiveBattler]]; + perMovePPBonuses[gMoveSelectionCursor[gActiveBattler]] = perMovePPBonuses[gUnknown_03004344]; + perMovePPBonuses[gUnknown_03004344] = totalPPBonuses; + + totalPPBonuses = 0; + for (i = 0; i < 4; i++) + totalPPBonuses |= perMovePPBonuses[i] << (i * 2); + + for (i = 0; i < 4; i++) + { + SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + i, &sp0.moves[i]); + SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_PP1 + i, &sp0.pp[i]); + } + SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_PP_BONUSES, &totalPPBonuses); + } + } + else + { + sub_802E12C(gUnknown_03004344, BattleText_Format); + } + gBattleBankFunc[gActiveBattler] = sub_802C68C; + gMoveSelectionCursor[gActiveBattler] = gUnknown_03004344; + sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); + Text_FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x37, 0x1C, 0x3A); + Text_InitWindow(&gUnknown_03004210, BattleText_PP, 0x290, 0x17, 0x37); + Text_PrintWindow8002F44(&gUnknown_03004210); + sub_802E220(); + sub_802E2D4(); + } + if (gMain.newKeys & (B_BUTTON | SELECT_BUTTON)) + { + PlaySE(SE_SELECT); + nullsub_7(gUnknown_03004344); + sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); + sub_802E12C(gMoveSelectionCursor[gActiveBattler], BattleText_Format); + gBattleBankFunc[gActiveBattler] = sub_802C68C; + Text_FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x37, 0x1C, 0x3A); + Text_InitWindow(&gUnknown_03004210, BattleText_PP, 0x290, 0x17, 0x37); + Text_PrintWindow8002F44(&gUnknown_03004210); + sub_802E220(); + sub_802E2D4(); + } + if ((gMain.newKeys & DPAD_LEFT) && (gUnknown_03004344 & 1)) + { + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) + sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0x1D); + else + nullsub_7(gUnknown_03004344); + gUnknown_03004344 ^= 1; + PlaySE(SE_SELECT); + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) + sub_802E3B4(gUnknown_03004344, 0); + else + sub_802E3B4(gUnknown_03004344, 0x1B); + } + if ((gMain.newKeys & DPAD_RIGHT) && !(gUnknown_03004344 & 1) && (gUnknown_03004344 ^ 1) < gUnknown_03004348) + { + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) + sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0x1D); + else + nullsub_7(gUnknown_03004344); + gUnknown_03004344 ^= 1; + PlaySE(SE_SELECT); + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) + sub_802E3B4(gUnknown_03004344, 0); + else + sub_802E3B4(gUnknown_03004344, 0x1B); + } + if ((gMain.newKeys & DPAD_UP) && (gUnknown_03004344 & 2)) + { + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) + sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0x1D); + else + nullsub_7(gUnknown_03004344); + gUnknown_03004344 ^= 2; + PlaySE(SE_SELECT); + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) + sub_802E3B4(gUnknown_03004344, 0); + else + sub_802E3B4(gUnknown_03004344, 0x1B); + } + if ((gMain.newKeys & DPAD_DOWN) && !(gUnknown_03004344 & 2) && (gUnknown_03004344 ^ 2) < gUnknown_03004348) + { + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) + sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0x1D); + else + nullsub_7(gUnknown_03004344); + gUnknown_03004344 ^= 2; + PlaySE(SE_SELECT); + if (gUnknown_03004344 == gMoveSelectionCursor[gActiveBattler]) + sub_802E3B4(gUnknown_03004344, 0); + else + sub_802E3B4(gUnknown_03004344, 0x1B); + } +} + +void sub_802D148(void) +{ + if (gReceivedRemoteLinkPlayers == 0) + { + m4aSongNumStop(SE_HINSI); + gMain.inBattle = FALSE; + gMain.callback1 = gPreBattleCallback1; + SetMainCallback2(c2_8011A1C); + } +} + +void sub_802D18C(void) +{ + if (!gPaletteFade.active) + { + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + sub_800832C(); + gBattleBankFunc[gActiveBattler] = sub_802D148; + } + else + { + m4aSongNumStop(SE_HINSI); + gMain.inBattle = FALSE; + gMain.callback1 = gPreBattleCallback1; + SetMainCallback2(gMain.savedCallback); + } + } +} + +#if DEBUG + +void debug_sub_803107C(void); + +void debug_sub_8030C24(void) +{ + s16 move = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1); + + switch (gMain.newAndRepeatedKeys) + { + case START_BUTTON: + dp11b_obj_free(gActiveBattler, 1); + dp11b_obj_free(gActiveBattler, 0); + gBankAttacker = gActiveBattler; + if ((gMain.heldKeysRaw & B_BUTTON) && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + gBankTarget = gBankAttacker ^ 2; + else if ((gMain.heldKeysRaw & A_BUTTON) && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + gBankTarget = GetBattlerAtPosition(3); + else + gBankTarget = GetBattlerAtPosition(1); + sub_80326EC(0); + DoMoveAnim(move); + gBattleBankFunc[gActiveBattler] = debug_sub_803107C; + break; + case SELECT_BUTTON: + dp11b_obj_free(gActiveBattler, 1); + dp11b_obj_free(gActiveBattler, 0); + gBankTarget = gActiveBattler; + if ((gMain.heldKeysRaw & B_BUTTON) && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + gBankAttacker = gBankTarget ^ 2; + else if ((gMain.heldKeysRaw & A_BUTTON) && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + gBankAttacker = GetBattlerAtPosition(3); + else + gBankAttacker = GetBattlerAtPosition(1); + sub_80326EC(0); + DoMoveAnim(move); + gBattleBankFunc[gActiveBattler] = debug_sub_803107C; + break; + case R_BUTTON: + if ((gMain.heldKeysRaw & B_BUTTON) && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + dp11b_obj_free(gActiveBattler, 1); + dp11b_obj_free(gActiveBattler, 0); + gBankAttacker = GetBattlerAtPosition(3); + gBankTarget = GetBattlerAtPosition(1); + sub_80326EC(0); + DoMoveAnim(move); + gBattleBankFunc[gActiveBattler] = debug_sub_803107C; + } + else + { + move += 9; + case DPAD_RIGHT: + if (++move > 354) + move = 1; + SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1, &move); + gBattleMons[gActiveBattler].moves[0] = move; + Text_FillWindowRect(&gUnknown_03004210, 0x1016, 1, 0x37, 16, 0x38); + Text_InitWindowAndPrintText(&gUnknown_03004210, gMoveNames[move], 0x100, 2, 0x37); + ConvertIntToDecimalStringN(gDisplayedStringBattle, move, 2, 3); + Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 272, 10, 0x37); + } + break; + case L_BUTTON: + if ((gMain.heldKeysRaw & B_BUTTON) && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + dp11b_obj_free(gActiveBattler, 1); + dp11b_obj_free(gActiveBattler, 0); + gBankAttacker = GetBattlerAtPosition(1); + gBankTarget = GetBattlerAtPosition(3); + sub_80326EC(0); + DoMoveAnim(move); + gBattleBankFunc[gActiveBattler] = debug_sub_803107C; + } + else + { + move -= 9; + case DPAD_LEFT: + if (--move <= 0) + move = 354; + SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1, &move); + gBattleMons[gActiveBattler].moves[0] = move; + Text_FillWindowRect(&gUnknown_03004210, 0x1016, 1, 0x37, 16, 0x38); + Text_InitWindowAndPrintText(&gUnknown_03004210, gMoveNames[move], 0x100, 2, 0x37); + ConvertIntToDecimalStringN(gDisplayedStringBattle, move, 2, 3); + Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 272, 10, 0x37); + } + break; + case DPAD_UP: + case DPAD_DOWN: + if (gMain.newAndRepeatedKeys == DPAD_UP) + gAnimMoveTurn--; + else + gAnimMoveTurn++; + ConvertIntToDecimalStringN(gDisplayedStringBattle, gAnimMoveTurn, 2, 3); + Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 284, 4, 0x39); + break; + } + + if ((gMain.heldKeysRaw & (L_BUTTON | R_BUTTON)) == (L_BUTTON | R_BUTTON)) + { + u8 i; + u32 move; + + for (i = 0; i < 4; i++) + { + StringCopy(gDisplayedStringBattle, BattleText_Format); + move = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MOVE1 + i); + StringAppend(gDisplayedStringBattle, gMoveNames[move]); + Text_InitWindow( + &gUnknown_03004210, + gDisplayedStringBattle, + 0x100 + i * 16, + (i & 1) ? 10 : 2, + (i < 2) ? 0x37 : 0x39); + Text_PrintWindow8002F44(&gUnknown_03004210); + } + gBattleBankFunc[gActiveBattler] = sub_802C68C; + } +} + +void debug_sub_803107C(void) +{ + u8 count = 0; + + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + s32 i; + + sub_80326EC(1); + dp11b_obj_instanciate(gActiveBattler, 1, 7, 1); + dp11b_obj_instanciate(gActiveBattler, 0, 7, 1); + + for (i = 0, count = 0; i < MAX_SPRITES; i++) + { + if (gSprites[i].inUse) + count++; + } + ConvertIntToDecimalStringN(gDisplayedStringBattle, count, 2, 2); + Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 290, 8, 0x39); + + count = GetTaskCount(); + ConvertIntToDecimalStringN(gDisplayedStringBattle, count, 2, 2); + Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 294, 11, 0x39); + + for (i = 0, count = 0; i < 32; i++) + { + if (gOamMatrixAllocBitmap & (1 << i)) + count++; + } + ConvertIntToDecimalStringN(gDisplayedStringBattle, count, 2, 2); + Text_InitWindowAndPrintText(&gUnknown_03004210, gDisplayedStringBattle, 298, 14, 0x39); + + gBattleBankFunc[gActiveBattler] = debug_sub_8030C24; + } +} + +#endif + +void sub_802D204(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + PlayerBufferExecCompleted(); +} + +// duplicate of sub_802D204 +void sub_802D23C(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + PlayerBufferExecCompleted(); +} + +void sub_802D274(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + { + nullsub_10(gSaveBlock2.playerGender); + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + PlayerBufferExecCompleted(); + } +} + +void sub_802D2E0(void) +{ + if (--ewram17810[gActiveBattler].unk9 == 0xFF) + { + ewram17810[gActiveBattler].unk9 = 0; + PlayerBufferExecCompleted(); + } +} + +void sub_802D31C(void) +{ + bool8 r6 = FALSE; + + if (!IsDoubleBattle() || (IsDoubleBattle() && (gBattleTypeFlags & BATTLE_TYPE_MULTI))) + { + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) + r6 = TRUE; + } + else + { + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy + && gSprites[gHealthboxIDs[gActiveBattler ^ 2]].callback == SpriteCallbackDummy) + r6 = TRUE; + } + if (IsCryPlayingOrClearCrySongs()) + r6 = FALSE; + + if (r6 && ewram17810[gActiveBattler].unk1_0 && ewram17810[gActiveBattler ^ 2].unk1_0) + { + ewram17810[gActiveBattler].unk0_7 = 0; + ewram17810[gActiveBattler].unk1_0 = 0; + ewram17810[gActiveBattler ^ 2].unk0_7 = 0; + ewram17810[gActiveBattler ^ 2].unk1_0 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + m4aMPlayContinue(&gMPlay_BGM); + else + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 256); + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + if (IsDoubleBattle()) + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], gActiveBattler ^ 2); + ewram17810[gActiveBattler].unk9 = 3; + gBattleBankFunc[gActiveBattler] = sub_802D2E0; + } +} + +void sub_802D500(void) +{ + if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) + sub_8141828(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + if (!ewram17810[gActiveBattler ^ 2].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_7) + sub_8141828(gActiveBattler ^ 2, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ 2]]); + if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_3) + { + if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler ^ 2]]); + sub_8045A5C( + gHealthboxIDs[gActiveBattler ^ 2], + &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], + 0); + sub_804777C(gActiveBattler ^ 2); + sub_8043DFC(gHealthboxIDs[gActiveBattler ^ 2]); + } + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); + sub_8045A5C( + gHealthboxIDs[gActiveBattler], + &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], + 0); + sub_804777C(gActiveBattler); + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + ewram17840.unk9_0 = 0; + gBattleBankFunc[gActiveBattler] = sub_802D31C; + } +} + +void sub_802D680(void) +{ + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy + && ewram17810[gActiveBattler].unk1_0) + { + ewram17810[gActiveBattler].unk0_7 = 0; + ewram17810[gActiveBattler].unk1_0 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + if (ewram17800[gActiveBattler].substituteSprite) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); + gBattleBankFunc[gActiveBattler] = sub_802D730; + } +} + +void sub_802D730(void) +{ + if (!ewram17810[gActiveBattler].unk0_6 && !IsCryPlayingOrClearCrySongs()) + { + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + PlayerBufferExecCompleted(); + } +} + +void sub_802D798(void) +{ + if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) + sub_8141828(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + if (gSprites[gUnknown_0300434C[gActiveBattler]].callback == SpriteCallbackDummy + && !ewram17810[gActiveBattler].unk0_3) + { + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); + sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 0); + sub_804777C(gActiveBattler); + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + sub_8031F88(gActiveBattler); + gBattleBankFunc[gActiveBattler] = sub_802D680; + } +} + +void c3_0802FDF4(u8 taskId) +{ + if (!IsCryPlayingOrClearCrySongs()) + { + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 0x100); + DestroyTask(taskId); + } +} + +void bx_t1_healthbar_update(void) +{ + s16 r4 = sub_8045C78(gActiveBattler, gHealthboxIDs[gActiveBattler], 0, 0); + + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + if (r4 != -1) + { + sub_80440EC(gHealthboxIDs[gActiveBattler], r4, 0); + } + else + { + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + PlayerBufferExecCompleted(); + } +} + +void sub_802D90C(void) +{ + if (gUnknown_03004210.state == 0) + PlayerBufferExecCompleted(); +} + +// Rare Candy usage, maybe? +void sub_802D924(u8 taskId) +{ + u32 pkmnIndex = (u8)gTasks[taskId].data[0]; + u8 bank = gTasks[taskId].data[2]; + s16 gainedExp = gTasks[taskId].data[1]; + + if (IsDoubleBattle() == TRUE || pkmnIndex != gBattlerPartyIndexes[bank]) + { + struct Pokemon *pkmn = &gPlayerParty[pkmnIndex]; + u16 species = GetMonData(pkmn, MON_DATA_SPECIES); + u8 level = GetMonData(pkmn, MON_DATA_LEVEL); + u32 currExp = GetMonData(pkmn, MON_DATA_EXP); + u32 nextLvlExp = gExperienceTables[gBaseStats[species].growthRate][level + 1]; + + if (currExp + gainedExp >= nextLvlExp) + { + u8 savedActiveBank; + + SetMonData(pkmn, MON_DATA_EXP, &nextLvlExp); + CalculateMonStats(pkmn); + gainedExp -= nextLvlExp - currExp; + savedActiveBank = gActiveBattler; + gActiveBattler = bank; + Emitcmd33(1, 11, gainedExp); + gActiveBattler = savedActiveBank; + + if (IsDoubleBattle() == TRUE + && ((u16)pkmnIndex == gBattlerPartyIndexes[bank] || (u16)pkmnIndex == gBattlerPartyIndexes[bank ^ 2])) + gTasks[taskId].func = sub_802DCB0; + else + gTasks[taskId].func = sub_802DDC4; + } + else + { + currExp += gainedExp; + SetMonData(pkmn, MON_DATA_EXP, &currExp); + gBattleBankFunc[bank] = sub_802D90C; + DestroyTask(taskId); + } + } + else + { + gTasks[taskId].func = sub_802DA9C; + } +} + +void sub_802DA9C(u8 taskId) +{ + u8 pkmnIndex = gTasks[taskId].data[0]; + s32 r9 = gTasks[taskId].data[1]; + u8 bank = gTasks[taskId].data[2]; + struct Pokemon *pkmn = &gPlayerParty[pkmnIndex]; + u8 level = GetMonData(pkmn, MON_DATA_LEVEL); + u16 species = GetMonData(pkmn, MON_DATA_SPECIES); + u32 exp = GetMonData(pkmn, MON_DATA_EXP); + u32 currLvlExp = gExperienceTables[gBaseStats[species].growthRate][level]; + u32 expToNextLvl; + + exp -= currLvlExp; + expToNextLvl = gExperienceTables[gBaseStats[species].growthRate][level + 1] - currLvlExp; + sub_8043D84(bank, gHealthboxIDs[bank], expToNextLvl, exp, -r9); + PlaySE(SE_EXP); + gTasks[taskId].func = sub_802DB6C; +} + +#ifdef NONMATCHING +void sub_802DB6C(u8 taskId) +{ + if (gTasks[taskId].data[10] < 13) + { + gTasks[taskId].data[10]++; + } + else + { + u8 r9 = gTasks[taskId].data[0]; + s32 r10 = gTasks[taskId].data[1]; //s16? + u8 r7 = gTasks[taskId].data[2]; + s16 r4; + + r4 = sub_8045C78(r7, gHealthboxIDs[r7], 1, 0); + sub_8043DFC(gHealthboxIDs[r7]); + if (r4 == -1) + { + struct Pokemon *pkmn; + u8 r4; + u32 sp4; + u16 r0; + u32 sp0; + + m4aSongNumStop(SE_EXP); + pkmn = &gPlayerParty[r9]; + r4 = GetMonData(pkmn, MON_DATA_LEVEL); + sp4 = GetMonData(pkmn, MON_DATA_EXP); + r0 = GetMonData(pkmn, MON_DATA_SPECIES); + sp0 = gExperienceTables[gBaseStats[r0].growthRate][r4 + 1]; + if (sp4 + r10 >= sp0) + { + u8 r5; + u32 asdf; + + SetMonData(pkmn, MON_DATA_EXP, &sp0); + CalculateMonStats(pkmn); + //r10 -= sp0 - sp4; + asdf = sp0 - sp4; + //asdf = r10 - (sp0 - sp4); + r10 -= asdf; + r5 = gActiveBattler; + gActiveBattler = r7; + Emitcmd33(1, 11, r10); + gActiveBattler = r5; + gTasks[taskId].func = sub_802DCB0; + } + else + { + //u32 asdf = sp4 + r10; + sp4 += r10; + SetMonData(pkmn, MON_DATA_EXP, &sp4); + gBattleBankFunc[r7] = sub_802D90C; + DestroyTask(taskId); + } + } + } +} +#else +NAKED +void sub_802DB6C(u8 taskId) +{ + asm_unified("push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x8\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + mov r8, r0\n\ + ldr r1, _0802DB98 @ =gTasks\n\ + lsls r0, 2\n\ + add r0, r8\n\ + lsls r0, 3\n\ + adds r6, r0, r1\n\ + ldrh r1, [r6, 0x1C]\n\ + movs r2, 0x1C\n\ + ldrsh r0, [r6, r2]\n\ + cmp r0, 0xC\n\ + bgt _0802DB9C\n\ + adds r0, r1, 0x1\n\ + strh r0, [r6, 0x1C]\n\ + b _0802DC98\n\ + .align 2, 0\n\ +_0802DB98: .4byte gTasks\n\ +_0802DB9C:\n\ + ldrb r0, [r6, 0x8]\n\ + mov r9, r0\n\ + ldrh r2, [r6, 0xA]\n\ + mov r10, r2\n\ + ldrb r7, [r6, 0xC]\n\ + ldr r5, _0802DC64 @ =gHealthboxIDs\n\ + adds r5, r7, r5\n\ + ldrb r1, [r5]\n\ + adds r0, r7, 0\n\ + movs r2, 0x1\n\ + movs r3, 0\n\ + bl sub_8045C78\n\ + adds r4, r0, 0\n\ + lsls r4, 16\n\ + lsrs r4, 16\n\ + ldrb r0, [r5]\n\ + bl sub_8043DFC\n\ + lsls r4, 16\n\ + asrs r4, 16\n\ + movs r0, 0x1\n\ + negs r0, r0\n\ + cmp r4, r0\n\ + bne _0802DC98\n\ + movs r0, 0x21\n\ + bl m4aSongNumStop\n\ + movs r0, 0x64\n\ + mov r1, r9\n\ + muls r1, r0\n\ + ldr r0, _0802DC68 @ =gPlayerParty\n\ + adds r5, r1, r0\n\ + adds r0, r5, 0\n\ + movs r1, 0x38\n\ + bl GetMonData\n\ + adds r4, r0, 0\n\ + lsls r4, 24\n\ + lsrs r4, 24\n\ + adds r0, r5, 0\n\ + movs r1, 0x19\n\ + bl GetMonData\n\ + str r0, [sp, 0x4]\n\ + adds r0, r5, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + ldr r3, _0802DC6C @ =gExperienceTables\n\ + adds r4, 0x1\n\ + lsls r4, 2\n\ + ldr r2, _0802DC70 @ =gBaseStats\n\ + lsls r1, r0, 3\n\ + subs r1, r0\n\ + lsls r1, 2\n\ + adds r1, r2\n\ + ldrb r1, [r1, 0x13]\n\ + movs r0, 0xCA\n\ + lsls r0, 1\n\ + muls r0, r1\n\ + adds r4, r0\n\ + adds r4, r3\n\ + ldr r1, [r4]\n\ + str r1, [sp]\n\ + mov r2, r10\n\ + lsls r0, r2, 16\n\ + asrs r4, r0, 16\n\ + ldr r0, [sp, 0x4]\n\ + adds r0, r4\n\ + cmp r0, r1\n\ + blt _0802DC7C\n\ + adds r0, r5, 0\n\ + movs r1, 0x19\n\ + mov r2, sp\n\ + bl SetMonData\n\ + adds r0, r5, 0\n\ + bl CalculateMonStats\n\ + ldr r2, [sp]\n\ + add r0, sp, 0x4\n\ + ldrh r0, [r0]\n\ + subs r2, r0\n\ + subs r2, r4, r2\n\ + ldr r4, _0802DC74 @ =gActiveBattler\n\ + ldrb r5, [r4]\n\ + strb r7, [r4]\n\ + lsls r2, 16\n\ + lsrs r2, 16\n\ + movs r0, 0x1\n\ + movs r1, 0xB\n\ + bl Emitcmd33\n\ + strb r5, [r4]\n\ + ldr r0, _0802DC78 @ =sub_802DCB0\n\ + str r0, [r6]\n\ + b _0802DC98\n\ + .align 2, 0\n\ +_0802DC64: .4byte gHealthboxIDs\n\ +_0802DC68: .4byte gPlayerParty\n\ +_0802DC6C: .4byte gExperienceTables\n\ +_0802DC70: .4byte gBaseStats\n\ +_0802DC74: .4byte gActiveBattler\n\ +_0802DC78: .4byte sub_802DCB0\n\ +_0802DC7C:\n\ + str r0, [sp, 0x4]\n\ + add r2, sp, 0x4\n\ + adds r0, r5, 0\n\ + movs r1, 0x19\n\ + bl SetMonData\n\ + ldr r1, _0802DCA8 @ =gBattleBankFunc\n\ + lsls r0, r7, 2\n\ + adds r0, r1\n\ + ldr r1, _0802DCAC @ =sub_802D90C\n\ + str r1, [r0]\n\ + mov r0, r8\n\ + bl DestroyTask\n\ +_0802DC98:\n\ + add sp, 0x8\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0802DCA8: .4byte gBattleBankFunc\n\ +_0802DCAC: .4byte sub_802D90C\n"); +} +#endif + +void sub_802DCB0(u8 taskId) +{ + u8 bank = gTasks[taskId].data[2]; + u8 pkmnIndex = gTasks[taskId].data[0]; + + if (IsDoubleBattle() == TRUE && pkmnIndex == gBattlerPartyIndexes[bank ^ 2]) + bank ^= 2; + move_anim_start_t4(bank, bank, bank, 0); + gTasks[taskId].func = sub_802DD10; +} + +void sub_802DD10(u8 taskId) +{ + u8 bank = gTasks[taskId].data[2]; + + if (!ewram17810[bank].unk0_6) + { + u8 pkmnIndex = gTasks[taskId].data[0]; + + GetMonData(&gPlayerParty[pkmnIndex], MON_DATA_LEVEL); // Unused return value + if (IsDoubleBattle() == TRUE && pkmnIndex == gBattlerPartyIndexes[bank ^ 2]) + sub_8045A5C(gHealthboxIDs[bank ^ 2], &gPlayerParty[pkmnIndex], 0); + else + sub_8045A5C(gHealthboxIDs[bank], &gPlayerParty[pkmnIndex], 0); + gTasks[taskId].func = sub_802DDC4; + } +} + +void sub_802DDC4(u8 taskId) +{ + u8 pkmnIndex; + u8 bank; + + pkmnIndex = gTasks[taskId].data[0]; + GetMonData(&gPlayerParty[pkmnIndex], MON_DATA_LEVEL); // Unused return value + bank = gTasks[taskId].data[2]; + gBattleBankFunc[bank] = sub_802D90C; + DestroyTask(taskId); +} + +void sub_802DE10(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].pos1.y + gSprites[gBankSpriteIds[gActiveBattler]].pos2.y > DISPLAY_HEIGHT) + { + u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); + + nullsub_9(species); + FreeOamMatrix(gSprites[gBankSpriteIds[gActiveBattler]].oam.matrixNum); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + PlayerBufferExecCompleted(); + } +} + +void sub_802DEAC(void) +{ + if (!ewram17810[gActiveBattler].unk0_6) + { + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + PlayerBufferExecCompleted(); + } +} + +// Duplicate of sub_802D90C +void sub_802DF18(void) +{ + if (gUnknown_03004210.state == 0) + PlayerBufferExecCompleted(); +} + +void sub_802DF30(void) +{ + if (!gPaletteFade.active) + { + u8 r4; + + gBattleBankFunc[gActiveBattler] = sub_802DF88; + r4 = gTasks[gUnknown_0300434C[gActiveBattler]].data[0]; + DestroyTask(gUnknown_0300434C[gActiveBattler]); + sub_8094E20(r4); + } +} + +void sub_802DF88(void) +{ + if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) + { + if (gUnknown_0202E8F4 == 1) + Emitcmd34(1, gUnknown_0202E8F5, gUnknown_02038470); + else + Emitcmd34(1, 6, NULL); + if ((gBattleBufferA[gActiveBattler][1] & 0xF) == 1) + b_link_standby_message(); + PlayerBufferExecCompleted(); + } +} + +void sub_802E004(void) +{ + if (!gPaletteFade.active) + { + gBattleBankFunc[gActiveBattler] = sub_802E03C; + nullsub_14(); + sub_80A6DCC(); + } +} + +void sub_802E03C(void) +{ + if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) + { + Emitcmd35(1, gSpecialVar_ItemId); + PlayerBufferExecCompleted(); + } +} + +void bx_wait_t1(void) +{ + if (!gDoingBattleAnim || !ewram17810[gActiveBattler].unk0_6) + PlayerBufferExecCompleted(); +} + +void bx_blink_t1(void) +{ + u8 spriteId = gBankSpriteIds[gActiveBattler]; + + if (gSprites[spriteId].data[1] == 32) + { + gSprites[spriteId].data[1] = 0; + gSprites[spriteId].invisible = FALSE; + gDoingBattleAnim = 0; + PlayerBufferExecCompleted(); + } + else + { + if (((u16)gSprites[spriteId].data[1] % 4) == 0) + gSprites[spriteId].invisible ^= 1; + gSprites[spriteId].data[1]++; + } +} + +void sub_802E12C(s32 a, const u8 *b) +{ + struct ChooseMoveStruct *r4 = (struct ChooseMoveStruct *)&gBattleBufferA[gActiveBattler][4]; + + StringCopy(gDisplayedStringBattle, b); + StringAppend(gDisplayedStringBattle, gMoveNames[r4->moves[a]]); + Text_InitWindow( + &gUnknown_03004210, + gDisplayedStringBattle, + 0x300 + a * 20, + (a & 1) ? 11 : 1, + (a < 2) ? 0x37 : 0x39); + Text_PrintWindow8002F44(&gUnknown_03004210); +} + +void sub_802E1B0(void) +{ + struct ChooseMoveStruct *r4 = (struct ChooseMoveStruct *)&gBattleBufferA[gActiveBattler][4]; + s32 i; + + gUnknown_03004348 = 0; + Text_FillWindowRect(&gUnknown_03004210, 0x1016, 1, 0x37, 0x14, 0x3A); + for (i = 0; i < 4; i++) + { + nullsub_7(i); + sub_802E12C(i, BattleText_Format); + if (r4->moves[i] != 0) + gUnknown_03004348++; + } +} + +void sub_802E220(void) +{ + if (gBattleBufferA[gActiveBattler][2] != 1) + { + struct ChooseMoveStruct *r4 = (struct ChooseMoveStruct *)&gBattleBufferA[gActiveBattler][4]; + u8 *str = gDisplayedStringBattle; + + str = StringCopy(str, BattleText_Format); + str[0] = EXT_CTRL_CODE_BEGIN; + str[1] = 0x11; + str[2] = 2; + str += 3; + str[0] = EXT_CTRL_CODE_BEGIN; + str[1] = 0x14; + str[2] = 6; + str += 3; + str = ConvertIntToDecimalStringN(str, r4->pp[gMoveSelectionCursor[gActiveBattler]], 1, 2); + *str++ = CHAR_SLASH; + ConvertIntToDecimalStringN(str, r4->unkC[gMoveSelectionCursor[gActiveBattler]], 1, 2); + Text_InitWindow(&gUnknown_03004210, gDisplayedStringBattle, 0x2A2, 0x19, 0x37); + Text_PrintWindow8002F44(&gUnknown_03004210); + } +} + +extern const u8 BattleText_ForgetMove[]; +extern const u8 gTypeNames[][7]; + +void sub_802E2D4(void) +{ + if (gBattleBufferA[gActiveBattler][2] == 1) + { + Text_FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x37, 0x1C, 0x3A); + Text_InitWindow(&gUnknown_03004210, BattleText_ForgetMove, 0x290, 0x13, 0x37); + } + else + { + struct ChooseMoveStruct *r4 = (struct ChooseMoveStruct *)&gBattleBufferA[gActiveBattler][4]; + u8 *str = gDisplayedStringBattle; + + str = StringCopy(str, BattleText_Format); + StringCopy(str, gTypeNames[gBattleMoves[r4->moves[gMoveSelectionCursor[gActiveBattler]]].type]); + Text_FillWindowRect(&gUnknown_03004210, 0x1016, 0x17, 0x39, 0x1C, 0x3A); + Text_InitWindow(&gUnknown_03004210, gDisplayedStringBattle, 0x2C0, 0x17, 0x39); + } + Text_PrintWindow8002F44(&gUnknown_03004210); +} + +const u8 gUnknown_081FAE89[][2] = +{ + { 8, 120}, + {88, 120}, + { 8, 136}, + {88, 136}, +}; + +const u8 gUnknown_081FAE91[][2] = +{ + {144, 120}, + {190, 120}, + {144, 136}, + {190, 136}, + { 72, 72}, + { 32, 90}, + { 80, 80}, + { 80, 88}, +}; + +void sub_802E3B4(u8 a, int unused) +{ + sub_814A958(0x48); + MenuCursor_SetPos814A880(gUnknown_081FAE89[a][0], gUnknown_081FAE89[a][1]); +} + +void nullsub_7(u8 a) +{ +} + +void sub_802E3E4(u8 a, int unused) +{ + sub_814A958(0x2A); + MenuCursor_SetPos814A880(gUnknown_081FAE91[a][0], gUnknown_081FAE91[a][1]); +} + +void nullsub_8(u8 a) +{ +} + +void sub_802E414(void) +{ + SetMainCallback2(ReshowBattleScreenAfterMenu); +} + +void sub_802E424(void) +{ + SetMainCallback2(ReshowBattleScreenAfterMenu); +} + +void sub_802E434(void) +{ + if (!ewram17810[gActiveBattler].unk0_4) + PlayerBufferExecCompleted(); +} + +void sub_802E460(void) +{ + if (!ewram17810[gActiveBattler].unk0_5) + PlayerBufferExecCompleted(); +} + +void b_link_standby_message(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + Text_InitWindow8002EB0(&gUnknown_03004210, BattleText_LinkStandby, 0x90, 2, 15); + } +} + +void PlayerHandleGetAttributes(void) +{ + u8 unkData[0x100]; + u32 offset = 0; + u8 r4; + s32 i; + + if (gBattleBufferA[gActiveBattler][2] == 0) + { + offset += dp01_getattr_by_ch1_for_player_pokemon_(gBattlerPartyIndexes[gActiveBattler], unkData); + } + else + { + r4 = gBattleBufferA[gActiveBattler][2]; + for (i = 0; i < 6; i++) + { + if (r4 & 1) + offset += dp01_getattr_by_ch1_for_player_pokemon_(i, unkData + offset); + r4 >>= 1; + } + } + Emitcmd29(1, offset, unkData); + PlayerBufferExecCompleted(); +} + +// Duplicate of dp01_getattr_by_ch1_for_player_pokemon +u32 dp01_getattr_by_ch1_for_player_pokemon_(u8 a, u8 *buffer) +{ + struct BattlePokemon battlePokemon; + struct MovePpInfo moveData; + u8 nickname[20]; + u8 *src; + s16 data16; + u32 data32; + s32 size = 0; + + switch (gBattleBufferA[gActiveBattler][1]) + { + case 0: + battlePokemon.species = GetMonData(&gPlayerParty[a], MON_DATA_SPECIES); + battlePokemon.item = GetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM); + for (size = 0; size < 4; size++) + { + battlePokemon.moves[size] = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + size); + battlePokemon.pp[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); + } + battlePokemon.ppBonuses = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); + battlePokemon.friendship = GetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP); + battlePokemon.experience = GetMonData(&gPlayerParty[a], MON_DATA_EXP); + battlePokemon.hpIV = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); + battlePokemon.attackIV = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); + battlePokemon.defenseIV = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); + battlePokemon.speedIV = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); + battlePokemon.spAttackIV = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); + battlePokemon.spDefenseIV = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); + battlePokemon.personality = GetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY); + battlePokemon.status1 = GetMonData(&gPlayerParty[a], MON_DATA_STATUS); + battlePokemon.level = GetMonData(&gPlayerParty[a], MON_DATA_LEVEL); + battlePokemon.hp = GetMonData(&gPlayerParty[a], MON_DATA_HP); + battlePokemon.maxHP = GetMonData(&gPlayerParty[a], MON_DATA_MAX_HP); + battlePokemon.attack = GetMonData(&gPlayerParty[a], MON_DATA_ATK); + battlePokemon.defense = GetMonData(&gPlayerParty[a], MON_DATA_DEF); + battlePokemon.speed = GetMonData(&gPlayerParty[a], MON_DATA_SPEED); + battlePokemon.spAttack = GetMonData(&gPlayerParty[a], MON_DATA_SPATK); + battlePokemon.spDefense = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF); + battlePokemon.isEgg = GetMonData(&gPlayerParty[a], MON_DATA_IS_EGG); + battlePokemon.altAbility = GetMonData(&gPlayerParty[a], MON_DATA_ALT_ABILITY); + battlePokemon.otId = GetMonData(&gPlayerParty[a], MON_DATA_OT_ID); + GetMonData(&gPlayerParty[a], MON_DATA_NICKNAME, nickname); + StringCopy10(battlePokemon.nickname, nickname); + GetMonData(&gPlayerParty[a], MON_DATA_OT_NAME, battlePokemon.otName); + MEMCPY_ALT(&battlePokemon, buffer, sizeof(battlePokemon), size, src); + break; + case 1: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPECIES); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 2: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 3: + for (size = 0; size < 4; size++) + { + moveData.moves[size] = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + size); + moveData.pp[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); + } + moveData.ppBonuses = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); + MEMCPY_ALT(&moveData, buffer, sizeof(moveData), size, src); + break; + case 4: + case 5: + case 6: + case 7: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 8: + for (size = 0; size < 4; size++) + buffer[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); + buffer[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); + size++; + break; + case 9: + case 10: + case 11: + case 12: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9); + size = 1; + break; + case 17: + data32 = GetMonData(&gPlayerParty[a], MON_DATA_OT_ID); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + size = 3; + break; + case 18: + data32 = GetMonData(&gPlayerParty[a], MON_DATA_EXP); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + size = 3; + break; + case 19: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_EV); + size = 1; + break; + case 20: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_EV); + size = 1; + break; + case 21: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_EV); + size = 1; + break; + case 22: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_EV); + size = 1; + break; + case 23: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_EV); + size = 1; + break; + case 24: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_EV); + size = 1; + break; + case 25: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP); + size = 1; + break; + case 26: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_POKERUS); + size = 1; + break; + case 27: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_LOCATION); + size = 1; + break; + case 28: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_LEVEL); + size = 1; + break; + case 29: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_GAME); + size = 1; + break; + case 30: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_POKEBALL); + size = 1; + break; + case 31: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); + buffer[1] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); + buffer[2] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); + buffer[3] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); + buffer[4] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); + buffer[5] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); + size = 6; + break; + case 32: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); + size = 1; + break; + case 33: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); + size = 1; + break; + case 34: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); + size = 1; + break; + case 35: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); + size = 1; + break; + case 36: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); + size = 1; + break; + case 37: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); + size = 1; + break; + case 38: + data32 = GetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + buffer[3] = (data32 & 0xFF000000) >> 24; + size = 4; + break; + case 39: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_CHECKSUM); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 40: + data32 = GetMonData(&gPlayerParty[a], MON_DATA_STATUS); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + buffer[3] = (data32 & 0xFF000000) >> 24; + size = 4; + break; + case 41: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_LEVEL); + size = 1; + break; + case 42: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_HP); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 43: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_MAX_HP); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 44: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_ATK); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 45: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_DEF); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 46: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPEED); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 47: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPATK); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 48: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 49: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_COOL); + size = 1; + break; + case 50: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_BEAUTY); + size = 1; + break; + case 51: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_CUTE); + size = 1; + break; + case 52: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SMART); + size = 1; + break; + case 53: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_TOUGH); + size = 1; + break; + case 54: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SHEEN); + size = 1; + break; + case 55: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_COOL_RIBBON); + size = 1; + break; + case 56: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_BEAUTY_RIBBON); + size = 1; + break; + case 57: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_CUTE_RIBBON); + size = 1; + break; + case 58: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SMART_RIBBON); + size = 1; + break; + case 59: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_TOUGH_RIBBON); + size = 1; + break; + } + return size; +} + +void PlayerHandlecmd1(void) +{ + struct BattlePokemon battleMon; + u8 i; + // TODO: Maybe fix this. Integrating this into MEMSET_ALT is too hard. + u8 *src = (u8 *)&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1]; + u8 *dst; + + MEMSET_ALT(&battleMon + gBattleBufferA[gActiveBattler][1], src[i], gBattleBufferA[gActiveBattler][2], i, dst); + Emitcmd29(1, gBattleBufferA[gActiveBattler][2], dst); + PlayerBufferExecCompleted(); +} + +void PlayerHandleSetAttributes(void) +{ + u8 r4; + u8 i; + + if (gBattleBufferA[gActiveBattler][2] == 0) + { + dp01_setattr_by_ch1_for_player_pokemon(gBattlerPartyIndexes[gActiveBattler]); + } + else + { + r4 = gBattleBufferA[gActiveBattler][2]; + for (i = 0; i < 6; i++) + { + if (r4 & 1) + dp01_setattr_by_ch1_for_player_pokemon(i); + r4 >>= 1; + } + } + PlayerBufferExecCompleted(); +} + +// Duplicate of sub_811EC68 +void dp01_setattr_by_ch1_for_player_pokemon(u8 a) +{ + struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBattler][3]; + struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBattler][3]; + s32 i; + + switch (gBattleBufferA[gActiveBattler][1]) + { + case 0: + { + u8 iv; + + SetMonData(&gPlayerParty[a], MON_DATA_SPECIES, &battlePokemon->species); + SetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM, &battlePokemon->item); + for (i = 0; i < 4; i++) + { + SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); + SetMonData(&gPlayerParty[a], MON_DATA_PP1 + i, &battlePokemon->pp[i]); + } + SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); + SetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); + SetMonData(&gPlayerParty[a], MON_DATA_EXP, &battlePokemon->experience); + iv = battlePokemon->hpIV; + SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &iv); + iv = battlePokemon->attackIV; + SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &iv); + iv = battlePokemon->defenseIV; + SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &iv); + iv = battlePokemon->speedIV; + SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &iv); + iv = battlePokemon->spAttackIV; + SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &iv); + iv = battlePokemon->spDefenseIV; + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &iv); + SetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY, &battlePokemon->personality); + SetMonData(&gPlayerParty[a], MON_DATA_STATUS, &battlePokemon->status1); + SetMonData(&gPlayerParty[a], MON_DATA_LEVEL, &battlePokemon->level); + SetMonData(&gPlayerParty[a], MON_DATA_HP, &battlePokemon->hp); + SetMonData(&gPlayerParty[a], MON_DATA_MAX_HP, &battlePokemon->maxHP); + SetMonData(&gPlayerParty[a], MON_DATA_ATK, &battlePokemon->attack); + SetMonData(&gPlayerParty[a], MON_DATA_DEF, &battlePokemon->defense); + SetMonData(&gPlayerParty[a], MON_DATA_SPEED, &battlePokemon->speed); + SetMonData(&gPlayerParty[a], MON_DATA_SPATK, &battlePokemon->spAttack); + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF, &battlePokemon->spDefense); + } + break; + case 1: + SetMonData(&gPlayerParty[a], MON_DATA_SPECIES, &gBattleBufferA[gActiveBattler][3]); + break; + case 2: + SetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]); + break; + case 3: + for (i = 0; i < 4; i++) + { + SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + i, &moveData->moves[i]); + SetMonData(&gPlayerParty[a], MON_DATA_PP1 + i, &moveData->pp[i]); + } + SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &moveData->ppBonuses); + break; + case 4: + case 5: + case 6: + case 7: + SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4, &gBattleBufferA[gActiveBattler][3]); + break; + case 8: + SetMonData(&gPlayerParty[a], MON_DATA_PP1, &gBattleBufferA[gActiveBattler][3]); + SetMonData(&gPlayerParty[a], MON_DATA_PP2, &gBattleBufferA[gActiveBattler][4]); + SetMonData(&gPlayerParty[a], MON_DATA_PP3, &gBattleBufferA[gActiveBattler][5]); + SetMonData(&gPlayerParty[a], MON_DATA_PP4, &gBattleBufferA[gActiveBattler][6]); + SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBattler][7]); + break; + case 9: + case 10: + case 11: + case 12: + SetMonData(&gPlayerParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9, &gBattleBufferA[gActiveBattler][3]); + break; + case 17: + SetMonData(&gPlayerParty[a], MON_DATA_OT_ID, &gBattleBufferA[gActiveBattler][3]); + break; + case 18: + SetMonData(&gPlayerParty[a], MON_DATA_EXP, &gBattleBufferA[gActiveBattler][3]); + break; + case 19: + SetMonData(&gPlayerParty[a], MON_DATA_HP_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 20: + SetMonData(&gPlayerParty[a], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 21: + SetMonData(&gPlayerParty[a], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 22: + SetMonData(&gPlayerParty[a], MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 23: + SetMonData(&gPlayerParty[a], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 24: + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 25: + SetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBattler][3]); + break; + case 26: + SetMonData(&gPlayerParty[a], MON_DATA_POKERUS, &gBattleBufferA[gActiveBattler][3]); + break; + case 27: + SetMonData(&gPlayerParty[a], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBattler][3]); + break; + case 28: + SetMonData(&gPlayerParty[a], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBattler][3]); + break; + case 29: + SetMonData(&gPlayerParty[a], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBattler][3]); + break; + case 30: + SetMonData(&gPlayerParty[a], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBattler][3]); + break; + case 31: + SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); + SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][4]); + SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][5]); + SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][6]); + SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][7]); + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][8]); + break; + case 32: + SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 33: + SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 34: + SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 35: + SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 36: + SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 37: + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 38: + SetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBattler][3]); + break; + case 39: + SetMonData(&gPlayerParty[a], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBattler][3]); + break; + case 40: + SetMonData(&gPlayerParty[a], MON_DATA_STATUS, &gBattleBufferA[gActiveBattler][3]); + break; + case 41: + SetMonData(&gPlayerParty[a], MON_DATA_LEVEL, &gBattleBufferA[gActiveBattler][3]); + break; + case 42: + SetMonData(&gPlayerParty[a], MON_DATA_HP, &gBattleBufferA[gActiveBattler][3]); + break; + case 43: + SetMonData(&gPlayerParty[a], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBattler][3]); + break; + case 44: + SetMonData(&gPlayerParty[a], MON_DATA_ATK, &gBattleBufferA[gActiveBattler][3]); + break; + case 45: + SetMonData(&gPlayerParty[a], MON_DATA_DEF, &gBattleBufferA[gActiveBattler][3]); + break; + case 46: + SetMonData(&gPlayerParty[a], MON_DATA_SPEED, &gBattleBufferA[gActiveBattler][3]); + break; + case 47: + SetMonData(&gPlayerParty[a], MON_DATA_SPATK, &gBattleBufferA[gActiveBattler][3]); + break; + case 48: + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF, &gBattleBufferA[gActiveBattler][3]); + break; + case 49: + SetMonData(&gPlayerParty[a], MON_DATA_COOL, &gBattleBufferA[gActiveBattler][3]); + break; + case 50: + SetMonData(&gPlayerParty[a], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBattler][3]); + break; + case 51: + SetMonData(&gPlayerParty[a], MON_DATA_CUTE, &gBattleBufferA[gActiveBattler][3]); + break; + case 52: + SetMonData(&gPlayerParty[a], MON_DATA_SMART, &gBattleBufferA[gActiveBattler][3]); + break; + case 53: + SetMonData(&gPlayerParty[a], MON_DATA_TOUGH, &gBattleBufferA[gActiveBattler][3]); + break; + case 54: + SetMonData(&gPlayerParty[a], MON_DATA_SHEEN, &gBattleBufferA[gActiveBattler][3]); + break; + case 55: + SetMonData(&gPlayerParty[a], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 56: + SetMonData(&gPlayerParty[a], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 57: + SetMonData(&gPlayerParty[a], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 58: + SetMonData(&gPlayerParty[a], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 59: + SetMonData(&gPlayerParty[a], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + } + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); +} + +void PlayerHandlecmd3(void) +{ + u8 i; + u8 *dst; + + MEMSET_ALT(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]] + gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][3 + i], + gBattleBufferA[gActiveBattler][2], i, dst); + PlayerBufferExecCompleted(); +} + +void PlayerHandleLoadPokeSprite(void) +{ + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; + gBattleBankFunc[gActiveBattler] = bx_0802E404; +} + +void PlayerHandleSendOutPoke(void) +{ + sub_8032AA8(gActiveBattler, gBattleBufferA[gActiveBattler][2]); + gBattlerPartyIndexes[gActiveBattler] = gBattleBufferA[gActiveBattler][1]; + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + gActionSelectionCursor[gActiveBattler] = 0; + gMoveSelectionCursor[gActiveBattler] = 0; + sub_802F934(gActiveBattler, gBattleBufferA[gActiveBattler][2]); + gBattleBankFunc[gActiveBattler] = sub_802D798; +} + +void sub_802F934(u8 bank, u8 b) +{ + u16 species; + + sub_8032AA8(bank, b); + gBattlerPartyIndexes[bank] = gBattleBufferA[bank][1]; + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES); + gUnknown_0300434C[bank] = CreateInvisibleSpriteWithCallback(sub_80312F0); + GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(bank)); + gBankSpriteIds[bank] = CreateSprite( + &gUnknown_02024E8C, + GetBattlerSpriteCoord(bank, 2), + sub_8077F68(bank), + GetBattlerSubpriority(bank)); + gSprites[gUnknown_0300434C[bank]].data[1] = gBankSpriteIds[bank]; + gSprites[gBankSpriteIds[bank]].data[0] = bank; + gSprites[gBankSpriteIds[bank]].data[2] = species; + gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; + StartSpriteAnim(&gSprites[gBankSpriteIds[bank]], gBattleMonForms[bank]); + gSprites[gBankSpriteIds[bank]].invisible = TRUE; + gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; + gSprites[gUnknown_0300434C[bank]].data[0] = StartSendOutMonAnimation(0, 0xFF); +} + +void PlayerHandleReturnPokeToBall(void) +{ + if (gBattleBufferA[gActiveBattler][1] == 0) + { + ewram17810[gActiveBattler].unk4 = 0; + gBattleBankFunc[gActiveBattler] = sub_802FB2C; + } + else + { + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + PlayerBufferExecCompleted(); + } +} + +void sub_802FB2C(void) +{ + switch (ewram17810[gActiveBattler].unk4) + { + case 0: + if (ewram17800[gActiveBattler].substituteSprite) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + ewram17810[gActiveBattler].unk4 = 1; + break; + case 1: + if (!ewram17810[gActiveBattler].unk0_6) + { + ewram17810[gActiveBattler].unk4 = 0; + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 1); + gBattleBankFunc[gActiveBattler] = sub_802DEAC; + } + } +} + +void PlayerHandleTrainerThrow(void) +{ + s16 r7; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (GetBattlerPosition(gActiveBattler) & 2) + r7 = 16; + else + r7 = -16; + } + else + { + r7 = 0; + } + LoadPlayerTrainerBankSprite(gSaveBlock2.playerGender, gActiveBattler); + GetMonSpriteTemplate_803C5A0(gSaveBlock2.playerGender, GetBattlerPosition(gActiveBattler)); + gBankSpriteIds[gActiveBattler] = CreateSprite( + &gUnknown_02024E8C, + r7 + 80, + (8 - gTrainerBackPicCoords[gSaveBlock2.playerGender].coords) * 4 + 80, + GetBattlerSubpriority(gActiveBattler)); + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; + gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = 240; + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = -2; + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; + gBattleBankFunc[gActiveBattler] = sub_802D204; +} + +void PlayerHandleTrainerSlide(void) +{ + LoadPlayerTrainerBankSprite(gSaveBlock2.playerGender, gActiveBattler); + GetMonSpriteTemplate_803C5A0(gSaveBlock2.playerGender, GetBattlerPosition(gActiveBattler)); + gBankSpriteIds[gActiveBattler] = CreateSprite( + &gUnknown_02024E8C, + 80, + (8 - gTrainerBackPicCoords[gSaveBlock2.playerGender].coords) * 4 + 80, + 30); + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; + gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -96; + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 2; + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; + gBattleBankFunc[gActiveBattler] = sub_802D23C; +} + +void PlayerHandleTrainerSlideBack(void) +{ + oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 50; + gSprites[gBankSpriteIds[gActiveBattler]].data[2] = -40; + gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; + gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; + StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], SpriteCallbackDummy); + StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 1); + gBattleBankFunc[gActiveBattler] = sub_802D274; +} + +void PlayerHandlecmd10(void) +{ + if (ewram17810[gActiveBattler].unk4 == 0) + { + if (ewram17800[gActiveBattler].substituteSprite) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + ewram17810[gActiveBattler].unk4++; + } + else + { + if (ewram17810[gActiveBattler].unk0_6 == 0) + { + ewram17810[gActiveBattler].unk4 = 0; + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + PlaySE12WithPanning(SE_POKE_DEAD, -64); + gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; + gSprites[gBankSpriteIds[gActiveBattler]].data[2] = 5; + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80105EC; + gBattleBankFunc[gActiveBattler] = sub_802DE10; + } + } +} + +void PlayerHandlecmd11(void) +{ + BeginNormalPaletteFade(0xFFFFFFFF, 2, 0, 16, RGB(0, 0, 0)); + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd12(void) +{ + ewram17840.unk8 = 4; + gDoingBattleAnim = 1; + move_anim_start_t4(gActiveBattler, gActiveBattler, GetBattlerAtPosition(1), 3); + gBattleBankFunc[gActiveBattler] = bx_wait_t1; +} + +void PlayerHandleBallThrow(void) +{ + u8 var = gBattleBufferA[gActiveBattler][1]; + + ewram17840.unk8 = var; + gDoingBattleAnim = 1; + move_anim_start_t4(gActiveBattler, gActiveBattler, GetBattlerAtPosition(1), 3); + gBattleBankFunc[gActiveBattler] = bx_wait_t1; +} + +void PlayerHandlePuase(void) +{ + u8 var = gBattleBufferA[gActiveBattler][1]; + + // WTF is this?? + while (var != 0) + var--; + + PlayerBufferExecCompleted(); +} + +void PlayerHandleMoveAnimation(void) +{ + if (!mplay_80342A4(gActiveBattler)) + { + u16 r0 = gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8); + + gAnimMoveTurn = gBattleBufferA[gActiveBattler][3]; + gAnimMovePower = gBattleBufferA[gActiveBattler][4] | (gBattleBufferA[gActiveBattler][5] << 8); + gAnimMoveDmg = gBattleBufferA[gActiveBattler][6] | (gBattleBufferA[gActiveBattler][7] << 8) | (gBattleBufferA[gActiveBattler][8] << 16) | (gBattleBufferA[gActiveBattler][9] << 24); + gAnimFriendship = gBattleBufferA[gActiveBattler][10]; + gWeatherMoveAnim = gBattleBufferA[gActiveBattler][12] | (gBattleBufferA[gActiveBattler][13] << 8); + gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBattler][16]; + gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; + if (sub_8031720(r0, gAnimMoveTurn) != 0) + { + // Dead code. sub_8031720 always returns 0. + PlayerBufferExecCompleted(); + } + else + { + ewram17810[gActiveBattler].unk4 = 0; + gBattleBankFunc[gActiveBattler] = sub_8030190; + } + } +} + +void sub_8030190(void) +{ + u16 r4 = gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8); + u8 r7 = gBattleBufferA[gActiveBattler][11]; + + switch (ewram17810[gActiveBattler].unk4) + { + case 0: + if (ewram17800[gActiveBattler].substituteSprite == 1 && ewram17800[gActiveBattler].unk0_3 == 0) + { + ewram17800[gActiveBattler].unk0_3 = 1; + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + } + ewram17810[gActiveBattler].unk4 = 1; + break; + case 1: + if (ewram17810[gActiveBattler].unk0_6 == 0) + { + sub_80326EC(0); + DoMoveAnim(r4); + ewram17810[gActiveBattler].unk4 = 2; + } + break; + case 2: + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + sub_80326EC(1); + if (ewram17800[gActiveBattler].substituteSprite == 1 && r7 < 2) + { + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); + ewram17800[gActiveBattler].unk0_3 = 0; + } + ewram17810[gActiveBattler].unk4 = 3; + } + break; + case 3: + if (ewram17810[gActiveBattler].unk0_6 == 0) + { + sub_8031F24(); + sub_80324BC(gActiveBattler, gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + ewram17810[gActiveBattler].unk4 = 0; + PlayerBufferExecCompleted(); + } + break; + } +} + +void PlayerHandlePrintString(void) +{ + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + BufferStringBattle(*(u16 *)&gBattleBufferA[gActiveBattler][2]); + Text_InitWindow8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 0x90, 2, 15); + gBattleBankFunc[gActiveBattler] = sub_802DF18; +} + +void PlayerHandlePrintStringPlayerOnly(void) +{ + if (GetBattlerSide(gActiveBattler) == 0) + PlayerHandlePrintString(); + else + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd18(void) +{ + int r4; + + gBattle_BG0_X = 0; + gBattle_BG0_Y = 160; + Text_FillWindowRect(&gUnknown_03004210, 10, 2, 15, 27, 18); + Text_FillWindowRect(&gUnknown_03004210, 10, 2, 35, 16, 38); + + gBattleBankFunc[gActiveBattler] = sub_802C098; + + Text_InitWindow(&gUnknown_03004210, BattleText_MenuOptions, 400, 18, 35); + Text_PrintWindow8002F44(&gUnknown_03004210); + MenuCursor_Create814A5C0(0, 0xFFFF, 12, 11679, 0); + + for (r4 = 0; r4 < 4; r4++) + nullsub_8(r4); + + sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); + + StrCpyDecodeToDisplayedStringBattle(BattleText_OtherMenu); + Text_InitWindow(&gUnknown_03004210, gDisplayedStringBattle, SUB_803037C_TILE_DATA_OFFSET, 2, 35); + Text_PrintWindow8002F44(&gUnknown_03004210); +} + +void PlayerHandlecmd19() +{ +} + +void PlayerHandlecmd20(void) +{ + MenuCursor_Create814A5C0(0, 0xFFFF, 12, 0x2D9F, 0); + sub_80304A8(); + gBattleBankFunc[gActiveBattler] = sub_802C68C; +} + +void sub_80304A8(void) +{ + gBattle_BG0_X = 0; + gBattle_BG0_Y = 320; + sub_802E1B0(); + gUnknown_03004344 = 0xFF; + sub_802E3B4(gMoveSelectionCursor[gActiveBattler], 0); + if (gBattleBufferA[gActiveBattler][2] != 1) + { + Text_InitWindow(&gUnknown_03004210, BattleText_PP, 656, 23, 55); + Text_PrintWindow8002F44(&gUnknown_03004210); + } + sub_802E220(); + sub_802E2D4(); +} + +void PlayerHandleOpenBag(void) +{ + s32 i; + + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); + gBattleBankFunc[gActiveBattler] = sub_802E004; + gBankInMenu = gActiveBattler; + for (i = 0; i < 3; i++) + gUnknown_02038470[i] = gBattleBufferA[gActiveBattler][1 + i]; +} + +void PlayerHandlecmd22(void) +{ + s32 i; + + gUnknown_0300434C[gActiveBattler] = CreateTask(TaskDummy, 0xFF); + gTasks[gUnknown_0300434C[gActiveBattler]].data[0] = gBattleBufferA[gActiveBattler][1] & 0xF; + ewram16054 = gBattleBufferA[gActiveBattler][1] >> 4; + EWRAM_1609D = gBattleBufferA[gActiveBattler][2]; + ewram160C0 = gBattleBufferA[gActiveBattler][3]; + for (i = 0; i < 3; i++) + gUnknown_02038470[i] = gBattleBufferA[gActiveBattler][4 + i]; + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); + gBattleBankFunc[gActiveBattler] = sub_802DF30; + gBankInMenu = gActiveBattler; +} + +void PlayerHandlecmd23(void) +{ + BattleStopLowHpSound(); + BeginNormalPaletteFade(0xFFFFFFFF, 2, 0, 16, RGB(0, 0, 0)); + PlayerBufferExecCompleted(); +} + +void PlayerHandleHealthBarUpdate(void) +{ + s16 r7; + + load_gfxc_health_bar(0); + r7 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + if (r7 != 0x7FFF) + { + u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); + u32 curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); + + sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, curHP, r7); + } + else + { + u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); + + sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, 0, r7); + sub_80440EC(gHealthboxIDs[gActiveBattler], 0, 0); + } + gBattleBankFunc[gActiveBattler] = bx_t1_healthbar_update; +} + +void PlayerHandleExpBarUpdate(void) +{ + u8 r7 = gBattleBufferA[gActiveBattler][1]; + + if (GetMonData(&gPlayerParty[r7], MON_DATA_LEVEL) >= 100) + { + PlayerBufferExecCompleted(); + } + else + { + u16 r4; + u8 taskId; + + load_gfxc_health_bar(1); + GetMonData(&gPlayerParty[r7], MON_DATA_SPECIES); // unused return value + r4 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + taskId = CreateTask(sub_802D924, 10); + gTasks[taskId].data[0] = r7; + gTasks[taskId].data[1] = r4; + gTasks[taskId].data[2] = gActiveBattler; + gBattleBankFunc[gActiveBattler] = nullsub_91; + } +} + +void PlayerHandleStatusIconUpdate(void) +{ + if (!mplay_80342A4(gActiveBattler)) + { + sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 9); + ewram17810[gActiveBattler].unk0_4 = 0; + gBattleBankFunc[gActiveBattler] = sub_802E434; + } +} + +void PlayerHandleStatusAnimation(void) +{ + if (!mplay_80342A4(gActiveBattler)) + { + move_anim_start_t2_for_situation( + gBattleBufferA[gActiveBattler][1], + gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8) | (gBattleBufferA[gActiveBattler][4] << 16) | (gBattleBufferA[gActiveBattler][5] << 24)); + gBattleBankFunc[gActiveBattler] = sub_802E434; + } +} + +void PlayerHandleStatusXor(void) +{ + u8 val = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_STATUS) ^ gBattleBufferA[gActiveBattler][1]; + + SetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_STATUS, &val); + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd29(void) +{ + PlayerBufferExecCompleted(); +} + +void PlayerHandleDMATransfer(void) +{ + u32 val1 = gBattleBufferA[gActiveBattler][1] + | (gBattleBufferA[gActiveBattler][2] << 8) + | (gBattleBufferA[gActiveBattler][3] << 16) + | (gBattleBufferA[gActiveBattler][4] << 24); + u16 val2 = gBattleBufferA[gActiveBattler][5] | (gBattleBufferA[gActiveBattler][6] << 8); + + Dma3CopyLarge16_(&gBattleBufferA[gActiveBattler][7], (u8 *)val1, val2); + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd31(void) +{ + PlayBGM(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd32(void) +{ + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd33(void) +{ + Emitcmd33(1, 0, 0); + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd34(void) +{ + Emitcmd34(1, 0, 0); + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd35(void) +{ + Emitcmd35(1, 0); + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd36(void) +{ + Emitcmd36(1, 0); + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd37(void) +{ + gUnknown_020238C8.unk0_0 = 0; + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd38(void) +{ + gUnknown_020238C8.unk0_0 = gBattleBufferA[gActiveBattler][1]; + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd39(void) +{ + gUnknown_020238C8.unk0_7 = 0; + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd40(void) +{ + gUnknown_020238C8.unk0_7 ^= 1; + PlayerBufferExecCompleted(); +} + +void PlayerHandleHitAnimation(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].invisible == TRUE) + { + PlayerBufferExecCompleted(); + } + else + { + gDoingBattleAnim = 1; + gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; + sub_8047858(gActiveBattler); + gBattleBankFunc[gActiveBattler] = bx_blink_t1; + } +} + +void PlayerHandlecmd42(void) +{ + PlayerBufferExecCompleted(); +} + +void PlayerHandleEffectivenessSound(void) +{ + s8 pan; + + if (GetBattlerSide(gActiveBattler) == 0) + pan = -64; + else + pan = 63; + PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan); + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd44(void) +{ + PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + PlayerBufferExecCompleted(); +} + +void PlayerHandleFaintingCry(void) +{ + u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); + + PlayCry3(species, -25, 5); + PlayerBufferExecCompleted(); +} + +void PlayerHandleIntroSlide(void) +{ + StartBattleIntroAnim(gBattleBufferA[gActiveBattler][1]); + gUnknown_02024DE8 |= 1; + PlayerBufferExecCompleted(); +} + +void PlayerHandleTrainerBallThrow(void) +{ + u8 paletteNum; + u8 taskId; + + oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 50; + gSprites[gBankSpriteIds[gActiveBattler]].data[2] = -40; + gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; + gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; + gSprites[gBankSpriteIds[gActiveBattler]].data[5] = gActiveBattler; + StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], sub_8030E38); + StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 1); + paletteNum = AllocSpritePalette(0xD6F8); + LoadCompressedPalette(gTrainerBackPicPaletteTable[gSaveBlock2.playerGender].data, 0x100 + paletteNum * 16, 32); + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = paletteNum; + taskId = CreateTask(task05_08033660, 5); + gTasks[taskId].data[0] = gActiveBattler; + if (ewram17810[gActiveBattler].unk0_0) + gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; + ewram17810[4].unk9 |= 1; + gBattleBankFunc[gActiveBattler] = nullsub_91; +} + +void sub_8030E38(struct Sprite *sprite) +{ + u8 r4 = sprite->data[5]; + + FreeSpriteOamMatrix(sprite); + FreeSpritePaletteByTag(GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum)); + DestroySprite(sprite); + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[r4]], r4); + StartSpriteAnim(&gSprites[gBankSpriteIds[r4]], 0); +} + +void task05_08033660(u8 taskId) +{ + if (gTasks[taskId].data[1] < 31) + { + gTasks[taskId].data[1]++; + } + else + { + u8 savedActiveBank = gActiveBattler; + + gActiveBattler = gTasks[taskId].data[0]; + if (!IsDoubleBattle() || (gBattleTypeFlags & 0x40)) + { + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_802F934(gActiveBattler, 0); + } + else + { + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_802F934(gActiveBattler, 0); + gActiveBattler ^= 2; + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + sub_802F934(gActiveBattler, 0); + gActiveBattler ^= 2; + } + gBattleBankFunc[gActiveBattler] = sub_802D500; + gActiveBattler = savedActiveBank; + DestroyTask(taskId); + } +} + +void PlayerHandlecmd48(void) +{ + if (gBattleBufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == 0) + { + PlayerBufferExecCompleted(); + } + else + { + ewram17810[gActiveBattler].unk0_0 = 1; + gUnknown_02024E68[gActiveBattler] = sub_8044804(gActiveBattler, (struct BattleInterfaceStruct2 *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); + ewram17810[gActiveBattler].unk5 = 0; + if (gBattleBufferA[gActiveBattler][2] != 0) + ewram17810[gActiveBattler].unk5 = 0x5D; + gBattleBankFunc[gActiveBattler] = sub_8031064; + } +} + +void sub_8031064(void) +{ + if (ewram17810[gActiveBattler].unk5++ > 0x5C) + { + ewram17810[gActiveBattler].unk5 = 0; + PlayerBufferExecCompleted(); + } +} + +void PlayerHandlecmd49(void) +{ + if (ewram17810[gActiveBattler].unk0_0) + gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd50(void) +{ + dp11b_obj_free(gActiveBattler, 1); + dp11b_obj_free(gActiveBattler, 0); + PlayerBufferExecCompleted(); +} + +void PlayerHandleSpriteInvisibility(void) +{ + if (IsBankSpritePresent(gActiveBattler)) + { + gSprites[gBankSpriteIds[gActiveBattler]].invisible = gBattleBufferA[gActiveBattler][1]; + sub_8031F88(gActiveBattler); + } + PlayerBufferExecCompleted(); +} + +void PlayerHandleBattleAnimation(void) +{ + if (!mplay_80342A4(gActiveBattler)) + { + u8 val2 = gBattleBufferA[gActiveBattler][1]; + u16 val = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + + if (move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, val2, val)) + PlayerBufferExecCompleted(); + else + gBattleBankFunc[gActiveBattler] = sub_802E460; + } +} + +void PlayerHandleLinkStandbyMsg(void) +{ + switch (gBattleBufferA[gActiveBattler][1]) + { + case 0: + b_link_standby_message(); + // fall through + case 1: + dp11b_obj_free(gActiveBattler, 1); + dp11b_obj_free(gActiveBattler, 0); + break; + case 2: + b_link_standby_message(); + break; + } + PlayerBufferExecCompleted(); +} + +void PlayerHandleResetActionMoveSelection(void) +{ + switch (gBattleBufferA[gActiveBattler][1]) + { + case 0: + gActionSelectionCursor[gActiveBattler] = 0; + gMoveSelectionCursor[gActiveBattler] = 0; + break; + case 1: + gActionSelectionCursor[gActiveBattler] = 0; + break; + case 2: + gMoveSelectionCursor[gActiveBattler] = 0; + break; + } + PlayerBufferExecCompleted(); +} + +void PlayerHandlecmd55(void) +{ + gBattleOutcome = gBattleBufferA[gActiveBattler][1]; + FadeOutMapMusic(5); + BeginFastPaletteFade(3); + PlayerBufferExecCompleted(); + gBattleBankFunc[gActiveBattler] = sub_802D18C; +} + +void PlayerHandlecmd56(void) +{ +} diff --git a/src/battle_controller_safari.c b/src/battle_controller_safari.c new file mode 100644 index 000000000..e547c4a3c --- /dev/null +++ b/src/battle_controller_safari.c @@ -0,0 +1,720 @@ +#include "global.h" +#include "battle_anim_81258BC.h" +#include "battle.h" +#include "battle_interface.h" +#include "battle_message.h" +#include "data2.h" +#include "link.h" +#include "main.h" +#include "menu_cursor.h" +#include "palette.h" +#include "rom3.h" +#include "constants/songs.h" +#include "sound.h" +#include "text.h" +#include "util.h" +#include "ewram.h" + +extern struct Window gUnknown_03004210; +extern u8 gDisplayedStringBattle[]; +extern u8 gActionSelectionCursor[]; + +extern const u8 BattleText_PlayerMenu[]; +extern u8 gActiveBattler; +extern const u8 BattleText_MenuOptionsSafari[]; + +extern void *gBattleBankFunc[]; +extern u8 gBattleBufferA[][0x200]; +extern bool8 gDoingBattleAnim; +extern u8 gBankSpriteIds[]; +extern struct SpriteTemplate gUnknown_02024E8C; +extern u16 gBattleTypeFlags; +extern u32 gBattleExecBuffer; +extern u16 gSpecialVar_ItemId; +extern MainCallback gPreBattleCallback1; +extern u8 gBankInMenu; +extern u8 gHealthboxIDs[]; +extern u16 gBattlerPartyIndexes[]; +extern u16 gUnknown_02024DE8; +extern u8 gBattleOutcome; + +extern u8 GetBattlerSide(u8); +extern u8 GetBattlerAtPosition(u8); +extern u8 GetBattlerPosition(u8); +extern void LoadPlayerTrainerBankSprite(); +extern u8 GetBattlerSubpriority(); +extern void sub_80313A0(struct Sprite *); +extern void sub_810BADC(void); +extern void sub_8045A5C(); +extern void StartBattleIntroAnim(); +extern void sub_804777C(); +extern void sub_8043DFC(); +extern bool8 move_anim_start_t3(); + +#if ENGLISH +#define SUB_812BB10_TILE_DATA_OFFSET 440 +#elif GERMAN +#define SUB_812BB10_TILE_DATA_OFFSET 444 +#endif + +// this file's functions +void SafariHandleGetAttributes(void); +void SafariHandlecmd1(void); +void SafariHandleSetAttributes(void); +void SafariHandlecmd3(void); +void SafariHandleLoadPokeSprite(void); +void SafariHandleSendOutPoke(void); +void SafariHandleReturnPokeToBall(void); +void SafariHandleTrainerThrow(void); +void SafariHandleTrainerSlide(void); +void SafariHandleTrainerSlideBack(void); +void SafariHandlecmd10(void); +void SafariHandlecmd11(void); +void SafariHandlecmd12(void); +void SafariHandleBallThrow(void); +void SafariHandlePuase(void); +void SafariHandleMoveAnimation(void); +void SafariHandlePrintString(void); +void SafariHandlePrintStringPlayerOnly(void); +void SafariHandlecmd18(void); +void SafariHandlecmd19(void); +void SafariHandlecmd20(void); +void SafariHandleOpenBag(void); +void SafariHandlecmd22(void); +void SafariHandlecmd23(void); +void SafariHandleHealthBarUpdate(void); +void SafariHandleExpBarUpdate(void); +void SafariHandleStatusIconUpdate(void); +void SafariHandleStatusAnimation(void); +void SafariHandleStatusXor(void); +void SafariHandlecmd29(void); +void SafariHandleDMATransfer(void); +void SafariHandlecmd31(void); +void SafariHandlecmd32(void); +void SafariHandlecmd33(void); +void SafariHandlecmd34(void); +void SafariHandlecmd35(void); +void SafariHandlecmd36(void); +void SafariHandlecmd37(void); +void SafariHandlecmd38(void); +void SafariHandlecmd39(void); +void SafariHandlecmd40(void); +void SafariHandleHitAnimation(void); +void SafariHandlecmd42(void); +void SafariHandleEffectivenessSound(void); +void SafariHandlecmd44(void); +void SafariHandleFaintingCry(void); +void SafariHandleIntroSlide(void); +void SafariHandleTrainerBallThrow(void); +void SafariHandlecmd48(void); +void SafariHandlecmd49(void); +void SafariHandlecmd50(void); +void SafariHandleSpriteInvisibility(void); +void SafariHandleBattleAnimation(void); +void SafariHandleLinkStandbyMsg(void); +void SafariHandleResetActionMoveSelection(void); +void SafariHandlecmd55(void); +void SafariHandlecmd56(void); + +// const data +typedef void (*BattleBufferCmd) (void); +const BattleBufferCmd gSafariBufferCommands[] = +{ + SafariHandleGetAttributes, + SafariHandlecmd1, + SafariHandleSetAttributes, + SafariHandlecmd3, + SafariHandleLoadPokeSprite, + SafariHandleSendOutPoke, + SafariHandleReturnPokeToBall, + SafariHandleTrainerThrow, + SafariHandleTrainerSlide, + SafariHandleTrainerSlideBack, + SafariHandlecmd10, + SafariHandlecmd11, + SafariHandlecmd12, + SafariHandleBallThrow, + SafariHandlePuase, + SafariHandleMoveAnimation, + SafariHandlePrintString, + SafariHandlePrintStringPlayerOnly, + SafariHandlecmd18, + SafariHandlecmd19, + SafariHandlecmd20, + SafariHandleOpenBag, + SafariHandlecmd22, + SafariHandlecmd23, + SafariHandleHealthBarUpdate, + SafariHandleExpBarUpdate, + SafariHandleStatusIconUpdate, + SafariHandleStatusAnimation, + SafariHandleStatusXor, + SafariHandlecmd29, + SafariHandleDMATransfer, + SafariHandlecmd31, + SafariHandlecmd32, + SafariHandlecmd33, + SafariHandlecmd34, + SafariHandlecmd35, + SafariHandlecmd36, + SafariHandlecmd37, + SafariHandlecmd38, + SafariHandlecmd39, + SafariHandlecmd40, + SafariHandleHitAnimation, + SafariHandlecmd42, + SafariHandleEffectivenessSound, + SafariHandlecmd44, + SafariHandleFaintingCry, + SafariHandleIntroSlide, + SafariHandleTrainerBallThrow, + SafariHandlecmd48, + SafariHandlecmd49, + SafariHandlecmd50, + SafariHandleSpriteInvisibility, + SafariHandleBattleAnimation, + SafariHandleLinkStandbyMsg, + SafariHandleResetActionMoveSelection, + SafariHandlecmd55, + SafariHandlecmd56, +}; +// code + +void SafariBufferExecCompleted(void); +void bx_wait_t6(void); +void sub_812B65C(void); +void SafariBufferRunCommand(void); +void sub_812B758(void); + +void unref_sub_812B464(void) +{ +} + +void SetBankFuncToSafariBufferRunCommand(void) +{ + gBattleBankFunc[gActiveBattler] = SafariBufferRunCommand; +} + +void SafariBufferRunCommand(void) +{ + if (gBattleExecBuffer & gBitTable[gActiveBattler]) + { + if (gBattleBufferA[gActiveBattler][0] < 0x39) + gSafariBufferCommands[gBattleBufferA[gActiveBattler][0]](); + else + SafariBufferExecCompleted(); + } +} + +void bx_battle_menu_t6_2(void) +{ + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + DestroyMenuCursor(); + + // Useless switch statement. + switch (gActionSelectionCursor[gActiveBattler]) + { + case 0: + Emitcmd33(1, 5, 0); + break; + case 1: + Emitcmd33(1, 6, 0); + break; + case 2: + Emitcmd33(1, 7, 0); + break; + case 3: + Emitcmd33(1, 8, 0); + break; + } + SafariBufferExecCompleted(); + } + else if (gMain.newKeys & DPAD_LEFT) + { + if (gActionSelectionCursor[gActiveBattler] & 1) + { + PlaySE(SE_SELECT); + nullsub_8(gActionSelectionCursor[gActiveBattler]); + gActionSelectionCursor[gActiveBattler] ^= 1; + sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); + } + } + else if (gMain.newKeys & DPAD_RIGHT) + { + if (!(gActionSelectionCursor[gActiveBattler] & 1)) + { + PlaySE(SE_SELECT); + nullsub_8(gActionSelectionCursor[gActiveBattler]); + gActionSelectionCursor[gActiveBattler] ^= 1; + sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); + } + } + else if (gMain.newKeys & DPAD_UP) + { + if (gActionSelectionCursor[gActiveBattler] & 2) + { + PlaySE(SE_SELECT); + nullsub_8(gActionSelectionCursor[gActiveBattler]); + gActionSelectionCursor[gActiveBattler] ^= 2; + sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); + } + } + else if (gMain.newKeys & DPAD_DOWN) + { + if (!(gActionSelectionCursor[gActiveBattler] & 2)) + { + PlaySE(SE_SELECT); + nullsub_8(gActionSelectionCursor[gActiveBattler]); + gActionSelectionCursor[gActiveBattler] ^= 2; + sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); + } + } +#if DEBUG + else if (gMain.newKeys & R_BUTTON) + { + if (!ewram17810[gActiveBattler].unk0_5) + move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, 4, 0); + } + else if (gMain.newKeys & START_BUTTON) + { + sub_804454C(); + } +#endif +} + +void sub_812B65C(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + SafariBufferExecCompleted(); +} + +void sub_812B694(void) +{ + if (gUnknown_03004210.state == 0) + SafariBufferExecCompleted(); +} + +void sub_812B6AC(void) +{ + if (!gPaletteFade.active) + { + gMain.inBattle = FALSE; + gMain.callback1 = gPreBattleCallback1; + SetMainCallback2(gMain.savedCallback); + } +} + +void bx_wait_t6(void) +{ + if (!gDoingBattleAnim || !ewram17810[gActiveBattler].unk0_6) + SafariBufferExecCompleted(); +} + +void sub_812B724(void) +{ + if (!gPaletteFade.active) + { + gBattleBankFunc[gActiveBattler] = sub_812B758; + sub_810BADC(); + } +} + +void sub_812B758(void) +{ + if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) + { + Emitcmd35(1, gSpecialVar_ItemId); + SafariBufferExecCompleted(); + } +} + +void sub_812B794(void) +{ + if (!ewram17810[gActiveBattler].unk0_5) + SafariBufferExecCompleted(); +} + +void SafariBufferExecCompleted(void) +{ + gBattleBankFunc[gActiveBattler] = SafariBufferRunCommand; + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + u8 playerId = GetMultiplayerId(); + + PrepareBufferDataTransferLink(2, 4, &playerId); + gBattleBufferA[gActiveBattler][0] = 0x38; + } + else + { + gBattleExecBuffer &= ~gBitTable[gActiveBattler]; + } +} + +void unref_sub_812B838(void) +{ + if (!ewram17810[gActiveBattler].unk0_4) + SafariBufferExecCompleted(); +} + +void SafariHandleGetAttributes(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd1(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleSetAttributes(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd3(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleLoadPokeSprite(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleSendOutPoke(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleReturnPokeToBall(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleTrainerThrow(void) +{ + LoadPlayerTrainerBankSprite(gSaveBlock2.playerGender, gActiveBattler); + GetMonSpriteTemplate_803C5A0(gSaveBlock2.playerGender, GetBattlerPosition(gActiveBattler)); + gBankSpriteIds[gActiveBattler] = CreateSprite( + &gUnknown_02024E8C, + 80, + (8 - gTrainerBackPicCoords[gSaveBlock2.playerGender].coords) * 4 + 80, + 30); + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; + gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = 240; + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = -2; + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; + gBattleBankFunc[gActiveBattler] = sub_812B65C; +} + +void SafariHandleTrainerSlide(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleTrainerSlideBack(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd10(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd11(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd12(void) +{ + ewram17840.unk8 = 4; + gDoingBattleAnim = 1; + move_anim_start_t4(gActiveBattler, gActiveBattler, GetBattlerAtPosition(1), 4); + gBattleBankFunc[gActiveBattler] = bx_wait_t6; +} + +void SafariHandleBallThrow(void) +{ + u8 var = gBattleBufferA[gActiveBattler][1]; + + ewram17840.unk8 = var; + gDoingBattleAnim = 1; + move_anim_start_t4(gActiveBattler, gActiveBattler, GetBattlerAtPosition(1), 4); + gBattleBankFunc[gActiveBattler] = bx_wait_t6; +} + +// TODO: spell Pause correctly +void SafariHandlePuase(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleMoveAnimation(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlePrintString(void) +{ + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + BufferStringBattle(*(u16 *)&gBattleBufferA[gActiveBattler][2]); + Text_InitWindow8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 144, 2, 15); + gBattleBankFunc[gActiveBattler] = sub_812B694; +} + +void SafariHandlePrintStringPlayerOnly(void) +{ + if (GetBattlerSide(gActiveBattler) == 0) + SafariHandlePrintString(); + else + SafariBufferExecCompleted(); +} + +void SafariHandlecmd18(void) +{ + int i; + + gBattle_BG0_X = 0; + gBattle_BG0_Y = 160; + gUnknown_03004210.paletteNum = 0; + Text_FillWindowRectDefPalette(&gUnknown_03004210, 10, 2, 15, 27, 18); + Text_FillWindowRectDefPalette(&gUnknown_03004210, 10, 2, 35, 16, 36); + gBattleBankFunc[gActiveBattler] = bx_battle_menu_t6_2; + + Text_InitWindow(&gUnknown_03004210, BattleText_MenuOptionsSafari, 400, 18, 35); + Text_PrintWindow8002F44(&gUnknown_03004210); + MenuCursor_Create814A5C0(0, 0xFFFF, 12, 11679, 0); + + for (i = 0; i < 4; i++) + nullsub_8(i); + + sub_802E3E4(gActionSelectionCursor[gActiveBattler], 0); + StrCpyDecodeToDisplayedStringBattle(BattleText_PlayerMenu); + + Text_InitWindow(&gUnknown_03004210, gDisplayedStringBattle, SUB_812BB10_TILE_DATA_OFFSET, 2, 35); + Text_PrintWindow8002F44(&gUnknown_03004210); +} + +void SafariHandlecmd19(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd20(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleOpenBag(void) +{ + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); + gBattleBankFunc[gActiveBattler] = sub_812B724; + gBankInMenu = gActiveBattler; +} + +void SafariHandlecmd22(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd23(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleHealthBarUpdate(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleExpBarUpdate(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleStatusIconUpdate(void) +{ + sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 11); + SafariBufferExecCompleted(); +} + +void SafariHandleStatusAnimation(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleStatusXor(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd29(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleDMATransfer(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd31(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd32(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd33(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd34(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd35(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd36(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd37(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd38(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd39(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd40(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleHitAnimation(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd42(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleEffectivenessSound(void) +{ + s8 pan; + + if (GetBattlerSide(gActiveBattler) == 0) + pan = -64; + else + pan = 63; + PlaySE12WithPanning(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8), pan); + SafariBufferExecCompleted(); +} + +void SafariHandlecmd44(void) +{ + PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + SafariBufferExecCompleted(); +} + +void SafariHandleFaintingCry(void) +{ + u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES); + + PlayCry1(species, 25); + SafariBufferExecCompleted(); +} + +void SafariHandleIntroSlide(void) +{ + StartBattleIntroAnim(gBattleBufferA[gActiveBattler][1]); + gUnknown_02024DE8 |= 1; + SafariBufferExecCompleted(); +} + +void SafariHandleTrainerBallThrow(void) +{ + sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 10); + sub_804777C(gActiveBattler); + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + SafariBufferExecCompleted(); +} + +void SafariHandlecmd48(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd49(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd50(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleSpriteInvisibility(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleBattleAnimation(void) +{ + u8 r3 = gBattleBufferA[gActiveBattler][1]; + u16 r4 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + + if (move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, r3, r4) != 0) + SafariBufferExecCompleted(); + else + gBattleBankFunc[gActiveBattler] = sub_812B794; +} + +void SafariHandleLinkStandbyMsg(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandleResetActionMoveSelection(void) +{ + SafariBufferExecCompleted(); +} + +void SafariHandlecmd55(void) +{ + gBattleOutcome = gBattleBufferA[gActiveBattler][1]; + FadeOutMapMusic(5); + BeginFastPaletteFade(3); + SafariBufferExecCompleted(); + if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && !(gBattleTypeFlags & BATTLE_TYPE_WILD)) + gBattleBankFunc[gActiveBattler] = sub_812B6AC; +} + +void SafariHandlecmd56(void) +{ +} diff --git a/src/battle_controller_wally.c b/src/battle_controller_wally.c new file mode 100644 index 000000000..807ec1572 --- /dev/null +++ b/src/battle_controller_wally.c @@ -0,0 +1,1605 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "battle_anim_special.h" +#include "battle_interface.h" +#include "battle_message.h" +#include "data2.h" +#include "link.h" +#include "main.h" +#include "menu_cursor.h" +#include "palette.h" +#include "pokemon.h" +#include "rom3.h" +#include "constants/songs.h" +#include "sound.h" +#include "sprite.h" +#include "item_use.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "util.h" +#include "ewram.h" + +struct MovePpInfo +{ + u16 moves[4]; + u8 pp[4]; + u8 ppBonuses; +}; + +extern u8 gActiveBattler; +extern void (*gBattleBankFunc[])(void); +extern u32 gBattleExecBuffer; +extern u8 gBattleBufferA[][0x200]; +extern u8 gBankSpriteIds[]; +extern MainCallback gPreBattleCallback1; +extern bool8 gDoingBattleAnim; +extern u16 gBattlerPartyIndexes[]; +extern u8 gHealthboxIDs[]; +extern u16 gBattleTypeFlags; +extern u16 gAnimMovePower; +extern s32 gAnimMoveDmg; +extern u8 gAnimFriendship; +extern u16 gWeatherMoveAnim; +extern u32 gTransformedPersonalities[]; +extern void (*gAnimScriptCallback)(void); +extern bool8 gAnimScriptActive; +extern u8 gDisplayedStringBattle[]; +extern u8 gBankInMenu; +extern u8 gBattleMonForms[]; +extern u8 gBattleOutcome; +extern u16 gUnknown_02024DE8; +extern u8 gUnknown_02024E68[]; +extern struct SpriteTemplate gUnknown_02024E8C; +extern u8 gAnimMoveTurn; +extern struct Window gUnknown_03004210; +extern u8 gUnknown_0300434C[]; +extern const u8 BattleText_WallyMenu[]; +extern const u8 BattleText_MenuOptions[]; + +// TODO: include rom3.h when my other PR gets merged +extern void Emitcmd33(u8, u8, u16); +extern void Emitcmd35(u8, u16); + +extern void nullsub_14(void); +extern void PrepareBagForWallyTutorial(void); +extern void sub_8045A5C(); +extern void sub_804777C(); +extern void sub_8043DFC(); +extern bool8 IsDoubleBattle(void); +extern void c3_0802FDF4(u8); +extern void PlayerHandlecmd1(void); +extern void LoadPlayerTrainerBankSprite(); +extern u8 GetBattlerPosition(u8); +extern void sub_80313A0(struct Sprite *); +extern u8 GetBattlerAtPosition(u8); +extern u8 sub_8031720(); +extern void DoMoveAnim(); +extern void sub_80326EC(); +extern void sub_8031F24(void); +extern void sub_80324BC(); +extern void BufferStringBattle(); +extern u8 GetBattlerSide(u8); +extern void sub_80304A8(void); +extern void sub_8047858(); +extern void StartBattleIntroAnim(); +extern void oamt_add_pos2_onto_pos1(); +extern void StartAnimLinearTranslation(struct Sprite *); +extern void sub_8030E38(struct Sprite *); +extern void StoreSpriteCallbackInData(); +extern u8 StartSendOutMonAnimation(); +extern u8 GetBattlerSpriteCoord(); +extern u8 sub_8077F68(); +extern u8 GetBattlerSubpriority(); +extern void sub_80312F0(struct Sprite *); +extern bool8 move_anim_start_t3(); + +// this file's functions + +void WallyBufferRunCommand(void); +void sub_81374FC(void); +void sub_81376B8(void); +void WallyBufferExecCompleted(void); +u32 sub_8137A84(u8, u8 *); +void sub_8138294(u8); +void sub_81390D0(void); +void sub_8139A2C(u8); + +void WallyHandleGetAttributes(void); +void WallyHandlecmd1(void); +void WallyHandleSetAttributes(void); +void WallyHandlecmd3(void); +void WallyHandleLoadPokeSprite(void); +void WallyHandleSendOutPoke(void); +void WallyHandleReturnPokeToBall(void); +void WallyHandleTrainerThrow(void); +void WallyHandleTrainerSlide(void); +void WallyHandleTrainerSlideBack(void); +void WallyHandlecmd10(void); +void WallyHandlecmd11(void); +void WallyHandlecmd12(void); +void WallyHandleBallThrow(void); +void WallyHandlePuase(void); +void WallyHandleMoveAnimation(void); +void WallyHandlePrintString(void); +void WallyHandlePrintStringPlayerOnly(void); +void WallyHandlecmd18(void); +void WallyHandlecmd19(void); +void WallyHandlecmd20(void); +void WallyHandleOpenBag(void); +void WallyHandlecmd22(void); +void WallyHandlecmd23(void); +void WallyHandleHealthBarUpdate(void); +void WallyHandleExpBarUpdate(void); +void WallyHandleStatusIconUpdate(void); +void WallyHandleStatusAnimation(void); +void WallyHandleStatusXor(void); +void WallyHandlecmd29(void); +void WallyHandleDMATransfer(void); +void WallyHandlecmd31(void); +void WallyHandlecmd32(void); +void WallyHandlecmd33(void); +void WallyHandlecmd34(void); +void WallyHandlecmd35(void); +void WallyHandlecmd36(void); +void WallyHandlecmd37(void); +void WallyHandlecmd38(void); +void WallyHandlecmd39(void); +void WallyHandlecmd40(void); +void WallyHandleHitAnimation(void); +void WallyHandlecmd42(void); +void WallyHandleEffectivenessSound(void); +void WallyHandlecmd44(void); +void WallyHandleFaintingCry(void); +void WallyHandleIntroSlide(void); +void WallyHandleTrainerBallThrow(void); +void WallyHandlecmd48(void); +void WallyHandlecmd49(void); +void WallyHandlecmd50(void); +void WallyHandleSpriteInvisibility(void); +void WallyHandleBattleAnimation(void); +void WallyHandleLinkStandbyMsg(void); +void WallyHandleResetActionMoveSelection(void); +void WallyHandlecmd55(void); +void WallyHandlecmd56(void); + +// const data + +typedef void (*BattleBufferCmd) (void); +static const BattleBufferCmd gWallyBufferCommands[] = +{ + WallyHandleGetAttributes, + WallyHandlecmd1, + WallyHandleSetAttributes, + WallyHandlecmd3, + WallyHandleLoadPokeSprite, + WallyHandleSendOutPoke, + WallyHandleReturnPokeToBall, + WallyHandleTrainerThrow, + WallyHandleTrainerSlide, + WallyHandleTrainerSlideBack, + WallyHandlecmd10, + WallyHandlecmd11, + WallyHandlecmd12, + WallyHandleBallThrow, + WallyHandlePuase, + WallyHandleMoveAnimation, + WallyHandlePrintString, + WallyHandlePrintStringPlayerOnly, + WallyHandlecmd18, + WallyHandlecmd19, + WallyHandlecmd20, + WallyHandleOpenBag, + WallyHandlecmd22, + WallyHandlecmd23, + WallyHandleHealthBarUpdate, + WallyHandleExpBarUpdate, + WallyHandleStatusIconUpdate, + WallyHandleStatusAnimation, + WallyHandleStatusXor, + WallyHandlecmd29, + WallyHandleDMATransfer, + WallyHandlecmd31, + WallyHandlecmd32, + WallyHandlecmd33, + WallyHandlecmd34, + WallyHandlecmd35, + WallyHandlecmd36, + WallyHandlecmd37, + WallyHandlecmd38, + WallyHandlecmd39, + WallyHandlecmd40, + WallyHandleHitAnimation, + WallyHandlecmd42, + WallyHandleEffectivenessSound, + WallyHandlecmd44, + WallyHandleFaintingCry, + WallyHandleIntroSlide, + WallyHandleTrainerBallThrow, + WallyHandlecmd48, + WallyHandlecmd49, + WallyHandlecmd50, + WallyHandleSpriteInvisibility, + WallyHandleBattleAnimation, + WallyHandleLinkStandbyMsg, + WallyHandleResetActionMoveSelection, + WallyHandlecmd55, + WallyHandlecmd56, +}; + +// code + +void unref_sub_8137220(void) +{ +} + +void SetBankFuncToWallyBufferRunCommand(void) +{ + gBattleBankFunc[gActiveBattler] = WallyBufferRunCommand; + ewram160A8 = 0; + ewram160A9 = 0; + ewram160AA = 0; + ewram160AB = 0; +} + +void WallyBufferRunCommand(void) +{ + if (gBattleExecBuffer & gBitTable[gActiveBattler]) + { + if (gBattleBufferA[gActiveBattler][0] < 0x39) + gWallyBufferCommands[gBattleBufferA[gActiveBattler][0]](); + else + WallyBufferExecCompleted(); + } +} + +void sub_81372BC(void) +{ + u8 r4; + + switch (ewram160A8) + { + case 0: + ewram160AA = 64; + ewram160A8++; + // fall through + case 1: + r4 = --ewram160AA; + if (r4 == 0) + { + PlaySE(SE_SELECT); + Emitcmd33(1, 0, 0); + WallyBufferExecCompleted(); + ewram160A8++; + ewram160A9 = r4; + ewram160AA = 64; + } + break; + case 2: + r4 = --ewram160AA; + if (r4 == 0) + { + PlaySE(SE_SELECT); + Emitcmd33(1, 0, 0); + WallyBufferExecCompleted(); + ewram160A8++; + ewram160A9 = r4; + ewram160AA = 64; + } + break; + case 3: + r4 = --ewram160AA; + if (r4 == 0) + { + Emitcmd33(1, 9, 0); + WallyBufferExecCompleted(); + ewram160A8++; + ewram160A9 = r4; + ewram160AA = 64; + } + break; + case 4: + if (--ewram160AA == 0) + { + PlaySE(SE_SELECT); + nullsub_8(0); + sub_802E3E4(1, 0); + ewram160AA = 64; + ewram160A8++; + } + break; + case 5: + if (--ewram160AA == 0) + { + PlaySE(SE_SELECT); + DestroyMenuCursor(); + Emitcmd33(1, 1, 0); + WallyBufferExecCompleted(); + } + break; + } +} + +void sub_813741C(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + WallyBufferExecCompleted(); +} + +void sub_8137454(void) +{ + if (gUnknown_03004210.state == 0) + WallyBufferExecCompleted(); +} + +void sub_813746C(void) +{ + if (!gPaletteFade.active) + { + gMain.inBattle = FALSE; + gMain.callback1 = gPreBattleCallback1; + SetMainCallback2(gMain.savedCallback); + } +} + +void bx_wait_t5(void) +{ + if (!gDoingBattleAnim) + WallyBufferExecCompleted(); +} + +void sub_81374C4(void) +{ + if (!gPaletteFade.active) + { + gBattleBankFunc[gActiveBattler] = sub_81374FC; + nullsub_14(); + PrepareBagForWallyTutorial(); + } +} + +void sub_81374FC(void) +{ + if (gMain.callback2 == BattleMainCB2 + && !gPaletteFade.active) + { + Emitcmd35(1, gSpecialVar_ItemId); + WallyBufferExecCompleted(); + } +} + +void sub_8137538(void) +{ + if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler].unk0_7) + sub_8141828(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]); + + if (!ewram17810[gActiveBattler ^ 2].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_7) + sub_8141828(gActiveBattler ^ 2, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ 2]]); + + if (!ewram17810[gActiveBattler].unk0_3 && !ewram17810[gActiveBattler ^ 2].unk0_3) + { + if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + { + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler ^ 2]]); + sub_8045A5C(gHealthboxIDs[gActiveBattler ^ 2], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ 2]], 0); + sub_804777C(gActiveBattler ^ 2); + sub_8043DFC(gHealthboxIDs[gActiveBattler ^ 2]); + } + DestroySprite(&gSprites[gUnknown_0300434C[gActiveBattler]]); + sub_8045A5C(gHealthboxIDs[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], 0); + sub_804777C(gActiveBattler); + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + ewram17840.unk9_0 = 0; + gBattleBankFunc[gActiveBattler] = sub_81376B8; + } +} + +void sub_81376B8(void) +{ + bool8 r4 = FALSE; + + if (gSprites[gHealthboxIDs[gActiveBattler]].callback == SpriteCallbackDummy) + r4 = TRUE; + if (r4 && ewram17810[gActiveBattler].unk1_0 && ewram17810[gActiveBattler ^ 2].unk1_0) + { + ewram17810[gActiveBattler].unk0_7 = 0; + ewram17810[gActiveBattler].unk1_0 = 0; + ewram17810[gActiveBattler ^ 2].unk0_7 = 0; + ewram17810[gActiveBattler ^ 2].unk1_0 = 0; + FreeSpriteTilesByTag(0x27F9); + FreeSpritePaletteByTag(0x27F9); + CreateTask(c3_0802FDF4, 10); + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + WallyBufferExecCompleted(); + } +} + +void sub_81377B0(void) +{ + s16 r4; + + r4 = sub_8045C78(gActiveBattler, gHealthboxIDs[gActiveBattler], 0, 0); + sub_8043DFC(gHealthboxIDs[gActiveBattler]); + if (r4 != -1) + { + sub_80440EC(gHealthboxIDs[gActiveBattler], r4, 0); + } + else + { + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + WallyBufferExecCompleted(); + } +} + +void bx_blink_t5(void) +{ + u8 spriteId = gBankSpriteIds[gActiveBattler]; + + if (gSprites[spriteId].data[1] == 32) + { + gSprites[spriteId].data[1] = 0; + gSprites[spriteId].invisible = FALSE; + gDoingBattleAnim = FALSE; + WallyBufferExecCompleted(); + } + else + { + if (((u16)gSprites[spriteId].data[1] % 4) == 0) + gSprites[spriteId].invisible ^= 1; + gSprites[spriteId].data[1]++; + } +} + +void sub_813789C(void) +{ + if (!ewram17810[gActiveBattler].unk0_6) + { + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + WallyBufferExecCompleted(); + } +} + +// Duplicate of sub_813741C +void sub_8137908(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy) + WallyBufferExecCompleted(); +} + +void sub_8137940(void) +{ + if (!ewram17810[gActiveBattler].unk0_5) + WallyBufferExecCompleted(); +} + +void WallyBufferExecCompleted(void) +{ + gBattleBankFunc[gActiveBattler] = WallyBufferRunCommand; + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + u8 multiplayerId = GetMultiplayerId(); + + PrepareBufferDataTransferLink(2, 4, &multiplayerId); + gBattleBufferA[gActiveBattler][0] = 0x38; + } + else + { + gBattleExecBuffer &= ~gBitTable[gActiveBattler]; + } +} + +void unref_sub_81379E4(void) +{ + if (!ewram17810[gActiveBattler].unk0_4) + WallyBufferExecCompleted(); +} + +void WallyHandleGetAttributes(void) +{ + u8 arr[0x100]; + u32 r6 = 0; + u8 r4; + s32 i; + + if (gBattleBufferA[gActiveBattler][2] == 0) + { + r6 = sub_8137A84(gBattlerPartyIndexes[gActiveBattler], arr); + } + else + { + r4 = gBattleBufferA[gActiveBattler][2]; + for (i = 0; i < 6; i++) + { + if (r4 & 1) + r6 += sub_8137A84(i, arr + r6); + r4 >>= 1; + } + } + Emitcmd29(1, r6, arr); + WallyBufferExecCompleted(); +} + +u32 sub_8137A84(u8 a, u8 *buffer) +{ + struct BattlePokemon battlePokemon; + struct MovePpInfo moveData; + u8 nickname[20]; + u8 *src; + s16 data16; + u32 data32; + s32 size = 0; + + switch (gBattleBufferA[gActiveBattler][1]) + { + case 0: + battlePokemon.species = GetMonData(&gPlayerParty[a], MON_DATA_SPECIES); + battlePokemon.item = GetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM); + for (size = 0; size < 4; size++) + { + battlePokemon.moves[size] = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + size); + battlePokemon.pp[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); + } + battlePokemon.ppBonuses = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); + battlePokemon.friendship = GetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP); + battlePokemon.experience = GetMonData(&gPlayerParty[a], MON_DATA_EXP); + battlePokemon.hpIV = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); + battlePokemon.attackIV = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); + battlePokemon.defenseIV = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); + battlePokemon.speedIV = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); + battlePokemon.spAttackIV = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); + battlePokemon.spDefenseIV = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); + battlePokemon.personality = GetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY); + battlePokemon.status1 = GetMonData(&gPlayerParty[a], MON_DATA_STATUS); + battlePokemon.level = GetMonData(&gPlayerParty[a], MON_DATA_LEVEL); + battlePokemon.hp = GetMonData(&gPlayerParty[a], MON_DATA_HP); + battlePokemon.maxHP = GetMonData(&gPlayerParty[a], MON_DATA_MAX_HP); + battlePokemon.attack = GetMonData(&gPlayerParty[a], MON_DATA_ATK); + battlePokemon.defense = GetMonData(&gPlayerParty[a], MON_DATA_DEF); + battlePokemon.speed = GetMonData(&gPlayerParty[a], MON_DATA_SPEED); + battlePokemon.spAttack = GetMonData(&gPlayerParty[a], MON_DATA_SPATK); + battlePokemon.spDefense = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF); + battlePokemon.isEgg = GetMonData(&gPlayerParty[a], MON_DATA_IS_EGG); + battlePokemon.altAbility = GetMonData(&gPlayerParty[a], MON_DATA_ALT_ABILITY); + battlePokemon.otId = GetMonData(&gPlayerParty[a], MON_DATA_OT_ID); + GetMonData(&gPlayerParty[a], MON_DATA_NICKNAME, nickname); + StringCopy10(battlePokemon.nickname, nickname); + GetMonData(&gPlayerParty[a], MON_DATA_OT_NAME, battlePokemon.otName); + MEMCPY_ALT(&battlePokemon, buffer, sizeof(battlePokemon), size, src); + break; + case 1: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPECIES); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 2: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 3: + for (size = 0; size < 4; size++) + { + moveData.moves[size] = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + size); + moveData.pp[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); + } + moveData.ppBonuses = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); + MEMCPY_ALT(&moveData, buffer, sizeof(moveData), size, src); + break; + case 4: + case 5: + case 6: + case 7: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 8: + for (size = 0; size < 4; size++) + buffer[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + size); + buffer[size] = GetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES); + size++; + break; + case 9: + case 10: + case 11: + case 12: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9); + size = 1; + break; + case 17: + data32 = GetMonData(&gPlayerParty[a], MON_DATA_OT_ID); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + size = 3; + break; + case 18: + data32 = GetMonData(&gPlayerParty[a], MON_DATA_EXP); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + size = 3; + break; + case 19: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_EV); + size = 1; + break; + case 20: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_EV); + size = 1; + break; + case 21: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_EV); + size = 1; + break; + case 22: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_EV); + size = 1; + break; + case 23: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_EV); + size = 1; + break; + case 24: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_EV); + size = 1; + break; + case 25: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP); + size = 1; + break; + case 26: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_POKERUS); + size = 1; + break; + case 27: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_LOCATION); + size = 1; + break; + case 28: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_LEVEL); + size = 1; + break; + case 29: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_MET_GAME); + size = 1; + break; + case 30: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_POKEBALL); + size = 1; + break; + case 31: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); + buffer[1] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); + buffer[2] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); + buffer[3] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); + buffer[4] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); + buffer[5] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); + size = 6; + break; + case 32: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_HP_IV); + size = 1; + break; + case 33: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_ATK_IV); + size = 1; + break; + case 34: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_DEF_IV); + size = 1; + break; + case 35: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV); + size = 1; + break; + case 36: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV); + size = 1; + break; + case 37: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV); + size = 1; + break; + case 38: + data32 = GetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + buffer[3] = (data32 & 0xFF000000) >> 24; + size = 4; + break; + case 39: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_CHECKSUM); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 40: + data32 = GetMonData(&gPlayerParty[a], MON_DATA_STATUS); + buffer[0] = (data32 & 0x000000FF); + buffer[1] = (data32 & 0x0000FF00) >> 8; + buffer[2] = (data32 & 0x00FF0000) >> 16; + buffer[3] = (data32 & 0xFF000000) >> 24; + size = 4; + break; + case 41: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_LEVEL); + size = 1; + break; + case 42: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_HP); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 43: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_MAX_HP); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 44: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_ATK); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 45: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_DEF); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 46: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPEED); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 47: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPATK); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 48: + data16 = GetMonData(&gPlayerParty[a], MON_DATA_SPDEF); + buffer[0] = data16; + buffer[1] = data16 >> 8; + size = 2; + break; + case 49: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_COOL); + size = 1; + break; + case 50: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_BEAUTY); + size = 1; + break; + case 51: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_CUTE); + size = 1; + break; + case 52: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SMART); + size = 1; + break; + case 53: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_TOUGH); + size = 1; + break; + case 54: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SHEEN); + size = 1; + break; + case 55: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_COOL_RIBBON); + size = 1; + break; + case 56: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_BEAUTY_RIBBON); + size = 1; + break; + case 57: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_CUTE_RIBBON); + size = 1; + break; + case 58: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_SMART_RIBBON); + size = 1; + break; + case 59: + buffer[0] = GetMonData(&gPlayerParty[a], MON_DATA_TOUGH_RIBBON); + size = 1; + break; + } + return size; +} + +void WallyHandlecmd1(void) +{ + PlayerHandlecmd1(); +} + +void WallyHandleSetAttributes(void) +{ + u8 r4; + u8 i; + + if (gBattleBufferA[gActiveBattler][2] == 0) + { + sub_8138294(gBattlerPartyIndexes[gActiveBattler]); + } + else + { + r4 = gBattleBufferA[gActiveBattler][2]; + for (i = 0; i < 6; i++) + { + if (r4 & 1) + sub_8138294(i); + r4 >>= 1; + } + } + WallyBufferExecCompleted(); +} + +void sub_8138294(u8 a) +{ + struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBattler][3]; + struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBattler][3]; + s32 i; + + switch (gBattleBufferA[gActiveBattler][1]) + { + case 0: + { + u8 iv; + + SetMonData(&gPlayerParty[a], MON_DATA_SPECIES, &battlePokemon->species); + SetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM, &battlePokemon->item); + for (i = 0; i < 4; i++) + { + SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + i, &battlePokemon->moves[i]); + SetMonData(&gPlayerParty[a], MON_DATA_PP1 + i, &battlePokemon->pp[i]); + } + SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses); + SetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP, &battlePokemon->friendship); + SetMonData(&gPlayerParty[a], MON_DATA_EXP, &battlePokemon->experience); + iv = battlePokemon->hpIV; + SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &iv); + iv = battlePokemon->attackIV; + SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &iv); + iv = battlePokemon->defenseIV; + SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &iv); + iv = battlePokemon->speedIV; + SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &iv); + iv = battlePokemon->spAttackIV; + SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &iv); + iv = battlePokemon->spDefenseIV; + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &iv); + SetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY, &battlePokemon->personality); + SetMonData(&gPlayerParty[a], MON_DATA_STATUS, &battlePokemon->status1); + SetMonData(&gPlayerParty[a], MON_DATA_LEVEL, &battlePokemon->level); + SetMonData(&gPlayerParty[a], MON_DATA_HP, &battlePokemon->hp); + SetMonData(&gPlayerParty[a], MON_DATA_MAX_HP, &battlePokemon->maxHP); + SetMonData(&gPlayerParty[a], MON_DATA_ATK, &battlePokemon->attack); + SetMonData(&gPlayerParty[a], MON_DATA_DEF, &battlePokemon->defense); + SetMonData(&gPlayerParty[a], MON_DATA_SPEED, &battlePokemon->speed); + SetMonData(&gPlayerParty[a], MON_DATA_SPATK, &battlePokemon->spAttack); + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF, &battlePokemon->spDefense); + } + break; + case 1: + SetMonData(&gPlayerParty[a], MON_DATA_SPECIES, &gBattleBufferA[gActiveBattler][3]); + break; + case 2: + SetMonData(&gPlayerParty[a], MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]); + break; + case 3: + for (i = 0; i < 4; i++) + { + SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + i, &moveData->moves[i]); + SetMonData(&gPlayerParty[a], MON_DATA_PP1 + i, &moveData->pp[i]); + } + SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &moveData->ppBonuses); + break; + case 4: + case 5: + case 6: + case 7: + SetMonData(&gPlayerParty[a], MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - 4, &gBattleBufferA[gActiveBattler][3]); + break; + case 8: + SetMonData(&gPlayerParty[a], MON_DATA_PP1, &gBattleBufferA[gActiveBattler][3]); + SetMonData(&gPlayerParty[a], MON_DATA_PP2, &gBattleBufferA[gActiveBattler][4]); + SetMonData(&gPlayerParty[a], MON_DATA_PP3, &gBattleBufferA[gActiveBattler][5]); + SetMonData(&gPlayerParty[a], MON_DATA_PP4, &gBattleBufferA[gActiveBattler][6]); + SetMonData(&gPlayerParty[a], MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBattler][7]); + break; + case 9: + case 10: + case 11: + case 12: + SetMonData(&gPlayerParty[a], MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - 9, &gBattleBufferA[gActiveBattler][3]); + break; + case 17: + SetMonData(&gPlayerParty[a], MON_DATA_OT_ID, &gBattleBufferA[gActiveBattler][3]); + break; + case 18: + SetMonData(&gPlayerParty[a], MON_DATA_EXP, &gBattleBufferA[gActiveBattler][3]); + break; + case 19: + SetMonData(&gPlayerParty[a], MON_DATA_HP_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 20: + SetMonData(&gPlayerParty[a], MON_DATA_ATK_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 21: + SetMonData(&gPlayerParty[a], MON_DATA_DEF_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 22: + SetMonData(&gPlayerParty[a], MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 23: + SetMonData(&gPlayerParty[a], MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 24: + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBattler][3]); + break; + case 25: + SetMonData(&gPlayerParty[a], MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBattler][3]); + break; + case 26: + SetMonData(&gPlayerParty[a], MON_DATA_POKERUS, &gBattleBufferA[gActiveBattler][3]); + break; + case 27: + SetMonData(&gPlayerParty[a], MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBattler][3]); + break; + case 28: + SetMonData(&gPlayerParty[a], MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBattler][3]); + break; + case 29: + SetMonData(&gPlayerParty[a], MON_DATA_MET_GAME, &gBattleBufferA[gActiveBattler][3]); + break; + case 30: + SetMonData(&gPlayerParty[a], MON_DATA_POKEBALL, &gBattleBufferA[gActiveBattler][3]); + break; + case 31: + SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); + SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][4]); + SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][5]); + SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][6]); + SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][7]); + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][8]); + break; + case 32: + SetMonData(&gPlayerParty[a], MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 33: + SetMonData(&gPlayerParty[a], MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 34: + SetMonData(&gPlayerParty[a], MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 35: + SetMonData(&gPlayerParty[a], MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 36: + SetMonData(&gPlayerParty[a], MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 37: + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][3]); + break; + case 38: + SetMonData(&gPlayerParty[a], MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBattler][3]); + break; + case 39: + SetMonData(&gPlayerParty[a], MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBattler][3]); + break; + case 40: + SetMonData(&gPlayerParty[a], MON_DATA_STATUS, &gBattleBufferA[gActiveBattler][3]); + break; + case 41: + SetMonData(&gPlayerParty[a], MON_DATA_LEVEL, &gBattleBufferA[gActiveBattler][3]); + break; + case 42: + SetMonData(&gPlayerParty[a], MON_DATA_HP, &gBattleBufferA[gActiveBattler][3]); + break; + case 43: + SetMonData(&gPlayerParty[a], MON_DATA_MAX_HP, &gBattleBufferA[gActiveBattler][3]); + break; + case 44: + SetMonData(&gPlayerParty[a], MON_DATA_ATK, &gBattleBufferA[gActiveBattler][3]); + break; + case 45: + SetMonData(&gPlayerParty[a], MON_DATA_DEF, &gBattleBufferA[gActiveBattler][3]); + break; + case 46: + SetMonData(&gPlayerParty[a], MON_DATA_SPEED, &gBattleBufferA[gActiveBattler][3]); + break; + case 47: + SetMonData(&gPlayerParty[a], MON_DATA_SPATK, &gBattleBufferA[gActiveBattler][3]); + break; + case 48: + SetMonData(&gPlayerParty[a], MON_DATA_SPDEF, &gBattleBufferA[gActiveBattler][3]); + break; + case 49: + SetMonData(&gPlayerParty[a], MON_DATA_COOL, &gBattleBufferA[gActiveBattler][3]); + break; + case 50: + SetMonData(&gPlayerParty[a], MON_DATA_BEAUTY, &gBattleBufferA[gActiveBattler][3]); + break; + case 51: + SetMonData(&gPlayerParty[a], MON_DATA_CUTE, &gBattleBufferA[gActiveBattler][3]); + break; + case 52: + SetMonData(&gPlayerParty[a], MON_DATA_SMART, &gBattleBufferA[gActiveBattler][3]); + break; + case 53: + SetMonData(&gPlayerParty[a], MON_DATA_TOUGH, &gBattleBufferA[gActiveBattler][3]); + break; + case 54: + SetMonData(&gPlayerParty[a], MON_DATA_SHEEN, &gBattleBufferA[gActiveBattler][3]); + break; + case 55: + SetMonData(&gPlayerParty[a], MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 56: + SetMonData(&gPlayerParty[a], MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 57: + SetMonData(&gPlayerParty[a], MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 58: + SetMonData(&gPlayerParty[a], MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + case 59: + SetMonData(&gPlayerParty[a], MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBattler][3]); + break; + } + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); +} + +void WallyHandlecmd3(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleLoadPokeSprite(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleSendOutPoke(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleReturnPokeToBall(void) +{ + if (gBattleBufferA[gActiveBattler][1] == 0) + { + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 1); + gBattleBankFunc[gActiveBattler] = sub_813789C; + } + else + { + FreeSpriteOamMatrix(&gSprites[gBankSpriteIds[gActiveBattler]]); + DestroySprite(&gSprites[gBankSpriteIds[gActiveBattler]]); + sub_8043DB0(gHealthboxIDs[gActiveBattler]); + WallyBufferExecCompleted(); + } +} + +void WallyHandleTrainerThrow(void) +{ + LoadPlayerTrainerBankSprite(2, gActiveBattler); + GetMonSpriteTemplate_803C5A0(2, GetBattlerPosition(gActiveBattler)); + gBankSpriteIds[gActiveBattler] = CreateSprite( + &gUnknown_02024E8C, + 80, 80 + 4 * (8 - gTrainerBackPicCoords[2].coords), + 30); + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; + gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = 240; + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = -2; + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; + gBattleBankFunc[gActiveBattler] = sub_813741C; +} + +void WallyHandleTrainerSlide(void) +{ + LoadPlayerTrainerBankSprite(2, gActiveBattler); + GetMonSpriteTemplate_803C5A0(2, GetBattlerPosition(gActiveBattler)); + gBankSpriteIds[gActiveBattler] = CreateSprite( + &gUnknown_02024E8C, + 80, 80 + 4 * (8 - gTrainerBackPicCoords[2].coords), + 30); + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler; + gSprites[gBankSpriteIds[gActiveBattler]].pos2.x = -96; + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 2; + gSprites[gBankSpriteIds[gActiveBattler]].callback = sub_80313A0; + gBattleBankFunc[gActiveBattler] = sub_8137908; +} + +void WallyHandleTrainerSlideBack(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd10(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd11(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd12(void) +{ + ewram17840.unk8 = 4; + gDoingBattleAnim = TRUE; + move_anim_start_t4(gActiveBattler, gActiveBattler, GetBattlerAtPosition(1), 4); + gBattleBankFunc[gActiveBattler] = bx_wait_t5; +} + +void WallyHandleBallThrow(void) +{ + u8 val = gBattleBufferA[gActiveBattler][1]; + + ewram17840.unk8 = val; + gDoingBattleAnim = TRUE; + move_anim_start_t4(gActiveBattler, gActiveBattler, GetBattlerAtPosition(1), 4); + gBattleBankFunc[gActiveBattler] = bx_wait_t5; +} + +void WallyHandlePuase(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleMoveAnimation(void) +{ + u16 move = gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8); + + gAnimMoveTurn = gBattleBufferA[gActiveBattler][3]; + gAnimMovePower = gBattleBufferA[gActiveBattler][4] | (gBattleBufferA[gActiveBattler][5] << 8); + gAnimMoveDmg = gBattleBufferA[gActiveBattler][6] | (gBattleBufferA[gActiveBattler][7] << 8) | (gBattleBufferA[gActiveBattler][8] << 16) | (gBattleBufferA[gActiveBattler][9] << 24); + gAnimFriendship = gBattleBufferA[gActiveBattler][10]; + gWeatherMoveAnim = gBattleBufferA[gActiveBattler][12] | (gBattleBufferA[gActiveBattler][13] << 8); + gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBattler][16]; + gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality; + if (sub_8031720(move, gAnimMoveTurn) != 0) + { + // Dead code. sub_8031720 always returns 0. + WallyBufferExecCompleted(); + } + else + { + ewram17810[gActiveBattler].unk4 = 0; + gBattleBankFunc[gActiveBattler] = sub_81390D0; + } +} + +void sub_81390D0(void) +{ + u16 r4 = gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8); + +#ifndef NONMATCHING + asm("":::"r6"); +#endif + + switch (ewram17810[gActiveBattler].unk4) + { + case 0: + if (ewram17800[gActiveBattler].substituteSprite == 1) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 5); + ewram17810[gActiveBattler].unk4 = 1; + break; + case 1: + if (ewram17810[gActiveBattler].unk0_6 == 0) + { + sub_80326EC(0); + DoMoveAnim(r4); + ewram17810[gActiveBattler].unk4 = 2; + } + break; + case 2: + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + sub_80326EC(1); + if (ewram17800[gActiveBattler].substituteSprite == 1) + move_anim_start_t4(gActiveBattler, gActiveBattler, gActiveBattler, 6); + ewram17810[gActiveBattler].unk4 = 3; + } + break; + case 3: + if (ewram17810[gActiveBattler].unk0_6 == 0) + { + sub_8031F24(); + sub_80324BC(gActiveBattler, gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + ewram17810[gActiveBattler].unk4 = 0; + WallyBufferExecCompleted(); + } + break; + } +} + +void WallyHandlePrintString(void) +{ + u16 *ptr; + + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + ptr = (u16 *)&gBattleBufferA[gActiveBattler][2]; + if (*ptr == 2) + DestroyMenuCursor(); + BufferStringBattle(*ptr); + Text_InitWindow8002EB0(&gUnknown_03004210, gDisplayedStringBattle, 0x90, 2, 15); + gBattleBankFunc[gActiveBattler] = sub_8137454; +} + +void WallyHandlePrintStringPlayerOnly(void) +{ + if (GetBattlerSide(gActiveBattler) == 0) + WallyHandlePrintString(); + else + WallyBufferExecCompleted(); +} + +void WallyHandlecmd18(void) +{ + s32 i; + + gBattle_BG0_X = 0; + gBattle_BG0_Y = 160; + gUnknown_03004210.paletteNum = 0; + Text_FillWindowRectDefPalette(&gUnknown_03004210, 10, 2, 15, 27, 18); + Text_FillWindowRectDefPalette(&gUnknown_03004210, 10, 2, 35, 16, 36); + gBattleBankFunc[gActiveBattler] = sub_81372BC; + Text_InitWindow(&gUnknown_03004210, BattleText_MenuOptions, 400, 18, 35); + Text_PrintWindow8002F44(&gUnknown_03004210); + MenuCursor_Create814A5C0(0, 0xFFFF, 12, 0x2D9F, 0); + for (i = 0; i < 4; i++) + nullsub_8(i); + sub_802E3E4(0, 0); + StrCpyDecodeToDisplayedStringBattle(BattleText_WallyMenu); +#ifdef ENGLISH + Text_InitWindow(&gUnknown_03004210, gDisplayedStringBattle, 440, 2, 35); +#else + Text_InitWindow(&gUnknown_03004210, gDisplayedStringBattle, 444, 2, 35); +#endif + Text_PrintWindow8002F44(&gUnknown_03004210); +} + +void WallyHandlecmd19(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd20(void) +{ + switch (ewram160A9) + { + case 0: + sub_80304A8(); + ewram160A9++; + ewram160AB = 80; + // fall through + case 1: + ewram160AB--; + if (ewram160AB == 0) + { + DestroyMenuCursor(); + PlaySE(SE_SELECT); + Emitcmd33(1, 10, 256); + WallyBufferExecCompleted(); + } + break; + } +} + +void WallyHandleOpenBag(void) +{ + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); + gBattleBankFunc[gActiveBattler] = sub_81374C4; + gBankInMenu = gActiveBattler; +} + +void WallyHandlecmd22(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd23(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleHealthBarUpdate(void) +{ + s16 r7; + + load_gfxc_health_bar(0); + r7 = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + if (r7 != 0x7FFF) + { + u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); + u32 curHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_HP); + + sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, curHP, r7); + } + else + { + u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); + + sub_8043D84(gActiveBattler, gHealthboxIDs[gActiveBattler], maxHP, 0, r7); + sub_80440EC(gHealthboxIDs[gActiveBattler], 0, 0); + } + gBattleBankFunc[gActiveBattler] = sub_81377B0; +} + +void WallyHandleExpBarUpdate(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleStatusIconUpdate(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleStatusAnimation(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleStatusXor(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd29(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleDMATransfer(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd31(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd32(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd33(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd34(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd35(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd36(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd37(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd38(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd39(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd40(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleHitAnimation(void) +{ + if (gSprites[gBankSpriteIds[gActiveBattler]].invisible == TRUE) + { + WallyBufferExecCompleted(); + } + else + { + gDoingBattleAnim = 1; + gSprites[gBankSpriteIds[gActiveBattler]].data[1] = 0; + sub_8047858(gActiveBattler); + gBattleBankFunc[gActiveBattler] = bx_blink_t5; + } +} + +void WallyHandlecmd42(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleEffectivenessSound(void) +{ + PlaySE(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + WallyBufferExecCompleted(); +} + +void WallyHandlecmd44(void) +{ + PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8)); + WallyBufferExecCompleted(); +} + +void WallyHandleFaintingCry(void) +{ + PlayCry1(GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES), 25); + WallyBufferExecCompleted(); +} + +void WallyHandleIntroSlide(void) +{ + StartBattleIntroAnim(gBattleBufferA[gActiveBattler][1]); + gUnknown_02024DE8 |= 1; + WallyBufferExecCompleted(); +} + +void WallyHandleTrainerBallThrow(void) +{ + u8 paletteNum; + u8 taskId; + + oamt_add_pos2_onto_pos1(&gSprites[gBankSpriteIds[gActiveBattler]]); + gSprites[gBankSpriteIds[gActiveBattler]].data[0] = 50; + gSprites[gBankSpriteIds[gActiveBattler]].data[2] = -40; + gSprites[gBankSpriteIds[gActiveBattler]].data[4] = gSprites[gBankSpriteIds[gActiveBattler]].pos1.y; + gSprites[gBankSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation; + gSprites[gBankSpriteIds[gActiveBattler]].data[5] = gActiveBattler; + StoreSpriteCallbackInData(&gSprites[gBankSpriteIds[gActiveBattler]], sub_8030E38); + StartSpriteAnim(&gSprites[gBankSpriteIds[gActiveBattler]], 1); + paletteNum = AllocSpritePalette(0xD6F8); + LoadCompressedPalette(gTrainerBackPicPaletteTable[2].data, 0x100 + paletteNum * 16, 32); + gSprites[gBankSpriteIds[gActiveBattler]].oam.paletteNum = paletteNum; + taskId = CreateTask(sub_8139A2C, 5); + gTasks[taskId].data[0] = gActiveBattler; + if (ewram17810[gActiveBattler].unk0_0) + gTasks[gUnknown_02024E68[gActiveBattler]].func = sub_8044CA0; + ewram17810[4].unk9 |= 1; + gBattleBankFunc[gActiveBattler] = nullsub_91; +} + +void sub_81398BC(u8 bank) +{ + u16 species; + + ewram17800[bank].transformedSpecies = 0; + gBattlerPartyIndexes[bank] = gBattleBufferA[bank][1]; + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES); + gUnknown_0300434C[bank] = CreateInvisibleSpriteWithCallback(sub_80312F0); + GetMonSpriteTemplate_803C56C(species, GetBattlerPosition(bank)); + gBankSpriteIds[bank] = CreateSprite( + &gUnknown_02024E8C, + GetBattlerSpriteCoord(bank, 2), + sub_8077F68(bank), + GetBattlerSubpriority(bank)); + gSprites[gUnknown_0300434C[bank]].data[1] = gBankSpriteIds[bank]; + gSprites[gBankSpriteIds[bank]].data[0] = bank; + gSprites[gBankSpriteIds[bank]].data[2] = species; + gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; + StartSpriteAnim(&gSprites[gBankSpriteIds[bank]], gBattleMonForms[bank]); + gSprites[gBankSpriteIds[bank]].invisible = TRUE; + gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; + gSprites[gUnknown_0300434C[bank]].data[0] = StartSendOutMonAnimation(0, 0xFF); +} + +void sub_8139A2C(u8 taskId) +{ + if (gTasks[taskId].data[1] < 31) + { + gTasks[taskId].data[1]++; + } + else + { + u8 savedActiveBank = gActiveBattler; + + gActiveBattler = gTasks[taskId].data[0]; + gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler]; + sub_81398BC(gActiveBattler); + gBattleBankFunc[gActiveBattler] = sub_8137538; + gActiveBattler = savedActiveBank; + DestroyTask(taskId); + } +} + +void WallyHandlecmd48(void) +{ + if (gBattleBufferA[gActiveBattler][1] != 0 && GetBattlerSide(gActiveBattler) == 0) + { + WallyBufferExecCompleted(); + } + else + { + ewram17810[gActiveBattler].unk0_0 = 1; + gUnknown_02024E68[gActiveBattler] = sub_8044804(gActiveBattler, (struct BattleInterfaceStruct2 *)&gBattleBufferA[gActiveBattler][4], gBattleBufferA[gActiveBattler][1], gBattleBufferA[gActiveBattler][2]); + WallyBufferExecCompleted(); + } +} + +void WallyHandlecmd49(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd50(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleSpriteInvisibility(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleBattleAnimation(void) +{ + u8 val2 = gBattleBufferA[gActiveBattler][1]; + u16 val = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8); + + if (move_anim_start_t3(gActiveBattler, gActiveBattler, gActiveBattler, val2, val)) + WallyBufferExecCompleted(); + else + gBattleBankFunc[gActiveBattler] = sub_8137940; +} + +void WallyHandleLinkStandbyMsg(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandleResetActionMoveSelection(void) +{ + WallyBufferExecCompleted(); +} + +void WallyHandlecmd55(void) +{ + gBattleOutcome = gBattleBufferA[gActiveBattler][1]; + FadeOutMapMusic(5); + BeginFastPaletteFade(3); + WallyBufferExecCompleted(); + if ((gBattleTypeFlags & BATTLE_TYPE_LINK) && !(gBattleTypeFlags & BATTLE_TYPE_WILD)) + gBattleBankFunc[gActiveBattler] = sub_813746C; +} + +void WallyHandlecmd56(void) +{ +} diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c new file mode 100644 index 000000000..80cbed64e --- /dev/null +++ b/src/battle_gfx_sfx_util.c @@ -0,0 +1,969 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "battle_anim_special.h" +#include "battle_interface.h" +#include "blend_palette.h" +#include "contest.h" +#include "data2.h" +#include "decompress.h" +#include "main.h" +#include "m4a.h" +#include "palette.h" +#include "pokemon.h" +#include "rom_8077ABC.h" +#include "rom_8094928.h" +#include "constants/songs.h" +#include "sound.h" +#include "constants/species.h" +#include "sprite.h" +#include "task.h" +#include "text.h" +#include "gba/m4a_internal.h" +#include "ewram.h" +#include "graphics.h" + +extern u8 gBattleBufferA[][0x200]; +extern u8 gActiveBattler; +extern u8 gBattlersCount; +extern u16 gBattlerPartyIndexes[]; +extern u8 gBanksBySide[]; +extern u8 gBankSpriteIds[]; +extern u16 gUnknown_02024DE8; +extern u8 gDoingBattleAnim; +extern u32 gTransformedPersonalities[]; +extern struct Window gUnknown_03004210; +extern void (*gBattleBankFunc[])(void); +extern u8 gHealthboxIDs[]; +extern u8 gUnknown_0300434C[]; +extern struct MusicPlayerInfo gMPlay_SE1; +extern struct MusicPlayerInfo gMPlay_SE2; +extern struct MusicPlayerInfo gMPlay_BGM; +extern u32 gBitTable[]; +extern u16 gBattleTypeFlags; +extern u8 gBattleMonForms[]; +extern u8 gBattleAnimAttacker; +extern u8 gBattleAnimTarget; +extern void (*gAnimScriptCallback)(void); +extern u8 gAnimScriptActive; +extern const u8 *const gBattleAnims_General[]; +extern const u8 *const gBattleAnims_Special[]; +extern const struct CompressedSpriteSheet gTrainerFrontPicTable[]; +extern const struct MonCoords gTrainerFrontPicCoords[]; +extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[]; +extern const struct CompressedSpriteSheet gUnknown_081FAF24; +extern const struct SpriteTemplate gSpriteTemplate_81FAF34; +extern const u8 gSubstituteDollTilemap[]; // graphics.s +extern const u8 gSubstituteDollGfx[]; // graphics.s +extern const u8 gSubstituteDollPal[]; // graphics.s +extern const u8 gUnknown_08D09C48[]; // graphics.s + +const struct CompressedSpriteSheet gUnknown_0820A47C = +{ gBattleWindowLargeGfx, 4096, 0xd6ff }; + +const struct CompressedSpriteSheet gUnknown_0820A484 = +{ gBattleWindowSmallGfx, 4096, 0xd701 }; + +const struct CompressedSpriteSheet gUnknown_0820A48C[] = +{ + { gBattleWindowSmall2Gfx, 2048, 0xd6ff }, + { gBattleWindowSmall2Gfx, 2048, 0xd700 }, +}; + +const struct CompressedSpriteSheet gUnknown_0820A49C[] = +{ + { gBattleWindowSmall3Gfx, 2048, 0xd701 }, + { gBattleWindowSmall3Gfx, 2048, 0xd702 }, +}; + +const struct CompressedSpriteSheet gUnknown_0820A4AC = +{ gBattleWindowLarge2Gfx, 4096, 0xd70b }; + +const struct CompressedSpriteSheet gUnknown_0820A4B4[] = +{ + { gBlankGfxCompressed, 256, 0xd704 }, + { gBlankGfxCompressed, 288, 0xd705 }, + { gBlankGfxCompressed, 256, 0xd706 }, + { gBlankGfxCompressed, 288, 0xd707 }, +}; + +const struct SpritePalette gUnknown_0820A4D4[] = +{ + { gUnknown_08D1212C, 0xD6FF }, + { gUnknown_08D1214C, 0xD704 }, +}; + +extern void c3_0802FDF4(u8); +extern void sub_80440EC(); +extern void sub_804777C(); +extern u8 GetBattlerSpriteCoord(); +extern u8 IsBankSpritePresent(u8); +extern u8 sub_8077F68(u8); +extern u8 sub_8077F7C(u8); +extern void sub_8094958(void); +extern void sub_80105DC(struct Sprite *); +extern void move_anim_start_t2(); + +void sub_80315E8(u8); +u8 sub_803163C(u8); +void sub_80316CC(u8); +void sub_8031F0C(void); +void refresh_graphics_maybe(u8, u8, u8); +void sub_80324E0(u8 a); +void sub_80327CC(void); +void sub_8032978(struct Sprite *); +void sub_80328A4(struct Sprite *); + +void sub_80312F0(struct Sprite *sprite) +{ + u8 spriteId = sprite->data[1]; + + if (gSprites[spriteId].affineAnimEnded && !gSprites[spriteId].invisible) + { + if (gSprites[spriteId].animPaused) + gSprites[spriteId].animPaused = FALSE; + else if (gSprites[spriteId].animEnded) + { + gSprites[spriteId].callback = sub_80105DC; + StartSpriteAffineAnim(&gSprites[spriteId], 0); + sprite->callback = SpriteCallbackDummy; + } + } +} + +void unref_sub_8031364(struct Sprite *sprite, bool8 stupid) +{ + sprite->animPaused = TRUE; + sprite->callback = SpriteCallbackDummy; + if (!stupid) + StartSpriteAffineAnim(sprite, 1); + else + StartSpriteAffineAnim(sprite, 1); + AnimateSprite(sprite); +} + +void sub_80313A0(struct Sprite *sprite) +{ + if (!(gUnknown_02024DE8 & 1)) + { + sprite->pos2.x += sprite->data[0]; + if (sprite->pos2.x == 0) + sprite->callback = SpriteCallbackDummy; + } +} + +void move_anim_start_t2_for_situation(u8 a, u32 b) +{ + ewram17810[gActiveBattler].unk0_4 = 1; + if (a == 0) + { + if (b == 0x20) + move_anim_start_t2(gActiveBattler, 6); + else if (b == 8 || (b & 0x80)) + move_anim_start_t2(gActiveBattler, 0); + else if (b == 0x10) + move_anim_start_t2(gActiveBattler, 2); + else if (b & 7) + move_anim_start_t2(gActiveBattler, 4); + else if (b == 0x40) + move_anim_start_t2(gActiveBattler, 5); + else + ewram17810[gActiveBattler].unk0_4 = 0; + } + else + { + if (b & 0x000F0000) + move_anim_start_t2(gActiveBattler, 3); + else if (b & 7) + move_anim_start_t2(gActiveBattler, 1); + else if (b & 0x10000000) + move_anim_start_t2(gActiveBattler, 7); + else if (b & 0x08000000) + move_anim_start_t2(gActiveBattler, 8); + else if (b & 0x0000E000) + move_anim_start_t2(gActiveBattler, 9); + else + ewram17810[gActiveBattler].unk0_4 = 0; + } +} + +bool8 move_anim_start_t3(u8 a, u8 b, u8 c, u8 d, u16 e) +{ + u8 taskId; + + if (d == 0 && (e & 0x80)) + { + gBattleMonForms[a] = e & 0x7F; + return TRUE; + } + if (ewram17800[a].substituteSprite && sub_803163C(d) == 0) + return TRUE; + if (ewram17800[a].substituteSprite && d == 2 && gSprites[gBankSpriteIds[a]].invisible) + { + refresh_graphics_maybe(a, 1, gBankSpriteIds[a]); + sub_80324E0(a); + return TRUE; + } + gBattleAnimAttacker = b; + gBattleAnimTarget = c; + ewram17840.unk0 = e; + LaunchBattleAnimation(gBattleAnims_General, d, 0); + taskId = CreateTask(sub_80315E8, 10); + gTasks[taskId].data[0] = a; + ewram17810[gTasks[taskId].data[0]].unk0_5 = 1; + return FALSE; +} + +void sub_80315E8(u8 taskId) +{ + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + ewram17810[gTasks[taskId].data[0]].unk0_5 = 0; + DestroyTask(taskId); + } +} + +u8 sub_803163C(u8 a) +{ + switch (a) + { + case 2: + case 10: + case 11: + case 12: + case 13: + case 17: + return 1; + default: + return 0; + } +} + +void move_anim_start_t4(u8 a, u8 b, u8 c, u8 d) +{ + u8 taskId; + + gBattleAnimAttacker = b; + gBattleAnimTarget = c; + LaunchBattleAnimation(gBattleAnims_Special, d, 0); + taskId = CreateTask(sub_80316CC, 10); + gTasks[taskId].data[0] = a; + ewram17810[gTasks[taskId].data[0]].unk0_6 = 1; +} + +void sub_80316CC(u8 taskId) +{ + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + ewram17810[gTasks[taskId].data[0]].unk0_6 = 0; + DestroyTask(taskId); + } +} + +u8 sub_8031720(int unused1, int unused2) +{ + return 0; +} + +bool8 mplay_80342A4(u8 a) +{ + u8 zero = 0; + + if (IsSEPlaying()) + { + ewram17810[a].unk8++; + if (ewram17810[gActiveBattler].unk8 < 30) + return TRUE; + m4aMPlayStop(&gMPlay_SE1); + m4aMPlayStop(&gMPlay_SE2); + } + if (zero == 0) + { + ewram17810[a].unk8 = 0; + return FALSE; + } + return TRUE; +} + +void BattleLoadOpponentMonSprite(struct Pokemon *pkmn, u8 b) +{ + u32 personalityValue; + u16 species; + u32 r7; + u32 otId; + u8 var; + u16 paletteOffset; + const u8 *lzPaletteData; + + personalityValue = GetMonData(pkmn, MON_DATA_PERSONALITY); + if (ewram17800[b].transformedSpecies == 0) + { + species = GetMonData(pkmn, MON_DATA_SPECIES); + r7 = personalityValue; + } + else + { + species = ewram17800[b].transformedSpecies; + r7 = gTransformedPersonalities[b]; + } + otId = GetMonData(pkmn, MON_DATA_OT_ID); + var = GetBattlerPosition(b); + HandleLoadSpecialPokePic( + &gMonFrontPicTable[species], + gMonFrontPicCoords[species].coords, + gMonFrontPicCoords[species].y_offset, + eVoidSharedArr2, + gUnknown_081FAF4C[var], + species, + r7); + paletteOffset = 0x100 + b * 16; + if (ewram17800[b].transformedSpecies == 0) + lzPaletteData = GetMonSpritePal(pkmn); + else + lzPaletteData = GetMonSpritePalFromOtIdPersonality(species, otId, personalityValue); + LZDecompressWram(lzPaletteData, gSharedMem); + LoadPalette(gSharedMem, paletteOffset, 0x20); + LoadPalette(gSharedMem, 0x80 + b * 16, 0x20); + if (species == SPECIES_CASTFORM) + { + paletteOffset = 0x100 + b * 16; + LZDecompressWram(lzPaletteData, ewram16400); + LoadPalette(ewram16400 + gBattleMonForms[b] * 32, paletteOffset, 0x20); + } + if (ewram17800[b].transformedSpecies != 0) + { + BlendPalette(paletteOffset, 16, 6, RGB(31, 31, 31)); + CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); + } +} + +void BattleLoadPlayerMonSprite(struct Pokemon *pkmn, u8 b) +{ + u32 personalityValue; + u16 species; + u32 r7; + u32 otId; + u8 var; + u16 paletteOffset; + const u8 *lzPaletteData; + + personalityValue = GetMonData(pkmn, MON_DATA_PERSONALITY); + if (ewram17800[b].transformedSpecies == 0) + { + species = GetMonData(pkmn, MON_DATA_SPECIES); + r7 = personalityValue; + } + else + { + species = ewram17800[b].transformedSpecies; + r7 = gTransformedPersonalities[b]; + } + otId = GetMonData(pkmn, MON_DATA_OT_ID); + var = GetBattlerPosition(b); + HandleLoadSpecialPokePic( + &gMonBackPicTable[species], + gMonBackPicCoords[species].coords, + gMonBackPicCoords[species].y_offset, + eVoidSharedArr2, + gUnknown_081FAF4C[var], + species, + r7); + paletteOffset = 0x100 + b * 16; + if (ewram17800[b].transformedSpecies == 0) + lzPaletteData = GetMonSpritePal(pkmn); + else + lzPaletteData = GetMonSpritePalFromOtIdPersonality(species, otId, personalityValue); + LZDecompressWram(lzPaletteData, gSharedMem); + LoadPalette(gSharedMem, paletteOffset, 0x20); + LoadPalette(gSharedMem, 0x80 + b * 16, 0x20); + if (species == SPECIES_CASTFORM) + { + paletteOffset = 0x100 + b * 16; + LZDecompressWram(lzPaletteData, ewram16400); + LoadPalette(ewram16400 + gBattleMonForms[b] * 32, paletteOffset, 0x20); + } + if (ewram17800[b].transformedSpecies != 0) + { + BlendPalette(paletteOffset, 16, 6, RGB(31, 31, 31)); + CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); + } +} + +void unref_sub_8031A64(void) +{ +} + +void nullsub_9(u16 unused) +{ +} + +void sub_8031A6C(u16 a, u8 b) +{ + u8 status; + struct CompressedSpriteSheet spriteSheet; + + status = GetBattlerPosition(b); + DecompressPicFromTable_2( + &gTrainerFrontPicTable[a], + gTrainerFrontPicCoords[a].coords, + gTrainerFrontPicCoords[a].y_offset, + eVoidSharedArr, + gUnknown_081FAF4C[status], + 0); + spriteSheet.data = gUnknown_081FAF4C[status]; + spriteSheet.size = gTrainerFrontPicTable[a].size; + spriteSheet.tag = gTrainerFrontPicTable[a].tag; + LoadCompressedObjectPic(&spriteSheet); + LoadCompressedObjectPalette(&gTrainerFrontPicPaletteTable[a]); +} + +void LoadPlayerTrainerBankSprite(u16 a, u8 b) +{ + u8 status; + + status = GetBattlerPosition(b); + DecompressPicFromTable_2( + &gTrainerBackPicTable[a], + gTrainerBackPicCoords[a].coords, + gTrainerBackPicCoords[a].y_offset, + eVoidSharedArr, + gUnknown_081FAF4C[status], + 0); + LoadCompressedPalette(gTrainerBackPicPaletteTable[a].data, 0x100 + b * 16, 32); +} + +void nullsub_10(int unused) +{ +} + +void sub_8031B74(u16 a) +{ + FreeSpritePaletteByTag(gTrainerFrontPicPaletteTable[a].tag); + FreeSpriteTilesByTag(gTrainerFrontPicTable[a].tag); +} + +void unref_sub_8031BA0(void) +{ + u8 count; + u8 i; + + LoadSpritePalette(&gUnknown_0820A4D4[0]); + LoadSpritePalette(&gUnknown_0820A4D4[1]); + if (!IsDoubleBattle()) + { + LoadCompressedObjectPic(&gUnknown_0820A47C); + LoadCompressedObjectPic(&gUnknown_0820A484); + count = 2; + } + else + { + LoadCompressedObjectPic(&gUnknown_0820A48C[0]); + LoadCompressedObjectPic(&gUnknown_0820A48C[1]); + LoadCompressedObjectPic(&gUnknown_0820A49C[0]); + LoadCompressedObjectPic(&gUnknown_0820A49C[1]); + count = 4; + } + for (i = 0; i < count; i++) + LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[i]]); +} + +bool8 sub_8031C30(u8 a) +{ + bool8 retVal = FALSE; + + if (a != 0) + { + if (a == 1) + { + LoadSpritePalette(&gUnknown_0820A4D4[0]); + LoadSpritePalette(&gUnknown_0820A4D4[1]); + } + else if (!IsDoubleBattle()) + { + if (a == 2) + { + if (gBattleTypeFlags & 0x80) + LoadCompressedObjectPic(&gUnknown_0820A4AC); + else + LoadCompressedObjectPic(&gUnknown_0820A47C); + } + else if (a == 3) + LoadCompressedObjectPic(&gUnknown_0820A484); + else if (a == 4) + LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[0]]); + else if (a == 5) + LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[1]]); + else + retVal = TRUE; + } + else + { + if (a == 2) + LoadCompressedObjectPic(&gUnknown_0820A48C[0]); + else if (a == 3) + LoadCompressedObjectPic(&gUnknown_0820A48C[1]); + else if (a == 4) + LoadCompressedObjectPic(&gUnknown_0820A49C[0]); + else if (a == 5) + LoadCompressedObjectPic(&gUnknown_0820A49C[1]); + else if (a == 6) + LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[0]]); + else if (a == 7) + LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[1]]); + else if (a == 8) + LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[2]]); + else if (a == 9) + LoadCompressedObjectPic(&gUnknown_0820A4B4[gBanksBySide[3]]); + else + retVal = TRUE; + } + } + return retVal; +} + +void load_gfxc_health_bar(u8 a) +{ + LZDecompressWram(gUnknown_08D09C48, eVoidSharedArr); +} + +u8 battle_load_something(u8 *pState, u8 *b) +{ + bool8 retVal = FALSE; + + switch (*pState) + { + case 0: + sub_8031F0C(); + (*pState)++; + break; + case 1: + if (sub_8031C30(*b) == 0) + { + (*b)++; + } + else + { + *b = 0; + (*pState)++; + } + break; + case 2: + (*pState)++; + break; + case 3: + if ((gBattleTypeFlags & 0x80) && *b == 0) + gHealthboxIDs[*b] = battle_make_oam_safari_battle(); + else + gHealthboxIDs[*b] = battle_make_oam_normal_battle(*b); + (*b)++; + if (*b == gBattlersCount) + { + *b = 0; + (*pState)++; + } + break; + case 4: + sub_8043F44(*b); + if (gBanksBySide[*b] <= 1) + nullsub_11(gHealthboxIDs[*b], 0); + else + nullsub_11(gHealthboxIDs[*b], 1); + (*b)++; + if (*b == gBattlersCount) + { + *b = 0; + (*pState)++; + } + break; + case 5: + if (GetBattlerSide(*b) == 0) + { + if (!(gBattleTypeFlags & 0x80)) + sub_8045A5C(gHealthboxIDs[*b], &gPlayerParty[gBattlerPartyIndexes[*b]], 0); + } + else + { + sub_8045A5C(gHealthboxIDs[*b], &gEnemyParty[gBattlerPartyIndexes[*b]], 0); + } + sub_8043DB0(gHealthboxIDs[*b]); + (*b)++; + if (*b == gBattlersCount) + { + *b = 0; + (*pState)++; + } + break; + case 6: + sub_80327CC(); + sub_8094958(); + retVal = TRUE; + break; + } + return retVal; +} + +void sub_8031EE8(void) +{ + memset(ewram17810, 0, 0x30); + memset(&ewram17840, 0, 0x10); +} + +void sub_8031F0C(void) +{ + sub_8031EE8(); + memset(ewram17800, 0, 0x10); +} + +void sub_8031F24(void) +{ + s32 i; + + for (i = 0; i < gBattlersCount; i++) + ewram17800[i].invisible = gSprites[gBankSpriteIds[i]].invisible; +} + +void sub_8031F88(u8 a) +{ + ewram17800[a].invisible = gSprites[gBankSpriteIds[a]].invisible; +} + +void sub_8031FC4(u8 a, u8 b, bool8 c) +{ + u16 paletteOffset; + u16 species; + u32 personalityValue; + u32 otId; + u8 r10; + const u8 *lzPaletteData; + + if (c) + { + StartSpriteAnim(&gSprites[gBankSpriteIds[a]], ewram17840.unk0); + paletteOffset = 0x100 + a * 16; + LoadPalette(ewram16400 + ewram17840.unk0 * 32, paletteOffset, 32); + gBattleMonForms[a] = ewram17840.unk0; + if (ewram17800[a].transformedSpecies != 0) + { + BlendPalette(paletteOffset, 16, 6, RGB(31, 31, 31)); + CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); + } + gSprites[gBankSpriteIds[a]].pos1.y = sub_8077F68(a); + } + else + { + if (IsContest()) + { + r10 = 0; + species = shared19348.unk2; + personalityValue = shared19348.unk8; + otId = shared19348.unkC; + HandleLoadSpecialPokePic( + &gMonBackPicTable[species], + gMonBackPicCoords[species].coords, + gMonBackPicCoords[species].y_offset, + eVoidSharedArr2, + gUnknown_081FAF4C[0], + species, + shared19348.unk10); + } + else + { + r10 = GetBattlerPosition(a); + if (GetBattlerSide(b) == 1) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[b]], MON_DATA_SPECIES); + else + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[b]], MON_DATA_SPECIES); + if (GetBattlerSide(a) == 0) + { + personalityValue = GetMonData(&gPlayerParty[gBattlerPartyIndexes[a]], MON_DATA_PERSONALITY); + otId = GetMonData(&gPlayerParty[gBattlerPartyIndexes[a]], MON_DATA_OT_ID); + HandleLoadSpecialPokePic( + &gMonBackPicTable[species], + gMonBackPicCoords[species].coords, + gMonBackPicCoords[species].y_offset, + eVoidSharedArr2, + gUnknown_081FAF4C[r10], + species, + gTransformedPersonalities[a]); + } + else + { + personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[a]], MON_DATA_PERSONALITY); + otId = GetMonData(&gEnemyParty[gBattlerPartyIndexes[a]], MON_DATA_OT_ID); + HandleLoadSpecialPokePic( + &gMonFrontPicTable[species], + gMonFrontPicCoords[species].coords, + gMonFrontPicCoords[species].y_offset, + eVoidSharedArr2, + gUnknown_081FAF4C[r10], + species, + gTransformedPersonalities[a]); + } + } + DmaCopy32Defvars(3, gUnknown_081FAF4C[r10], (void *)(VRAM + 0x10000 + gSprites[gBankSpriteIds[a]].oam.tileNum * 32), 0x800); + paletteOffset = 0x100 + a * 16; + lzPaletteData = GetMonSpritePalFromOtIdPersonality(species, otId, personalityValue); + LZDecompressWram(lzPaletteData, gSharedMem); + LoadPalette(gSharedMem, paletteOffset, 32); + if (species == SPECIES_CASTFORM) + { + u16 *paletteSrc = (u16 *)ewram16400; // TODO: avoid casting? + + LZDecompressWram(lzPaletteData, paletteSrc); + LoadPalette(paletteSrc + gBattleMonForms[b] * 16, paletteOffset, 32); + } + BlendPalette(paletteOffset, 16, 6, RGB(31, 31, 31)); + CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); + if (!IsContest()) + { + ewram17800[a].transformedSpecies = species; + gBattleMonForms[a] = gBattleMonForms[b]; + } + gSprites[gBankSpriteIds[a]].pos1.y = sub_8077F68(a); + StartSpriteAnim(&gSprites[gBankSpriteIds[a]], gBattleMonForms[a]); + } +} + +void BattleLoadSubstituteSprite(u8 a, u8 b) +{ + u8 r4; + u16 foo; + const u8 *gSubstituteDollPal_; + void *src; + s32 i; + + if (b == 0) + { + if (IsContest()) + r4 = 0; + else + r4 = GetBattlerPosition(a); + if (IsContest()) + LZDecompressVram(gSubstituteDollTilemap, gUnknown_081FAF4C[r4]); + else if (GetBattlerSide(a) != 0) + LZDecompressVram(gSubstituteDollGfx, gUnknown_081FAF4C[r4]); + else + LZDecompressVram(gSubstituteDollTilemap, gUnknown_081FAF4C[r4]); + // There is probably a way to do this without all the temp variables, but I couldn't figure it out. + foo = a * 16; + gSubstituteDollPal_ = gSubstituteDollPal; + src = gUnknown_081FAF4C[r4]; + for (i = 0; i < 3; i++) + DmaCopy32(3, src, src + i * 0x800 + 0x800, 0x800); + LoadCompressedPalette(gSubstituteDollPal_, 0x100 + foo, 32); + } + else + { + if (!IsContest()) + { + if (GetBattlerSide(a) != 0) + BattleLoadOpponentMonSprite(&gEnemyParty[gBattlerPartyIndexes[a]], a); + else + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[a]], a); + } + } +} + +void refresh_graphics_maybe(u8 a, u8 b, u8 spriteId) +{ + BattleLoadSubstituteSprite(a, b); + StartSpriteAnim(&gSprites[spriteId], gBattleMonForms[a]); + if (b == 0) + gSprites[spriteId].pos1.y = sub_8077F7C(a); + else + gSprites[spriteId].pos1.y = sub_8077F68(a); +} + +void sub_80324BC(u8 a, u16 b) +{ + if (b == 0xA4) + ewram17800[a].substituteSprite = 1; +} + +void sub_80324E0(u8 a) +{ + ewram17800[a].substituteSprite = 0; +} + +void HandleLowHpMusicChange(struct Pokemon *pkmn, u8 b) +{ + u16 hp = GetMonData(pkmn, MON_DATA_HP); + u16 maxHP = GetMonData(pkmn, MON_DATA_MAX_HP); + + if (GetHPBarLevel(hp, maxHP) == 1) + { + if (!ewram17800[b].unk0_1) + { + if (!ewram17800[b ^ 2].unk0_1) + PlaySE(SE_HINSI); + ewram17800[b].unk0_1 = 1; + } + } + else + { + ewram17800[b].unk0_1 = 0; + if (!IsDoubleBattle()) + { + m4aSongNumStop(SE_HINSI); + return; + } + if (IsDoubleBattle() && !ewram17800[b ^ 2].unk0_1) + { + m4aSongNumStop(SE_HINSI); + return; + } + } +} + +void BattleStopLowHpSound(void) +{ + u8 r4 = GetBattlerAtPosition(0); + + ewram17800[r4].unk0_1 = 0; + if (IsDoubleBattle()) + ewram17800[r4 ^ 2].unk0_1 = 0; + m4aSongNumStop(SE_HINSI); +} + +u8 unref_sub_8032604(struct Pokemon *pkmn) +{ + u16 hp = GetMonData(pkmn, MON_DATA_HP); + u16 maxHP = GetMonData(pkmn, MON_DATA_MAX_HP); + + return GetHPBarLevel(hp, maxHP); +} + +void sub_8032638(void) +{ + if (gMain.inBattle) + { + u8 r8 = GetBattlerAtPosition(0); + u8 r9 = GetBattlerAtPosition(2); + u8 r4 = pokemon_order_func(gBattlerPartyIndexes[r8]); + u8 r5 = pokemon_order_func(gBattlerPartyIndexes[r9]); + + if (GetMonData(&gPlayerParty[r4], MON_DATA_HP) != 0) + HandleLowHpMusicChange(&gPlayerParty[r4], r8); + if (IsDoubleBattle()) + { + if (GetMonData(&gPlayerParty[r5], MON_DATA_HP) != 0) + HandleLowHpMusicChange(&gPlayerParty[r5], r9); + } + } +} + +void sub_80326EC(u8 a) +{ + s32 i; + + for (i = 0; i < gBattlersCount; i++) + { + if (IsBankSpritePresent(i) != 0) + { + gSprites[gBankSpriteIds[i]].oam.affineMode = a; + if (a == 0) + { + ewram17810[i].unk6 = gSprites[gBankSpriteIds[i]].oam.matrixNum; + gSprites[gBankSpriteIds[i]].oam.matrixNum = 0; + } + else + { + gSprites[gBankSpriteIds[i]].oam.matrixNum = ewram17810[i].unk6; + } + } + } +} + +void sub_80327CC(void) +{ + u8 r5; + + LoadCompressedObjectPic(&gUnknown_081FAF24); + r5 = GetBattlerAtPosition(1); + ewram17810[r5].unk7 = CreateSprite(&gSpriteTemplate_81FAF34, GetBattlerSpriteCoord(r5, 0), GetBattlerSpriteCoord(r5, 1) + 32, 0xC8); + gSprites[ewram17810[r5].unk7].data[0] = r5; + if (IsDoubleBattle()) + { + r5 = GetBattlerAtPosition(3); + ewram17810[r5].unk7 = CreateSprite(&gSpriteTemplate_81FAF34, GetBattlerSpriteCoord(r5, 0), GetBattlerSpriteCoord(r5, 1) + 32, 0xC8); + gSprites[ewram17810[r5].unk7].data[0] = r5; + } +} + +void sub_80328A4(struct Sprite *sprite) +{ + bool8 invisible = FALSE; + u8 r4 = sprite->data[0]; + struct Sprite *r7 = &gSprites[gBankSpriteIds[r4]]; + + if (!r7->inUse || IsBankSpritePresent(r4) == 0) + { + sprite->callback = sub_8032978; + return; + } + if (gAnimScriptActive || r7->invisible) + invisible = TRUE; + else if (ewram17800[r4].transformedSpecies != 0 && gEnemyMonElevation[ewram17800[r4].transformedSpecies] == 0) + invisible = TRUE; + if (ewram17800[r4].substituteSprite) + invisible = TRUE; + sprite->pos1.x = r7->pos1.x; + sprite->pos2.x = r7->pos2.x; + sprite->invisible = invisible; +} + +void sub_8032978(struct Sprite *sprite) +{ + sprite->invisible = TRUE; +} + +void sub_8032984(u8 a, u16 b) +{ + if (GetBattlerSide(a) != 0) + { + if (ewram17800[a].transformedSpecies != 0) + b = ewram17800[a].transformedSpecies; + if (gEnemyMonElevation[b] != 0) + gSprites[ewram17810[a].unk7].callback = sub_80328A4; + else + gSprites[ewram17810[a].unk7].callback = sub_8032978; + } +} + +void sub_8032A08(u8 a) +{ + gSprites[ewram17810[a].unk7].callback = sub_8032978; +} + +void sub_8032A38(void) +{ + u16 *ptr = (u16 *)(VRAM + 0x240); + s32 i; + s32 j; + + for (i = 0; i < 9; i++) + { + for (j = 0; j < 16; j++) + { + if (!(*ptr & 0xF000)) + *ptr |= 0xF000; + if (!(*ptr & 0x0F00)) + *ptr |= 0x0F00; + if (!(*ptr & 0x00F0)) + *ptr |= 0x00F0; + if (!(*ptr & 0x000F)) + *ptr |= 0x000F; + ptr++; + } + } +} + +void sub_8032AA8(u8 a, u8 b) +{ + ewram17800[a].transformedSpecies = 0; + gBattleMonForms[a] = 0; + if (b == 0) + sub_80324E0(a); +} diff --git a/src/battle_interface.c b/src/battle_interface.c new file mode 100644 index 000000000..dedde2cb3 --- /dev/null +++ b/src/battle_interface.c @@ -0,0 +1,3423 @@ +#include "global.h" +#include "battle.h" +#include "battle_interface.h" +#include "decompress.h" +#include "palette.h" +#include "pokedex.h" +#include "pokemon.h" +#include "rom_8077ABC.h" +#include "safari_zone.h" +#include "constants/songs.h" +#include "sound.h" +#include "sprite.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "ewram.h" +#include "graphics.h" + +struct UnknownStruct5 +{ + u8 unk0; + u32 unk4; + u32 unk8; + u32 unkC; + u32 unk10; +}; + +struct UnknownStruct7 +{ + u8 filler0[0x180]; +}; + +static void sub_8043CEC(struct Sprite *sprite); +static void sub_8045030(struct Sprite *sprite); +static void sub_804507C(struct Sprite *sprite); + +const struct OamData gOamData_820A4E4 = +{ + .shape = 1, + .size = 3, + .priority = 1, +}; + +const struct SpriteTemplate gSpriteTemplates_820A4EC[] = +{ + { + .tileTag = 55039, + .paletteTag = 55039, + .oam = &gOamData_820A4E4, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55040, + .paletteTag = 55039, + .oam = &gOamData_820A4E4, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, +}; + +const struct SpriteTemplate gSpriteTemplates_820A51C[] = +{ + { + .tileTag = 55041, + .paletteTag = 55039, + .oam = &gOamData_820A4E4, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55042, + .paletteTag = 55039, + .oam = &gOamData_820A4E4, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, +}; + +const struct SpriteTemplate gSpriteTemplate_820A54C = +{ + .tileTag = 55051, + .paletteTag = 55039, + .oam = &gOamData_820A4E4, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +const struct OamData gOamData_820A564 = +{ + .shape = 1, + .size = 1, + .priority = 1, +}; + +const struct SpriteTemplate gSpriteTemplates_820A56C[] = +{ + { + .tileTag = 55044, + .paletteTag = 55044, + .oam = &gOamData_820A564, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8043CEC, + }, + { + .tileTag = 55045, + .paletteTag = 55044, + .oam = &gOamData_820A564, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8043CEC, + }, + { + .tileTag = 55046, + .paletteTag = 55044, + .oam = &gOamData_820A564, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8043CEC, + }, + { + .tileTag = 55047, + .paletteTag = 55044, + .oam = &gOamData_820A564, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8043CEC, + }, +}; + +const struct Subsprite gSubspriteTable_820A5CC[] = +{ + { .x = -16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 3 }, // size := 64x32 + { .x = 48, .y = 0, .shape = ST_OAM_SQUARE, .priority = 1, .tileOffset = 32, .size = 2 }, // size := 32x32 + { .x = -16, .y = 32, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 48, .size = 1 }, // size := 32x8 + { .x = 16, .y = 32, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 52, .size = 1 }, // size := 32x8 + { .x = 48, .y = 32, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 56, .size = 1 }, // size := 32x8 +}; + +const struct Subsprite gSubspriteTable_820A5F4[] = +{ + { .x = -16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 64, .size = 3 }, // size := 64x32 + { .x = 48, .y = 0, .shape = ST_OAM_SQUARE, .priority = 1, .tileOffset = 96, .size = 2 }, // size := 32x32 + { .x = -16, .y = 32, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset =112, .size = 1 }, // size := 32x8 + { .x = 16, .y = 32, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset =116, .size = 1 }, // size := 32x8 + { .x = 48, .y = 32, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset =120, .size = 1 }, // size := 32x8 +}; + +const struct Subsprite gSubspriteTable_820A61C[] = +{ + { .x = -16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 3 }, // size := 64x32 + { .x = 48, .y = 0, .shape = ST_OAM_SQUARE, .priority = 1, .tileOffset = 32, .size = 2 }, // size := 32x32 +}; + +const struct Subsprite gSubspriteTable_820A62C[] = +{ + { .x = -16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 3 }, // size := 64x32 + { .x = 48, .y = 0, .shape = ST_OAM_SQUARE, .priority = 1, .tileOffset = 32, .size = 2 }, // size := 32x32 +}; + +const struct Subsprite gSubspriteTable_820A63C[] = +{ + { .x = -16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 1 }, // size := 32x8 + { .x = 16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 4, .size = 1 }, // size := 32x8 +}; + +const struct Subsprite gSubspriteTable_820A64C[] = +{ + { .x = -16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 1 }, // size := 32x8 + { .x = 16, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 4, .size = 1 }, // size := 32x8 + { .x = -32, .y = 0, .shape = ST_OAM_SQUARE, .priority = 1, .tileOffset = 8, .size = 0 }, // size := 8x8 +}; + +const struct SubspriteTable gSubspriteTables_unreferenced[] = +{ + { ARRAY_COUNT(gSubspriteTable_820A5CC), gSubspriteTable_820A5CC }, + { ARRAY_COUNT(gSubspriteTable_820A61C), gSubspriteTable_820A61C }, + { ARRAY_COUNT(gSubspriteTable_820A5F4), gSubspriteTable_820A5F4 }, + { ARRAY_COUNT(gSubspriteTable_820A62C), gSubspriteTable_820A62C }, +}; + +const struct SubspriteTable gSubspriteTables_820A684[] = +{ + { ARRAY_COUNT(gSubspriteTable_820A63C), gSubspriteTable_820A63C }, + { ARRAY_COUNT(gSubspriteTable_820A64C), gSubspriteTable_820A64C }, +}; + +const struct Subsprite gSubspriteTable_820A694[] = +{ + { .x = -96, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 1 }, // size := 32x8 + { .x = -64, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 4, .size = 1 }, // size := 32x8 + { .x = -32, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 8, .size = 1 }, // size := 32x8 + { .x = 0, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 12, .size = 1 }, // size := 32x8 +}; + +const struct Subsprite gSubspriteTable_820A6B4[] = +{ + { .x = -96, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 0, .size = 1 }, // size := 32x8 + { .x = -64, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 4, .size = 1 }, // size := 32x8 + { .x = -32, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 8, .size = 1 }, // size := 32x8 + { .x = 0, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 8, .size = 1 }, // size := 32x8 + { .x = 32, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 8, .size = 1 }, // size := 32x8 + { .x = 64, .y = 0, .shape = ST_OAM_H_RECTANGLE, .priority = 1, .tileOffset = 12, .size = 1 }, // size := 32x8 +}; + +const struct SubspriteTable gSubspriteTables_820A6E4[] = +{ + { ARRAY_COUNT(gSubspriteTable_820A694), gSubspriteTable_820A694 }, +}; + +const struct SubspriteTable gSubspriteTables_820A6EC[] = +{ + { ARRAY_COUNT(gSubspriteTable_820A6B4), gSubspriteTable_820A6B4 }, +}; + +// unused dakuten/handakuten tiles +const u8 gUnusedDakuten[] = INCBIN_U8("graphics/unused/dakuten.4bpp"); + +const struct CompressedSpriteSheet gUnknown_0820A754[] = +{ + { gBattleGfx_BallStatusBar, 512, 0xd70c }, + { gBattleGfx_BallStatusBar, 512, 0xd70d }, +}; + +const struct SpritePalette gUnknown_0820A764[] = +{ + { gUnknown_08D1212C, 0xd710 }, + { gUnknown_08D1212C, 0xd711 }, +}; + +const struct SpritePalette gUnknown_0820A774[] = +{ + { gUnknown_08D1214C, 0xd712 }, + { gUnknown_08D1214C, 0xd713 }, +}; + +const struct CompressedSpriteSheet gUnknown_0820A784[] = +{ + { Tiles_D129AC, 0x80, 0xd714 }, + { Tiles_D129AC, 0x80, 0xd715 }, +}; + +const struct OamData gOamData_820A794 = +{ + .shape = 1, + .size = 3, + .priority = 1, +}; + +const struct OamData gOamData_820A79C = +{ + .shape = 0, + .size = 0, + .priority = 1, +}; + +const struct SpriteTemplate gSpriteTemplate_820A7A4 = +{ + .tileTag = 55052, + .paletteTag = 55056, + .oam = &gOamData_820A4E4, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8045030, +}; + +const struct SpriteTemplate gSpriteTemplate_820A7BC = +{ + .tileTag = 55053, + .paletteTag = 55057, + .oam = &gOamData_820A4E4, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_8045030, +}; + +const struct SpriteTemplate gSpriteTemplate_820A7D4 = +{ + .tileTag = 55060, + .paletteTag = 55058, + .oam = &gOamData_820A79C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_804507C, +}; + +const struct SpriteTemplate gSpriteTemplate_820A7EC = +{ + .tileTag = 55061, + .paletteTag = 55059, + .oam = &gOamData_820A79C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_804507C, +}; + +u8 *const gUnknown_0820A804[2] = +{ + OBJ_VRAM0 + 32 * 74, + OBJ_VRAM0 + 32 * 75, +}; + +u8 *const gUnknown_0820A80C[2] = +{ + OBJ_VRAM0 + 32 * 41, + OBJ_VRAM0 + 32 * 42, +}; + +u8 *const gUnknown_0820A814[2] = +{ + OBJ_VRAM0 + 32 * 42, + OBJ_VRAM0 + 32 * 43, +}; + +const u8 gUnknown_0820A81C[] = __("{COLOR DARK_GREY}{HIGHLIGHT RED} "); + +u8 *const gUnknown_0820A83C[3] = +{ + OBJ_VRAM0 + 32 * 31, + OBJ_VRAM0 + 32 * 88, + OBJ_VRAM0 + 32 * 89, +}; + +u8 *const gUnknown_0820A848[3] = +{ + OBJ_VRAM0 + 32 * 22, + OBJ_VRAM0 + 32 * 23, + OBJ_VRAM0 + 32 * 48, +}; + +u8 *const gUnknown_0820A854[2] = +{ + OBJ_VRAM0 + 32 * 90, + OBJ_VRAM0 + 32 * 91, +}; + +u8 *const gUnknown_0820A85C[2] = +{ + OBJ_VRAM0 + 32 * 49, + OBJ_VRAM0 + 32 * 50, +}; + +const u8 gUnknown_0820A864[] = _("{COLOR DARK_GREY}{HIGHLIGHT RED} /"); + +u8 *const gUnknown_0820A87C[6] = +{ + OBJ_VRAM0 + 32 * 0, + OBJ_VRAM0 + 32 * 1, + OBJ_VRAM0 + 32 * 2, + OBJ_VRAM0 + 32 * 3, + OBJ_VRAM0 + 32 * 4, + OBJ_VRAM0 + 32 * 5, +}; + +u8 *const gUnknown_0820A894[2] = +{ + OBJ_VRAM0 + 32 * 6, + OBJ_VRAM0 + 32 * 7, +}; + +const u8 gUnknown_0820A89C[] = __("{COLOR DARK_GREY}{HIGHLIGHT TRANSPARENT} "); +const u8 gUnknown_0820A8B0[] = _("{HIGHLIGHT RED}"); + +u8 *const gUnknown_0820A8B4[10] = +{ + OBJ_VRAM0 + 32 * 2, + OBJ_VRAM0 + 32 * 3, + OBJ_VRAM0 + 32 * 4, + OBJ_VRAM0 + 32 * 5, + OBJ_VRAM0 + 32 * 6, + OBJ_VRAM0 + 32 * 7, + OBJ_VRAM0 + 32 * 64, + OBJ_VRAM0 + 32 * 65, + OBJ_VRAM0 + 32 * 66, + OBJ_VRAM0 + 32 * 67, +}; + +u8 *const gUnknown_0820A8DC[10] = +{ + OBJ_VRAM0 + 32 * 1, + OBJ_VRAM0 + 32 * 2, + OBJ_VRAM0 + 32 * 3, + OBJ_VRAM0 + 32 * 4, + OBJ_VRAM0 + 32 * 5, + OBJ_VRAM0 + 32 * 6, + OBJ_VRAM0 + 32 * 7, + OBJ_VRAM0 + 32 * 32, + OBJ_VRAM0 + 32 * 33, + OBJ_VRAM0 + 32 * 34, +}; + +u8 *const gUnknown_0820A904[10] = +{ + OBJ_VRAM0 + 32 * 2, + OBJ_VRAM0 + 32 * 3, + OBJ_VRAM0 + 32 * 4, + OBJ_VRAM0 + 32 * 5, + OBJ_VRAM0 + 32 * 6, + OBJ_VRAM0 + 32 * 7, + OBJ_VRAM0 + 32 * 32, + OBJ_VRAM0 + 32 * 33, + OBJ_VRAM0 + 32 * 34, + OBJ_VRAM0 + 32 * 35, +}; + +extern u8 gDisplayedStringBattle[]; +extern u8 gBattlersCount; +extern u16 gBattlerPartyIndexes[]; +extern u8 gBanksBySide[]; +extern u8 gHealthboxIDs[]; + +extern u16 gBattleTypeFlags; + +extern const u8 BattleText_SafariBalls[]; +extern const u8 BattleText_SafariBallsLeft[]; +extern const u8 BattleText_HighlightRed[]; +extern const u8 gHealthboxElementsGfxTable[][32]; + +extern const u16 gBattleInterfaceStatusIcons_DynPal[]; + +#define ABS(n) ((n) >= 0 ? (n) : -(n)) +// Used for computing copy destination addresses +#define MACRO1(n) ((n) - (n) / 8 * 8) + 64 * ((n) / 8) + +static void sub_8043D5C(struct Sprite *); +static const void *sub_8043CDC(u8); +/*static*/ void sub_8044210(u8, s16, u8); +/*static*/ void draw_status_ailment_maybe(u8); +extern void sub_8045180(struct Sprite *); +static void sub_8045110(struct Sprite *); +static void sub_8045048(struct Sprite *); +static void sub_8044F70(u8 taskId); +static void sub_8044E74(u8 taskId); +static void sub_8044ECC(u8 taskId); +static u8 sub_80457E8(u8, u8); +static int sub_8045F58(s32, s32, int, int *, u8, u16); +static u8 GetScaledExpFraction(int, int, int, u8); +static void sub_8045D58(u8, u8); +static u8 sub_804602C(int, int, int, int *, u8 *, u8); +static void sub_8046128(struct BattleInterfaceStruct1 *a, int *b, u16 *c); + +static int do_nothing(s16 unused1, s16 unused2, int unused3) +{ + return 9; +} + +#ifdef NONMATCHING +void sub_8043740(s16 a, u16 *b, u8 c) +{ + u8 sp0[4]; + s8 i; + s8 j; + s32 r9; + + for (i = 0; i < 4; i++) + sp0[i] = 0; + + //_0804377C + //i = 3; + //r9 = -1; + for (i = 3, r9 = -1;;) + { + if (a > 0) + { + sp0[i] = a % 10; + a /= 10; + i--; + } + else + break; + asm(""::"r"(r9)); + } + + //_080437AA + for (; i > r9; i--) + { + //asm("":"=r"(r9)); + sp0[i] = -1; + } + //_080437CE + if (sp0[3] == 0xFF) + sp0[3] = 0; + + //_080437DA + if (c == 0) + { + for (i = 0, j = 0; i < 4; i++) + { + if (sp0[j] == 0xFF) + { + b[j] = (b[j] & 0xFC00) | 0x1E; + b[i + 0x20] = (b[i + 0x20] & 0xFC00) | 0x1E; + } + else + { + b[j] = (b[j] & 0xFC00) | (sp0[j] + 0x14); + b[i + 0x20] = (b[i + 0x20] & 0xFC00) | (sp0[i] + 0x34); + } + j++; + } + + } + //_0804386A + else + { + for (i = 0; i < 4; i++) + { + if (sp0[i] == 0xFF) + { + b[i] = (b[i] & 0xFC00) | 0x1E; + b[i + 0x20] = (b[i + 0x20] & 0xFC00) | 0x1E; + } + else + { + b[i] = (b[i] & 0xFC00) | (sp0[i] + 0x14); + b[i + 0x20] = (b[i + 0x20] & 0xFC00) | (sp0[i] + 0x34); + } + } + } + asm(""::"r"(r9)); +} +#else +NAKED +void sub_8043740(s16 a, u16 *b, u8 c) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x4\n\ + adds r7, r1, 0\n\ + lsls r0, 16\n\ + lsrs r5, r0, 16\n\ + lsls r2, 24\n\ + lsrs r2, 24\n\ + mov r10, r2\n\ + movs r3, 0\n\ + movs r2, 0\n\ +_0804375C:\n\ + lsls r0, r3, 24\n\ + asrs r0, 24\n\ + mov r3, sp\n\ + adds r1, r3, r0\n\ + strb r2, [r1]\n\ + adds r0, 0x1\n\ + lsls r0, 24\n\ + lsrs r3, r0, 24\n\ + asrs r0, 24\n\ + cmp r0, 0x3\n\ + ble _0804375C\n\ + movs r3, 0x3\n\ + movs r0, 0x1\n\ + negs r0, r0\n\ + mov r9, r0\n\ + mov r8, sp\n\ +_0804377C:\n\ + lsls r0, r5, 16\n\ + asrs r6, r0, 16\n\ + cmp r6, 0\n\ + ble _080437AA\n\ + lsls r4, r3, 24\n\ + asrs r4, 24\n\ + mov r1, sp\n\ + adds r5, r1, r4\n\ + adds r0, r6, 0\n\ + movs r1, 0xA\n\ + bl __modsi3\n\ + strb r0, [r5]\n\ + adds r0, r6, 0\n\ + movs r1, 0xA\n\ + bl __divsi3\n\ + lsls r0, 16\n\ + lsrs r5, r0, 16\n\ + subs r4, 0x1\n\ + lsls r4, 24\n\ + lsrs r3, r4, 24\n\ + b _0804377C\n\ +_080437AA:\n\ + lsls r1, r3, 24\n\ + asrs r0, r1, 24\n\ + cmp r0, r9\n\ + ble _080437CE\n\ + movs r4, 0xFF\n\ + movs r3, 0x1\n\ + negs r3, r3\n\ +_080437B8:\n\ + asrs r2, r1, 24\n\ + mov r5, sp\n\ + adds r1, r5, r2\n\ + ldrb r0, [r1]\n\ + orrs r0, r4\n\ + strb r0, [r1]\n\ + subs r2, 0x1\n\ + lsls r1, r2, 24\n\ + asrs r0, r1, 24\n\ + cmp r0, r3\n\ + bgt _080437B8\n\ +_080437CE:\n\ + mov r1, r8\n\ + ldrb r0, [r1, 0x3]\n\ + cmp r0, 0xFF\n\ + bne _080437DA\n\ + movs r0, 0\n\ + strb r0, [r1, 0x3]\n\ +_080437DA:\n\ + mov r2, r10\n\ + cmp r2, 0\n\ + bne _0804386A\n\ + movs r3, 0\n\ + movs r1, 0\n\ + movs r6, 0xFC\n\ + lsls r6, 8\n\ + movs r5, 0x1E\n\ + mov r12, r5\n\ +_080437EC:\n\ + lsls r1, 24\n\ + asrs r2, r1, 24\n\ + mov r0, sp\n\ + adds r5, r0, r2\n\ + ldrb r0, [r5]\n\ + mov r8, r1\n\ + cmp r0, 0xFF\n\ + bne _08043822\n\ + lsls r1, r2, 1\n\ + adds r1, r7\n\ + ldrh r2, [r1]\n\ + adds r0, r6, 0\n\ + ands r0, r2\n\ + mov r2, r12\n\ + orrs r0, r2\n\ + strh r0, [r1]\n\ + lsls r3, 24\n\ + asrs r1, r3, 23\n\ + adds r1, r7\n\ + adds r1, 0x40\n\ + ldrh r2, [r1]\n\ + adds r0, r6, 0\n\ + ands r0, r2\n\ + mov r5, r12\n\ + orrs r0, r5\n\ + strh r0, [r1]\n\ + b _08043852\n\ +_08043822:\n\ + lsls r2, 1\n\ + adds r2, r7\n\ + ldrh r0, [r2]\n\ + adds r1, r6, 0\n\ + ands r1, r0\n\ + ldrb r0, [r5]\n\ + adds r0, 0x14\n\ + orrs r1, r0\n\ + strh r1, [r2]\n\ + lsls r4, r3, 24\n\ + asrs r3, r4, 24\n\ + lsls r2, r3, 1\n\ + adds r2, r7\n\ + adds r2, 0x40\n\ + ldrh r0, [r2]\n\ + adds r1, r6, 0\n\ + ands r1, r0\n\ + mov r5, sp\n\ + adds r0, r5, r3\n\ + ldrb r0, [r0]\n\ + adds r0, 0x34\n\ + orrs r1, r0\n\ + strh r1, [r2]\n\ + adds r3, r4, 0\n\ +_08043852:\n\ + movs r0, 0x80\n\ + lsls r0, 17\n\ + add r0, r8\n\ + lsrs r1, r0, 24\n\ + movs r2, 0x80\n\ + lsls r2, 17\n\ + adds r0, r3, r2\n\ + lsrs r3, r0, 24\n\ + asrs r0, 24\n\ + cmp r0, 0x3\n\ + ble _080437EC\n\ + b _080438CE\n\ +_0804386A:\n\ + movs r3, 0\n\ + movs r4, 0xFC\n\ + lsls r4, 8\n\ + movs r6, 0x1E\n\ +_08043872:\n\ + lsls r1, r3, 24\n\ + asrs r2, r1, 24\n\ + mov r3, sp\n\ + adds r5, r3, r2\n\ + ldrb r0, [r5]\n\ + adds r3, r1, 0\n\ + cmp r0, 0xFF\n\ + bne _0804389E\n\ + lsls r1, r2, 1\n\ + adds r1, r7\n\ + ldrh r2, [r1]\n\ + adds r0, r4, 0\n\ + ands r0, r2\n\ + orrs r0, r6\n\ + strh r0, [r1]\n\ + adds r1, 0x40\n\ + ldrh r2, [r1]\n\ + adds r0, r4, 0\n\ + ands r0, r2\n\ + orrs r0, r6\n\ + strh r0, [r1]\n\ + b _080438C0\n\ +_0804389E:\n\ + lsls r2, 1\n\ + adds r2, r7\n\ + ldrh r0, [r2]\n\ + adds r1, r4, 0\n\ + ands r1, r0\n\ + ldrb r0, [r5]\n\ + adds r0, 0x14\n\ + orrs r1, r0\n\ + strh r1, [r2]\n\ + adds r2, 0x40\n\ + ldrh r0, [r2]\n\ + adds r1, r4, 0\n\ + ands r1, r0\n\ + ldrb r0, [r5]\n\ + adds r0, 0x34\n\ + orrs r1, r0\n\ + strh r1, [r2]\n\ +_080438C0:\n\ + movs r5, 0x80\n\ + lsls r5, 17\n\ + adds r0, r3, r5\n\ + lsrs r3, r0, 24\n\ + asrs r0, 24\n\ + cmp r0, 0x3\n\ + ble _08043872\n\ +_080438CE:\n\ + add sp, 0x4\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .syntax divided\n"); +} +#endif + +void unref_sub_80438E0(s16 a, s16 b, u16 *c) +{ + c[4] = 0x1E; + sub_8043740(b, c, 0); + sub_8043740(a, c + 5, 1); +} + +u8 battle_make_oam_normal_battle(u8 a) +{ + int sp0 = 0; + u8 spriteId1; + u8 spriteId2; + u8 spriteId3; + struct Sprite *sprite; + + if (!IsDoubleBattle()) + { + if (GetBattlerSide(a) == 0) + { + spriteId1 = CreateSprite(&gSpriteTemplates_820A4EC[0], 240, 160, 1); + spriteId2 = CreateSpriteAtEnd(&gSpriteTemplates_820A4EC[0], 240, 160, 1); + + gSprites[spriteId1].oam.shape = 0; + gSprites[spriteId2].oam.shape = 0; + gSprites[spriteId2].oam.tileNum += 64; + } + else + { + spriteId1 = CreateSprite(&gSpriteTemplates_820A51C[0], 240, 160, 1); + spriteId2 = CreateSpriteAtEnd(&gSpriteTemplates_820A51C[0], 240, 160, 1); + + gSprites[spriteId2].oam.tileNum += 32; + sp0 = 2; + } + //_080439F2 + + gSprites[spriteId1].oam.affineParam = spriteId2; + gSprites[spriteId2].data[5] = spriteId1; + gSprites[spriteId2].callback = sub_8043D5C; + } + //_08043A28 + else + { + if (GetBattlerSide(a) == 0) + { + spriteId1 = CreateSprite(&gSpriteTemplates_820A4EC[GetBattlerPosition(a) / 2], 240, 160, 1); + spriteId2 = CreateSpriteAtEnd(&gSpriteTemplates_820A4EC[GetBattlerPosition(a) / 2], 240, 160, 1); + + gSprites[spriteId1].oam.affineParam = spriteId2; + gSprites[spriteId2].data[5] = spriteId1; + gSprites[spriteId2].oam.tileNum += 32; + gSprites[spriteId2].callback = sub_8043D5C; + sp0 = 1; + } + //_08043ACC + else + { + spriteId1 = CreateSprite(&gSpriteTemplates_820A51C[GetBattlerPosition(a) / 2], 240, 160, 1); + spriteId2 = CreateSpriteAtEnd(&gSpriteTemplates_820A51C[GetBattlerPosition(a) / 2], 240, 160, 1); + + gSprites[spriteId1].oam.affineParam = spriteId2; + gSprites[spriteId2].data[5] = spriteId1; + gSprites[spriteId2].oam.tileNum += 32; + gSprites[spriteId2].callback = sub_8043D5C; + sp0 = 2; + } + //_08043B4E + } + //_08043B50 + + spriteId3 = CreateSpriteAtEnd(&gSpriteTemplates_820A56C[gBanksBySide[a]], 140, 60, 0); + sprite = &gSprites[spriteId3]; + SetSubspriteTables(sprite, &gSubspriteTables_820A684[GetBattlerSide(a)]); + sprite->subspriteMode = 2; + sprite->oam.priority = 1; + CpuCopy32(sub_8043CDC(1), OBJ_VRAM0 + sprite->oam.tileNum * 32, 64); + + gSprites[spriteId1].data[5] = spriteId3; + gSprites[spriteId1].data[6] = a; + gSprites[spriteId1].invisible = TRUE; + gSprites[spriteId2].invisible = TRUE; + sprite->data[5] = spriteId1; + sprite->data[6] = sp0; + sprite->invisible = TRUE; + + return spriteId1; +} + +u8 battle_make_oam_safari_battle(void) +{ + u8 spriteId1 = CreateSprite(&gSpriteTemplate_820A54C, 240, 160, 1); + u8 spriteId2 = CreateSpriteAtEnd(&gSpriteTemplate_820A54C, 240, 160, 1); + + gSprites[spriteId1].oam.shape = 0; + gSprites[spriteId2].oam.shape = 0; + gSprites[spriteId2].oam.tileNum += 0x40; + gSprites[spriteId1].oam.affineParam = spriteId2; + gSprites[spriteId2].data[5] = spriteId1; + gSprites[spriteId2].callback = sub_8043D5C; + return spriteId1; +} + +static const void *sub_8043CDC(u8 a) +{ + return gHealthboxElementsGfxTable[a]; +} + +static void sub_8043CEC(struct Sprite *sprite) +{ + u8 r5 = sprite->data[5]; + + switch (sprite->data[6]) + { + case 0: + sprite->pos1.x = gSprites[r5].pos1.x + 16; + sprite->pos1.y = gSprites[r5].pos1.y; + break; + case 1: + sprite->pos1.x = gSprites[r5].pos1.x + 16; + sprite->pos1.y = gSprites[r5].pos1.y; + break; + default: + case 2: + sprite->pos1.x = gSprites[r5].pos1.x + 8; + sprite->pos1.y = gSprites[r5].pos1.y; + break; + } + sprite->pos2.x = gSprites[r5].pos2.x; + sprite->pos2.y = gSprites[r5].pos2.y; +} + +static void sub_8043D5C(struct Sprite *sprite) +{ + u8 data5 = sprite->data[5]; + + sprite->pos1.x = gSprites[data5].pos1.x + 64; + sprite->pos1.y = gSprites[data5].pos1.y; + sprite->pos2.x = gSprites[data5].pos2.x; + sprite->pos2.y = gSprites[data5].pos2.y; +} + +void sub_8043D84(u8 a, u8 b, u32 c, u32 d, u32 e) +{ + ewram17850[a].unk0 = b; + ewram17850[a].unk4 = c; + ewram17850[a].unk8 = d; + ewram17850[a].unkC = e; + ewram17850[a].unk10 = 0xFFFF8000; +} + +void sub_8043DB0(u8 a) +{ + gSprites[a].invisible = TRUE; + gSprites[gSprites[a].data[5]].invisible = TRUE; + gSprites[gSprites[a].oam.affineParam].invisible = TRUE; +} + +void sub_8043DFC(u8 a) +{ + gSprites[a].invisible = FALSE; + gSprites[gSprites[a].data[5]].invisible = FALSE; + gSprites[gSprites[a].oam.affineParam].invisible = FALSE; +} + +static void sub_8043E50(u8 spriteId, s16 x, s16 y) +{ + gSprites[spriteId].pos1.x = x; + gSprites[spriteId].pos1.y = y; +} + +void unref_sub_8043E70(u8 a) +{ + DestroySprite(&gSprites[gSprites[a].oam.affineParam]); + DestroySprite(&gSprites[gSprites[a].data[5]]); + DestroySprite(&gSprites[a]); +} + +void nullsub_11() +{ +} + +void UpdateOamPriorityInAllHealthboxes(u8 priority) +{ + s32 i; + + for (i = 0; i < gBattlersCount; i++) + { + u8 spriteId1; + u8 spriteId2; + u8 spriteId3; + + spriteId1 = gHealthboxIDs[i]; + spriteId2 = gSprites[spriteId1].oam.affineParam; + spriteId3 = gSprites[spriteId1].data[5]; + gSprites[spriteId1].oam.priority = priority; + gSprites[spriteId2].oam.priority = priority; + gSprites[spriteId3].oam.priority = priority; + } +} + +void sub_8043F44(u8 a) +{ + s16 x = 0; + s16 y = 0; + + if (!IsDoubleBattle()) + { + if (GetBattlerSide(a) != 0) + { + x = 44; + y = 30; + } + else + { + x = 158; + y = 88; + } + } + else + { + switch (GetBattlerPosition(a)) + { + case 0: + x = 159; + y = 77; + break; + case 2: + x = 171; + y = 102; + break; + case 1: + x = 44; + y = 19; + break; + case 3: + x = 32; + y = 44; + break; + } + } + sub_8043E50(gHealthboxIDs[a], x, y); +} + +#if ENGLISH +#define CHAR_LV_SEPARATOR CHAR_COLON +#elif GERMAN +#define CHAR_LV_SEPARATOR CHAR_PERIOD +#endif + +/*static*/ void sub_8043FC0(u8 a, u8 b) +{ + u8 str[30]; + u8 *const *r7; + u8 *ptr; + s32 i; + s32 two; + + // TODO: Make this a local variable + memcpy(str, gUnknown_0820A81C, sizeof(str)); + if (!IsDoubleBattle()) + { + if (GetBattlerSide(gSprites[a].data[6]) == 0) + r7 = gUnknown_0820A804; + else + r7 = gUnknown_0820A80C; + } + else + { + if (GetBattlerSide(gSprites[a].data[6]) == 0) + r7 = gUnknown_0820A814; + else + r7 = gUnknown_0820A80C; + } + + ptr = str + 6; + if (b == 100) + { + ptr = ConvertIntToDecimalStringN(ptr, 100, 0, 3); + } + else + { + *(ptr++) = EXT_CTRL_CODE_BEGIN; + *(ptr++) = 0x11; + *(ptr++) = 1; + *(ptr++) = EXT_CTRL_CODE_BEGIN; + *(ptr++) = 0x14; + *(ptr++) = 4; + *(ptr++) = CHAR_LV_SEPARATOR; + *(ptr++) = EXT_CTRL_CODE_BEGIN; + *(ptr++) = 0x14; + *(ptr++) = 0; + ptr = ConvertIntToDecimalStringN(ptr, b, 0, 2); + } + + *(ptr++) = EXT_CTRL_CODE_BEGIN; + *(ptr++) = 0x13; + *(ptr++) = 0xF; + *(ptr++) = EOS; + sub_80034D4(ewram0_9(0), str); + + two = 2; + for (i = 0; i < two; i++) + CpuCopy32((void *)(ewram0_9(1) + i * 64), r7[i] + gSprites[a].oam.tileNum * 32, 32); +} + +#ifdef NONMATCHING +void sub_80440EC(u8 a, s16 b, u8 c) +{ + u8 str[0x14]; + u8 *ptr; + s32 foo; + u8 *const *r4; + s32 i; + + // TODO: make this a local variable + memcpy(str, gUnknown_0820A864, sizeof(str)); + foo = gSprites[a].data[6]; + + if (IsDoubleBattle() == TRUE || GetBattlerSide(foo) == 1) + { + //_08044136 + sub_8044210(a, b, c); + return; + } + // + ptr = str + 6; + if (c == 0) + { + if (GetBattlerSide(gSprites[a].data[6]) == 0) + r4 = gUnknown_0820A83C; + else + r4 = gUnknown_0820A848; + c = 3; + ptr = sub_8003504(ptr, b, 0x13, 1); + *(ptr++) = 0xBA; + *(ptr++) = 0xFF; + sub_80034D4(ewram0_9(0), str); + } + else + { + if (GetBattlerSide(gSprites[a].data[6]) == 0) + r4 = gUnknown_0820A854; + else + r4 = gUnknown_0820A85C; + c = 2; + sub_8003504(ptr, b, 0xF, 1); + sub_80034D4(ewram0_9(0), str); + } + //asm(""::"r"(a)); + //_080441B6 + for (i = 0; i < c; i++) // _080440BC + { + void *temp = r4[i] + gSprites[a].oam.tileNum * 32; + CpuCopy32((void *)(ewram0_9(1) + i * 0x40), temp, 0x20); + } +} +#else +NAKED +void sub_80440EC(u8 a, s16 b, u8 c) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r8\n\ + push {r7}\n\ + sub sp, 0x14\n\ + lsls r0, 24\n\ + lsrs r7, r0, 24\n\ + lsls r1, 16\n\ + lsrs r6, r1, 16\n\ + lsls r2, 24\n\ + lsrs r2, 24\n\ + mov r8, r2\n\ + ldr r1, _08044144 @ =gUnknown_0820A864\n\ + mov r0, sp\n\ + movs r2, 0x14\n\ + bl memcpy\n\ + ldr r1, _08044148 @ =gSprites\n\ + lsls r0, r7, 4\n\ + adds r0, r7\n\ + lsls r0, 2\n\ + adds r4, r0, r1\n\ + movs r0, 0x3A\n\ + ldrsh r5, [r4, r0]\n\ + bl IsDoubleBattle\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x1\n\ + beq _08044136\n\ + lsls r0, r5, 24\n\ + lsrs r0, 24\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x1\n\ + bne _0804414C\n\ +_08044136:\n\ + lsls r1, r6, 16\n\ + asrs r1, 16\n\ + adds r0, r7, 0\n\ + mov r2, r8\n\ + bl sub_8044210\n\ + b _080441F0\n\ + .align 2, 0\n\ +_08044144: .4byte gUnknown_0820A864\n\ +_08044148: .4byte gSprites\n\ +_0804414C:\n\ + mov r5, sp\n\ + adds r5, 0x6\n\ + mov r0, r8\n\ + cmp r0, 0\n\ + bne _08044190\n\ + ldrh r0, [r4, 0x3A]\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + ldr r4, _08044188 @ =gUnknown_0820A848\n\ + cmp r0, 0\n\ + bne _0804416A\n\ + ldr r4, _0804418C @ =gUnknown_0820A83C\n\ +_0804416A:\n\ + movs r0, 0x3\n\ + mov r8, r0\n\ + lsls r1, r6, 16\n\ + asrs r1, 16\n\ + adds r0, r5, 0\n\ + movs r2, 0x13\n\ + movs r3, 0x1\n\ + bl sub_8003504\n\ + adds r5, r0, 0\n\ + movs r0, 0xBA\n\ + strb r0, [r5]\n\ + movs r0, 0xFF\n\ + strb r0, [r5, 0x1]\n\ + b _080441B6\n\ + .align 2, 0\n\ +_08044188: .4byte gUnknown_0820A848\n\ +_0804418C: .4byte gUnknown_0820A83C\n\ +_08044190:\n\ + ldrh r0, [r4, 0x3A]\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + ldr r4, _080441FC @ =gUnknown_0820A85C\n\ + cmp r0, 0\n\ + bne _080441A4\n\ + ldr r4, _08044200 @ =gUnknown_0820A854\n\ +_080441A4:\n\ + movs r0, 0x2\n\ + mov r8, r0\n\ + lsls r1, r6, 16\n\ + asrs r1, 16\n\ + adds r0, r5, 0\n\ + movs r2, 0xF\n\ + movs r3, 0x1\n\ + bl sub_8003504\n\ +_080441B6:\n\ + movs r0, 0x80\n\ + lsls r0, 18\n\ + mov r1, sp\n\ + bl sub_80034D4\n\ + mov r0, r8\n\ + cmp r0, 0\n\ + beq _080441F0\n\ + ldr r1, _08044204 @ =gSprites\n\ + lsls r0, r7, 4\n\ + adds r0, r7\n\ + lsls r0, 2\n\ + adds r6, r0, r1\n\ + adds r7, r4, 0\n\ + ldr r5, _08044208 @ =gSharedMem + 0x20\n\ + mov r4, r8\n\ +_080441D6:\n\ + ldrh r0, [r6, 0x4]\n\ + lsls r0, 22\n\ + lsrs r0, 17\n\ + ldm r7!, {r1}\n\ + adds r1, r0\n\ + adds r0, r5, 0\n\ + ldr r2, _0804420C @ =REG_BG0CNT\n\ + bl CpuSet\n\ + adds r5, 0x40\n\ + subs r4, 0x1\n\ + cmp r4, 0\n\ + bne _080441D6\n\ +_080441F0:\n\ + add sp, 0x14\n\ + pop {r3}\n\ + mov r8, r3\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_080441FC: .4byte gUnknown_0820A85C\n\ +_08044200: .4byte gUnknown_0820A854\n\ +_08044204: .4byte gSprites\n\ +_08044208: .4byte gSharedMem + 0x20\n\ +_0804420C: .4byte 0x04000008\n\ + .syntax divided\n"); +} +#endif + +/*static*/ void sub_8044210(u8 a, s16 b, u8 c) +{ + u8 str[0x14]; + u8 *ptr; + u8 *const *r7; + int r10; + int r4; + int i; + + // TODO: make this a local variable + memcpy(str, gUnknown_0820A89C, sizeof(str)); + r4 = gSprites[a].data[6]; + if ((ewram17800[r4].unk0_4) == 0) + return; + ptr = str + 6; + if (c == 0) + { + r7 = gUnknown_0820A87C; + r10 = 6; + ptr = sub_8003504(ptr, b, 0x2B, 1); + *(ptr++) = CHAR_SLASH; + *(ptr++) = EOS; + } + else + { + r7 = gUnknown_0820A894; + r10 = 2; + sub_8003504(ptr, b, 0xF, 1); + if (GetBattlerSide(r4) == 0) + { + CpuCopy32(sub_8043CDC(0x74), OBJ_VRAM0 + (gSprites[a].oam.tileNum + 0x34) * 32, 32); + } + } + r4 = gSprites[a].data[5]; + sub_80034D4(ewram0_9(0), str); + for (i = 0; i < r10; i++) + { + CpuCopy32((void *)(ewram0_9(1) + i * 0x40), r7[i] + gSprites[r4].oam.tileNum * 32, 32); + } +} + +#ifdef NONMATCHING +void sub_8044338(u8 a, struct Pokemon *pkmn) +{ + u8 str[0x14]; + u8 *r6; + s32 r8; + u8 nature; // = GetNature(pkmn); + s32 r7; + u8 i; + u8 r5; + + // TODO: make this a local variable + memcpy(str, gUnknown_0820A864, sizeof(str)); + r6 = ewram520[GetBattlerPosition(gSprites[a].data[6])].filler0; + r8 = 5; + nature = GetNature(pkmn); + StringCopy(str + 6, gNatureNames[nature]); + sub_80034D4(r6, str); + r7 = 6; + for (i = 0; i < (u32)r8; i++, r7++) //_080443AA + { + u8 val; + + if ((u8)(str[r7] - 0x37) <= 0x13 || (u8)(str[r7] + 0x79) <= 0x13) + val = 0x2C; + //_080443DC + else if ((u8)(str[r7] - 0x4B) <= 4 || (u8)(str[r7] + 0x65) <= 4) + val = 0x2D; + else + val = 0x2B; + + CpuCopy32(sub_8043CDC(val), r6 + i * 64, 32); + } + //r7 = 1; + //sp18 = a * 16; + for (r7 = 1; r7 < r8 + 1; r7++) + { + int foo; + + foo = gSprites[a].oam.tileNum + MACRO1(r7); + CpuCopy32(r6, (u8 *)0x06010000 + foo * 32, 32); + r6 += 32; + + foo = gSprites[a].oam.tileNum + 8 + MACRO1(r7); + CpuCopy32(r6, (u8 *)0x06010000 + foo * 32, 32); + r6 += 32; + } + //_08044486 + r5 = gSprites[a].data[5]; + ConvertIntToDecimalStringN(str + 6, ewram16089, 1, 2); + ConvertIntToDecimalStringN(str + 9, ewram16088, 1, 2); + str[5] = 0; + str[8] = 0xBA; + sub_80034D4(ewram0_9(0), str); + + for (r7 = 0; r7 < 5; r7++) + { + if (r7 <= 1) + { + int foo = (gSprites[r5].oam.tileNum + 2 + r7); + CpuCopy32(ewram0_9(1) + r7 * 0x40, (u8 *)0x06010000 + foo * 32, 32); + } + else + { + int foo = (r7 + gSprites[r5].oam.tileNum); + CpuCopy32(ewram0_9(1) + r7 * 0x40, (u8 *)0x060100C0 + foo * 32, 32); + } + } +} +#else +NAKED +void sub_8044338(u8 a, struct Pokemon *pkmn) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x20\n\ + adds r4, r1, 0\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + str r0, [sp, 0x14]\n\ + ldr r1, _080443CC @ =gUnknown_0820A864\n\ + mov r0, sp\n\ + movs r2, 0x14\n\ + bl memcpy\n\ + ldr r1, _080443D0 @ =gSprites\n\ + ldr r2, [sp, 0x14]\n\ + lsls r0, r2, 4\n\ + adds r0, r2\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrh r0, [r0, 0x3A]\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + bl GetBattlerPosition\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + lsls r1, r0, 1\n\ + adds r1, r0\n\ + lsls r1, 7\n\ + ldr r3, _080443D4 @ =gSharedMem + 0x520\n\ + adds r6, r1, r3\n\ + movs r0, 0x5\n\ + mov r8, r0\n\ + adds r0, r4, 0\n\ + bl GetNature\n\ + lsls r0, 24\n\ + mov r4, sp\n\ + adds r4, 0x6\n\ + ldr r1, _080443D8 @ =gNatureNames\n\ + lsrs r0, 22\n\ + adds r0, r1\n\ + ldr r1, [r0]\n\ + adds r0, r4, 0\n\ + bl StringCopy\n\ + adds r0, r6, 0\n\ + mov r1, sp\n\ + bl sub_80034D4\n\ + movs r7, 0x6\n\ + movs r5, 0\n\ + mov r1, sp\n\ + adds r1, 0x9\n\ + str r1, [sp, 0x1C]\n\ +_080443AA:\n\ + mov r2, sp\n\ + adds r0, r2, r7\n\ + ldrb r1, [r0]\n\ + adds r0, r1, 0\n\ + subs r0, 0x37\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x13\n\ + bls _080443C8\n\ + adds r0, r1, 0\n\ + adds r0, 0x79\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x13\n\ + bhi _080443DC\n\ +_080443C8:\n\ + movs r0, 0x2C\n\ + b _080443FA\n\ + .align 2, 0\n\ +_080443CC: .4byte gUnknown_0820A864\n\ +_080443D0: .4byte gSprites\n\ +_080443D4: .4byte gSharedMem + 0x520\n\ +_080443D8: .4byte gNatureNames\n\ +_080443DC:\n\ + adds r0, r1, 0\n\ + subs r0, 0x4B\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x4\n\ + bls _080443F4\n\ + adds r0, r1, 0\n\ + adds r0, 0x65\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x4\n\ + bhi _080443F8\n\ +_080443F4:\n\ + movs r0, 0x2D\n\ + b _080443FA\n\ +_080443F8:\n\ + movs r0, 0x2B\n\ +_080443FA:\n\ + bl sub_8043CDC\n\ + lsls r1, r5, 6\n\ + adds r1, r6, r1\n\ + ldr r2, _080444F8 @ =REG_BG0CNT\n\ + bl CpuSet\n\ + adds r0, r5, 0x1\n\ + lsls r0, 24\n\ + lsrs r5, r0, 24\n\ + adds r7, 0x1\n\ + cmp r5, r8\n\ + bcc _080443AA\n\ + movs r7, 0x1\n\ + ldr r3, [sp, 0x14]\n\ + lsls r3, 4\n\ + str r3, [sp, 0x18]\n\ + movs r0, 0x1\n\ + add r0, r8\n\ + mov r9, r0\n\ + cmp r7, r9\n\ + bge _08044486\n\ + ldr r1, _080444FC @ =gSprites\n\ + ldr r2, _080444F8 @ =REG_BG0CNT\n\ + mov r10, r2\n\ + ldr r2, [sp, 0x14]\n\ + adds r0, r3, r2\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + mov r8, r0\n\ +_08044436:\n\ + mov r3, r8\n\ + ldrh r0, [r3, 0x4]\n\ + lsls r0, 22\n\ + lsrs r0, 22\n\ + adds r5, r7, 0\n\ + cmp r7, 0\n\ + bge _08044446\n\ + adds r5, r7, 0x7\n\ +_08044446:\n\ + asrs r5, 3\n\ + lsls r4, r5, 3\n\ + subs r4, r7, r4\n\ + adds r0, r4\n\ + lsls r5, 6\n\ + adds r0, r5\n\ + lsls r0, 5\n\ + ldr r2, _08044500 @ =0x06010000\n\ + adds r1, r0, r2\n\ + adds r0, r6, 0\n\ + mov r2, r10\n\ + bl CpuSet\n\ + adds r6, 0x20\n\ + mov r3, r8\n\ + ldrh r0, [r3, 0x4]\n\ + lsls r0, 22\n\ + lsrs r0, 22\n\ + adds r4, 0x8\n\ + adds r0, r4\n\ + adds r0, r5\n\ + lsls r0, 5\n\ + ldr r2, _08044500 @ =0x06010000\n\ + adds r1, r0, r2\n\ + adds r0, r6, 0\n\ + mov r2, r10\n\ + bl CpuSet\n\ + adds r6, 0x20\n\ + adds r7, 0x1\n\ + cmp r7, r9\n\ + blt _08044436\n\ +_08044486:\n\ + ldr r6, _080444FC @ =gSprites\n\ + ldr r3, [sp, 0x18]\n\ + ldr r1, [sp, 0x14]\n\ + adds r0, r3, r1\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldrh r5, [r0, 0x38]\n\ + lsls r5, 24\n\ + lsrs r5, 24\n\ + ldr r4, _08044504 @ =gSharedMem\n\ + ldr r2, _08044508 @ =0x00016089\n\ + adds r0, r4, r2\n\ + ldrb r1, [r0]\n\ + mov r0, sp\n\ + adds r0, 0x6\n\ + movs r2, 0x1\n\ + movs r3, 0x2\n\ + bl ConvertIntToDecimalStringN\n\ + ldr r3, _0804450C @ =0x00016088\n\ + adds r4, r3\n\ + ldrb r1, [r4]\n\ + ldr r0, [sp, 0x1C]\n\ + movs r2, 0x1\n\ + movs r3, 0x2\n\ + bl ConvertIntToDecimalStringN\n\ + mov r1, sp\n\ + movs r0, 0\n\ + strb r0, [r1, 0x5]\n\ + movs r0, 0xBA\n\ + strb r0, [r1, 0x8]\n\ + movs r0, 0x80\n\ + lsls r0, 18\n\ + bl sub_80034D4\n\ + movs r7, 0\n\ + lsls r0, r5, 4\n\ + adds r0, r5\n\ + lsls r0, 2\n\ + adds r5, r0, r6\n\ + ldr r4, _08044510 @ =gSharedMem + 0x20\n\ +_080444DA:\n\ + cmp r7, 0x1\n\ + bgt _08044514\n\ + ldrh r1, [r5, 0x4]\n\ + lsls r1, 22\n\ + lsrs r1, 22\n\ + adds r0, r7, 0x2\n\ + adds r1, r0\n\ + lsls r1, 5\n\ + ldr r0, _08044500 @ =0x06010000\n\ + adds r1, r0\n\ + adds r0, r4, 0\n\ + ldr r2, _080444F8 @ =REG_BG0CNT\n\ + bl CpuSet\n\ + b _0804452A\n\ + .align 2, 0\n\ +_080444F8: .4byte 0x04000008\n\ +_080444FC: .4byte gSprites\n\ +_08044500: .4byte 0x06010000\n\ +_08044504: .4byte gSharedMem\n\ +_08044508: .4byte 0x00016089\n\ +_0804450C: .4byte 0x00016088\n\ +_08044510: .4byte gSharedMem + 0x20\n\ +_08044514:\n\ + ldrh r1, [r5, 0x4]\n\ + lsls r1, 22\n\ + lsrs r1, 22\n\ + adds r1, r7, r1\n\ + lsls r1, 5\n\ + ldr r2, _08044544 @ =0x060100c0\n\ + adds r1, r2\n\ + adds r0, r4, 0\n\ + ldr r2, _08044548 @ =REG_BG0CNT\n\ + bl CpuSet\n\ +_0804452A:\n\ + adds r4, 0x40\n\ + adds r7, 0x1\n\ + cmp r7, 0x4\n\ + ble _080444DA\n\ + add sp, 0x20\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08044544: .4byte 0x060100c0\n\ +_08044548: .4byte 0x04000008\n\ + .syntax divided\n"); +} +#endif + +extern u8 gUnknown_020297ED; + +void sub_804454C(void) +{ + s32 i; + u8 spriteId; + + for (i = 0; i < gBattlersCount; i++) + { + if (gSprites[gHealthboxIDs[i]].callback == SpriteCallbackDummy +#if DEBUG + && (gUnknown_020297ED != 0 || GetBattlerSide(i) != 1) +#else + && GetBattlerSide(i) != 1 +#endif + && (IsDoubleBattle() || GetBattlerSide(i) != 0)) + { + u8 r6; + + ewram17800[i].unk0_4 ^= 1; + r6 = ewram17800[i].unk0_4; + if (GetBattlerSide(i) == 0) + { + + if (!IsDoubleBattle()) + continue; + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + continue; + + if (r6 == 1) + { + spriteId = gSprites[gHealthboxIDs[i]].data[5]; + + CpuFill32(0, OBJ_VRAM0 + gSprites[spriteId].oam.tileNum * 32, 0x100); + sub_8044210(gHealthboxIDs[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_HP), 0); + sub_8044210(gHealthboxIDs[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), 1); + } + else + { + draw_status_ailment_maybe(gHealthboxIDs[i]); + sub_8045A5C(gHealthboxIDs[i], &gPlayerParty[gBattlerPartyIndexes[i]], 5); + CpuCopy32(sub_8043CDC(0x75), OBJ_VRAM0 + 0x680 + gSprites[gHealthboxIDs[i]].oam.tileNum * 32, 32); + } + } + else + { + if (r6 == 1) + { + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + { + sub_8044338(gHealthboxIDs[i], &gEnemyParty[gBattlerPartyIndexes[i]]); + } + else + { + spriteId = gSprites[gHealthboxIDs[i]].data[5]; + + CpuFill32(0, OBJ_VRAM0 + gSprites[spriteId].oam.tileNum * 32, 0x100); + sub_8044210(gHealthboxIDs[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_HP), 0); + sub_8044210(gHealthboxIDs[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), 1); + } + } + else + { + draw_status_ailment_maybe(gHealthboxIDs[i]); + sub_8045A5C(gHealthboxIDs[i], &gEnemyParty[gBattlerPartyIndexes[i]], 5); + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + sub_8045A5C(gHealthboxIDs[i], &gEnemyParty[gBattlerPartyIndexes[i]], 4); + } + } + gSprites[gHealthboxIDs[i]].data[7] ^= 1; + } + } +} + +// This function almost matches except for just two instructions around 0x08044B52 that are swapped. +#ifdef NONMATCHING +u8 sub_8044804(u8 a, const struct BattleInterfaceStruct2 *b, u8 c, u8 d) +{ + u8 r7; + s16 x; + s16 y; + s16 r8; + s16 r5; + + int i; + u8 sp[6]; + s8 sp14; + u8 sp18; + u8 taskId; + + if (c == 0 || GetBattlerPosition(a) != 3) + { + if (GetBattlerSide(a) == 0) + { + r7 = 0; + x = 136; + y = 96; + r8 = 100; + r5 = -5; + } + else + { + r7 = 1; + if (c == 0 || !IsDoubleBattle()) + { + x = 104; + y = 40; + } + else + { + x = 104; + y = 16; + } + r8 = -100; + r5 = 5; + } + } + else + { + r7 = 1; + x = 104; + y = 40; + r8 = -100; + r5 = 5; + } + //_08044884 + + sp14 = 0; + for (i = 0; i < 6; i++) //_080448A0 + { + if (b[i].unk0 != 0xFFFF) + sp14++; + } + + LoadCompressedObjectPic(&gUnknown_0820A754[r7]); + LoadSpriteSheet(&gUnknown_0820A784[r7]); + LoadSpritePalette(&gUnknown_0820A764[r7]); + LoadSpritePalette(&gUnknown_0820A774[r7]); + + sp18 = CreateSprite(&gSpriteTemplate_820A7A4[r7], x, y, 10); + SetSubspriteTables(&gSprites[sp18], gSubspriteTables_820A6E4); + gSprites[sp18].pos2.x = r8; + gSprites[sp18].data[0] = r5; + if (r7 != 0) + { + gSprites[sp18].pos1.x -= 96; + gSprites[sp18].oam.matrixNum = 8; + } + else + { + gSprites[sp18].pos1.x += 0x60; + } + //_0804495A + for (i = 0; i < 6; i++) //_08044970 + { + sp[i] = CreateSpriteAtEnd(&gSpriteTemplate_820A7D4[r7], x, y - 4, 9); + if (d == 0) + { + gSprites[sp[i]].callback = sub_8045180; + } + //_080449A0 + if (r7 == 0) + { + gSprites[sp[i]].pos2.x = 0; + gSprites[sp[i]].pos2.y = 0; + } + //_080449BE + gSprites[sp[i]].data[0] = sp18; + if (r7 == 0) + { + gSprites[sp[i]].pos1.x += 10 * i + 24; + gSprites[sp[i]].data[1] = i * 7 + 10; + gSprites[sp[i]].pos2.x = 120; + } + //_08044A18 + else + { + gSprites[sp[i]].pos1.x -= 10 * (5 - i) + 24; + gSprites[sp[i]].data[1] = (6 - i) * 7 + 10; + gSprites[sp[i]].pos2.x = -120; + } + //_08044A56 + gSprites[sp[i]].data[2] = r7; + } + //_08044A76 + if (GetBattlerSide(a) == 0) + { + for (i = 0; i < 6; i++) //_08044A9A + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) // && b[i] != 0xFFFF && b[i] + { + if (b[i].unk0 == 0xFFFF) + { + //_08044AE6 + gSprites[sp[i]].oam.tileNum += 1; + gSprites[sp[i]].data[7] = 1; + // to _08044B52 + } + else if (b[i].unk0 == 0) + { + gSprites[sp[i]].oam.tileNum += 3; + // to _08044B46 + } + else if (b[i].unk4 != 0) + { + gSprites[sp[i]].oam.tileNum += 2; + } + } + //_08044ADC + else + { + if (i >= sp14) + { + //_08044AE6 + gSprites[sp[i]].oam.tileNum += 1; + gSprites[sp[i]].data[7] = 1; + // to _08044B52 + } + else if (b[i].unk0 == 0) + { + //_08044B14 + gSprites[sp[i]].oam.tileNum += 3; + // to _08044B46 + } + else if (b[i].unk4 != 0) + { + gSprites[sp[i]].oam.tileNum += 2; + } + } + } + } + //_08044B5E + else + { + // Mismatch occurrs in this loop initialization + for (i = 0; i < 6; i++) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (b[i].unk0 == 0xFFFF) + { + gSprites[sp[5 - i]].oam.tileNum += 1; + gSprites[sp[5 - i]].data[7] = 1; + } + else if (b[i].unk0 == 0) + { + gSprites[sp[5 - i]].oam.tileNum += 3; + } + else if (b[i].unk4 != 0) + { + gSprites[sp[5 - i]].oam.tileNum += 2; + } + } + else + { + if (i >= sp14) + { + gSprites[sp[5 - i]].oam.tileNum += 1; + gSprites[sp[5 - i]].data[7] = 1; + } + else if (b[i].unk0 == 0) + { + gSprites[sp[5 - i]].oam.tileNum += 3; + } + else if (b[i].unk4 != 0) + { + gSprites[sp[5 - i]].oam.tileNum += 2; + } + } + // This corrects the initialization order, but messes up the counter update order + asm(""::"r"(&b[i])); + } + } + //_08044C38 + taskId = CreateTask(TaskDummy, 5); + gTasks[taskId].data[0] = a; + gTasks[taskId].data[1] = sp18; + for (i = 0; i < 6; i++) + gTasks[taskId].data[3 + i] = sp[i]; + gTasks[taskId].data[10] = d; + PlaySE12WithPanning(SE_TB_START, 0); + return taskId; +} +#else +NAKED +u8 sub_8044804(u8 a, const struct BattleInterfaceStruct2 *b, u8 c, u8 d) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x28\n\ + str r1, [sp, 0xC]\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + str r0, [sp, 0x8]\n\ + lsls r2, 24\n\ + lsrs r2, 24\n\ + adds r4, r2, 0\n\ + lsls r3, 24\n\ + lsrs r3, 24\n\ + str r3, [sp, 0x10]\n\ + cmp r4, 0\n\ + beq _08044834\n\ + bl GetBattlerPosition\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x3\n\ + beq _08044878\n\ +_08044834:\n\ + ldr r0, [sp, 0x8]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _08044854\n\ + movs r7, 0\n\ + movs r1, 0x88\n\ + movs r2, 0x60\n\ + movs r0, 0x64\n\ + mov r8, r0\n\ + ldr r5, _08044850 @ =0x0000fffb\n\ + b _08044884\n\ + .align 2, 0\n\ +_08044850: .4byte 0x0000fffb\n\ +_08044854:\n\ + movs r7, 0x1\n\ + cmp r4, 0\n\ + beq _08044864\n\ + bl IsDoubleBattle\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _0804486A\n\ +_08044864:\n\ + movs r1, 0x68\n\ + movs r2, 0x28\n\ + b _0804486E\n\ +_0804486A:\n\ + movs r1, 0x68\n\ + movs r2, 0x10\n\ +_0804486E:\n\ + ldr r3, _08044874 @ =0x0000ff9c\n\ + mov r8, r3\n\ + b _08044882\n\ + .align 2, 0\n\ +_08044874: .4byte 0x0000ff9c\n\ +_08044878:\n\ + movs r7, 0x1\n\ + movs r1, 0x68\n\ + movs r2, 0x28\n\ + ldr r5, _08044930 @ =0x0000ff9c\n\ + mov r8, r5\n\ +_08044882:\n\ + movs r5, 0x5\n\ +_08044884:\n\ + movs r6, 0\n\ + str r6, [sp, 0x14]\n\ + lsls r4, r7, 3\n\ + ldr r0, _08044934 @ =gUnknown_0820A754\n\ + mov r10, r0\n\ + lsls r3, r7, 1\n\ + mov r9, r3\n\ + lsls r1, 16\n\ + str r1, [sp, 0x20]\n\ + lsls r2, 16\n\ + str r2, [sp, 0x24]\n\ + ldr r2, _08044938 @ =0x0000ffff\n\ + ldr r1, [sp, 0xC]\n\ + movs r6, 0x5\n\ +_080448A0:\n\ + ldrh r0, [r1]\n\ + cmp r0, r2\n\ + beq _080448B4\n\ + ldr r3, [sp, 0x14]\n\ + lsls r0, r3, 24\n\ + movs r3, 0x80\n\ + lsls r3, 17\n\ + adds r0, r3\n\ + lsrs r0, 24\n\ + str r0, [sp, 0x14]\n\ +_080448B4:\n\ + adds r1, 0x8\n\ + subs r6, 0x1\n\ + cmp r6, 0\n\ + bge _080448A0\n\ + mov r6, r10\n\ + adds r0, r4, r6\n\ + bl LoadCompressedObjectPic\n\ + ldr r0, _0804493C @ =gUnknown_0820A784\n\ + adds r0, r4, r0\n\ + bl LoadSpriteSheet\n\ + ldr r0, _08044940 @ =gUnknown_0820A764\n\ + adds r0, r4, r0\n\ + bl LoadSpritePalette\n\ + ldr r0, _08044944 @ =gUnknown_0820A774\n\ + adds r0, r4, r0\n\ + bl LoadSpritePalette\n\ + mov r1, r9\n\ + adds r0, r1, r7\n\ + lsls r0, 3\n\ + ldr r1, _08044948 @ =gSpriteTemplate_820A7A4\n\ + adds r0, r1\n\ + ldr r2, [sp, 0x20]\n\ + asrs r1, r2, 16\n\ + ldr r3, [sp, 0x24]\n\ + asrs r2, r3, 16\n\ + movs r3, 0xA\n\ + bl CreateSprite\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + str r0, [sp, 0x18]\n\ + lsls r0, 4\n\ + ldr r6, [sp, 0x18]\n\ + adds r0, r6\n\ + lsls r0, 2\n\ + ldr r1, _0804494C @ =gSprites\n\ + adds r4, r0, r1\n\ + ldr r1, _08044950 @ =gSubspriteTables_820A6E4\n\ + adds r0, r4, 0\n\ + bl SetSubspriteTables\n\ + mov r0, r8\n\ + strh r0, [r4, 0x24]\n\ + strh r5, [r4, 0x2E]\n\ + cmp r7, 0\n\ + beq _08044954\n\ + ldrh r0, [r4, 0x20]\n\ + subs r0, 0x60\n\ + strh r0, [r4, 0x20]\n\ + ldrb r1, [r4, 0x3]\n\ + movs r0, 0x3F\n\ + negs r0, r0\n\ + ands r0, r1\n\ + movs r1, 0x10\n\ + orrs r0, r1\n\ + strb r0, [r4, 0x3]\n\ + b _0804495A\n\ + .align 2, 0\n\ +_08044930: .4byte 0x0000ff9c\n\ +_08044934: .4byte gUnknown_0820A754\n\ +_08044938: .4byte 0x0000ffff\n\ +_0804493C: .4byte gUnknown_0820A784\n\ +_08044940: .4byte gUnknown_0820A764\n\ +_08044944: .4byte gUnknown_0820A774\n\ +_08044948: .4byte gSpriteTemplate_820A7A4\n\ +_0804494C: .4byte gSprites\n\ +_08044950: .4byte gSubspriteTables_820A6E4\n\ +_08044954:\n\ + ldrh r0, [r4, 0x20]\n\ + adds r0, 0x60\n\ + strh r0, [r4, 0x20]\n\ +_0804495A:\n\ + movs r6, 0\n\ + ldr r1, _08044A04 @ =gSprites\n\ + mov r10, r1\n\ + mov r4, sp\n\ + mov r2, r9\n\ + adds r0, r2, r7\n\ + lsls r0, 3\n\ + str r0, [sp, 0x1C]\n\ + movs r3, 0xA\n\ + mov r9, r3\n\ + mov r8, r6\n\ +_08044970:\n\ + ldr r0, _08044A08 @ =gSpriteTemplate_820A7D4\n\ + ldr r5, [sp, 0x24]\n\ + ldr r1, _08044A0C @ =0xfffc0000\n\ + adds r2, r5, r1\n\ + ldr r3, [sp, 0x1C]\n\ + adds r0, r3, r0\n\ + ldr r5, [sp, 0x20]\n\ + asrs r1, r5, 16\n\ + asrs r2, 16\n\ + movs r3, 0x9\n\ + bl CreateSpriteAtEnd\n\ + strb r0, [r4]\n\ + ldr r0, [sp, 0x10]\n\ + cmp r0, 0\n\ + bne _080449A0\n\ + ldrb r0, [r4]\n\ + lsls r1, r0, 4\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + ldr r2, _08044A10 @ =gSprites + 0x1C\n\ + adds r1, r2\n\ + ldr r0, _08044A14 @ =sub_8045180\n\ + str r0, [r1]\n\ +_080449A0:\n\ + ldr r5, _08044A04 @ =gSprites\n\ + cmp r7, 0\n\ + bne _080449BE\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 4\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + add r0, r10\n\ + strh r7, [r0, 0x24]\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 4\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + add r0, r10\n\ + strh r7, [r0, 0x26]\n\ +_080449BE:\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 4\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r5\n\ + movs r1, 0\n\ + mov r3, sp\n\ + ldrh r3, [r3, 0x18]\n\ + strh r3, [r0, 0x2E]\n\ + cmp r7, 0\n\ + bne _08044A18\n\ + ldrb r0, [r4]\n\ + lsls r1, r0, 4\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + adds r1, r5\n\ + ldrh r0, [r1, 0x20]\n\ + adds r0, 0x18\n\ + add r0, r8\n\ + strh r0, [r1, 0x20]\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 4\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r5\n\ + mov r1, r9\n\ + strh r1, [r0, 0x30]\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 4\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r5\n\ + movs r1, 0x78\n\ + b _08044A56\n\ + .align 2, 0\n\ +_08044A04: .4byte gSprites\n\ +_08044A08: .4byte gSpriteTemplate_820A7D4\n\ +_08044A0C: .4byte 0xfffc0000\n\ +_08044A10: .4byte gSprites + 0x1C\n\ +_08044A14: .4byte sub_8045180\n\ +_08044A18:\n\ + ldrb r0, [r4]\n\ + lsls r2, r0, 4\n\ + adds r2, r0\n\ + lsls r2, 2\n\ + adds r2, r5\n\ + ldrh r3, [r2, 0x20]\n\ + subs r3, 0x18\n\ + movs r1, 0x5\n\ + subs r1, r6\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 1\n\ + subs r3, r0\n\ + strh r3, [r2, 0x20]\n\ + ldrb r0, [r4]\n\ + lsls r2, r0, 4\n\ + adds r2, r0\n\ + lsls r2, 2\n\ + adds r2, r5\n\ + movs r1, 0x6\n\ + subs r1, r6\n\ + lsls r0, r1, 3\n\ + subs r0, r1\n\ + adds r0, 0xA\n\ + strh r0, [r2, 0x30]\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 4\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r5\n\ + ldr r1, _08044AC4 @ =0x0000ff88\n\ +_08044A56:\n\ + strh r1, [r0, 0x24]\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 4\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r5\n\ + strh r7, [r0, 0x32]\n\ + adds r4, 0x1\n\ + movs r2, 0x7\n\ + add r9, r2\n\ + movs r3, 0xA\n\ + add r8, r3\n\ + adds r6, 0x1\n\ + cmp r6, 0x5\n\ + bgt _08044A76\n\ + b _08044970\n\ +_08044A76:\n\ + ldr r0, [sp, 0x8]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _08044B5E\n\ + movs r6, 0\n\ + ldr r5, _08044AC8 @ =gBattleTypeFlags\n\ + mov r10, r5\n\ + ldr r0, _08044ACC @ =0x0000ffff\n\ + mov r9, r0\n\ + ldr r7, _08044AD0 @ =gSprites\n\ + ldr r1, _08044AD4 @ =0x000003ff\n\ + mov r12, r1\n\ + ldr r2, _08044AD8 @ =0xfffffc00\n\ + mov r8, r2\n\ + mov r4, sp\n\ + ldr r5, [sp, 0xC]\n\ +_08044A9A:\n\ + mov r3, r10\n\ + ldrh r1, [r3]\n\ + movs r0, 0x40\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08044ADC\n\ + ldrh r0, [r5]\n\ + cmp r0, r9\n\ + beq _08044AE6\n\ + cmp r0, 0\n\ + bne _08044B2E\n\ + ldrb r0, [r4]\n\ + lsls r2, r0, 4\n\ + adds r2, r0\n\ + lsls r2, 2\n\ + adds r2, r7\n\ + ldrh r3, [r2, 0x4]\n\ + lsls r1, r3, 22\n\ + lsrs r1, 22\n\ + adds r1, 0x3\n\ + b _08044B46\n\ + .align 2, 0\n\ +_08044AC4: .4byte 0x0000ff88\n\ +_08044AC8: .4byte gBattleTypeFlags\n\ +_08044ACC: .4byte 0x0000ffff\n\ +_08044AD0: .4byte gSprites\n\ +_08044AD4: .4byte 0x000003ff\n\ +_08044AD8: .4byte 0xfffffc00\n\ +_08044ADC:\n\ + ldr r1, [sp, 0x14]\n\ + lsls r0, r1, 24\n\ + asrs r0, 24\n\ + cmp r6, r0\n\ + blt _08044B14\n\ +_08044AE6:\n\ + ldrb r0, [r4]\n\ + lsls r2, r0, 4\n\ + adds r2, r0\n\ + lsls r2, 2\n\ + adds r2, r7\n\ + ldrh r3, [r2, 0x4]\n\ + lsls r1, r3, 22\n\ + lsrs r1, 22\n\ + adds r1, 0x1\n\ + mov r0, r12\n\ + ands r1, r0\n\ + mov r0, r8\n\ + ands r0, r3\n\ + orrs r0, r1\n\ + strh r0, [r2, 0x4]\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 4\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r7\n\ + movs r1, 0x1\n\ + strh r1, [r0, 0x3C]\n\ + b _08044B52\n\ +_08044B14:\n\ + ldrh r0, [r5]\n\ + cmp r0, 0\n\ + bne _08044B2E\n\ + ldrb r0, [r4]\n\ + lsls r2, r0, 4\n\ + adds r2, r0\n\ + lsls r2, 2\n\ + adds r2, r7\n\ + ldrh r3, [r2, 0x4]\n\ + lsls r1, r3, 22\n\ + lsrs r1, 22\n\ + adds r1, 0x3\n\ + b _08044B46\n\ +_08044B2E:\n\ + ldr r0, [r5, 0x4]\n\ + cmp r0, 0\n\ + beq _08044B52\n\ + ldrb r0, [r4]\n\ + lsls r2, r0, 4\n\ + adds r2, r0\n\ + lsls r2, 2\n\ + adds r2, r7\n\ + ldrh r3, [r2, 0x4]\n\ + lsls r1, r3, 22\n\ + lsrs r1, 22\n\ + adds r1, 0x2\n\ +_08044B46:\n\ + mov r0, r12\n\ + ands r1, r0\n\ + mov r0, r8\n\ + ands r0, r3\n\ + orrs r0, r1\n\ + strh r0, [r2, 0x4]\n\ +_08044B52:\n\ + adds r4, 0x1\n\ + adds r5, 0x8\n\ + adds r6, 0x1\n\ + cmp r6, 0x5\n\ + ble _08044A9A\n\ + b _08044C38\n\ +_08044B5E:\n\ + movs r6, 0\n\ + ldr r1, _08044BA4 @ =gBattleTypeFlags\n\ + mov r10, r1\n\ + ldr r2, _08044BA8 @ =0x0000ffff\n\ + mov r9, r2\n\ + ldr r7, _08044BAC @ =gSprites\n\ + ldr r3, _08044BB0 @ =0x000003ff\n\ + mov r12, r3\n\ + ldr r5, _08044BB4 @ =0xfffffc00\n\ + mov r8, r5\n\ + ldr r5, [sp, 0xC]\n\ + mov r4, sp\n\ + adds r4, 0x5\n\ +_08044B78:\n\ + mov r0, r10\n\ + ldrh r1, [r0]\n\ + movs r0, 0x40\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08044BB8\n\ + ldrh r0, [r5]\n\ + cmp r0, r9\n\ + beq _08044BC2\n\ + cmp r0, 0\n\ + bne _08044C0A\n\ + ldrb r0, [r4]\n\ + lsls r2, r0, 4\n\ + adds r2, r0\n\ + lsls r2, 2\n\ + adds r2, r7\n\ + ldrh r3, [r2, 0x4]\n\ + lsls r1, r3, 22\n\ + lsrs r1, 22\n\ + adds r1, 0x3\n\ + b _08044C22\n\ + .align 2, 0\n\ +_08044BA4: .4byte gBattleTypeFlags\n\ +_08044BA8: .4byte 0x0000ffff\n\ +_08044BAC: .4byte gSprites\n\ +_08044BB0: .4byte 0x000003ff\n\ +_08044BB4: .4byte 0xfffffc00\n\ +_08044BB8:\n\ + ldr r1, [sp, 0x14]\n\ + lsls r0, r1, 24\n\ + asrs r0, 24\n\ + cmp r6, r0\n\ + blt _08044BF0\n\ +_08044BC2:\n\ + ldrb r0, [r4]\n\ + lsls r2, r0, 4\n\ + adds r2, r0\n\ + lsls r2, 2\n\ + adds r2, r7\n\ + ldrh r3, [r2, 0x4]\n\ + lsls r1, r3, 22\n\ + lsrs r1, 22\n\ + adds r1, 0x1\n\ + mov r0, r12\n\ + ands r1, r0\n\ + mov r0, r8\n\ + ands r0, r3\n\ + orrs r0, r1\n\ + strh r0, [r2, 0x4]\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 4\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r7\n\ + movs r1, 0x1\n\ + strh r1, [r0, 0x3C]\n\ + b _08044C2E\n\ +_08044BF0:\n\ + ldrh r0, [r5]\n\ + cmp r0, 0\n\ + bne _08044C0A\n\ + ldrb r0, [r4]\n\ + lsls r2, r0, 4\n\ + adds r2, r0\n\ + lsls r2, 2\n\ + adds r2, r7\n\ + ldrh r3, [r2, 0x4]\n\ + lsls r1, r3, 22\n\ + lsrs r1, 22\n\ + adds r1, 0x3\n\ + b _08044C22\n\ +_08044C0A:\n\ + ldr r0, [r5, 0x4]\n\ + cmp r0, 0\n\ + beq _08044C2E\n\ + ldrb r0, [r4]\n\ + lsls r2, r0, 4\n\ + adds r2, r0\n\ + lsls r2, 2\n\ + adds r2, r7\n\ + ldrh r3, [r2, 0x4]\n\ + lsls r1, r3, 22\n\ + lsrs r1, 22\n\ + adds r1, 0x2\n\ +_08044C22:\n\ + mov r0, r12\n\ + ands r1, r0\n\ + mov r0, r8\n\ + ands r0, r3\n\ + orrs r0, r1\n\ + strh r0, [r2, 0x4]\n\ +_08044C2E:\n\ + subs r4, 0x1\n\ + adds r5, 0x8\n\ + adds r6, 0x1\n\ + cmp r6, 0x5\n\ + ble _08044B78\n\ +_08044C38:\n\ + ldr r0, _08044C98 @ =TaskDummy\n\ + movs r1, 0x5\n\ + bl CreateTask\n\ + lsls r0, 24\n\ + lsrs r4, r0, 24\n\ + ldr r2, _08044C9C @ =gTasks\n\ + lsls r3, r4, 2\n\ + adds r1, r3, r4\n\ + lsls r1, 3\n\ + adds r0, r1, r2\n\ + mov r5, sp\n\ + ldrh r5, [r5, 0x8]\n\ + strh r5, [r0, 0x8]\n\ + mov r6, sp\n\ + ldrh r6, [r6, 0x18]\n\ + strh r6, [r0, 0xA]\n\ + movs r6, 0\n\ + adds r0, r2, 0\n\ + adds r0, 0xE\n\ + adds r1, r0\n\ +_08044C62:\n\ + mov r5, sp\n\ + adds r0, r5, r6\n\ + ldrb r0, [r0]\n\ + strh r0, [r1]\n\ + adds r1, 0x2\n\ + adds r6, 0x1\n\ + cmp r6, 0x5\n\ + ble _08044C62\n\ + adds r0, r3, r4\n\ + lsls r0, 3\n\ + adds r0, r2\n\ + ldrh r6, [r5, 0x10]\n\ + strh r6, [r0, 0x1C]\n\ + movs r0, 0x72\n\ + movs r1, 0\n\ + bl PlaySE12WithPanning\n\ + adds r0, r4, 0\n\ + add sp, 0x28\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r1}\n\ + bx r1\n\ + .align 2, 0\n\ +_08044C98: .4byte TaskDummy\n\ +_08044C9C: .4byte gTasks\n\ + .syntax divided\n"); +} +#endif + +void sub_8044CA0(u8 taskId) +{ + u8 sp[6]; + u8 r9; + u8 r10; + u8 sp8; + s32 i; + + r9 = gTasks[taskId].data[10]; + r10 = gTasks[taskId].data[1]; + sp8 = gTasks[taskId].data[0]; + for (i = 0; i < 6; i++) + sp[i] = gTasks[taskId].data[3 + i]; + + REG_BLDCNT = 0x3F40; + REG_BLDALPHA = 0x10; + gTasks[taskId].data[15] = 16; + for (i = 0; i < 6; i++) + gSprites[sp[i]].oam.objMode = 1; + gSprites[r10].oam.objMode = 1; + if (r9 != 0) + { + for (i = 0; i < 6; i++) + { + if (GetBattlerSide(sp8) != 0) + { + gSprites[sp[5 - i]].data[1] = 7 * i; + gSprites[sp[5 - i]].data[3] = 0; + gSprites[sp[5 - i]].data[4] = 0; + gSprites[sp[5 - i]].callback = sub_8045110; + } + else + { + gSprites[sp[i]].data[1] = 7 * i; + gSprites[sp[i]].data[3] = 0; + gSprites[sp[i]].data[4] = 0; + gSprites[sp[i]].callback = sub_8045110; + } + } + gSprites[r10].data[0] /= 2; + gSprites[r10].data[1] = 0; + gSprites[r10].callback = sub_8045048; + SetSubspriteTables(&gSprites[r10], gSubspriteTables_820A6EC); + gTasks[taskId].func = sub_8044E74; + } + else + { + gTasks[taskId].func = sub_8044F70; + } +} + +static void sub_8044E74(u8 taskId) +{ + u16 temp = gTasks[taskId].data[11]++; + + if ((temp & 1) == 0) + { + gTasks[taskId].data[15]--; + if (gTasks[taskId].data[15] < 0) + return; + REG_BLDALPHA = (gTasks[taskId].data[15]) | ((16 - gTasks[taskId].data[15]) << 8); + } + if (gTasks[taskId].data[15] == 0) + gTasks[taskId].func = sub_8044ECC; +} + +static void sub_8044ECC(u8 taskId) +{ + u8 sp[6]; + s32 i; + + gTasks[taskId].data[15]--; + if (gTasks[taskId].data[15] == -1) + { + u8 var = gTasks[taskId].data[1]; + + for (i = 0; i < 6; i++) + sp[i] = gTasks[taskId].data[3 + i]; + DestroySpriteAndFreeResources(&gSprites[var]); + DestroySpriteAndFreeResources(&gSprites[sp[0]]); + for (i = 1; i < 6; i++) + DestroySprite(&gSprites[sp[i]]); + } + else if (gTasks[taskId].data[15] == -3) + { + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + DestroyTask(taskId); + } +} + +static void sub_8044F70(u8 taskId) +{ + u8 sp[6]; + s32 i; + + gTasks[taskId].data[15]--; + // Same as above function except with this check. + if (gTasks[taskId].data[15] >= 0) + { + REG_BLDALPHA = (gTasks[taskId].data[15]) | ((16 - gTasks[taskId].data[15]) << 8); + } + else if (gTasks[taskId].data[15] == -1) + { + u8 var = gTasks[taskId].data[1]; + + for (i = 0; i < 6; i++) + sp[i] = gTasks[taskId].data[3 + i]; + DestroySpriteAndFreeResources(&gSprites[var]); + DestroySpriteAndFreeResources(&gSprites[sp[0]]); + for (i = 1; i < 6; i++) + DestroySprite(&gSprites[sp[i]]); + } + else if (gTasks[taskId].data[15] == -3) + { + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + DestroyTask(taskId); + } +} + +static void sub_8045030(struct Sprite *sprite) +{ + if (sprite->pos2.x != 0) + sprite->pos2.x += sprite->data[0]; +} + +static void sub_8045048(struct Sprite *sprite) +{ + sprite->data[1] += 32; + if (sprite->data[0] > 0) + sprite->pos2.x += sprite->data[1] >> 4; + else + sprite->pos2.x -= sprite->data[1] >> 4; + sprite->data[1] &= 0xF; +} + +static void sub_804507C(struct Sprite *sprite) +{ + u8 r3; + u16 r2; + s8 pan; + + if (sprite->data[1] > 0) + { + sprite->data[1]--; + return; + } + r3 = sprite->data[2]; + r2 = sprite->data[3]; + r2 += 56; + sprite->data[3] = r2 & 0xFFF0; + if (r3 != 0) + { + sprite->pos2.x += r2 >> 4; + if (sprite->pos2.x > 0) + sprite->pos2.x = 0; + } + else + { + sprite->pos2.x -= r2 >> 4; + if (sprite->pos2.x < 0) + sprite->pos2.x = 0; + } + if (sprite->pos2.x == 0) + { + pan = 63; + if (r3 != 0) + pan = -64; + if (sprite->data[7] != 0) + PlaySE2WithPanning(SE_TB_KARA, pan); + else + PlaySE1WithPanning(SE_TB_KON, pan); + sprite->callback = SpriteCallbackDummy; + } +} + +static void sub_8045110(struct Sprite *sprite) +{ + u8 r0; + u16 r2; + + if (sprite->data[1] > 0) + { + sprite->data[1]--; + return; + } + r0 = sprite->data[2]; + r2 = sprite->data[3]; + r2 += 56; + sprite->data[3] = r2 & 0xFFF0; + if (r0 != 0) + sprite->pos2.x += r2 >> 4; + else + sprite->pos2.x -= r2 >> 4; + if (sprite->pos2.x + sprite->pos1.x > 248 + || sprite->pos2.x + sprite->pos1.x < -8) + { + sprite->invisible = TRUE; + sprite->callback = SpriteCallbackDummy; + } +} + +void sub_8045180(struct Sprite *sprite) +{ + u8 spriteId = sprite->data[0]; + + sprite->pos2.x = gSprites[spriteId].pos2.x; + sprite->pos2.y = gSprites[spriteId].pos2.y; +} + +/*static*/ void sub_80451A0(u8 a, struct Pokemon *pkmn) +{ + u8 nickname[POKEMON_NAME_LENGTH]; + u8 gender; + u16 species; + u8 language; + u8 *ptr; + s32 i; + s32 _7; + u8 *const *r1; + + StringCopy(gDisplayedStringBattle, gUnknown_0820A8B0); + GetMonData(pkmn, MON_DATA_NICKNAME, nickname); + StringGetEnd10(nickname); + ptr = StringCopy(gDisplayedStringBattle + 3, nickname); + ptr[0] = EXT_CTRL_CODE_BEGIN; + ptr[1] = 3; + ptr[2] = 2; + ptr[3] = EXT_CTRL_CODE_BEGIN; + ptr[4] = 1; + ptr += 5; + gender = GetMonGender(pkmn); + species = GetMonData(pkmn, MON_DATA_SPECIES); + language = GetMonData(pkmn, MON_DATA_LANGUAGE); + if (ShouldHideGenderIconForLanguage(species, nickname, language)) + gender = 100; + switch (gender) + { + default: + ptr[0] = 0xB; + ptr[1] = EOS; + ptr += 1; + break; + case MON_MALE: + ptr[0] = 0xB; + ptr[1] = CHAR_MALE; + ptr[2] = EOS; + ptr += 2; + break; + case MON_FEMALE: + ptr[0] = 0xA; + ptr[1] = CHAR_FEMALE; + ptr[2] = EOS; + ptr += 2; + break; + } + ptr[0] = EXT_CTRL_CODE_BEGIN; + ptr[1] = 0x13; + ptr[2] = 0x37; + ptr[3] = EOS; + ptr = ewram520_2 + GetBattlerPosition(gSprites[a].data[6]) * 0x180; + sub_80034D4(ptr, gDisplayedStringBattle); + + i = 0; + _7 = 7; + if (GetMonData(pkmn, MON_DATA_LANGUAGE) == 1 + && GetMonData(pkmn, MON_DATA_IS_EGG) == 0) + { + u8 *p = gDisplayedStringBattle; + + while (*p != EOS) + { + if (*p == EXT_CTRL_CODE_BEGIN) + { + p += GetExtCtrlCodeLength(p[1]) + 1; + } + else + { + u8 r0; + + if ((*p >= 0x37 && *p <= 0x4A) || (*p >= 0x87 && *p <= 0x9A)) + r0 = 0x2C; + else if ((*p >= 0x4B && *p <= 0x4F) || (*p >= 0x9B && *p <= 0x9F)) + r0 = 0x2D; + else + r0 = 0x2B; + + CpuCopy32(sub_8043CDC(r0), ptr + 0x40 * i, 32); + i++; + p++; + } + } + } + + for (; i < _7; i++) + CpuCopy32(sub_8043CDC(0x2B), ptr + 64 * i, 32); + + if (GetBattlerSide(gSprites[a].data[6]) == 0 && !IsDoubleBattle()) + { + r1 = (u8 *const *)gUnknown_0820A8B4; + for (i = 0; i < _7; i++) + { + u8 *r4 = r1[i]; + + r4 += gSprites[a].oam.tileNum * 32; + CpuCopy32(ptr, r4, 32); + ptr += 32; + + r4 += 0x100; + CpuCopy32(ptr, r4, 32); + ptr += 32; + } + } + else + { + if (GetBattlerSide(gSprites[a].data[6]) == 0) + r1 = (u8 *const *)gUnknown_0820A904; + else + r1 = (u8 *const *)gUnknown_0820A8DC; + for (i = 0; i < _7; i++) + { + u8 *r4 = r1[i]; + + r4 += gSprites[a].oam.tileNum * 32; + CpuCopy32(ptr, r4, 32); + ptr += 32; + + r4 += 0x100; + CpuCopy32(ptr, r4, 32); + ptr += 32; + } + } +} + +static void sub_8045458(u8 a, u8 b) +{ + u8 r4; + + if (gBattleTypeFlags & 0x200) + return; + if (gBattleTypeFlags & 8) + return; + + r4 = gSprites[a].data[6]; + if (GetBattlerSide(r4) != 0) + { + u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[r4]], MON_DATA_SPECIES); + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), 1) != 0) + { + r4 = gSprites[a].data[5]; + if (b != 0) + CpuCopy32(sub_8043CDC(0x46), OBJ_VRAM0 + (gSprites[r4].oam.tileNum + 8) * 32, 32); + else + CpuFill32(0, OBJ_VRAM0 + (gSprites[r4].oam.tileNum + 8) * 32, 32); + } + } +} + +/*static*/ void draw_status_ailment_maybe(u8 a) +{ + s32 r4; + s32 r4_2; + u8 r7; + u8 r10; + s16 r8; + const u8 *r6; + u8 r0; + s32 i; + + r7 = gSprites[a].data[6]; + r10 = gSprites[a].data[5]; + if (GetBattlerSide(r7) == 0) + { + r4 = GetMonData(&gPlayerParty[gBattlerPartyIndexes[r7]], MON_DATA_STATUS); + if (!IsDoubleBattle()) + r8 = 0x1A; + else + r8 = 0x12; + } + else + { + r4 = GetMonData(&gEnemyParty[gBattlerPartyIndexes[r7]], MON_DATA_STATUS); + r8 = 0x11; + } + if (r4 & 7) + { + r6 = sub_8043CDC(sub_80457E8(0x1B, r7)); + r0 = 2; + } + else if (r4 & 0x88) + { + r6 = sub_8043CDC(sub_80457E8(0x15, r7)); + r0 = 0; + } + else if (r4 & 0x10) + { + r6 = sub_8043CDC(sub_80457E8(0x21, r7)); + r0 = 4; + } + else if (r4 & 0x20) + { + r6 = sub_8043CDC(sub_80457E8(0x1E, r7)); + r0 = 3; + } + else if (r4 & 0x40) + { + r6 = sub_8043CDC(sub_80457E8(0x18, r7)); + r0 = 1; + } + else + { + r6 = sub_8043CDC(0x27); + + for (i = 0; i < 3; i++) + CpuCopy32(r6, OBJ_VRAM0 + (gSprites[a].oam.tileNum + r8 + i) * 32, 32); + + if (!ewram17800[r7].unk0_4) + CpuCopy32(sub_8043CDC(1), OBJ_VRAM0 + gSprites[r10].oam.tileNum * 32, 64); + + sub_8045458(a, 1); + return; + } + + r4_2 = gSprites[a].oam.paletteNum * 16; + r4_2 += r7 + 12; + // I don't like writing the array index like this, but I can't get it to match otherwise. + FillPalette(r0[gBattleInterfaceStatusIcons_DynPal], r4_2 + 0x100, 2); + CpuCopy16(gPlttBufferUnfaded + 0x100 + r4_2, (void *)(OBJ_PLTT + r4_2 * 2), 2); + CpuCopy32(r6, OBJ_VRAM0 + (gSprites[a].oam.tileNum + r8) * 32, 96); + if (IsDoubleBattle() == TRUE || GetBattlerSide(r7) == TRUE) + { + if (!ewram17800[r7].unk0_4) + { + CpuCopy32(sub_8043CDC(0), OBJ_VRAM0 + gSprites[r10].oam.tileNum * 32, 32); + CpuCopy32(sub_8043CDC(0x41), OBJ_VRAM0 + (gSprites[r10].oam.tileNum + 1) * 32, 32); + } + } + sub_8045458(a, 0); +} + +static u8 sub_80457E8(u8 a, u8 b) +{ + u8 ret = a; + + switch (a) + { + case 21: + if (b == 0) + ret = 21; + else if (b == 1) + ret = 71; + else if (b == 2) + ret = 86; + else + ret = 101; + break; + case 24: + if (b == 0) + ret = 24; + else if (b == 1) + ret = 74; + else if (b == 2) + ret = 89; + else + ret = 104; + break; + case 27: + if (b == 0) + ret = 27; + else if (b == 1) + ret = 77; + else if (b == 2) + ret = 92; + else + ret = 107; + break; + case 30: + if (b == 0) + ret = 30; + else if (b == 1) + ret = 80; + else if (b == 2) + ret = 95; + else + ret = 110; + break; + case 33: + if (b == 0) + ret = 33; + else if (b == 1) + ret = 83; + else if (b == 2) + ret = 98; + else + ret = 113; + break; + } + return ret; +} + +/*static*/ void sub_80458B0(u8 a) +{ + u8 *r6; + u8 r8; + u8 i; + s32 r7; + u8 *addr; + + r6 = ewram520_2 + GetBattlerPosition(gSprites[a].data[6]) * 0x180; + r8 = 7; + sub_80034D4(r6, BattleText_SafariBalls); + for (i = 0; i < r8; i++) + CpuCopy32(sub_8043CDC(0x2B), r6 + i * 64, 32); + for (r7 = 3; r7 < 3 + r8; r7++) + { + addr = OBJ_VRAM0 + (gSprites[a].oam.tileNum + MACRO1(r7)) * 32; + CpuCopy32(r6, addr, 32); + r6 += 32; + + addr = OBJ_VRAM0 + (8 + gSprites[a].oam.tileNum + MACRO1(r7)) * 32; + CpuCopy32(r6, addr, 32); + r6 += 32; + } + +} + +/*static*/ void sub_8045998(u8 a) +{ + u8 *r7; + u8 status; + s32 r6; + s32 i; + + r7 = StringCopy(gDisplayedStringBattle, BattleText_SafariBallsLeft); + r7 = sub_8003504(r7, gNumSafariBalls, 10, 1); + StringAppend(r7, BattleText_HighlightRed); + status = GetBattlerPosition(gSprites[a].data[6]); + r7 = ewram520_2 + status * 0x180; + r6 = 5; + sub_80034D4(r7, gDisplayedStringBattle); + r7 = ewram520_2 + status * 0x180 + 32; + for (i = 6; i < 6 + r6; i++) + { + CpuCopy32(r7, OBJ_VRAM0 + (gSprites[a].oam.tileNum + 0x18 + MACRO1(i)) * 32, 32); + r7 += 64; + } +} + +void sub_8045A5C(u8 a, struct Pokemon *pkmn, u8 c) +{ + u8 r10; + u32 maxhp; + u32 currhp; + + r10 = gSprites[a].data[6]; + if (GetBattlerSide(r10) == 0) + { + if (c == 3 || c == 0) + sub_8043FC0(a, GetMonData(pkmn, MON_DATA_LEVEL)); + if (c == 1 || c == 0) + sub_80440EC(a, GetMonData(pkmn, MON_DATA_HP), 0); + if (c == 2 || c == 0) + sub_80440EC(a, GetMonData(pkmn, MON_DATA_MAX_HP), 1); + if (c == 5 || c == 0) + { + load_gfxc_health_bar(0); + maxhp = GetMonData(pkmn, MON_DATA_MAX_HP); + currhp = GetMonData(pkmn, MON_DATA_HP); + sub_8043D84(r10, a, maxhp, currhp, 0); + sub_8045C78(r10, a, 0, 0); + } + if (!IsDoubleBattle() && (c == 6 || c == 0)) + { + u16 species; + u8 level; + u32 exp; + u32 var1; + u32 var2; + u32 currLevelExp; + + load_gfxc_health_bar(3); + species = GetMonData(pkmn, MON_DATA_SPECIES); + level = GetMonData(pkmn, MON_DATA_LEVEL); + exp = GetMonData(pkmn, MON_DATA_EXP); + currLevelExp = gExperienceTables[gBaseStats[species].growthRate][level]; + var1 = exp - currLevelExp; + var2 = gExperienceTables[gBaseStats[species].growthRate][level + 1] - currLevelExp; + sub_8043D84(r10, a, var2, var1, 0); + sub_8045C78(r10, a, 1, 0); + } + if (c == 4 || c == 0) + sub_80451A0(a, pkmn); + if (c == 9 || c == 0) + draw_status_ailment_maybe(a); + if (c == 10) + sub_80458B0(a); + if (c == 10 || c == 11) + sub_8045998(a); + } + else + { + if (c == 3 || c == 0) + sub_8043FC0(a, GetMonData(pkmn, MON_DATA_LEVEL)); +#if DEBUG + if (gUnknown_020297ED == 1) + { + if (c == 1 || c == 0) + sub_80440EC(a, GetMonData(pkmn, MON_DATA_HP), 0); + if (c == 2 || c == 0) + sub_80440EC(a, GetMonData(pkmn, MON_DATA_MAX_HP), 1); + } +#endif + if (c == 5 || c == 0) + { + load_gfxc_health_bar(0); + maxhp = GetMonData(pkmn, MON_DATA_MAX_HP); + currhp = GetMonData(pkmn, MON_DATA_HP); + sub_8043D84(r10, a, maxhp, currhp, 0); + sub_8045C78(r10, a, 0, 0); + } + if (c == 4 || c == 0) + sub_80451A0(a, pkmn); + if (c == 9 || c == 0) + draw_status_ailment_maybe(a); + } +} + +s32 sub_8045C78(u8 a, u8 unused1, u8 c, u8 unused2) +{ + s32 r6; + + if (c == 0) + { + r6 = sub_8045F58(ewram17850[a].unk4, ewram17850[a].unk8, ewram17850[a].unkC, &ewram17850[a].unk10, 6, 1); + } + else + { + u16 r5; + s32 r8; + + r5 = GetScaledExpFraction(ewram17850[a].unk8, ewram17850[a].unkC, ewram17850[a].unk4, 8); + if (r5 == 0) + r5 = 1; + r8 = ewram17850[a].unkC; + r5 = ABS(r8 / r5); + r6 = sub_8045F58(ewram17850[a].unk4, ewram17850[a].unk8, r8, &ewram17850[a].unk10, 8, r5); + } + if (c == 1 || (c == 0 && (!ewram17800[a].unk0_4))) + sub_8045D58(a, c); + if (r6 == -1) + ewram17850[a].unk10 = 0; + return r6; +} + +static void sub_8045D58(u8 a, u8 b) +{ + u8 sp8[7]; + u8 r0; + u8 r8; + u8 i; + + switch (b) + { + case 0: + r0 = sub_804602C(ewram17850[a].unk4, ewram17850[a].unk8, ewram17850[a].unkC, &ewram17850[a].unk10, sp8, 6); + r8 = 3; + if (r0 <= 0x18) + { + r8 = 0x38; + if (r0 > 9) + r8 = 0x2F; + } + for (i = 0; i < 6; i++) + { + u8 r4 = gSprites[ewram17850[a].unk0].data[5]; + if (i < 2) + CpuCopy32(sub_8043CDC(r8) + sp8[i] * 32, OBJ_VRAM0 + (gSprites[r4].oam.tileNum + 2 + i) * 32, 32); + else + CpuCopy32(sub_8043CDC(r8) + sp8[i] * 32, OBJ_VRAM0 + 64 + (i + gSprites[r4].oam.tileNum) * 32, 32); + } + break; + case 1: + sub_804602C(ewram17850[a].unk4, ewram17850[a].unk8, ewram17850[a].unkC, &ewram17850[a].unk10, sp8, 8); + r0 = GetMonData(&gPlayerParty[gBattlerPartyIndexes[a]], MON_DATA_LEVEL); + if (r0 == 100) + { + for (i = 0; i < 8; i++) + sp8[i] = 0; + } + for (i = 0; i < 8; i++) + { + if (i < 4) + CpuCopy32(sub_8043CDC(0xC) + sp8[i] * 32, OBJ_VRAM0 + (gSprites[ewram17850[a].unk0].oam.tileNum + 0x24 + i) * 32, 32); + else + CpuCopy32(sub_8043CDC(0xC) + sp8[i] * 32, OBJ_VRAM0 + 0xB80 + (i + gSprites[ewram17850[a].unk0].oam.tileNum) * 32, 32); + } + break; + } +} + +static int sub_8045F58(s32 a, s32 b, int c, int *d, u8 e, u16 f) +{ + u8 r2 = e << 3; + int r6; + int ret; + + if (*d == -32768) + { + if (a < r2) + *d = b << 8; + else + *d = b; + } + //_08045F8A + b -= c; + if (b < 0) + b = 0; + else if (b > a) + b = a; + if (a < r2) + { + int var = *d >> 8; + + r6 = *d; + if (b == var && (r6 & 0xFF) == 0) + return -1; + } + else + { + r6 = *d; + if (b == r6) + return -1; + } + //_08045FC4 + if (a < r2) + { + int r0 = (a << 8) / r2; + + if (c < 0) + { + *d = r6 + r0; + ret = *d >> 8; + if (ret >= b) + { + *d = b << 8; + ret = b; + } + } + //_08045FE2 + else + { + *d = r6 - r0; + ret = *d >> 8; + if ((*d & 0xFF) > 0) + ret++; + if (ret <= b) + { + *d = b << 8; + ret = b; + } + } + } + else + { + //_08045FFE + if (c < 0) + { + *d += f; + if (*d > b) + *d = b; + ret = *d; + } + //_08046010 + else + { + *d -= f; + if (*d < b) + *d = b; + ret = *d; + } + } + return ret; +} + +static u8 sub_804602C(int a, int b, int c, int *d, u8 *e, u8 f) +{ + s32 r5 = b - c; + u8 r3; + u8 i; + u8 r2; + + if (r5 < 0) + r5 = 0; + else if (r5 > a) + r5 = a; + r3 = f << 3; + for (i = 0; i < f; i++) + e[i] = 0; + if (a < r3) + r2 = *d * r3 / a >> 8; + else + r2 = *d * r3 / a; + r3 = r2; + if (r3 == 0 && r5 > 0) + { + e[0] = 1; + r3 = 1; + } + else + { + for (i = 0; i < f; i++) + { + if (r2 >= 8) + { + e[i] = 8; + } + else + { + e[i] = r2; + break; + } + r2 -= 8; + } + } + return r3; +} + +s16 sub_80460C8(struct BattleInterfaceStruct1 *a, int *b, u16 *c, int d) +{ + u16 r7; + s16 r1; + + r7 = sub_8045F58(a->unk0, a->unk4, a->unk8, b, 6, 1); + sub_8046128(a, b, c); + if (a->unk0 < 0x30) + r1 = *b >> 8; + else + r1 = *b; + do_nothing(a->unk0, r1, d); + return r7; +} + +static void sub_8046128(struct BattleInterfaceStruct1 *a, int *b, u16 *c) +{ + u8 sp8[6]; + u16 sp10[6]; + u8 i; + + sub_804602C(a->unk0, a->unk4, a->unk8, b, (u8 *)sp8, 6); + for (i = 0; i < 6; i++) + sp10[i] = (a->unkC_0 << 12) | (a->unk10 + sp8[i]); + CpuCopy16(sp10, c, sizeof(sp10)); +} + +static u8 GetScaledExpFraction(int a, int b, int c, u8 d) +{ + u8 r7 = d * 8; + int r5 = a - b; + s8 r4; + s8 r0; + s32 result; + + if (r5 < 0) + r5 = 0; + else if (r5 > c) + r5 = c; + + r4 = a * r7 / c; + r0 = r5 * r7 / c; + result = r4 - r0; + return ABS(result); +} + +u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale) +{ + u8 result = hp * scale / maxhp; + + if (result == 0 && hp > 0) + return 1; + return result; +} + +u8 GetHPBarLevel(s16 hp, s16 maxhp) +{ + int result; + + if (hp == maxhp) + result = 4; + else + { + u8 fraction = GetScaledHPFraction(hp, maxhp, 48); + if (fraction >= 25) + result = 3; + else if (fraction >= 10) + result = 2; + else if (fraction > 0) + result = 1; + else + result = 0; + } + return result; +} diff --git a/src/battle_main.c b/src/battle_main.c new file mode 100644 index 000000000..ff376a5e4 --- /dev/null +++ b/src/battle_main.c @@ -0,0 +1,5580 @@ +#include "global.h" +#include "constants/abilities.h" +#include "constants/battle_move_effects.h" +#include "constants/hold_effects.h" +#include "constants/items.h" +#include "constants/moves.h" +#include "constants/songs.h" +#include "constants/species.h" +#include "gba/flash_internal.h" +#include "battle.h" +#include "battle_ai_script_commands.h" +#include "battle_interface.h" +#include "battle_message.h" +#include "battle_setup.h" +#include "battle_util.h" +#include "data2.h" +#include "decompress.h" +#include "event_data.h" +#include "evolution_scene.h" +#include "item.h" +#include "item_menu.h" +#include "link.h" +#include "main.h" +#include "m4a.h" +#include "name_string_util.h" +#include "overworld.h" +#include "palette.h" +#include "party_menu.h" +#include "pokeball.h" +#include "pokeblock.h" +#include "pokedex.h" +#include "pokemon.h" +#include "random.h" +#include "roamer.h" +#include "rom3.h" +#include "rom_8077ABC.h" +#include "rom_8094928.h" +#include "safari_zone.h" +#include "sound.h" +#include "sprite.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "trainer.h" +#include "trig.h" +#include "tv.h" +#include "scanline_effect.h" +#include "util.h" +#include "ewram.h" + +struct UnknownStruct7 +{ + u8 unk0; + u8 unk1; + u8 unk2; + u8 unk3; +}; + +struct UnknownStruct8 +{ + u8 unk0[7]; + u8 unk7; + u8 unk8[18]; + u8 unk1A; +}; + +extern void sub_802BBD4(); + +extern struct SpriteTemplate gUnknown_02024E8C; +extern const u8 Str_821F7B8[]; +extern u8 gUnknown_02023A14_50; +extern const u16 gBattleTextboxPalette[]; +extern const struct MonCoords gCastformFrontSpriteCoords[]; +extern const u8 Str_821F7EA[]; +extern const u8 gUnknown_Debug_821F7F3[]; +extern const u8 BattleText_YesNo[]; +extern u8 gStatStageRatios[][2]; +extern u8 gActionsByTurnOrder[4]; +extern struct UnknownPokemonStruct2 gMultiPartnerParty[]; +extern u8 gBattleBufferB[][0x200]; +extern u8 gActiveBattler; +extern u32 gBattleExecBuffer; +extern u8 gBattlersCount; +extern u16 gBattlerPartyIndexes[]; +extern u8 gCurrentActionFuncId; +extern u8 gBanksByTurnOrder[]; +extern u8 gBankSpriteIds[]; +extern u16 gCurrentMove; // This is mis-named. It is a species, not a move ID. +extern u8 gLastUsedAbility; +extern u8 gStringBank; +extern u8 gAbsentBattlerFlags; +extern u8 gMultiHitCounter; +extern u8 gActionForBanks[]; +extern u16 gUnknown_02024C2C[]; +extern u16 gLastUsedMove[]; +extern u16 gLastLandedMoves[]; +extern u16 gLastHitByType[]; +extern u16 gUnknown_02024C4C[]; +extern u16 gLockedMoves[]; +extern u8 gLastHitBy[]; +extern u16 gChosenMovesByBanks[]; +extern u32 gHitMarker; +extern u8 gUnknown_02024C70[]; +extern u16 gSideAffecting[]; +extern u32 gStatuses3[]; +//extern u8 gDisableStructs[][0x1C]; +extern u16 gPauseCounterBattle; +extern u16 gPaydayMoney; +extern u16 gRandomTurnNumber; +extern u8 gBattleCommunication[]; +extern u8 gUnknown_02024D1F[]; // I don't actually know what type this is. +extern u8 gBattleOutcome; +extern u16 gUnknown_02024DE8; +extern u8 gActionSelectionCursor[]; +extern u8 gMoveSelectionCursor[]; +extern u8 gUnknown_02038470[]; +extern struct Window gUnknown_030041D0; +extern struct Window gUnknown_03004210; +extern struct Window gUnknown_03004250; +extern u32 gUnknown_03004284; +extern MainCallback gPreBattleCallback1; +extern void (*gBattleMainFunc)(void); +extern u8 gLeveledUpInBattle; +extern void (*gBattleBankFunc[])(void); +extern u8 gHealthboxIDs[]; +extern u16 gBattleTypeFlags; +extern s8 gBattleTerrain; // I'm not sure if this is supposed to be s8 or u8. Regardless, it must have the same type as the return value of BattleSetup_GetTerrain. +extern u8 gReservedSpritePaletteCount; +extern u16 gTrainerBattleOpponent; +extern struct BattleEnigmaBerry gEnigmaBerries[]; +extern u16 gBlockRecvBuffer[MAX_LINK_PLAYERS][BLOCK_BUFFER_SIZE / 2]; +extern u8 gBattleMonForms[]; +extern u8 gBankAttacker; +extern u8 gBankTarget; +extern u16 gBattleWeather; +extern s32 gBattleMoveDamage; +extern struct BattlePokemon gBattleMons[]; +extern u8 gMoveResultFlags; +extern u8 BattleScript_FocusPunchSetUp[]; +extern u16 gDynamicBasePower; +extern u8 gCurrentTurnActionNumber; +extern void (* const gUnknown_081FA640[])(void); +extern void (* const gUnknown_081FA678[])(void); +extern u8* gBattlescriptCurrInstr; +extern u8 BattleScript_LinkBattleWonOrLost[]; +extern u8 BattleScript_PayDayMoneyAndPickUpItems[]; +extern u8 gUnknown_081D8E0D[]; +extern u8 BattleScript_LocalTrainerBattleWon[]; +extern u8 BattleScript_LocalBattleLost[]; +extern u8 BattleScript_GotAwaySafely[]; +extern u8 BattleScript_SmokeBallEscape[]; +extern u8 BattleScript_RanAwayUsingMonAbility[]; +extern u8 BattleScript_WildMonFled[]; +extern u8 BattleScript_ActionSwitch[]; +extern u8 BattleScript_PrintFailedToRunString[]; +extern const BattleCmdFunc gBattleScriptingCommandsTable[]; +extern u8 gCritMultiplier; +extern u8 gCurrMovePos; +extern u8 gUnknown_02024BE5; +extern u16 gChosenMove; +extern u8* gBattleScriptsForMoveEffects[]; +extern u16 gLastUsedItem; +extern u8 * const gBattlescriptsForBallThrow[]; +extern u8 * const gBattlescriptsForRunningByItem[]; +extern u8 * const gBattlescriptsForUsingItem[]; +extern u8 * const gBattlescriptsForSafariActions[]; +extern u8 gBattleTextBuff2[]; +extern u8 gNumSafariBalls; +extern u8 gUnknown_081FA70C[][3]; +extern u8 gUnknown_081FA71B[]; +extern u8 gUnknown_081FA71F[]; + +void sub_8010824(void); +static void BattlePrepIntroSlide(void); +void CheckFocusPunch_ClearVarsBeforeTurnStarts(void); +void SetActionsAndBanksTurnOrder(void); +static void TurnValuesCleanUp(u8); +void SpecialStatusesClear(void); +static void RunTurnActionsFunctions(void); +void HandleEndTurn_FinishBattle(); +static void FreeResetData_ReturnToOvOrDoEvolutions(void); +void TryEvolvePokemon(void); +static void ReturnFromBattleToOverworld(void); +static void WaitForEvoSceneToFinish(void); + +void sub_800E7C4(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + sub_800B858(); + SetMainCallback2(sub_800F104); + gBattleCommunication[0] = 0; + } + else + { + InitBattle(); + } +} + +void InitBattle(void) +{ + s32 i; + + SetHBlankCallback(NULL); + SetVBlankCallback(NULL); + + CpuFill32(0, (void *)VRAM, VRAM_SIZE); + + REG_MOSAIC = 0; + REG_WIN0H = 0xF0; + REG_WIN0V = 0x5051; + REG_WININ = 0; + REG_WINOUT = 0; + gBattle_WIN0H = 0xF0; + gBattle_WIN0V = 0x5051; + ScanlineEffect_Clear(); + + for (i = 0; i < 80; i++) + { + gScanlineEffectRegBuffers[0][i] = 0xF0; + gScanlineEffectRegBuffers[1][i] = 0xF0; + } + for (i = 80; i < 160; i++) + { + asm(""::"r"(i)); // Needed to stop the compiler from optimizing out the loop counter + gScanlineEffectRegBuffers[0][i] = 0xFF10; + gScanlineEffectRegBuffers[1][i] = 0xFF10; + } + //ScanlineEffect_SetParams(gUnknown_081F9674.unk0, gUnknown_081F9674.unk4, gUnknown_081F9674.unk8); + ScanlineEffect_SetParams(gUnknown_081F9674); + Text_LoadWindowTemplate(&gWindowTemplate_81E6C58); + ResetPaletteFade(); + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + gBattle_BG2_X = 0; + gBattle_BG2_Y = 0; + gBattle_BG3_X = 0; + gBattle_BG3_Y = 0; + +#if DEBUG + if (!(gUnknown_02023A14_50 & 8)) + gBattleTerrain = BattleSetup_GetTerrain(); +#else + gBattleTerrain = BattleSetup_GetTerrain(); +#endif + + Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58); + Text_InitWindowWithTemplate(&gUnknown_030041D0, &gWindowTemplate_81E71D0); + Text_InitWindowWithTemplate(&gUnknown_03004250, &gWindowTemplate_81E71EC); + sub_800D6D4(); + LoadBattleTextboxAndBackground(); + ResetSpriteData(); + ResetTasks(); + LoadBattleEntryBackground(); + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 4; + SetVBlankCallback(sub_800FCFC); + setup_poochyena_battle(); + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + SetMainCallback2(sub_800F298); + else + SetMainCallback2(sub_800EC9C); + if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) +#if DEBUG + && !(gUnknown_02023A14_50 & 8) +#endif + ) + { + CreateNPCTrainerParty(gEnemyParty, gTrainerBattleOpponent); + SetWildMonHeldItem(); + } + gMain.inBattle = TRUE; + for (i = 0; i < PARTY_SIZE; i++) + AdjustFriendship(&gPlayerParty[i], FRIENDSHIP_EVENT_LEAGUE_BATTLE); + gBattleCommunication[0] = 0; +} + +void sub_800E9EC(void) +{ + u16 r6 = 0; + u16 species; + u16 hp; + u32 status; + s32 i; + + for (i = 0; i < PARTY_SIZE; i++) + { + species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); + hp = GetMonData(&gPlayerParty[i], MON_DATA_HP); + status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS); + + if (species == 0) + continue; + if (species != SPECIES_EGG && hp != 0 && status == 0) + r6 |= 1 << i * 2; + + if (species == 0) + continue; + if (hp != 0 && (species == SPECIES_EGG || status != 0)) + r6 |= 2 << i * 2; + + if (species == 0) + continue; + if (species != SPECIES_EGG && hp == 0) + r6 |= 3 << i * 2; + } + gBattleStruct->unk2 = r6; + gBattleStruct->unk3 = r6 >> 8; +} + +void sub_800EAAC(void) +{ + s32 i; + struct UnknownStruct8 *_ewram4 = &ewram4; + + for (i = 0; i < 7; i++) + _ewram4->unk0[i] = gSaveBlock1.enigmaBerry.berry.name[i]; + for (i = 0; i < 18; i++) + _ewram4->unk8[i] = gSaveBlock1.enigmaBerry.itemEffect[i]; + _ewram4->unk7 = gSaveBlock1.enigmaBerry.holdEffect; + _ewram4->unk1A = gSaveBlock1.enigmaBerry.holdEffectParam; +} + +void sub_800EB08(void) +{ + s32 i; + s32 j; + + if (!(gBattleTypeFlags & BATTLE_TYPE_LINK)) + { + for (i = 0; i < 7; i++) + { + gEnigmaBerries[0].name[i] = gSaveBlock1.enigmaBerry.berry.name[i]; + gEnigmaBerries[2].name[i] = gSaveBlock1.enigmaBerry.berry.name[i]; + } + for (i = 0; i < 18; i++) + { + gEnigmaBerries[0].itemEffect[i] = gSaveBlock1.enigmaBerry.itemEffect[i]; + gEnigmaBerries[2].itemEffect[i] = gSaveBlock1.enigmaBerry.itemEffect[i]; + } + gEnigmaBerries[0].holdEffect = gSaveBlock1.enigmaBerry.holdEffect; + gEnigmaBerries[2].holdEffect = gSaveBlock1.enigmaBerry.holdEffect; + gEnigmaBerries[0].holdEffectParam = gSaveBlock1.enigmaBerry.holdEffectParam; + gEnigmaBerries[2].holdEffectParam = gSaveBlock1.enigmaBerry.holdEffectParam; + } + else + { + s32 numPlayers; + struct BattleEnigmaBerry *src; + u8 r4; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + numPlayers = 4; + else + numPlayers = 2; + for (i = 0; i < numPlayers; i++) + { + src = (struct BattleEnigmaBerry *)(gBlockRecvBuffer[i] + 2); + r4 = gLinkPlayers[i].lp_field_18; + + for (j = 0; j < 7; j++) + gEnigmaBerries[r4].name[j] = src->name[j]; + for (j = 0; j < 18; j++) + gEnigmaBerries[r4].itemEffect[j] = src->itemEffect[j]; + gEnigmaBerries[r4].holdEffect = src->holdEffect; + gEnigmaBerries[r4].holdEffectParam = src->holdEffectParam; + } + } +} + +void shedinja_something(struct Pokemon *pkmn) +{ + u8 nickname[POKEMON_NAME_LENGTH + 1]; + u8 language = 1; + + if (GetMonData(pkmn, MON_DATA_SPECIES) == SPECIES_SHEDINJA + && GetMonData(pkmn, MON_DATA_LANGUAGE) != language) + { + GetMonData(pkmn, MON_DATA_NICKNAME, nickname); + if (StringCompareWithoutExtCtrlCodes(nickname, gUnknown_081F96C8) == 0) + SetMonData(pkmn, MON_DATA_LANGUAGE, &language); + } +} + +void sub_800EC9C(void) +{ + u8 playerId; + u8 enemyId; + s32 id; + + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + playerId = GetMultiplayerId(); + ewram160CB = playerId; + enemyId = playerId ^ 1; + + switch (gBattleCommunication[0]) + { + case 0: + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + if (gReceivedRemoteLinkPlayers != 0 && IsLinkTaskFinished()) + { + gBattleStruct->unk0 = 1; + gBattleStruct->unk1 = 1; + sub_800E9EC(); + sub_800EAAC(); +#if DEBUG + if (gUnknown_02023A14_50 & 8) + { + for (id = 0; id < 2; id++) // Why < 2 here? + { + gLinkPlayers[id].lp_field_18 = id; + gLinkPlayers[id].linkType = 0x2211; + } + } +#endif + SendBlock(bitmask_all_link_players_but_self(), gBattleStruct, 32); + gBattleCommunication[0] = 1; + } + } + else + { + gBattleTypeFlags |= BATTLE_TYPE_WILD; + gBattleCommunication[0] = 8; + sub_800EB08(); + } + break; + case 1: + if ((GetBlockReceivedStatus() & 3) == 3) + { + u8 taskId; + + ResetBlockReceivedFlags(); + id = 0; + if (gBlockRecvBuffer[0][0] == 0x100) + { + if (playerId == 0) + gBattleTypeFlags |= 12; + else + gBattleTypeFlags |= 8; + id++; + } + if (id == 0) + { + if (gBlockRecvBuffer[0][0] == gBlockRecvBuffer[1][0]) + { + if (playerId == 0) + gBattleTypeFlags |= 12; + else + gBattleTypeFlags |= 8; + id++; + } + if (id == 0) + { + while (id < 2) + { + if (gBlockRecvBuffer[id][0] > 0x0101 && id != playerId) + break; + id++; + } + if (id == 2) + gBattleTypeFlags |= 12; + else + gBattleTypeFlags |= 8; + } + } + sub_800EB08(); + taskId = CreateTask(sub_800DE30, 0); + gTasks[taskId].data[1] = 0x10E; + gTasks[taskId].data[2] = 0x5A; + gTasks[taskId].data[5] = 0; + gTasks[taskId].data[3] = gBattleStruct->unk2 | (gBattleStruct->unk3 << 8); + gTasks[taskId].data[4] = gBlockRecvBuffer[enemyId][1]; + gBattleCommunication[0]++; + } + break; + case 2: + if (IsLinkTaskFinished()) + { + SendBlock(bitmask_all_link_players_but_self(), gPlayerParty, sizeof(*gPlayerParty) * 2); + gBattleCommunication[0]++; + } + break; + case 3: + if ((GetBlockReceivedStatus() & 3) == 3) + { + ResetBlockReceivedFlags(); + memcpy(gEnemyParty, gBlockRecvBuffer[enemyId], sizeof(*gEnemyParty) * 2); + gBattleCommunication[0]++; + } + break; + case 4: + if (IsLinkTaskFinished()) + { + SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 2, sizeof(*gPlayerParty) * 2); + gBattleCommunication[0]++; + } + break; + case 5: + if ((GetBlockReceivedStatus() & 3) == 3) + { + ResetBlockReceivedFlags(); + memcpy(gEnemyParty + 2, gBlockRecvBuffer[enemyId], sizeof(*gEnemyParty) * 2); + gBattleCommunication[0]++; + } + break; + case 6: + if (IsLinkTaskFinished()) + { + SendBlock(bitmask_all_link_players_but_self(), gPlayerParty + 4, sizeof(*gPlayerParty) * 2); + gBattleCommunication[0]++; + } + break; + case 7: + if ((GetBlockReceivedStatus() & 3) == 3) + { + ResetBlockReceivedFlags(); + memcpy(gEnemyParty + 4, gBlockRecvBuffer[enemyId], sizeof(*gEnemyParty) * 2); + shedinja_something(&gEnemyParty[0]); + shedinja_something(&gEnemyParty[1]); + shedinja_something(&gEnemyParty[2]); + shedinja_something(&gEnemyParty[3]); + shedinja_something(&gEnemyParty[4]); + shedinja_something(&gEnemyParty[5]); + gBattleCommunication[0]++; + } + break; + case 8: + sub_800B950(); + gBattleCommunication[0]++; + gBattleCommunication[1] = 0; + gBattleCommunication[2] = 0; + break; + case 9: + if (battle_load_something(gUnknown_02024D1F, gUnknown_02024D1F + 1) != 0) + { + gPreBattleCallback1 = gMain.callback1; + gMain.callback1 = sub_8010824; + SetMainCallback2(BattleMainCB2); + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gTrainerBattleOpponent = LINK_BATTLE_OPPONENT; + gBattleTypeFlags |= BATTLE_TYPE_20; + } + } + break; + } +} + +void sub_800F02C(void) +{ + s32 i; + + for (i = 0; i < 3; i++) + { + u8 *nickname = gMultiPartnerParty[i].nickname; + + gMultiPartnerParty[i].species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES); + gMultiPartnerParty[i].heldItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); + GetMonData(&gPlayerParty[i], MON_DATA_NICKNAME, nickname); + gMultiPartnerParty[i].level = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); + gMultiPartnerParty[i].hp = GetMonData(&gPlayerParty[i], MON_DATA_HP); + gMultiPartnerParty[i].maxhp = GetMonData(&gPlayerParty[i], MON_DATA_MAX_HP); + gMultiPartnerParty[i].status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS); + gMultiPartnerParty[i].personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY); + gMultiPartnerParty[i].gender = GetMonGender(&gPlayerParty[i]); + Text_StripExtCtrlCodes(nickname); + gMultiPartnerParty[i].language = GetMonData(&gPlayerParty[i], MON_DATA_LANGUAGE); + if (gMultiPartnerParty[i].language != 1) + PadNameString(nickname, 0); + } + memcpy(gSharedMem, gMultiPartnerParty, 0x60); +} + +void sub_800F104(void) +{ + u8 playerId; + MainCallback *pSavedCallback; + u16 *pSavedBattleTypeFlags; + s32 i; + + playerId = GetMultiplayerId(); + ewram160CB = playerId; + // Seriously, Game Freak? + pSavedCallback = ewram160C4_Callback; + pSavedBattleTypeFlags = ewram160C2_Flags; + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + + switch (gBattleCommunication[0]) + { + case 0: + if (gReceivedRemoteLinkPlayers != 0) + { +#if DEBUG + if (gUnknown_02023A14_50 & 8) + { + for (i = 0; i < 4; i++) + { + gLinkPlayers[i].lp_field_18 = i; + gLinkPlayers[i].linkType = 0x2211; + } + } +#endif + if (IsLinkTaskFinished()) + { + sub_800F02C(); + SendBlock(bitmask_all_link_players_but_self(), gSharedMem, 0x60); + gBattleCommunication[0]++; + } + } + break; + case 1: + if ((GetBlockReceivedStatus() & 0xF) == 0xF) + { + //s32 i; + + ResetBlockReceivedFlags(); + for (i = 0; i < 4; i++) + { + if (i != playerId) + { + if ((!(gLinkPlayers[i].lp_field_18 & 1) && !(gLinkPlayers[playerId].lp_field_18 & 1)) + || ((gLinkPlayers[i].lp_field_18 & 1) && (gLinkPlayers[playerId].lp_field_18 & 1))) + memcpy(gMultiPartnerParty, gBlockRecvBuffer[i], 0x60); + } + } + gBattleCommunication[0]++; + *pSavedCallback = gMain.savedCallback; + *pSavedBattleTypeFlags = gBattleTypeFlags; + gMain.savedCallback = sub_800F104; + OpenPartyMenu(PARTY_MENU_TYPE_LINK_MULTI_BATTLE, 0); + } + break; + case 2: + if (!gPaletteFade.active) + { + gBattleCommunication[0] = 3; + sub_800832C(); + } + break; + case 3: + if (gReceivedRemoteLinkPlayers == 0) + { + gBattleTypeFlags = *pSavedBattleTypeFlags; + gMain.savedCallback = *pSavedCallback; + SetMainCallback2(InitBattle); + } + break; + } +} + +void sub_800F298(void) +{ + u8 playerId; + s32 id; + + playerId = GetMultiplayerId(); + ewram160CB = playerId; + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + switch (gBattleCommunication[0]) + { + case 0: + if (gReceivedRemoteLinkPlayers != 0) + { +#if DEBUG + if (gUnknown_02023A14_50 & 8) + { + for (id = 0; id < 4; id++) + { + gLinkPlayers[id].lp_field_18 = id; + gLinkPlayers[id].linkType = 0x2211; + } + } +#endif + if (IsLinkTaskFinished()) + { + gBattleStruct->unk0 = 1; + gBattleStruct->unk1 = 1; + sub_800E9EC(); + sub_800EAAC(); + SendBlock(bitmask_all_link_players_but_self(), gSharedMem, 0x20); + gBattleCommunication[0]++; + } + } + break; + case 1: + if ((GetBlockReceivedStatus() & 0xF) == 0xF) + { + u8 taskId; + + ResetBlockReceivedFlags(); + id = 0; + if (gBlockRecvBuffer[0][0] == 0x100) + { + if (playerId == 0) + gBattleTypeFlags |= 12; + else + gBattleTypeFlags |= 8; + id++; + } + if (id == 0) + { + s32 i; + + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + if (gBlockRecvBuffer[0][0] != gBlockRecvBuffer[i][0]) + break; + } + if (i == MAX_LINK_PLAYERS) + { + if (playerId == 0) + gBattleTypeFlags |= 12; + else + gBattleTypeFlags |= 8; + id++; + } + if (id == 0) + { + while (id < MAX_LINK_PLAYERS) + { + if (gBlockRecvBuffer[id][0] == 0x0101 && id != playerId) + if (id < playerId) + break; + if (gBlockRecvBuffer[id][0] > 0x0101 && id != playerId) + break; + id++; + } + if (id == MAX_LINK_PLAYERS) + gBattleTypeFlags |= 12; + else + gBattleTypeFlags |= 8; + } + } + sub_800EB08(); + memcpy(ewram1D000, gPlayerParty, sizeof(struct Pokemon) * 3); + taskId = CreateTask(sub_800DE30, 0); + gTasks[taskId].data[1] = 0x10E; + gTasks[taskId].data[2] = 0x5A; + gTasks[taskId].data[5] = 0; + gTasks[taskId].data[3] = 0; + gTasks[taskId].data[4] = 0; + for (id = 0; id < MAX_LINK_PLAYERS; id++) + { + switch (gLinkPlayers[id].lp_field_18) + { + case 0: + gTasks[taskId].data[3] |= gBlockRecvBuffer[id][1] & 0x3F; + break; + case 1: + gTasks[taskId].data[4] |= gBlockRecvBuffer[id][1] & 0x3F; + break; + case 2: + gTasks[taskId].data[3] |= (gBlockRecvBuffer[id][1] & 0x3F) << 6; + break; + case 3: + gTasks[taskId].data[4] |= (gBlockRecvBuffer[id][1] & 0x3F) << 6; + break; + } + } + ZeroPlayerPartyMons(); + ZeroEnemyPartyMons(); + gBattleCommunication[0]++; + // fallthrough + case 2: + if (IsLinkTaskFinished()) + { + SendBlock(bitmask_all_link_players_but_self(), ewram1D000, sizeof(struct Pokemon) * 2); + gBattleCommunication[0]++; + } + } + break; + case 3: + if ((GetBlockReceivedStatus() & 0xF) == 0xF) + { + ResetBlockReceivedFlags(); + for (id = 0; id < MAX_LINK_PLAYERS; id++) + { + if (id == playerId) + { + switch (gLinkPlayers[id].lp_field_18) + { + case 0: + case 3: + memcpy(gPlayerParty, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2); + break; + case 1: + case 2: + memcpy(gPlayerParty + 3, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2); + break; + } + } + else + { + if ((!(gLinkPlayers[id].lp_field_18 & 1) && !(gLinkPlayers[playerId].lp_field_18 & 1)) + || ((gLinkPlayers[id].lp_field_18 & 1) && (gLinkPlayers[playerId].lp_field_18 & 1))) + { + switch (gLinkPlayers[id].lp_field_18) + { + case 0: + case 3: + memcpy(gPlayerParty, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2); + break; + case 1: + case 2: + memcpy(gPlayerParty + 3, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2); + break; + } + } + else + { + switch (gLinkPlayers[id].lp_field_18) + { + case 0: + case 3: + memcpy(gEnemyParty, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2); + break; + case 1: + case 2: + memcpy(gEnemyParty + 3, gBlockRecvBuffer[id], sizeof(struct Pokemon) * 2); + break; + } + } + } + } + gBattleCommunication[0]++; + } + break; + case 4: + if (IsLinkTaskFinished()) + { + SendBlock(bitmask_all_link_players_but_self(), ewram1D000 + 2, sizeof(struct Pokemon)); + gBattleCommunication[0]++; + } + break; + case 5: + if ((GetBlockReceivedStatus() & 0xF) == 0xF) + { + ResetBlockReceivedFlags(); + for (id = 0; id < MAX_LINK_PLAYERS; id++) + { + if (id == playerId) + { + switch (gLinkPlayers[id].lp_field_18) + { + case 0: + case 3: + memcpy(gPlayerParty + 2, gBlockRecvBuffer[id], sizeof(struct Pokemon)); + break; + case 1: + case 2: + memcpy(gPlayerParty + 5, gBlockRecvBuffer[id], sizeof(struct Pokemon)); + break; + } + } + else + { + if ((!(gLinkPlayers[id].lp_field_18 & 1) && !(gLinkPlayers[playerId].lp_field_18 & 1)) + || ((gLinkPlayers[id].lp_field_18 & 1) && (gLinkPlayers[playerId].lp_field_18 & 1))) + { + switch (gLinkPlayers[id].lp_field_18) + { + case 0: + case 3: + memcpy(gPlayerParty + 2, gBlockRecvBuffer[id], sizeof(struct Pokemon)); + break; + case 1: + case 2: + memcpy(gPlayerParty + 5, gBlockRecvBuffer[id], sizeof(struct Pokemon)); + break; + } + } + else + { + switch (gLinkPlayers[id].lp_field_18) + { + case 0: + case 3: + memcpy(gEnemyParty + 2, gBlockRecvBuffer[id], sizeof(struct Pokemon)); + break; + case 1: + case 2: + memcpy(gEnemyParty + 5, gBlockRecvBuffer[id], sizeof(struct Pokemon)); + break; + } + } + } + } + + shedinja_something(&gPlayerParty[0]); + shedinja_something(&gPlayerParty[1]); + shedinja_something(&gPlayerParty[2]); + shedinja_something(&gPlayerParty[3]); + shedinja_something(&gPlayerParty[4]); + shedinja_something(&gPlayerParty[5]); + + shedinja_something(&gEnemyParty[0]); + shedinja_something(&gEnemyParty[1]); + shedinja_something(&gEnemyParty[2]); + shedinja_something(&gEnemyParty[3]); + shedinja_something(&gEnemyParty[4]); + shedinja_something(&gEnemyParty[5]); + + gBattleCommunication[0]++; + } + break; + case 6: + sub_800B950(); + gBattleCommunication[0]++; + gBattleCommunication[1] = 0; + gBattleCommunication[2] = 0; + break; + case 7: + if (battle_load_something(gUnknown_02024D1F, gUnknown_02024D1F + 1) != 0) + { + gPreBattleCallback1 = gMain.callback1; + gMain.callback1 = sub_8010824; + SetMainCallback2(BattleMainCB2); + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gTrainerBattleOpponent = 0x800; + gBattleTypeFlags |= BATTLE_TYPE_20; + } + } + break; + } +} + +void BattleMainCB2(void) +{ + AnimateSprites(); + BuildOamBuffer(); + +#if DEBUG + if ((gMain.heldKeys & (R_BUTTON | SELECT_BUTTON)) == ((R_BUTTON | SELECT_BUTTON))) + { + gSpecialVar_Result = gBattleOutcome = 1; + gMain.inBattle = FALSE; + gScanlineEffect.state = 3; + gMain.callback1 = gPreBattleCallback1; + ZeroEnemyPartyMons(); + m4aSongNumStop(0x5A); + if (gBattleTypeFlags & 2) + SetMainCallback2(sub_805465C); + else + SetMainCallback2(gMain.savedCallback); + } + if (gBattleTypeFlags & 2) + { + debug_sub_8008264((gBattleTypeFlags >> 2) % 2, 1, 1, 1, 1); + debug_sub_8008264((gBattleTypeFlags >> 2) % 2, 1, 21, 1, 1); + debug_sub_8008264((gBattleTypeFlags >> 2) % 2, 1, 41, 1, 1); + } +#endif + + Text_UpdateWindowInBattle(&gUnknown_03004210); + UpdatePaletteFade(); + RunTasks(); +} + +void sub_800F828(struct Sprite *sprite) +{ + sprite->data[0] = 0; + sprite->callback = sub_800F838; +} + +void sub_800F838(struct Sprite *sprite) +{ + u16 *arr = (u16 *)gSharedMem; + + switch (sprite->data[0]) + { + case 0: + sprite->data[0]++; + sprite->data[1] = 0; + sprite->data[2] = 0x281; + sprite->data[3] = 0; + sprite->data[4] = 1; + // fall through + case 1: + sprite->data[4]--; + if (sprite->data[4] == 0) + { + s32 i; + s32 r2; + s32 r0; + + sprite->data[4] = 2; + r2 = sprite->data[1] + sprite->data[3] * 32; + r0 = sprite->data[2] - sprite->data[3] * 32; + for (i = 0; i < 29; i += 2) + { + arr[r2 + i] = 0x3D; + arr[r0 + i] = 0x3D; + } + sprite->data[3]++; + if (sprite->data[3] == 21) + { + sprite->data[0]++; + sprite->data[1] = 32; + } + } + break; + case 2: + sprite->data[1]--; + if (sprite->data[1] == 20) + SetMainCallback2(sub_800E7C4); + break; + } +} + +u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum) +{ + u32 nameHash = 0; + s32 i; + + if (trainerNum == 0x400) + return 0; + + if ((gBattleTypeFlags & 0x908) == 8) + { + ZeroEnemyPartyMons(); + for (i = 0; i < gTrainers[trainerNum].partySize; i++) + { + u32 personalityValue; + s32 j; + u8 fixedIV; + + if (gTrainers[trainerNum].doubleBattle == TRUE) + personalityValue = 0x80; + else if (gTrainers[trainerNum].encounterMusic_gender & 0x80) + personalityValue = 0x78; + else + personalityValue = 0x88; + + for (j = 0; gTrainers[trainerNum].trainerName[j] != 0xFF; j++) + nameHash += gTrainers[trainerNum].trainerName[j]; + + switch (gTrainers[trainerNum].partyFlags) + { + case 0: + { + const struct TrainerMonNoItemDefaultMoves *partyData = gTrainers[trainerNum].party.NoItemDefaultMoves; + + for (j = 0; gSpeciesNames[partyData[i].species][j] != 0xFF; j++) + nameHash += gSpeciesNames[partyData[i].species][j]; + personalityValue += nameHash << 8; + fixedIV = partyData[i].iv * 31 / 255; + CreateMon(&party[i], partyData[i].species, partyData[i].level, fixedIV, TRUE, personalityValue, 2, 0); + break; + } + case F_TRAINER_PARTY_CUSTOM_MOVESET: + { + const struct TrainerMonNoItemCustomMoves *partyData = gTrainers[trainerNum].party.NoItemCustomMoves; + + for (j = 0; gSpeciesNames[partyData[i].species][j] != 0xFF; j++) + nameHash += gSpeciesNames[partyData[i].species][j]; + personalityValue += nameHash << 8; + fixedIV = partyData[i].iv * 31 / 255; + CreateMon(&party[i], partyData[i].species, partyData[i].level, fixedIV, TRUE, personalityValue, 2, 0); + + for (j = 0; j < 4; j++) + { + SetMonData(&party[i], MON_DATA_MOVE1 + j, &partyData[i].moves[j]); + SetMonData(&party[i], MON_DATA_PP1 + j, &gBattleMoves[partyData[i].moves[j]].pp); + } + break; + } + case F_TRAINER_PARTY_HELD_ITEM: + { + const struct TrainerMonItemDefaultMoves *partyData = gTrainers[trainerNum].party.ItemDefaultMoves; + + for (j = 0; gSpeciesNames[partyData[i].species][j] != 0xFF; j++) + nameHash += gSpeciesNames[partyData[i].species][j]; + personalityValue += nameHash << 8; + fixedIV = partyData[i].iv * 31 / 255; + CreateMon(&party[i], partyData[i].species, partyData[i].level, fixedIV, TRUE, personalityValue, 2, 0); + + SetMonData(&party[i], MON_DATA_HELD_ITEM, &partyData[i].heldItem); + break; + } + case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM: + { + const struct TrainerMonItemCustomMoves *partyData = gTrainers[trainerNum].party.ItemCustomMoves; + + for (j = 0; gSpeciesNames[partyData[i].species][j] != 0xFF; j++) + nameHash += gSpeciesNames[partyData[i].species][j]; + personalityValue += nameHash << 8; + fixedIV = partyData[i].iv * 31 / 255; + CreateMon(&party[i], partyData[i].species, partyData[i].level, fixedIV, TRUE, personalityValue, 2, 0); + + SetMonData(&party[i], MON_DATA_HELD_ITEM, &partyData[i].heldItem); + for (j = 0; j < 4; j++) + { + SetMonData(&party[i], MON_DATA_MOVE1 + j, &partyData[i].moves[j]); + SetMonData(&party[i], MON_DATA_PP1 + j, &gBattleMoves[partyData[i].moves[j]].pp); + } + break; + } + } + } + gBattleTypeFlags |= gTrainers[trainerNum].doubleBattle; + } + return gTrainers[trainerNum].partySize; +} + +void sub_800FCD4(void) +{ + if (REG_VCOUNT < 0xA0 && REG_VCOUNT >= 0x6F ) + REG_BG0CNT = 0x9800; +} + +void sub_800FCFC(void) +{ + Random(); // unused return value + REG_BG0HOFS = gBattle_BG0_X; + REG_BG0VOFS = gBattle_BG0_Y; + REG_BG1HOFS = gBattle_BG1_X; + REG_BG1VOFS = gBattle_BG1_Y; + REG_BG2HOFS = gBattle_BG2_X; + REG_BG2VOFS = gBattle_BG2_Y; + REG_BG3HOFS = gBattle_BG3_X; + REG_BG3VOFS = gBattle_BG3_Y; + REG_WIN0H = gBattle_WIN0H; + REG_WIN0V = gBattle_WIN0V; + REG_WIN1H = gBattle_WIN1H; + REG_WIN1V = gBattle_WIN1V; + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); + ScanlineEffect_InitHBlankDmaTransfer(); +} + +void nullsub_36(struct Sprite *sprite) +{ +} + +void sub_800FDB0(struct Sprite *sprite) +{ + if (sprite->data[0] != 0) + sprite->pos1.x = sprite->data[1] + ((sprite->data[2] & 0xFF00) >> 8); + else + sprite->pos1.x = sprite->data[1] - ((sprite->data[2] & 0xFF00) >> 8); + sprite->data[2] += 0x180; + if (sprite->affineAnimEnded) + { + FreeSpriteTilesByTag(0x2710); + FreeSpritePaletteByTag(0x2710); + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); + } +} + +void sub_800FE20(struct Sprite *sprite) +{ + StartSpriteAffineAnim(sprite, 1); + sprite->callback = sub_800FDB0; + PlaySE(SE_BT_START); +} + +void sub_800FE40(u8 taskId) +{ + struct Pokemon *sp4 = NULL; + struct Pokemon *sp8 = NULL; + u8 r2 = ewram160CB; + u32 r7; + s32 i; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + switch (gLinkPlayers[r2].lp_field_18) + { + case 0: + case 2: + sp4 = gPlayerParty; + sp8 = gEnemyParty; + break; + case 1: + case 3: + sp4 = gEnemyParty; + sp8 = gPlayerParty; + break; + } + } + else + { + sp4 = gPlayerParty; + sp8 = gEnemyParty; + } + + r7 = 0; + for (i = 0; i < 6; i++) + { + u16 species = GetMonData(&sp4[i], MON_DATA_SPECIES2); + u16 hp = GetMonData(&sp4[i], MON_DATA_HP); + u32 status = GetMonData(&sp4[i], MON_DATA_STATUS); + + if (species == 0) + continue; + if (species != SPECIES_EGG && hp != 0 && status == 0) + r7 |= 1 << i * 2; + + if (species == 0) + continue; + if (hp != 0 && (species == SPECIES_EGG || status != 0)) + r7 |= 2 << i * 2; + + if (species == 0) + continue; + if (species != SPECIES_EGG && hp == 0) + r7 |= 3 << i * 2; + } + gTasks[taskId].data[3] = r7; + + r7 = 0; + for (i = 0; i < 6; i++) + { + u16 species = GetMonData(&sp8[i], MON_DATA_SPECIES2); + u16 hp = GetMonData(&sp8[i], MON_DATA_HP); + u32 status = GetMonData(&sp8[i], MON_DATA_STATUS); + + if (species == 0) + continue; + if (species != SPECIES_EGG && hp != 0 && status == 0) + r7 |= 1 << i * 2; + + if (species == 0) + continue; + if (hp != 0 && (species == SPECIES_EGG || status != 0)) + r7 |= 2 << i * 2; + + if (species == 0) + continue; + if (species != SPECIES_EGG && hp == 0) + r7 |= 3 << i * 2; + } + gTasks[taskId].data[4] = r7; +} + +void c2_8011A1C(void) +{ + s32 i; + u8 taskId; + + SetHBlankCallback(NULL); + SetVBlankCallback(NULL); + CpuFill32(0, (void *)VRAM, VRAM_SIZE); + REG_MOSAIC = 0; + REG_WIN0H = 0xF0; + REG_WIN0V = 0x5051; + REG_WININ = 0; + REG_WINOUT = 0; + gBattle_WIN0H = 0xF0; + gBattle_WIN0V = 0x5051; + ScanlineEffect_Clear(); + + for (i = 0; i < 80; i++) + { + gScanlineEffectRegBuffers[0][i] = 0xF0; + gScanlineEffectRegBuffers[1][i] = 0xF0; + } + for (i = 80; i < 160; i++) + { + asm(""::"r"(i)); // Needed to stop the compiler from optimizing out the loop counter + gScanlineEffectRegBuffers[0][i] = 0xFF10; + gScanlineEffectRegBuffers[1][i] = 0xFF10; + } + Text_LoadWindowTemplate(&gWindowTemplate_81E6C58); + ResetPaletteFade(); + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + gBattle_BG2_X = 0; + gBattle_BG2_Y = 0; + gBattle_BG3_X = 0; + gBattle_BG3_Y = 0; + + Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58); + Text_InitWindowWithTemplate(&gUnknown_030041D0, &gWindowTemplate_81E71D0); + Text_InitWindowWithTemplate(&gUnknown_03004250, &gWindowTemplate_81E71EC); + sub_800D6D4(); + LoadCompressedPalette(gBattleTextboxPalette, 0, 64); + ApplyPlayerChosenFrameToBattleMenu(); + ResetSpriteData(); + ResetTasks(); + LoadBattleEntryBackground(); + REG_WINOUT = 0x37; + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 4; + SetVBlankCallback(sub_800FCFC); + taskId = CreateTask(sub_800DE30, 0); + gTasks[taskId].data[1] = 0x10E; + gTasks[taskId].data[2] = 0x5A; + gTasks[taskId].data[5] = 1; + sub_800FE40(taskId); + SetMainCallback2(sub_80101B8); + gBattleCommunication[0] = 0; +} + +void sub_80101B8(void) +{ + c2_081284E0(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); + RunTasks(); +} + +void c2_081284E0(void) +{ + switch (gBattleCommunication[0]) + { + case 0: + gBattleCommunication[1] = 0xFF; + gBattleCommunication[0]++; + break; + case 1: + gBattleCommunication[1]--; + if (gBattleCommunication[1] == 0) + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); + gBattleCommunication[0]++; + } + break; + case 2: + if (!gPaletteFade.active) + SetMainCallback2(gMain.savedCallback); + break; + } +} + +#if DEBUG + +extern u8 gUnknown_Debug_2023B62[]; +extern const u8 Str_821F7BD[]; +extern const u8 Str_821F7DA[]; + +void debug_sub_8010818(void); +void debug_sub_80108B8(void); +void debug_sub_8010CAC(void); +void debug_sub_8011498(void); +void debug_sub_801174C(void); +void debug_sub_8011D40(void); +void debug_sub_8011E5C(void); +void debug_sub_8011E74(void); +void debug_sub_8011EA0(u8); +void debug_sub_8012294(void); +void debug_sub_80123D8(u8); +void debug_sub_8012540(void); +void debug_nullsub_3(void); +void debug_sub_80125A0(void); +void debug_sub_80125E4(void); +void debug_sub_8012628(void); +void debug_sub_8012658(void); +void debug_sub_8012688(void); +void debug_sub_8012878(void); +void debug_sub_8012D10(u8); +u32 debug_sub_8013294(u8, void *, u32); +void debug_sub_80132C8(u8, void *, u32); + +extern s16 gUnknown_Debug_2023A76[][35]; +extern s16 gUnknown_Debug_2023B02[][6][4]; +extern u8 gUnknown_Debug_03004360; +extern struct Window gUnknown_Debug_03004370; +extern u8 gUnknown_Debug_030043A0; +extern u8 gUnknown_Debug_030043A4; +extern u8 gUnknown_Debug_030043A8; +extern u8 gBattleBuffersTransferData[]; + +extern const u16 gUnknown_Debug_821F424[][5]; +extern const u16 gUnknown_Debug_821F56C[][5]; +extern const u32 gUnknown_Debug_821F798[][4]; + +extern const u8 gUnusedOldCharmap_Gfx_lz[]; +extern const u8 gUnusedOldCharmap_Tilemap_lz[]; +extern const u8 gUnusedOldCharmap_Pal_lz[]; + +void debug_sub_8010800(void) +{ + debug_sub_8010818(); + debug_sub_80108B8(); + *(u32 *)(gBattleBuffersTransferData + 0x100) = 0; +} + +void debug_sub_8010818(void) +{ + s32 i; + + gUnknown_Debug_2023A76[0][0] = 0x115; + gUnknown_Debug_2023A76[1][0] = 0x115; + for (i = 1; i < 31; i++) + { + gUnknown_Debug_2023A76[0][i] = gUnknown_Debug_821F424[i][4]; + gUnknown_Debug_2023A76[1][i] = gUnknown_Debug_821F424[i][4]; + } + + for (i = 0; i < 6; i++) + { + for (gUnknown_Debug_030043A8 = 0; gUnknown_Debug_030043A8 < 4; gUnknown_Debug_030043A8++) + { + gUnknown_Debug_2023B02[0][i][gUnknown_Debug_030043A8] = gUnknown_Debug_821F56C[gUnknown_Debug_030043A8][0]; + gUnknown_Debug_2023B02[1][i][gUnknown_Debug_030043A8] = gUnknown_Debug_821F56C[gUnknown_Debug_030043A8][0]; + } + } +} + +void debug_sub_80108B8(void) +{ + s32 i; + + m4aSoundVSyncOff(); + SetHBlankCallback(NULL); + SetVBlankCallback(NULL); + DmaFill32(3, 0, (void *)VRAM, VRAM_SIZE); + REG_IE = 1; + REG_DISPCNT = 0x1340; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + gBattle_BG2_X = 0; + gBattle_BG2_Y = 0; + gBattle_BG3_X = 0; + gBattle_BG3_Y = 0; + REG_BG0CNT = 0x1F09; + REG_BG1CNT = 0x4801; + REG_BLDCNT = 0; + REG_BLDY = 0; + LZDecompressVram(gUnusedOldCharmap_Gfx_lz, (void *)VRAM); + LZDecompressWram(gUnusedOldCharmap_Tilemap_lz, gSharedMem); + LZDecompressVram(gUnusedOldCharmap_Pal_lz, (void *)PLTT); + LZDecompressVram(gUnusedOldCharmap_Pal_lz, (void *)(PLTT + 0x1E0)); + m4aSoundVSyncOn(); + SetVBlankCallback(debug_sub_8011D40); + SetMainCallback2(debug_sub_8010CAC); + ResetTasks(); + ResetSpriteData(); + ScanlineEffect_Stop(); + Text_LoadWindowTemplate(&gWindowTemplate_81E6C3C); + Text_InitWindowWithTemplate(&gUnknown_Debug_03004370, &gWindowTemplate_81E6C3C); + gUnknown_Debug_03004360 = 0; + gUnknown_Debug_030043A0 = 0; + gUnknown_Debug_030043A4 = 0; + for (i = 0; i < 31; i++) + debug_sub_8011EA0(i); + for (gUnknown_Debug_030043A8 = 0; gUnknown_Debug_030043A8 < 4; gUnknown_Debug_030043A8++) + debug_sub_8012294(); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + debug_sub_8012540(); + debug_nullsub_3(); + gUnknown_Debug_030043A8 = 0; + debug_sub_80125A0(); + if (gUnknown_Debug_2023A76[0][0x22] == 8) + { + debug_sub_801174C(); + } + else + { + for (i = 0; i < 8; i++) + gSharedMem[0x160B4 + i] = 0; + } +} + +void debug_sub_8010A7C(u8 a, u8 b) +{ + s32 i; + + for (i = 0; i < b; i++) + gBattleTextBuff1[i] = a; + gBattleTextBuff1[i] = EOS; +} + +void debug_sub_8010AAC(u8 a) +{ + switch (gBaseStats[gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5]].genderRatio) + { + case 0: + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + 4] = 2; + break; + case 0xFE: + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + 4] = 3; + break; + case 0xFF: + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + 4] = 4; + break; + default: + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + 4] &= 1; + if (a != 0) + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + 4] ^= 1; + else + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + 4] = 0; + break; + } +} + +// gUnknown_Debug_2023A76 2D array +void debug_sub_8010B80(u8 a) +{ + s8 r12 = 0; + s8 r7 = gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5]; + + while (r7 >= 10) + { + r7 -= 10; + r12++; + } + + if (a & 2) + { + if (a & 1) + r12++; + else + r12--; + if (r12 < 0) + r12 = 9; + if (r12 > 9) + r12 = 0; + } + else + { + if (a & 1) + r7++; + else + r7--; + if (r7 < 1) + r7 = 9; + if (r7 > 9) + r7 = 1; + } + gUnknown_Debug_2023A76[gUnknown_Debug_03004360 ^ 1][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5] + = gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5] + = r12 * 10 + r7; +} + +void debug_sub_8010CAC(void) +{ + s32 r5; + + if (gMain.heldKeysRaw == (L_BUTTON | SELECT_BUTTON)) + DoSoftReset(); + if (gMain.newKeysRaw == SELECT_BUTTON) + { + if (gUnknown_Debug_030043A4 < 6) + { + gUnknown_Debug_030043A8 = 0; + debug_sub_8012628(); + SetMainCallback2(debug_sub_8011498); + } + if (gUnknown_Debug_030043A0 == 0 && gUnknown_Debug_030043A4 == 6) + { + gMain.savedCallback = debug_sub_80108B8; + CreateMon( + &gPlayerParty[0], + gUnknown_Debug_2023A76[0][0 * 5 + 0], + gUnknown_Debug_2023A76[0][0 * 5 + 1], + 32, + 0, 0, 0, 0); + for (r5 = 0; r5 < 4; r5++) + { + SetMonData(&gPlayerParty[0], MON_DATA_MOVE1 + r5, &gUnknown_Debug_2023B02[0][0][r5]); + SetMonData(&gPlayerParty[0], MON_DATA_PP1 + r5, &gBattleMoves[gUnknown_Debug_2023B02[0][0][r5]].pp); + } + switch (gUnknown_Debug_2023A76[0][6 * 5 + 0]) + { + case 1: + gCB2_AfterEvolution = debug_sub_80108B8; + EvolutionScene(&gPlayerParty[0], gUnknown_Debug_2023A76[0][1 * 5 + 0], 1, 0); + break; + case 2: + debug_sub_8012688(); + break; + } + } + if (gUnknown_Debug_030043A0 == 1 && gUnknown_Debug_030043A4 == 6) + { + // This is really weird + r5 = (gSaveBlock2.optionsBattleSceneOff | (gSaveBlock2.optionsSound << 1)); + r5++; + if (r5 == 4) + r5 = 0; + gSaveBlock2.optionsBattleSceneOff = (r5 & 1); + gSaveBlock2.optionsSound = (r5 & 2) >> 1; + SetPokemonCryStereo(gSaveBlock2.optionsSound); + debug_nullsub_3(); + } + } + if (gMain.newKeysRaw == START_BUTTON) + debug_sub_801174C(); + if (gMain.newKeysRaw == DPAD_UP) + { + debug_sub_80125E4(); + if (gUnknown_Debug_030043A4 != 0) + gUnknown_Debug_030043A4--; + else + gUnknown_Debug_030043A4 = 6; + debug_sub_8011E74(); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + debug_sub_80125A0(); + } + if (gMain.newKeysRaw == DPAD_DOWN) + { + debug_sub_80125E4(); + if (gUnknown_Debug_030043A4 == 6) + gUnknown_Debug_030043A4 = 0; + else + gUnknown_Debug_030043A4++; + debug_sub_8011E74(); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + debug_sub_80125A0(); + } + if (gMain.newKeysRaw == DPAD_LEFT) + { + debug_sub_80125E4(); + if (gUnknown_Debug_030043A0 != 0) + { + gUnknown_Debug_030043A0--; + } + else + { + if (gUnknown_Debug_03004360 != 0) + { + gUnknown_Debug_03004360 = 0; + gUnknown_Debug_030043A0 = 4; + gBattle_BG1_X = 0; + debug_sub_8011E5C(); + debug_sub_8011E74(); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + } + } + debug_sub_80125A0(); + } + if (gMain.newKeysRaw == DPAD_RIGHT) + { + debug_sub_80125E4(); + if (gUnknown_Debug_030043A0 != 4) + { + gUnknown_Debug_030043A0++; + } + else + { + if (gUnknown_Debug_03004360 == 0) + { + gUnknown_Debug_03004360 = 1; + gUnknown_Debug_030043A0 = 0; + gBattle_BG1_X = 0x100; + debug_sub_8011E5C(); + debug_sub_8011E74(); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + } + } + debug_sub_80125A0(); + } + if (gMain.newAndRepeatedKeys & B_BUTTON) + { + switch (gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5) + { + case 31: + debug_sub_8010818(); + debug_sub_8011E5C(); + debug_sub_8011E74(); + debug_sub_8012540(); + debug_nullsub_3(); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + break; + case 32: + debug_sub_80132C8(31, gUnknown_Debug_2023A76, 0xEC); + debug_sub_8011E5C(); + debug_sub_8011E74(); + debug_sub_8012540(); + debug_nullsub_3(); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + break; + case 33: + debug_sub_8013294(31, gUnknown_Debug_2023A76, 0xEC); + break; + case 34: + if (gUnknown_Debug_2023A76[0][6 * 5 + 4] != 0) + { + gUnknown_Debug_2023A76[0][6 * 5 + 4]--; + gUnknown_Debug_2023A76[1][6 * 5 + 4]--; + } + else + { + gUnknown_Debug_2023A76[0][6 * 5 + 4] = 8; + gUnknown_Debug_2023A76[1][6 * 5 + 4] = 8; + } + debug_sub_8012540(); + break; + case 30: + debug_sub_8010B80(0); + debug_sub_8011EA0(gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5); + break; + default: + if (gUnknown_Debug_030043A0 == 4 && gUnknown_Debug_030043A4 < 6) + { + debug_sub_8010AAC(1); + } + else + { + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5]--; + if (gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5] < gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][4]) + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5] = gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][3]; + } + if (gUnknown_Debug_030043A0 == 0) + { + debug_sub_8010AAC(0); + debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + 4); + } + debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + break; + } + } + if (gMain.newAndRepeatedKeys & A_BUTTON) + { + switch (gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5) + { + case 31: + debug_sub_8010818(); + debug_sub_8011E5C(); + debug_sub_8011E74(); + debug_sub_8012540(); + debug_nullsub_3(); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + break; + case 32: + debug_sub_80132C8(31, gUnknown_Debug_2023A76, 0xEC); + debug_sub_8011E5C(); + debug_sub_8011E74(); + debug_sub_8012540(); + debug_nullsub_3(); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + break; + case 33: + debug_sub_8013294(31, gUnknown_Debug_2023A76, 0xEC); + break; + case 34: + if (gUnknown_Debug_2023A76[0][6 * 5 + 4] < 8) + { + gUnknown_Debug_2023A76[0][6 * 5 + 4]++; + gUnknown_Debug_2023A76[1][6 * 5 + 4]++; + } + else + { + gUnknown_Debug_2023A76[0][6 * 5 + 4] = 0; + gUnknown_Debug_2023A76[1][6 * 5 + 4] = 0; + } + debug_sub_8012540(); + break; + case 30: + debug_sub_8010B80(1); + debug_sub_8011EA0(gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5); + break; + default: + if (gUnknown_Debug_030043A0 == 4 && gUnknown_Debug_030043A4 < 6) + { + debug_sub_8010AAC(1); + } + else + { + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5]++; + if (gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] > gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][3]) + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] = gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][4]; + } + if (gUnknown_Debug_030043A0 == 0) + { + debug_sub_8010AAC(0); + debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + 4); + } + debug_sub_8011EA0(gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + break; + } + } + if (gMain.newAndRepeatedKeys & L_BUTTON) + { + if (gUnknown_Debug_030043A0 == 4 && gUnknown_Debug_030043A4 < 6) + { + debug_sub_8010AAC(1); + } + else + { + if (gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0 == 30) + { + debug_sub_8010B80(2); + } + else + { + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] -= 10; + while (gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] < gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][4]) + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] += gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][3]; + } + } + if (gUnknown_Debug_030043A0 == 0) + { + debug_sub_8010AAC(0); + debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + 4); + } + debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + } + if (gMain.newAndRepeatedKeys & R_BUTTON) + { + if (gUnknown_Debug_030043A0 == 4 && gUnknown_Debug_030043A4 < 6) + { + debug_sub_8010AAC(1); + } + else + { + if (gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0 == 30) + { + debug_sub_8010B80(3); + } + else + { + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] += 10; + while (gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] > gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][3]) + gUnknown_Debug_2023A76[gUnknown_Debug_03004360][gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0] -= gUnknown_Debug_821F424[gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0][3]; + } + } + if (gUnknown_Debug_030043A0 == 0) + { + debug_sub_8010AAC(0); + debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + 4); + } + debug_sub_8011EA0(gUnknown_Debug_030043A4 * 5 + gUnknown_Debug_030043A0); + debug_sub_80123D8(gUnknown_Debug_030043A4 * 5); + } + AnimateSprites(); + BuildOamBuffer(); +} + +extern u16 gUnknown_Debug_821F564[][5]; + +void debug_sub_8011498(void) +{ + u8 r9 = gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5; + + if (gMain.heldKeysRaw == (L_BUTTON | SELECT_BUTTON)) + DoSoftReset(); + if (gMain.newKeysRaw == SELECT_BUTTON) + { + debug_sub_8012658(); + SetMainCallback2(debug_sub_8010CAC); + } + if (gMain.newKeysRaw == START_BUTTON) + debug_sub_801174C(); + if (gMain.newKeysRaw == DPAD_UP || gMain.newKeysRaw == DPAD_DOWN) + { + debug_sub_8012658(); + gUnknown_Debug_030043A8 ^= 2; + debug_sub_8012628(); + } + if (gMain.newKeysRaw == DPAD_LEFT || gMain.newKeysRaw == DPAD_RIGHT) + { + debug_sub_8012658(); + gUnknown_Debug_030043A8 ^= 1; + debug_sub_8012628(); + } + if (gMain.newAndRepeatedKeys & B_BUTTON) + { + gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8]--; + if (gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] < gUnknown_Debug_821F564[gUnknown_Debug_030043A8][4]) + gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] = gUnknown_Debug_821F564[gUnknown_Debug_030043A8][3]; + debug_sub_8012294(); + } + if (gMain.newAndRepeatedKeys & A_BUTTON) + { + gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8]++; + if (gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] > gUnknown_Debug_821F564[gUnknown_Debug_030043A8][3]) + gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] = gUnknown_Debug_821F564[gUnknown_Debug_030043A8][4]; + debug_sub_8012294(); + } + if (gMain.newAndRepeatedKeys & L_BUTTON) + { + gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] -= 10; + while (gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] < gUnknown_Debug_821F564[gUnknown_Debug_030043A8][4]) + gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] += gUnknown_Debug_821F564[gUnknown_Debug_030043A8][3]; + debug_sub_8012294(); + } + if (gMain.newAndRepeatedKeys & R_BUTTON) + { + gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] += 10; + while (gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] > gUnknown_Debug_821F564[gUnknown_Debug_030043A8][3]) + gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r9 / 5][gUnknown_Debug_030043A8] -= gUnknown_Debug_821F564[gUnknown_Debug_030043A8][3]; + debug_sub_8012294(); + } + AnimateSprites(); + BuildOamBuffer(); +} + +extern const u16 gUnknown_Debug_821F598[]; +extern const u8 str_821F631[][6]; +extern const u8 Str_821F649[]; +extern const struct Pokeblock gUnknown_Debug_821F5AC[]; + +extern u8 gUnknown_020297ED; + +extern void debug_sub_800D684(void); + +void debug_sub_801174C(void) +{ + u8 r9 = 0; + u8 r6; + s32 i; + s32 spC; + u16 sp10; + + gUnknown_020297ED = 1; + r6 = Random() % 4; + StringCopy(gSaveBlock2.playerName, str_821F631[r6]); + gSaveBlock2.playerGender = r6 >> 1; + ZeroPlayerPartyMons(); + ZeroEnemyPartyMons(); + i = gUnknown_Debug_2023A76[0][30]; + spC = 0; + if (i >= 10) + { + spC = 0; + while (i >= 10) + { + i -= 10; + spC++; + } + } + gBattleTypeFlags = gUnknown_Debug_821F598[i - 1]; + gUnknown_02023A14_50 = 8; + gBattleTerrain = spC; + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + EnterSafariMode(); + if (gUnknown_Debug_2023A76[0][30] >= 2 && gUnknown_Debug_2023A76[0][30] <= 4) + gTrainerBattleOpponent = (Random() & 7) + 1; + + gPlayerPartyCount = 0; + for (i = 0; i < 30; i += 5) + { + if (gUnknown_Debug_2023A76[0][i] != 0) + { + switch (gUnknown_Debug_2023A76[0][i + 4]) + { + case 0: + case 2: + r6 = 0; + break; + case 1: + case 3: + r6 = 0xFE; + break; + default: + r6 = 0xFF; + break; + } + if (gUnknown_Debug_2023A76[0][i] == 0xC9 && i + 5 < 30) + r9 = gUnknown_Debug_2023A76[0][i + 7]; + else + r9 = 0; + CreateMonWithGenderNatureLetter( + &gEnemyParty[i / 5], + gUnknown_Debug_2023A76[0][i], + gUnknown_Debug_2023A76[0][i + 1], + 0, + r6, + 0, + r9); + } + SetMonData(&gEnemyParty[i / 5], MON_DATA_HELD_ITEM, &gUnknown_Debug_2023A76[0][i + 2]); + sp10 = gUnknown_Debug_2023A76[0][i + 2] - 1; + if (sp10 <= 11) + SetMonData(&gEnemyParty[i / 5], MON_DATA_POKEBALL, &gUnknown_Debug_2023A76[0][i + 2]); + if (gUnknown_Debug_2023A76[0][i + 3] != 0 && gUnknown_Debug_2023A76[0][i + 3] != 3) + { + if (gUnknown_Debug_2023A76[0][i + 3] <= 2) + spC = gUnknown_Debug_2023A76[0][i + 3] - 1; + else + spC = gUnknown_Debug_2023A76[0][i + 3] - 4; + SetMonData(&gEnemyParty[i / 5], MON_DATA_ALT_ABILITY, &spC); + } + + if (gUnknown_Debug_2023A76[1][i] != 0) + { + switch (gUnknown_Debug_2023A76[1][i + 4]) + { + case 0: + case 2: + r6 = 0; + break; + case 1: + case 3: + r6 = 0xFE; + break; + default: + r6 = 0xFF; + break; + } + if (gUnknown_Debug_2023A76[1][i] == 0xC9 && i + 5 < 30) + r9 = gUnknown_Debug_2023A76[1][i + 7]; + else + r9 = 0; + CreateMonWithGenderNatureLetter( + &gPlayerParty[i / 5], + gUnknown_Debug_2023A76[1][i], + gUnknown_Debug_2023A76[1][i + 1], + 0, + r6, + 0, + r9); + gPlayerPartyCount++; + } + SetMonData(&gPlayerParty[i / 5], MON_DATA_HELD_ITEM, &gUnknown_Debug_2023A76[1][i + 2]); + sp10 = gUnknown_Debug_2023A76[0][i + 2] - 1; + if (sp10 <= 11) + SetMonData(&gPlayerParty[i / 5], MON_DATA_POKEBALL, &gUnknown_Debug_2023A76[1][i + 2]); + if (gUnknown_Debug_2023A76[1][i + 3] != 0 && gUnknown_Debug_2023A76[1][i + 3] != 3) + { + if (gUnknown_Debug_2023A76[1][i + 3] <= 2) + spC = gUnknown_Debug_2023A76[1][i + 3] - 1; + else + spC = gUnknown_Debug_2023A76[1][i + 3] - 4; + SetMonData(&gPlayerParty[i / 5], MON_DATA_ALT_ABILITY, &spC); + } + if (gUnknown_Debug_2023A76[1][i + 3] > 2) + { + SetMonData(&gPlayerParty[i / 5], MON_DATA_OT_NAME, Str_821F649); + gUnknown_02023A14_50 |= 0x40; + } + } + + for (spC = 0; spC < 6; spC++) + { + for (i = 0; i < 4; i++) + { + SetMonData(&gEnemyParty[spC], MON_DATA_MOVE1 + i, &gUnknown_Debug_2023B02[0][spC][i]); + SetMonData(&gEnemyParty[spC], MON_DATA_PP1 + i, &gBattleMoves[gUnknown_Debug_2023B02[0][spC][i]].pp); + SetMonData(&gPlayerParty[spC], MON_DATA_MOVE1 + i, &gUnknown_Debug_2023B02[1][spC][i]); + SetMonData(&gPlayerParty[spC], MON_DATA_PP1 + i, &gBattleMoves[gUnknown_Debug_2023B02[1][spC][i]].pp); + } + } + + if (gUnknown_Debug_2023A76[0][0x22] == 8) + { + gUnknown_02023A14_50 |= 0x80; + sub_80408BC(); + } + else if (gUnknown_Debug_2023A76[0][0x22] == 7) + { + gUnknown_02023A14_50 |= 0x20; + sub_80408BC(); + } + else if (gUnknown_Debug_2023A76[0][0x22] == 6) + { + gUnknown_02023A14_50 |= 0x10; + if (gUnknown_Debug_2023A76[0][2] > 5) + gSharedMem[0x160A3] = gUnknown_Debug_2023A76[0][2] - 2; + else + gSharedMem[0x160A3] = gUnknown_Debug_2023A76[0][2]; + sub_80408BC(); + } + else if (gUnknown_Debug_2023A76[0][0x22] == 5) + { + gUnknown_02023A14_50 |= 0x21; + sub_80408BC(); + } + else + { + if (!(gUnknown_Debug_2023A76[0][0x22] & 1)) + sub_80408BC(); + if (gUnknown_Debug_2023A76[0][0x22] & 2) + gUnknown_02023A14_50 |= 4; + if (gUnknown_Debug_2023A76[0][0x22] & 4) + gUnknown_02023A14_50 |= 6; + } + + gMain.savedCallback = debug_sub_80108B8; + SetMainCallback2(debug_sub_800D684); + + ClearBag(); + + AddBagItem(ITEM_MASTER_BALL, 10); + AddBagItem(ITEM_ULTRA_BALL, 10); + AddBagItem(ITEM_GREAT_BALL, 10); + AddBagItem(ITEM_POKE_BALL, 10); + AddBagItem(ITEM_SAFARI_BALL, 10); + AddBagItem(ITEM_NET_BALL, 10); + AddBagItem(ITEM_DIVE_BALL, 10); + AddBagItem(ITEM_NEST_BALL, 10); + AddBagItem(ITEM_REPEAT_BALL, 10); + AddBagItem(ITEM_TIMER_BALL, 10); + AddBagItem(ITEM_LUXURY_BALL, 10); + AddBagItem(ITEM_PREMIER_BALL, 10); + + AddBagItem(ITEM_FULL_RESTORE, 99); + AddBagItem(ITEM_MAX_POTION, 99); + AddBagItem(ITEM_MAX_REVIVE, 99); + AddBagItem(ITEM_ETHER, 99); + AddBagItem(ITEM_MAX_ETHER, 99); + AddBagItem(ITEM_MAX_ELIXIR, 99); + + AddBagItem(ITEM_GUARD_SPEC, 99); + AddBagItem(ITEM_DIRE_HIT, 99); + AddBagItem(ITEM_X_ATTACK, 99); + AddBagItem(ITEM_X_DEFEND, 99); + AddBagItem(ITEM_X_SPEED, 99); + AddBagItem(ITEM_X_ACCURACY, 99); + // hmm... no X Special? Why do we need Poke Doll? + AddBagItem(ITEM_POKE_DOLL, 99); + + for (i = 0; i < 15; i++) + GivePokeblock(&gUnknown_Debug_821F5AC[i]); +} + +void debug_sub_8011D40(void) +{ + DmaCopy16(3, gSharedMem, (void *)(VRAM + 0x4000), 0x1000); + REG_BG0HOFS = gBattle_BG0_X; + REG_BG0VOFS = gBattle_BG0_Y; + REG_BG1HOFS = gBattle_BG1_X; + REG_BG1VOFS = gBattle_BG1_Y; + REG_BG2HOFS = gBattle_BG2_X; + REG_BG2VOFS = gBattle_BG2_Y; + REG_BG3HOFS = gBattle_BG3_X; + REG_BG3VOFS = gBattle_BG3_Y; + LoadOam(); + ProcessSpriteCopyRequests(); +} + +void debug_nullsub_45() +{ +} + +void debug_sub_8011DD4(void) +{ + REG_BG0CNT = 0x9803; + + REG_BG0HOFS = gBattle_BG0_X; + REG_BG0VOFS = gBattle_BG0_Y; + + REG_BG1HOFS = gBattle_BG1_X; + REG_BG1VOFS = gBattle_BG1_Y; + + REG_BG2HOFS = gBattle_BG2_X; + REG_BG2VOFS = gBattle_BG2_Y; + + REG_BG3HOFS = gBattle_BG3_X; + REG_BG3VOFS = gBattle_BG3_Y; + + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); + ScanlineEffect_InitHBlankDmaTransfer(); +} + +void debug_sub_8011E5C(void) +{ + s32 i; + + for (i = 0; i < 31; i++) + debug_sub_8011EA0(i); +} + +extern u8 gUnknown_Debug_030043A8; + +void debug_sub_8011E74(void) +{ + u8 r5 = gUnknown_Debug_030043A8; + + for (gUnknown_Debug_030043A8 = 0; gUnknown_Debug_030043A8 < 4; gUnknown_Debug_030043A8++) + debug_sub_8012294(); + + gUnknown_Debug_030043A8 = r5; +} + +extern const u8 Str_821F624[]; + +void debug_sub_8011EA0(u8 a) +{ + u32 length; + + switch (a) + { + case 0: + case 5: + case 10: + case 15: + case 20: + case 25: + debug_sub_8010A7C(0, 20); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F424[a][0], + gUnknown_Debug_821F424[a][1], + gUnknown_Debug_821F424[a][2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + ConvertIntToDecimalStringN(gBattleTextBuff1, gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a], 2, 3); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + 422, + gUnknown_Debug_03004360 * 32 + 25, + 0); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + gBattleTextBuff1[0] = EOS; + StringAppend(gBattleTextBuff1, gSpeciesNames[gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a]]); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F424[a][0], + gUnknown_Debug_821F424[a][1], + gUnknown_Debug_821F424[a][2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + break; + case 1: + case 6: + case 11: + case 16: + case 21: + case 26: + case 30: + ConvertIntToDecimalStringN(gBattleTextBuff1, gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a], 2, 3); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F424[a][0], + gUnknown_Debug_821F424[a][1], + gUnknown_Debug_821F424[a][2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + break; + case 2: + case 7: + case 12: + case 17: + case 22: + case 27: + debug_sub_8010A7C(0, 24); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F424[a][0], + gUnknown_Debug_821F424[a][1], + gUnknown_Debug_821F424[a][2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + ConvertIntToDecimalStringN(gBattleTextBuff1, gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a], 2, 3); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + 422, + gUnknown_Debug_03004360 * 32 + 25, + 0); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + gBattleTextBuff1[0] = EOS; + if (gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a] != 0) + StringAppend(gBattleTextBuff1, ItemId_GetName(gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a])); + else + StringAppend(gBattleTextBuff1, Str_821F624); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F424[a][0], + gUnknown_Debug_821F424[a][1], + gUnknown_Debug_821F424[a][2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + break; + case 4: + case 9: + case 14: + case 19: + case 24: + case 29: + debug_sub_8010A7C(0, 4); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F424[a][0], + gUnknown_Debug_821F424[a][1], + gUnknown_Debug_821F424[a][2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + length = 0; + switch (gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a]) + { + case 0: + gBattleTextBuff1[0] = CHAR_MALE; + length = 1; + break; + case 1: + gBattleTextBuff1[0] = CHAR_FEMALE; + length = 1; + break; + case 2: + gBattleTextBuff1[0] = CHAR_MALE; + gBattleTextBuff1[1] = CHAR_MALE; + length = 2; + break; + case 3: + gBattleTextBuff1[0] = CHAR_FEMALE; + gBattleTextBuff1[1] = CHAR_FEMALE; + length = 2; + break; + default: + gBattleTextBuff1[length] = CHAR_QUESTION_MARK; + length++; + break; + } + gBattleTextBuff1[length] = EOS; + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F424[a][0], + gUnknown_Debug_821F424[a][1], + gUnknown_Debug_821F424[a][2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + break; + case 3: + case 8: + case 13: + case 18: + case 23: + case 28: + default: + ConvertIntToDecimalStringN(gBattleTextBuff1, gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a], 2, 1); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F424[a][0], + gUnknown_Debug_821F424[a][1], + gUnknown_Debug_821F424[a][2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + break; + case 31: + case 32: + case 33: + case 34: + break; + } +} + +void debug_sub_8012294(void) +{ + u8 r5 = gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5; + + if (r5 < 30) + { + debug_sub_8010A7C(0, 24); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F564[gUnknown_Debug_030043A8][0], + gUnknown_Debug_821F564[gUnknown_Debug_030043A8][1], + gUnknown_Debug_821F564[gUnknown_Debug_030043A8][2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + ConvertIntToDecimalStringN(gBattleTextBuff1, gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r5 / 5][gUnknown_Debug_030043A8], 2, 3); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + 422, + gUnknown_Debug_03004360 * 32 + 25, + 0); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + gBattleTextBuff1[0] = EOS; + StringAppend(gBattleTextBuff1, gMoveNames[gUnknown_Debug_2023B02[gUnknown_Debug_03004360][r5 / 5][gUnknown_Debug_030043A8]]); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F564[gUnknown_Debug_030043A8][0], + gUnknown_Debug_821F564[gUnknown_Debug_030043A8][1], + gUnknown_Debug_821F564[gUnknown_Debug_030043A8][2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + } +} + +extern const u16 gUnknown_Debug_821F58C[]; + +void debug_sub_80123D8(u8 a) +{ + if (a < 30) + { + debug_sub_8010A7C(0, 18); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F58C[0], + gUnknown_Debug_821F58C[1], + gUnknown_Debug_821F58C[2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + StringCopy(gBattleTextBuff1, gAbilityNames[gBaseStats[gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a]].ability1]); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F58C[0], + gUnknown_Debug_821F58C[1], + gUnknown_Debug_821F58C[2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + debug_sub_8010A7C(0, 18); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F58C[3], + gUnknown_Debug_821F58C[4], + gUnknown_Debug_821F58C[5]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + StringCopy(gBattleTextBuff1, gAbilityNames[gBaseStats[gUnknown_Debug_2023A76[gUnknown_Debug_03004360][a]].ability2]); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F58C[3], + gUnknown_Debug_821F58C[4], + gUnknown_Debug_821F58C[5]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + } + else + { + StringCopy(gBattleTextBuff1, gAbilityNames[0]); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F58C[0], + gUnknown_Debug_821F58C[1], + gUnknown_Debug_821F58C[2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F58C[3], + gUnknown_Debug_821F58C[4], + gUnknown_Debug_821F58C[5]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + } +} + +void debug_sub_8012540(void) +{ + ConvertIntToDecimalStringN(gBattleTextBuff1, gUnknown_Debug_2023A76[0][0x22], 0, 1); + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + gUnknown_Debug_821F424[31][0], + gUnknown_Debug_821F424[31][1], + gUnknown_Debug_821F424[31][2]); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); +} + +void debug_nullsub_3(void) +{ +} + +extern const u32 gUnknown_Debug_821F680[][0x23]; + +void debug_sub_80125A0(void) +{ + gSharedMem[gUnknown_Debug_821F680[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5]] = 0x6D; +} + +void debug_sub_80125E4(void) +{ + gSharedMem[gUnknown_Debug_821F680[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5]] = 0x81; +} + +void debug_sub_8012628(void) +{ + gSharedMem[gUnknown_Debug_821F798[gUnknown_Debug_03004360][gUnknown_Debug_030043A8]] = 0x6D; +} + +void debug_sub_8012658(void) +{ + gSharedMem[gUnknown_Debug_821F798[gUnknown_Debug_03004360][gUnknown_Debug_030043A8]] = 0x81; +} + +void debug_sub_8012688(void) +{ + s32 i; + u8 spriteId; + u8 taskId; + + for (i = 0; i < 411; i++) + gUnknown_Debug_2023B62[i] = 0; + SetHBlankCallback(NULL); + SetVBlankCallback(NULL); + DmaFill32(3, 0, (void *)VRAM, VRAM_SIZE); + REG_MOSAIC = 0; + REG_WIN0H = 0; + REG_WIN0V = 0; + REG_WIN1H = 0; + REG_WIN1V = 0; + REG_WININ = 0; + REG_WINOUT = 0; + Text_LoadWindowTemplate(&gWindowTemplate_81E6C58); + ResetPaletteFade(); + gBattle_BG0_X = 0; + gBattle_BG0_Y = DISPLAY_HEIGHT; + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + gBattle_BG2_X = 0; + gBattle_BG2_Y = 0; + gBattle_BG3_X = 0; + gBattle_BG3_Y = 0; + gBattleTerrain = 9; + sub_800D6D4(); + LoadBattleTextboxAndBackground(); + ResetSpriteData(); + ResetTasks(); + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 4; + gCurrentMove = 1; + Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58); + DecompressPicFromTable_2( + &gMonFrontPicTable[gCurrentMove], + gMonFrontPicCoords[gCurrentMove].coords, + gMonFrontPicCoords[gCurrentMove].y_offset, + (void *)0x02000000, + gUnknown_081FAF4C[1], + gCurrentMove); + LoadCompressedPalette(gMonPaletteTable[gCurrentMove].data, 272, 32); + GetMonSpriteTemplate_803C56C(gCurrentMove, 1); + spriteId = CreateSprite(&gUnknown_02024E8C, 176, 40 + gMonFrontPicCoords[gCurrentMove].y_offset, 40); + gSprites[spriteId].callback = nullsub_37; + gSprites[spriteId].oam.paletteNum = 1; + REG_DISPCNT = 0x1F40; + SetHBlankCallback(debug_nullsub_45); + SetVBlankCallback(debug_sub_8011DD4); + m4aMPlayAllStop(); + taskId = CreateTask(debug_sub_8012D10, 0); + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[1] = spriteId; + SetMainCallback2(debug_sub_8012878); +} + +void debug_sub_8012878(void) +{ + AnimateSprites(); + BuildOamBuffer(); + Text_UpdateWindowInBattle(&gUnknown_03004210); + UpdatePaletteFade(); + RunTasks(); + if (gMain.heldKeys == (SELECT_BUTTON | R_BUTTON)) + SetMainCallback2(debug_sub_80108B8); +} + +void debug_sub_80128B4(void) +{ + debug_sub_8010A7C(0, 9); + Text_InitWindow(&gUnknown_03004210, gBattleTextBuff1, 144, 2, 35); + Text_PrintWindow8002F44(&gUnknown_03004210); + ConvertIntToDecimalStringN(gBattleTextBuff1, gCurrentMove, 2, 3); + gBattleTextBuff1[3] = CHAR_SPACE; + gBattleTextBuff1[4] = EOS; + StringAppend(gBattleTextBuff1, gSpeciesNames[gCurrentMove]); + Text_InitWindow(&gUnknown_03004210, gBattleTextBuff1, 144, 2, 35); + Text_PrintWindow8002F44(&gUnknown_03004210); +} + +void debug_sub_8012938(u8 taskId) +{ + debug_sub_8010A7C(0, 7); + Text_InitWindow(&gUnknown_03004210, gBattleTextBuff1, 162, 2, 37); + Text_PrintWindow8002F44(&gUnknown_03004210); + StringCopy(gBattleTextBuff1, Str_821F7B8); + ConvertIntToDecimalStringN(gBattleTextBuff1 + 4, gUnknown_Debug_2023B62[gCurrentMove - 1], 2, 3); + Text_InitWindow(&gUnknown_03004210, gBattleTextBuff1, 162, 2, 37); + Text_PrintWindow8002F44(&gUnknown_03004210); + gSprites[gTasks[taskId].data[1]].pos2.y = -gUnknown_Debug_2023B62[gCurrentMove - 1]; +} + +void debug_sub_80129F8(u8 taskId) +{ + DecompressPicFromTable_2( + &gMonFrontPicTable[gCurrentMove], + gMonFrontPicCoords[gCurrentMove].coords, + gMonFrontPicCoords[gCurrentMove].y_offset, + (void *)0x02000000, + gUnknown_081FAF4C[1], + gCurrentMove); + LoadCompressedPalette(gMonPaletteTable[gCurrentMove].data, 272, 32); + gSprites[gTasks[taskId].data[1]].pos1.y = gMonFrontPicCoords[gCurrentMove].y_offset + 40; + gSprites[gTasks[taskId].data[1]].pos2.y = -gUnknown_Debug_2023B62[gCurrentMove - 1]; + StartSpriteAnim(&gSprites[gTasks[taskId].data[1]], 0); +} + +void debug_sub_8012AC0(s8 a, u8 taskId) +{ + do + { + gCurrentMove += a; + if (gCurrentMove == 0) + gCurrentMove = 411; + if (gCurrentMove == 411) + gCurrentMove = 1; + } while (gBaseStats[gCurrentMove].type1 != 2 && gBaseStats[gCurrentMove].type2 != 2); + debug_sub_80128B4(); + debug_sub_8012938(taskId); + debug_sub_80129F8(taskId); +} + +void debug_sub_8012B2C(u8 a) +{ + *(u16 *)(VRAM + 0xC000 + 0x772 + (a * 4 + 0) * 0x20) = 1; + *(u16 *)(VRAM + 0xC000 + 0x772 + (a * 4 + 2) * 0x20) = 2; +} + +void debug_sub_8012B4C(u8 a) +{ + *(u16 *)(VRAM + 0xC000 + 0x772 + (a * 4 + 0) * 0x20) = 0x1016; + *(u16 *)(VRAM + 0xC000 + 0x772 + (a * 4 + 2) * 0x20) = 0x1016; +} + +void debug_sub_8012B70(u8 taskId, u8 b) +{ + if (b != 0) + { + sub_802BBD4(24, 28, 29, 33, 1); + debug_sub_80128B4(); + debug_sub_8012938(taskId); + debug_sub_80129F8(taskId); + gTasks[taskId].data[0] = 1; + } + else + { + sub_802BBD4(24, 28, 29, 33, 0); + gTasks[taskId].data[0] = 2; + Text_InitWindow(&gUnknown_03004210, Str_821F7DA, 656, 26, 29); + Text_PrintWindow8002F44(&gUnknown_03004210); + gTasks[taskId].data[3] = 0; + debug_sub_8012B2C(0); + } +} + +void debug_sub_8012C08(u8 taskId, u8 b) +{ + debug_sub_8010A7C(0, 9); + Text_InitWindow(&gUnknown_03004210, gBattleTextBuff1, 144, 2, 35); + Text_PrintWindow8002F44(&gUnknown_03004210); + debug_sub_8010A7C(0, 7); + Text_InitWindow(&gUnknown_03004210, gBattleTextBuff1, 162, 2, 37); + Text_PrintWindow8002F44(&gUnknown_03004210); + sub_802BBD4(24, 28, 29, 33, 0); + if (b != 0) + { + gTasks[taskId].data[0] = 4; + Text_InitWindow(&gUnknown_03004210, gUnknown_Debug_821F7F3, 144, 2, 35); + } + else + { + gTasks[taskId].data[0] = 3; + Text_InitWindow(&gUnknown_03004210, Str_821F7EA, 144, 2, 35); + } + Text_PrintWindow8002F44(&gUnknown_03004210); + Text_InitWindow(&gUnknown_03004210, BattleText_YesNo, 656, 26, 29); + Text_PrintWindow8002F44(&gUnknown_03004210); + gTasks[taskId].data[3] = 1; + debug_sub_8012B2C(1); +} + +void debug_sub_8012D10(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + case 0: + debug_sub_80128B4(); + debug_sub_8012938(taskId); + Text_InitWindow(&gUnknown_03004210, Str_821F7BD, 400, 19, 35); + Text_PrintWindow8002F44(&gUnknown_03004210); + gTasks[taskId].data[0]++; + sub_802E3E4(gTasks[taskId].data[2], 0); + break; + case 1: + if (gMain.newKeys & DPAD_UP) + { + PlaySE(SE_SELECT); + nullsub_8(gTasks[taskId].data[2]); + gTasks[taskId].data[2] &= ~2; + sub_802E3E4(gTasks[taskId].data[2], 0); + } + else if (gMain.newKeys & DPAD_DOWN) + { + PlaySE(SE_SELECT); + nullsub_8(gTasks[taskId].data[2]); + gTasks[taskId].data[2] |= 2; + sub_802E3E4(gTasks[taskId].data[2], 0); + } + else if (gMain.newKeys & DPAD_LEFT) + { + PlaySE(SE_SELECT); + nullsub_8(gTasks[taskId].data[2]); + gTasks[taskId].data[2] &= ~1; + sub_802E3E4(gTasks[taskId].data[2], 0); + } + else if (gMain.newKeys & DPAD_RIGHT) + { + PlaySE(SE_SELECT); + nullsub_8(gTasks[taskId].data[2]); + gTasks[taskId].data[2] |= 1; + sub_802E3E4(gTasks[taskId].data[2], 0); + } + else if (gMain.newAndRepeatedKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + switch (gTasks[taskId].data[2]) + { + case 0: + if (gUnknown_Debug_2023B62[gCurrentMove - 1] < 64) + { + gUnknown_Debug_2023B62[gCurrentMove - 1] += 1; + debug_sub_8012938(taskId); + } + break; + case 1: + debug_sub_8012AC0(1, taskId); + break; + case 2: + if (gCurrentMove < 411) + gCurrentMove++; + else + gCurrentMove = 1; + debug_sub_80128B4(); + debug_sub_8012938(taskId); + debug_sub_80129F8(taskId); + break; + case 3: + debug_sub_8012B70(taskId, 0); + break; + } + } + else if (gMain.newAndRepeatedKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + switch (gTasks[taskId].data[2]) + { + case 0: + if (gUnknown_Debug_2023B62[gCurrentMove - 1] > 0) + { + gUnknown_Debug_2023B62[gCurrentMove - 1] -= 1; + debug_sub_8012938(taskId); + } + break; + case 1: + debug_sub_8012AC0(-1, taskId); + break; + case 2: + if (gCurrentMove > 1) + gCurrentMove--; + else + gCurrentMove = 411; + debug_sub_80128B4(); + debug_sub_8012938(taskId); + debug_sub_80129F8(taskId); + break; + case 3: + debug_sub_8012B70(taskId, 0); + break; + } + } + else if (gMain.newAndRepeatedKeys & R_BUTTON) + { + PlaySE(SE_SELECT); + switch (gTasks[taskId].data[2]) + { + case 0: + if (gUnknown_Debug_2023B62[gCurrentMove - 1] < 64) + { + gUnknown_Debug_2023B62[gCurrentMove - 1] += 8; + if (gUnknown_Debug_2023B62[gCurrentMove - 1] > 64) + gUnknown_Debug_2023B62[gCurrentMove - 1] = 64; + debug_sub_8012938(taskId); + } + break; + case 1: + debug_sub_8012AC0(1, taskId); + break; + case 2: + if (gCurrentMove + 10 < 412) + gCurrentMove += 10; + else + gCurrentMove -= 400; + debug_sub_80128B4(); + debug_sub_8012938(taskId); + debug_sub_80129F8(taskId); + break; + case 3: + debug_sub_8012B70(taskId, 0); + break; + } + } + else if (gMain.newAndRepeatedKeys & L_BUTTON) + { + PlaySE(SE_SELECT); + switch (gTasks[taskId].data[2]) + { + case 0: + if (gUnknown_Debug_2023B62[gCurrentMove - 1] > 0) + { + if (gUnknown_Debug_2023B62[gCurrentMove - 1] > 8) + gUnknown_Debug_2023B62[gCurrentMove - 1] -= 8; + else + gUnknown_Debug_2023B62[gCurrentMove - 1] = 0; + debug_sub_8012938(taskId); + } + break; + case 1: + debug_sub_8012AC0(-1, taskId); + break; + case 2: + if (gCurrentMove - 10 > 1) + gCurrentMove -= 10; + else + gCurrentMove += 400; + debug_sub_80128B4(); + debug_sub_8012938(taskId); + debug_sub_80129F8(taskId); + break; + case 3: + debug_sub_8012B70(taskId, 0); + break; + } + } + break; + case 2: + if (gMain.newKeys & DPAD_UP) + { + PlaySE(SE_SELECT); + debug_sub_8012B4C(gTasks[taskId].data[3]); + gTasks[taskId].data[3] = 0; + debug_sub_8012B2C(0); + } + else if (gMain.newKeys & DPAD_DOWN) + { + PlaySE(SE_SELECT); + debug_sub_8012B4C(gTasks[taskId].data[3]); + gTasks[taskId].data[3] = 1; + debug_sub_8012B2C(1); + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + debug_sub_8012C08(taskId, gTasks[taskId].data[3]); + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + asm(""); + debug_sub_8012B70(taskId, 1); + } + return; + case 3: + if (gMain.newKeys & DPAD_UP) + { + PlaySE(SE_SELECT); + debug_sub_8012B4C(gTasks[taskId].data[3]); + gTasks[taskId].data[3] = 0; + debug_sub_8012B2C(0); + } + else if (gMain.newKeys & DPAD_DOWN) + { + PlaySE(SE_SELECT); + debug_sub_8012B4C(gTasks[taskId].data[3]); + gTasks[taskId].data[3] = 1; + debug_sub_8012B2C(1); + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + if (gTasks[taskId].data[3] == 0) + debug_sub_80132C8(31, gUnknown_Debug_2023B62, 411); + debug_sub_8012B70(taskId, 1); + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + debug_sub_8012B70(taskId, 1); + } + break; + case 4: + if (gMain.newKeys & DPAD_UP) + { + PlaySE(SE_SELECT); + debug_sub_8012B4C(gTasks[taskId].data[3]); + gTasks[taskId].data[3] = 0; + debug_sub_8012B2C(0); + } + else if (gMain.newKeys & DPAD_DOWN) + { + PlaySE(SE_SELECT); + debug_sub_8012B4C(gTasks[taskId].data[3]); + gTasks[taskId].data[3] = 1; + debug_sub_8012B2C(1); + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + if (gTasks[taskId].data[3] == 0) + debug_sub_8013294(31, gUnknown_Debug_2023B62, 411); + debug_sub_8012B70(taskId, 1); + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + debug_sub_8012B70(taskId, 1); + } + break; + } +} + +u8 debug_sub_8013240(void) +{ + if (IdentifyFlash() == 0) + return 0; + else + return 1; +} + +u32 debug_sub_8013258(u16 sectorNum, u8 *data, u32 size) +{ + while (1) + { + if (ProgramFlashSectorAndVerify(sectorNum, data) != 0) + return 0; + if (size <= 0x1000) + break; + size -= 0x1000; + data += 0x1000; + sectorNum++; + } + return 1; +} + +u32 debug_sub_8013294(u8 sectorNum, void *data, u32 size) +{ + u32 result; + + if (debug_sub_8013240() != 0) + return 0; + m4aSoundVSyncOff(); + result = debug_sub_8013258(sectorNum, data, size); + m4aSoundVSyncOn(); + return result; +} + +void debug_sub_80132C8(u8 a, void *b, u32 c) +{ + if (debug_sub_8013240() == 0) + ReadFlash(a, 0, b, c); +} +#endif + +void oac_poke_opponent(struct Sprite *sprite) +{ + sprite->callback = sub_8010278; + StartSpriteAnimIfDifferent(sprite, 0); + BeginNormalPaletteFade(0x00020000, 0, 10, 10, RGB(15, 15, 15)); +} + +void sub_8010278(struct Sprite *sprite) +{ + if ((gUnknown_02024DE8 & 1) == 0) + { + sprite->pos2.x += 2; + if (sprite->pos2.x == 0) + { + sprite->callback = sub_80102AC; + PlayCry1(sprite->data[2], 25); + } + } +} + +void sub_80102AC(struct Sprite *sprite) +{ + if (sprite->animEnded) + { + sub_804777C(sprite->data[0]); + sub_8043DFC(gHealthboxIDs[sprite->data[0]]); + sprite->callback = nullsub_37; + StartSpriteAnimIfDifferent(sprite, 0); + BeginNormalPaletteFade(0x00020000, 0, 10, 0, RGB(15, 15, 15)); + } +} + +void nullsub_37(struct Sprite *sprite) +{ +} + +void unref_sub_801030C(struct Sprite *sprite) +{ + sprite->data[3] = 6; + sprite->data[4] = 1; + sprite->callback = sub_8010320; +} + +void sub_8010320(struct Sprite *sprite) +{ + sprite->data[4]--; + if (sprite->data[4] == 0) + { + sprite->data[4] = 8; + sprite->invisible ^= 1; + sprite->data[3]--; + if (sprite->data[3] == 0) + { + sprite->invisible = FALSE; + sprite->callback = nullsub_37; + gUnknown_03004284 = 0; + } + } +} + +void sub_8010384(struct Sprite *sprite) +{ + u8 r6 = sprite->data[0]; + u16 species; + u8 yOffset; + + if (ewram17800[r6].transformedSpecies != 0) + species = ewram17800[r6].transformedSpecies; + else + species = sprite->data[2]; + + GetMonData(&gEnemyParty[gBattlerPartyIndexes[r6]], MON_DATA_PERSONALITY); // Unused return value + + if (species == SPECIES_UNOWN) + { + u32 personalityValue = GetMonData(&gEnemyParty[gBattlerPartyIndexes[r6]], MON_DATA_PERSONALITY); + u16 unownForm = ((((personalityValue & 0x3000000) >> 18) | ((personalityValue & 0x30000) >> 12) | ((personalityValue & 0x300) >> 6) | (personalityValue & 3)) % 0x1C); + u16 unownSpecies; + + if (unownForm == 0) + unownSpecies = SPECIES_UNOWN; // Use the A Unown form + else + unownSpecies = NUM_SPECIES + unownForm; // Use one of the other Unown letters + + yOffset = gMonFrontPicCoords[unownSpecies].y_offset; + } + else if (species == SPECIES_CASTFORM) + { + yOffset = gCastformFrontSpriteCoords[gBattleMonForms[r6]].y_offset; + } + else if (species > NUM_SPECIES) + { + yOffset = gMonFrontPicCoords[SPECIES_NONE].y_offset; + } + else + { + yOffset = gMonFrontPicCoords[species].y_offset; + } + + sprite->data[3] = 8 - yOffset / 8; + sprite->data[4] = 1; + sprite->callback = sub_8010494; +} + +void sub_8010494(struct Sprite *sprite) +{ + s32 i; + u8 *dst; + + sprite->data[4]--; + if (sprite->data[4] == 0) + { + sprite->data[4] = 2; + sprite->pos2.y += 8; + sprite->data[3]--; + if (sprite->data[3] < 0) + { + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); + } + else + { + // this should use a MEMSET_ALT, but *(dst++) wont match with it. + dst = (u8 *)gUnknown_081FAF4C[GetBattlerPosition(sprite->data[0])] + (gBattleMonForms[sprite->data[0]] << 11) + (sprite->data[3] << 8); + for (i = 0; i < 0x100; i++) + *(dst++) = 0; + StartSpriteAnim(sprite, gBattleMonForms[sprite->data[0]]); + } + } +} + +void sub_8010520(struct Sprite *sprite) +{ + sprite->data[3] = 8; + sprite->data[4] = sprite->invisible; + sprite->callback = sub_801053C; +} + +void sub_801053C(struct Sprite *sprite) +{ + sprite->data[3]--; + if (sprite->data[3] == 0) + { + sprite->invisible ^= 1; + sprite->data[3] = 8; + } +} + +void sub_8010574(struct Sprite *sprite) +{ + sprite->invisible = sprite->data[4]; + sprite->data[4] = FALSE; + sprite->callback = nullsub_37; +} + +void sub_80105A0(struct Sprite *sprite) +{ + sprite->callback = oac_poke_ally_; +} + +void oac_poke_ally_(struct Sprite *sprite) +{ + if ((gUnknown_02024DE8 & 1) == 0) + { + sprite->pos2.x -= 2; + if (sprite->pos2.x == 0) + { + sprite->callback = nullsub_86; + sprite->data[1] = 0; + } + } +} + +void sub_80105DC(struct Sprite *sprite) +{ + sprite->callback = nullsub_86; +} + +void nullsub_86(struct Sprite *sprite) +{ +} + +void sub_80105EC(struct Sprite *sprite) +{ + if ((gUnknown_02024DE8 & 1) == 0) + { + sprite->pos2.x += sprite->data[1]; + sprite->pos2.y += sprite->data[2]; + } +} + +void dp11b_obj_instanciate(u8 bank, u8 b, s8 c, s8 d) +{ + u8 spriteId; + u8 objectID; + + if (b) + { + if (ewram17810[bank].unk0_1) + return; + } + else + { + if (ewram17810[bank].unk0_2) + return; + } + + spriteId = CreateInvisibleSpriteWithCallback(objc_dp11b_pingpong); + if (b == TRUE) + { + objectID = gHealthboxIDs[bank]; + ewram17810[bank].unk2 = spriteId; + ewram17810[bank].unk0_1 = 1; + gSprites[spriteId].data[0] = 0x80; + } + else + { + objectID = gBankSpriteIds[bank]; + ewram17810[bank].unk3 = spriteId; + ewram17810[bank].unk0_2 = 1; + gSprites[spriteId].data[0] = 0xC0; + } + gSprites[spriteId].data[1] = c; + gSprites[spriteId].data[2] = d; + gSprites[spriteId].data[3] = objectID; + gSprites[spriteId].data[4] = b; + gSprites[objectID].pos2.x = 0; + gSprites[objectID].pos2.y = 0; +} + +void dp11b_obj_free(u8 a, u8 b) +{ + u8 r4; + + if (b == TRUE) + { + if (!ewram17810[a].unk0_1) + return; + r4 = gSprites[ewram17810[a].unk2].data[3]; + DestroySprite(&gSprites[ewram17810[a].unk2]); + ewram17810[a].unk0_1 = 0; + } + else + { + if (!ewram17810[a].unk0_2) + return; + r4 = gSprites[ewram17810[a].unk3].data[3]; + DestroySprite(&gSprites[ewram17810[a].unk3]); + ewram17810[a].unk0_2 = 0; + } + gSprites[r4].pos2.x = 0; + gSprites[r4].pos2.y = 0; +} + +void objc_dp11b_pingpong(struct Sprite *sprite) +{ + u8 spriteId = sprite->data[3]; + s32 var; + + if (sprite->data[4] == 1) + var = sprite->data[0]; + else + var = sprite->data[0]; + + gSprites[spriteId].pos2.y = Sin(var, sprite->data[2]) + sprite->data[2]; + sprite->data[0] = (sprite->data[0] + sprite->data[1]) & 0xFF; +} + +void nullsub_41(void) +{ +} + +void sub_8010800(void) +{ + sub_8010874(); + gBattleCommunication[1] = 0; + gBattleMainFunc = bc_8012FAC; +} + +#if DEBUG +void debug_sub_80138CC(void) +{ + if (GetBattlerSide(gActiveBattler) == 0) + { + switch (gSharedMem[0x160FD]) + { + case 0: + if (gBattleBankFunc[gActiveBattler] == sub_802C098) + gSharedMem[0x160FD]++; + break; + case 1: + gMain.heldKeys = A_BUTTON; + gMain.newKeys = A_BUTTON; + gSharedMem[0x160FD]++; + gSharedMem[0x160FE] = 0x80; + break; + case 2: + gSharedMem[0x160FE]--; + if (gSharedMem[0x160FE] == 0) + { + gMain.heldKeys = A_BUTTON; + gMain.newKeys = A_BUTTON; + gSharedMem[0x160FD]++; + gSharedMem[0x160FE] = 0x80; + } + break; + case 3: + gSharedMem[0x160FE]--; + if (gSharedMem[0x160FE] == 0) + { + gMain.heldKeys = A_BUTTON; + gMain.newKeys = A_BUTTON; + gSharedMem[0x160FD]++; + } + break; + case 4: + gSharedMem[0x160FD] = 0; + break; + } + } +} +#endif + +void sub_8010824(void) +{ +#if DEBUG + if (gUnknown_02023A14_50 & 0x80) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + debug_sub_80138CC(); + gBattleMainFunc(); + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + gBattleBankFunc[gActiveBattler](); + } + else +#endif + { + gBattleMainFunc(); + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + gBattleBankFunc[gActiveBattler](); + } +} + +void sub_8010874(void) +{ + s32 i; + u32 j; + u8 *r4; + + TurnValuesCleanUp(0); + SpecialStatusesClear(); + + for (i = 0; i < 4; i++) + { + gStatuses3[i] = 0; + + MEMSET_ALT(&gDisableStructs[i], 0, 0x1C, j, r4); + gDisableStructs[i].isFirstTurn= 2; + gUnknown_02024C70[i] = 0; + gLastUsedMove[i] = 0; + gLastLandedMoves[i] = 0; + gLastHitByType[i] = 0; + gUnknown_02024C4C[i] = 0; + gLastHitBy[i] = 0xFF; + gLockedMoves[i] = 0; + gUnknown_02024C2C[i] = 0; + eFlashFireArr.arr[i] = 0; + } + + for (i = 0; i < 2; i++) + { + gSideAffecting[i] = 0; + MEMSET_ALT(&gSideTimers[i], 0, 12, j, r4); + } + + gBankAttacker = 0; + gBankTarget = 0; + gBattleWeather = 0; + + MEMSET_ALT(&gWishFutureKnock, 0, 0x2C, i, r4); + + gHitMarker = 0; + if ((gBattleTypeFlags & BATTLE_TYPE_LINK) == 0 && gSaveBlock2.optionsBattleSceneOff == TRUE) + gHitMarker = HITMARKER_NO_ANIMATIONS; + ewram16084 = gSaveBlock2.optionsBattleStyle; + gMultiHitCounter = 0; + gBattleOutcome = 0; + gBattleExecBuffer = 0; + gPaydayMoney = 0; + ewram17130 = 0; + ewram17160 = 0; + for (i = 0; i < 8; i++) + gBattleCommunication[i] = 0; + gPauseCounterBattle = 0; + gBattleMoveDamage = 0; + gUnknown_02024DE8 = 0; + ewram16002 = 0; + ewram160A1 = 0; + gLeveledUpInBattle = 0; + gAbsentBattlerFlags = 0; + ewram16078 = 0; + ewram16086 = 0; + ewram16087 = 0; + ewram16089 = gBaseStats[GetMonData(&gEnemyParty[0], MON_DATA_SPECIES)].catchRate * 100 / 1275; + ewram16088 = 3; + ewram1601B = 0; + ewram16056 = 1; + + for (i = 0; i < 8; i++) + { + ewram160ACarr(i) = 0; + ewram160CCarr(i) = 0; + ewram160E8arr(i) = 0; + ewram160F0arr(i) = 0; + ewram16100arr(i) = 0; + ewram16108arr(i) = 0; + } + + ewram160C8 = 6; + ewram160C9 = 6; + ewram16113 = 0; + for (i = 0; i < 11; i++) + gBattleResults.usedBalls[i] = 0; + gBattleResults.battleTurnCounter = 0; + gBattleResults.playerFaintCounter = 0; + gBattleResults.opponentFaintCounter = 0; + gBattleResults.unk2 = 0; + gBattleResults.unk3 = 0; + gBattleResults.unk4 = 0; + gBattleResults.unk5_0 = 0; + gBattleResults.unk5_1 = 0; + gBattleResults.lastOpponentSpecies = 0; + gBattleResults.lastUsedMove = 0; + gBattleResults.opponentMove = 0; + gBattleResults.poke1Species = 0; + gBattleResults.opponentSpecies = 0; + gBattleResults.caughtPoke = 0; + for (i = 0; i < 10; i++) + { + gBattleResults.pokeString1[i] = 0; + gBattleResults.pokeString2[i] = 0; + gBattleResults.caughtNick[i] = 0; + } +#if DEBUG + gSharedMem[0x1609E] = 0; + gSharedMem[0x1609F] = 0; +#endif +} + +void SwitchInClearSetData(void) +{ + struct DisableStruct sp0 = gDisableStructs[gActiveBattler]; + s32 i; + u8 *ptr; + + if (gBattleMoves[gCurrentMove].effect != EFFECT_BATON_PASS) + { + for (i = 0; i < 8; i++) + gBattleMons[gActiveBattler].statStages[i] = 6; + for (i = 0; i < gBattlersCount; i++) + { + if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].bankPreventingEscape == gActiveBattler) + gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION; + if ((gStatuses3[i] & STATUS3_ALWAYS_HITS) && gDisableStructs[i].bankWithSureHit == gActiveBattler) + { + gStatuses3[i] &= ~STATUS3_ALWAYS_HITS; + gDisableStructs[i].bankWithSureHit = 0; + } + } + } + if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS) + { + gBattleMons[gActiveBattler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED); + gStatuses3[gActiveBattler] &= (STATUS3_LEECHSEED_BANK | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED | STATUS3_MUDSPORT | STATUS3_WATERSPORT); + + for (i = 0; i < gBattlersCount; i++) + { + if (GetBattlerSide(gActiveBattler) != GetBattlerSide(i) + && (gStatuses3[i] & STATUS3_ALWAYS_HITS) != 0 + && (gDisableStructs[i].bankWithSureHit == gActiveBattler)) + { + gStatuses3[i] &= ~STATUS3_ALWAYS_HITS; + gStatuses3[i] |= 0x10; + } + } + } + else + { + gBattleMons[gActiveBattler].status2 = 0; + gStatuses3[gActiveBattler] = 0; + } + + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].status2 & (gBitTable[gActiveBattler] << 16)) + gBattleMons[i].status2 &= ~(gBitTable[gActiveBattler] << 16); + if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && ewram16020arr(i) == gActiveBattler) + gBattleMons[i].status2 &= ~STATUS2_WRAPPED; + } + + gActionSelectionCursor[gActiveBattler] = 0; + gMoveSelectionCursor[gActiveBattler] = 0; + + MEMSET_ALT(&gDisableStructs[gActiveBattler], 0, 0x1C, i, ptr); + + if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS) + { + gDisableStructs[gActiveBattler].substituteHP = sp0.substituteHP; + gDisableStructs[gActiveBattler].bankWithSureHit = sp0.bankWithSureHit; + gDisableStructs[gActiveBattler].perishSongTimer1 = sp0.perishSongTimer1; + gDisableStructs[gActiveBattler].perishSongTimer2 = sp0.perishSongTimer2; + } + + gDisableStructs[gActiveBattler].isFirstTurn= 2; + gLastUsedMove[gActiveBattler] = 0; + gLastLandedMoves[gActiveBattler] = 0; + gLastHitByType[gActiveBattler] = 0; + gUnknown_02024C4C[gActiveBattler] = 0; + gUnknown_02024C2C[gActiveBattler] = 0; + gLastHitBy[gActiveBattler] = 0xFF; + + ewram160ACarr2(0, gActiveBattler) = 0; + ewram160ACarr2(1, gActiveBattler) = 0; + ewram16100arr2(0, gActiveBattler) = 0; + ewram16100arr2(1, gActiveBattler) = 0; + ewram16100arr2(2, gActiveBattler) = 0; + ewram16100arr2(3, gActiveBattler) = 0; + ewram160E8arr2(0, gActiveBattler) = 0; + ewram160E8arr2(1, gActiveBattler) = 0; + + eFlashFireArr.arr[gActiveBattler] = 0; + + gCurrentMove = 0; +} + +void UndoEffectsAfterFainting(void) +{ + s32 i; + u8 *ptr; + + for (i = 0; i < 8; i++) + gBattleMons[gActiveBattler].statStages[i] = 6; + gBattleMons[gActiveBattler].status2 = 0; + gStatuses3[gActiveBattler] = 0; + for (i = 0; i < gBattlersCount; i++) + { + if ((gBattleMons[i].status2 & STATUS2_ESCAPE_PREVENTION) && gDisableStructs[i].bankPreventingEscape == gActiveBattler) + gBattleMons[i].status2 &= ~STATUS2_ESCAPE_PREVENTION; + if (gBattleMons[i].status2 & (gBitTable[gActiveBattler] << 16)) + gBattleMons[i].status2 &= ~(gBitTable[gActiveBattler] << 16); + if ((gBattleMons[i].status2 & STATUS2_WRAPPED) && ewram16020arr(i) == gActiveBattler) + gBattleMons[i].status2 &= ~STATUS2_WRAPPED; + } + gActionSelectionCursor[gActiveBattler] = 0; + gMoveSelectionCursor[gActiveBattler] = 0; + + MEMSET_ALT(&gDisableStructs[gActiveBattler], 0, 0x1C, i, ptr); + gProtectStructs[gActiveBattler].protected = 0; + gProtectStructs[gActiveBattler].endured = 0; + gProtectStructs[gActiveBattler].onlyStruggle = 0; + gProtectStructs[gActiveBattler].helpingHand = 0; + gProtectStructs[gActiveBattler].bounceMove = 0; + gProtectStructs[gActiveBattler].stealMove = 0; + gProtectStructs[gActiveBattler].flag0Unknown = 0; + gProtectStructs[gActiveBattler].prlzImmobility = 0; + gProtectStructs[gActiveBattler].confusionSelfDmg = 0; + gProtectStructs[gActiveBattler].notEffective = 0; + gProtectStructs[gActiveBattler].chargingTurn = 0; + gProtectStructs[gActiveBattler].fleeFlag = 0; + gProtectStructs[gActiveBattler].usedImprisionedMove = 0; + gProtectStructs[gActiveBattler].loveImmobility = 0; + gProtectStructs[gActiveBattler].usedDisabledMove = 0; + gProtectStructs[gActiveBattler].usedTauntedMove = 0; + gProtectStructs[gActiveBattler].flag2Unknown = 0; + gProtectStructs[gActiveBattler].flinchImmobility = 0; + gProtectStructs[gActiveBattler].notFirstStrike = 0; + + gDisableStructs[gActiveBattler].isFirstTurn= 2; + gLastUsedMove[gActiveBattler] = 0; + gLastLandedMoves[gActiveBattler] = 0; + gLastHitByType[gActiveBattler] = 0; + gUnknown_02024C4C[gActiveBattler] = 0; + gUnknown_02024C2C[gActiveBattler] = 0; + gLastHitBy[gActiveBattler] = 0xFF; + + ewram160E8arr2(0, gActiveBattler) = 0; + ewram160E8arr2(1, gActiveBattler) = 0; + ewram160ACarr2(0, gActiveBattler) = 0; + ewram160ACarr2(1, gActiveBattler) = 0; + ewram16100arr2(0, gActiveBattler) = 0; + ewram16100arr2(1, gActiveBattler) = 0; + ewram16100arr2(2, gActiveBattler) = 0; + ewram16100arr2(3, gActiveBattler) = 0; + + eFlashFireArr.arr[gActiveBattler] = 0; + + gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1; + gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2; +} + +void bc_8012FAC(void) +{ + switch (gBattleCommunication[0]) + { + case 0: + gActiveBattler = gBattleCommunication[1]; + EmitGetAttributes(0, 0, 0); + MarkBufferBankForExecution(gActiveBattler); + gBattleCommunication[0]++; + break; + case 1: + if (gBattleExecBuffer == 0) + { + gBattleCommunication[1]++; + if (gBattleCommunication[1] == gBattlersCount) + gBattleMainFunc = BattlePrepIntroSlide; + else + gBattleCommunication[0] = 0; + } + break; + } +} + +static void BattlePrepIntroSlide(void) +{ + if (gBattleExecBuffer == 0) + { + gActiveBattler = GetBattlerAtPosition(0); + EmitIntroSlide(0, gBattleTerrain); + MarkBufferBankForExecution(gActiveBattler); + gBattleMainFunc = sub_8011384; + gBattleCommunication[0] = 0; + gBattleCommunication[1] = 0; + } +} + +void sub_8011384(void) +{ + u8 *ptr; + s32 i; + + if (gBattleExecBuffer == 0) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if ((gBattleTypeFlags & BATTLE_TYPE_SAFARI) + && GetBattlerSide(gActiveBattler) == 0) + { + MEMSET_ALT(&gBattleMons[gActiveBattler], 0, 0x58, i, ptr); + } + else + { + u8 r0; + + MEMSET_ALT(&gBattleMons[gActiveBattler], gBattleBufferB[gActiveBattler][4 + i], 0x58, i, ptr); + gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1; + gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2; + gBattleMons[gActiveBattler].ability = GetAbilityBySpecies(gBattleMons[gActiveBattler].species, gBattleMons[gActiveBattler].altAbility); + r0 = GetBattlerSide(gActiveBattler); + ewram160BC[r0] = gBattleMons[gActiveBattler].hp; + for (i = 0; i < 8; i++) + gBattleMons[gActiveBattler].statStages[i] = 6; + gBattleMons[gActiveBattler].status2 = 0; + } + + if (GetBattlerPosition(gActiveBattler) == 0) + { + EmitTrainerThrow(0); + MarkBufferBankForExecution(gActiveBattler); + } + + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + { + if (GetBattlerPosition(gActiveBattler) == 1) + { + EmitTrainerThrow(0); + MarkBufferBankForExecution(gActiveBattler); + } + if (GetBattlerSide(gActiveBattler) == 1 + && !(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK))) + GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBattler].species), 2); + } + else + { + if (GetBattlerSide(gActiveBattler) == 1 + && !(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK))) + { + GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBattler].species), 2); + EmitLoadPokeSprite(0); + MarkBufferBankForExecution(gActiveBattler); + } + } + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (GetBattlerPosition(gActiveBattler) == 2 + || GetBattlerPosition(gActiveBattler) == 3) + { + EmitTrainerThrow(0); + MarkBufferBankForExecution(gActiveBattler); + } + } + } + gBattleMainFunc = bc_801333C; + } +} + +void bc_801333C(void) +{ + s32 i; + + if (gBattleExecBuffer == 0) + { + struct HpAndStatus hpStatus[6]; + + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + { + for (i = 0; i < 6; i++) + { + if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == 0 + || GetMonData(&gEnemyParty[i], MON_DATA_SPECIES2) == SPECIES_EGG) + { + hpStatus[i].hp = 0xFFFF; + hpStatus[i].status = 0; + } + else + { + hpStatus[i].hp = GetMonData(&gEnemyParty[i], MON_DATA_HP); + hpStatus[i].status = GetMonData(&gEnemyParty[i], MON_DATA_STATUS); + } + } + gActiveBattler = GetBattlerAtPosition(1); + EmitDrawPartyStatusSummary(0, hpStatus, 0x80); + MarkBufferBankForExecution(gActiveBattler); + + for (i = 0; i < 6; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) == 0 + || GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) == SPECIES_EGG) + { + hpStatus[i].hp = 0xFFFF; + hpStatus[i].status = 0; + } + else + { + hpStatus[i].hp = GetMonData(&gPlayerParty[i], MON_DATA_HP); + hpStatus[i].status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS); + } + } + gActiveBattler = GetBattlerAtPosition(0); + EmitDrawPartyStatusSummary(0, hpStatus, 0x80); + MarkBufferBankForExecution(gActiveBattler); + + gBattleMainFunc = bc_battle_begin_message; + } + else + { + // The array gets set here, but nothing is ever done with it. + // Likely unfinished code. + + for (i = 0; i < 6; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) == 0 + || GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) == SPECIES_EGG) + { + hpStatus[i].hp = 0xFFFF; + hpStatus[i].status = 0; + } + else + { + hpStatus[i].hp = GetMonData(&gPlayerParty[i], MON_DATA_HP); + hpStatus[i].status = GetMonData(&gPlayerParty[i], MON_DATA_STATUS); + } + } + + gBattleMainFunc = bc_8013568; + } + } +} + +void bc_battle_begin_message(void) +{ + if (gBattleExecBuffer == 0) + { + gActiveBattler = GetBattlerAtPosition(1); + PrepareStringBattle(0, gActiveBattler); + gBattleMainFunc = sub_8011800; + } +} + +void bc_8013568(void) +{ + if (gBattleExecBuffer == 0) + { + gBattleMainFunc = sub_8011970; + PrepareStringBattle(0, 0); + } +} + +void sub_8011800(void) +{ + if (gBattleExecBuffer == 0) + { + PrepareStringBattle(1, GetBattlerAtPosition(1)); + gBattleMainFunc = sub_8011834; + } +} + +void sub_8011834(void) +{ + if (gBattleExecBuffer == 0) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (GetBattlerPosition(gActiveBattler) == 1) + { + EmitTrainerBallThrow(0); + MarkBufferBankForExecution(gActiveBattler); + } + if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) + && GetBattlerPosition(gActiveBattler) == 3) + { + EmitTrainerBallThrow(0); + MarkBufferBankForExecution(gActiveBattler); + } + } + gBattleMainFunc = bc_801362C; + } +} + +void bc_801362C(void) +{ + if (gBattleExecBuffer == 0) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (GetBattlerSide(gActiveBattler) == 1 + && !(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK))) + GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBattler].species), 2); + } + gBattleMainFunc = sub_8011970; + } +} + +void unref_sub_8011950(void) +{ + if (gBattleExecBuffer == 0) + gBattleMainFunc = sub_8011970; +} + +void sub_8011970(void) +{ + if (gBattleExecBuffer == 0) + { + if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) + PrepareStringBattle(1, GetBattlerAtPosition(0)); + gBattleMainFunc = sub_80119B4; + } +} + +void sub_80119B4(void) +{ + if (gBattleExecBuffer == 0) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (GetBattlerPosition(gActiveBattler) == 0) + { + EmitTrainerBallThrow(0); + MarkBufferBankForExecution(gActiveBattler); + } + if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) + && GetBattlerPosition(gActiveBattler) == 2) + { + EmitTrainerBallThrow(0); + MarkBufferBankForExecution(gActiveBattler); + } + } + ewram16058 = 0; + ewram160F9 = 0; + ewram160E6 = 0; + gBattleMainFunc = BattleBeginFirstTurn; + } +} + +void unref_sub_8011A68(void) +{ + if (gBattleExecBuffer == 0) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (GetBattlerSide(gActiveBattler) == 0) + { + EmitSendOutPoke(0, gBattlerPartyIndexes[gActiveBattler], 0); + MarkBufferBankForExecution(gActiveBattler); + } + } + ewram16058 = 0; + ewram160F9 = 0; + ewram160E6 = 0; + gBattleMainFunc = BattleBeginFirstTurn; + } +} + +void BattleBeginFirstTurn(void) +{ + s32 i; + s32 j; + u8 r9 = 0; + + if (gBattleExecBuffer == 0) + { + if (ewram16058 == 0) + { + for (i = 0; i < gBattlersCount; i++) + gBanksByTurnOrder[i] = i; + for (i = 0; i < gBattlersCount - 1; i++) + { + for (j = i + 1; j < gBattlersCount; j++) + { + if (GetWhoStrikesFirst(gBanksByTurnOrder[i], gBanksByTurnOrder[j], 1) != 0) + SwapTurnOrder(i, j); + } + } + } + if (ewram160E6 == 0 && AbilityBattleEffects(0, 0, 0, 0xFF, 0) != 0) + { + ewram160E6 = 1; + return; + } + while (ewram16058 < gBattlersCount) + { + if (AbilityBattleEffects(0, gBanksByTurnOrder[ewram16058], 0, 0, 0) != 0) + r9++; + ewram16058++; + if (r9 != 0) + return; + } + if (AbilityBattleEffects(9, 0, 0, 0, 0) != 0) + return; + if (AbilityBattleEffects(11, 0, 0, 0, 0) != 0) + return; + while (ewram160F9 < gBattlersCount) + { + if (ItemBattleEffects(0, gBanksByTurnOrder[ewram160F9], 0) != 0) + r9++; + ewram160F9++; + if (r9 != 0) + return; + } + // Absolutely pointless for-loop that somehow doesn't get optimized out + for (i = 0; i < gBattlersCount; i++) + ; + for (i = 0; i < 4; i++) + { + ewram16068arr(i) = 6; + gActionForBanks[i] = 0xFF; + gChosenMovesByBanks[i] = 0; + } + TurnValuesCleanUp(0); + SpecialStatusesClear(); + ewram160A6 = gAbsentBattlerFlags; + gBattleMainFunc = sub_8012324; + ResetSentPokesToOpponentValue(); + for (i = 0; i < 8; i++) + gBattleCommunication[i] = 0; + for (i = 0; i < gBattlersCount; i++) + gBattleMons[i].status2 &= ~8; + ewram16000 = 0; + ewram16001 = 0; + ewram16110 = 0; + ewram16111 = 0; + ewram1600C = 0; + ewram16059 = 0; + ewram1600E = 0; + gMoveResultFlags = 0; + gRandomTurnNumber = Random(); + } +} + +void bc_8013B1C(void) +{ + s32 i; + + if (gBattleExecBuffer == 0) + { + gBattleMainFunc = BattleTurnPassed; + for (i = 0; i < 8; i++) + gBattleCommunication[i] = 0; + for (i = 0; i < gBattlersCount; i++) + { + gBattleMons[i].status2 &= ~8; + if ((gBattleMons[i].status1 & 7) && (gBattleMons[i].status2 & 0x1000)) + CancelMultiTurnMoves(i); + } + ewram16000 = 0; + ewram16001 = 0; + ewram16110 = 0; + ewram16111 = 0; + ewram1600E = 0; + gMoveResultFlags = 0; + } +} + +void BattleTurnPassed(void) +{ + s32 i; + + TurnValuesCleanUp(1); + if (gBattleOutcome == 0) + { + if (UpdateTurnCounters() != 0) + return; + if (TurnBasedEffects() != 0) + return; + } + if (HandleFaintedMonActions() != 0) + return; + ewram16059 = 0; + if (HandleWishPerishSongOnTurnEnd() != 0) + return; + TurnValuesCleanUp(0); + gHitMarker &= ~HITMARKER_NO_ATTACKSTRING; + gHitMarker &= ~0x80000; + gHitMarker &= ~0x400000; + gHitMarker &= ~0x100000; + ewram16002 = 0; + ewram160A1 = 0; + ewram1600C = 0; + gBattleMoveDamage = 0; + gMoveResultFlags = 0; + for (i = 0; i < 5; i++) + gBattleCommunication[i] = 0; + if (gBattleOutcome != 0) + { + gCurrentActionFuncId = 12; + gBattleMainFunc = RunTurnActionsFunctions; + return; + } + if (gBattleResults.battleTurnCounter < 0xFF) + gBattleResults.battleTurnCounter++; + for (i = 0; i < gBattlersCount; i++) + { + gActionForBanks[i] = 0xFF; + gChosenMovesByBanks[i] = 0; + } + for (i = 0; i < 4; i++) + ewram16068arr(i) = 6; + ewram160A6 = gAbsentBattlerFlags; + gBattleMainFunc = sub_8012324; + gRandomTurnNumber = Random(); +} + +u8 CanRunFromBattle(void) +{ + u8 r2; + u8 r6; + s32 i; + + if (gBattleMons[gActiveBattler].item == ITEM_ENIGMA_BERRY) + r2 = gEnigmaBerries[gActiveBattler].holdEffect; + else + r2 = ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item); + gStringBank = gActiveBattler; + if (r2 == HOLD_EFFECT_CAN_ALWAYS_RUN) + return 0; + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + return 0; + if (gBattleMons[gActiveBattler].ability == ABILITY_RUN_AWAY) + return 0; + r6 = GetBattlerSide(gActiveBattler); + for (i = 0; i < gBattlersCount; i++) + { + if (r6 != GetBattlerSide(i) + && gBattleMons[i].ability == ABILITY_SHADOW_TAG) + { + ewram16003 = i; + gLastUsedAbility = gBattleMons[i].ability; + gBattleCommunication[5] = 2; + return 2; + } + if (r6 != GetBattlerSide(i) + && gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE + && gBattleMons[gActiveBattler].type1 != 2 + && gBattleMons[gActiveBattler].type2 != 2 + && gBattleMons[i].ability == ABILITY_ARENA_TRAP) + { + ewram16003 = i; + gLastUsedAbility = gBattleMons[i].ability; + gBattleCommunication[5] = 2; + return 2; + } + } + i = AbilityBattleEffects(15, gActiveBattler, ABILITY_MAGNET_PULL, 0, 0); + if (i != 0 && (gBattleMons[gActiveBattler].type1 == 8 || gBattleMons[gActiveBattler].type2 == 8)) + { + ewram16003 = i - 1; + gLastUsedAbility = gBattleMons[i - 1].ability; + gBattleCommunication[5] = 2; + return 2; + } + if ((gBattleMons[gActiveBattler].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED)) || (gStatuses3[gActiveBattler] & STATUS3_ROOTED)) + { + gBattleCommunication[5] = 0; + return 1; + } + if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) + { + gBattleCommunication[5] = 1; + return 1; + } + return 0; +} + +void sub_8012258(u8 a) +{ + s32 i; + u8 r4; + u8 r1; + + for (i = 0; i < 3; i++) + gUnknown_02038470[i] = ewram1606Carr(i, a); + r4 = pokemon_order_func(gBattlerPartyIndexes[a]); + r1 = pokemon_order_func(ewram16068arr(a)); + sub_8094C98(r4, r1); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + for (i = 0; i < 3; i++) + { + ewram1606Carr(i, a) = gUnknown_02038470[i]; + ewram1606Carr(i, (a ^ 2)) = gUnknown_02038470[i]; + } + } + else + { + for (i = 0; i < 3; i++) + { + ewram1606Carr(i, a) = gUnknown_02038470[i]; + } + } +} + +enum +{ + STATE_BEFORE_ACTION_CHOSEN, + STATE_WAIT_ACTION_CHOSEN, + STATE_WAIT_ACTION_CASE_CHOSEN, + STATE_WAIT_ACTION_CONFIRMED_STANDBY, + STATE_WAIT_ACTION_CONFIRMED, + STATE_SELECTION_SCRIPT, + STATE_WAIT_SET_BEFORE_ACTION, + STATE_SELECTION_SCRIPT_MAY_RUN +}; + +extern u8 * gSelectionBattleScripts[]; +extern u8 BattleScript_ActionSelectionItemsCantBeUsed[]; +extern u8 BattleScript_PrintFullBox[]; +extern u8 BattleScript_PrintCantRunFromTrainer[]; +extern u8 BattleScript_PrintCantEscapeFromBattle[]; + +void sub_8012324(void) +{ + u8 position; + s32 i; + + gBattleCommunication[4] = 0; + // inverted loop + //_0801234C + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + position = GetBattlerPosition(gActiveBattler); + switch (gBattleCommunication[gActiveBattler]) + { + case STATE_BEFORE_ACTION_CHOSEN: + ewram16068arr(gActiveBattler) = 6; + if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) + && (position & BIT_FLANK) != B_FLANK_LEFT + && !(ewram160A6 & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(position))]) + && gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(position))] != STATE_WAIT_ACTION_CONFIRMED) + break; + //_080123F8 + if (ewram160A6 & gBitTable[gActiveBattler]) + { + gActionForBanks[gActiveBattler] = 13; + if (!(gBattleTypeFlags & 0x40)) + gBattleCommunication[gActiveBattler] = 4; + //_08012454 + else + gBattleCommunication[gActiveBattler] = 3; + break; + } + //_08012468 + if ((gBattleMons[gActiveBattler].status2 & 0x1000) + || (gBattleMons[gActiveBattler].status2 & 0x400000)) + { + gActionForBanks[gActiveBattler] = 0; + gBattleCommunication[gActiveBattler] = 3; + } + else + { + Emitcmd18(0, gActionForBanks[0], gBattleBufferB[0][1] | (gBattleBufferB[0][2] << 8)); + MarkBufferBankForExecution(gActiveBattler); + gBattleCommunication[gActiveBattler]++; + } + break; + case STATE_WAIT_ACTION_CHOSEN: + if (!(gBattleExecBuffer & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) + { + gActionForBanks[gActiveBattler] = gBattleBufferB[gActiveBattler][1]; + switch (gBattleBufferB[gActiveBattler][1]) + { + case B_ACTION_USE_MOVE: + if (AreAllMovesUnusable()) + { + gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT; + ewram16060(gActiveBattler) = FALSE; + ewram16094arr(gActiveBattler) = STATE_WAIT_ACTION_CONFIRMED_STANDBY; + ewram16010arr(gActiveBattler) = gBattleBufferB[gActiveBattler][3]; + return; + } + else if (gDisableStructs[gActiveBattler].encoredMove != 0) + { + gChosenMovesByBanks[gActiveBattler] = gDisableStructs[gActiveBattler].encoredMove; + gBattleCommunication[gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY; + return; + } + else + { + struct ChooseMoveStruct { + u16 moves[4]; + u8 currentPp[4]; + u8 maxPp[4]; + u16 species; + u8 monType1; + u8 monType2; + } moveInfo; + + moveInfo.species = gBattleMons[gActiveBattler].species; + moveInfo.monType1 = gBattleMons[gActiveBattler].type1; + moveInfo.monType2 = gBattleMons[gActiveBattler].type2; + + for (i = 0; i < 4; i++) + { + moveInfo.moves[i] = gBattleMons[gActiveBattler].moves[i]; + moveInfo.currentPp[i] = gBattleMons[gActiveBattler].pp[i]; + moveInfo.maxPp[i] = CalculatePPWithBonus( + gBattleMons[gActiveBattler].moves[i], + gBattleMons[gActiveBattler].ppBonuses, + i); + } + + Emitcmd20(0, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0, FALSE, (u8 *)&moveInfo); + MarkBufferBankForExecution(gActiveBattler); + } + break; + case B_ACTION_USE_ITEM: + if (gBattleTypeFlags & (BATTLE_TYPE_LINK + | BATTLE_TYPE_BATTLE_TOWER + | BATTLE_TYPE_EREADER_TRAINER)) + { + gSelectionBattleScripts[gActiveBattler] = BattleScript_ActionSelectionItemsCantBeUsed; + gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT; + ewram16060(gActiveBattler) = FALSE; + ewram16094arr(gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN; + return; + } + else + { + EmitOpenBag(0, &ewram1606Carr(0, gActiveBattler)); + MarkBufferBankForExecution(gActiveBattler); + } + break; + case B_ACTION_SWITCH: + ewram16064arr(gActiveBattler) = gBattlerPartyIndexes[gActiveBattler]; + if (gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION) + || gStatuses3[gActiveBattler] & STATUS3_ROOTED) + { + EmitChoosePokemon(0, 2, 6, ABILITY_NONE, &ewram1606Carr(0, gActiveBattler)); + } + else if ((i = ABILITY_ON_OPPOSING_FIELD(gActiveBattler, ABILITY_SHADOW_TAG)) + || ((i = ABILITY_ON_OPPOSING_FIELD(gActiveBattler, ABILITY_ARENA_TRAP)) + && !IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_FLYING) + && gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE) + || ((i = AbilityBattleEffects(ABILITYEFFECT_CHECK_FIELD_EXCEPT_BATTLER, gActiveBattler, ABILITY_MAGNET_PULL, 0, 0)) + && IS_BATTLER_OF_TYPE(gActiveBattler, TYPE_STEEL))) + { + EmitChoosePokemon(0, ((i - 1) << 4) | PARTY_ABILITY_PREVENTS, 6, gLastUsedAbility, &ewram1606Carr(0, gActiveBattler)); + } + else + { + if (gActiveBattler == 2 && gActionForBanks[0] == B_ACTION_SWITCH) + EmitChoosePokemon(0, PARTY_CHOOSE_MON, ewram16068arr(0), ABILITY_NONE, &ewram1606Carr(0, gActiveBattler)); + else if (gActiveBattler == 3 && gActionForBanks[1] == B_ACTION_SWITCH) + EmitChoosePokemon(0, PARTY_CHOOSE_MON, ewram16068arr(1), ABILITY_NONE, &ewram1606Carr(0, gActiveBattler)); + else + EmitChoosePokemon(0, PARTY_CHOOSE_MON, 6, ABILITY_NONE, &ewram1606Carr(0, gActiveBattler)); + } + MarkBufferBankForExecution(gActiveBattler); + break; + case B_ACTION_SAFARI_BALL: + if (PlayerPartyAndPokemonStorageFull()) + { + gSelectionBattleScripts[gActiveBattler] = BattleScript_PrintFullBox; + gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT; + ewram16060(gActiveBattler) = FALSE; + ewram16094arr(gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN; + return; + } + break; + case B_ACTION_SAFARI_POKEBLOCK: + EmitOpenBag(0, &ewram1606Carr(0, gActiveBattler)); + MarkBufferBankForExecution(gActiveBattler); + break; + case B_ACTION_CANCEL_PARTNER: + gBattleCommunication[gActiveBattler] = STATE_WAIT_SET_BEFORE_ACTION; + gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] = STATE_BEFORE_ACTION_CHOSEN; + Emitcmd50(0); + MarkBufferBankForExecution(gActiveBattler); + return; + } + + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER + && !(gBattleTypeFlags & (BATTLE_TYPE_LINK)) + && gBattleBufferB[gActiveBattler][1] == B_ACTION_RUN) + { + BattleScriptExecute(BattleScript_PrintCantRunFromTrainer); + gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; + } + else if (CanRunFromBattle() + && gBattleBufferB[gActiveBattler][1] == B_ACTION_RUN) + { + gSelectionBattleScripts[gActiveBattler] = BattleScript_PrintCantEscapeFromBattle; + gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT; + ewram16060(gActiveBattler) = FALSE; + ewram16094arr(gActiveBattler) = STATE_BEFORE_ACTION_CHOSEN; + return; + } + else + { + gBattleCommunication[gActiveBattler]++; + } + } + break; + case STATE_WAIT_ACTION_CASE_CHOSEN: + if (!(gBattleExecBuffer & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) + { + switch (gActionForBanks[gActiveBattler]) + { + case B_ACTION_USE_MOVE: + switch (gBattleBufferB[gActiveBattler][1]) + { + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + gActionForBanks[gActiveBattler] = gBattleBufferB[gActiveBattler][1]; + return; + default: + if ((gBattleBufferB[gActiveBattler][2] | (gBattleBufferB[gActiveBattler][3] << 8)) == 0xFFFF) + { + gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; + } + else if (TrySetCantSelectMoveBattleScript()) + { + gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT; + ewram16060(gActiveBattler) = FALSE; + gBattleBufferB[gActiveBattler][1] = 0; + ewram16094arr(gActiveBattler) = STATE_WAIT_ACTION_CHOSEN; + return; + } + else + { + ewram1608Carr(gActiveBattler) = gBattleBufferB[gActiveBattler][2]; + gChosenMovesByBanks[gActiveBattler] = gBattleMons[gActiveBattler].moves[ewram1608Carr(gActiveBattler)]; + ewram16010arr(gActiveBattler) = gBattleBufferB[gActiveBattler][3]; + gBattleCommunication[gActiveBattler]++; + } + break; + } + break; + case B_ACTION_USE_ITEM: + if ((gBattleBufferB[gActiveBattler][1] | (gBattleBufferB[gActiveBattler][2] << 8)) == 0) + { + gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; + } + else + { + gLastUsedItem = (gBattleBufferB[gActiveBattler][1] | (gBattleBufferB[gActiveBattler][2] << 8)); + gBattleCommunication[gActiveBattler]++; + } + break; + case B_ACTION_SWITCH: + if (gBattleBufferB[gActiveBattler][1] == PARTY_SIZE) + { + gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; + } + else + { + ewram16068arr(gActiveBattler) = gBattleBufferB[gActiveBattler][1]; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + ewram1606Carr(0, gActiveBattler) &= 0xF; + ewram1606Carr(0, gActiveBattler) |= (gBattleBufferB[gActiveBattler][2] & 0xF0); + ewram1606Carr(1, gActiveBattler) = gBattleBufferB[gActiveBattler][3]; + + ewram1606Carr(0, (gActiveBattler ^ BIT_FLANK)) &= (0xF0); + ewram1606Carr(0, (gActiveBattler ^ BIT_FLANK)) |= (gBattleBufferB[gActiveBattler][2] & 0xF0) >> 4; + ewram1606Carr(2, (gActiveBattler ^ BIT_FLANK)) = gBattleBufferB[gActiveBattler][3]; + } + gBattleCommunication[gActiveBattler]++; + } + break; + case B_ACTION_RUN: + gHitMarker |= HITMARKER_RUN; + gBattleCommunication[gActiveBattler]++; + break; + case B_ACTION_SAFARI_WATCH_CAREFULLY: + gBattleCommunication[gActiveBattler]++; + break; + case B_ACTION_SAFARI_BALL: + gBattleCommunication[gActiveBattler]++; + break; + case B_ACTION_SAFARI_POKEBLOCK: + if ((gBattleBufferB[gActiveBattler][1] | (gBattleBufferB[gActiveBattler][2] << 8)) != 0) + { + gBattleCommunication[gActiveBattler]++; + } + else + { + gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; + } + break; + case B_ACTION_SAFARI_GO_NEAR: + gBattleCommunication[gActiveBattler]++; + break; + case B_ACTION_SAFARI_RUN: + gHitMarker |= HITMARKER_RUN; + gBattleCommunication[gActiveBattler]++; + break; + case B_ACTION_WALLY_THROW: + gBattleCommunication[gActiveBattler]++; + break; + } + } + break; + case STATE_WAIT_ACTION_CONFIRMED_STANDBY: + if (!(gBattleExecBuffer & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) + { + if (((gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_DOUBLE)) != BATTLE_TYPE_DOUBLE) + || (position & BIT_FLANK) != B_FLANK_LEFT + || (ewram160A6 & gBitTable[GetBattlerAtPosition(position ^ BIT_FLANK)])) + { + EmitLinkStandbyMsg(0, 0); + } + else + { + EmitLinkStandbyMsg(0, 1); + } + MarkBufferBankForExecution(gActiveBattler); + gBattleCommunication[gActiveBattler]++; + } + break; + case STATE_WAIT_ACTION_CONFIRMED: + if (!(gBattleExecBuffer & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) + { + gBattleCommunication[ACTIONS_CONFIRMED_COUNT]++; + } + break; + case STATE_SELECTION_SCRIPT: + if (ewram16060(gActiveBattler)) + { + gBattleCommunication[gActiveBattler] = ewram16094arr(gActiveBattler); + } + else + { + gBankAttacker = gActiveBattler; + gBattlescriptCurrInstr = gSelectionBattleScripts[gActiveBattler]; + if (!(gBattleExecBuffer & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) + { + gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); + } + gSelectionBattleScripts[gActiveBattler] = gBattlescriptCurrInstr; + } + break; + case STATE_WAIT_SET_BEFORE_ACTION: + if (!(gBattleExecBuffer & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) + { + gBattleCommunication[gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; + } + break; + } + } + + // Check if everyone chose actions. + if (gBattleCommunication[ACTIONS_CONFIRMED_COUNT] == gBattlersCount) + { + gBattleMainFunc = SetActionsAndBanksTurnOrder; + } +} + +void SwapTurnOrder(u8 a, u8 b) +{ + int temp; + + temp = gActionsByTurnOrder[a]; + gActionsByTurnOrder[a] = gActionsByTurnOrder[b]; + gActionsByTurnOrder[b] = temp; + + temp = gBanksByTurnOrder[a]; + gBanksByTurnOrder[a] = gBanksByTurnOrder[b]; + gBanksByTurnOrder[b] = temp; +} + +// Determines which of the two given mons will strike first in a battle. +// Returns: +// 0 = first mon moves first +// 1 = second mon moves first +// 2 = second mon moves first because it won a 50/50 roll +u8 GetWhoStrikesFirst(u8 bank1, u8 bank2, bool8 ignoreMovePriorities) +{ + int bank1SpeedMultiplier, bank2SpeedMultiplier; + u32 bank1AdjustedSpeed, bank2AdjustedSpeed; + u8 heldItemEffect; + u8 heldItemEffectParam; + u16 bank1Move; + u16 bank2Move; + u8 strikesFirst = 0; + + // Check for abilities that boost speed in weather. + if (WEATHER_HAS_EFFECT) + { + if ((gBattleMons[bank1].ability == ABILITY_SWIFT_SWIM && (gBattleWeather & WEATHER_RAIN_ANY)) + || (gBattleMons[bank1].ability == ABILITY_CHLOROPHYLL && (gBattleWeather & WEATHER_SUN_ANY))) + bank1SpeedMultiplier = 2; + else + bank1SpeedMultiplier = 1; + + if ((gBattleMons[bank2].ability == ABILITY_SWIFT_SWIM && (gBattleWeather & WEATHER_RAIN_ANY)) + || (gBattleMons[bank2].ability == ABILITY_CHLOROPHYLL && (gBattleWeather & WEATHER_SUN_ANY))) + bank2SpeedMultiplier = 2; + else + bank2SpeedMultiplier = 1; + } + else + { + bank1SpeedMultiplier = 1; + bank2SpeedMultiplier = 1; + } + + // Calculate adjusted speed for first mon. + bank1AdjustedSpeed = (gBattleMons[bank1].speed * bank1SpeedMultiplier) + * gStatStageRatios[gBattleMons[bank1].statStages[STAT_STAGE_SPEED]][0] / gStatStageRatios[gBattleMons[bank1].statStages[STAT_STAGE_SPEED]][1]; + + if (gBattleMons[bank1].item == ITEM_ENIGMA_BERRY) + { + heldItemEffect = gEnigmaBerries[bank1].holdEffect; + heldItemEffectParam = gEnigmaBerries[bank1].holdEffectParam; + } + else + { + heldItemEffect = ItemId_GetHoldEffect(gBattleMons[bank1].item); + heldItemEffectParam = ItemId_GetHoldEffectParam(gBattleMons[bank1].item); + } + + // Only give badge speed boost to the player's mon. + if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && FlagGet(FLAG_BADGE03_GET) && GetBattlerSide(bank1) == 0) + bank1AdjustedSpeed = (bank1AdjustedSpeed * 110) / 100; + + if (heldItemEffect == HOLD_EFFECT_MACHO_BRACE) + bank1AdjustedSpeed /= 2; + + if (gBattleMons[bank1].status1 & STATUS_PARALYSIS) + bank1AdjustedSpeed /= 4; + + if (heldItemEffect == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (heldItemEffectParam * 0xFFFF) / 100) + bank1AdjustedSpeed = UINT_MAX; + + // Calculate adjusted speed for second mon. + bank2AdjustedSpeed = gBattleMons[bank2].speed * bank2SpeedMultiplier + * gStatStageRatios[gBattleMons[bank2].statStages[STAT_STAGE_SPEED]][0] / gStatStageRatios[gBattleMons[bank2].statStages[STAT_STAGE_SPEED]][1]; + + if (gBattleMons[bank2].item == ITEM_ENIGMA_BERRY) + { + heldItemEffect = gEnigmaBerries[bank2].holdEffect; + heldItemEffectParam = gEnigmaBerries[bank2].holdEffectParam; + } + else + { + heldItemEffect = ItemId_GetHoldEffect(gBattleMons[bank2].item); + heldItemEffectParam = ItemId_GetHoldEffectParam(gBattleMons[bank2].item); + } + + // Only give badge speed boost to the player's mon. + if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && FlagGet(FLAG_BADGE03_GET) && GetBattlerSide(bank2) == 0) + { + bank2AdjustedSpeed = (bank2AdjustedSpeed * 110) / 100; + } + + if (heldItemEffect == HOLD_EFFECT_MACHO_BRACE) + bank2AdjustedSpeed /= 2; + + if (gBattleMons[bank2].status1 & STATUS_PARALYSIS) + bank2AdjustedSpeed /= 4; + + if (heldItemEffect == HOLD_EFFECT_QUICK_CLAW && gRandomTurnNumber < (heldItemEffectParam * 0xFFFF) / 100) + bank2AdjustedSpeed = UINT_MAX; + + if (ignoreMovePriorities) + { + bank1Move = MOVE_NONE; + bank2Move = MOVE_NONE; + } + else + { + if (gActionForBanks[bank1] == 0) + { + if (gProtectStructs[bank1].onlyStruggle) + bank1Move = MOVE_STRUGGLE; + else + bank1Move = gBattleMons[bank1].moves[ewram1608Carr(bank1)]; + } + else + bank1Move = MOVE_NONE; + + if (gActionForBanks[bank2] == 0) + { + if (gProtectStructs[bank2].onlyStruggle) + bank2Move = MOVE_STRUGGLE; + else + bank2Move = gBattleMons[bank2].moves[ewram1608Carr(bank2)]; + } + else + bank2Move = MOVE_NONE; + } + + if (gBattleMoves[bank1Move].priority != 0 || gBattleMoves[bank2Move].priority != 0) + { + if (gBattleMoves[bank1Move].priority == gBattleMoves[bank2Move].priority) + { + if (bank1AdjustedSpeed == bank2AdjustedSpeed && (Random() & 1)) + strikesFirst = 2; + else if (bank1AdjustedSpeed < bank2AdjustedSpeed) + strikesFirst = 1; + } + else if (gBattleMoves[bank1Move].priority < gBattleMoves[bank2Move].priority) + strikesFirst = 1; + } + else + { + if (bank1AdjustedSpeed == bank2AdjustedSpeed && (Random() & 1)) + strikesFirst = 2; + else if (bank1AdjustedSpeed < bank2AdjustedSpeed) + strikesFirst = 1; + } + + return strikesFirst; +} + +void SetActionsAndBanksTurnOrder(void) +{ + s32 var = 0; + s32 i, j; + + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + gActionsByTurnOrder[var] = gActionForBanks[gActiveBattler]; + gBanksByTurnOrder[var] = gActiveBattler; + var++; + } + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (gActionForBanks[gActiveBattler] == ACTION_RUN) + { + var = 5; + break; + } + } + } + else + { + if (gActionForBanks[0] == ACTION_RUN) + { + gActiveBattler = 0; + var = 5; + } + } + + if (var == 5) + { + gActionsByTurnOrder[0] = gActionForBanks[gActiveBattler]; + gBanksByTurnOrder[0] = gActiveBattler; + var = 1; + for (i = 0; i < gBattlersCount; i++) + { + if (i != gActiveBattler) + { + gActionsByTurnOrder[var] = gActionForBanks[i]; + gBanksByTurnOrder[var] = i; + var++; + } + } + gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; + eFocusPunchBattler = 0; + return; + } + else + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (gActionForBanks[gActiveBattler] == ACTION_USE_ITEM || gActionForBanks[gActiveBattler] == ACTION_SWITCH) + { + gActionsByTurnOrder[var] = gActionForBanks[gActiveBattler]; + gBanksByTurnOrder[var] = gActiveBattler; + var++; + } + } + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (gActionForBanks[gActiveBattler] != ACTION_USE_ITEM && gActionForBanks[gActiveBattler] != ACTION_SWITCH) + { + gActionsByTurnOrder[var] = gActionForBanks[gActiveBattler]; + gBanksByTurnOrder[var] = gActiveBattler; + var++; + } + } + for (i = 0; i < gBattlersCount - 1; i++) + { + for (j = i + 1; j < gBattlersCount; j++) + { + u8 bank1 = gBanksByTurnOrder[i]; + u8 bank2 = gBanksByTurnOrder[j]; + if (gActionsByTurnOrder[i] != ACTION_USE_ITEM + && gActionsByTurnOrder[j] != ACTION_USE_ITEM + && gActionsByTurnOrder[i] != ACTION_SWITCH + && gActionsByTurnOrder[j] != ACTION_SWITCH) + { + if (GetWhoStrikesFirst(bank1, bank2, FALSE)) + SwapTurnOrder(i, j); + } + } + } + } + } + + gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; + eFocusPunchBattler = 0; +} + +static void TurnValuesCleanUp(bool8 var0) +{ + s32 i; + u8 *dataPtr; + + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (var0) + { + gProtectStructs[gActiveBattler].protected = 0; + gProtectStructs[gActiveBattler].endured = 0; + } + else + { + dataPtr = (u8*)(&gProtectStructs[gActiveBattler]); + for (i = 0; i < sizeof(struct ProtectStruct); i++) + dataPtr[i] = 0; + + if (gDisableStructs[gActiveBattler].isFirstTurn) + gDisableStructs[gActiveBattler].isFirstTurn--; + + if (gDisableStructs[gActiveBattler].rechargeCounter) + { + gDisableStructs[gActiveBattler].rechargeCounter--; + if (gDisableStructs[gActiveBattler].rechargeCounter == 0) + gBattleMons[gActiveBattler].status2 &= ~(STATUS2_RECHARGE); + } + } + + if (gDisableStructs[gActiveBattler].substituteHP == 0) + gBattleMons[gActiveBattler].status2 &= ~(STATUS2_SUBSTITUTE); + } + + gSideTimers[0].followmeTimer = 0; + gSideTimers[1].followmeTimer = 0; +} + +void SpecialStatusesClear(void) +{ + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + s32 i; + u8 *dataPtr = (u8*)(&gSpecialStatuses[gActiveBattler]); + + for (i = 0; i < sizeof(struct SpecialStatus); i++) + dataPtr[i] = 0; + } +} + +void CheckFocusPunch_ClearVarsBeforeTurnStarts(void) +{ + if (!(gHitMarker & HITMARKER_RUN)) + { + while (eFocusPunchBattler < gBattlersCount) + { + gActiveBattler = gBankAttacker = eFocusPunchBattler; + eFocusPunchBattler++; + if (gChosenMovesByBanks[gActiveBattler] == MOVE_FOCUS_PUNCH + && !(gBattleMons[gActiveBattler].status1 & STATUS_SLEEP) + && !(gDisableStructs[gBankAttacker].truantCounter) + && !(gProtectStructs[gActiveBattler].onlyStruggle)) + { + BattleScriptExecute(BattleScript_FocusPunchSetUp); + return; + } + } + } + + TryClearRageStatuses(); + gCurrentTurnActionNumber = 0; + { + // something stupid needed to match + u8 zero; + gCurrentActionFuncId = gActionsByTurnOrder[(zero = 0)]; + } + + gDynamicBasePower = 0; + gBattleStruct->dynamicMoveType = 0; + gBattleMainFunc = RunTurnActionsFunctions; + gBattleCommunication[3] = 0; + gBattleCommunication[4] = 0; + eMultihitMoveEffect = 0; + ewram17130 = 0; +} + +static void RunTurnActionsFunctions(void) +{ + if (gBattleOutcome != 0) + gCurrentActionFuncId = 12; + + gBattleStruct->unk16057 = gCurrentTurnActionNumber; + gUnknown_081FA640[gCurrentActionFuncId](); + + if (gCurrentTurnActionNumber >= gBattlersCount) // everyone did their actions, turn finished + { + gHitMarker &= ~(HITMARKER_x100000); + gBattleMainFunc = gUnknown_081FA678[gBattleOutcome & 0x7F]; + } + else + { + if (gBattleStruct->unk16057 != gCurrentTurnActionNumber) // action turn has been done, clear hitmarker bits for another bank + { + gHitMarker &= ~(HITMARKER_NO_ATTACKSTRING); + gHitMarker &= ~(HITMARKER_UNABLE_TO_USE_MOVE); + } + } +} + +void HandleEndTurn_BattleWon(void) +{ + gCurrentActionFuncId = 0; + + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gBattleTextBuff1[0] = gBattleOutcome; + gBankAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + gBattlescriptCurrInstr = BattleScript_LinkBattleWonOrLost; + gBattleOutcome &= ~(OUTCOME_LINK_BATTLE_RUN); + } + else if (gBattleTypeFlags & (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER)) + { + gBattlescriptCurrInstr = gUnknown_081D8E0D; + } + else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && !(gBattleTypeFlags & BATTLE_TYPE_LINK)) + { + BattleStopLowHpSound(); + gBattlescriptCurrInstr = BattleScript_LocalTrainerBattleWon; + + switch (gTrainers[gTrainerBattleOpponent].trainerClass) + { + case TRAINER_CLASS_ELITE_FOUR: + case TRAINER_CLASS_CHAMPION: + PlayBGM(MUS_KACHI5); + break; + case TRAINER_CLASS_TEAM_AQUA: + case TRAINER_CLASS_TEAM_MAGMA: + case TRAINER_CLASS_AQUA_ADMIN: + case TRAINER_CLASS_AQUA_LEADER: + case TRAINER_CLASS_MAGMA_ADMIN: + case TRAINER_CLASS_MAGMA_LEADER: + PlayBGM(MUS_KACHI4); + break; + case TRAINER_CLASS_LEADER: + PlayBGM(MUS_KACHI3); + break; + default: + PlayBGM(MUS_KACHI1); + break; + } + } + else + { + gBattlescriptCurrInstr = BattleScript_PayDayMoneyAndPickUpItems; + } + + gBattleMainFunc = HandleEndTurn_FinishBattle; +} + +void HandleEndTurn_BattleLost(void) +{ + gCurrentActionFuncId = 0; + + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gBattleTextBuff1[0] = gBattleOutcome; + gBankAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + gBattlescriptCurrInstr = BattleScript_LinkBattleWonOrLost; + gBattleOutcome &= ~(OUTCOME_LINK_BATTLE_RUN); + } + else + { + gBattlescriptCurrInstr = BattleScript_LocalBattleLost; + } + + gBattleMainFunc = HandleEndTurn_FinishBattle; +} + +void HandleEndTurn_RanFromBattle(void) +{ + gCurrentActionFuncId = 0; + + switch (gProtectStructs[gBankAttacker].fleeFlag) + { + default: + gBattlescriptCurrInstr = BattleScript_GotAwaySafely; + break; + case 1: + gBattlescriptCurrInstr = BattleScript_SmokeBallEscape; + break; + case 2: + gBattlescriptCurrInstr = BattleScript_RanAwayUsingMonAbility; + break; + } + + gBattleMainFunc = HandleEndTurn_FinishBattle; +} + +void HandleEndTurn_MonFled(void) +{ + gCurrentActionFuncId = 0; + + PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBankAttacker, gBattlerPartyIndexes[gBankAttacker]); + gBattlescriptCurrInstr = BattleScript_WildMonFled; + + gBattleMainFunc = HandleEndTurn_FinishBattle; +} + +void HandleEndTurn_FinishBattle(void) +{ + if (gCurrentActionFuncId == 0xB || gCurrentActionFuncId == 0xC) + { + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK + | BATTLE_TYPE_FIRST_BATTLE + | BATTLE_TYPE_SAFARI + | BATTLE_TYPE_EREADER_TRAINER + | BATTLE_TYPE_WALLY_TUTORIAL + | BATTLE_TYPE_BATTLE_TOWER))) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) + { + if (gBattleResults.poke1Species == SPECIES_NONE) + { + gBattleResults.poke1Species = gBattleMons[gActiveBattler].species; + StringCopy(gBattleResults.pokeString1, gBattleMons[gActiveBattler].nickname); + } + else + { + gBattleResults.opponentSpecies = gBattleMons[gActiveBattler].species; + StringCopy(gBattleResults.pokeString2, gBattleMons[gActiveBattler].nickname); + } + } + } + PutPokemonTodayCaughtOnAir(); + } + + BeginFastPaletteFade(3); + FadeOutMapMusic(5); + gBattleMainFunc = FreeResetData_ReturnToOvOrDoEvolutions; + gCB2_AfterEvolution = BattleMainCB2; + } + else + { + if (gBattleExecBuffer == 0) + gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); + } +} + +static void FreeResetData_ReturnToOvOrDoEvolutions(void) +{ + if (!gPaletteFade.active) + { + ResetSpriteData(); + if (gLeveledUpInBattle == 0 || gBattleOutcome != BATTLE_WON) + { + gBattleMainFunc = ReturnFromBattleToOverworld; + return; + } + else + { + gBattleMainFunc = TryEvolvePokemon; + } + } +} + +void TryEvolvePokemon(void) +{ + s32 i; + + while (gLeveledUpInBattle != 0) + { + for (i = 0; i < 6; i++) + { + if (gLeveledUpInBattle & gBitTable[i]) + { + u16 species; + u8 levelUpBits = gLeveledUpInBattle; + + levelUpBits &= ~(gBitTable[i]); + gLeveledUpInBattle = levelUpBits; + + species = GetEvolutionTargetSpecies(&gPlayerParty[i], 0, levelUpBits); + if (species != SPECIES_NONE) + { + gBattleMainFunc = WaitForEvoSceneToFinish; + EvolutionScene(&gPlayerParty[i], species, 0x81, i); + return; + } + } + } + } + + gBattleMainFunc = ReturnFromBattleToOverworld; +} + +static void WaitForEvoSceneToFinish(void) +{ + if (gMain.callback2 == BattleMainCB2) + gBattleMainFunc = TryEvolvePokemon; +} + +static void ReturnFromBattleToOverworld(void) +{ + if (!(gBattleTypeFlags & BATTLE_TYPE_LINK)) + { + RandomlyGivePartyPokerus(gPlayerParty); + PartySpreadPokerus(gPlayerParty); + } + + if (gBattleTypeFlags & BATTLE_TYPE_LINK && gReceivedRemoteLinkPlayers != 0) + return; + + gSpecialVar_Result = gBattleOutcome; + gMain.inBattle = 0; + gMain.callback1 = gPreBattleCallback1; + + if (gBattleTypeFlags & BATTLE_TYPE_ROAMER) + { + UpdateRoamerHPStatus(&gEnemyParty[0]); + if (gBattleOutcome == BATTLE_WON || gBattleOutcome == BATTLE_CAUGHT) + SetRoamerInactive(); + } + + m4aSongNumStop(0x5A); + SetMainCallback2(gMain.savedCallback); +} + +void RunBattleScriptCommands_PopCallbacksStack(void) +{ + if (gCurrentActionFuncId == 0xB || gCurrentActionFuncId == 0xC) + { + if (B_FUNCTION_STACK->size != 0) + B_FUNCTION_STACK->size--; + gBattleMainFunc = B_FUNCTION_STACK->ptr[B_FUNCTION_STACK->size]; + } + else + { + if (gBattleExecBuffer == 0) + gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); + } +} + +void RunBattleScriptCommands(void) +{ + if (gBattleExecBuffer == 0) + gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); +} + +void HandleAction_UseMove(void) +{ + u8 side; + u8 var = 4; + + gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; + + if (ewram160A6 & gBitTable[gBankAttacker]) + { + gCurrentActionFuncId = ACTION_FINISHED; + return; + } + + gCritMultiplier = 1; + eDmgMultiplier = 1; + ewram160E7 = 0; + gMoveResultFlags = 0; + gMultiHitCounter = 0; + gBattleCommunication[6] = 0; + gCurrMovePos = gUnknown_02024BE5 = ewram1608Carr(gBankAttacker); + + // choose move + if (gProtectStructs[gBankAttacker].onlyStruggle) + { + gProtectStructs[gBankAttacker].onlyStruggle = 0; + gCurrentMove = gChosenMove = MOVE_STRUGGLE; + gHitMarker |= HITMARKER_NO_PPDEDUCT; + ewram16010arr(gBankAttacker) = GetMoveTarget(MOVE_STRUGGLE, 0); + } + else if (gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS || gBattleMons[gBankAttacker].status2 & STATUS2_RECHARGE) + { + gCurrentMove = gChosenMove = gLockedMoves[gBankAttacker]; + } + // encore forces you to use the same move + else if (gDisableStructs[gBankAttacker].encoredMove != MOVE_NONE + && gDisableStructs[gBankAttacker].encoredMove == gBattleMons[gBankAttacker].moves[gDisableStructs[gBankAttacker].encoredMovePos]) + { + gCurrentMove = gChosenMove = gDisableStructs[gBankAttacker].encoredMove; + gCurrMovePos = gUnknown_02024BE5 = gDisableStructs[gBankAttacker].encoredMovePos; + ewram16010arr(gBankAttacker) = GetMoveTarget(gCurrentMove, 0); + } + // check if the encored move wasn't overwritten + else if (gDisableStructs[gBankAttacker].encoredMove != MOVE_NONE + && gDisableStructs[gBankAttacker].encoredMove != gBattleMons[gBankAttacker].moves[gDisableStructs[gBankAttacker].encoredMovePos]) + { + gCurrMovePos = gUnknown_02024BE5 = gDisableStructs[gBankAttacker].encoredMovePos; + gCurrentMove = gChosenMove = gBattleMons[gBankAttacker].moves[gCurrMovePos]; + gDisableStructs[gBankAttacker].encoredMove = MOVE_NONE; + gDisableStructs[gBankAttacker].encoredMovePos = 0; + gDisableStructs[gBankAttacker].encoreTimer1 = 0; + ewram16010arr(gBankAttacker) = GetMoveTarget(gCurrentMove, 0); + } + else if (gBattleMons[gBankAttacker].moves[gCurrMovePos] != gChosenMovesByBanks[gBankAttacker]) + { + gCurrentMove = gChosenMove = gBattleMons[gBankAttacker].moves[gCurrMovePos]; + ewram16010arr(gBankAttacker) = GetMoveTarget(gCurrentMove, 0); + } + else + { + gCurrentMove = gChosenMove = gBattleMons[gBankAttacker].moves[gCurrMovePos]; + } + + if (GetBattlerSide(gBankAttacker) == B_SIDE_PLAYER) + gBattleResults.lastUsedMove = gCurrentMove; + else + gBattleResults.opponentMove = gCurrentMove; + + // choose target + side = GetBattlerSide(gBankAttacker) ^ BIT_SIDE; + if (gSideTimers[side].followmeTimer != 0 + && gBattleMoves[gCurrentMove].target == MOVE_TARGET_SELECTED + && GetBattlerSide(gBankAttacker) != GetBattlerSide(gSideTimers[side].followmeTarget) + && gBattleMons[gSideTimers[side].followmeTarget].hp != 0) + { + gBankTarget = gSideTimers[side].followmeTarget; + } + else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + && gSideTimers[side].followmeTimer == 0 + && (gBattleMoves[gCurrentMove].power != 0 + || gBattleMoves[gCurrentMove].target != MOVE_TARGET_x10) + && gBattleMons[ewram16010arr(gBankAttacker)].ability != ABILITY_LIGHTNING_ROD + && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) + { + side = GetBattlerSide(gBankAttacker); + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (side != GetBattlerSide(gActiveBattler) + && ewram16010arr(gBankAttacker) != gActiveBattler + && gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD + && BankGetTurnOrder(gActiveBattler) < var) + { + var = BankGetTurnOrder(gActiveBattler); + } + } + if (var == 4) + { + if (gBattleMoves[gChosenMove].target & MOVE_TARGET_RANDOM) + { + if (GetBattlerSide(gBankAttacker) == B_SIDE_PLAYER) + { + if (Random() & 1) + gBankTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + else + gBankTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); + } + else + { + if (Random() & 1) + gBankTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + else + gBankTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); + } + } + else + { + gBankTarget = ewram16010arr(gBankAttacker); + } + + if (gAbsentBattlerFlags & gBitTable[gBankTarget]) + { + if (GetBattlerSide(gBankAttacker) != GetBattlerSide(gBankTarget)) + { + gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankTarget) ^ BIT_FLANK); + } + else + { + gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ BIT_SIDE); + if (gAbsentBattlerFlags & gBitTable[gBankTarget]) + gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankTarget) ^ BIT_FLANK); + } + } + } + else + { + gActiveBattler = gBanksByTurnOrder[var]; + RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability); + gSpecialStatuses[gActiveBattler].lightningRodRedirected = 1; + gBankTarget = gActiveBattler; + } + } + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && gBattleMoves[gChosenMove].target & MOVE_TARGET_RANDOM) + { + if (GetBattlerSide(gBankAttacker) == B_SIDE_PLAYER) + { + if (Random() & 1) + gBankTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + else + gBankTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); + } + else + { + if (Random() & 1) + gBankTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + else + gBankTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); + } + + if (gAbsentBattlerFlags & gBitTable[gBankTarget] + && GetBattlerSide(gBankAttacker) != GetBattlerSide(gBankTarget)) + { + gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankTarget) ^ BIT_FLANK); + } + } + else + { + gBankTarget = ewram16010arr(gBankAttacker); + if (gAbsentBattlerFlags & gBitTable[gBankTarget]) + { + if (GetBattlerSide(gBankAttacker) != GetBattlerSide(gBankTarget)) + { + gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankTarget) ^ BIT_FLANK); + } + else + { + gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ BIT_SIDE); + if (gAbsentBattlerFlags & gBitTable[gBankTarget]) + gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankTarget) ^ BIT_FLANK); + } + } + } + + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; +} + +void HandleAction_Switch(void) +{ + gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gActionSelectionCursor[gBankAttacker] = 0; + gMoveSelectionCursor[gBankAttacker] = 0; + + PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBankAttacker, ewram16064arr(gBankAttacker)) + + ewram16003 = gBankAttacker; + gBattlescriptCurrInstr = BattleScript_ActionSwitch; + gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; + + if (gBattleResults.unk2 < 255) + gBattleResults.unk2++; +} + +void HandleAction_UseItem(void) +{ + gBankAttacker = gBankTarget = gBanksByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gDisableStructs[gBankAttacker].furyCutterCounter = 0; + gLastUsedItem = gBattleBufferB[gBankAttacker][1] | (gBattleBufferB[gBankAttacker][2] << 8); + + if (gLastUsedItem <= ITEM_PREMIER_BALL) // is ball + { + gBattlescriptCurrInstr = gBattlescriptsForBallThrow[gLastUsedItem]; + } + else if (gLastUsedItem == ITEM_POKE_DOLL || gLastUsedItem == ITEM_FLUFFY_TAIL) + { + gBattlescriptCurrInstr = gBattlescriptsForRunningByItem[0]; + } + else if (GetBattlerSide(gBankAttacker) == B_SIDE_PLAYER) + { + gBattlescriptCurrInstr = gBattlescriptsForUsingItem[0]; + } + else + { + + switch (ewram160D8((ewram16003 = gBankAttacker))) + { + case AI_ITEM_FULL_RESTORE: + case AI_ITEM_HEAL_HP: + break; + case AI_ITEM_CURE_CONDITION: + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + if (ewram160DA(gBankAttacker) & 1) + { + if (ewram160DA(gBankAttacker) & 0x3E) + gBattleCommunication[MULTISTRING_CHOOSER] = 5; + } + else + { + while (!(ewram160DA(gBankAttacker) & 1)) + { + ewram160DA(gBankAttacker) >>= 1; + gBattleCommunication[MULTISTRING_CHOOSER]++; + } + } + break; + case AI_ITEM_X_STAT: + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + if (ewram160DA(gBankAttacker) & 0x80) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 5; + } + else + { + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK) + PREPARE_STRING_BUFFER(gBattleTextBuff2, 0xD2) + + while (!(ewram160DA(gBankAttacker) & 1)) + { + ewram160DA(gBankAttacker) >>= 1; + gBattleTextBuff1[2]++; + } + + ewram160A4 = gBattleTextBuff1[2] + 14; + ewram160A5 = 0; + } + break; + case AI_ITEM_GUARD_SPECS: + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + break; + } + + gBattlescriptCurrInstr = gBattlescriptsForUsingItem[ewram160D8(gBankAttacker)]; + } + gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; +} + +bool8 TryRunFromBattle(u8 bank) +{ + bool8 effect = FALSE; + u8 holdEffect; + u8 speedVar; + + if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY) + holdEffect = gEnigmaBerries[bank].holdEffect; + else + holdEffect = ItemId_GetHoldEffect(gBattleMons[bank].item); + + gStringBank = bank; + + if (holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN) + { + gLastUsedItem = gBattleMons[bank].item ; + gProtectStructs[bank].fleeFlag = 1; + effect++; + } + else if (gBattleMons[bank].ability == ABILITY_RUN_AWAY) + { + gLastUsedAbility = ABILITY_RUN_AWAY; + gProtectStructs[bank].fleeFlag = 2; + effect++; + } + else + { + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + if (gBattleMons[bank].speed < gBattleMons[bank ^ BIT_SIDE].speed) + { + speedVar = (gBattleMons[bank].speed * 128) / (gBattleMons[bank ^ BIT_SIDE].speed) + (ewram16078 * 30); + if (speedVar > (Random() & 0xFF)) + effect++; + } + else // same speed or faster + { + effect++; + } + } + + ewram16078++; + } + + if (effect) + { + gCurrentTurnActionNumber = gBattlersCount; + gBattleOutcome = BATTLE_RAN; + } + + return effect; +} + +void HandleAction_Run(void) +{ + gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; + + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gCurrentTurnActionNumber = gBattlersCount; + + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) + { + if (gActionForBanks[gActiveBattler] == ACTION_RUN) + gBattleOutcome |= BATTLE_LOST; + } + else + { + if (gActionForBanks[gActiveBattler] == ACTION_RUN) + gBattleOutcome |= BATTLE_WON; + } + } + + gBattleOutcome |= OUTCOME_LINK_BATTLE_RUN; + } + else + { + if (GetBattlerSide(gBankAttacker) == B_SIDE_PLAYER) + { + if (!TryRunFromBattle(gBankAttacker)) // failed to run away + { + gBattleMons[gBankAttacker].status2 &= ~STATUS2_DESTINY_BOND; + gBattleCommunication[MULTISTRING_CHOOSER] = 3; + gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString; + gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; + } + } + else + { + if (gBattleMons[gBankAttacker].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString; + gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; + } + else + { + gCurrentTurnActionNumber = gBattlersCount; + gBattleOutcome = BATTLE_POKE_FLED; + } + } + } +} + +void HandleAction_WatchesCarefully(void) +{ + gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gBattlescriptCurrInstr = gBattlescriptsForSafariActions[0]; + gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; +} + +void HandleAction_SafariZoneBallThrow(void) +{ + gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gNumSafariBalls--; + gLastUsedItem = ITEM_SAFARI_BALL; + gBattlescriptCurrInstr = gBattlescriptsForBallThrow[ITEM_SAFARI_BALL]; + gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; +} + +void HandleAction_ThrowPokeblock(void) +{ + gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = gBattleBufferB[gBankAttacker][1] - 1; + gLastUsedItem = gBattleBufferB[gBankAttacker][2]; + + if (ewram16087 < 3) + ewram16087++; + if (ewram16088 > 1) + { + if (ewram16088 < gUnknown_081FA70C[ewram16087][gBattleCommunication[MULTISTRING_CHOOSER]]) + ewram16088 = 1; + else + ewram16088 -= gUnknown_081FA70C[ewram16087][gBattleCommunication[MULTISTRING_CHOOSER]]; + } + + gBattlescriptCurrInstr = gBattlescriptsForSafariActions[2]; + gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; +} + +void HandleAction_GoNear(void) +{ + gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + + ewram16089 += gUnknown_081FA71B[ewram16086]; + if (ewram16089 > 20) + ewram16089 = 20; + + ewram16088 += gUnknown_081FA71F[ewram16086]; + if (ewram16088 > 20) + ewram16088 = 20; + + if (ewram16086 < 3) + { + ewram16086++; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + gBattlescriptCurrInstr = gBattlescriptsForSafariActions[1]; + gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; +} + +void HandleAction_SafriZoneRun(void) +{ + gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; + PlaySE(SE_NIGERU); + gCurrentTurnActionNumber = gBattlersCount; + gBattleOutcome = BATTLE_RAN; +} + +void HandleAction_Action9(void) +{ + gBankAttacker = gBanksByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + + PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBankAttacker, gBattlerPartyIndexes[gBankAttacker]) + + gBattlescriptCurrInstr = gBattlescriptsForSafariActions[3]; + gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT; + gActionsByTurnOrder[1] = ACTION_FINISHED; +} + +void HandleAction_Action11(void) +{ + if (!HandleFaintedMonActions()) + { + ewram16059 = 0; + gCurrentActionFuncId = ACTION_FINISHED; + } +} + +void HandleAction_NothingIsFainted(void) +{ + gCurrentTurnActionNumber++; + gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber]; + gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED + | HITMARKER_NO_PPDEDUCT | HITMARKER_IGNORE_SAFEGUARD | HITMARKER_IGNORE_ON_AIR + | HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000 + | HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT + | HITMARKER_x8000000 | HITMARKER_x4000000); +} + +void HandleAction_ActionFinished(void) +{ + gCurrentTurnActionNumber++; + gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber]; + SpecialStatusesClear(); + gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED + | HITMARKER_NO_PPDEDUCT | HITMARKER_IGNORE_SAFEGUARD | HITMARKER_IGNORE_ON_AIR + | HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000 + | HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT + | HITMARKER_x8000000 | HITMARKER_x4000000); + + gBattleMoveDamage = 0; + ewram16002 = 0; + ewram160A1 = 0; + gLastLandedMoves[gBankAttacker] = 0; + gLastHitByType[gBankAttacker] = 0; + eDynamicMoveType = 0; + gDynamicBasePower = 0; + ewram1600C = 0; + gBattleCommunication[3] = 0; + gBattleCommunication[4] = 0; + eMultihitMoveEffect = 0; + ewram17130 = 0; +} diff --git a/src/battle_message.c b/src/battle_message.c new file mode 100644 index 000000000..6f3fa63c6 --- /dev/null +++ b/src/battle_message.c @@ -0,0 +1,1054 @@ +#include "global.h" +#include "battle.h" +#include "battle_message.h" +#include "battle_tower.h" +#include "item.h" +#include "event_data.h" +#include "constants/items.h" +#include "pokemon.h" +#include "data2.h" +#include "text.h" +#include "string_util.h" +#include "link.h" +#include "battle_setup.h" +#include "battle_tower.h" +#include "constants/flags.h" +#include "ewram.h" + +#define BATTLESTRING_TO_SUB 12 +#define BATTLESTRINGS_NO 351 +#define BATTLESTRINGS_MAX BATTLESTRINGS_NO + BATTLESTRING_TO_SUB + +#ifdef GERMAN +#include "data/battle_strings_de.h" // TODO: German +#else +#include "data/battle_strings_en.h" +#endif + +// This is four lists of moves which use a different attack string in Japanese +// to the default. See the documentation for sub_8121D74 for more detail. +const u16 gUnknown_084016BC[] = +{ + MOVE_SWORDS_DANCE, + MOVE_STRENGTH, + MOVE_GROWTH, + MOVE_HARDEN, + MOVE_MINIMIZE, + MOVE_SMOKESCREEN, + MOVE_WITHDRAW, + MOVE_DEFENSE_CURL, + MOVE_EGG_BOMB, + MOVE_SMOG, + MOVE_BONE_CLUB, + MOVE_FLASH, + MOVE_SPLASH, + MOVE_ACID_ARMOR, + MOVE_BONEMERANG, + MOVE_REST, + MOVE_SHARPEN, + MOVE_SUBSTITUTE, + MOVE_MIND_READER, + MOVE_SNORE, + MOVE_PROTECT, + MOVE_SPIKES, + MOVE_ENDURE, + MOVE_ROLLOUT, + MOVE_SWAGGER, + MOVE_SLEEP_TALK, + MOVE_HIDDEN_POWER, + MOVE_PSYCH_UP, + MOVE_EXTREME_SPEED, + MOVE_FOLLOW_ME, + MOVE_TRICK, + MOVE_ASSIST, + MOVE_INGRAIN, + MOVE_KNOCK_OFF, + MOVE_CAMOUFLAGE, + MOVE_ASTONISH, + MOVE_ODOR_SLEUTH, + MOVE_GRASS_WHISTLE, + MOVE_SHEER_COLD, + MOVE_MUDDY_WATER, + MOVE_IRON_DEFENSE, + MOVE_BOUNCE, + 0, + MOVE_TELEPORT, + MOVE_RECOVER, + MOVE_BIDE, + MOVE_AMNESIA, + MOVE_FLAIL, + MOVE_TAUNT, + MOVE_BULK_UP, + 0, + MOVE_MEDITATE, + MOVE_AGILITY, + MOVE_MIMIC, + MOVE_DOUBLE_TEAM, + MOVE_BARRAGE, + MOVE_TRANSFORM, + MOVE_STRUGGLE, + MOVE_SCARY_FACE, + MOVE_CHARGE, + MOVE_WISH, + MOVE_BRICK_BREAK, + MOVE_YAWN, + MOVE_FEATHER_DANCE, + MOVE_TEETER_DANCE, + MOVE_MUD_SPORT, + MOVE_FAKE_TEARS, + MOVE_WATER_SPORT, + MOVE_CALM_MIND, + 0, + MOVE_POUND, + MOVE_SCRATCH, + MOVE_VICE_GRIP, + MOVE_WING_ATTACK, + MOVE_FLY, + MOVE_BIND, + MOVE_SLAM, + MOVE_HORN_ATTACK, + MOVE_WRAP, + MOVE_THRASH, + MOVE_TAIL_WHIP, + MOVE_LEER, + MOVE_BITE, + MOVE_GROWL, + MOVE_ROAR, + MOVE_SING, + MOVE_PECK, + MOVE_ABSORB, + MOVE_STRING_SHOT, + MOVE_EARTHQUAKE, + MOVE_FISSURE, + MOVE_DIG, + MOVE_TOXIC, + MOVE_SCREECH, + MOVE_METRONOME, + MOVE_LICK, + MOVE_CLAMP, + MOVE_CONSTRICT, + MOVE_POISON_GAS, + MOVE_BUBBLE, + MOVE_SLASH, + MOVE_SPIDER_WEB, + MOVE_NIGHTMARE, + MOVE_CURSE, + MOVE_FORESIGHT, + MOVE_CHARM, + MOVE_ATTRACT, + MOVE_ROCK_SMASH, + MOVE_UPROAR, + MOVE_SPIT_UP, + MOVE_SWALLOW, + MOVE_TORMENT, + MOVE_FLATTER, + MOVE_ROLE_PLAY, + MOVE_ENDEAVOR, + MOVE_TICKLE, + MOVE_COVET, + 0, +}; + +const u8 gUnknown_084017A8[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // empty flags + +extern const u8* const gBattleStringsTable[BATTLESTRINGS_NO]; + +extern u16 gLastUsedItem; +extern u8 gLastUsedAbility; +extern u8 gActiveBattler; +extern u8 gBankAttacker; +extern u8 gBankTarget; +extern u8 gStringBank; +extern u8 gEffectBank; +extern u8 gBattleTextBuff1[]; +extern u8 gBattleTextBuff2[]; +extern u8 gBattleTextBuff3[]; +extern u8 gStringVar1[]; +extern u8 gStringVar2[]; +extern u8 gStringVar3[]; +extern u16 gBattleTypeFlags; +extern u16 gTrainerBattleOpponent; +extern u8 gDisplayedStringBattle[]; +extern u8 gStringVar1[]; +extern u8 gStringVar2[]; +extern u8 gStringVar3[]; +extern u16 gBattlerPartyIndexes[4]; +extern struct BattleEnigmaBerry gEnigmaBerries[4]; +extern u8 gBattleBufferA[4][0x200]; + +EWRAM_DATA u8 gAbilitiesPerBank[4] = {0}; + +extern const u8* const gUnknown_08401674[]; // table of pointers to 'a -TYPE' strings +extern const u8* const gUnknown_08400F58[]; // table of pointers to stat strings +extern const u8* const gUnknown_08400F78[]; // table of pointers to flavour strings + +struct StatusFlagString +{ + u8* flag; + u8* ptr; +}; + +extern const struct StatusFlagString gUnknown_081FA6D4[7]; // status flag/text + +extern struct StringInfoBattle* gSelectedOrderFromParty; +#define gStringInfo gSelectedOrderFromParty + +void sub_8121D1C(u8* textBuff); +void sub_8121D74(u8* textBuff); +void StrCpyDecodeBattleTextBuff(u8* src, u8* dst); + +u8 GetBattlerSide(u8 bank); +s32 sub_803FC34(u16); +void get_trainer_name(u8* dst); +u8 get_trainer_class_name_index(void); +u8 GetMultiplayerId(void); +u8 GetBattlerAtPosition(u8 ID); +u8 GetBattlerSide(u8 bank); +u8 GetBattlerPosition(u8 bank); +#ifdef GERMAN +extern u8 *de_sub_804110C(); +#endif + +void BufferStringBattle(u16 stringID) +{ + int i; + const u8* stringPtr = NULL; + + gStringInfo = (struct StringInfoBattle*)(&gBattleBufferA[gActiveBattler][4]); + gLastUsedItem = gStringInfo->lastItem; + gLastUsedAbility = gStringInfo->lastAbility; + gBattleStruct->scriptingActive = gStringInfo->scrActive; + gBattleStruct->unk1605E = gStringInfo->unk1605E; + gBattleStruct->hpScale = gStringInfo->hpScale; + gStringBank = gStringInfo->StringBank; + gBattleStruct->stringMoveType = gStringInfo->moveType; + for (i = 0; i < 4; i++) + { + gAbilitiesPerBank[i] = gStringInfo->abilities[i]; + } + for (i = 0; i < 0x10; i++) + { + gBattleTextBuff1[i] = gStringInfo->textBuffs[0][i]; + gBattleTextBuff2[i] = gStringInfo->textBuffs[1][i]; + gBattleTextBuff3[i] = gStringInfo->textBuffs[2][i]; + } + switch (stringID) + { + case 0: // first battle msg + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + { + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + stringPtr = BattleText_DoubleWantToBattle; + else + stringPtr = BattleText_SingleWantToBattle2; + } + else + { + stringPtr = BattleText_SingleWantToBattle1; +#ifdef GERMAN + stringPtr = de_sub_804110C(0xFFFF, stringPtr); +#endif + } + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_LEGENDARY) + stringPtr = BattleText_WildAppeared2; + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) // interesting, looks like they had something planned for wild double battles + stringPtr = BattleText_WildDoubleAppeared; + else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) + stringPtr = BattleText_WildAppeared3; + else + stringPtr = BattleText_WildAppeared1; + } + break; + case 1: // poke first send-out + if (GetBattlerSide(gActiveBattler) == 0) + { + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + stringPtr = BattleText_SentOutSingle11; + else + stringPtr = BattleText_SentOutDouble4; + } + else + stringPtr = BattleText_SentOutSingle6; + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + stringPtr = BattleText_SentOutDouble3; + else if (gBattleTypeFlags & BATTLE_TYPE_LINK) + stringPtr = BattleText_SentOutDouble2; + else + { + stringPtr = BattleText_SentOutDouble1; +#ifdef GERMAN + stringPtr = de_sub_804110C(0xFFFF, stringPtr); +#endif + } + } + else if (gBattleTypeFlags & BATTLE_TYPE_LINK) + stringPtr = BattleText_SentOutSingle3; + else + { + stringPtr = BattleText_SentOutSingle1; +#ifdef GERMAN + stringPtr = de_sub_804110C(0xFFFF, stringPtr); +#endif + } + } + break; + case 2: // sending poke to ball msg + if (GetBattlerSide(gActiveBattler) == 0) + { + if (gBattleStruct->hpScale == 0) + stringPtr = BattleText_ComeBackSingle1; + else if (gBattleStruct->hpScale == 1 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + stringPtr = BattleText_ComeBackSingle2; + else if (gBattleStruct->hpScale == 2) + stringPtr = BattleText_ComeBackSingle3; + else + stringPtr = BattleText_ComeBackSingle4; + } + else + { + if (gTrainerBattleOpponent == LINK_BATTLE_OPPONENT) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + stringPtr = BattleText_WithdrewPoke3; + else + stringPtr = BattleText_WithdrewPoke2; + } + else + { + stringPtr = BattleText_WithdrewPoke1; +#ifdef GERMAN + stringPtr = de_sub_804110C(0xFFFF, stringPtr); +#endif + } + } + break; + case 3: // switch-in msg + if (GetBattlerSide(gBattleStruct->scriptingActive) == 0) + { + if (gBattleStruct->hpScale == 0 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + stringPtr = BattleText_SentOutSingle7; + else if (gBattleStruct->hpScale == 1) + stringPtr = BattleText_SentOutSingle8; + else if (gBattleStruct->hpScale == 2) + stringPtr = BattleText_SentOutSingle9; + else + stringPtr = BattleText_SentOutSingle10; + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + stringPtr = BattleText_SentOutSingle5; + else + stringPtr = BattleText_SentOutSingle4; + } + else + { + stringPtr = BattleText_SentOutSingle2; +#ifdef GERMAN + stringPtr = de_sub_804110C(0xFFFF, stringPtr); +#endif + } + } + break; + case 4: // pokemon used a move msg + sub_8121D1C(gBattleTextBuff1); + if (gStringInfo->currentMove > 0x162) + StringCopy(gBattleTextBuff2, gUnknown_08401674[gBattleStruct->stringMoveType]); + else + StringCopy(gBattleTextBuff2, gMoveNames[gStringInfo->currentMove]); + sub_8121D74(gBattleTextBuff2); + stringPtr = BattleText_OpponentUsedMove; + break; + case 5: // battle end + if (gBattleTextBuff1[0] & 0x80) + { + gBattleTextBuff1[0] &= ~(0x80); + if (GetBattlerSide(gActiveBattler) == 1 && gBattleTextBuff1[0] != 3) + gBattleTextBuff1[0] ^= 3; + if (gBattleTextBuff1[0] == BATTLE_LOST || gBattleTextBuff1[0] == BATTLE_DREW) + stringPtr = BattleText_GotAwaySafely; + else + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + stringPtr = BattleText_FledDouble; + else + stringPtr = BattleText_FledSingle; + } + } + else + { + if (GetBattlerSide(gActiveBattler) == 1 && gBattleTextBuff1[0] != 3) + gBattleTextBuff1[0] ^= 3; + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + switch (gBattleTextBuff1[0]) + { + case BATTLE_WON: + stringPtr = BattleText_PlayerDefeatedTrainers; + break; + case BATTLE_LOST: + stringPtr = BattleText_PlayerLostTrainers; + break; + case BATTLE_DREW: + stringPtr = BattleText_PlayerTiedTrainers; + break; + } + } + else + { + switch (gBattleTextBuff1[0]) + { + case BATTLE_WON: + stringPtr = BattleText_PlayerDefeatedTrainer; + break; + case BATTLE_LOST: + stringPtr = BattleText_PlayerLostTrainer; + break; + case BATTLE_DREW: + stringPtr = BattleText_PlayerTiedTrainer; + break; + } + } + } + break; + default: // load a string from the table + if (stringID >= BATTLESTRINGS_MAX) + { + gDisplayedStringBattle[0] = EOS; + return; + } + else + { + stringPtr = gBattleStringsTable[stringID - BATTLESTRING_TO_SUB]; +#ifdef GERMAN + stringPtr = de_sub_804110C(stringID, stringPtr); +#endif + } + break; + } + StrCpyDecodeToDisplayedStringBattle(stringPtr); +} + +u32 StrCpyDecodeToDisplayedStringBattle(const u8* src) +{ + StrCpyDecodeBattle(src, gDisplayedStringBattle); +} + +const u8* AppendStatusString(u8* src) +{ + u32 i; + u8 status[8]; + u32 flag1, flag2; + u8* statusPtr; + + memcpy(status, gUnknown_084017A8, 8); + + statusPtr = status; + for (i = 0; i < sizeof(struct StatusFlagString); i++) + { + if (*src == EOS) + break; + *statusPtr = *src; + src++; + statusPtr++; + } + flag1 = *(u32*)(&status[0]); + flag2 = *(u32*)(&status[4]); + for (i = 0; i < 7; i++) + { + if (flag1 == *(u32*)(&gUnknown_081FA6D4[i].flag[0]) && flag2 == *(u32*)(&gUnknown_081FA6D4[i].flag[4])) + return gUnknown_081FA6D4[i].ptr; + } + return NULL; +} + +#ifdef GERMAN +extern u8 *de_sub_8073174(u8 *, const u8 *); +extern u8 *de_sub_8041024(s32, u32); +#endif + +#ifdef ENGLISH +#define HANDLE_NICKNAME_STRING_CASE(bank, monIndex) \ + if (GetBattlerSide(bank) != 0) \ + { \ + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) \ + toCpy = BattleText_Foe; \ + else \ + toCpy = BattleText_Wild; \ + while (*toCpy != EOS) \ + { \ + dst[dstID] = *toCpy; \ + dstID++; \ + toCpy++; \ + } \ + GetMonData(&gEnemyParty[monIndex], MON_DATA_NICKNAME, text); \ + } \ + else \ + { \ + GetMonData(&gPlayerParty[monIndex], MON_DATA_NICKNAME, text); \ + } \ + StringGetEnd10(text); \ + toCpy = text; +#else +#define HANDLE_NICKNAME_STRING_CASE(bank, monIndex) \ + if (GetBattlerSide(bank) != 0) \ + { \ + GetMonData(&gEnemyParty[monIndex], MON_DATA_NICKNAME, text); \ + StringGetEnd10(text); \ + toCpy = text; \ + while (*toCpy != EOS) \ + { \ + dst[dstID] = *toCpy; \ + dstID++; \ + toCpy++; \ + } \ + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) \ + toCpy = BattleText_Foe; \ + else \ + toCpy = BattleText_Wild; \ + } \ + else \ + { \ + GetMonData(&gPlayerParty[monIndex], MON_DATA_NICKNAME, text); \ + StringGetEnd10(text); \ + toCpy = text; \ + } +#endif + +u32 StrCpyDecodeBattle(const u8* src, u8* dst) +{ + u32 dstID = 0; // if they used dstID, why not use srcID as well? + const u8* toCpy = NULL; + u8 text[12]; + u8 multiplayerID = GetMultiplayerId(); + + while (*src != EOS) + { + if (*src == 0xFD) + { + src++; + switch (*src) + { + case 0: + if (gBattleTextBuff1[0] == 0xFD) + { + StrCpyDecodeBattleTextBuff(gBattleTextBuff1, gStringVar1); + toCpy = gStringVar1; + } + else + { + toCpy = AppendStatusString(gBattleTextBuff1); + if (toCpy == 0) + toCpy = gBattleTextBuff1; + } + break; + case 1: + if (gBattleTextBuff2[0] == 0xFD) + { + StrCpyDecodeBattleTextBuff(gBattleTextBuff2, gStringVar2); + toCpy = gStringVar2; + } + else + toCpy = gBattleTextBuff2; + break; + case 42: + if (gBattleTextBuff3[0] == 0xFD) + { + StrCpyDecodeBattleTextBuff(gBattleTextBuff3, gStringVar3); + toCpy = gStringVar3; + } + else + toCpy = gBattleTextBuff3; + break; + case 2: // first player poke name + GetMonData(&gPlayerParty[gBattlerPartyIndexes[GetBattlerAtPosition(0)]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 3: // first enemy poke name + GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(1)]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 4: // second player poke name + GetMonData(&gPlayerParty[gBattlerPartyIndexes[GetBattlerAtPosition(2)]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 5: // second enemy poke name + GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(3)]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 6: // link first player poke name + GetMonData(&gPlayerParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerID].lp_field_18]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 7: // link first opponent poke name + GetMonData(&gEnemyParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerID].lp_field_18 ^ 1]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 8: // link second player poke name + GetMonData(&gPlayerParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerID].lp_field_18 ^ 2]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 9: // link second opponent poke name + GetMonData(&gEnemyParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerID].lp_field_18 ^ 3]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + toCpy = text; + break; + case 10: // attacker name with prefix, only bank 0/1 + HANDLE_NICKNAME_STRING_CASE(gBankAttacker, gBattlerPartyIndexes[GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) & 1)]) + break; + case 11: // attacker partner name, only bank 0/1 + if (GetBattlerSide(gBankAttacker) == 0) + GetMonData(&gPlayerParty[gBattlerPartyIndexes[GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) & 1) + 2]], MON_DATA_NICKNAME, text); + else + GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) & 1) + 2]], MON_DATA_NICKNAME, text); + + StringGetEnd10(text); + toCpy = text; + break; + case 12: // attacker name with prefix + HANDLE_NICKNAME_STRING_CASE(gBankAttacker, gBattlerPartyIndexes[gBankAttacker]) + break; + case 13: // target name with prefix + HANDLE_NICKNAME_STRING_CASE(gBankTarget, gBattlerPartyIndexes[gBankTarget]) + break; + case 14: // effect bank name with prefix + HANDLE_NICKNAME_STRING_CASE(gEffectBank, gBattlerPartyIndexes[gEffectBank]) + break; + case 15: // active bank name with prefix + HANDLE_NICKNAME_STRING_CASE(gActiveBattler, gBattlerPartyIndexes[gActiveBattler]) + break; + case 16: // scripting active bank name with prefix + HANDLE_NICKNAME_STRING_CASE(gBattleStruct->scriptingActive, gBattlerPartyIndexes[gBattleStruct->scriptingActive]) + break; + case 17: // current move name + if (gStringInfo->currentMove > 0x162) + toCpy = (void*) &gUnknown_08401674[gBattleStruct->stringMoveType]; + else + toCpy = gMoveNames[gStringInfo->currentMove]; + break; + case 18: // last used move name + if (gStringInfo->lastMove > 0x162) + toCpy = (void*) &gUnknown_08401674[gBattleStruct->stringMoveType]; + else + toCpy = gMoveNames[gStringInfo->lastMove]; + break; + case 19: // last used item + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + if (gLastUsedItem == ITEM_ENIGMA_BERRY) + { + if (gLinkPlayers[gBattleStruct->linkPlayerIndex].lp_field_18 == gStringBank) + { + StringCopy(text, gEnigmaBerries[gStringBank].name); +#ifdef ENGLISH + StringAppend(text, BattleText_Berry); +#else + de_sub_8073174(text, BattleText_Berry); +#endif + toCpy = text; + } + else + toCpy = BattleText_EnigmaBerry; + } + else + { + CopyItemName(gLastUsedItem, text); + toCpy = text; + } + } + else + { + CopyItemName(gLastUsedItem, text); + toCpy = text; + } + break; + case 20: // last used ability + toCpy = gAbilityNames[gLastUsedAbility]; + break; + case 21: // attacker ability + toCpy = gAbilityNames[gAbilitiesPerBank[gBankAttacker]]; + break; + case 22: // target ability + toCpy = gAbilityNames[gAbilitiesPerBank[gBankTarget]]; + break; + case 23: // scripting active ability + toCpy = gAbilityNames[gAbilitiesPerBank[gBattleStruct->scriptingActive]]; + break; + case 24: // effect bank ability + toCpy = gAbilityNames[gAbilitiesPerBank[gEffectBank]]; + break; + case 25: // trainer class name +#ifdef ENGLISH + if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) + toCpy = gTrainerClassNames[GetSecretBaseTrainerNameIndex()]; + else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + toCpy = gTrainerClassNames[get_trainer_class_name_index()]; + else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) + toCpy = gTrainerClassNames[GetEReaderTrainerClassNameIndex()]; + else + toCpy = gTrainerClassNames[gTrainers[gTrainerBattleOpponent].trainerClass]; + break; +#else + if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) + toCpy = de_sub_8041024(gTrainerBattleOpponent, 0); + else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + toCpy = de_sub_8041024(BATTLE_TYPE_BATTLE_TOWER, 0); + else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) + toCpy = de_sub_8041024(BATTLE_TYPE_EREADER_TRAINER, 0); + else + toCpy = de_sub_8041024(0, gTrainerBattleOpponent); + break; +#endif + case 26: // trainer name + if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) + { + memset(text, 0xFF, 8); + memcpy(text, ewram17002, 7); + toCpy = text; + } + else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) + { + get_trainer_name(text); + toCpy = text; + } + else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER) + { + SetEReaderTrainerName(text); + toCpy = text; + } + else + toCpy = gTrainers[gTrainerBattleOpponent].trainerName; + break; + case 27: // link player name? + toCpy = gLinkPlayers[multiplayerID].name; + break; + case 28: // link partner name? + toCpy = gLinkPlayers[sub_803FC34(2 ^ gLinkPlayers[multiplayerID].lp_field_18)].name; + break; + case 29: // link opponent 1 name? + toCpy = gLinkPlayers[sub_803FC34(1 ^ gLinkPlayers[multiplayerID].lp_field_18)].name; + break; + case 30: // link opponent 2 name? + toCpy = gLinkPlayers[sub_803FC34(3 ^ gLinkPlayers[multiplayerID].lp_field_18)].name; + break; + case 31: // link scripting active name + toCpy = gLinkPlayers[sub_803FC34(gBattleStruct->scriptingActive)].name; + break; + case 32: // player name + toCpy = gSaveBlock2.playerName; + break; + case 33: // ? + toCpy = GetTrainerLoseText(); + break; + case 34: // ? + HANDLE_NICKNAME_STRING_CASE(gBattleStruct->scriptingActive, gBattleStruct->unk1605E) + break; + case 35: // lanette pc + if (FlagGet(FLAG_SYS_PC_LANETTE)) + toCpy = BattleText_Lanette; + else + toCpy = BattleText_Someone; + break; + case 38: + if (GetBattlerSide(gBankAttacker) == 0) + toCpy = BattleText_Ally2; + else + toCpy = BattleText_Foe3; + break; + case 39: + if (GetBattlerSide(gBankTarget) == 0) + toCpy = BattleText_Ally2; + else + toCpy = BattleText_Foe3; + break; + case 36: + if (GetBattlerSide(gBankAttacker) == 0) + toCpy = BattleText_Ally; + else + toCpy = BattleText_Foe2; + break; + case 37: + if (GetBattlerSide(gBankTarget) == 0) + toCpy = BattleText_Ally; + else + toCpy = BattleText_Foe2; + break; + case 40: + if (GetBattlerSide(gBankAttacker) == 0) + toCpy = BattleText_Ally3; + else + toCpy = BattleText_Foe4; + break; + case 41: + if (GetBattlerSide(gBankTarget) == 0) + toCpy = BattleText_Ally3; + else + toCpy = BattleText_Foe4; + break; + } + //if (toCpy != NULL) really GF, why did you forget about this? + while (*toCpy != EOS) + { + dst[dstID] = *toCpy; + dstID++; + toCpy++; + } + if (*src == 33) + { + dst[dstID] = 0xFC; + dstID++; + dst[dstID] = 9; + dstID++; + } + } + else + { + dst[dstID] = *src; + dstID++; + } + src++; + } + dst[dstID] = *src; + dstID++; + return dstID; +} + +#define ByteRead16(ptr) ((ptr)[0] | ((ptr)[1] << 8)) +#define ByteRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) + +void StrCpyDecodeBattleTextBuff(u8* src, u8* dst) +{ + u32 srcID = 1; + u32 value = 0; + u8 text[12]; + u16 hword; + + *dst = EOS; + while (src[srcID] != EOS) + { + switch (src[srcID]) + { + case 0: // battle string + hword = ByteRead16(&src[srcID + 1]); +#ifdef GERMAN + if (hword == 209 || hword == 211) + srcID += 3; +#endif + StringAppend(dst, gBattleStringsTable[hword - BATTLESTRING_TO_SUB]); + srcID += 3; + break; + case 1: // int to string + switch (src[srcID + 1]) + { + case 1: + value = src[srcID + 3]; + break; + case 2: + value = ByteRead16(&src[srcID + 3]); + break; + case 4: + value = ByteRead32(&src[srcID + 3]); + break; + } + ConvertIntToDecimalStringN(dst, value, 0, src[srcID + 2]); + srcID += src[srcID + 1] + 3; + break; + case 2: // move name + StringAppend(dst, gMoveNames[ByteRead16(&src[srcID + 1])]); + srcID += 3; + break; + case 3: // type name + StringAppend(dst, gTypeNames[src[srcID + 1]]); + srcID += 2; + break; + case 4: // poke nick with prefix +#ifdef ENGLISH + if (GetBattlerSide(src[srcID + 1]) == 0) + { + GetMonData(&gPlayerParty[src[srcID + 2]], MON_DATA_NICKNAME, text); + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + StringAppend(dst, BattleText_Foe); + else + StringAppend(dst, BattleText_Wild); + GetMonData(&gEnemyParty[src[srcID + 2]], MON_DATA_NICKNAME, text); + } + StringGetEnd10(text); + StringAppend(dst, text); +#else + if (GetBattlerSide(src[srcID + 1]) == 0) + { + GetMonData(&gPlayerParty[src[srcID + 2]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + StringAppend(dst, text); + } + else + { + GetMonData(&gEnemyParty[src[srcID + 2]], MON_DATA_NICKNAME, text); + StringGetEnd10(text); + StringAppend(dst, text); + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + StringAppend(dst, BattleText_Foe); + else + StringAppend(dst, BattleText_Wild); + } +#endif + srcID += 3; + break; + case 5: // stats + StringAppend(dst, gUnknown_08400F58[src[srcID + 1]]); + srcID += 2; + break; + case 6: // species name + GetSpeciesName(dst, ByteRead16(&src[srcID + 1])); + srcID += 3; + break; + case 7: // poke nick without prefix + if (GetBattlerSide(src[srcID + 1]) == 0) + GetMonData(&gPlayerParty[src[srcID + 2]], MON_DATA_NICKNAME, dst); + else + GetMonData(&gEnemyParty[src[srcID + 2]], MON_DATA_NICKNAME, dst); + StringGetEnd10(dst); + srcID += 3; + break; + case 8: // flavour table + StringAppend(dst, gUnknown_08400F78[src[srcID + 1]]); + srcID += 2; + break; + case 9: // ability names + StringAppend(dst, gAbilityNames[src[srcID + 1]]); + srcID += 2; + break; + case 10: // item name + { + hword = ByteRead16(&src[srcID + 1]); + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + if (hword == ITEM_ENIGMA_BERRY) + { + if (gLinkPlayers[gBattleStruct->linkPlayerIndex].lp_field_18 == gStringBank) + { + StringCopy(dst, gEnigmaBerries[gStringBank].name); +#ifdef ENGLISH + StringAppend(dst, BattleText_Berry); +#else + de_sub_8073174(dst, BattleText_Berry); +#endif + } + else + StringAppend(dst, BattleText_EnigmaBerry); + } + else + CopyItemName(hword, dst); + } + else + CopyItemName(hword, dst); + srcID += 3; + } + break; + } + } +} + +// Loads one of two text strings into the provided buffer. This is functionally +// unused, since the value loaded into the buffer is not read; it loaded one of +// two particles (either "は" or "の") which works in tandem with sub_8121D74 +// below to effect changes in the meaning of the line. +void sub_8121D1C(u8* textBuff) +{ + s32 counter = 0; + u32 i = 0; + + while (counter != 4) + { + if (gUnknown_084016BC[i] == 0) + counter++; + if (gUnknown_084016BC[i++] == gStringInfo->currentMove) + break; + } + + if (counter >= 0) + { + if (counter <= 2) + StringCopy(textBuff, BattleText_Format10); // is + else if (counter <= 4) + StringCopy(textBuff, BattleText_Format11); // 's + } +} + +// Appends "!" to the text buffer `dst`. In the original Japanese this looked +// into the table of moves at gUnknown_084016BC and varied the line accordingly. +// +// BattleText_Exclamation was a plain "!", used for any attack not on the list. +// It resulted in the translation "'s !". +// +// BattleText_Exclamation2 was "を つかった!". This resulted in the translation +// " used !", which was used for all attacks in English. +// +// BattleText_Exclamation3 was "した!". This was used for those moves whose +// names were verbs, such as Recover, and resulted in translations like " +// recovered itself!". +// +// BattleText_Exclamation4 was "を した!" This resulted in a translation of +// " did an !". +// +// BattleText_Exclamation5 was " こうげき!" This resulted in a translation of +// "'s attack!". +void sub_8121D74(u8* dst) +{ + s32 counter = 0; + s32 i = 0; + + while (*dst != EOS) + dst++; + + while (counter != 4) + { + if (gUnknown_084016BC[i] == 0) + counter++; + if (gUnknown_084016BC[i++] == gStringInfo->currentMove) + break; + } + + switch (counter) + { + case 0: + StringCopy(dst, BattleText_Exclamation2); + break; + case 1: + StringCopy(dst, BattleText_Exclamation3); + break; + case 2: + StringCopy(dst, BattleText_Exclamation4); + break; + case 3: + StringCopy(dst, BattleText_Exclamation5); + break; + case 4: + StringCopy(dst, BattleText_Exclamation); + break; + } +} diff --git a/src/battle_party_menu.c b/src/battle_party_menu.c new file mode 100644 index 000000000..e758b7957 --- /dev/null +++ b/src/battle_party_menu.c @@ -0,0 +1,731 @@ +#include "global.h" +#include "battle_party_menu.h" +#include "battle.h" +#include "item_menu.h" +#include "item_use.h" +#include "main.h" +#include "menu.h" +#include "menu_helpers.h" +#include "palette.h" +#include "party_menu.h" +#include "pokemon.h" +#include "pokemon_summary_screen.h" +#include "rom_8077ABC.h" +#include "rom_8094928.h" +#include "constants/songs.h" +#include "sound.h" +#include "string_util.h" +#include "strings.h" +#include "task.h" +#include "text.h" +#include "ewram.h" + +extern u8 sub_806BD58(u8, u8); +extern void PartyMenuPrintMonsLevelOrStatus(void); +extern void nullsub_13(void); +extern void sub_802E414(void); +extern void sub_80A6DCC(void); +extern u8 *sub_8040D08(); +extern void sub_8040B8C(void); +extern void nullsub_14(); +extern u8 sub_803FBBC(void); + +extern u8 gPlayerPartyCount; +extern u8 gBattlersCount; +extern u16 gBattlerPartyIndexes[]; +extern u8 gBankInMenu; +extern u8 gUnknown_0202E8F4; +extern u8 gUnknown_0202E8F5; +extern u8 gUnknown_0202E8F6; +extern u8 gUnknown_02038470[3]; +extern u8 gUnknown_02038473; +extern u8 gUnknown_020384F0; +extern void (*gPokemonItemUseCallback)(); //don't know types yet +extern struct PokemonStorage gPokemonStorage; +extern void nullsub_14(); + +void sub_8094C98(u8, u8); +u8 pokemon_order_func(u8); + +static void sub_8094998(u8[3], u8); +static void sub_8094A74(u8[3], u8, u32); +static void sub_8094D60(void); +static void Task_809527C(u8); +static void Task_80952B4(u8); +static void Task_80952E4(u8); +static void Task_8095330(u8); +static void Task_809538C(void); +static void Task_HandlePopupMenuInput(u8); +static void Task_BattlePartyMenuSummary(u8 taskId); +static void Task_BattlePartyMenuShift(u8 taskId); +static void Task_BattlePartyMenuCancel(u8 taskId); + +static const struct MenuAction2 sBattlePartyMenuActions[] = +{ + {OtherText_Summary, Task_BattlePartyMenuSummary}, + {gOtherText_CancelNoTerminator, Task_BattlePartyMenuCancel}, + {OtherText_Shift, Task_BattlePartyMenuShift}, + {OtherText_SendOut, Task_BattlePartyMenuShift}, +}; +static const u8 Unknown_83B5FEC[] = {2, 0, 1}; //SHIFT, SUMMARY, CANCEL +static const u8 Unknown_83B5FEF[] = {3, 0, 1}; //SEND OUT, SUMMARY, CANCEL +static const u8 Unknown_83B5FF2[] = {0, 1}; //SUMMARY, CANCEL +static const struct PartyPopupMenu sBattlePartyPopupMenus[] = +{ + {ARRAY_COUNT(Unknown_83B5FEC), 9, Unknown_83B5FEC}, + {ARRAY_COUNT(Unknown_83B5FEF), 9, Unknown_83B5FEF}, + {ARRAY_COUNT(Unknown_83B5FF2), 9, Unknown_83B5FF2}, +}; + +void unref_sub_8094928(struct PokemonStorage *ptr) +{ + *ptr = gPokemonStorage; +} + +void unref_sub_8094940(struct PokemonStorage *ptr) +{ + gPokemonStorage = *ptr; +} + +void sub_8094958(void) +{ + sub_8094998(gUnknown_02038470, sub_803FBBC()); +} + +void sub_8094978(u8 arg1, u8 arg2) +{ + sub_8094A74((UNK_201606C_ARRAY) + arg1 * 3, arg2, arg1); +} + +static void sub_8094998(u8 arg[3], u8 player_number) +{ + int i; + u32 pos; + u8 temp[6]; + if (IsLinkDoubleBattle() == TRUE) + { + if (player_number) + { + *arg = 0x30; + arg[1] = 0x45; + arg[2] = 0x12; + } + else + { + *arg = 0x03; + arg[1] = 0x12; + arg[2] = 0x45; + } + } + else + { + if (!IsDoubleBattle()) + { + pos = 1; + *temp = gBattlerPartyIndexes[GetBattlerAtPosition(0)]; + for (i = 0; i <= 5; i++) + if (i != *temp) + temp[pos++] = i; + } + else + { + pos = 2; + *temp = gBattlerPartyIndexes[GetBattlerAtPosition(0)]; + temp[1] = gBattlerPartyIndexes[GetBattlerAtPosition(2)]; + for (i = 0; i <= 5; i++) + if ((i != *temp) && (i != temp[1])) + temp[pos++] = i; + } + for (i = 0; i <= 2; i++) + arg[i] = (temp[i << 1] << 4) | temp[(i << 1) + 1]; + } +} + +static void sub_8094A74(u8 arg[3], u8 player_number, u32 arg3) +{ + int i, j; + u8 temp[6]; + if (!GetBattlerSide(arg3)) + { + i = GetBattlerAtPosition(0); + j = GetBattlerAtPosition(2); + } + else + { + i = GetBattlerAtPosition(1); + j = GetBattlerAtPosition(3); + } + if (IsLinkDoubleBattle() == TRUE) + { + if (player_number) + { + *arg = 0x30; + arg[1] = 0x45; + arg[2] = 0x12; + } + else + { + *arg = 0x03; + arg[1] = 0x12; + arg[2] = 0x45; + } + } + else + { + if (!IsDoubleBattle()) + { + int pos = 1; + *temp = gBattlerPartyIndexes[i]; + for (i = 0; i <= 5; i++) + if (i != *temp) + temp[pos++] = i; + } + else + { + int pos = 2; + *temp = gBattlerPartyIndexes[i]; + temp[1] = gBattlerPartyIndexes[j]; + for (i = 0; i <= 5; i++) + if ((i != *temp) && (i != temp[1])) + temp[pos++] = i; + } + for (i = 0; i <= 2; i++) + arg[i] = (temp[i << 1] << 4) | temp[(i << 1) + 1]; + } +} + +void sub_8094B6C(u8 a, u8 b, u8 c) +{ + s32 i; + s32 j; + u8 temp[6]; + u8 r3; + u8 r7 = 0; + + if (IsLinkDoubleBattle()) + { + u8 *arr = &ewram1606Carr(0, a); + + for (i = 0, j = 0; i < 3; i++) + { + temp[j++] = arr[i] >> 4; + temp[j++] = arr[i] & 0xF; + } + r3 = temp[c]; + for (i = 0; i < 6; i++) + { + if (temp[i] == b) + { + r7 = temp[i]; + temp[i] = r3; + break; + } + } + if (i != 6) + { + temp[c] = r7; + + arr[0] = (temp[0] << 4) | temp[1]; + arr[1] = (temp[2] << 4) | temp[3]; + arr[2] = (temp[4] << 4) | temp[5]; + } + } +} + +u8 sub_8094C20(u8 monIndex) +{ + u8 retVal; + u8 val = monIndex & 1; + + monIndex /= 2; + if (val) + retVal = gUnknown_02038470[monIndex] & 0xF; + else + retVal = gUnknown_02038470[monIndex] >> 4; + return retVal; +} + +void sub_8094C54(u8 a, u8 b) +{ + u8 val = a & 1; + + a /= 2; + if (val) + gUnknown_02038470[a] = (gUnknown_02038470[a] & 0xF0) | b; + else + gUnknown_02038470[a] = (gUnknown_02038470[a] & 0xF) | (b << 4); +} + +void sub_8094C98(u8 a, u8 b) +{ + u8 r4 = sub_8094C20(a); + u8 r1 = sub_8094C20(b); + + sub_8094C54(a, r1); + sub_8094C54(b, r4); +} + +u8 pokemon_order_func(u8 a) +{ + u8 i; + u8 r2; + + for (i = 0, r2 = 0; i < 3; i++) + { + if ((gUnknown_02038470[i] >> 4) == a) + return r2; + r2++; + if ((gUnknown_02038470[i] & 0xF) == a) + return r2; + r2++; + } + return 0; +} + +void pokemon_change_order(void) +{ + u8 i; + + memcpy(ewram1B000.unk0, gPlayerParty, sizeof(gPlayerParty)); + for (i = 0; i < 6; i++) + { + u8 n = pokemon_order_func(i); + + memcpy(&gPlayerParty[n], &ewram1B000.unk0[i], sizeof(struct Pokemon)); + } +} + +static void sub_8094D60(void) +{ + struct Pokemon temp[6]; + u8 i; + + memcpy(temp, gPlayerParty, sizeof(gPlayerParty)); + for (i = 0; i < 6; i++) + { + u8 n = sub_8094C20(i); + + memcpy(&gPlayerParty[n], &temp[i], sizeof(struct Pokemon)); + } +} + +void unref_sub_8094DB0(void) +{ + u8 i; + u8 r4; + + for (i = 1; i < 6; i++) + { + u8 n = sub_8094C20(i); + + if (GetMonData(&gPlayerParty[n], MON_DATA_SPECIES) != 0 + && GetMonData(&gPlayerParty[n], MON_DATA_HP) != 0) + { + r4 = sub_8094C20(0); + sub_8094C98(0, i); + SwapPokemon(&gPlayerParty[r4], &gPlayerParty[n]); + break; + } + } +} + +void sub_8094E20(u8 a) +{ + gPaletteFade.bufferTransferDisabled = TRUE; + gUnknown_02038473 = a; + nullsub_14(); + pokemon_change_order(); + OpenPartyMenu(PARTY_MENU_TYPE_BATTLE, 0xFF); +} + +void sub_8094E4C(void) +{ + sub_8094E20(3); +} + +bool8 SetUpBattlePartyMenu(void) +{ + switch (EWRAM_1B000.setupState) + //switch (ewram1B000.unk264[0]) + { + case 0: + //TODO: try to get rid of this duplicate code + if (IsLinkDoubleBattle() == TRUE) + { + if (EWRAM_1B000.monIndex != 6) + { + TryCreatePartyMenuMonIcon(EWRAM_1B000.menuHandlerTaskId, EWRAM_1B000.monIndex, &gPlayerParty[EWRAM_1B000.monIndex]); + EWRAM_1B000.monIndex++; + } + else + { + EWRAM_1B000.monIndex = 0; + EWRAM_1B000.setupState++; + } + } + else + { + if (EWRAM_1B000.monIndex < 6) + { + TryCreatePartyMenuMonIcon(EWRAM_1B000.menuHandlerTaskId, EWRAM_1B000.monIndex, &gPlayerParty[EWRAM_1B000.monIndex]); + EWRAM_1B000.monIndex++; + } + else + { + EWRAM_1B000.monIndex = 0; + EWRAM_1B000.setupState++; + } + } + break; + case 1: + LoadHeldItemIconGraphics(); + EWRAM_1B000.setupState++; + break; + case 2: + CreateHeldItemIcons_806DC34(EWRAM_1B000.menuHandlerTaskId); + EWRAM_1B000.setupState++; + break; + case 3: + if (sub_806BD58(EWRAM_1B000.menuHandlerTaskId, EWRAM_1B000.monIndex) == 1) + { + EWRAM_1B000.monIndex = 0; + EWRAM_1B000.setupState++; + } + else + EWRAM_1B000.monIndex++; + break; + case 4: + PartyMenuPrintMonsLevelOrStatus(); + EWRAM_1B000.setupState++; + break; + case 5: + PrintPartyMenuMonNicknames(); + EWRAM_1B000.setupState++; + break; + case 6: + PartyMenuTryPrintMonsHP(); + EWRAM_1B000.setupState++; + break; + case 7: + nullsub_13(); + EWRAM_1B000.setupState++; + break; + case 8: + PartyMenuDrawHPBars(); + EWRAM_1B000.setupState++; + break; + case 9: + if (DrawPartyMonBackground(EWRAM_1B000.monIndex) == 1) + { + EWRAM_1B000.monIndex = 0; + EWRAM_1B000.setupState++; + } + else + EWRAM_1B000.monIndex++; + break; + case 10: + if (gUnknown_02038473 == 3) + { + if (GetItemEffectType(gSpecialVar_ItemId) == 10) + ewram1B000.promptTextId = 0xFF; + else + ewram1B000.promptTextId = 3; + } + return TRUE; + } + return FALSE; +} + +static void sub_8095050(u8 a, u8 b) +{ + if (!GetMonData(&gPlayerParty[b], MON_DATA_IS_EGG)) + { + if (gUnknown_02038473 == 1) + { + gTasks[EWRAM_1B000.menuHandlerTaskId].data[4] = 1; + gTasks[EWRAM_1B000.menuHandlerTaskId].data[5] = 1; + } + else + { + gTasks[EWRAM_1B000.menuHandlerTaskId].data[4] = 0; + gTasks[EWRAM_1B000.menuHandlerTaskId].data[5] = 0; + } + } + else + { + gTasks[EWRAM_1B000.menuHandlerTaskId].data[4] = 2; + gTasks[EWRAM_1B000.menuHandlerTaskId].data[5] = 2; + } + + ShowPartyPopupMenu(gTasks[a].data[4], sBattlePartyPopupMenus, sBattlePartyMenuActions, 0); +} + +void HandleBattlePartyMenu(u8 taskId) +{ + if (!gPaletteFade.active) + { + if (gUnknown_02038473 == 3 && GetItemEffectType(gSpecialVar_ItemId) == 10) + { + gPokemonItemUseCallback(taskId, gSpecialVar_ItemId, Task_80952E4); + return; + } + + switch (HandleDefaultPartyMenuInput(taskId)) + { + case A_BUTTON: + if (gUnknown_02038473 == 3) + { + if (GetMonData(&gPlayerParty[sub_806CA38(taskId)], MON_DATA_IS_EGG)) + PlaySE(SE_HAZURE); + else + { + sub_806D5A4(); + gPokemonItemUseCallback(taskId, gSpecialVar_ItemId, Task_80952E4); + } + } + else + { + PlaySE(SE_SELECT); + GetMonNickname(&gPlayerParty[sub_806CA38(taskId)], gStringVar1); + sub_8095050(taskId, sub_806CA38(taskId)); + SetTaskFuncWithFollowupFunc(taskId, Task_HandlePopupMenuInput, HandleBattlePartyMenu); + } + break; + case B_BUTTON: + if (gUnknown_02038473 == 1) + PlaySE(SE_HAZURE); + else + { + PlaySE(SE_SELECT); + if (gUnknown_02038473 == 3) + { + gUnknown_0202E8F4 = 0; + gTasks[taskId].func = Task_80952E4; + } + else + { + gUnknown_0202E8F4 = 0; + gTasks[taskId].func = Task_809527C; + } + } + break; + } + } +} + +static void Task_809527C(u8 taskId) +{ + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); + gTasks[taskId].func = Task_80952B4; +} + +static void Task_80952B4(u8 taskId) +{ + if (!gPaletteFade.active) + { + sub_8094D60(); + DestroyTask(taskId); + SetMainCallback2(sub_802E414); + } +} + +static void Task_80952E4(u8 taskId) +{ + if (gUnknown_0202E8F4 != 0) + Task_809527C(taskId); + else + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); + gTasks[taskId].func = Task_8095330; + } +} + +static void Task_8095330(u8 taskId) +{ + if (!gPaletteFade.active) + { + sub_8094D60(); + DestroyTask(taskId); + sub_80A6DCC(); + } +} + +static void Task_809535C(void) +{ + gPaletteFade.bufferTransferDisabled = TRUE; + SetPartyMenuSettings(PARTY_MENU_TYPE_BATTLE, 0xFF, HandleBattlePartyMenu, 5); + SetMainCallback2(Task_809538C); +} + +static void Task_809538C(void) +{ + do + { + if (InitPartyMenu() == TRUE) + { + sub_806C994(EWRAM_1B000.menuHandlerTaskId, gUnknown_020384F0); + ChangePartyMenuSelection(EWRAM_1B000.menuHandlerTaskId, 0); + GetMonNickname(&gPlayerParty[gUnknown_020384F0], gStringVar1); + sub_8095050(EWRAM_1B000.menuHandlerTaskId, gUnknown_020384F0); + SetTaskFuncWithFollowupFunc(EWRAM_1B000.menuHandlerTaskId, Task_HandlePopupMenuInput, HandleBattlePartyMenu); + SetMainCallback2(CB2_PartyMenuMain); + return; + } + } while (sub_80F9344() != 1); +} + +static void Task_HandlePopupMenuInput(u8 taskId) +{ + TaskFunc func; + + if (!gPaletteFade.active) + { + if (gMain.newAndRepeatedKeys & DPAD_UP) + { + PlaySE(SE_SELECT); + Menu_MoveCursor(-1); + return; + } + if (gMain.newAndRepeatedKeys & DPAD_DOWN) + { + PlaySE(SE_SELECT); + Menu_MoveCursor(1); + return; + } + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + func = PartyMenuGetPopupMenuFunc(gTasks[taskId].data[4], + sBattlePartyPopupMenus, + sBattlePartyMenuActions, + Menu_GetCursorPos()); + func(taskId); + return; + } + if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + Task_BattlePartyMenuCancel(taskId); + return; + } + } +} + +static void Task_80954C0(u8 taskId) +{ + if (gUnknown_0202E8F6 == 0) + Task_BattlePartyMenuCancel(taskId); +} + +static void Task_ShowSummaryScreen(u8 taskId) +{ + u8 partySelection = sub_806CA38(taskId); + + if (!gPaletteFade.active) + { + DestroyTask(taskId); + EWRAM_1B000.unk262 = 1; + ShowPokemonSummaryScreen(gPlayerParty, partySelection, gPlayerPartyCount - 1, Task_809535C, PSS_MODE_NO_MOVE_ORDER_EDIT); + } +} + +static void Task_BattlePartyMenuSummary(u8 taskId) +{ + sub_806CA38(taskId); //an unused variable was probably set with this. + gTasks[taskId].func = Task_ShowSummaryScreen; + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); +} + +static void Task_BattlePartyMenuShift(u8 taskId) +{ + u8 partySelection; + u8 i; + u8 r4; + + ClosePartyPopupMenu(gTasks[taskId].data[4], sBattlePartyPopupMenus); + partySelection = sub_806CA38(taskId); + if (IsLinkDoubleBattle() == TRUE && (partySelection == 1 || partySelection == 4 || partySelection == 5)) + { + sub_806D5A4(); + StringCopy(gStringVar1, sub_8040D08()); + StringExpandPlaceholders(gStringVar4, gOtherText_CantSwitchPokeWithYours); + sub_806E834(gStringVar4, 0); + gTasks[taskId].func = Task_80954C0; + return; + } + if (GetMonData(&gPlayerParty[partySelection], MON_DATA_HP) == 0) + { + sub_806D5A4(); + GetMonNickname(&gPlayerParty[partySelection], gStringVar1); + StringExpandPlaceholders(gStringVar4, gOtherText_NoEnergyLeft); + sub_806E834(gStringVar4, 0); + gTasks[taskId].func = Task_80954C0; + return; + } + for (i = 0; i < gBattlersCount; i++) + { + if (GetBattlerSide(i) == 0 + && sub_8094C20(partySelection) == gBattlerPartyIndexes[i]) + { + sub_806D5A4(); + GetMonNickname(&gPlayerParty[partySelection], gStringVar1); + StringExpandPlaceholders(gStringVar4, gOtherText_AlreadyBattle); + sub_806E834(gStringVar4, 0); + gTasks[taskId].func = Task_80954C0; + return; + } + } + if (GetMonData(&gPlayerParty[partySelection], MON_DATA_IS_EGG)) + { + sub_806D5A4(); + StringExpandPlaceholders(gStringVar4, gOtherText_EGGCantBattle); + sub_806E834(gStringVar4, 0); + gTasks[taskId].func = Task_80954C0; + return; + } + if (sub_8094C20(partySelection) == EWRAM_1609D) + { + sub_806D5A4(); + GetMonNickname(&gPlayerParty[partySelection], gStringVar1); + StringExpandPlaceholders(gStringVar4, gOtherText_AlreadySelected); + sub_806E834(gStringVar4, 0); + gTasks[taskId].func = Task_80954C0; + return; + } + if (gUnknown_02038473 == 4) + { + sub_806D5A4(); + sub_8040B8C(); + sub_806E834(gStringVar4, 0); + gTasks[taskId].func = Task_80954C0; + return; + } + if (gUnknown_02038473 == 2) + { + u8 r0; + u8 r4 = gBankInMenu; + + sub_806D5A4(); + r0 = pokemon_order_func(gBattlerPartyIndexes[r4]); + GetMonNickname(&gPlayerParty[r0], gStringVar1); + StringExpandPlaceholders(gStringVar4, gOtherText_CantBeSwitched); + sub_806E834(gStringVar4, 0); + gTasks[taskId].func = Task_80954C0; + return; + } + gUnknown_0202E8F5 = sub_8094C20(partySelection); + gUnknown_0202E8F4 = 1; + r4 = pokemon_order_func(gBattlerPartyIndexes[gBankInMenu]); + sub_8094C98(r4, partySelection); + SwapPokemon(&gPlayerParty[r4], &gPlayerParty[partySelection]); + gTasks[taskId].func = Task_809527C; +} + +static void Task_BattlePartyMenuCancel(u8 taskId) +{ + Menu_DestroyCursor(); + ClosePartyPopupMenu(gTasks[taskId].data[4], sBattlePartyPopupMenus); + gTasks[taskId].data[4] = gTasks[taskId].data[5]; + PrintPartyMenuPromptText(0, 0); + SwitchTaskToFollowupFunc(taskId); +} diff --git a/src/battle_records.c b/src/battle_records.c new file mode 100644 index 000000000..d94d88032 --- /dev/null +++ b/src/battle_records.c @@ -0,0 +1,382 @@ +#include "global.h" +#include "battle_records.h" +#include "constants/game_stat.h" +#include "link.h" +#include "menu.h" +#include "overworld.h" +#include "string_util.h" +#include "strings2.h" +#include "trainer_card.h" + +struct DebugStruct1 +{ + u16 var0; + u8 var1[10]; +}; + +extern struct LinkPlayerEventObject gLinkPlayerEventObjects[4]; +extern u8 gBattleOutcome; + +#if DEBUG +const struct DebugStruct1 gUnknown_Debug_4245CC[] = +{ + { 1, _("NUMBER1") }, + { 2, _("ナンバー2") }, + { 3, _("ナンバー3") }, + { 4, _("ナンバー4") }, + { 5, _("ナンバー5") }, + { 6, _("ナンバー6") }, + { 7, _("ナンバー7") }, +}; + +const struct {u8 unk0; u8 unk1;} gUnknown_Debug_8424620[] = +{ + { 1, 1 }, + { 2, 1 }, + { 3, 1 }, +}; +#endif + +static void InitLinkBattleRecord(struct LinkBattleRecord *record) +{ + CpuFill16(0, record, sizeof(struct LinkBattleRecord)); + record->name[0] = 0xFF; + record->trainerId = 0; + record->wins = 0; + record->losses = 0; + record->draws = 0; +} + +static void InitLinkBattleRecords_(struct LinkBattleRecord *records) +{ + int i; + for (i = 0; i < 5; i++) + { + InitLinkBattleRecord(records + i); + } + SetGameStat(GAME_STAT_LINK_BATTLE_WINS, 0); + SetGameStat(GAME_STAT_LINK_BATTLE_LOSSES, 0); + SetGameStat(GAME_STAT_LINK_BATTLE_DRAWS, 0); +} + +static int GetLinkBattleRecordTotalBattles(struct LinkBattleRecord *record) +{ + return record->wins + record->losses + record->draws; +} + +static int FindLinkBattleRecord(struct LinkBattleRecord *records, const u8 *name, u16 trainerId) +{ + int i; + + for (i = 0; i < 5; i++) + { + memcpy(gStringVar1, records[i].name, 7); + gStringVar1[7] = EOS; + if (!StringCompareWithoutExtCtrlCodes(gStringVar1, name) && records[i].trainerId == trainerId) + return i; + } + + return 5; +} + +static void SortLinkBattleRecords(struct LinkBattleRecord *records) +{ + int i, j; + + for (i = 4; i > 0; i--) + { + for (j = i - 1; j >= 0; j--) + { + int totalBattlesI = GetLinkBattleRecordTotalBattles(records + i); + int totalBattlesJ = GetLinkBattleRecordTotalBattles(records + j); + + if (totalBattlesI > totalBattlesJ) + { + struct LinkBattleRecord temp = *(records + i); + *(records + i) = *(records + j); + *(records + j) = temp; + } + } + } +} + +static void UpdateLinkBattleRecord(struct LinkBattleRecord *record, int battleOutcome) +{ + switch (battleOutcome) + { + case 1: + record->wins++; + if (record->wins > 9999) + record->wins = 9999; + break; + case 2: + record->losses++; + if (record->losses > 9999) + record->losses = 9999; + break; + case 3: + record->draws++; + if (record->draws > 9999) + record->draws = 9999; + break; + } +} + +static void UpdateLinkBattleGameStats(int battleOutcome) +{ + u8 stat; + + switch (battleOutcome) + { + case 1: + stat = GAME_STAT_LINK_BATTLE_WINS; + break; + case 2: + stat = GAME_STAT_LINK_BATTLE_LOSSES; + break; + case 3: + stat = GAME_STAT_LINK_BATTLE_DRAWS; + break; + default: + return; + } + + if (GetGameStat(stat) < 9999) + IncrementGameStat(stat); +} + +static void UpdateLinkBattleRecords_(struct LinkBattleRecord *records, const u8 *name, u16 trainerId, int battleOutcome, u8 language) +{ + int index; + UpdateLinkBattleGameStats(battleOutcome); + SortLinkBattleRecords(records); + index = FindLinkBattleRecord(records, name, trainerId); + if (index == 5) + { + index = 4; + InitLinkBattleRecord(records + index); + if (language == LANGUAGE_JAPANESE) + { + records[index].name[0] = EXT_CTRL_CODE_BEGIN; + records[index].name[1] = 0x15; + StringCopyN(records[index].name + 2, name, 5); + } + else + { + StringCopyN(records[index].name, name, 7); + } + + // needed block to match + { + struct LinkBattleRecord *record = records + index; + record->trainerId = trainerId; + } + } + UpdateLinkBattleRecord(records + index, battleOutcome); + SortLinkBattleRecords(records); +} + +void InitLinkBattleRecords(void) +{ + InitLinkBattleRecords_(gSaveBlock1.linkBattleRecords); +} + +static void IncTrainerCardWins(int id) +{ + u16 *wins = &gTrainerCards[id].linkBattleWins; + (*wins)++; + if (*wins > 9999) + *wins = 9999; +} + +static void IncTrainerCardLosses(int id) +{ + u16 *losses = &gTrainerCards[id].linkBattleLosses; + (*losses)++; + if (*losses > 9999) + *losses = 9999; +} + +static void UpdateTrainerCardWinsLosses(int id) +{ + switch (gBattleOutcome) + { + case 1: + IncTrainerCardWins(id ^ 1); + IncTrainerCardLosses(id); + break; + case 2: + IncTrainerCardLosses(id ^ 1); + IncTrainerCardWins(id); + break; + } +} + +void UpdateLinkBattleRecords(int id) +{ + UpdateTrainerCardWinsLosses(id); + UpdateLinkBattleRecords_( + gSaveBlock1.linkBattleRecords, + gTrainerCards[id].playerName, + gTrainerCards[id].trainerId, + gBattleOutcome, + gLinkPlayers[gLinkPlayerEventObjects[id].linkPlayerId].language); +} + +#if DEBUG +void debug_sub_81257E0(void) +{ + u32 i; + + InitLinkBattleRecords(); + for (i = 0; i < 3; i++) + { + u32 id = gUnknown_Debug_8424620[i].unk0 - 1; + + UpdateLinkBattleRecords_( + gSaveBlock1.linkBattleRecords, + gUnknown_Debug_4245CC[id].var1, + gUnknown_Debug_4245CC[id].var0, + gUnknown_Debug_8424620[i].unk1, + gLinkPlayers[gLinkPlayerEventObjects[id].linkPlayerId].language); + } +} +#endif + +static void PrintLinkBattleWinsLossesDraws(struct LinkBattleRecord *records) +{ + ConvertIntToDecimalStringN_DigitWidth6(gStringVar1, GetGameStat(GAME_STAT_LINK_BATTLE_WINS), STR_CONV_MODE_RIGHT_ALIGN, 4); + ConvertIntToDecimalStringN_DigitWidth6(gStringVar2, GetGameStat(GAME_STAT_LINK_BATTLE_LOSSES), STR_CONV_MODE_RIGHT_ALIGN, 4); + ConvertIntToDecimalStringN_DigitWidth6(gStringVar3, GetGameStat(GAME_STAT_LINK_BATTLE_DRAWS), STR_CONV_MODE_RIGHT_ALIGN, 4); + Menu_PrintText(gOtherText_WinRecord, 3, 3); +} + +static void PrintLinkBattleRecord(struct LinkBattleRecord *record, u8 y) +{ + if (!record->wins && !record->losses && !record->draws) + { + u8 buffer[16]; + buffer[0] = EXT_CTRL_CODE_BEGIN; + buffer[1] = 0x14; + buffer[2] = 6; + buffer[3] = EXT_CTRL_CODE_BEGIN; + buffer[4] = 0x11; + buffer[5] = 1; + StringCopy(buffer + 6, gOtherText_SevenDashes); + Menu_PrintText(buffer, 3, y); + StringCopy(buffer + 6, gOtherText_FourDashes); + Menu_PrintText(buffer, 11, y); + Menu_PrintText(buffer, 17, y); + Menu_PrintText(buffer, 23, y); + } + else + { + StringFillWithTerminator(gStringVar1, 8); + StringCopyN(gStringVar1, record->name, 7); + Menu_PrintText(gStringVar1, 3, y); + gStringVar1[0] = EXT_CTRL_CODE_BEGIN; + gStringVar1[1] = 0x14; + gStringVar1[2] = 6; + ConvertIntToDecimalStringN(gStringVar1 + 3, record->wins, STR_CONV_MODE_RIGHT_ALIGN, 4); + Menu_PrintText(gStringVar1, 11, y); + ConvertIntToDecimalStringN(gStringVar1 + 3, record->losses, STR_CONV_MODE_RIGHT_ALIGN, 4); + Menu_PrintText(gStringVar1, 17, y); + ConvertIntToDecimalStringN(gStringVar1 + 3, record->draws, STR_CONV_MODE_RIGHT_ALIGN, 4); + Menu_PrintText(gStringVar1, 23, y); + } +} + +void ShowLinkBattleRecords(void) +{ + s32 i; + Menu_DrawStdWindowFrame(1, 0, 28, 18); + MenuPrint_Centered(gOtherText_BattleResults, 0, 1, 240); + + PrintLinkBattleWinsLossesDraws(gSaveBlock1.linkBattleRecords); +#if ENGLISH + Menu_PrintText(gOtherText_WinLoseDraw, 12, 6); +#elif GERMAN + Menu_PrintTextPixelCoords(gOtherText_WinLoseDraw, 88, 48, 1); +#endif + + for (i = 0; i < 5; i++) + { + PrintLinkBattleRecord(&gSaveBlock1.linkBattleRecords[i], 6 + (i + 1) * 2); + } +} + +static bool32 sub_8110494(u8 level) +{ + struct BattleTowerData *battleTower = &gSaveBlock2.battleTower; + + switch (battleTower->var_4AE[level]) + { + case 0: + return FALSE; + case 1: + return FALSE; + case 2: + return TRUE; + case 4: + return FALSE; + case 3: + return TRUE; + case 5: + return FALSE; + case 6: + return TRUE; + default: + return FALSE; + } +} + +static void PrintWinStreak(const u8 *str, u16 streak, u8 left, u8 top) +{ + Menu_PrintText(str, left, top); + if (streak > 9999) + streak = 9999; + AlignInt1InMenuWindow(gStringVar1, streak, 24, 1); + Menu_PrintText(gOtherText_WinStreak, left + 7, top); +} + +static void PrintRecordWinStreak(u8 level, u8 left, u8 top) +{ + struct BattleTowerData *battleTower = &gSaveBlock2.battleTower; + u16 winStreak = battleTower->recordWinStreaks[level]; + PrintWinStreak(gOtherText_Record, winStreak, left, top); +} + +static u16 GetLastWinStreak(u8 level) +{ + u16 winStreak = gSaveBlock2.battleTower.currentWinStreaks[level]; + if (winStreak > 9999) + winStreak = 9999; + + return winStreak; +} + +static void PrintLastWinStreak(u8 level, u8 left, u8 top) +{ + u16 winStreak = GetLastWinStreak(level); + if (sub_8110494(level) == TRUE) + PrintWinStreak(gOtherText_Current, winStreak, left, top); + else + PrintWinStreak(gOtherText_Prev, winStreak, left, top); +} + +void ShowBattleTowerRecords(void) +{ + u16 i; + Menu_DrawStdWindowFrame(3, 1, 27, 17); + MenuPrint_Centered(gOtherText_BattleTowerResults, 3, 2, 0xC8); + Menu_PrintText(gOtherText_Lv50, 5, 6); + Menu_PrintText(gOtherText_Lv100, 5, 12); + for (i = 5; i < 26; i++) + { + sub_8071F60(CHAR_HYPHEN, i, 10); + } + PrintLastWinStreak(0, 10, 6); + PrintRecordWinStreak(0, 10, 8); + PrintLastWinStreak(1, 10, 12); + PrintRecordWinStreak(1, 10, 14); +} diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c new file mode 100644 index 000000000..a84e16116 --- /dev/null +++ b/src/battle_script_commands.c @@ -0,0 +1,15941 @@ +#include "global.h" +#include "battle.h" +#include "battle_message.h" +#include "battle_string_ids.h" +#include "battle_script_commands.h" +#include "battle_util.h" +#include "constants/battle_move_effects.h" +#include "constants/moves.h" +#include "constants/abilities.h" +#include "item.h" +#include "constants/items.h" +#include "data2.h" +#include "constants/hold_effects.h" +#include "random.h" +#include "rom3.h" +#include "constants/species.h" +#include "pokemon.h" +#include "text.h" +#include "palette.h" +#include "main.h" +#include "constants/songs.h" +#include "sound.h" +#include "task.h" +#include "decompress.h" +#include "pokemon_summary_screen.h" +#include "naming_screen.h" +#include "ewram.h" +#include "util.h" + +// TODO: put this into battle_controllers.h + +#define RET_VALUE_LEVELLED_UP 11 + +enum +{ + CONTROLLER_GETMONDATA, + CONTROLLER_GETRAWMONDATA, + CONTROLLER_SETMONDATA, + CONTROLLER_SETRAWMONDATA, + CONTROLLER_LOADMONSPRITE, + CONTROLLER_SWITCHINANIM, + CONTROLLER_RETURNMONTOBALL, + CONTROLLER_DRAWTRAINERPIC, + CONTROLLER_TRAINERSLIDE, + CONTROLLER_TRAINERSLIDEBACK, + CONTROLLER_FAINTANIMATION, + CONTROLLER_PALETTEFADE, + CONTROLLER_SUCCESSBALLTHROWANIM, + CONTROLLER_BALLTHROWANIM, + CONTROLLER_PAUSE, + CONTROLLER_MOVEANIMATION, + CONTROLLER_PRINTSTRING, + CONTROLLER_PRINTSTRINGPLAYERONLY, + CONTROLLER_CHOOSEACTION, + CONTROLLER_UNKNOWNYESNOBOX, + CONTROLLER_CHOOSEMOVE, + CONTROLLER_OPENBAG, + CONTROLLER_CHOOSEPOKEMON, + CONTROLLER_23, + CONTROLLER_HEALTHBARUPDATE, + CONTROLLER_EXPUPDATE, + CONTROLLER_STATUSICONUPDATE, + CONTROLLER_STATUSANIMATION, + CONTROLLER_STATUSXOR, + CONTROLLER_DATATRANSFER, + CONTROLLER_DMA3TRANSFER, + CONTROLLER_31, + CONTROLLER_32, + CONTROLLER_TWORETURNVALUES, + CONTROLLER_CHOSENMONRETURNVALUE, + CONTROLLER_ONERETURNVALUE, + CONTROLLER_ONERETURNVALUE_DUPLICATE, + CONTROLLER_37, + CONTROLLER_38, + CONTROLLER_39, + CONTROLLER_40, + CONTROLLER_HITANIMATION, + CONTROLLER_42, + CONTROLLER_EFFECTIVENESSSOUND, + CONTROLLER_PLAYFANFAREORBGM, + CONTROLLER_FAINTINGCRY, + CONTROLLER_INTROSLIDE, + CONTROLLER_INTROTRAINERBALLTHROW, + CONTROLLER_DRAWPARTYSTATUSSUMMARY, + CONTROLLER_49, + CONTROLLER_50, + CONTROLLER_SPRITEINVISIBILITY, + CONTROLLER_BATTLEANIMATION, + CONTROLLER_LINKSTANDBYMSG, + CONTROLLER_RESETACTIONMOVESELECTION, + CONTROLLER_55, + /*new controllers should go here*/ + CONTROLLER_TERMINATOR_NOP, + CONTROLLER_CMDS_COUNT +}; + +//extern needed variables +extern u8 gUnknown_02023A14_50; +extern u8 gCritMultiplier; +extern s32 gBattleMoveDamage; +extern u32 gStatuses3[MAX_BATTLERS_COUNT]; +extern u16 gBattleTypeFlags; +extern const struct BaseStats gBaseStats[]; +extern struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT]; +extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT]; +extern u8 gActiveBattler; +extern u32 gBattleExecBuffer; +extern u8 gBattlersCount; +extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; +extern u8 gBanksByTurnOrder[MAX_BATTLERS_COUNT]; +extern u8 gActionsByTurnOrder[MAX_BATTLERS_COUNT]; +extern u16 gCurrentMove; +extern u8 gLastUsedAbility; +extern u16 gBattleWeather; +extern u8 gStringBank; +extern u8 gEffectBank; +extern u8 gAbsentBattlerFlags; +extern u8 gMultiHitCounter; +extern u16 gLastUsedMove[4]; +extern u16 gLockedMoves[4]; +extern u16 gChosenMovesByBanks[4]; +extern u16 gSideAffecting[2]; +extern u16 gPauseCounterBattle; +extern u16 gPaydayMoney; +extern u16 gRandomTurnNumber; +extern u8 gBattleOutcome; +extern u8 gBattleTerrain; +extern u16 gTrainerBattleOpponent; +extern u8 gBankAttacker; +extern u8 gBankTarget; +extern const u8* gBattlescriptCurrInstr; +extern u8 gCurrMovePos; +extern u8 gCurrentActionFuncId; +extern u32 gHitMarker; +extern u8 gMoveResultFlags; +extern u8 gBattleCommunication[]; +extern u16 gLastLandedMoves[4]; +extern u16 gLastHitByType[4]; +extern u8 gStringBank; +extern u16 gDynamicBasePower; +extern const u8 gTypeEffectiveness[]; +extern u16 gLastUsedItem; +extern u16 gBattleMovePower; +extern s32 gHpDealt; +extern s32 gTakenDmg[MAX_BATTLERS_COUNT]; +extern u8 gTakenDmgBanks[MAX_BATTLERS_COUNT]; +extern const u16 gMissStringIds[]; +extern u8 gSentPokesToOpponent[2]; +extern u8 gBank1; +extern u16 gExpShareExp; +extern u8 gBattleTextBuff1[]; +extern u8 gBattleTextBuff2[]; +extern u8 gBattleTextBuff3[]; +extern u8 gLeveledUpInBattle; +extern void (*gBattleMainFunc)(void); +extern struct Window gUnknown_03004210; +extern const u8 BattleText_YesNo[]; +extern u8 gPlayerPartyCount; +extern u16 gMoveToLearn; //move to learn +extern const u8 gTrainerMoney[]; +extern u16 gRandomMove; +extern u8* gBattleScriptsForMoveEffects[]; +extern u16 gChosenMove; //last used move in battle +extern u8 gBankInMenu; +extern u8 gActionForBanks[4]; +extern u16 gUnknown_02024C2C[4]; //last used moves 2, used by sketch +extern u16 gUnknown_02024C4C[4]; //last used moves by banks, another one +extern u8 gCurrentTurnActionNumber; +extern u16 gTrappingMoves[]; + +extern u8 BattleScript_MoveEffectSleep[]; +extern u8 BattleScript_MoveEffectPoison[]; +extern u8 BattleScript_MoveEffectBurn[]; +extern u8 BattleScript_MoveEffectFreeze[]; +extern u8 BattleScript_MoveEffectParalysis[]; +extern u8 BattleScript_MoveEffectToxic[]; +extern u8 BattleScript_MoveEffectConfusion[]; +extern u8 BattleScript_MoveEffectUproar[]; +extern u8 BattleScript_MoveEffectWrap[]; +extern u8 BattleScript_MoveEffectPayDay[]; +extern u8 BattleScript_MoveEffectRecoil33[]; + +//extern functions +u8 AtkCanceller_UnableToUseMove(void); +void PressurePPLose(u8 bank_atk, u8 bank_def, u16 move); +void CancelMultiTurnMoves(u8 bank); +void BattleScriptPush(const u8* BS_ptr); +void BattleScriptPushCursor(void); +void RecordAbilityBattle(u8 bank, u8 ability); +void RecordItemBattle(u8 bank, u8 holdEffect); +static bool8 IsTwoTurnsMove(u16 move); +static void TrySetDestinyBondToHappen(void); +static void CheckWonderGuardAndLevitate(void); +u8 GetBattlerPosition(u8 bank); +u8 GetBattlerSide(u8 bank); +u8 GetBattleBank(u8 bankValue); +s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 a4, u16 powerOverride, u8 typeOverride, u8 bank_atk, u8 bank_def); +static u8 AttacksThisTurn(u8 bank, u16 move); //Note: returns 1 if it's a charging turn, otherwise 2 +void UndoEffectsAfterFainting(void); +void BattleStopLowHpSound(void); +void PlayBGM(u16 songID); +void MonGainEVs(struct Pokemon*, u16 defeatedSpecies); +extern u8 gBattleBufferB[4][0x200]; +void HandleLowHpMusicChange(struct Pokemon*, u8 bank); +bool8 IsTradedMon(struct Pokemon*); +void BattleScriptPop(void); +void SwitchInClearSetData(void); +u8* ConvertIntToDecimalStringN(u8*, s32, u8, u8); +u8 GetSetPokedexFlag(u16 nationalNum, u8 caseID); +u16 SpeciesToNationalPokedexNum(u16 species); +u8 sub_803FC34(u8 bank); +u16 sub_803FBFC(u8 a); +u8 GetBattlerAtPosition(u8 ID); +void sub_8012258(u8); +//MonTryLearningNewMove teach poke a move +u16 GiveMoveToBattleMon(struct BattlePokemon *mon, u16 move); +void IncrementGameStat(u8 index); +u8 GetScaledHPFraction(s16 hp, s16 maxhp, u8 scale); +u16 GetPokedexHeightWeight(u16 national_num, u8 heightweight); +u8 MenuCursor_Create814A5C0(u8 a1, u16 a2, u8 a3, u16 a4, u8 a5); +void DestroyMenuCursor(void); +void sub_802BC6C(void); +u8 sub_809FA30(void); +bool32 IsHMMove2(u16 move); +void sub_802BBD4(u8 r0, u8 r1, u8 r2, u8 r3, u8 sp0); +void nullsub_6(void); +void ReshowBattleScreenAfterMenu(void); +void BattleMainCB2(void); +void AddMoney(u32* moneySaveblock, u32 to_give); +u8 CountAliveMons(u8 caseID); +void PokemonUseItemEffects(struct Pokemon*, u16 item, u8 partyID, u8 r3, u8 sp); +u8 CanRunFromBattle(void); +u8 GetMoveTarget(u16 move, u8 targetbyte); //get target of move +u8 CastformDataTypeChange(u8 bank); +u8 Overworld_GetMapTypeOfSaveblockLocation(void); +u8 CalculatePlayerPartyCount(void); +u16 Sqrt(u32 num); +u8 sub_809070C(u16 nationalNum, u32 TiD, u32 PiD); //task prepare poke dex display +void MenuCursor_SetPos814A880(u8 a1, u8 a2); +u8 CheckMoveLimitations(u8 bank, u8 unusable_moves, u8 flags); +bool8 IsLinkDoubleBattle(void); +void sub_8094B6C(u8 bank, u8 partyID, u8 r2); + +//extern BattleScripts +extern u8 BattleScript_MoveEnd[]; +extern u8 BattleScript_NoPPForMove[]; +extern u8 BattleScript_MagicCoatBounce[]; +extern u8 BattleScript_TookAttack[]; +extern u8 BattleScript_SnatchedMove[]; +extern u8 BattleScript_Pausex20[]; +extern u8 BattleScript_SubstituteFade[]; +extern u8 BattleScript_HangedOnMsg[]; +extern u8 BattleScript_OneHitKOMsg[]; +extern u8 BattleScript_EnduredMsg[]; +extern u8 BattleScript_PSNPrevention[]; +extern u8 BattleScript_BRNPrevention[]; +extern u8 BattleScript_PRLZPrevention[]; +extern u8 BattleScript_FlinchPrevention[]; +extern u8 BattleScript_StatUp[]; +extern u8 BattleScript_StatDown[]; +extern u8 BattleScript_NoItemSteal[]; +extern u8 BattleScript_ItemSteal[]; +extern u8 BattleScript_RapidSpinAway[]; +extern u8 BattleScript_TargetPRLZHeal[]; +extern u8 BattleScript_KnockedOff[]; +extern u8 BattleScript_LevelUp[]; +extern u8 BattleScript_WrapFree[]; +extern u8 BattleScript_LeechSeedFree[]; +extern u8 BattleScript_SpikesFree[]; +extern u8 BattleScript_ButItFailed[]; +extern u8 BattleScript_ObliviousPreventsAttraction[]; +extern u8 BattleScript_MistProtected[]; +extern u8 BattleScript_AbilityNoStatLoss[]; +extern u8 BattleScript_AbilityNoSpecificStatLoss[]; +extern u8 BattleScript_TrainerBallBlock[]; +extern u8 BattleScript_WallyBallThrow[]; +extern u8 BattleScript_SuccessBallThrow[]; +extern u8 BattleScript_ShakeBallThrow[]; +extern u8 BattleScript_AllStatsUp[]; +extern u8 BattleScript_AtkDefDown[]; +extern u8 BattleScript_SAtkDown2[]; + +extern u8 BattleScript_SpikesOnTarget[]; //spikes1 +extern u8 BattleScript_SpikesOnAttacker[]; //spikes2 +extern u8 BattleScript_SpikesOngBank1[]; //spikes3 +extern u8 BattleScript_HitFromCritCalc[]; //present dmg +extern u8 BattleScript_AlreadyAtFullHp[]; //present full hp +extern u8 BattleScript_PresentHealTarget[]; //present hp heal +extern u8 BattleScript_MoveMissedPause[]; +extern u8 BattleScript_CastformChange[]; +extern u8 BattleScript_DampStopsExplosion[]; +extern u8 BattleScript_SuccessForceOut[]; //bs random switchout +extern u8 BattleScript_PrintPayDayMoneyString[]; //bs payday money give +extern u8 BattleScript_FaintAttacker[]; +extern u8 BattleScript_FaintTarget[]; +extern u8 BattleScript_DestinyBondTakesLife[]; +extern u8 BattleScript_SelectingImprisionedMoveInPalace[]; + +// read via orr +#define BSScriptRead32(ptr) ((ptr)[0] | (ptr)[1] << 8 | (ptr)[2] << 16 | (ptr)[3] << 24) +#define BSScriptRead16(ptr) ((ptr)[0] | ((ptr)[1] << 8)) +#define BSScriptReadPtr(ptr) ((void *)BSScriptRead32(ptr)) + +// read via add +#define BS2ScriptRead32(ptr) ((ptr)[0] + ((ptr)[1] << 8) + ((ptr)[2] << 16) + ((ptr)[3] << 24)) +#define BS2ScriptRead16(ptr) ((ptr)[0] + ((ptr)[1] << 8)) +#define BS2ScriptReadPtr(ptr) ((void *)BS2ScriptRead32(ptr)) + +#define TARGET_PROTECT_AFFECTED ((gProtectStructs[gBankTarget].protected && gBattleMoves[gCurrentMove].flags & F_AFFECTED_BY_PROTECT)) + +//array entries for battle communication +#define MOVE_EFFECT_BYTE 0x3 +#define MULTISTRING_CHOOSER 0x5 +#define MSG_DISPLAY 0x7 + +#define TARGET_SELECTED 0x0 +#define TARGET_DEPENDS 0x1 +#define TARGET_BOTH 0x8 +#define TARGET_FOES_AND_ALLY 0x20 +#define TARGET_OPPONENTS_FIELD 0x40 + +#define TYPE_FORESIGHT 0xFE +#define TYPE_ENDTABLE 0xFF + +#define CMP_EQUAL 0x0 +#define CMP_NOT_EQUAL 0x1 +#define CMP_GREATER_THAN 0x2 +#define CMP_LESS_THAN 0x3 +#define CMP_COMMON_BITS 0x4 +#define CMP_NO_COMMON_BITS 0x5 + +#define uBYTE0_16(value)(( (u8) (((u16)(value) & (0x000000FF)) >> 0x00))) +#define uBYTE1_16(value)(( (u8) (((u16)(value) & (0x0000FF00)) >> 0x08))) + +#define uBYTE0_32(value)(( (u8) (((u32)(value) & (0x000000FF)) >> 0x00))) +#define uBYTE1_32(value)(( (u8) (((u32)(value) & (0x0000FF00)) >> 0x08))) +#define uBYTE2_32(value)(( (u8) (((u32)(value) & (0x00FF0000)) >> 0x10))) +#define uBYTE3_32(value)(( (u8) (((u32)(value) & (0xFF000000)) >> 0x18))) + +#define sBYTE0_16(value)(( (u8) (((s16)(value) & (0x000000FF)) >> 0x00))) +#define sBYTE1_16(value)(( (u8) (((s16)(value) & (0x0000FF00)) >> 0x08))) + +#define sBYTE0_32(value)(( (u8) (((s32)(value) & (0x000000FF)) >> 0x00))) +#define sBYTE1_32(value)(( (u8) (((s32)(value) & (0x0000FF00)) >> 0x08))) +#define sBYTE2_32(value)(( (u8) (((s32)(value) & (0x00FF0000)) >> 0x10))) +#define sBYTE3_32(value)(( (u8) (((s32)(value) & (0xFF000000)) >> 0x18))) + +#define RecordAbilitySetField6(ability, fieldValue) \ +(gLastUsedAbility = ability, gBattleCommunication[6] = fieldValue, RecordAbilityBattle(gBankTarget, ability)) + +#define TARGET_TURN_DAMAGED (((gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special))) + +#define HP_ON_SWITCHOUT (((u16*)(ewram_addr + 0x160BC))) + +static void atk00_attackcanceler(void); +static void atk01_accuracycheck(void); +static void atk02_attackstring(void); +static void atk03_ppreduce(void); +static void atk04_critcalc(void); +static void atk05_damagecalc(void); +static void atk06_typecalc(void); +static void atk07_adjustnormaldamage(void); +static void atk08_adjustnormaldamage2(void); +static void atk09_attackanimation(void); +static void atk0A_waitanimation(void); +static void atk0B_healthbarupdate(void); +static void atk0C_datahpupdate(void); +static void atk0D_critmessage(void); +static void atk0E_effectivenesssound(void); +static void atk0F_resultmessage(void); +static void atk10_printstring(void); +static void atk11_printselectionstring(void); +static void atk12_waitmessage(void); +static void atk13_printfromtable(void); +static void atk14_printselectionstringfromtable(void); +static void atk15_seteffectwithchance(void); +static void atk16_seteffectprimary(void); +static void atk17_seteffectsecondary(void); +static void atk18_clearstatusfromeffect(void); +static void atk19_tryfaintmon(void); +static void atk1A_dofaintanimation(void); +static void atk1B_cleareffectsonfaint(void); +static void atk1C_jumpifstatus(void); +static void atk1D_jumpifstatus2(void); +static void atk1E_jumpifability(void); +static void atk1F_jumpifsideaffecting(void); +static void atk20_jumpifstat(void); +static void atk21_jumpifstatus3condition(void); +static void atk22_jumpiftype(void); +static void atk23_getexp(void); +static void atk24(void); +static void atk25_movevaluescleanup(void); +static void atk26_setmultihit(void); +static void atk27_decrementmultihit(void); +static void atk28_goto(void); +static void atk29_jumpifbyte(void); +static void atk2A_jumpifhalfword(void); +static void atk2B_jumpifword(void); +static void atk2C_jumpifarrayequal(void); +static void atk2D_jumpifarraynotequal(void); +static void atk2E_setbyte(void); +static void atk2F_addbyte(void); +static void atk30_subbyte(void); +static void atk31_copyarray(void); +static void atk32_copyarraywithindex(void); +static void atk33_orbyte(void); +static void atk34_orhalfword(void); +static void atk35_orword(void); +static void atk36_bicbyte(void); +static void atk37_bichalfword(void); +static void atk38_bicword(void); +static void atk39_pause(void); +static void atk3A_waitstate(void); +static void atk3B_healthbar_update(void); +static void atk3C_return(void); +static void atk3D_end(void); +static void atk3E_end2(void); +static void atk3F_end3(void); +static void atk40_jumpifaffectedbyprotect(void); +static void atk41_call(void); +static void atk42_jumpiftype2(void); +static void atk43_jumpifabilitypresent(void); +static void atk44_endselectionscript(void); +static void atk45_playanimation(void); +static void atk46_playanimation2(void); +static void atk47_setgraphicalstatchangevalues(void); +static void atk48_playstatchangeanimation(void); +void atk49_moveend(void); +static void atk4A_typecalc2(void); +static void atk4B_returnatktoball(void); +static void atk4C_getswitchedmondata(void); +static void atk4D_switchindataupdate(void); +static void atk4E_switchinanim(void); +static void atk4F_jumpifcantswitch(void); +static void atk50_openpartyscreen(void); +static void atk51_switchhandleorder(void); +static void atk52_switchineffects(void); +static void atk53_trainerslidein(void); +static void atk54_playse(void); +static void atk55_fanfare(void); +static void atk56_playfaintcry(void); +static void atk57(void); +static void atk58_returntoball(void); +void atk59_handlelearnnewmove(void); +static void atk5A_yesnoboxlearnmove(void); +static void atk5B_yesnoboxstoplearningmove(void); +static void atk5C_hitanimation(void); +static void atk5D_getmoneyreward(void); +static void atk5E_8025A70(void); +static void atk5F_8025B24(void); +static void atk60_incrementgamestat(void); +static void atk61_drawpartystatussummary(void); +static void atk62_08025C6C(void); +static void atk63_jumptorandomattack(void); +static void atk64_statusanimation(void); +static void atk65_status2animation(void); +static void atk66_chosenstatusanimation(void); +static void atk67_yesnobox(void); +static void atk68_cancelallactions(void); +static void atk69_adjustsetdamage(void); +void atk6A_removeitem(void); +static void atk6B_atknameinbuff1(void); +static void atk6C_drawlvlupbox(void); +static void atk6D_resetsentmonsvalue(void); +static void atk6E_setatktoplayer0(void); +static void atk6F_makevisible(void); +static void atk70_recordlastability(void); +static void atk71_buffermovetolearn(void); +static void atk72_jumpifplayerran(void); +static void atk73_hpthresholds(void); +static void atk74_hpthresholds2(void); +static void atk75_useitemonopponent(void); +static void atk76_various(void); +static void atk77_setprotectlike(void); +static void atk78_faintifabilitynotdamp(void); +static void atk79_setatkhptozero(void); +static void atk7A_jumpifnexttargetvalid(void); +static void atk7B_tryhealhalfhealth(void); +static void atk7C_trymirrormove(void); +static void atk7D_setrain(void); +static void atk7E_setreflect(void); +static void atk7F_setseeded(void); +static void atk80_manipulatedamage(void); +static void atk81_trysetrest(void); +static void atk82_jumpifnotfirstturn(void); +static void atk83_nop(void); +static void atk84_jumpifcantmakeasleep(void); +static void atk85_stockpile(void); +static void atk86_stockpiletobasedamage(void); +static void atk87_stockpiletohpheal(void); +static void atk88_negativedamage(void); +static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8 *BS_ptr); +static void atk89_statbuffchange(void); +static void atk8A_normalisebuffs(void); +static void atk8B_setbide(void); +static void atk8C_confuseifrepeatingattackends(void); +static void atk8D_setmultihitcounter(void); +static void atk8E_initmultihitstring(void); +static void atk8F_forcerandomswitch(void); +static void atk90_tryconversiontypechange(void); +static void atk91_givepaydaymoney(void); +static void atk92_setlightscreen(void); +static void atk93_tryKO(void); +static void atk94_damagetohalftargethp(void); +static void atk95_setsandstorm(void); +static void atk96_weatherdamage(void); +static void atk97_tryinfatuating(void); +static void atk98_updatestatusicon(void); +static void atk99_setmist(void); +static void atk9A_setfocusenergy(void); +static void atk9B_transformdataexecution(void); +static void atk9C_setsubstitute(void); +static void atk9D_mimicattackcopy(void); +static void atk9E_metronome(void); +static void atk9F_dmgtolevel(void); +static void atkA0_psywavedamageeffect(void); +static void atkA1_counterdamagecalculator(void); +static void atkA2_mirrorcoatdamagecalculator(void); +static void atkA3_disablelastusedattack(void); +static void atkA4_trysetencore(void); +static void atkA5_painsplitdmgcalc(void); +static void atkA6_settypetorandomresistance(void); +static void atkA7_setalwayshitflag(void); +static void atkA8_copymovepermanently(void); +static void atkA9_trychoosesleeptalkmove(void); +static void atkAA_setdestinybond(void); +static void atkAB_trysetdestinybondtohappen(void); +static void atkAC_remaininghptopower(void); +static void atkAD_tryspiteppreduce(void); +static void atkAE_healpartystatus(void); +static void atkAF_cursetarget(void); +static void atkB0_trysetspikes(void); +static void atkB1_setforesight(void); +static void atkB2_trysetperishsong(void); +static void atkB3_rolloutdamagecalculation(void); +static void atkB4_jumpifconfusedandstatmaxed(void); +static void atkB5_furycuttercalc(void); +static void atkB6_happinesstodamagecalculation(void); +static void atkB7_presentdamagecalculation(void); +static void atkB8_setsafeguard(void); +static void atkB9_magnitudedamagecalculation(void); +static void atkBA_jumpifnopursuitswitchdmg(void); +static void atkBB_setsunny(void); +static void atkBC_maxattackhalvehp(void); +static void atkBD_copyfoestats(void); +static void atkBE_rapidspinfree(void); +static void atkBF_setdefensecurlbit(void); +static void atkC0_recoverbasedonsunlight(void); +static void atkC1_hiddenpowercalc(void); +static void atkC2_selectfirstvalidtarget(void); +static void atkC3_trysetfutureattack(void); +static void atkC4_trydobeatup(void); +static void atkC5_setsemiinvulnerablebit(void); +static void atkC6_clearsemiinvulnerablebit(void); +static void atkC7_setminimize(void); +static void atkC8_sethail(void); +static void atkC9_jumpifattackandspecialattackcannotfall(void); +static void atkCA_setforcedtarget(void); +static void atkCB_setcharge(void); +static void atkCC_callterrainattack(void); +static void atkCD_cureifburnedparalysedorpoisoned(void); +static void atkCE_settorment(void); +static void atkCF_jumpifnodamage(void); +static void atkD0_settaunt(void); +static void atkD1_trysethelpinghand(void); +static void atkD2_tryswapitems(void); +static void atkD3_trycopyability(void); +static void atkD4_trywish(void); +static void atkD5_trysetroots(void); +static void atkD6_doubledamagedealtifdamaged(void); +static void atkD7_setyawn(void); +static void atkD8_setdamagetohealthdifference(void); +static void atkD9_scaledamagebyhealthratio(void); +static void atkDA_tryswapabilities(void); +static void atkDB_tryimprision(void); +static void atkDC_trysetgrudge(void); +static void atkDD_weightdamagecalculation(void); +static void atkDE_asistattackselect(void); +static void atkDF_trysetmagiccoat(void); +static void atkE0_trysetsnatch(void); +static void atkE1_trygetintimidatetarget(void); +static void atkE2_switchoutabilities(void); +static void atkE3_jumpifhasnohp(void); +static void atkE4_getsecretpowereffect(void); +static void atkE5_pickup(void); +static void atkE6_docastformchangeanimation(void); +static void atkE7_trycastformdatachange(void); +static void atkE8_settypebasedhalvers(void); +static void atkE9_setweatherballtype(void); +static void atkEA_tryrecycleitem(void); +static void atkEB_settypetoterrain(void); +static void atkEC_pursuitrelated(void); +static void atkED_snatchsetbanks(void); +static void atkEE_removelightscreenreflect(void); +void atkEF_handleballthrow(void); +static void atkF0_givecaughtmon(void); +static void atkF1_trysetcaughtmondexflags(void); +static void atkF2_displaydexinfo(void); +static void atkF3_trygivecaughtmonnick(void); +static void atkF4_subattackerhpbydmg(void); +static void atkF5_removeattackerstatus1(void); +static void atkF6_finishaction(void); +static void atkF7_finishturn(void); + +void (* const gBattleScriptingCommandsTable[])(void) = +{ + atk00_attackcanceler, + atk01_accuracycheck, + atk02_attackstring, + atk03_ppreduce, + atk04_critcalc, + atk05_damagecalc, + atk06_typecalc, + atk07_adjustnormaldamage, + atk08_adjustnormaldamage2, + atk09_attackanimation, + atk0A_waitanimation, + atk0B_healthbarupdate, + atk0C_datahpupdate, + atk0D_critmessage, + atk0E_effectivenesssound, + atk0F_resultmessage, + atk10_printstring, + atk11_printselectionstring, + atk12_waitmessage, + atk13_printfromtable, + atk14_printselectionstringfromtable, + atk15_seteffectwithchance, + atk16_seteffectprimary, + atk17_seteffectsecondary, + atk18_clearstatusfromeffect, + atk19_tryfaintmon, + atk1A_dofaintanimation, + atk1B_cleareffectsonfaint, + atk1C_jumpifstatus, + atk1D_jumpifstatus2, + atk1E_jumpifability, + atk1F_jumpifsideaffecting, + atk20_jumpifstat, + atk21_jumpifstatus3condition, + atk22_jumpiftype, + atk23_getexp, + atk24, + atk25_movevaluescleanup, + atk26_setmultihit, + atk27_decrementmultihit, + atk28_goto, + atk29_jumpifbyte, + atk2A_jumpifhalfword, + atk2B_jumpifword, + atk2C_jumpifarrayequal, + atk2D_jumpifarraynotequal, + atk2E_setbyte, + atk2F_addbyte, + atk30_subbyte, + atk31_copyarray, + atk32_copyarraywithindex, + atk33_orbyte, + atk34_orhalfword, + atk35_orword, + atk36_bicbyte, + atk37_bichalfword, + atk38_bicword, + atk39_pause, + atk3A_waitstate, + atk3B_healthbar_update, + atk3C_return, + atk3D_end, + atk3E_end2, + atk3F_end3, + atk40_jumpifaffectedbyprotect, + atk41_call, + atk42_jumpiftype2, + atk43_jumpifabilitypresent, + atk44_endselectionscript, + atk45_playanimation, + atk46_playanimation2, + atk47_setgraphicalstatchangevalues, + atk48_playstatchangeanimation, + atk49_moveend, + atk4A_typecalc2, + atk4B_returnatktoball, + atk4C_getswitchedmondata, + atk4D_switchindataupdate, + atk4E_switchinanim, + atk4F_jumpifcantswitch, + atk50_openpartyscreen, + atk51_switchhandleorder, + atk52_switchineffects, + atk53_trainerslidein, + atk54_playse, + atk55_fanfare, + atk56_playfaintcry, + atk57, + atk58_returntoball, + atk59_handlelearnnewmove, + atk5A_yesnoboxlearnmove, + atk5B_yesnoboxstoplearningmove, + atk5C_hitanimation, + atk5D_getmoneyreward, + atk5E_8025A70, + atk5F_8025B24, + atk60_incrementgamestat, + atk61_drawpartystatussummary, + atk62_08025C6C, + atk63_jumptorandomattack, + atk64_statusanimation, + atk65_status2animation, + atk66_chosenstatusanimation, + atk67_yesnobox, + atk68_cancelallactions, + atk69_adjustsetdamage, + atk6A_removeitem, + atk6B_atknameinbuff1, + atk6C_drawlvlupbox, + atk6D_resetsentmonsvalue, + atk6E_setatktoplayer0, + atk6F_makevisible, + atk70_recordlastability, + atk71_buffermovetolearn, + atk72_jumpifplayerran, + atk73_hpthresholds, + atk74_hpthresholds2, + atk75_useitemonopponent, + atk76_various, + atk77_setprotectlike, + atk78_faintifabilitynotdamp, + atk79_setatkhptozero, + atk7A_jumpifnexttargetvalid, + atk7B_tryhealhalfhealth, + atk7C_trymirrormove, + atk7D_setrain, + atk7E_setreflect, + atk7F_setseeded, + atk80_manipulatedamage, + atk81_trysetrest, + atk82_jumpifnotfirstturn, + atk83_nop, + atk84_jumpifcantmakeasleep, + atk85_stockpile, + atk86_stockpiletobasedamage, + atk87_stockpiletohpheal, + atk88_negativedamage, + atk89_statbuffchange, + atk8A_normalisebuffs, + atk8B_setbide, + atk8C_confuseifrepeatingattackends, + atk8D_setmultihitcounter, + atk8E_initmultihitstring, + atk8F_forcerandomswitch, + atk90_tryconversiontypechange, + atk91_givepaydaymoney, + atk92_setlightscreen, + atk93_tryKO, + atk94_damagetohalftargethp, + atk95_setsandstorm, + atk96_weatherdamage, + atk97_tryinfatuating, + atk98_updatestatusicon, + atk99_setmist, + atk9A_setfocusenergy, + atk9B_transformdataexecution, + atk9C_setsubstitute, + atk9D_mimicattackcopy, + atk9E_metronome, + atk9F_dmgtolevel, + atkA0_psywavedamageeffect, + atkA1_counterdamagecalculator, + atkA2_mirrorcoatdamagecalculator, + atkA3_disablelastusedattack, + atkA4_trysetencore, + atkA5_painsplitdmgcalc, + atkA6_settypetorandomresistance, + atkA7_setalwayshitflag, + atkA8_copymovepermanently, + atkA9_trychoosesleeptalkmove, + atkAA_setdestinybond, + atkAB_trysetdestinybondtohappen, + atkAC_remaininghptopower, + atkAD_tryspiteppreduce, + atkAE_healpartystatus, + atkAF_cursetarget, + atkB0_trysetspikes, + atkB1_setforesight, + atkB2_trysetperishsong, + atkB3_rolloutdamagecalculation, + atkB4_jumpifconfusedandstatmaxed, + atkB5_furycuttercalc, + atkB6_happinesstodamagecalculation, + atkB7_presentdamagecalculation, + atkB8_setsafeguard, + atkB9_magnitudedamagecalculation, + atkBA_jumpifnopursuitswitchdmg, + atkBB_setsunny, + atkBC_maxattackhalvehp, + atkBD_copyfoestats, + atkBE_rapidspinfree, + atkBF_setdefensecurlbit, + atkC0_recoverbasedonsunlight, + atkC1_hiddenpowercalc, + atkC2_selectfirstvalidtarget, + atkC3_trysetfutureattack, + atkC4_trydobeatup, + atkC5_setsemiinvulnerablebit, + atkC6_clearsemiinvulnerablebit, + atkC7_setminimize, + atkC8_sethail, + atkC9_jumpifattackandspecialattackcannotfall, + atkCA_setforcedtarget, + atkCB_setcharge, + atkCC_callterrainattack, + atkCD_cureifburnedparalysedorpoisoned, + atkCE_settorment, + atkCF_jumpifnodamage, + atkD0_settaunt, + atkD1_trysethelpinghand, + atkD2_tryswapitems, + atkD3_trycopyability, + atkD4_trywish, + atkD5_trysetroots, + atkD6_doubledamagedealtifdamaged, + atkD7_setyawn, + atkD8_setdamagetohealthdifference, + atkD9_scaledamagebyhealthratio, + atkDA_tryswapabilities, + atkDB_tryimprision, + atkDC_trysetgrudge, + atkDD_weightdamagecalculation, + atkDE_asistattackselect, + atkDF_trysetmagiccoat, + atkE0_trysetsnatch, + atkE1_trygetintimidatetarget, + atkE2_switchoutabilities, + atkE3_jumpifhasnohp, + atkE4_getsecretpowereffect, + atkE5_pickup, + atkE6_docastformchangeanimation, + atkE7_trycastformdatachange, + atkE8_settypebasedhalvers, + atkE9_setweatherballtype, + atkEA_tryrecycleitem, + atkEB_settypetoterrain, + atkEC_pursuitrelated, + atkED_snatchsetbanks, + atkEE_removelightscreenreflect, + atkEF_handleballthrow, + atkF0_givecaughtmon, + atkF1_trysetcaughtmondexflags, + atkF2_displaydexinfo, + atkF3_trygivecaughtmonnick, + atkF4_subattackerhpbydmg, + atkF5_removeattackerstatus1, + atkF6_finishaction, + atkF7_finishturn, +}; + +struct StatFractions +{ + u8 dividend; + u8 divisor; +}; + +static const struct StatFractions gAccuracyStageRatios[] = +{ + { 33, 100}, // -6 + { 36, 100}, // -5 + { 43, 100}, // -4 + { 50, 100}, // -3 + { 60, 100}, // -2 + { 75, 100}, // -1 + { 1, 1}, // 0 + {133, 100}, // +1 + {166, 100}, // +2 + { 2, 1}, // +3 + {233, 100}, // +4 + {133, 50}, // +5 + { 3, 1}, // +6 +}; + +// The chance is 1/N for each stage. +static const u16 sCriticalHitChance[] = {16, 8, 4, 3, 2}; + +static const u32 sStatusFlagsForMoveEffects[] = +{ + 0x00000000, + STATUS_SLEEP, + STATUS_POISON, + STATUS_BURN, + STATUS_FREEZE, + STATUS_PARALYSIS, + STATUS_TOXIC_POISON, + STATUS2_CONFUSION, + STATUS2_FLINCHED, + 0x00000000, + STATUS2_UPROAR, + 0x00000000, + STATUS2_MULTIPLETURNS, + STATUS2_WRAPPED, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + STATUS2_RECHARGE, + 0x00000000, + 0x00000000, + STATUS2_ESCAPE_PREVENTION, + STATUS2_NIGHTMARE, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + STATUS2_LOCK_CONFUSE, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; + +u8* const gMoveEffectBS_Ptrs[] = +{ + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectPoison, + BattleScript_MoveEffectBurn, + BattleScript_MoveEffectFreeze, + BattleScript_MoveEffectParalysis, + BattleScript_MoveEffectToxic, + BattleScript_MoveEffectConfusion, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectUproar, + BattleScript_MoveEffectPayDay, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectWrap, + BattleScript_MoveEffectRecoil33, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectSleep, + BattleScript_MoveEffectRecoil33 +}; + +const u8 sUnreferencedBitMask1[] = {0, 1, 3, 7, 0xF, 0x1F, 0x3F}; + +const u8 gLevelUpStatBoxStats[] = +{ + MON_DATA_MAX_HP, MON_DATA_SPATK, MON_DATA_ATK, + MON_DATA_SPDEF, MON_DATA_DEF, MON_DATA_SPEED +}; + +static const u16 sProtectSuccessRates[] = {0xFFFF, 0x7FFF, 0x3FFF, 0x1FFF}; + +#define MIMIC_FORBIDDEN_END 0xFFFE +#define METRONOME_FORBIDDEN_END 0xFFFF +#define ASSIST_FORBIDDEN_END 0xFFFF + +static const u16 sMovesForbiddenToCopy[] = +{ + MOVE_METRONOME, + MOVE_STRUGGLE, + MOVE_SKETCH, + MOVE_MIMIC, + MIMIC_FORBIDDEN_END, + MOVE_COUNTER, + MOVE_MIRROR_COAT, + MOVE_PROTECT, + MOVE_DETECT, + MOVE_ENDURE, + MOVE_DESTINY_BOND, + MOVE_SLEEP_TALK, + MOVE_THIEF, + MOVE_FOLLOW_ME, + MOVE_SNATCH, + MOVE_HELPING_HAND, + MOVE_COVET, + MOVE_TRICK, + MOVE_FOCUS_PUNCH, + METRONOME_FORBIDDEN_END +}; + +static const u8 sFlailHpScaleToPowerTable[] = //reversal+flail HP thresholds to power +{ + 1, 200, + 4, 150, + 9, 100, + 16, 80, + 32, 40, + 48, 20 +}; + +static const u16 sNaturePowerMoves[] = +{ + MOVE_STUN_SPORE, + MOVE_RAZOR_LEAF, + MOVE_EARTHQUAKE, + MOVE_HYDRO_PUMP, + MOVE_SURF, + MOVE_BUBBLE_BEAM, + MOVE_ROCK_SLIDE, + MOVE_SHADOW_BALL, + MOVE_SWIFT, + MOVE_SWIFT +}; + +// weight-based damage table for Low Kick +// format: min. weight (hectograms), base power +static const u16 sWeightToDamageTable[] = +{ + 100, 20, + 250, 40, + 500, 60, + 1000, 80, + 2000, 100, + 0xFFFF, 0xFFFF +}; + +static const u16 sPickupItems[] = +{ + ITEM_SUPER_POTION, 30, + ITEM_FULL_HEAL, 40, + ITEM_ULTRA_BALL, 50, + ITEM_RARE_CANDY, 60, + ITEM_FULL_RESTORE, 70, + ITEM_REVIVE, 80, + ITEM_NUGGET, 90, + ITEM_PROTEIN, 95, + ITEM_PP_UP, 99, + ITEM_KINGS_ROCK, 1 +}; + +static const u8 sTerrainToType[] = +{ + TYPE_GRASS, // tall grass + TYPE_GRASS, // long grass + TYPE_GROUND, // sand + TYPE_WATER, // underwater + TYPE_WATER, // water + TYPE_WATER, // pond water + TYPE_ROCK, // rock + TYPE_ROCK, // cave + TYPE_NORMAL, // building + TYPE_NORMAL, // plain +}; + +static const u8 sBallCatchBonuses[] = +{ + 20, 15, 10, 15 // Ultra, Great, Poke, Safari +}; + +static void atk00_attackcanceler(void) +{ + s32 i; + + if (gBattleOutcome != 0) + { + gCurrentActionFuncId = ACTION_FINISHED; + return; + } + if (gBattleMons[gBankAttacker].hp == 0 && !(gHitMarker & HITMARKER_NO_ATTACKSTRING)) + { + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gBattlescriptCurrInstr = BattleScript_MoveEnd; + return; + } + if (AtkCanceller_UnableToUseMove()) + return; + if (AbilityBattleEffects(ABILITYEFFECT_MOVES_BLOCK, gBankTarget, 0, 0, 0)) + return; + if (!gBattleMons[gBankAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE && !(gHitMarker & 0x800200) + && !(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) + { + gBattlescriptCurrInstr = BattleScript_NoPPForMove; + gMoveResultFlags |= MOVE_RESULT_MISSED; + return; + } + + gHitMarker &= ~(HITMARKER_x800000); + + if (!(gHitMarker & HITMARKER_OBEYS) && !(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) + { + i = IsMonDisobedient(); // why use the 'i' variable...? + switch (i) + { + case 0: + break; + case 2: + gHitMarker |= HITMARKER_OBEYS; + return; + default: + gMoveResultFlags |= MOVE_RESULT_MISSED; + return; + } + } + + gHitMarker |= HITMARKER_OBEYS; + + if (gProtectStructs[gBankTarget].bounceMove && gBattleMoves[gCurrentMove].flags & F_AFFECTED_BY_MAGIC_COAT) + { + PressurePPLose(gBankAttacker, gBankTarget, MOVE_MAGIC_COAT); + gProtectStructs[gBankTarget].bounceMove = 0; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MagicCoatBounce; + return; + } + + for (i = 0; i < gBattlersCount; i++) + { + if ((gProtectStructs[gBanksByTurnOrder[i]].stealMove) && gBattleMoves[gCurrentMove].flags & F_AFFECTED_BY_SNATCH) + { + PressurePPLose(gBankAttacker, gBanksByTurnOrder[i], MOVE_SNATCH); + gProtectStructs[gBanksByTurnOrder[i]].stealMove = 0; + gBattleStruct->scriptingActive = gBanksByTurnOrder[i]; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_SnatchedMove; + return; + } + } + + if (gSpecialStatuses[gBankTarget].lightningRodRedirected) + { + gSpecialStatuses[gBankTarget].lightningRodRedirected = 0; + gLastUsedAbility = ABILITY_LIGHTNING_ROD; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_TookAttack; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else if (TARGET_PROTECT_AFFECTED + && (gCurrentMove != MOVE_CURSE || (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST)) + && ((!IsTwoTurnsMove(gCurrentMove) || (gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)))) + { + CancelMultiTurnMoves(gBankAttacker); + gMoveResultFlags |= MOVE_RESULT_MISSED; + gLastLandedMoves[gBankTarget] = 0; + gLastHitByType[gBankTarget] = 0; + gBattleCommunication[6] = 1; + gBattlescriptCurrInstr++; + } + else + { + gBattlescriptCurrInstr++; + } +} + +static void JumpIfMoveFailed(u8 adder, u16 move) +{ + const u8 *BS_ptr = gBattlescriptCurrInstr + adder; + if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + { + gLastLandedMoves[gBankTarget] = 0; + gLastHitByType[gBankTarget] = 0; + BS_ptr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else + { + TrySetDestinyBondToHappen(); + if (AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBankTarget, 0, 0, move)) + return; + } + gBattlescriptCurrInstr = BS_ptr; +} + +static void atk40_jumpifaffectedbyprotect(void) +{ + if (TARGET_PROTECT_AFFECTED) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + JumpIfMoveFailed(5, 0); + gBattleCommunication[6] = 1; + } + else + { + gBattlescriptCurrInstr += 5; + } +} + +static bool8 JumpIfMoveAffectedByProtect(u16 move) +{ + bool8 affected = FALSE; + if (TARGET_PROTECT_AFFECTED) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + JumpIfMoveFailed(7, move); + gBattleCommunication[6] = 1; + affected = TRUE; + } + return affected; +} + +static bool8 AccuracyCalcHelper(u16 move) +{ + if (gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker) + { + JumpIfMoveFailed(7, move); + return TRUE; + } + + if (!(gHitMarker & HITMARKER_IGNORE_ON_AIR) && gStatuses3[gBankTarget] & STATUS3_ON_AIR) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + JumpIfMoveFailed(7, move); + return TRUE; + } + + gHitMarker &= ~HITMARKER_IGNORE_ON_AIR; + + if (!(gHitMarker & HITMARKER_IGNORE_UNDERGROUND) && gStatuses3[gBankTarget] & STATUS3_UNDERGROUND) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + JumpIfMoveFailed(7, move); + return TRUE; + } + + gHitMarker &= ~HITMARKER_IGNORE_UNDERGROUND; + + if (!(gHitMarker & HITMARKER_IGNORE_UNDERWATER) && gStatuses3[gBankTarget] & STATUS3_UNDERWATER) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + JumpIfMoveFailed(7, move); + return TRUE; + } + + gHitMarker &= ~HITMARKER_IGNORE_UNDERWATER; + + if ((WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY) && gBattleMoves[move].effect == EFFECT_THUNDER) + || (gBattleMoves[move].effect == EFFECT_ALWAYS_HIT || gBattleMoves[move].effect == EFFECT_VITAL_THROW)) + { + JumpIfMoveFailed(7, move); + return TRUE; + } + + return FALSE; +} + +static void atk01_accuracycheck(void) +{ + u16 move = T2_READ_16(gBattlescriptCurrInstr + 5); + + if (move == 0xFFFE || move == 0xFFFF) + { + if (gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS && move == 0xFFFF && gDisableStructs[gBankTarget].bankWithSureHit == gBankAttacker) + gBattlescriptCurrInstr += 7; + else if (gStatuses3[gBankTarget] & (STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else if (!JumpIfMoveAffectedByProtect(0)) + gBattlescriptCurrInstr += 7; + } + else + { + u8 type, moveAcc, holdEffect, quality; + s8 buff; + u16 calc; + + if (move == 0) + move = gCurrentMove; + + GET_MOVE_TYPE(move, type); + + if (JumpIfMoveAffectedByProtect(move)) + return; + if (AccuracyCalcHelper(move)) + return; + + if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) + { + u8 acc = gBattleMons[gBankAttacker].statStages[STAT_STAGE_ACC]; + buff = acc; + } + else + { + u8 acc = gBattleMons[gBankAttacker].statStages[STAT_STAGE_ACC]; + buff = acc + 6 - gBattleMons[gBankTarget].statStages[STAT_STAGE_EVASION]; + } + + if (buff < 0) + buff = 0; + if (buff > 0xC) + buff = 0xC; + + moveAcc = gBattleMoves[move].accuracy; + // check Thunder on sunny weather + if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY && gBattleMoves[move].effect == EFFECT_THUNDER) + moveAcc = 50; + + calc = gAccuracyStageRatios[buff].dividend * moveAcc; + calc /= gAccuracyStageRatios[buff].divisor; + + if (gBattleMons[gBankAttacker].ability == ABILITY_COMPOUND_EYES) + calc = (calc * 130) / 100; // 1.3 compound eyes boost + if (WEATHER_HAS_EFFECT && gBattleMons[gBankTarget].ability == ABILITY_SAND_VEIL && gBattleWeather & WEATHER_SANDSTORM_ANY) + calc = (calc * 80) / 100; // 1.2 sand veil loss; + if (gBattleMons[gBankAttacker].ability == ABILITY_HUSTLE && type < 9) + calc = (calc * 80) / 100; // 1.2 hustle loss; + + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + holdEffect = gEnigmaBerries[gBankTarget].holdEffect; + quality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + holdEffect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (holdEffect == HOLD_EFFECT_EVASION_UP) + calc = (calc * (100 - quality)) / 100; + + // final calculation + if ((Random() % 100 + 1) > calc) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && + (gBattleMoves[move].target == 0x8 || gBattleMoves[move].target == 0x20)) + gBattleCommunication[6] = 2; + else + gBattleCommunication[6] = 0; + CheckWonderGuardAndLevitate(); + } + JumpIfMoveFailed(7, move); + } +} + +static void atk02_attackstring(void) +{ + if (gBattleExecBuffer) + return; + if (!(gHitMarker & (HITMARKER_NO_ATTACKSTRING | HITMARKER_ATTACKSTRING_PRINTED))) + { + PrepareStringBattle(4, gBankAttacker); + gHitMarker |= HITMARKER_ATTACKSTRING_PRINTED; + } + gBattlescriptCurrInstr++; + gBattleCommunication[MSG_DISPLAY] = 0; +} + +static void atk03_ppreduce(void) +{ + s32 ppToDeduct = 1; + + if (gBattleExecBuffer) + return; + + if (!gSpecialStatuses[gBankAttacker].flag20) + { + switch (gBattleMoves[gCurrentMove].target) + { + case TARGET_FOES_AND_ALLY: + ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_ON_FIELD, gBankAttacker, ABILITY_PRESSURE, 0, 0); + break; + case TARGET_BOTH: + case TARGET_OPPONENTS_FIELD: + ppToDeduct += AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIZE, gBankAttacker, ABILITY_PRESSURE, 0, 0); + break; + default: + if (gBankAttacker != gBankTarget && gBattleMons[gBankTarget].ability == ABILITY_PRESSURE) + ppToDeduct++; + break; + } + } + + if (!(gHitMarker & (HITMARKER_NO_PPDEDUCT | HITMARKER_NO_ATTACKSTRING)) && gBattleMons[gBankAttacker].pp[gCurrMovePos]) + { + gProtectStructs[gBankAttacker].notFirstStrike = 1; + + if (gBattleMons[gBankAttacker].pp[gCurrMovePos] > ppToDeduct) + gBattleMons[gBankAttacker].pp[gCurrMovePos] -= ppToDeduct; + else + gBattleMons[gBankAttacker].pp[gCurrMovePos] = 0; + + if (!(gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED) + && !((gDisableStructs[gBankAttacker].unk18_b) & gBitTable[gCurrMovePos])) + { + gActiveBattler = gBankAttacker; + EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + gCurrMovePos, 0, 1, &gBattleMons[gBankAttacker].pp[gCurrMovePos]); + MarkBufferBankForExecution(gBankAttacker); + } + } + + gHitMarker &= ~(HITMARKER_NO_PPDEDUCT); + gBattlescriptCurrInstr++; +} + +static void atk04_critcalc(void) +{ + u8 holdEffect; + u16 item, critChance; + + item = gBattleMons[gBankAttacker].item; + + if (item == ITEM_ENIGMA_BERRY) + holdEffect = gEnigmaBerries[gBankAttacker].holdEffect; + else + holdEffect = ItemId_GetHoldEffect(item); + + gStringBank = gBankAttacker; + + critChance = 2 * ((gBattleMons[gBankAttacker].status2 & STATUS2_FOCUS_ENERGY) != 0) + + (gBattleMoves[gCurrentMove].effect == EFFECT_HIGH_CRITICAL) + + (gBattleMoves[gCurrentMove].effect == EFFECT_SKY_ATTACK) + + (gBattleMoves[gCurrentMove].effect == EFFECT_BLAZE_KICK) + + (gBattleMoves[gCurrentMove].effect == EFFECT_POISON_TAIL) + + (holdEffect == HOLD_EFFECT_SCOPE_LENS) + + 2 * (holdEffect == HOLD_EFFECT_LUCKY_PUNCH && gBattleMons[gBankAttacker].species == SPECIES_CHANSEY) + + 2 * (holdEffect == HOLD_EFFECT_STICK && gBattleMons[gBankAttacker].species == SPECIES_FARFETCHD); + + if (critChance > 4) + critChance = 4; + + if ((gBattleMons[gBankTarget].ability != ABILITY_BATTLE_ARMOR && gBattleMons[gBankTarget].ability != ABILITY_SHELL_ARMOR) + && !(gStatuses3[gBankAttacker] & STATUS3_CANT_SCORE_A_CRIT) + && !(gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE)) + && !(Random() % sCriticalHitChance[critChance])) + gCritMultiplier = 2; + else + gCritMultiplier = 1; + + gBattlescriptCurrInstr++; +} + +static void atk05_damagecalc(void) +{ + u16 side_hword = gSideAffecting[GetBattlerPosition(gBankTarget) & 1]; + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, + side_hword, gDynamicBasePower, + gBattleStruct->dynamicMoveType, gBankAttacker, gBankTarget); + gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleStruct->dmgMultiplier; + + if (gStatuses3[gBankAttacker] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) + gBattleMoveDamage *= 2; + if (gProtectStructs[gBankAttacker].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; + + gBattlescriptCurrInstr++; +} + +void AI_CalcDmg(u8 BankAtk, u8 BankDef) +{ + u16 side_hword = gSideAffecting[GetBattlerPosition(BankDef) & 1]; + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[BankAtk], &gBattleMons[BankDef], gCurrentMove, + side_hword, gDynamicBasePower, + gBattleStruct->dynamicMoveType, BankAtk, BankDef); + gDynamicBasePower = 0; + gBattleMoveDamage = gBattleMoveDamage * gCritMultiplier * gBattleStruct->dmgMultiplier; + + if (gStatuses3[BankAtk] & STATUS3_CHARGED_UP && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) + gBattleMoveDamage *= 2; + if (gProtectStructs[BankAtk].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; +} + +static void ModulateDmgByType(u8 multiplier) +{ + gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; + if (gBattleMoveDamage == 0 && multiplier != 0) + gBattleMoveDamage = 1; + + switch (multiplier) + { + case 0: //no effect + gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE; + gMoveResultFlags &= ~MOVE_RESULT_NOT_VERY_EFFECTIVE; + gMoveResultFlags &= ~MOVE_RESULT_SUPER_EFFECTIVE; + break; + case 5: //not very effecting + if (gBattleMoves[gCurrentMove].power && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + { + if (gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) + gMoveResultFlags &= ~MOVE_RESULT_SUPER_EFFECTIVE; + else + gMoveResultFlags |= MOVE_RESULT_NOT_VERY_EFFECTIVE; + } + break; + case 20: //super effective + if (gBattleMoves[gCurrentMove].power && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + { + if (gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE) + gMoveResultFlags &= ~MOVE_RESULT_NOT_VERY_EFFECTIVE; + else + gMoveResultFlags |= MOVE_RESULT_SUPER_EFFECTIVE; + } + break; + } +} + +static void atk06_typecalc(void) +{ + int i = 0; + u8 move_type; + if (gCurrentMove != MOVE_STRUGGLE) + { + if (gBattleStruct->dynamicMoveType) + move_type = gBattleStruct->dynamicMoveType & 0x3F; + else + move_type = gBattleMoves[gCurrentMove].type; + + //check stab + if (gBattleMons[gBankAttacker].type1 == move_type || gBattleMons[gBankAttacker].type2 == move_type) + { + gBattleMoveDamage = gBattleMoveDamage * 15; + gBattleMoveDamage = gBattleMoveDamage / 10; + } + + if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && move_type == TYPE_GROUND) + { + gLastUsedAbility = gBattleMons[gBankTarget].ability; + gMoveResultFlags |= (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE); + gLastLandedMoves[gBankTarget] = 0; + gLastHitByType[gBankTarget] = 0; + gBattleCommunication[6] = move_type; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else + { + while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) + break; + i += 3; + continue; + } + + else if (gTypeEffectiveness[i] == move_type) + { + //check type1 + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1) + ModulateDmgByType(gTypeEffectiveness[i + 2]); + //check type2 + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 && + gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2) + ModulateDmgByType(gTypeEffectiveness[i + 2]); + } + i += 3; + } + } + + if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2 + && (!(gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) || ((gMoveResultFlags & (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE)) == (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE))) + && gBattleMoves[gCurrentMove].power) + { + gLastUsedAbility = ABILITY_WONDER_GUARD; + gMoveResultFlags |= MOVE_RESULT_MISSED; + gLastLandedMoves[gBankTarget] = 0; + gLastHitByType[gBankTarget] = 0; + gBattleCommunication[6] = 3; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + if (gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) + gProtectStructs[gBankAttacker].notEffective = 1; + } + gBattlescriptCurrInstr++; +} +static void CheckWonderGuardAndLevitate(void) +{ + u8 flags = 0; + int i = 0; + u8 move_type; + + if (gCurrentMove == MOVE_STRUGGLE || !gBattleMoves[gCurrentMove].power) + return; + + if (gBattleStruct->dynamicMoveType) + move_type = gBattleStruct->dynamicMoveType & 0x3F; + else + move_type = gBattleMoves[gCurrentMove].type; + + if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && move_type == TYPE_GROUND) + { + RecordAbilitySetField6(ABILITY_LEVITATE, move_type); + return; + } + + while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) + break; + i += 3; + continue; + } + + if (gTypeEffectiveness[i] == move_type) + { + //check no effect + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 0) + { + gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE; + gProtectStructs[gBankAttacker].notEffective = 1; + } + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 && + gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 && + gTypeEffectiveness[i + 2] == 0) + { + gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE; + gProtectStructs[gBankAttacker].notEffective = 1; + } + + //check super effective + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 20) + flags |= 1; + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 + && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == 20) + flags |= 1; + + //check not very effective + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1 && gTypeEffectiveness[i + 2] == 5) + flags |= 2; + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 + && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == 5) + flags |= 2; + } + i += 3; + } + + if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2) + { + if (((flags & 2) || !(flags & 1)) && gBattleMoves[gCurrentMove].power) + { + RecordAbilitySetField6(ABILITY_WONDER_GUARD, 3); + } + } +} + +static void ModulateDmgByType2(u8 multiplier, u16 move, u8* flags) //a literal copy of the ModulateDmgbyType1 with different args... +{ + gBattleMoveDamage = gBattleMoveDamage * multiplier / 10; + if (gBattleMoveDamage == 0 && multiplier != 0) + gBattleMoveDamage = 1; + + switch (multiplier) + { + case 0: //no effect + *flags |= MOVE_RESULT_DOESNT_AFFECT_FOE; + *flags &= ~MOVE_RESULT_NOT_VERY_EFFECTIVE; + *flags &= ~MOVE_RESULT_SUPER_EFFECTIVE; + break; + case 5: //not very effecting + if (gBattleMoves[move].power && !(*flags & MOVE_RESULT_NO_EFFECT)) + { + if (*flags & MOVE_RESULT_SUPER_EFFECTIVE) + *flags &= ~MOVE_RESULT_SUPER_EFFECTIVE; + else + *flags |= MOVE_RESULT_NOT_VERY_EFFECTIVE; + } + break; + case 20: //super effective + if (gBattleMoves[move].power && !(*flags & MOVE_RESULT_NO_EFFECT)) + { + if (*flags & MOVE_RESULT_NOT_VERY_EFFECTIVE) + *flags &= ~MOVE_RESULT_NOT_VERY_EFFECTIVE; + else + *flags |= MOVE_RESULT_SUPER_EFFECTIVE; + } + break; + } +} + +u8 TypeCalc(u16 move, u8 bank_atk, u8 bank_def) +{ + int i = 0; + u8 flags = 0; + u8 move_type; + + if (move == MOVE_STRUGGLE) + return 0; + + move_type = gBattleMoves[move].type; + + //check stab + if (gBattleMons[bank_atk].type1 == move_type || gBattleMons[bank_atk].type2 == move_type) + { + gBattleMoveDamage = gBattleMoveDamage * 15; + gBattleMoveDamage = gBattleMoveDamage / 10; + } + + if (gBattleMons[bank_def].ability == ABILITY_LEVITATE && move_type == TYPE_GROUND) + { + flags |= (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE); + } + else + { + while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + if (gBattleMons[bank_def].status2 & STATUS2_FORESIGHT) + break; + i += 3; + continue; + } + + else if (gTypeEffectiveness[i] == move_type) + { + //check type1 + if (gTypeEffectiveness[i + 1] == gBattleMons[bank_def].type1) + ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); + //check type2 + if (gTypeEffectiveness[i + 1] == gBattleMons[bank_def].type2 && + gBattleMons[gBankTarget /* what the christ */].type1 != gBattleMons[bank_def].type2) + ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); + } + i += 3; + } + } + + if (gBattleMons[bank_def].ability == ABILITY_WONDER_GUARD && !(flags & MOVE_RESULT_MISSED) && + AttacksThisTurn(bank_atk, move) == 2 && + (!(flags & MOVE_RESULT_SUPER_EFFECTIVE) || ((flags & (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE)) == (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE))) && + gBattleMoves[move].power) + { + flags |= MOVE_RESULT_MISSED; + } + return flags; +} + +u8 AI_TypeCalc(u16 move, u16 species, u8 ability) +{ + int i = 0; + u8 flags = 0; + u8 type1 = gBaseStats[species].type1, type2 = gBaseStats[species].type2, move_type; + + if (move == MOVE_STRUGGLE) + return 0; + + move_type = gBattleMoves[move].type; + + if (ability == ABILITY_LEVITATE && move_type == TYPE_GROUND) + flags = MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE; + else + { + while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + i += 3; + continue; + } + if (gTypeEffectiveness[i] == move_type) + { + //check type1 + if (gTypeEffectiveness[i + 1] == type1) + ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); + //check type2 + if (gTypeEffectiveness[i + 1] == type2 && gBattleMons[gBankTarget].type1 != type2) //gf you morons, you should check if (type1 != type2)... + ModulateDmgByType2(gTypeEffectiveness[i + 2], move, &flags); + } + i += 3; + } + } + if (ability == ABILITY_WONDER_GUARD + && (!(flags & MOVE_RESULT_SUPER_EFFECTIVE) || ((flags & (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE)) == (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE))) + && gBattleMoves[move].power) + flags |= MOVE_RESULT_DOESNT_AFFECT_FOE; + return flags; +} + +// Multiplies the damage by a random factor between 85% to 100% inclusive +static inline void ApplyRandomDmgMultiplier(void) +{ + u16 rand = Random(); + u16 randPercent = 100 - (rand % 16); + + if (gBattleMoveDamage != 0) + { + gBattleMoveDamage *= randPercent; + gBattleMoveDamage /= 100; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } +} + +void Unused_ApplyRandomDmgMultiplier(void) +{ + ApplyRandomDmgMultiplier(); +} + +static void atk07_adjustnormaldamage(void) +{ + u8 hold_effect, quality; + ApplyRandomDmgMultiplier(); + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + hold_effect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + hold_effect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (hold_effect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + { + RecordItemBattle(gBankTarget, hold_effect); + gSpecialStatuses[gBankTarget].focusBanded = 1; + } + if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) + goto END; + if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE && !gProtectStructs[gBankTarget].endured + && !gSpecialStatuses[gBankTarget].focusBanded) + goto END; + + if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) + goto END; + + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + + if (gProtectStructs[gBankTarget].endured) + { + gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED; + goto END; + } + if (gSpecialStatuses[gBankTarget].focusBanded) + { + gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON; + gLastUsedItem = gBattleMons[gBankTarget].item; + } + + END: + gBattlescriptCurrInstr++; +} + +static void atk08_adjustnormaldamage2(void) //literally the same as 0x7 except it doesn't check for false swipe move effect... +{ + u8 hold_effect, quality; + ApplyRandomDmgMultiplier(); + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + { + hold_effect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + hold_effect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (hold_effect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + { + RecordItemBattle(gBankTarget, hold_effect); + gSpecialStatuses[gBankTarget].focusBanded = 1; + } + if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) + goto END; + if (!gProtectStructs[gBankTarget].endured + && !gSpecialStatuses[gBankTarget].focusBanded) + goto END; + + if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) + goto END; + + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + + if (gProtectStructs[gBankTarget].endured) + { + gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED; + goto END; + } + if (gSpecialStatuses[gBankTarget].focusBanded) + { + gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON; + gLastUsedItem = gBattleMons[gBankTarget].item; + } + + END: + gBattlescriptCurrInstr++; +} + +static void atk09_attackanimation(void) +{ + if (gBattleExecBuffer) + return; + + if ((gHitMarker & HITMARKER_NO_ANIMATIONS) && (gCurrentMove != MOVE_TRANSFORM && gCurrentMove != MOVE_SUBSTITUTE)) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_Pausex20; + gBattleStruct->animTurn += 1; + gBattleStruct->animTargetsHit += 1; + } + else + { + if ((gBattleMoves[gCurrentMove].target & TARGET_BOTH || gBattleMoves[gCurrentMove].target & TARGET_FOES_AND_ALLY || gBattleMoves[gCurrentMove].target & TARGET_DEPENDS) && gBattleStruct->animTargetsHit) + { + gBattlescriptCurrInstr++; + return; + } + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + { + gActiveBattler = gBankAttacker; + + EmitMoveAnimation(0, gCurrentMove, gBattleStruct->animTurn, gBattleMovePower, gBattleMoveDamage, gBattleMons[gBankAttacker].friendship, &gDisableStructs[gBankAttacker]); + gBattleStruct->animTurn += 1; + gBattleStruct->animTargetsHit += 1; + MarkBufferBankForExecution(gBankAttacker); + gBattlescriptCurrInstr++; + } + else + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_Pausex20; + } + } +} + +static void atk0A_waitanimation(void) +{ + if (gBattleExecBuffer == 0) + gBattlescriptCurrInstr++; +} + +static void atk0B_healthbarupdate(void) +{ + if (gBattleExecBuffer) + return; + + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + { + gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + + if (gBattleMons[gActiveBattler].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBattler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) + { + PrepareStringBattle(0x80, gActiveBattler); + } + else + { + // Emerald + /* + s16 healthValue; + + s32 currDmg = gBattleMoveDamage; + s32 maxPossibleDmgValue = 10000; // not present in R/S, ensures that huge damage values don't change sign + + if (currDmg <= maxPossibleDmgValue) + healthValue = currDmg; + else + healthValue = maxPossibleDmgValue; + + EmitHealthBarUpdate(0, healthValue); + */ + + EmitHealthBarUpdate(0, gBattleMoveDamage); + MarkBufferBankForExecution(gActiveBattler); + + if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER && gBattleMoveDamage > 0) + gBattleResults.unk5_0 = 1; + } + } + + gBattlescriptCurrInstr += 2; +} + +static void atk0C_datahpupdate(void) +{ + u32 moveType; + + if (gBattleExecBuffer) + return; + + if (gBattleStruct->dynamicMoveType == 0) + moveType = gBattleMoves[gCurrentMove].type; + else if (!(gBattleStruct->dynamicMoveType & 0x40)) + moveType = gBattleStruct->dynamicMoveType & 0x3F; + else + moveType = gBattleMoves[gCurrentMove].type; + + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + { + gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + if (gBattleMons[gActiveBattler].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBattler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) + { + if (gDisableStructs[gActiveBattler].substituteHP >= gBattleMoveDamage) + { + if (gSpecialStatuses[gActiveBattler].moveturnLostHP == 0) + gSpecialStatuses[gActiveBattler].moveturnLostHP = gBattleMoveDamage; + gDisableStructs[gActiveBattler].substituteHP -= gBattleMoveDamage; + gHpDealt = gBattleMoveDamage; + } + else + { + if (gSpecialStatuses[gActiveBattler].moveturnLostHP == 0) + gSpecialStatuses[gActiveBattler].moveturnLostHP = gDisableStructs[gActiveBattler].substituteHP; + gHpDealt = gDisableStructs[gActiveBattler].substituteHP; + gDisableStructs[gActiveBattler].substituteHP = 0; + } + // check substitute fading + if (gDisableStructs[gActiveBattler].substituteHP == 0) + { + gBattlescriptCurrInstr += 2; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_SubstituteFade; + return; + } + } + else + { + gHitMarker &= ~(HITMARKER_IGNORE_SUBSTITUTE); + if (gBattleMoveDamage < 0) // hp goes up + { + gBattleMons[gActiveBattler].hp -= gBattleMoveDamage; + if (gBattleMons[gActiveBattler].hp > gBattleMons[gActiveBattler].maxHP) + gBattleMons[gActiveBattler].hp = gBattleMons[gActiveBattler].maxHP; + + } + else // hp goes down + { + if (gHitMarker & HITMARKER_x20) + { + gHitMarker &= ~(HITMARKER_x20); + } + else + { + gTakenDmg[gActiveBattler] += gBattleMoveDamage; + if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) + gTakenDmgBanks[gActiveBattler] = gBankAttacker; + else + gTakenDmgBanks[gActiveBattler] = gBankTarget; + } + + if (gBattleMons[gActiveBattler].hp > gBattleMoveDamage) + { + gBattleMons[gActiveBattler].hp -= gBattleMoveDamage; + gHpDealt = gBattleMoveDamage; + } + else + { + gHpDealt = gBattleMons[gActiveBattler].hp; + gBattleMons[gActiveBattler].hp = 0; + } + + if (!gSpecialStatuses[gActiveBattler].moveturnLostHP && !(gHitMarker & HITMARKER_x100000)) + gSpecialStatuses[gActiveBattler].moveturnLostHP = gHpDealt; + + if (TYPE_IS_PHYSICAL(moveType) && !(gHitMarker & HITMARKER_x100000) && gCurrentMove != MOVE_PAIN_SPLIT) + { + gProtectStructs[gActiveBattler].physicalDmg = gHpDealt; + gSpecialStatuses[gActiveBattler].moveturnLostHP_physical = gHpDealt; + if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) + { + gProtectStructs[gActiveBattler].physicalBank = gBankAttacker; + gSpecialStatuses[gActiveBattler].moveturnPhysicalBank = gBankAttacker; + } + else + { + gProtectStructs[gActiveBattler].physicalBank = gBankTarget; + gSpecialStatuses[gActiveBattler].moveturnPhysicalBank = gBankTarget; + } + } + else if (!TYPE_IS_PHYSICAL(moveType) && !(gHitMarker & HITMARKER_x100000)) + { + gProtectStructs[gActiveBattler].specialDmg = gHpDealt; + gSpecialStatuses[gActiveBattler].moveturnLostHP_special = gHpDealt; + if (gBattlescriptCurrInstr[1] == BS_GET_TARGET) + { + gProtectStructs[gActiveBattler].specialBank = gBankAttacker; + gSpecialStatuses[gActiveBattler].moveturnSpecialBank = gBankAttacker; + } + else + { + gProtectStructs[gActiveBattler].specialBank = gBankTarget; + gSpecialStatuses[gActiveBattler].moveturnSpecialBank = gBankTarget; + } + } + } + gHitMarker &= ~(HITMARKER_x100000); + EmitSetMonData(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBattler].hp); + MarkBufferBankForExecution(gActiveBattler); + } + } + else + { + gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + if (gSpecialStatuses[gActiveBattler].moveturnLostHP == 0) + gSpecialStatuses[gActiveBattler].moveturnLostHP = 0xFFFF; + } + gBattlescriptCurrInstr += 2; +} + +static void atk0D_critmessage(void) +{ + if (gBattleExecBuffer == 0) + { + if (gCritMultiplier == 2 && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + { + PrepareStringBattle(0xD9, gBankAttacker); + gBattleCommunication[MSG_DISPLAY] = 1; + } + gBattlescriptCurrInstr++; + } +} + +static void atk0E_effectivenesssound(void) +{ + if (gBattleExecBuffer) + return; + + gActiveBattler = gBankTarget; + if (!(gMoveResultFlags & MOVE_RESULT_MISSED)) + { + u8 flag = ~MOVE_RESULT_MISSED; + switch (gMoveResultFlags & flag) + { + case MOVE_RESULT_SUPER_EFFECTIVE: + EmitEffectivenessSound(0, 14); + MarkBufferBankForExecution(gActiveBattler); + break; + case MOVE_RESULT_NOT_VERY_EFFECTIVE: + EmitEffectivenessSound(0, 12); + MarkBufferBankForExecution(gActiveBattler); + break; + case MOVE_RESULT_DOESNT_AFFECT_FOE: + case MOVE_RESULT_FAILED: + break; + case MOVE_RESULT_FOE_ENDURED: + case MOVE_RESULT_ONE_HIT_KO: + case MOVE_RESULT_FOE_HUNG_ON: + default: + if (gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) + { + EmitEffectivenessSound(0, 14); + MarkBufferBankForExecution(gActiveBattler); + } + else if (gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE) + { + EmitEffectivenessSound(0, 12); + MarkBufferBankForExecution(gActiveBattler); + } + else if (!(gMoveResultFlags & (MOVE_RESULT_DOESNT_AFFECT_FOE | MOVE_RESULT_FAILED))) + { + EmitEffectivenessSound(0, 13); + MarkBufferBankForExecution(gActiveBattler); + } + break; + } + } + gBattlescriptCurrInstr++; +} + +static void atk0F_resultmessage(void) +{ + u32 stringId = 0; + + if (gBattleExecBuffer) + return; + + if (gMoveResultFlags & MOVE_RESULT_MISSED && (!(gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) || gBattleCommunication[6] > 2)) + { + stringId = gMissStringIds[gBattleCommunication[6]]; + gBattleCommunication[MSG_DISPLAY] = 1; + } + else + { + gBattleCommunication[MSG_DISPLAY] = 1; + switch (gMoveResultFlags & (u8)(~(MOVE_RESULT_MISSED))) + { + case MOVE_RESULT_SUPER_EFFECTIVE: + stringId = STRINGID_SUPEREFFECTIVE; + break; + case MOVE_RESULT_NOT_VERY_EFFECTIVE: + stringId = STRINGID_NOTVERYEFFECTIVE; + break; + case MOVE_RESULT_ONE_HIT_KO: + stringId = STRINGID_ONEHITKO; + break; + case MOVE_RESULT_FOE_ENDURED: + stringId = STRINGID_PKMNENDUREDHIT; + break; + case MOVE_RESULT_FAILED: + stringId = STRINGID_BUTITFAILED; + break; + case MOVE_RESULT_DOESNT_AFFECT_FOE: + stringId = STRINGID_ITDOESNTAFFECT; + break; + case MOVE_RESULT_FOE_HUNG_ON: + gLastUsedItem = gBattleMons[gBankTarget].item; + gStringBank = gBankTarget; + gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_HangedOnMsg; + return; + default: + if (gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) + { + stringId = STRINGID_ITDOESNTAFFECT; + } + else if (gMoveResultFlags & MOVE_RESULT_ONE_HIT_KO) + { + gMoveResultFlags &= ~(MOVE_RESULT_ONE_HIT_KO); + gMoveResultFlags &= ~(MOVE_RESULT_SUPER_EFFECTIVE); + gMoveResultFlags &= ~(MOVE_RESULT_NOT_VERY_EFFECTIVE); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_OneHitKOMsg; + return; + } + else if (gMoveResultFlags & MOVE_RESULT_FOE_ENDURED) + { + gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_EnduredMsg; + return; + } + else if (gMoveResultFlags & MOVE_RESULT_FOE_HUNG_ON) + { + gLastUsedItem = gBattleMons[gBankTarget].item; + gStringBank = gBankTarget; + gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_HangedOnMsg; + return; + } + else if (gMoveResultFlags & MOVE_RESULT_FAILED) + { + stringId = STRINGID_BUTITFAILED; + } + else + { + gBattleCommunication[MSG_DISPLAY] = 0; + } + } + } + + if (stringId) + PrepareStringBattle(stringId, gBankAttacker); + + gBattlescriptCurrInstr++; +} + +static void atk10_printstring(void) +{ + if (gBattleExecBuffer == 0) + { + u16 var = T2_READ_16(gBattlescriptCurrInstr + 1); + PrepareStringBattle(var, gBankAttacker); + gBattlescriptCurrInstr += 3; + gBattleCommunication[MSG_DISPLAY] = 1; + } +} + +static void atk11_printselectionstring(void) +{ + gActiveBattler = gBankAttacker; + EmitPrintStringPlayerOnly(0, T2_READ_16(gBattlescriptCurrInstr + 1)); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 3; + gBattleCommunication[MSG_DISPLAY] = 1; +} + +static void atk12_waitmessage(void) +{ + if (gBattleExecBuffer == 0) + { + if (!gBattleCommunication[MSG_DISPLAY]) + { + gBattlescriptCurrInstr += 3; + } + else + { + u16 to_wait = T2_READ_16(gBattlescriptCurrInstr + 1); + if (++gPauseCounterBattle >= to_wait) + { + gPauseCounterBattle = 0; + gBattlescriptCurrInstr += 3; + gBattleCommunication[MSG_DISPLAY] = 0; + } + } + } +} + +static void atk13_printfromtable(void) +{ + if (gBattleExecBuffer == 0) + { + u16 *ptr = (u16 *)T1_READ_PTR(gBattlescriptCurrInstr + 1); + ptr += gBattleCommunication[MULTISTRING_CHOOSER]; + PrepareStringBattle(*(u16*)ptr, gBankAttacker); + gBattlescriptCurrInstr += 5; + gBattleCommunication[MSG_DISPLAY] = 1; + } +} + +static void atk14_printselectionstringfromtable(void) +{ + if (gBattleExecBuffer == 0) + { + u16 *ptr = (u16 *)T1_READ_PTR(gBattlescriptCurrInstr + 1); // FIXME + ptr += gBattleCommunication[MULTISTRING_CHOOSER]; + gActiveBattler = gBankAttacker; + EmitPrintStringPlayerOnly(0, *(u16*)ptr); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 5; + gBattleCommunication[MSG_DISPLAY] = 1; + } +} + +u8 BankGetTurnOrder(u8 bank) +{ + int i; + for (i = 0; i < gBattlersCount; i++) + { + if (gBanksByTurnOrder[i] == bank) + break; + } + return i; +} + +//Someone please decompile this monstrosity below... +#ifdef NONMATCHING +void SetMoveEffect(bool8 primary, u8 certainArg) +{ + #define EffectAffectsUser 0x40 + register u8 certain asm("r5") = certainArg; + register bool32 StatusChanged asm("r10") = 0; + register int AffectsUser asm("r6") = 0; //0x40 otherwise + bool32 NoSunCanFreeze = 1; + + if (gBattleCommunication[MOVE_EFFECT_BYTE] & EffectAffectsUser) + { + gEffectBank = gBankAttacker; //bank that effects get applied on + gBattleCommunication[MOVE_EFFECT_BYTE] &= ~(EffectAffectsUser); + AffectsUser = EffectAffectsUser; + gBattleStruct->scriptingActive = gBankTarget; //theoretically the attacker + } + else + { + gEffectBank = gBankTarget; + gBattleStruct->scriptingActive = gBankAttacker; + } + + if (gBattleMons[gEffectBank].ability == ABILITY_SHIELD_DUST && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && + !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 9) + {gBattlescriptCurrInstr++; return;} + + if (gSideAffecting[GetBattlerPosition(gEffectBank) & 1] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && + !primary && gBattleCommunication[MOVE_EFFECT_BYTE] <= 7) + {gBattlescriptCurrInstr++; return;} + + //make sure at least ONE HP except payday and thief + if (gBattleMons[gEffectBank].hp == 0 && gBattleCommunication[MOVE_EFFECT_BYTE] != 0xB && gBattleCommunication[MOVE_EFFECT_BYTE] != 0x1F) + {gBattlescriptCurrInstr++; return;} + + if (gBattleMons[gEffectBank].status2 & STATUS2_SUBSTITUTE && AffectsUser != EffectAffectsUser) + {gBattlescriptCurrInstr++; return;} + + if (gBattleCommunication[MOVE_EFFECT_BYTE] <= 6) //status change + { + switch (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) + { + case STATUS_SLEEP: + //check active uproar + if (gBattleMons[gEffectBank].ability != ABILITY_SOUNDPROOF) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount && !(gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR); gActiveBattler++) {} + } + else + gActiveBattler = gBattlersCount; + if (gBattleMons[gEffectBank].status1) {break;} + if (gActiveBattler != gBattlersCount) {break;} //nice way of checking uproar... + if (gBattleMons[gEffectBank].ability == ABILITY_VITAL_SPIRIT) {break;} + if (gBattleMons[gEffectBank].ability == ABILITY_INSOMNIA) {break;} + + CancelMultiTurnMoves(gEffectBank); + StatusChanged = 1; + break; + case STATUS_POISON: + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY && (primary == 1 || certain == 0x80)) + { + gLastUsedAbility = ABILITY_IMMUNITY; + RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); + BattleScriptPush(gBattlescriptCurrInstr + 1); + //_0801E664: + gBattlescriptCurrInstr = BattleScript_PSNPrevention; + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + return; + } + else + {gBattleCommunication[MULTISTRING_CHOOSER] = 0; return;} + } + if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) + && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && (primary == 1 || certain == 0x80)) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PSNPrevention; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + return; + } + if (gBattleMons[gEffectBank].type1 == TYPE_POISON) {break;} + if (gBattleMons[gEffectBank].type2 == TYPE_POISON) {break;} + if (gBattleMons[gEffectBank].type1 == TYPE_STEEL) {break;} + if (gBattleMons[gEffectBank].type2 == TYPE_STEEL) {break;} + if (gBattleMons[gEffectBank].status1) {break;} + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY) {break;} + + StatusChanged = 1; + break; + case STATUS_BURN: + if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL && (primary == 1 || certain == 0x80)) + { + gLastUsedAbility = ABILITY_WATER_VEIL; + RecordAbilityBattle(gEffectBank, ABILITY_WATER_VEIL); + BattleScriptPush(gBattlescriptCurrInstr + 1); + //_0801E664: + gBattlescriptCurrInstr = BattleScript_BRNPrevention; + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + return; + } + else + {gBattleCommunication[MULTISTRING_CHOOSER] = 0; return;} + } + if ((gBattleMons[gEffectBank].type1 == TYPE_FIRE || gBattleMons[gEffectBank].type2 == TYPE_FIRE) + && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && (primary == 1 || certain == 0x80)) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_BRNPrevention; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + return; + } + if (gBattleMons[gEffectBank].type1 == TYPE_FIRE) {break;} + if (gBattleMons[gEffectBank].type2 == TYPE_FIRE) {break;} + if (gBattleMons[gEffectBank].ability == ABILITY_WATER_VEIL) {break;} + if (gBattleMons[gEffectBank].status1 == 0) {break;} + StatusChanged = 1; + break; + case STATUS_FREEZE: + if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY) {NoSunCanFreeze = 0;} + if (gBattleMons[gEffectBank].type1 == TYPE_ICE) {break;} + if (gBattleMons[gEffectBank].type2 == TYPE_ICE) {break;} + if (gBattleMons[gEffectBank].status1) {break;} + if (NoSunCanFreeze == 0) {break;} + if (gBattleMons[gEffectBank].ability == ABILITY_MAGMA_ARMOR) {break;} + + CancelMultiTurnMoves(gEffectBank); + StatusChanged = 1; + break; + case STATUS_PARALYSIS: + if (gBattleMons[gEffectBank].ability == ABILITY_LIMBER) + { + if ((primary == 1 || certain == 0x80)) + { + gLastUsedAbility = ABILITY_LIMBER; + RecordAbilityBattle(gEffectBank, ABILITY_LIMBER); + BattleScriptPush(gBattlescriptCurrInstr + 1); + //_0801E664: + gBattlescriptCurrInstr = BattleScript_PRLZPrevention; + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + return; + } + else + {gBattleCommunication[MULTISTRING_CHOOSER] = 0; return;} + } + else {break;} + } + if (gBattleMons[gEffectBank].status1) {break;} + StatusChanged = 1; + break; + case STATUS_TOXIC_POISON: + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY && (primary == 1 || certain == 0x80)) + { + gLastUsedAbility = ABILITY_IMMUNITY; + RecordAbilityBattle(gEffectBank, ABILITY_IMMUNITY); + BattleScriptPush(gBattlescriptCurrInstr + 1); + //_0801E664: + gBattlescriptCurrInstr = BattleScript_PSNPrevention; + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + return; + } + else + {gBattleCommunication[MULTISTRING_CHOOSER] = 0; return;} + } + if ((gBattleMons[gEffectBank].type1 == TYPE_POISON || gBattleMons[gEffectBank].type2 == TYPE_POISON || gBattleMons[gEffectBank].type1 == TYPE_STEEL || gBattleMons[gEffectBank].type2 == TYPE_STEEL) + && !(gHitMarker & HITMARKER_IGNORE_SAFEGUARD) && (primary == 1 || certain == 0x80)) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PSNPrevention; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + return; + } + if (gBattleMons[gEffectBank].status1) {break;} + if (gBattleMons[gEffectBank].type1 != TYPE_POISON && + gBattleMons[gEffectBank].type2 != TYPE_POISON && + gBattleMons[gEffectBank].type1 != TYPE_STEEL && + gBattleMons[gEffectBank].type2 != TYPE_STEEL) + { + if (gBattleMons[gEffectBank].ability == ABILITY_IMMUNITY) {break;} + gBattleMons[gEffectBank].status1 &= ~(0x9); //This gets (correctly) optimized out... + StatusChanged = 1; + break; + } + else + gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE; + break; + } + if (StatusChanged == 1) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + if (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]] == STATUS_SLEEP) + gBattleMons[gEffectBank].status1 |= ((Random() & 3) + 2); + else + gBattleMons[gEffectBank].status1 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gActiveBattler = gEffectBank; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gEffectBank].status1); + MarkBufferBankForExecution(gActiveBattler); + if (gHitMarker & HITMARKER_IGNORE_SAFEGUARD) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gHitMarker &= ~(HITMARKER_IGNORE_SAFEGUARD); + } + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + if (gBattleCommunication[MOVE_EFFECT_BYTE] == 2 || gBattleCommunication[MOVE_EFFECT_BYTE] == 6 || gBattleCommunication[MOVE_EFFECT_BYTE] == 5 || gBattleCommunication[MOVE_EFFECT_BYTE] == 3) + { + gBattleStruct->synchroniseEffect = gBattleCommunication[MOVE_EFFECT_BYTE]; + gHitMarker |= HITMARKER_SYNCHRONISE_EFFECT; + } + return; + } + else if (StatusChanged == 0) + {gBattlescriptCurrInstr++; return;} + } + else + { + if (gBattleMons[gEffectBank].status2 & sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) + { + gBattlescriptCurrInstr++; + return; + } + switch (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) + { + case 7: //confusion + if (gBattleMons[gEffectBank].ability == ABILITY_OWN_TEMPO) + {gBattlescriptCurrInstr++; return;} + if (gBattleMons[gEffectBank].status2 & STATUS2_CONFUSION) + {gBattlescriptCurrInstr++; return;} + gBattleMons[gEffectBank].status2 |= (((Random()) % 0x4)) + 2; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + break; + case 8: //flinch + if (gBattleMons[gEffectBank].ability == ABILITY_INNER_FOCUS) + { + if (primary == 1 || certain == 0x80) + { + gLastUsedAbility = ABILITY_INNER_FOCUS; + RecordAbilityBattle(gEffectBank, ABILITY_INNER_FOCUS); + gBattlescriptCurrInstr = BattleScript_FlinchPrevention; + return; + } + else + {gBattlescriptCurrInstr++; return;} + } + else + { + if (BankGetTurnOrder(gEffectBank) > gCurrentTurnActionNumber) + gBattleMons[gEffectBank].status2 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattlescriptCurrInstr++; return; + } + break; + case 10: //uproar + if (gBattleMons[gEffectBank].status2 & STATUS2_UPROAR) + {gBattlescriptCurrInstr++; return;} + gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gEffectBank] = gCurrentMove; + gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 2) << 4; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + break; + case 11: //pay day + if (!(GetBattlerPosition(gBankAttacker) & 1)) + { + u16 PayDay = gPaydayMoney; + gPaydayMoney += (gBattleMons[gBankAttacker].level * 5); + if (PayDay > gPaydayMoney) + gPaydayMoney = 0xFFFF; + } + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + break; + case 9: //tri attack + if (gBattleMons[gEffectBank].status1) + {gBattlescriptCurrInstr++; return;} + gBattleCommunication[MOVE_EFFECT_BYTE] = Random() % 3 + 3; + SetMoveEffect(0, 0); + break; + case 12: //charging move + gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gEffectBank] = gCurrentMove; + gProtectStructs[gEffectBank].chargingTurn = 1; + gBattlescriptCurrInstr++; + break; + case 13: //wrap + if (gBattleMons[gEffectBank].status2 & STATUS2_WRAPPED) + {gBattlescriptCurrInstr++; return;} + gBattleMons[gEffectBank].status2 |= ((Random() & 3) + 2) << 0xD; + gBattleStruct->wrappedMove[gEffectBank*2] = (u8)gCurrentMove; + (1 + gBattleStruct->wrappedMove)[gEffectBank*2] = gCurrentMove >> 8; //don't ask. + gBattleStruct->wrappedBy[gEffectBank] = gBankAttacker; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + while (gBattleCommunication[MULTISTRING_CHOOSER] <= 4 + && gCurrentMove != gTrappingMoves[gBattleCommunication[MULTISTRING_CHOOSER]]) + gBattleCommunication[MULTISTRING_CHOOSER]++; + break; + case 14: //25% recoil + gBattleMoveDamage = (gHpDealt) / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + break; + case 15 ... 21: //stat + 1 + if (ChangeStatBuffs(0x10, gBattleCommunication[MOVE_EFFECT_BYTE] + 0xF2, certain, 0)) {gBattlescriptCurrInstr++;} + else + { + gBattleStruct->animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; //TODO: the arg ptr is wrong by one + gBattleStruct->animArg2 = 0; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_StatUp; + } + break; + case 22 ... 28: //stat - 1 + if (ChangeStatBuffs(~(0x6f), gBattleCommunication[MOVE_EFFECT_BYTE] + 0xEB, certain, 0)) {gBattlescriptCurrInstr++;} //TODO: negation doesnt work correctly + else + { + gBattleStruct->animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; + gBattleStruct->animArg2 = 0; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_StatDown; + } + break; + case 39 ... 45: //stat + 2 + if (ChangeStatBuffs(0x20, gBattleCommunication[MOVE_EFFECT_BYTE] + 0xDA, certain, 0)) {gBattlescriptCurrInstr++;} + else + { + gBattleStruct->animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; + gBattleStruct->animArg2 = 0; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_StatUp; + } + break; + case 46 ... 52: //stat - 2 + if (ChangeStatBuffs(~(0x5f), gBattleCommunication[MOVE_EFFECT_BYTE] + 0xD3, certain, 0)) {gBattlescriptCurrInstr++;} + else + { + gBattleStruct->animArg1 = gBattleCommunication[MOVE_EFFECT_BYTE] & 0x3F; + gBattleStruct->animArg2 = 0; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_StatDown; + } + break; + case 29: //recharge + gBattleMons[gEffectBank].status2 |= STATUS2_RECHARGE; + gDisableStructs[gEffectBank].rechargeCounter = 2; + gLockedMoves[gEffectBank] = gCurrentMove; + gBattlescriptCurrInstr++; + break; + case 30: //rage + gBattleMons[gBankAttacker].status2 |= STATUS2_RAGE; + gBattlescriptCurrInstr++; + break; + case 31: //item steal + { + u8 side = GetBattlerSide(gBankAttacker); + if (GetBattlerSide(gBankAttacker) == 1 && !(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK)) && gTrainerBattleOpponent != 0x400) + {gBattlescriptCurrInstr++; return;} + if (!(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK)) && gTrainerBattleOpponent != 0x400 && (gWishFutureKnock.knockedOffPokes[side] & gBitTable[gBattlerPartyIndexes[gBankAttacker]])) + {gBattlescriptCurrInstr++; return;} + if (gBattleMons[gBankTarget].item && gBattleMons[gBankTarget].ability == ABILITY_STICKY_HOLD) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_NoItemSteal; + gLastUsedAbility = gBattleMons[gBankTarget].ability; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + return; + } + if (gBattleMons[gBankAttacker].item) + {gBattlescriptCurrInstr++; return;} + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + {gBattlescriptCurrInstr++; return;} + if (gBattleMons[gBankTarget].item == 0) + {gBattlescriptCurrInstr++; return;} + + gLastUsedItem = gBattleMons[gBankTarget].item; + USED_HELD_ITEM(bank) = gLastUsedItem; + gBattleMons[gBankTarget].item = 0; + + gActiveBattler = gBankAttacker; + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gLastUsedItem); + MarkBufferBankForExecution(gBankAttacker); + + gActiveBattler = gBankTarget; + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gBankTarget].item); + MarkBufferBankForExecution(gBankTarget); + + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_ItemSteal; + + CHOICED_MOVE(gBankTarget) = 0; + } + break; + case 32: //escape prevention + gBattleMons[gBankTarget].status2 |= STATUS2_RECHARGE; + gDisableStructs[gBankTarget].bankPreventingEscape = gBankAttacker; + gBattlescriptCurrInstr++; + break; + case 33: //nightmare + gBattleMons[gBankTarget].status2 |= STATUS2_NIGHTMARE; + gBattlescriptCurrInstr++; + break; + case 34: //ancientpower + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_AllStatsUp; + return; + case 35: //break free rapidspin + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_RapidSpinAway; + return; + case 36: //paralysis removal + if (gBattleMons[gBankTarget].status1 & STATUS_PARALYSIS) + { + gBattleMons[gBankTarget].status1 &= ~(STATUS_PARALYSIS); + gActiveBattler = gBankTarget; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBankTarget].status1); + MarkBufferBankForExecution(gActiveBattler); + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal; + } + else + {gBattlescriptCurrInstr++; return;} + break; + case 37: //superpower + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_AtkDefDown; + return; + case 38: //33% recoil + gBattleMoveDamage = gHpDealt / 3; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = gMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; + break; + case 53: //thrash + if (!(gBattleMons[gEffectBank].status2 & STATUS2_LOCK_CONFUSE)) + { + gBattleMons[gEffectBank].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gEffectBank] = gCurrentMove; + gBattleMons[gEffectBank].status2 |= (((Random() & 1) + 2) << 0xA); + } + else + {gBattlescriptCurrInstr++; return;} + break; + case 54: //knock off + if (gBattleMons[gEffectBank].ability == ABILITY_STICKY_HOLD) + { + if (gBattleMons[gEffectBank].item == 0) + {gBattlescriptCurrInstr++; return;} + gLastUsedAbility = ABILITY_STICKY_HOLD; + gBattlescriptCurrInstr = BattleScript_NoItemSteal; + RecordAbilityBattle(gEffectBank, ABILITY_STICKY_HOLD); + return; + } + if (gBattleMons[gEffectBank].item == 0) + {gBattlescriptCurrInstr++; return;} + else + { + u8 side = GetBattlerSide(gEffectBank); + gLastUsedItem = gBattleMons[gEffectBank].item; + gBattleMons[gEffectBank].item = 0; + gWishFutureKnock.knockedOffPokes[side] |= gBitTable[gBattlerPartyIndexes[gEffectBank]]; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_KnockedOff; + + CHOICED_MOVE(gEffectBank) = 0; + } + break; + case 59: //overheat + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_SAtkDown2; + return; + } + } +} +#else +NAKED +void SetMoveEffect(bool8 primary, u8 certainArg) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x8\n\ + lsls r0, 24\n\ + lsrs r4, r0, 24\n\ + lsls r1, 24\n\ + lsrs r5, r1, 24\n\ + movs r0, 0\n\ + mov r10, r0\n\ + movs r6, 0\n\ + movs r1, 0x1\n\ + str r1, [sp, 0x4]\n\ + ldr r1, _0801E430 @ =gBattleCommunication\n\ + ldrb r3, [r1, 0x3]\n\ + movs r0, 0x40\n\ + ands r0, r3\n\ + adds r7, r1, 0\n\ + cmp r0, 0\n\ + beq _0801E444\n\ + ldr r2, _0801E434 @ =gEffectBank\n\ + ldr r0, _0801E438 @ =gBankAttacker\n\ + ldrb r0, [r0]\n\ + strb r0, [r2]\n\ + movs r0, 0xBF\n\ + ands r0, r3\n\ + strb r0, [r7, 0x3]\n\ + movs r6, 0x40\n\ + ldr r0, _0801E43C @ =gSharedMem\n\ + ldr r1, _0801E440 @ =gBankTarget\n\ + b _0801E450\n\ + .align 2, 0\n\ +_0801E430: .4byte gBattleCommunication\n\ +_0801E434: .4byte gEffectBank\n\ +_0801E438: .4byte gBankAttacker\n\ +_0801E43C: .4byte gSharedMem\n\ +_0801E440: .4byte gBankTarget\n\ +_0801E444:\n\ + ldr r2, _0801E538 @ =gEffectBank\n\ + ldr r0, _0801E53C @ =gBankTarget\n\ + ldrb r0, [r0]\n\ + strb r0, [r2]\n\ + ldr r0, _0801E540 @ =gSharedMem\n\ + ldr r1, _0801E544 @ =gBankAttacker\n\ +_0801E450:\n\ + ldrb r1, [r1]\n\ + ldr r3, _0801E548 @ =0x00016003\n\ + adds r0, r3\n\ + strb r1, [r0]\n\ + mov r8, r2\n\ + ldr r2, _0801E54C @ =gBattleMons\n\ + mov r0, r8\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r2\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x13\n\ + bne _0801E48A\n\ + ldr r0, _0801E550 @ =gHitMarker\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 6\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0801E48A\n\ + cmp r4, 0\n\ + bne _0801E48A\n\ + ldrb r0, [r7, 0x3]\n\ + cmp r0, 0x9\n\ + bhi _0801E48A\n\ + bl _0801F5DC\n\ +_0801E48A:\n\ + mov r1, r8\n\ + ldrb r0, [r1]\n\ + bl GetBattlerPosition\n\ + ldr r2, _0801E554 @ =gSideAffecting\n\ + movs r1, 0x1\n\ + ands r1, r0\n\ + lsls r1, 1\n\ + adds r1, r2\n\ + ldrh r1, [r1]\n\ + movs r0, 0x20\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0801E4C4\n\ + ldr r0, _0801E550 @ =gHitMarker\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 6\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0801E4C4\n\ + cmp r4, 0\n\ + bne _0801E4C4\n\ + ldr r0, _0801E558 @ =gBattleCommunication\n\ + ldrb r0, [r0, 0x3]\n\ + cmp r0, 0x7\n\ + bhi _0801E4C4\n\ + bl _0801F5DC\n\ +_0801E4C4:\n\ + ldr r3, _0801E54C @ =gBattleMons\n\ + ldr r2, _0801E538 @ =gEffectBank\n\ + ldrb r1, [r2]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r3\n\ + ldrh r0, [r0, 0x28]\n\ + mov r8, r2\n\ + mov r9, r3\n\ + cmp r0, 0\n\ + bne _0801E4EA\n\ + ldr r0, _0801E558 @ =gBattleCommunication\n\ + ldrb r0, [r0, 0x3]\n\ + cmp r0, 0xB\n\ + beq _0801E4EA\n\ + cmp r0, 0x1F\n\ + beq _0801E4EA\n\ + bl _0801F5DC\n\ +_0801E4EA:\n\ + mov r2, r8\n\ + ldrb r1, [r2]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + mov r1, r9\n\ + adds r1, 0x50\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 17\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0801E50C\n\ + cmp r6, 0x40\n\ + beq _0801E50C\n\ + bl _0801F5DC\n\ +_0801E50C:\n\ + ldr r0, _0801E558 @ =gBattleCommunication\n\ + ldrb r1, [r0, 0x3]\n\ + adds r7, r0, 0\n\ + cmp r1, 0x6\n\ + bls _0801E518\n\ + b _0801EB4A\n\ +_0801E518:\n\ + ldr r1, _0801E55C @ =sStatusFlagsForMoveEffects\n\ + ldrb r0, [r7, 0x3]\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + cmp r0, 0x10\n\ + bne _0801E528\n\ + b _0801E714\n\ +_0801E528:\n\ + cmp r0, 0x10\n\ + bhi _0801E560\n\ + cmp r0, 0x7\n\ + beq _0801E57A\n\ + cmp r0, 0x8\n\ + bne _0801E536\n\ + b _0801E630\n\ +_0801E536:\n\ + b _0801EA14\n\ + .align 2, 0\n\ +_0801E538: .4byte gEffectBank\n\ +_0801E53C: .4byte gBankTarget\n\ +_0801E540: .4byte gSharedMem\n\ +_0801E544: .4byte gBankAttacker\n\ +_0801E548: .4byte 0x00016003\n\ +_0801E54C: .4byte gBattleMons\n\ +_0801E550: .4byte gHitMarker\n\ +_0801E554: .4byte gSideAffecting\n\ +_0801E558: .4byte gBattleCommunication\n\ +_0801E55C: .4byte sStatusFlagsForMoveEffects\n\ +_0801E560:\n\ + cmp r0, 0x40\n\ + bne _0801E566\n\ + b _0801E888\n\ +_0801E566:\n\ + cmp r0, 0x40\n\ + bhi _0801E572\n\ + cmp r0, 0x20\n\ + bne _0801E570\n\ + b _0801E7EA\n\ +_0801E570:\n\ + b _0801EA14\n\ +_0801E572:\n\ + cmp r0, 0x80\n\ + bne _0801E578\n\ + b _0801E8E4\n\ +_0801E578:\n\ + b _0801EA14\n\ +_0801E57A:\n\ + mov r3, r8\n\ + ldrb r1, [r3]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + add r0, r9\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x2B\n\ + beq _0801E5DC\n\ + ldr r0, _0801E5D4 @ =gActiveBattler\n\ + movs r1, 0\n\ + strb r1, [r0]\n\ + ldr r1, _0801E5D8 @ =gBattlersCount\n\ + ldrb r3, [r1]\n\ + adds r7, r0, 0\n\ + mov r12, r1\n\ + cmp r3, 0\n\ + beq _0801E5E8\n\ + mov r4, r9\n\ + ldr r0, [r4, 0x50]\n\ + movs r1, 0x70\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0801E5E8\n\ + adds r1, r7, 0\n\ + mov r6, r9\n\ + adds r6, 0x50\n\ + movs r5, 0x58\n\ + movs r4, 0x70\n\ +_0801E5B4:\n\ + ldrb r0, [r1]\n\ + adds r0, 0x1\n\ + strb r0, [r1]\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, r3\n\ + bcs _0801E5E8\n\ + ldrb r0, [r7]\n\ + muls r0, r5\n\ + adds r0, r6\n\ + ldr r0, [r0]\n\ + ands r0, r4\n\ + cmp r0, 0\n\ + beq _0801E5B4\n\ + b _0801E5E8\n\ + .align 2, 0\n\ +_0801E5D4: .4byte gActiveBattler\n\ +_0801E5D8: .4byte gBattlersCount\n\ +_0801E5DC:\n\ + ldr r0, _0801E628 @ =gActiveBattler\n\ + ldr r2, _0801E62C @ =gBattlersCount\n\ + ldrb r1, [r2]\n\ + strb r1, [r0]\n\ + adds r7, r0, 0\n\ + mov r12, r2\n\ +_0801E5E8:\n\ + mov r0, r8\n\ + ldrb r2, [r0]\n\ + movs r0, 0x58\n\ + adds r1, r2, 0\n\ + muls r1, r0\n\ + mov r0, r9\n\ + adds r0, 0x4C\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + beq _0801E600\n\ + b _0801EA14\n\ +_0801E600:\n\ + ldrb r0, [r7]\n\ + mov r3, r12\n\ + ldrb r3, [r3]\n\ + cmp r0, r3\n\ + beq _0801E60C\n\ + b _0801EA14\n\ +_0801E60C:\n\ + mov r4, r9\n\ + adds r0, r1, r4\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x48\n\ + bne _0801E61A\n\ + b _0801EA14\n\ +_0801E61A:\n\ + cmp r0, 0xF\n\ + bne _0801E620\n\ + b _0801EA14\n\ +_0801E620:\n\ + adds r0, r2, 0\n\ + bl CancelMultiTurnMoves\n\ + b _0801EA04\n\ + .align 2, 0\n\ +_0801E628: .4byte gActiveBattler\n\ +_0801E62C: .4byte gBattlersCount\n\ +_0801E630:\n\ + mov r2, r8\n\ + ldrb r1, [r2]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + add r0, r9\n\ + adds r0, 0x20\n\ + ldrb r1, [r0]\n\ + cmp r1, 0x11\n\ + bne _0801E688\n\ + cmp r4, 0x1\n\ + beq _0801E64A\n\ + cmp r5, 0x80\n\ + bne _0801E688\n\ +_0801E64A:\n\ + ldr r0, _0801E678 @ =gLastUsedAbility\n\ + strb r1, [r0]\n\ + mov r3, r8\n\ + ldrb r0, [r3]\n\ + movs r1, 0x11\n\ + bl RecordAbilityBattle\n\ + ldr r4, _0801E67C @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801E680 @ =BattleScript_PSNPrevention\n\ +_0801E664:\n\ + str r0, [r4]\n\ + ldr r2, _0801E684 @ =gHitMarker\n\ + ldr r1, [r2]\n\ + movs r0, 0x80\n\ + lsls r0, 6\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0801E676\n\ + b _0801E928\n\ +_0801E676:\n\ + b _0801E94C\n\ + .align 2, 0\n\ +_0801E678: .4byte gLastUsedAbility\n\ +_0801E67C: .4byte gBattlescriptCurrInstr\n\ +_0801E680: .4byte BattleScript_PSNPrevention\n\ +_0801E684: .4byte gHitMarker\n\ +_0801E688:\n\ + mov r1, r8\n\ + ldrb r0, [r1]\n\ + movs r1, 0x58\n\ + muls r0, r1\n\ + add r0, r9\n\ + adds r1, r0, 0\n\ + adds r1, 0x21\n\ + ldrb r1, [r1]\n\ + cmp r1, 0x3\n\ + beq _0801E6AC\n\ + adds r0, 0x22\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x3\n\ + beq _0801E6AC\n\ + cmp r1, 0x8\n\ + beq _0801E6AC\n\ + cmp r0, 0x8\n\ + bne _0801E6C6\n\ +_0801E6AC:\n\ + ldr r0, _0801E710 @ =gHitMarker\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 6\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0801E6C6\n\ + cmp r4, 0x1\n\ + bne _0801E6C0\n\ + b _0801E98C\n\ +_0801E6C0:\n\ + cmp r5, 0x80\n\ + bne _0801E6C6\n\ + b _0801E98C\n\ +_0801E6C6:\n\ + mov r2, r8\n\ + ldrb r1, [r2]\n\ + movs r0, 0x58\n\ + muls r1, r0\n\ + mov r4, r9\n\ + adds r3, r1, r4\n\ + adds r0, r3, 0\n\ + adds r0, 0x21\n\ + ldrb r4, [r0]\n\ + cmp r4, 0x3\n\ + bne _0801E6DE\n\ + b _0801EA14\n\ +_0801E6DE:\n\ + adds r0, 0x1\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x3\n\ + bne _0801E6E8\n\ + b _0801EA14\n\ +_0801E6E8:\n\ + cmp r4, 0x8\n\ + bne _0801E6EE\n\ + b _0801EA14\n\ +_0801E6EE:\n\ + cmp r0, 0x8\n\ + bne _0801E6F4\n\ + b _0801EA14\n\ +_0801E6F4:\n\ + mov r0, r9\n\ + adds r0, 0x4C\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + beq _0801E702\n\ + b _0801EA14\n\ +_0801E702:\n\ + adds r0, r3, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x11\n\ + bne _0801E70E\n\ + b _0801EA14\n\ +_0801E70E:\n\ + b _0801EA04\n\ + .align 2, 0\n\ +_0801E710: .4byte gHitMarker\n\ +_0801E714:\n\ + mov r2, r8\n\ + ldrb r1, [r2]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + add r0, r9\n\ + adds r0, 0x20\n\ + ldrb r1, [r0]\n\ + cmp r1, 0x29\n\ + bne _0801E758\n\ + cmp r4, 0x1\n\ + beq _0801E72E\n\ + cmp r5, 0x80\n\ + bne _0801E758\n\ +_0801E72E:\n\ + ldr r0, _0801E74C @ =gLastUsedAbility\n\ + strb r1, [r0]\n\ + mov r3, r8\n\ + ldrb r0, [r3]\n\ + movs r1, 0x29\n\ + bl RecordAbilityBattle\n\ + ldr r4, _0801E750 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801E754 @ =BattleScript_BRNPrevention\n\ + b _0801E664\n\ + .align 2, 0\n\ +_0801E74C: .4byte gLastUsedAbility\n\ +_0801E750: .4byte gBattlescriptCurrInstr\n\ +_0801E754: .4byte BattleScript_BRNPrevention\n\ +_0801E758:\n\ + mov r0, r8\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + mov r2, r9\n\ + adds r1, r0, r2\n\ + adds r0, r1, 0\n\ + adds r0, 0x21\n\ + ldrb r0, [r0]\n\ + cmp r0, 0xA\n\ + beq _0801E778\n\ + adds r0, r1, 0\n\ + adds r0, 0x22\n\ + ldrb r0, [r0]\n\ + cmp r0, 0xA\n\ + bne _0801E7A8\n\ +_0801E778:\n\ + ldr r0, _0801E79C @ =gHitMarker\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 6\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0801E7A8\n\ + cmp r4, 0x1\n\ + beq _0801E78E\n\ + cmp r5, 0x80\n\ + bne _0801E7A8\n\ +_0801E78E:\n\ + ldr r4, _0801E7A0 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801E7A4 @ =BattleScript_BRNPrevention\n\ + b _0801E998\n\ + .align 2, 0\n\ +_0801E79C: .4byte gHitMarker\n\ +_0801E7A0: .4byte gBattlescriptCurrInstr\n\ +_0801E7A4: .4byte BattleScript_BRNPrevention\n\ +_0801E7A8:\n\ + mov r3, r8\n\ + ldrb r0, [r3]\n\ + movs r1, 0x58\n\ + adds r2, r0, 0\n\ + muls r2, r1\n\ + mov r4, r9\n\ + adds r1, r2, r4\n\ + adds r0, r1, 0\n\ + adds r0, 0x21\n\ + ldrb r0, [r0]\n\ + cmp r0, 0xA\n\ + bne _0801E7C2\n\ + b _0801EA14\n\ +_0801E7C2:\n\ + adds r0, r1, 0\n\ + adds r0, 0x22\n\ + ldrb r0, [r0]\n\ + cmp r0, 0xA\n\ + bne _0801E7CE\n\ + b _0801EA14\n\ +_0801E7CE:\n\ + adds r0, r1, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x29\n\ + bne _0801E7DA\n\ + b _0801EA14\n\ +_0801E7DA:\n\ + mov r0, r9\n\ + adds r0, 0x4C\n\ + adds r0, r2, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + beq _0801E7E8\n\ + b _0801EA14\n\ +_0801E7E8:\n\ + b _0801EA04\n\ +_0801E7EA:\n\ + movs r0, 0\n\ + str r0, [sp]\n\ + movs r0, 0x13\n\ + movs r1, 0\n\ + movs r2, 0xD\n\ + movs r3, 0\n\ + bl AbilityBattleEffects\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0\n\ + bne _0801E826\n\ + str r0, [sp]\n\ + movs r0, 0x13\n\ + movs r1, 0\n\ + movs r2, 0x4D\n\ + movs r3, 0\n\ + bl AbilityBattleEffects\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _0801E826\n\ + ldr r0, _0801E87C @ =gBattleWeather\n\ + ldrh r1, [r0]\n\ + movs r0, 0x60\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0801E826\n\ + movs r1, 0\n\ + str r1, [sp, 0x4]\n\ +_0801E826:\n\ + ldr r4, _0801E880 @ =gBattleMons\n\ + ldr r0, _0801E884 @ =gEffectBank\n\ + ldrb r3, [r0]\n\ + movs r0, 0x58\n\ + adds r2, r3, 0\n\ + muls r2, r0\n\ + adds r1, r2, r4\n\ + adds r0, r1, 0\n\ + adds r0, 0x21\n\ + ldrb r0, [r0]\n\ + cmp r0, 0xF\n\ + bne _0801E840\n\ + b _0801EA14\n\ +_0801E840:\n\ + adds r0, r1, 0\n\ + adds r0, 0x22\n\ + ldrb r0, [r0]\n\ + cmp r0, 0xF\n\ + bne _0801E84C\n\ + b _0801EA14\n\ +_0801E84C:\n\ + adds r0, r4, 0\n\ + adds r0, 0x4C\n\ + adds r0, r2, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + beq _0801E85A\n\ + b _0801EA14\n\ +_0801E85A:\n\ + ldr r2, [sp, 0x4]\n\ + cmp r2, 0\n\ + bne _0801E862\n\ + b _0801EA14\n\ +_0801E862:\n\ + adds r0, r1, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x28\n\ + bne _0801E86E\n\ + b _0801EA14\n\ +_0801E86E:\n\ + adds r0, r3, 0\n\ + bl CancelMultiTurnMoves\n\ + movs r3, 0x1\n\ + mov r10, r3\n\ + b _0801EA14\n\ + .align 2, 0\n\ +_0801E87C: .4byte gBattleWeather\n\ +_0801E880: .4byte gBattleMons\n\ +_0801E884: .4byte gEffectBank\n\ +_0801E888:\n\ + mov r0, r8\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + muls r1, r0\n\ + mov r2, r9\n\ + adds r0, r1, r2\n\ + adds r0, 0x20\n\ + ldrb r2, [r0]\n\ + cmp r2, 0x7\n\ + bne _0801E8D0\n\ + cmp r4, 0x1\n\ + beq _0801E8A6\n\ + cmp r5, 0x80\n\ + beq _0801E8A6\n\ + b _0801EA14\n\ +_0801E8A6:\n\ + ldr r0, _0801E8C4 @ =gLastUsedAbility\n\ + strb r2, [r0]\n\ + mov r3, r8\n\ + ldrb r0, [r3]\n\ + movs r1, 0x7\n\ + bl RecordAbilityBattle\n\ + ldr r4, _0801E8C8 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801E8CC @ =BattleScript_PRLZPrevention\n\ + b _0801E664\n\ + .align 2, 0\n\ +_0801E8C4: .4byte gLastUsedAbility\n\ +_0801E8C8: .4byte gBattlescriptCurrInstr\n\ +_0801E8CC: .4byte BattleScript_PRLZPrevention\n\ +_0801E8D0:\n\ + mov r0, r9\n\ + adds r0, 0x4C\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + beq _0801E8DE\n\ + b _0801EA14\n\ +_0801E8DE:\n\ + movs r4, 0x1\n\ + mov r10, r4\n\ + b _0801EA14\n\ +_0801E8E4:\n\ + mov r0, r8\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + add r0, r9\n\ + adds r0, 0x20\n\ + ldrb r1, [r0]\n\ + cmp r1, 0x11\n\ + bne _0801E952\n\ + cmp r4, 0x1\n\ + beq _0801E8FE\n\ + cmp r5, 0x80\n\ + bne _0801E952\n\ +_0801E8FE:\n\ + ldr r0, _0801E938 @ =gLastUsedAbility\n\ + strb r1, [r0]\n\ + mov r1, r8\n\ + ldrb r0, [r1]\n\ + movs r1, 0x11\n\ + bl RecordAbilityBattle\n\ + ldr r4, _0801E93C @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801E940 @ =BattleScript_PSNPrevention\n\ + str r0, [r4]\n\ + ldr r2, _0801E944 @ =gHitMarker\n\ + ldr r1, [r2]\n\ + movs r0, 0x80\n\ + lsls r0, 6\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0801E94C\n\ +_0801E928:\n\ + movs r0, 0x1\n\ + strb r0, [r7, 0x5]\n\ + ldr r0, _0801E948 @ =0xffffdfff\n\ + ands r1, r0\n\ + str r1, [r2]\n\ + bl _0801F5FA\n\ + .align 2, 0\n\ +_0801E938: .4byte gLastUsedAbility\n\ +_0801E93C: .4byte gBattlescriptCurrInstr\n\ +_0801E940: .4byte BattleScript_PSNPrevention\n\ +_0801E944: .4byte gHitMarker\n\ +_0801E948: .4byte 0xffffdfff\n\ +_0801E94C:\n\ + strb r0, [r7, 0x5]\n\ + bl _0801F5FA\n\ +_0801E952:\n\ + mov r2, r8\n\ + ldrb r0, [r2]\n\ + movs r1, 0x58\n\ + muls r0, r1\n\ + add r0, r9\n\ + adds r1, r0, 0\n\ + adds r1, 0x21\n\ + ldrb r1, [r1]\n\ + cmp r1, 0x3\n\ + beq _0801E976\n\ + adds r0, 0x22\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x3\n\ + beq _0801E976\n\ + cmp r1, 0x8\n\ + beq _0801E976\n\ + cmp r0, 0x8\n\ + bne _0801E9B4\n\ +_0801E976:\n\ + ldr r0, _0801E9A4 @ =gHitMarker\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 6\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0801E9B4\n\ + cmp r4, 0x1\n\ + beq _0801E98C\n\ + cmp r5, 0x80\n\ + bne _0801E9B4\n\ +_0801E98C:\n\ + ldr r4, _0801E9A8 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801E9AC @ =BattleScript_PSNPrevention\n\ +_0801E998:\n\ + str r0, [r4]\n\ + ldr r1, _0801E9B0 @ =gBattleCommunication\n\ + movs r0, 0x2\n\ + strb r0, [r1, 0x5]\n\ + bl _0801F5FA\n\ + .align 2, 0\n\ +_0801E9A4: .4byte gHitMarker\n\ +_0801E9A8: .4byte gBattlescriptCurrInstr\n\ +_0801E9AC: .4byte BattleScript_PSNPrevention\n\ +_0801E9B0: .4byte gBattleCommunication\n\ +_0801E9B4:\n\ + mov r3, r8\n\ + ldrb r0, [r3]\n\ + movs r6, 0x58\n\ + muls r0, r6\n\ + mov r2, r9\n\ + adds r2, 0x4C\n\ + adds r5, r0, r2\n\ + ldr r4, [r5]\n\ + cmp r4, 0\n\ + bne _0801EA14\n\ + mov r3, r9\n\ + adds r1, r0, r3\n\ + adds r0, r1, 0\n\ + adds r0, 0x21\n\ + ldrb r3, [r0]\n\ + cmp r3, 0x3\n\ + beq _0801EA0A\n\ + adds r0, 0x1\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x3\n\ + beq _0801EA0A\n\ + cmp r3, 0x8\n\ + beq _0801EA0A\n\ + cmp r0, 0x8\n\ + beq _0801EA0A\n\ + adds r0, r1, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x11\n\ + beq _0801EA14\n\ + mov r4, r8\n\ + ldrb r0, [r4]\n\ + adds r1, r0, 0\n\ + muls r1, r6\n\ + adds r1, r2\n\ + ldr r0, [r1]\n\ + movs r2, 0x9\n\ + negs r2, r2\n\ + ands r0, r2\n\ + str r0, [r1]\n\ +_0801EA04:\n\ + movs r0, 0x1\n\ + mov r10, r0\n\ + b _0801EA14\n\ +_0801EA0A:\n\ + ldr r0, _0801EA58 @ =gMoveResultFlags\n\ + ldrb r1, [r0]\n\ + movs r2, 0x8\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ +_0801EA14:\n\ + mov r1, r10\n\ + cmp r1, 0x1\n\ + beq _0801EA1C\n\ + b _0801EB3C\n\ +_0801EA1C:\n\ + ldr r0, _0801EA5C @ =gBattlescriptCurrInstr\n\ + ldr r0, [r0]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r1, _0801EA60 @ =sStatusFlagsForMoveEffects\n\ + ldr r0, _0801EA64 @ =gBattleCommunication\n\ + ldrb r0, [r0, 0x3]\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldr r3, [r0]\n\ + cmp r3, 0x7\n\ + bne _0801EA70\n\ + bl Random\n\ + ldr r2, _0801EA68 @ =gBattleMons\n\ + ldr r1, _0801EA6C @ =gEffectBank\n\ + ldrb r3, [r1]\n\ + movs r1, 0x58\n\ + muls r3, r1\n\ + adds r2, 0x4C\n\ + adds r3, r2\n\ + movs r1, 0x3\n\ + ands r1, r0\n\ + adds r1, 0x2\n\ + ldr r0, [r3]\n\ + orrs r0, r1\n\ + str r0, [r3]\n\ + b _0801EA84\n\ + .align 2, 0\n\ +_0801EA58: .4byte gMoveResultFlags\n\ +_0801EA5C: .4byte gBattlescriptCurrInstr\n\ +_0801EA60: .4byte sStatusFlagsForMoveEffects\n\ +_0801EA64: .4byte gBattleCommunication\n\ +_0801EA68: .4byte gBattleMons\n\ +_0801EA6C: .4byte gEffectBank\n\ +_0801EA70:\n\ + ldr r2, _0801EAD4 @ =gBattleMons\n\ + ldr r0, _0801EAD8 @ =gEffectBank\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + muls r1, r0\n\ + adds r2, 0x4C\n\ + adds r1, r2\n\ + ldr r0, [r1]\n\ + orrs r0, r3\n\ + str r0, [r1]\n\ +_0801EA84:\n\ + ldr r2, _0801EADC @ =gBattlescriptCurrInstr\n\ + ldr r1, _0801EAE0 @ =gMoveEffectBS_Ptrs\n\ + ldr r5, _0801EAE4 @ =gBattleCommunication\n\ + ldrb r0, [r5, 0x3]\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + str r0, [r2]\n\ + ldr r4, _0801EAE8 @ =gActiveBattler\n\ + ldr r1, _0801EAD8 @ =gEffectBank\n\ + ldrb r0, [r1]\n\ + strb r0, [r4]\n\ + ldrb r1, [r1]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + ldr r1, _0801EAEC @ =gBattleMons+0x4C @ gBattleMons.status1\n\ + adds r0, r1\n\ + str r0, [sp]\n\ + movs r0, 0\n\ + movs r1, 0x28\n\ + movs r2, 0\n\ + movs r3, 0x4\n\ + bl EmitSetMonData\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + ldr r2, _0801EAF0 @ =gHitMarker\n\ + ldr r1, [r2]\n\ + movs r0, 0x80\n\ + lsls r0, 6\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0801EAF8\n\ + movs r0, 0x1\n\ + strb r0, [r5, 0x5]\n\ + ldr r0, _0801EAF4 @ =0xffffdfff\n\ + ands r1, r0\n\ + str r1, [r2]\n\ + b _0801EAFA\n\ + .align 2, 0\n\ +_0801EAD4: .4byte gBattleMons\n\ +_0801EAD8: .4byte gEffectBank\n\ +_0801EADC: .4byte gBattlescriptCurrInstr\n\ +_0801EAE0: .4byte gMoveEffectBS_Ptrs\n\ +_0801EAE4: .4byte gBattleCommunication\n\ +_0801EAE8: .4byte gActiveBattler\n\ +_0801EAEC: .4byte gBattleMons+0x4C @ gBattleMons.status1\n\ +_0801EAF0: .4byte gHitMarker\n\ +_0801EAF4: .4byte 0xffffdfff\n\ +_0801EAF8:\n\ + strb r0, [r5, 0x5]\n\ +_0801EAFA:\n\ + ldr r0, _0801EB2C @ =gBattleCommunication\n\ + ldrb r2, [r0, 0x3]\n\ + adds r7, r0, 0\n\ + cmp r2, 0x2\n\ + beq _0801EB14\n\ + cmp r2, 0x6\n\ + beq _0801EB14\n\ + cmp r2, 0x5\n\ + beq _0801EB14\n\ + cmp r2, 0x3\n\ + beq _0801EB14\n\ + bl _0801F5FA\n\ +_0801EB14:\n\ + ldr r0, _0801EB30 @ =gSharedMem\n\ + ldrb r1, [r7, 0x3]\n\ + ldr r2, _0801EB34 @ =0x000160ca\n\ + adds r0, r2\n\ + strb r1, [r0]\n\ + ldr r2, _0801EB38 @ =gHitMarker\n\ + ldr r0, [r2]\n\ + movs r1, 0x80\n\ + lsls r1, 7\n\ + bl _0801F4F2\n\ + .align 2, 0\n\ +_0801EB2C: .4byte gBattleCommunication\n\ +_0801EB30: .4byte gSharedMem\n\ +_0801EB34: .4byte 0x000160ca\n\ +_0801EB38: .4byte gHitMarker\n\ +_0801EB3C:\n\ + mov r3, r10\n\ + cmp r3, 0\n\ + beq _0801EB46\n\ + bl _0801F5FA\n\ +_0801EB46:\n\ + bl _0801F5DC\n\ +_0801EB4A:\n\ + mov r0, r8\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + muls r1, r0\n\ + mov r0, r9\n\ + adds r0, 0x50\n\ + adds r1, r0\n\ + ldr r2, _0801EB84 @ =sStatusFlagsForMoveEffects\n\ + ldrb r3, [r7, 0x3]\n\ + lsls r0, r3, 2\n\ + adds r0, r2\n\ + ldr r1, [r1]\n\ + ldr r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + beq _0801EB6E\n\ + bl _0801F5DC\n\ +_0801EB6E:\n\ + subs r0, r3, 0x7\n\ + cmp r0, 0x34\n\ + bls _0801EB78\n\ + bl _0801F5FA\n\ +_0801EB78:\n\ + lsls r0, 2\n\ + ldr r1, _0801EB88 @ =_0801EB8C\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .align 2, 0\n\ +_0801EB84: .4byte sStatusFlagsForMoveEffects\n\ +_0801EB88: .4byte _0801EB8C\n\ + .align 2, 0\n\ +_0801EB8C:\n\ + .4byte _0801EC60\n\ + .4byte _0801ECD4\n\ + .4byte _0801EE4C\n\ + .4byte _0801ED60\n\ + .4byte _0801EDDC\n\ + .4byte _0801EE84\n\ + .4byte _0801EECC\n\ + .4byte _0801EFA8\n\ + .4byte _0801EFEC\n\ + .4byte _0801EFEC\n\ + .4byte _0801EFEC\n\ + .4byte _0801EFEC\n\ + .4byte _0801EFEC\n\ + .4byte _0801EFEC\n\ + .4byte _0801EFEC\n\ + .4byte _0801F040\n\ + .4byte _0801F040\n\ + .4byte _0801F040\n\ + .4byte _0801F040\n\ + .4byte _0801F040\n\ + .4byte _0801F040\n\ + .4byte _0801F040\n\ + .4byte _0801F13C\n\ + .4byte _0801F184\n\ + .4byte _0801F1A4\n\ + .4byte _0801F364\n\ + .4byte _0801F3A0\n\ + .4byte _0801F3BC\n\ + .4byte _0801F3D4\n\ + .4byte _0801F3EC\n\ + .4byte _0801F44C\n\ + .4byte _0801F464\n\ + .4byte _0801F094\n\ + .4byte _0801F094\n\ + .4byte _0801F094\n\ + .4byte _0801F094\n\ + .4byte _0801F094\n\ + .4byte _0801F094\n\ + .4byte _0801F094\n\ + .4byte _0801F0E8\n\ + .4byte _0801F0E8\n\ + .4byte _0801F0E8\n\ + .4byte _0801F0E8\n\ + .4byte _0801F0E8\n\ + .4byte _0801F0E8\n\ + .4byte _0801F0E8\n\ + .4byte _0801F4A8\n\ + .4byte _0801F500\n\ + .4byte _0801F5FA\n\ + .4byte _0801F5FA\n\ + .4byte _0801F5FA\n\ + .4byte _0801F5FA\n\ + .4byte _0801F5EC\n\ +_0801EC60:\n\ + mov r1, r8\n\ + ldrb r0, [r1]\n\ + movs r5, 0x58\n\ + adds r1, r0, 0\n\ + muls r1, r5\n\ + mov r2, r9\n\ + adds r0, r1, r2\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x14\n\ + bne _0801EC7A\n\ + bl _0801F5DC\n\ +_0801EC7A:\n\ + mov r4, r9\n\ + adds r4, 0x50\n\ + adds r0, r1, r4\n\ + ldr r0, [r0]\n\ + movs r1, 0x7\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0801EC8E\n\ + bl _0801F5DC\n\ +_0801EC8E:\n\ + bl Random\n\ + mov r3, r8\n\ + ldrb r1, [r3]\n\ + adds r2, r1, 0\n\ + muls r2, r5\n\ + adds r2, r4\n\ + lsls r0, 16\n\ + movs r1, 0xC0\n\ + lsls r1, 10\n\ + ands r1, r0\n\ + lsrs r1, 16\n\ + adds r1, 0x2\n\ + ldr r0, [r2]\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + ldr r4, _0801ECC8 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r1, _0801ECCC @ =gMoveEffectBS_Ptrs\n\ + ldr r0, _0801ECD0 @ =gBattleCommunication\n\ + ldrb r0, [r0, 0x3]\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + bl _0801F5F8\n\ + .align 2, 0\n\ +_0801ECC8: .4byte gBattlescriptCurrInstr\n\ +_0801ECCC: .4byte gMoveEffectBS_Ptrs\n\ +_0801ECD0: .4byte gBattleCommunication\n\ +_0801ECD4:\n\ + mov r0, r8\n\ + ldrb r2, [r0]\n\ + movs r6, 0x58\n\ + adds r0, r2, 0\n\ + muls r0, r6\n\ + add r0, r9\n\ + adds r0, 0x20\n\ + ldrb r1, [r0]\n\ + cmp r1, 0x27\n\ + bne _0801ED18\n\ + cmp r4, 0x1\n\ + beq _0801ECF4\n\ + cmp r5, 0x80\n\ + beq _0801ECF4\n\ + bl _0801F5DC\n\ +_0801ECF4:\n\ + ldr r0, _0801ED0C @ =gLastUsedAbility\n\ + strb r1, [r0]\n\ + mov r1, r8\n\ + ldrb r0, [r1]\n\ + movs r1, 0x27\n\ + bl RecordAbilityBattle\n\ + ldr r1, _0801ED10 @ =gBattlescriptCurrInstr\n\ + ldr r0, _0801ED14 @ =BattleScript_FlinchPrevention\n\ + str r0, [r1]\n\ + bl _0801F5FA\n\ + .align 2, 0\n\ +_0801ED0C: .4byte gLastUsedAbility\n\ +_0801ED10: .4byte gBattlescriptCurrInstr\n\ +_0801ED14: .4byte BattleScript_FlinchPrevention\n\ +_0801ED18:\n\ + adds r0, r2, 0\n\ + bl BankGetTurnOrder\n\ + ldr r1, _0801ED54 @ =gCurrentTurnActionNumber\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + ldrb r1, [r1]\n\ + cmp r0, r1\n\ + bhi _0801ED2E\n\ + bl _0801F5DC\n\ +_0801ED2E:\n\ + mov r2, r8\n\ + ldrb r0, [r2]\n\ + adds r2, r0, 0\n\ + muls r2, r6\n\ + mov r0, r9\n\ + adds r0, 0x50\n\ + adds r2, r0\n\ + ldr r1, _0801ED58 @ =sStatusFlagsForMoveEffects\n\ + ldr r0, _0801ED5C @ =gBattleCommunication\n\ + ldrb r0, [r0, 0x3]\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldr r1, [r2]\n\ + ldr r0, [r0]\n\ + orrs r1, r0\n\ + str r1, [r2]\n\ + bl _0801F5DC\n\ + .align 2, 0\n\ +_0801ED54: .4byte gCurrentTurnActionNumber\n\ +_0801ED58: .4byte sStatusFlagsForMoveEffects\n\ +_0801ED5C: .4byte gBattleCommunication\n\ +_0801ED60:\n\ + mov r3, r8\n\ + ldrb r0, [r3]\n\ + movs r5, 0x58\n\ + muls r0, r5\n\ + mov r4, r9\n\ + adds r4, 0x50\n\ + adds r2, r0, r4\n\ + ldr r1, [r2]\n\ + movs r0, 0x70\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0801ED7C\n\ + bl _0801F5DC\n\ +_0801ED7C:\n\ + movs r0, 0x80\n\ + lsls r0, 5\n\ + orrs r1, r0\n\ + str r1, [r2]\n\ + ldr r1, _0801EDC8 @ =gLockedMoves\n\ + ldrb r0, [r3]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + ldr r1, _0801EDCC @ =gCurrentMove\n\ + ldrh r1, [r1]\n\ + strh r1, [r0]\n\ + bl Random\n\ + mov r2, r8\n\ + ldrb r1, [r2]\n\ + adds r2, r1, 0\n\ + muls r2, r5\n\ + adds r2, r4\n\ + movs r1, 0x3\n\ + ands r1, r0\n\ + adds r1, 0x2\n\ + lsls r1, 4\n\ + ldr r0, [r2]\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + ldr r4, _0801EDD0 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r1, _0801EDD4 @ =gMoveEffectBS_Ptrs\n\ + ldr r0, _0801EDD8 @ =gBattleCommunication\n\ + ldrb r0, [r0, 0x3]\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + bl _0801F5F8\n\ + .align 2, 0\n\ +_0801EDC8: .4byte gLockedMoves\n\ +_0801EDCC: .4byte gCurrentMove\n\ +_0801EDD0: .4byte gBattlescriptCurrInstr\n\ +_0801EDD4: .4byte gMoveEffectBS_Ptrs\n\ +_0801EDD8: .4byte gBattleCommunication\n\ +_0801EDDC:\n\ + ldr r5, _0801EE30 @ =gBankAttacker\n\ + ldrb r0, [r5]\n\ + bl GetBattlerPosition\n\ + movs r1, 0x1\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + bne _0801EE14\n\ + ldr r4, _0801EE34 @ =gPaydayMoney\n\ + ldrh r3, [r4]\n\ + ldr r2, _0801EE38 @ =gBattleMons\n\ + ldrb r1, [r5]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r2\n\ + adds r0, 0x2A\n\ + ldrb r1, [r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + adds r0, r3, r0\n\ + strh r0, [r4]\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r3, r0\n\ + bls _0801EE14\n\ + ldr r3, _0801EE3C @ =0x0000ffff\n\ + adds r0, r3, 0\n\ + strh r0, [r4]\n\ +_0801EE14:\n\ + ldr r4, _0801EE40 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r1, _0801EE44 @ =gMoveEffectBS_Ptrs\n\ + ldr r0, _0801EE48 @ =gBattleCommunication\n\ + ldrb r0, [r0, 0x3]\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + bl _0801F5F8\n\ + .align 2, 0\n\ +_0801EE30: .4byte gBankAttacker\n\ +_0801EE34: .4byte gPaydayMoney\n\ +_0801EE38: .4byte gBattleMons\n\ +_0801EE3C: .4byte 0x0000ffff\n\ +_0801EE40: .4byte gBattlescriptCurrInstr\n\ +_0801EE44: .4byte gMoveEffectBS_Ptrs\n\ +_0801EE48: .4byte gBattleCommunication\n\ +_0801EE4C:\n\ + mov r4, r8\n\ + ldrb r1, [r4]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + mov r1, r9\n\ + adds r1, 0x4C\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + beq _0801EE62\n\ + b _0801F5DC\n\ +_0801EE62:\n\ + bl Random\n\ + ldr r4, _0801EE80 @ =gBattleCommunication\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0x3\n\ + bl __umodsi3\n\ + adds r0, 0x3\n\ + strb r0, [r4, 0x3]\n\ + movs r0, 0\n\ + movs r1, 0\n\ + bl SetMoveEffect\n\ + b _0801F5FA\n\ + .align 2, 0\n\ +_0801EE80: .4byte gBattleCommunication\n\ +_0801EE84:\n\ + mov r0, r8\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + adds r2, r1, 0\n\ + muls r2, r0\n\ + mov r0, r9\n\ + adds r0, 0x50\n\ + adds r2, r0\n\ + ldr r0, [r2]\n\ + movs r1, 0x80\n\ + lsls r1, 5\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + ldr r1, _0801EEC0 @ =gLockedMoves\n\ + mov r2, r8\n\ + ldrb r0, [r2]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + ldr r1, _0801EEC4 @ =gCurrentMove\n\ + ldrh r1, [r1]\n\ + strh r1, [r0]\n\ + ldr r0, _0801EEC8 @ =gProtectStructs\n\ + ldrb r1, [r2]\n\ + lsls r1, 4\n\ + adds r1, r0\n\ + ldrb r0, [r1, 0x1]\n\ + movs r2, 0x4\n\ + orrs r0, r2\n\ + strb r0, [r1, 0x1]\n\ + b _0801F5DC\n\ + .align 2, 0\n\ +_0801EEC0: .4byte gLockedMoves\n\ +_0801EEC4: .4byte gCurrentMove\n\ +_0801EEC8: .4byte gProtectStructs\n\ +_0801EECC:\n\ + mov r3, r8\n\ + ldrb r0, [r3]\n\ + movs r6, 0x58\n\ + muls r0, r6\n\ + mov r4, r9\n\ + adds r4, 0x50\n\ + adds r0, r4\n\ + ldr r5, [r0]\n\ + movs r0, 0xE0\n\ + lsls r0, 8\n\ + ands r5, r0\n\ + cmp r5, 0\n\ + beq _0801EEE8\n\ + b _0801F5DC\n\ +_0801EEE8:\n\ + bl Random\n\ + mov r2, r8\n\ + ldrb r1, [r2]\n\ + adds r2, r1, 0\n\ + muls r2, r6\n\ + adds r2, r4\n\ + movs r1, 0x3\n\ + ands r1, r0\n\ + adds r1, 0x3\n\ + lsls r1, 13\n\ + ldr r0, [r2]\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + ldr r2, _0801EF80 @ =gSharedMem\n\ + mov r3, r8\n\ + ldrb r0, [r3]\n\ + lsls r0, 1\n\ + ldr r4, _0801EF84 @ =0x00016004\n\ + adds r0, r4\n\ + adds r0, r2\n\ + ldr r6, _0801EF88 @ =gCurrentMove\n\ + ldrh r1, [r6]\n\ + strb r1, [r0]\n\ + ldrb r0, [r3]\n\ + lsls r0, 1\n\ + ldr r1, _0801EF8C @ =0x00016005\n\ + adds r0, r1\n\ + adds r0, r2\n\ + ldrh r1, [r6]\n\ + lsrs r1, 8\n\ + strb r1, [r0]\n\ + ldrb r0, [r3]\n\ + ldr r3, _0801EF90 @ =0x00016020\n\ + adds r0, r3\n\ + adds r0, r2\n\ + ldr r1, _0801EF94 @ =gBankAttacker\n\ + ldrb r1, [r1]\n\ + strb r1, [r0]\n\ + ldr r4, _0801EF98 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r1, _0801EF9C @ =gMoveEffectBS_Ptrs\n\ + ldr r2, _0801EFA0 @ =gBattleCommunication\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + str r0, [r4]\n\ + strb r5, [r2, 0x5]\n\ + ldr r1, _0801EFA4 @ =gTrappingMoves\n\ + ldrh r0, [r1]\n\ + ldrh r4, [r6]\n\ + cmp r0, r4\n\ + bne _0801EF5C\n\ + b _0801F5FA\n\ +_0801EF5C:\n\ + adds r3, r1, 0\n\ + adds r1, r6, 0\n\ +_0801EF60:\n\ + ldrb r0, [r2, 0x5]\n\ + adds r0, 0x1\n\ + strb r0, [r2, 0x5]\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x4\n\ + bls _0801EF70\n\ + b _0801F5FA\n\ +_0801EF70:\n\ + ldrb r0, [r2, 0x5]\n\ + lsls r0, 1\n\ + adds r0, r3\n\ + ldrh r0, [r0]\n\ + ldrh r4, [r1]\n\ + cmp r0, r4\n\ + bne _0801EF60\n\ + b _0801F5FA\n\ + .align 2, 0\n\ +_0801EF80: .4byte gSharedMem\n\ +_0801EF84: .4byte 0x00016004\n\ +_0801EF88: .4byte gCurrentMove\n\ +_0801EF8C: .4byte 0x00016005\n\ +_0801EF90: .4byte 0x00016020\n\ +_0801EF94: .4byte gBankAttacker\n\ +_0801EF98: .4byte gBattlescriptCurrInstr\n\ +_0801EF9C: .4byte gMoveEffectBS_Ptrs\n\ +_0801EFA0: .4byte gBattleCommunication\n\ +_0801EFA4: .4byte gTrappingMoves\n\ +_0801EFA8:\n\ + ldr r1, _0801EFD8 @ =gBattleMoveDamage\n\ + ldr r0, _0801EFDC @ =gHpDealt\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bge _0801EFB4\n\ + adds r0, 0x3\n\ +_0801EFB4:\n\ + asrs r0, 2\n\ + str r0, [r1]\n\ + cmp r0, 0\n\ + bne _0801EFC0\n\ + movs r0, 0x1\n\ + str r0, [r1]\n\ +_0801EFC0:\n\ + ldr r4, _0801EFE0 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r1, _0801EFE4 @ =gMoveEffectBS_Ptrs\n\ + ldr r0, _0801EFE8 @ =gBattleCommunication\n\ + ldrb r0, [r0, 0x3]\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + b _0801F5F8\n\ + .align 2, 0\n\ +_0801EFD8: .4byte gBattleMoveDamage\n\ +_0801EFDC: .4byte gHpDealt\n\ +_0801EFE0: .4byte gBattlescriptCurrInstr\n\ +_0801EFE4: .4byte gMoveEffectBS_Ptrs\n\ +_0801EFE8: .4byte gBattleCommunication\n\ +_0801EFEC:\n\ + ldrb r1, [r7, 0x3]\n\ + adds r1, 0xF2\n\ + lsls r1, 24\n\ + lsrs r1, 24\n\ + movs r0, 0x10\n\ + adds r2, r6, 0\n\ + movs r3, 0\n\ + bl ChangeStatBuffs\n\ + lsls r0, 24\n\ + lsrs r3, r0, 24\n\ + cmp r3, 0\n\ + beq _0801F008\n\ + b _0801F5DC\n\ +_0801F008:\n\ + ldr r2, _0801F02C @ =gSharedMem\n\ + ldrb r1, [r7, 0x3]\n\ + movs r0, 0x3F\n\ + ands r0, r1\n\ + ldr r4, _0801F030 @ =0x000160a4\n\ + adds r1, r2, r4\n\ + strb r0, [r1]\n\ + ldr r0, _0801F034 @ =0x000160a5\n\ + adds r2, r0\n\ + strb r3, [r2]\n\ + ldr r4, _0801F038 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801F03C @ =BattleScript_StatUp\n\ + b _0801F5F8\n\ + .align 2, 0\n\ +_0801F02C: .4byte gSharedMem\n\ +_0801F030: .4byte 0x000160a4\n\ +_0801F034: .4byte 0x000160a5\n\ +_0801F038: .4byte gBattlescriptCurrInstr\n\ +_0801F03C: .4byte BattleScript_StatUp\n\ +_0801F040:\n\ + movs r0, 0x70\n\ + negs r0, r0\n\ + ldrb r1, [r7, 0x3]\n\ + adds r1, 0xEB\n\ + lsls r1, 24\n\ + lsrs r1, 24\n\ + adds r2, r6, 0\n\ + movs r3, 0\n\ + bl ChangeStatBuffs\n\ + lsls r0, 24\n\ + lsrs r3, r0, 24\n\ + cmp r3, 0\n\ + beq _0801F05E\n\ + b _0801F5DC\n\ +_0801F05E:\n\ + ldr r2, _0801F080 @ =gSharedMem\n\ + ldrb r1, [r7, 0x3]\n\ + movs r0, 0x3F\n\ + ands r0, r1\n\ + ldr r4, _0801F084 @ =0x000160a4\n\ + adds r1, r2, r4\n\ + strb r0, [r1]\n\ + ldr r0, _0801F088 @ =0x000160a5\n\ + adds r2, r0\n\ + strb r3, [r2]\n\ + ldr r4, _0801F08C @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801F090 @ =BattleScript_StatDown\n\ + b _0801F5F8\n\ + .align 2, 0\n\ +_0801F080: .4byte gSharedMem\n\ +_0801F084: .4byte 0x000160a4\n\ +_0801F088: .4byte 0x000160a5\n\ +_0801F08C: .4byte gBattlescriptCurrInstr\n\ +_0801F090: .4byte BattleScript_StatDown\n\ +_0801F094:\n\ + ldrb r1, [r7, 0x3]\n\ + adds r1, 0xDA\n\ + lsls r1, 24\n\ + lsrs r1, 24\n\ + movs r0, 0x20\n\ + adds r2, r6, 0\n\ + movs r3, 0\n\ + bl ChangeStatBuffs\n\ + lsls r0, 24\n\ + lsrs r3, r0, 24\n\ + cmp r3, 0\n\ + beq _0801F0B0\n\ + b _0801F5DC\n\ +_0801F0B0:\n\ + ldr r2, _0801F0D4 @ =gSharedMem\n\ + ldrb r1, [r7, 0x3]\n\ + movs r0, 0x3F\n\ + ands r0, r1\n\ + ldr r4, _0801F0D8 @ =0x000160a4\n\ + adds r1, r2, r4\n\ + strb r0, [r1]\n\ + ldr r0, _0801F0DC @ =0x000160a5\n\ + adds r2, r0\n\ + strb r3, [r2]\n\ + ldr r4, _0801F0E0 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801F0E4 @ =BattleScript_StatUp\n\ + b _0801F5F8\n\ + .align 2, 0\n\ +_0801F0D4: .4byte gSharedMem\n\ +_0801F0D8: .4byte 0x000160a4\n\ +_0801F0DC: .4byte 0x000160a5\n\ +_0801F0E0: .4byte gBattlescriptCurrInstr\n\ +_0801F0E4: .4byte BattleScript_StatUp\n\ +_0801F0E8:\n\ + movs r0, 0x60\n\ + negs r0, r0\n\ + ldrb r1, [r7, 0x3]\n\ + adds r1, 0xD3\n\ + lsls r1, 24\n\ + lsrs r1, 24\n\ + adds r2, r6, 0\n\ + movs r3, 0\n\ + bl ChangeStatBuffs\n\ + lsls r0, 24\n\ + lsrs r3, r0, 24\n\ + cmp r3, 0\n\ + beq _0801F106\n\ + b _0801F5DC\n\ +_0801F106:\n\ + ldr r2, _0801F128 @ =gSharedMem\n\ + ldrb r1, [r7, 0x3]\n\ + movs r0, 0x3F\n\ + ands r0, r1\n\ + ldr r4, _0801F12C @ =0x000160a4\n\ + adds r1, r2, r4\n\ + strb r0, [r1]\n\ + ldr r0, _0801F130 @ =0x000160a5\n\ + adds r2, r0\n\ + strb r3, [r2]\n\ + ldr r4, _0801F134 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801F138 @ =BattleScript_StatDown\n\ + b _0801F5F8\n\ + .align 2, 0\n\ +_0801F128: .4byte gSharedMem\n\ +_0801F12C: .4byte 0x000160a4\n\ +_0801F130: .4byte 0x000160a5\n\ +_0801F134: .4byte gBattlescriptCurrInstr\n\ +_0801F138: .4byte BattleScript_StatDown\n\ +_0801F13C:\n\ + mov r2, r8\n\ + ldrb r1, [r2]\n\ + movs r0, 0x58\n\ + adds r2, r1, 0\n\ + muls r2, r0\n\ + mov r0, r9\n\ + adds r0, 0x50\n\ + adds r2, r0\n\ + ldr r0, [r2]\n\ + movs r1, 0x80\n\ + lsls r1, 15\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + ldr r2, _0801F178 @ =gDisableStructs\n\ + mov r3, r8\n\ + ldrb r1, [r3]\n\ + lsls r0, r1, 3\n\ + subs r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + movs r1, 0x2\n\ + strb r1, [r0, 0x19]\n\ + ldr r1, _0801F17C @ =gLockedMoves\n\ + ldrb r0, [r3]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + ldr r1, _0801F180 @ =gCurrentMove\n\ + ldrh r1, [r1]\n\ + strh r1, [r0]\n\ + b _0801F5DC\n\ + .align 2, 0\n\ +_0801F178: .4byte gDisableStructs\n\ +_0801F17C: .4byte gLockedMoves\n\ +_0801F180: .4byte gCurrentMove\n\ +_0801F184:\n\ + ldr r0, _0801F1A0 @ =gBankAttacker\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + adds r2, r1, 0\n\ + muls r2, r0\n\ + mov r0, r9\n\ + adds r0, 0x50\n\ + adds r2, r0\n\ + ldr r0, [r2]\n\ + movs r1, 0x80\n\ + lsls r1, 16\n\ +_0801F19A:\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + b _0801F5DC\n\ + .align 2, 0\n\ +_0801F1A0: .4byte gBankAttacker\n\ +_0801F1A4:\n\ + ldr r4, _0801F254 @ =gBankAttacker\n\ + ldrb r0, [r4]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + lsrs r6, r0, 24\n\ + ldrb r0, [r4]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x1\n\ + bne _0801F1D8\n\ + ldr r0, _0801F258 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + ldr r0, _0801F25C @ =0x00000902\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0801F214\n\ + ldr r0, _0801F260 @ =gTrainerBattleOpponent\n\ + ldrh r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 3\n\ + cmp r1, r0\n\ + beq _0801F1D8\n\ + b _0801F5DC\n\ +_0801F1D8:\n\ + ldr r0, _0801F258 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + ldr r0, _0801F25C @ =0x00000902\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0801F214\n\ + ldr r0, _0801F260 @ =gTrainerBattleOpponent\n\ + ldrh r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 3\n\ + cmp r1, r0\n\ + beq _0801F214\n\ + ldr r0, _0801F264 @ =gWishFutureKnock\n\ + adds r0, 0x29\n\ + adds r0, r6, r0\n\ + ldrb r1, [r0]\n\ + ldr r3, _0801F268 @ =gBitTable\n\ + ldr r2, _0801F26C @ =gBattlerPartyIndexes\n\ + ldr r0, _0801F254 @ =gBankAttacker\n\ + ldrb r0, [r0]\n\ + lsls r0, 1\n\ + adds r0, r2\n\ + ldrh r0, [r0]\n\ + lsls r0, 2\n\ + adds r0, r3\n\ + ldr r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + beq _0801F214\n\ + b _0801F5DC\n\ +_0801F214:\n\ + ldr r2, _0801F270 @ =gBattleMons\n\ + ldr r1, _0801F274 @ =gBankTarget\n\ + ldrb r0, [r1]\n\ + movs r3, 0x58\n\ + muls r0, r3\n\ + adds r4, r0, r2\n\ + ldrh r0, [r4, 0x2E]\n\ + adds r7, r1, 0\n\ + mov r9, r2\n\ + cmp r0, 0\n\ + beq _0801F284\n\ + adds r0, r4, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x3C\n\ + bne _0801F284\n\ + ldr r1, _0801F278 @ =gBattlescriptCurrInstr\n\ + ldr r0, _0801F27C @ =BattleScript_NoItemSteal\n\ + str r0, [r1]\n\ + ldr r1, _0801F280 @ =gLastUsedAbility\n\ + ldrb r0, [r7]\n\ + muls r0, r3\n\ + add r0, r9\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + strb r0, [r1]\n\ + ldrb r0, [r7]\n\ + ldrb r1, [r1]\n\ + bl RecordAbilityBattle\n\ + b _0801F5FA\n\ + .align 2, 0\n\ +_0801F254: .4byte gBankAttacker\n\ +_0801F258: .4byte gBattleTypeFlags\n\ +_0801F25C: .4byte 0x00000902\n\ +_0801F260: .4byte gTrainerBattleOpponent\n\ +_0801F264: .4byte gWishFutureKnock\n\ +_0801F268: .4byte gBitTable\n\ +_0801F26C: .4byte gBattlerPartyIndexes\n\ +_0801F270: .4byte gBattleMons\n\ +_0801F274: .4byte gBankTarget\n\ +_0801F278: .4byte gBattlescriptCurrInstr\n\ +_0801F27C: .4byte BattleScript_NoItemSteal\n\ +_0801F280: .4byte gLastUsedAbility\n\ +_0801F284:\n\ + ldr r4, _0801F340 @ =gBankAttacker\n\ + mov r10, r4\n\ + ldrb r1, [r4]\n\ + movs r0, 0x58\n\ + mov r8, r0\n\ + mov r0, r8\n\ + muls r0, r1\n\ + add r0, r9\n\ + ldrh r3, [r0, 0x2E]\n\ + cmp r3, 0\n\ + beq _0801F29C\n\ + b _0801F5DC\n\ +_0801F29C:\n\ + ldrb r0, [r7]\n\ + mov r2, r8\n\ + muls r2, r0\n\ + adds r0, r2, 0\n\ + add r0, r9\n\ + ldrh r2, [r0, 0x2E]\n\ + adds r0, r2, 0\n\ + cmp r0, 0xAF\n\ + bne _0801F2B0\n\ + b _0801F5DC\n\ +_0801F2B0:\n\ + cmp r0, 0\n\ + bne _0801F2B6\n\ + b _0801F5DC\n\ +_0801F2B6:\n\ + lsls r0, r1, 1\n\ + ldr r5, _0801F344 @ =gSharedMem + 0x160F0\n\ + adds r0, r5\n\ + ldr r1, _0801F348 @ =gLastUsedItem\n\ + strh r2, [r0]\n\ + strh r2, [r1]\n\ + ldrb r0, [r7]\n\ + mov r4, r8\n\ + muls r4, r0\n\ + adds r0, r4, 0\n\ + add r0, r9\n\ + movs r6, 0\n\ + strh r3, [r0, 0x2E]\n\ + ldr r4, _0801F34C @ =gActiveBattler\n\ + mov r2, r10\n\ + ldrb r0, [r2]\n\ + strb r0, [r4]\n\ + str r1, [sp]\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + movs r2, 0\n\ + movs r3, 0x2\n\ + bl EmitSetMonData\n\ + mov r3, r10\n\ + ldrb r0, [r3]\n\ + bl MarkBufferBankForExecution\n\ + ldrb r0, [r7]\n\ + strb r0, [r4]\n\ + ldrb r0, [r7]\n\ + mov r4, r8\n\ + muls r4, r0\n\ + adds r0, r4, 0\n\ + mov r1, r9\n\ + adds r1, 0x2E\n\ + adds r0, r1\n\ + str r0, [sp]\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + movs r2, 0\n\ + movs r3, 0x2\n\ + bl EmitSetMonData\n\ + ldrb r0, [r7]\n\ + bl MarkBufferBankForExecution\n\ + ldr r4, _0801F350 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801F354 @ =BattleScript_ItemSteal\n\ + str r0, [r4]\n\ + ldr r0, _0801F358 @ =0xfffe9f10\n\ + adds r5, r0\n\ + ldrb r0, [r7]\n\ + lsls r0, 1\n\ + ldr r1, _0801F35C @ =0x000160e8\n\ + adds r0, r1\n\ + adds r0, r5\n\ + strb r6, [r0]\n\ + ldrb r0, [r7]\n\ + lsls r0, 1\n\ + ldr r2, _0801F360 @ =0x000160e9\n\ + adds r0, r2\n\ + adds r0, r5\n\ + strb r6, [r0]\n\ + b _0801F5FA\n\ + .align 2, 0\n\ +_0801F340: .4byte gBankAttacker\n\ +_0801F344: .4byte gSharedMem + 0x160F0\n\ +_0801F348: .4byte gLastUsedItem\n\ +_0801F34C: .4byte gActiveBattler\n\ +_0801F350: .4byte gBattlescriptCurrInstr\n\ +_0801F354: .4byte BattleScript_ItemSteal\n\ +_0801F358: .4byte 0xfffe9f10\n\ +_0801F35C: .4byte 0x000160e8\n\ +_0801F360: .4byte 0x000160e9\n\ +_0801F364:\n\ + ldr r3, _0801F394 @ =gBankTarget\n\ + ldrb r1, [r3]\n\ + movs r0, 0x58\n\ + adds r2, r1, 0\n\ + muls r2, r0\n\ + mov r0, r9\n\ + adds r0, 0x50\n\ + adds r2, r0\n\ + ldr r0, [r2]\n\ + movs r1, 0x80\n\ + lsls r1, 19\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + ldr r2, _0801F398 @ =gDisableStructs\n\ + ldrb r1, [r3]\n\ + lsls r0, r1, 3\n\ + subs r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldr r1, _0801F39C @ =gBankAttacker\n\ + ldrb r1, [r1]\n\ + strb r1, [r0, 0x14]\n\ + b _0801F5DC\n\ + .align 2, 0\n\ +_0801F394: .4byte gBankTarget\n\ +_0801F398: .4byte gDisableStructs\n\ +_0801F39C: .4byte gBankAttacker\n\ +_0801F3A0:\n\ + ldr r0, _0801F3B8 @ =gBankTarget\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + adds r2, r1, 0\n\ + muls r2, r0\n\ + mov r0, r9\n\ + adds r0, 0x50\n\ + adds r2, r0\n\ + ldr r0, [r2]\n\ + movs r1, 0x80\n\ + lsls r1, 20\n\ + b _0801F19A\n\ + .align 2, 0\n\ +_0801F3B8: .4byte gBankTarget\n\ +_0801F3BC:\n\ + ldr r4, _0801F3CC @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801F3D0 @ =BattleScript_AllStatsUp\n\ + b _0801F5F8\n\ + .align 2, 0\n\ +_0801F3CC: .4byte gBattlescriptCurrInstr\n\ +_0801F3D0: .4byte BattleScript_AllStatsUp\n\ +_0801F3D4:\n\ + ldr r4, _0801F3E4 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801F3E8 @ =BattleScript_RapidSpinAway\n\ + b _0801F5F8\n\ + .align 2, 0\n\ +_0801F3E4: .4byte gBattlescriptCurrInstr\n\ +_0801F3E8: .4byte BattleScript_RapidSpinAway\n\ +_0801F3EC:\n\ + ldr r6, _0801F43C @ =gBankTarget\n\ + ldrb r0, [r6]\n\ + movs r2, 0x58\n\ + muls r0, r2\n\ + mov r1, r9\n\ + adds r1, 0x4C\n\ + adds r5, r0, r1\n\ + ldr r4, [r5]\n\ + movs r0, 0x40\n\ + ands r0, r4\n\ + cmp r0, 0\n\ + bne _0801F406\n\ + b _0801F5DC\n\ +_0801F406:\n\ + movs r0, 0x41\n\ + negs r0, r0\n\ + ands r4, r0\n\ + str r4, [r5]\n\ + ldr r4, _0801F440 @ =gActiveBattler\n\ + ldrb r0, [r6]\n\ + strb r0, [r4]\n\ + ldrb r0, [r4]\n\ + muls r0, r2\n\ + adds r0, r1\n\ + str r0, [sp]\n\ + movs r0, 0\n\ + movs r1, 0x28\n\ + movs r2, 0\n\ + movs r3, 0x4\n\ + bl EmitSetMonData\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + ldr r4, _0801F444 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801F448 @ =BattleScript_TargetPRLZHeal\n\ + b _0801F5F8\n\ + .align 2, 0\n\ +_0801F43C: .4byte gBankTarget\n\ +_0801F440: .4byte gActiveBattler\n\ +_0801F444: .4byte gBattlescriptCurrInstr\n\ +_0801F448: .4byte BattleScript_TargetPRLZHeal\n\ +_0801F44C:\n\ + ldr r4, _0801F45C @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801F460 @ =BattleScript_AtkDefDown\n\ + b _0801F5F8\n\ + .align 2, 0\n\ +_0801F45C: .4byte gBattlescriptCurrInstr\n\ +_0801F460: .4byte BattleScript_AtkDefDown\n\ +_0801F464:\n\ + ldr r4, _0801F494 @ =gBattleMoveDamage\n\ + ldr r0, _0801F498 @ =gHpDealt\n\ + ldr r0, [r0]\n\ + movs r1, 0x3\n\ + bl __divsi3\n\ + str r0, [r4]\n\ + cmp r0, 0\n\ + bne _0801F47A\n\ + movs r0, 0x1\n\ + str r0, [r4]\n\ +_0801F47A:\n\ + ldr r4, _0801F49C @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r1, _0801F4A0 @ =gMoveEffectBS_Ptrs\n\ + ldr r0, _0801F4A4 @ =gBattleCommunication\n\ + ldrb r0, [r0, 0x3]\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + b _0801F5F8\n\ + .align 2, 0\n\ +_0801F494: .4byte gBattleMoveDamage\n\ +_0801F498: .4byte gHpDealt\n\ +_0801F49C: .4byte gBattlescriptCurrInstr\n\ +_0801F4A0: .4byte gMoveEffectBS_Ptrs\n\ +_0801F4A4: .4byte gBattleCommunication\n\ +_0801F4A8:\n\ + mov r3, r8\n\ + ldrb r0, [r3]\n\ + movs r5, 0x58\n\ + muls r0, r5\n\ + mov r4, r9\n\ + adds r4, 0x50\n\ + adds r2, r0, r4\n\ + ldr r1, [r2]\n\ + movs r0, 0xC0\n\ + lsls r0, 4\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0801F4C4\n\ + b _0801F5DC\n\ +_0801F4C4:\n\ + movs r0, 0x80\n\ + lsls r0, 5\n\ + orrs r1, r0\n\ + str r1, [r2]\n\ + ldr r1, _0801F4F8 @ =gLockedMoves\n\ + ldrb r0, [r3]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + ldr r1, _0801F4FC @ =gCurrentMove\n\ + ldrh r1, [r1]\n\ + strh r1, [r0]\n\ + bl Random\n\ + mov r2, r8\n\ + ldrb r1, [r2]\n\ + adds r2, r1, 0\n\ + muls r2, r5\n\ + adds r2, r4\n\ + movs r1, 0x1\n\ + ands r1, r0\n\ + adds r1, 0x2\n\ + lsls r1, 10\n\ + ldr r0, [r2]\n\ +_0801F4F2:\n\ + orrs r0, r1\n\ + str r0, [r2]\n\ + b _0801F5FA\n\ + .align 2, 0\n\ +_0801F4F8: .4byte gLockedMoves\n\ +_0801F4FC: .4byte gCurrentMove\n\ +_0801F500:\n\ + mov r5, r8\n\ + ldrb r3, [r5]\n\ + movs r4, 0x58\n\ + adds r0, r3, 0\n\ + muls r0, r4\n\ + mov r2, r9\n\ + adds r1, r0, r2\n\ + adds r0, r1, 0\n\ + adds r0, 0x20\n\ + ldrb r2, [r0]\n\ + cmp r2, 0x3C\n\ + bne _0801F540\n\ + ldrh r0, [r1, 0x2E]\n\ + cmp r0, 0\n\ + beq _0801F5DC\n\ + ldr r0, _0801F534 @ =gLastUsedAbility\n\ + strb r2, [r0]\n\ + ldr r1, _0801F538 @ =gBattlescriptCurrInstr\n\ + ldr r0, _0801F53C @ =BattleScript_NoItemSteal\n\ + str r0, [r1]\n\ + ldrb r0, [r5]\n\ + movs r1, 0x3C\n\ + bl RecordAbilityBattle\n\ + b _0801F5FA\n\ + .align 2, 0\n\ +_0801F534: .4byte gLastUsedAbility\n\ +_0801F538: .4byte gBattlescriptCurrInstr\n\ +_0801F53C: .4byte BattleScript_NoItemSteal\n\ +_0801F540:\n\ + ldrh r0, [r1, 0x2E]\n\ + cmp r0, 0\n\ + beq _0801F5DC\n\ + adds r0, r3, 0\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + lsrs r6, r0, 24\n\ + ldr r1, _0801F5B8 @ =gLastUsedItem\n\ + mov r3, r8\n\ + ldrb r0, [r3]\n\ + muls r0, r4\n\ + add r0, r9\n\ + ldrh r0, [r0, 0x2E]\n\ + strh r0, [r1]\n\ + ldrb r0, [r3]\n\ + muls r0, r4\n\ + add r0, r9\n\ + movs r5, 0\n\ + movs r1, 0\n\ + strh r1, [r0, 0x2E]\n\ + ldr r2, _0801F5BC @ =gWishFutureKnock\n\ + adds r2, 0x29\n\ + adds r2, r6, r2\n\ + ldr r3, _0801F5C0 @ =gBitTable\n\ + ldr r1, _0801F5C4 @ =gBattlerPartyIndexes\n\ + mov r4, r8\n\ + ldrb r0, [r4]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + ldrh r0, [r0]\n\ + lsls r0, 2\n\ + adds r0, r3\n\ + ldr r0, [r0]\n\ + ldrb r1, [r2]\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + ldr r4, _0801F5C8 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801F5CC @ =BattleScript_KnockedOff\n\ + str r0, [r4]\n\ + ldr r1, _0801F5D0 @ =gSharedMem\n\ + mov r2, r8\n\ + ldrb r0, [r2]\n\ + lsls r0, 1\n\ + ldr r3, _0801F5D4 @ =0x000160e8\n\ + adds r0, r3\n\ + adds r0, r1\n\ + strb r5, [r0]\n\ + ldrb r0, [r2]\n\ + lsls r0, 1\n\ + ldr r4, _0801F5D8 @ =0x000160e9\n\ + adds r0, r4\n\ + adds r0, r1\n\ + strb r5, [r0]\n\ + b _0801F5FA\n\ + .align 2, 0\n\ +_0801F5B8: .4byte gLastUsedItem\n\ +_0801F5BC: .4byte gWishFutureKnock\n\ +_0801F5C0: .4byte gBitTable\n\ +_0801F5C4: .4byte gBattlerPartyIndexes\n\ +_0801F5C8: .4byte gBattlescriptCurrInstr\n\ +_0801F5CC: .4byte BattleScript_KnockedOff\n\ +_0801F5D0: .4byte gSharedMem\n\ +_0801F5D4: .4byte 0x000160e8\n\ +_0801F5D8: .4byte 0x000160e9\n\ +_0801F5DC:\n\ + ldr r1, _0801F5E8 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x1\n\ + str r0, [r1]\n\ + b _0801F5FA\n\ + .align 2, 0\n\ +_0801F5E8: .4byte gBattlescriptCurrInstr\n\ +_0801F5EC:\n\ + ldr r4, _0801F60C @ =gBattlescriptCurrInstr\n\ + ldr r0, [r4]\n\ + adds r0, 0x1\n\ + bl BattleScriptPush\n\ + ldr r0, _0801F610 @ =BattleScript_SAtkDown2\n\ +_0801F5F8:\n\ + str r0, [r4]\n\ +_0801F5FA:\n\ + add sp, 0x8\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0801F60C: .4byte gBattlescriptCurrInstr\n\ +_0801F610: .4byte BattleScript_SAtkDown2\n\ + .syntax divided\n"); +} +#endif // NONMATCHING + +static void atk15_seteffectwithchance(void) +{ + u32 PercentChance; + + if (gBattleMons[gBankAttacker].ability == ABILITY_SERENE_GRACE) + PercentChance = gBattleMoves[gCurrentMove].secondaryEffectChance * 2; + else + PercentChance = gBattleMoves[gCurrentMove].secondaryEffectChance; + + if (DEBUG && (gUnknown_02023A14_50 & 4) + && !(gBattleCommunication[MOVE_EFFECT_BYTE] & 0x80) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + { + SetMoveEffect(0, 0); + } + else if ((gBattleCommunication[MOVE_EFFECT_BYTE] & 0x80) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + { + gBattleCommunication[MOVE_EFFECT_BYTE] &= 0x7F; + SetMoveEffect(0, 0x80); + } + else if (Random() % 100 <= PercentChance && gBattleCommunication[MOVE_EFFECT_BYTE] != 0 && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + { + if (PercentChance >= 100) + SetMoveEffect(0, 0x80); + else + SetMoveEffect(0, 0); + } + else + { + gBattlescriptCurrInstr++; + } + + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; + gBattleStruct->unk16112 = 0; +} + +static void atk16_seteffectprimary(void) +{ + SetMoveEffect(1, 0); +} + +static void atk17_seteffectsecondary(void) +{ + SetMoveEffect(0, 0); +} + +static void atk18_clearstatusfromeffect(void) +{ + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + if (gBattleCommunication[MOVE_EFFECT_BYTE] <= 6) + gBattleMons[gActiveBattler].status1 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); + else + gBattleMons[gActiveBattler].status2 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); + + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; + gBattlescriptCurrInstr += 2; + gBattleStruct->unk16112 = 0; +} + +static void atk19_tryfaintmon(void) +{ + u8 *r4; + + if (gBattlescriptCurrInstr[2] != 0) + { + gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + if (gHitMarker & HITMARKER_FAINTED(gActiveBattler)) + { + r4 = T1_READ_PTR(gBattlescriptCurrInstr + 3); + + BattleScriptPop(); + gBattlescriptCurrInstr = r4; + gSideAffecting[GetBattlerSide(gActiveBattler)] &= ~SIDE_STATUS_SPIKES_DAMAGED; + } + else + { + gBattlescriptCurrInstr += 7; + } + } + else + { + u8 bank; + + if (gBattlescriptCurrInstr[1] == 1) + { + gActiveBattler = gBankAttacker; + bank = gBankTarget; + r4 = BattleScript_FaintAttacker; + } + else + { + gActiveBattler = gBankTarget; + bank = gBankAttacker; + r4 = BattleScript_FaintTarget; + } + if (!(gAbsentBattlerFlags & gBitTable[gActiveBattler]) + && gBattleMons[gActiveBattler].hp == 0) + { + ewram160ACarr2(0, bank) = 0; + ewram160ACarr2(1, bank) = 0; + ewram16100arr2(0, bank) = 0; + ewram16100arr2(1, bank) = 0; + ewram16100arr2(2, bank) = 0; + ewram16100arr2(3, bank) = 0; + + gHitMarker |= HITMARKER_FAINTED(gActiveBattler); + BattleScriptPush(gBattlescriptCurrInstr + 7); + gBattlescriptCurrInstr = r4; + if (GetBattlerSide(gActiveBattler) == 0) + { + gHitMarker |= HITMARKER_x400000; + if (gBattleResults.playerFaintCounter < 0xFF) + gBattleResults.playerFaintCounter++; + if (gBattleMons[bank].level > gBattleMons[gActiveBattler].level) + { + if (gBattleMons[bank].level - gBattleMons[gActiveBattler].level > 29) + AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], FRIENDSHIP_EVENT_FAINT_LARGE); + else + AdjustFriendship(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], FRIENDSHIP_EVENT_FAINT_SMALL); + } + } + else + { + if (gBattleResults.opponentFaintCounter < 0xFF) + gBattleResults.opponentFaintCounter++; + gBattleResults.lastOpponentSpecies = gBattleMons[gActiveBattler].species; + } + if ((gHitMarker & HITMARKER_DESTINYBOND) && gBattleMons[gBankAttacker].hp != 0) + { + BattleScriptPush(gBattlescriptCurrInstr); + gBattleMoveDamage = gBattleMons[bank].hp; + gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife; + } + if ((gStatuses3[gBankTarget] & STATUS3_GRUDGE) + && !(gHitMarker & HITMARKER_GRUDGE) + && GetBattlerSide(gBankAttacker) != GetBattlerSide(gBankTarget) + && gBattleMons[gBankAttacker].hp != 0 + && gCurrentMove != MOVE_STRUGGLE) + { + u8 moveIndex = ewram1608Carr(gBankAttacker); + + gBattleMons[gBankAttacker].pp[moveIndex] = 0; + BattleScriptPush(gBattlescriptCurrInstr); + gBattlescriptCurrInstr = BattleScript_SelectingImprisionedMoveInPalace; + gActiveBattler = gBankAttacker; + EmitSetMonData(0, moveIndex + 9, 0, 1, &gBattleMons[gActiveBattler].pp[moveIndex]); + MarkBufferBankForExecution(gActiveBattler); + + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = gBattleMons[gBankAttacker].moves[moveIndex]; + gBattleTextBuff1[3] = gBattleMons[gBankAttacker].moves[moveIndex] >> 8; + gBattleTextBuff1[4] = EOS; + } + } + else + { + gBattlescriptCurrInstr += 7; + } + } +} + +static void atk1A_dofaintanimation(void) +{ + if (gBattleExecBuffer == 0) + { + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + Emitcmd10(0); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 2; + } +} + +static void atk1B_cleareffectsonfaint(void) +{ + //Clears things like attraction or trapping to other banks + if (gBattleExecBuffer == 0) + { + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + gBattleMons[gActiveBattler].status1 = 0; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 0x4, &gBattleMons[gActiveBattler].status1); + MarkBufferBankForExecution(gActiveBattler); + UndoEffectsAfterFainting(); + gBattlescriptCurrInstr += 2; + } +} + +static void atk1C_jumpifstatus(void) +{ + u8 bank = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + u32 flags = T2_READ_32(gBattlescriptCurrInstr + 2); + void* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 6); + if (gBattleMons[bank].status1 & flags && gBattleMons[bank].hp) + gBattlescriptCurrInstr = jump_loc; + else + gBattlescriptCurrInstr += 10; +} + +static void atk1D_jumpifstatus2(void) +{ + u8 bank = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + u32 flags = T2_READ_32(gBattlescriptCurrInstr + 2); + void* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 6); + if (gBattleMons[bank].status2 & flags && gBattleMons[bank].hp) + gBattlescriptCurrInstr = jump_loc; + else + gBattlescriptCurrInstr += 10; +} + +static void atk1E_jumpifability(void) +{ + u8 bank; + u8 ability = T2_READ_8(gBattlescriptCurrInstr + 2); + void* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 3); + if (T2_READ_8(gBattlescriptCurrInstr + 1) == 8) + { + bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_BANK_SIDE, gBankAttacker, ability, 0, 0); + if (bank) + { + gLastUsedAbility = ability; + gBattlescriptCurrInstr = jump_loc; + RecordAbilityBattle(bank -1, gLastUsedAbility); + ewram160F8 = bank - 1; + } + else + gBattlescriptCurrInstr += 7; + } + else if (T2_READ_8(gBattlescriptCurrInstr + 1) == 9) + { + bank = AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gBankAttacker, ability, 0, 0); + if (bank) + { + gLastUsedAbility = ability; + gBattlescriptCurrInstr = jump_loc; + RecordAbilityBattle(bank - 1, gLastUsedAbility); + ewram160F8 = bank - 1; + } + else + gBattlescriptCurrInstr += 7; + } + else + { + bank = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + if (gBattleMons[bank].ability == ability) + { + gLastUsedAbility = ability; + gBattlescriptCurrInstr = jump_loc; + RecordAbilityBattle(bank, gLastUsedAbility); + ewram160F8 = bank; + } + else + gBattlescriptCurrInstr += 7; + } +} + +static void atk1F_jumpifsideaffecting(void) +{ + u8 side; + u16 flags; + void* jump_loc; + if (T2_READ_8(gBattlescriptCurrInstr + 1) == 1) + side = GetBattlerPosition(gBankAttacker) & 1; + else + side = GetBattlerPosition(gBankTarget) & 1; + + flags = T2_READ_16(gBattlescriptCurrInstr + 2); + jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 4); + + if (gSideAffecting[side] & flags) + gBattlescriptCurrInstr = jump_loc; + else + gBattlescriptCurrInstr += 8; +} + +static void atk20_jumpifstat(void) +{ + u8 ret = 0; + u8 bank = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + u8 value = gBattleMons[bank].statStages[T2_READ_8(gBattlescriptCurrInstr + 3)]; + switch (T2_READ_8(gBattlescriptCurrInstr + 2)) + { + case CMP_EQUAL: + if (value == T2_READ_8(gBattlescriptCurrInstr + 4)) + ret++; + break; + case CMP_NOT_EQUAL: + if (value != T2_READ_8(gBattlescriptCurrInstr + 4)) + ret++; + break; + case CMP_GREATER_THAN: + if (value > T2_READ_8(gBattlescriptCurrInstr + 4)) + ret++; + break; + case CMP_LESS_THAN: + if (value < T2_READ_8(gBattlescriptCurrInstr + 4)) + ret++; + break; + case CMP_COMMON_BITS: + if (value & T2_READ_8(gBattlescriptCurrInstr + 4)) + ret++; + break; + case CMP_NO_COMMON_BITS: + if (!(value & T2_READ_8(gBattlescriptCurrInstr + 4))) + ret++; + break; + } + if (ret) + gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 5); + else + gBattlescriptCurrInstr += 9; +} + +static void atk21_jumpifstatus3condition(void) +{ + u32 flags; + void* jump_loc; + + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + flags = T2_READ_32(gBattlescriptCurrInstr + 2); + jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 7); + if (T2_READ_8(gBattlescriptCurrInstr + 6)) + { + if ((gStatuses3[gActiveBattler] & flags) != 0) + gBattlescriptCurrInstr += 11; + else + gBattlescriptCurrInstr = jump_loc; + } + else + { + if ((gStatuses3[gActiveBattler] & flags) != 0) + gBattlescriptCurrInstr = jump_loc; + else + gBattlescriptCurrInstr += 11; + } +} + +static void atk22_jumpiftype(void) //u8 bank, u8 type, *ptr +{ + u8 bank = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + u8 type = T2_READ_8(gBattlescriptCurrInstr + 2); + void* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 3); + + if (gBattleMons[bank].type1 == type || gBattleMons[bank].type2 == type) + gBattlescriptCurrInstr = jump_loc; + else + gBattlescriptCurrInstr += 7; +} + +static void atk23_getexp(void) +{ + u16 item; + s32 i; // also used as stringId + u8 holdEffect; + s32 sentIn; + + s32 viaExpShare = 0; + u16* exp = &gBattleStruct->exp; + + gBank1 = GetBattleBank(gBattlescriptCurrInstr[1]); + sentIn = gSentPokesToOpponent[(gBank1 & 2) >> 1]; + + switch (gBattleStruct->getexpStateTracker) + { + case 0: // check if should receive exp at all + if (GetBattlerSide(gBank1) != B_SIDE_OPPONENT || (gBattleTypeFlags & + (BATTLE_TYPE_LINK + | BATTLE_TYPE_SAFARI + | BATTLE_TYPE_BATTLE_TOWER + | BATTLE_TYPE_EREADER_TRAINER))) + { + gBattleStruct->getexpStateTracker = 6; // goto last case + } + else + { + gBattleStruct->getexpStateTracker++; + gBattleStruct->unk16113 |= gBitTable[gBattlerPartyIndexes[gBank1]]; + } + break; + case 1: // calculate experience points to redistribute + { + u16 calculatedExp; + s32 viaSentIn; + + for (viaSentIn = 0, i = 0; i < 6; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == SPECIES_NONE || GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0) + continue; + if (gBitTable[i] & sentIn) + viaSentIn++; + + item = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); + + if (item == ITEM_ENIGMA_BERRY) + holdEffect = gSaveBlock1.enigmaBerry.holdEffect; + else + holdEffect = ItemId_GetHoldEffect(item); + + if (holdEffect == HOLD_EFFECT_EXP_SHARE) + viaExpShare++; + } + + calculatedExp = gBaseStats[gBattleMons[gBank1].species].expYield * gBattleMons[gBank1].level / 7; + + if (viaExpShare) // at least one mon is getting exp via exp share + { + *exp = calculatedExp / 2 / viaSentIn; + if (*exp == 0) + *exp = 1; + + gExpShareExp = calculatedExp / 2 / viaExpShare; + if (gExpShareExp == 0) + gExpShareExp = 1; + } + else + { + *exp = calculatedExp / viaSentIn; + if (*exp == 0) + *exp = 1; + gExpShareExp = 0; + } + + gBattleStruct->getexpStateTracker++; + gBattleStruct->expGetterID = 0; + gBattleStruct->sentInPokes = sentIn; + } + // fall through + case 2: // set exp value to the poke in expgetter_id and print message + if (gBattleExecBuffer == 0) + { + item = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_HELD_ITEM); + + if (item == ITEM_ENIGMA_BERRY) + holdEffect = gSaveBlock1.enigmaBerry.holdEffect; + else + holdEffect = ItemId_GetHoldEffect(item); + + if (holdEffect != HOLD_EFFECT_EXP_SHARE && !(gBattleStruct->sentInPokes & 1)) + { + gBattleStruct->sentInPokes >>= 1; + gBattleStruct->getexpStateTracker = 5; + gBattleMoveDamage = 0; // used for exp + } + else if (GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_LEVEL) == 100) + { + gBattleStruct->sentInPokes >>= 1; + gBattleStruct->getexpStateTracker = 5; + gBattleMoveDamage = 0; // used for exp + } + else + { + // music change in wild battle after fainting a poke + if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) && gBattleMons[0].hp && !gBattleStruct->wildVictorySong) + { + BattleStopLowHpSound(); + PlayBGM(0x161); + gBattleStruct->wildVictorySong++; + } + + if (GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_HP)) + { + if (gBattleStruct->sentInPokes & 1) + gBattleMoveDamage = *exp; + else + gBattleMoveDamage = 0; + + if (holdEffect == HOLD_EFFECT_EXP_SHARE) + gBattleMoveDamage += gExpShareExp; + if (holdEffect == HOLD_EFFECT_LUCKY_EGG) + gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; + + if (IsTradedMon(&gPlayerParty[gBattleStruct->expGetterID])) + { + gBattleMoveDamage = (gBattleMoveDamage * 150) / 100; + i = 0x14A; + } + else + { + i = 0x149; + } + + // get exp getter bank + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + if (!(gBattlerPartyIndexes[2] != gBattleStruct->expGetterID) && !(gAbsentBattlerFlags & gBitTable[2])) + gBattleStruct->expGetterBank = 2; + else + { + if (!(gAbsentBattlerFlags & gBitTable[0])) + gBattleStruct->expGetterBank = 0; + else + gBattleStruct->expGetterBank = 2; + } + } + else + gBattleStruct->expGetterBank = 0; + + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattleStruct->expGetterBank, gBattleStruct->expGetterID) + + // buffer 'gained' or 'gained a boosted' + PREPARE_STRING_BUFFER(gBattleTextBuff2, i) + + PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 5, gBattleMoveDamage) + + PrepareStringBattle(STRINGID_PKMNGAINEDEXP, gBattleStruct->expGetterBank); + MonGainEVs(&gPlayerParty[gBattleStruct->expGetterID], gBattleMons[gBank1].species); + } + gBattleStruct->sentInPokes >>= 1; + gBattleStruct->getexpStateTracker++; + } + } + break; + case 3: // Set stats and give exp + if (gBattleExecBuffer == 0) + { + gBattleBufferB[gBattleStruct->expGetterBank][0] = 0; + if (GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_HP) && GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_LEVEL) != 100) + { + gBattleResources_statsBeforeLvlUp->hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_MAX_HP); + gBattleResources_statsBeforeLvlUp->atk = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_ATK); + gBattleResources_statsBeforeLvlUp->def = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_DEF); + gBattleResources_statsBeforeLvlUp->spd = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPEED); + gBattleResources_statsBeforeLvlUp->spAtk = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPATK); + gBattleResources_statsBeforeLvlUp->spDef = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPDEF); + + gActiveBattler = gBattleStruct->expGetterBank; + + EmitExpBarUpdate(0, gBattleStruct->expGetterID, gBattleMoveDamage); + MarkBufferBankForExecution(gActiveBattler); + } + gBattleStruct->getexpStateTracker++; + } + break; + case 4: // lvl up if necessary + if (gBattleExecBuffer == 0) + { + gActiveBattler = gBattleStruct->expGetterBank; + if (gBattleBufferB[gActiveBattler][0] == CONTROLLER_TWORETURNVALUES + && gBattleBufferB[gActiveBattler][1] == RET_VALUE_LEVELLED_UP) + { + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterID) + HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); + + PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gActiveBattler, gBattleStruct->expGetterID) + + PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 3, GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_LEVEL)) + + BattleScriptPushCursor(); + gLeveledUpInBattle |= gBitTable[gBattleStruct->expGetterID]; + gBattlescriptCurrInstr = BattleScript_LevelUp; + gBattleMoveDamage = (gBattleBufferB[gActiveBattler][2] | (gBattleBufferB[gActiveBattler][3] << 8)); + AdjustFriendship(&gPlayerParty[gBattleStruct->expGetterID], FRIENDSHIP_EVENT_GROW_LEVEL); + + // update battle mon structure after level up + if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterID && gBattleMons[0].hp) + { + gBattleMons[0].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_LEVEL); + gBattleMons[0].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_HP); + gBattleMons[0].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_MAX_HP); + gBattleMons[0].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_ATK); + gBattleMons[0].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_DEF); + // Why is this duplicated? + gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPEED); + gBattleMons[0].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPEED); + gBattleMons[0].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPATK); + gBattleMons[0].spDefense = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPDEF); + } + // What is else if? + if (gBattlerPartyIndexes[2] == gBattleStruct->expGetterID && gBattleMons[2].hp && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + gBattleMons[2].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_LEVEL); + gBattleMons[2].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_HP); + gBattleMons[2].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_MAX_HP); + gBattleMons[2].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_ATK); + gBattleMons[2].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_DEF); + // Duplicated again, but this time there's no Sp Defense + gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPEED); + gBattleMons[2].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPEED); + gBattleMons[2].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_SPATK); + } + } + else + { + gBattleMoveDamage = 0; + } + gBattleStruct->getexpStateTracker = 5; + } + break; + case 5: // looper increment + if (gBattleMoveDamage) // there is exp to give, goto case 3 that gives exp + gBattleStruct->getexpStateTracker = 3; + else + { + gBattleStruct->expGetterID++; + if (gBattleStruct->expGetterID <= 5) + gBattleStruct->getexpStateTracker = 2; // loop again + else + gBattleStruct->getexpStateTracker = 6; // we're done + } + break; + case 6: // increment instruction + if (gBattleExecBuffer == 0) + { + // not sure why gf clears the item and ability here + gBattleMons[gBank1].item = 0; + gBattleMons[gBank1].ability = 0; + gBattlescriptCurrInstr += 2; + } + break; + } +} + +#ifdef NONMATCHING +static void atk24(void) +{ + u16 HP_count = 0; + int i; + if (gBattleExecBuffer) {return;} + + for (i = 0; i < 6; i++) + { + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)) + HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); + } + + if (HP_count == 0) + gBattleOutcome |= BATTLE_LOST; + + for (HP_count = 0, i = 0; i < 6; i++) + { + if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES) && !GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG)) + HP_count += GetMonData(&gEnemyParty[i], MON_DATA_HP); + } + + if (!HP_count) + gBattleOutcome |= BATTLE_WON; + + if (!gBattleOutcome && (gBattleTypeFlags & BATTLE_TYPE_LINK)) + { + register int found1 asm("r2"); + register int found2 asm("r4"); + + //I can't for the love of god decompile that part + + for (found1 = 0, i = 0; i < gBattlersCount; i += 2) + { + if ((gHitMarker & HITMARKER_UNK(i)) && !gSpecialStatuses[i].flag40) + found1++; + } + + for (found2 = 0, i = 1; i < gBattlersCount; i += 2) + { + if ((gHitMarker & HITMARKER_UNK(i)) && !gSpecialStatuses[i].flag40) + found2++; + } + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (found2 + found1 > 1) + gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; + } + else + { + if (found2 != 0 && found1 != 0) + gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; + } + } + else + gBattlescriptCurrInstr += 5; + +} +#else +NAKED +static void atk24(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r8\n\ + push {r7}\n\ + movs r6, 0\n\ + ldr r0, _08020AF0 @ =gBattleExecBuffer\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + beq _080209C6\n\ + b _08020B46\n\ +_080209C6:\n\ + movs r5, 0\n\ +_080209C8:\n\ + movs r0, 0x64\n\ + adds r1, r5, 0\n\ + muls r1, r0\n\ + ldr r0, _08020AF4 @ =gPlayerParty\n\ + adds r4, r1, r0\n\ + adds r0, r4, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _080209F8\n\ + adds r0, r4, 0\n\ + movs r1, 0x2D\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + bne _080209F8\n\ + adds r0, r4, 0\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + adds r0, r6, r0\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ +_080209F8:\n\ + adds r5, 0x1\n\ + cmp r5, 0x5\n\ + ble _080209C8\n\ + cmp r6, 0\n\ + bne _08020A0C\n\ + ldr r0, _08020AF8 @ =gBattleOutcome\n\ + ldrb r1, [r0]\n\ + movs r2, 0x2\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ +_08020A0C:\n\ + movs r6, 0\n\ + movs r5, 0\n\ +_08020A10:\n\ + movs r0, 0x64\n\ + adds r1, r5, 0\n\ + muls r1, r0\n\ + ldr r0, _08020AFC @ =gEnemyParty\n\ + adds r4, r1, r0\n\ + adds r0, r4, 0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _08020A40\n\ + adds r0, r4, 0\n\ + movs r1, 0x2D\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + bne _08020A40\n\ + adds r0, r4, 0\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + adds r0, r6, r0\n\ + lsls r0, 16\n\ + lsrs r6, r0, 16\n\ +_08020A40:\n\ + adds r5, 0x1\n\ + cmp r5, 0x5\n\ + ble _08020A10\n\ + ldr r2, _08020AF8 @ =gBattleOutcome\n\ + cmp r6, 0\n\ + bne _08020A54\n\ + ldrb r0, [r2]\n\ + movs r1, 0x1\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ +_08020A54:\n\ + ldrb r0, [r2]\n\ + cmp r0, 0\n\ + bne _08020B3E\n\ + ldr r2, _08020B00 @ =gBattleTypeFlags\n\ + ldrh r1, [r2]\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + mov r8, r2\n\ + cmp r0, 0\n\ + beq _08020B3E\n\ + movs r2, 0\n\ + movs r5, 0\n\ + ldr r0, _08020B04 @ =gBattlersCount\n\ + ldrb r3, [r0]\n\ + mov r12, r0\n\ + ldr r7, _08020B08 @ =gBattlescriptCurrInstr\n\ + cmp r2, r3\n\ + bge _08020AA0\n\ + ldr r0, _08020B0C @ =gHitMarker\n\ + movs r1, 0x80\n\ + lsls r1, 21\n\ + ldr r6, [r0]\n\ + adds r4, r3, 0\n\ + ldr r3, _08020B10 @ =gSpecialStatuses\n\ +_08020A84:\n\ + adds r0, r1, 0\n\ + lsls r0, r5\n\ + ands r0, r6\n\ + cmp r0, 0\n\ + beq _08020A98\n\ + ldrb r0, [r3]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _08020A98\n\ + adds r2, 0x1\n\ +_08020A98:\n\ + adds r3, 0x28\n\ + adds r5, 0x2\n\ + cmp r5, r4\n\ + blt _08020A84\n\ +_08020AA0:\n\ + movs r4, 0\n\ + movs r5, 0x1\n\ + mov r0, r12\n\ + ldrb r3, [r0]\n\ + cmp r5, r3\n\ + bge _08020ADA\n\ + ldr r0, _08020B0C @ =gHitMarker\n\ + movs r1, 0x80\n\ + lsls r1, 21\n\ + mov r12, r1\n\ + ldr r1, [r0]\n\ + ldr r0, _08020B10 @ =gSpecialStatuses\n\ + adds r6, r3, 0\n\ + adds r3, r0, 0\n\ + adds r3, 0x14\n\ +_08020ABE:\n\ + mov r0, r12\n\ + lsls r0, r5\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08020AD2\n\ + ldrb r0, [r3]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _08020AD2\n\ + adds r4, 0x1\n\ +_08020AD2:\n\ + adds r3, 0x28\n\ + adds r5, 0x2\n\ + cmp r5, r6\n\ + blt _08020ABE\n\ +_08020ADA:\n\ + mov r0, r8\n\ + ldrh r1, [r0]\n\ + movs r0, 0x40\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08020B14\n\ + adds r0, r4, r2\n\ + cmp r0, 0x1\n\ + bgt _08020B1C\n\ + b _08020B36\n\ + .align 2, 0\n\ +_08020AF0: .4byte gBattleExecBuffer\n\ +_08020AF4: .4byte gPlayerParty\n\ +_08020AF8: .4byte gBattleOutcome\n\ +_08020AFC: .4byte gEnemyParty\n\ +_08020B00: .4byte gBattleTypeFlags\n\ +_08020B04: .4byte gBattlersCount\n\ +_08020B08: .4byte gBattlescriptCurrInstr\n\ +_08020B0C: .4byte gHitMarker\n\ +_08020B10: .4byte gSpecialStatuses\n\ +_08020B14:\n\ + cmp r4, 0\n\ + beq _08020B36\n\ + cmp r2, 0\n\ + beq _08020B36\n\ +_08020B1C:\n\ + ldr r2, [r7]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + adds r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + adds r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 24\n\ + adds r1, r0\n\ + str r1, [r7]\n\ + b _08020B46\n\ +_08020B36:\n\ + ldr r0, [r7]\n\ + adds r0, 0x5\n\ + str r0, [r7]\n\ + b _08020B46\n\ +_08020B3E:\n\ + ldr r1, _08020B50 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x5\n\ + str r0, [r1]\n\ +_08020B46:\n\ + pop {r3}\n\ + mov r8, r3\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08020B50: .4byte gBattlescriptCurrInstr\n\ + .syntax divided\n"); +} +#endif + +static void MoveValuesCleanUp(void) +{ + gMoveResultFlags = 0; + gBattleStruct->dmgMultiplier = 1; + gCritMultiplier = 1; + gBattleCommunication[MOVE_EFFECT_BYTE] = 0; + gBattleCommunication[6] = 0; + gHitMarker &= ~(HITMARKER_DESTINYBOND); + gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT); +} + +static void atk25_movevaluescleanup(void) +{ + MoveValuesCleanUp(); + gBattlescriptCurrInstr += 1; +} + +static void atk26_setmultihit(void) +{ + gMultiHitCounter = T2_READ_8(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr += 2; +} + +static void atk27_decrementmultihit(void) +{ + if (--gMultiHitCounter == 0) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atk28_goto(void) +{ + gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atk29_jumpifbyte(void) +{ + u8 caseID = T2_READ_8(gBattlescriptCurrInstr + 1); + u8* ptr = T2_READ_PTR(gBattlescriptCurrInstr + 2); + u8 value = T2_READ_8(gBattlescriptCurrInstr + 6); + u8* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 7); + gBattlescriptCurrInstr += 11; + switch (caseID) + { + case CMP_EQUAL: + if (*ptr == value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_NOT_EQUAL: + if (*ptr != value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_GREATER_THAN: + if (*ptr > value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_LESS_THAN: + if (*ptr < value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_COMMON_BITS: + if (*ptr & value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_NO_COMMON_BITS: + if (!(*ptr & value)) + gBattlescriptCurrInstr = jump_loc; + break; + } +} + +static void atk2A_jumpifhalfword(void) +{ + u8 caseID = T2_READ_8(gBattlescriptCurrInstr + 1); + u16* ptr = T2_READ_PTR(gBattlescriptCurrInstr + 2); + u16 value = T2_READ_16(gBattlescriptCurrInstr + 6); + u8* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 8); + gBattlescriptCurrInstr += 12; + switch (caseID) + { + case CMP_EQUAL: + if (*ptr == value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_NOT_EQUAL: + if (*ptr != value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_GREATER_THAN: + if (*ptr > value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_LESS_THAN: + if (*ptr < value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_COMMON_BITS: + if (*ptr & value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_NO_COMMON_BITS: + if (!(*ptr & value)) + gBattlescriptCurrInstr = jump_loc; + break; + } +} + +// Strange that there's an instance of T1_READ_32 in what seems to be a T2 function. see global.h for the distinction. +static void atk2B_jumpifword(void) +{ + u8 caseID = T2_READ_8(gBattlescriptCurrInstr + 1); + u32* ptr = T2_READ_PTR(gBattlescriptCurrInstr + 2); + u32 value = T1_READ_32(gBattlescriptCurrInstr + 6); + u8* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 10); + gBattlescriptCurrInstr += 14; + switch (caseID) + { + case CMP_EQUAL: + if (*ptr == value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_NOT_EQUAL: + if (*ptr != value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_GREATER_THAN: + if (*ptr > value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_LESS_THAN: + if (*ptr < value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_COMMON_BITS: + if (*ptr & value) + gBattlescriptCurrInstr = jump_loc; + break; + case CMP_NO_COMMON_BITS: + if (!(*ptr & value)) + gBattlescriptCurrInstr = jump_loc; + break; + } +} + +static void atk2C_jumpifarrayequal(void) +{ + //Mem1, Mem2, Size, Jump Loc + u8* mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1); + u8* mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5); + u32 size = T2_READ_8(gBattlescriptCurrInstr + 9); + u8* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 10); + + u8 i; + for (i = 0; i < size; i++) + { + if (*mem1 != *mem2) + { + gBattlescriptCurrInstr += 14; + break; + } + mem1++, mem2++; + } + + if (i == size) + gBattlescriptCurrInstr = jump_loc; +} + +static void atk2D_jumpifarraynotequal(void) +{ + //Mem1, Mem2, Size, Jump Loc + u8 equal_bytes = 0; + u8* mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1); + u8* mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5); + u32 size = T2_READ_8(gBattlescriptCurrInstr + 9); + u8* jump_loc = T2_READ_PTR(gBattlescriptCurrInstr + 10); + + u8 i; + for (i = 0; i < size; i++) + { + if (*mem1 == *mem2) + { + equal_bytes++; + } + mem1++, mem2++; + } + + if (equal_bytes != size) + gBattlescriptCurrInstr = jump_loc; + else + gBattlescriptCurrInstr += 14; +} + +static void atk2E_setbyte(void) +{ + u8* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); + *mem = T2_READ_8(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr += 6; +} + +static void atk2F_addbyte(void) +{ + u8* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); + *mem += T2_READ_8(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr += 6; +} + +static void atk30_subbyte(void) +{ + u8* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); + *mem -= T2_READ_8(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr += 6; +} + +static void atk31_copyarray(void) +{ + u8* mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1); + u8* mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5); + s32 size = T2_READ_8(gBattlescriptCurrInstr + 9); + + s32 i; + for (i = 0; i < size; i++) + { + mem1[i] = mem2[i]; + } + + gBattlescriptCurrInstr += 10; +} + +static void atk32_copyarraywithindex(void) +{ + u8* mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1); + u8* mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5); + u8* index = T2_READ_PTR(gBattlescriptCurrInstr + 9); + s32 size = T2_READ_8(gBattlescriptCurrInstr + 13); + + s32 i; + for (i = 0; i < size; i++) + { + mem1[i] = mem2[i + *index]; + } + + gBattlescriptCurrInstr += 14; +} + +static void atk33_orbyte(void) +{ + u8* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); + *mem |= T2_READ_8(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr += 6; +} + +static void atk34_orhalfword(void) +{ + u16* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); + u16 val = T2_READ_16(gBattlescriptCurrInstr + 5); + + *mem |= val; + gBattlescriptCurrInstr += 7; +} + +static void atk35_orword(void) +{ + u32* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); + u32 val = T2_READ_32(gBattlescriptCurrInstr + 5); + + *mem |= val; + gBattlescriptCurrInstr += 9; +} + +static void atk36_bicbyte(void) +{ + u8* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); + *mem &= ~(T2_READ_8(gBattlescriptCurrInstr + 5)); + gBattlescriptCurrInstr += 6; +} + +static void atk37_bichalfword(void) +{ + u16* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); + u16 val = T2_READ_16(gBattlescriptCurrInstr + 5); + + *mem &= ~val; + gBattlescriptCurrInstr += 7; +} + +static void atk38_bicword(void) +{ + u32* mem = T2_READ_PTR(gBattlescriptCurrInstr + 1); + u32 val = T2_READ_32(gBattlescriptCurrInstr + 5); + + *mem &= ~val; + gBattlescriptCurrInstr += 9; +} + +static void atk39_pause(void) +{ + if (gBattleExecBuffer == 0) + { + u16 value = T2_READ_16(gBattlescriptCurrInstr + 1); + if (++gPauseCounterBattle >= value) + { + gPauseCounterBattle = 0; + gBattlescriptCurrInstr += 3; + } + } +} + +static void atk3A_waitstate(void) +{ + if (gBattleExecBuffer == 0) + gBattlescriptCurrInstr++; +} + +static void atk3B_healthbar_update(void) +{ + if (!T2_READ_8(gBattlescriptCurrInstr + 1)) + gActiveBattler = gBankTarget; + else + gActiveBattler = gBankAttacker; + + EmitHealthBarUpdate(0, gBattleMoveDamage); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 2; +} + +static void atk3C_return(void) +{ + BattleScriptPop(); +} + +static void atk3D_end(void) +{ + gMoveResultFlags = 0; + gActiveBattler = 0; + gCurrentActionFuncId = 0xB; +} + +static void atk3E_end2(void) +{ + //not much difference between this and 3D. It's more apparent in Emerald + gActiveBattler = 0; + gCurrentActionFuncId = 0xB; +} + +static void atk3F_end3(void) //pops the main function stack +{ + BattleScriptPop(); + if (B_FUNCTION_STACK->size) + B_FUNCTION_STACK->size--; + gBattleMainFunc = B_FUNCTION_STACK->ptr[B_FUNCTION_STACK->size]; +} + +static void atk41_call(void) +{ + BattleScriptPush(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atk42_jumpiftype2(void) //u8 bank, u8 type, *ptr +{ + u8 bank = GetBattleBank(T1_READ_8(gBattlescriptCurrInstr + 1)); + + if (T1_READ_8(gBattlescriptCurrInstr + 2) == gBattleMons[bank].type1 || T1_READ_8(gBattlescriptCurrInstr + 2) == gBattleMons[bank].type2) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + else + gBattlescriptCurrInstr += 7; +} + +static void atk43_jumpifabilitypresent(void) +{ + if (AbilityBattleEffects(ABILITYEFFECT_CHECK_ON_FIELD, 0, T2_READ_8(gBattlescriptCurrInstr + 1), 0, 0)) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; +} + +static void atk44_endselectionscript(void) +{ + ewram16060(gBankAttacker) = 1; +} + +static void atk45_playanimation(void) +{ + const u16* argumentPtr; + + gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 3); + + if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE + || gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE + || gBattlescriptCurrInstr[2] == B_ANIM_SUBSTITUTE_FADE) + { + EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 7; + } + else if (gHitMarker & HITMARKER_NO_ANIMATIONS) + { + BattleScriptPush(gBattlescriptCurrInstr + 7); + gBattlescriptCurrInstr = BattleScript_Pausex20; + } + else if (gBattlescriptCurrInstr[2] == B_ANIM_RAIN_CONTINUES + || gBattlescriptCurrInstr[2] == B_ANIM_SUN_CONTINUES + || gBattlescriptCurrInstr[2] == B_ANIM_SANDSTORM_CONTINUES + || gBattlescriptCurrInstr[2] == B_ANIM_HAIL_CONTINUES) + { + EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 7; + } + else if (gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) + { + gBattlescriptCurrInstr += 7; + } + else + { + EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 7; + } +} + +static void atk46_playanimation2(void) // animation Id is stored in the first pointer +{ + const u16* argumentPtr; + const u8* animationIdPtr; + + gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + animationIdPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 2); + argumentPtr = BS2ScriptReadPtr(gBattlescriptCurrInstr + 6); + + if (*animationIdPtr == B_ANIM_STATS_CHANGE + || *animationIdPtr == B_ANIM_SNATCH_MOVE + || *animationIdPtr == B_ANIM_SUBSTITUTE_FADE) + { + EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 10; + } + else if (gHitMarker & HITMARKER_NO_ANIMATIONS) + { + gBattlescriptCurrInstr += 10; + } + else if (*animationIdPtr == B_ANIM_RAIN_CONTINUES + || *animationIdPtr == B_ANIM_SUN_CONTINUES + || *animationIdPtr == B_ANIM_SANDSTORM_CONTINUES + || *animationIdPtr == B_ANIM_HAIL_CONTINUES) + { + EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 10; + } + else if (gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) + { + gBattlescriptCurrInstr += 10; + } + else + { + EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 10; + } +} + +static void atk47_setgraphicalstatchangevalues(void) +{ + u8 to_add = 0; + switch (gBattleStruct->statChanger & 0xF0) + { + case 0x10: //+1 + to_add = 0xF; + break; + case 0x20: //+2 + to_add = 0x27; + break; + case 0x90: //-1 + to_add = 0x16; + break; + case 0xA0: //-2 + to_add = 0x2E; + break; + } + gBattleStruct->animArg1 = (gBattleStruct->statChanger & 0xF) + to_add - 1; + gBattleStruct->animArg2 = 0; + gBattlescriptCurrInstr++; +} + +#ifdef NONMATCHING +static void atk48_playstatchangeanimation(void) +{ + int curr_stat = 0; + u16 stat_animID = 0; + int changeable_stats = 0; + u32 stats_to_check; + u8 arg3; + + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + stats_to_check = T2_READ_8(gBattlescriptCurrInstr + 2); + arg3 = T2_READ_8(gBattlescriptCurrInstr + 3); + if (arg3 & 1) + { + u16 r1 = 0x15; + if (arg3 & 0x2) + r1 = 0x2D; + while (stats_to_check != 0) + { + if (!(stats_to_check & 1)) + continue; + if (!(T2_READ_8(gBattlescriptCurrInstr + 3))) + { + u8 ability; + if (gSideTimers[GetBattlerPosition(gActiveBattler) & 1].mistTimer) + continue; + ability = gBattleMons[gActiveBattler].ability; + if (ability == ABILITY_CLEAR_BODY || ability == ABILITY_WHITE_SMOKE || (ability == ABILITY_KEEN_EYE && curr_stat == 6) || (ability == ABILITY_HYPER_CUTTER && curr_stat == 1)) + continue; + } + if (gBattleMons[gActiveBattler].statStages[curr_stat] > 0) + { + stat_animID = r1; + changeable_stats++; + } + + stats_to_check >>= 1; + r1 += 1; + curr_stat++; + } + if (changeable_stats > 1 && T2_READ_8(gBattlescriptCurrInstr + 3) & 2) + stat_animID = 0x39; + else + stat_animID = 0x3A; + } + else + { + u16 r1 = 0x15; + if (arg3 & 0x2) + r1 = 0x2D; + while (stats_to_check != 0) + { + if (!(stats_to_check & 1)) + continue; + if (gBattleMons[gActiveBattler].statStages[curr_stat] < 0xB) + { + stat_animID = r1; + changeable_stats++; + } + + stats_to_check >>= 1; + r1 += 1; + curr_stat++; + } + if (changeable_stats > 1 && T2_READ_8(gBattlescriptCurrInstr + 3) & 2) + stat_animID = 0x37; + else + stat_animID = 0x38; + } + if ((T2_READ_8(gBattlescriptCurrInstr + 3) & 2 && changeable_stats <= 1) + || changeable_stats == 0 || gBattleStruct->filler2[0] != 0) + gBattlescriptCurrInstr += 4; + else + { + EmitBattleAnimation(0, 1, stat_animID); + MarkBufferBankForExecution(gActiveBattler); + if ((T2_READ_8(gBattlescriptCurrInstr + 3) & 4) && changeable_stats > 1) + gBattleStruct->filler2[0] = 1; + gBattlescriptCurrInstr += 4; + } +} + +#else +NAKED +static void atk48_playstatchangeanimation(void) +{ + asm(".syntax unified\n\ +push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x4\n\ + movs r7, 0\n\ + movs r0, 0\n\ + mov r8, r0\n\ + movs r3, 0\n\ + ldr r5, _08021670 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r5]\n\ + ldrb r0, [r0, 0x1]\n\ + str r3, [sp]\n\ + bl GetBattleBank\n\ + ldr r2, _08021674 @ =gActiveBattler\n\ + strb r0, [r2]\n\ + ldr r0, [r5]\n\ + ldrb r4, [r0, 0x2]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + ldr r3, [sp]\n\ + cmp r0, 0\n\ + beq _08021710\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + movs r1, 0x15\n\ + cmp r0, 0\n\ + beq _0802163C\n\ + movs r1, 0x2D\n\ +_0802163C:\n\ + cmp r4, 0\n\ + beq _080216E4\n\ + movs r0, 0x1\n\ + mov r10, r0\n\ + ldr r0, _08021678 @ =gBattleMons+0x18 @ gBattleMons.statStages\n\ + mov r9, r0\n\ + lsls r5, r1, 16\n\ +_0802164A:\n\ + adds r0, r4, 0\n\ + mov r1, r10\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _080216D6\n\ + ldr r0, _08021670 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r0]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x8\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0802167C\n\ + ldr r0, _08021674 @ =gActiveBattler\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r7, r0\n\ + b _080216C4\n\ + .align 2, 0\n\ +_08021670: .4byte gBattlescriptCurrInstr\n\ +_08021674: .4byte gActiveBattler\n\ +_08021678: .4byte gBattleMons+0x18 @ gBattleMons.statStages\n\ +_0802167C:\n\ + ldr r6, _08021700 @ =gActiveBattler\n\ + ldrb r0, [r6]\n\ + str r3, [sp]\n\ + bl GetBattlerPosition\n\ + mov r1, r10\n\ + ands r1, r0\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + ldr r1, _08021704 @ =gSideTimers\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x2]\n\ + ldr r3, [sp]\n\ + cmp r0, 0\n\ + bne _080216D6\n\ + ldr r0, _08021708 @ =gBattleMons\n\ + ldrb r2, [r6]\n\ + movs r1, 0x58\n\ + muls r2, r1\n\ + adds r0, r2, r0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x1D\n\ + beq _080216D6\n\ + cmp r0, 0x49\n\ + beq _080216D6\n\ + cmp r0, 0x33\n\ + bne _080216BA\n\ + cmp r7, 0x6\n\ + beq _080216D6\n\ +_080216BA:\n\ + cmp r0, 0x34\n\ + bne _080216C2\n\ + cmp r7, 0x1\n\ + beq _080216D6\n\ +_080216C2:\n\ + adds r0, r7, r2\n\ +_080216C4:\n\ + add r0, r9\n\ + ldrb r0, [r0]\n\ + lsls r0, 24\n\ + asrs r0, 24\n\ + cmp r0, 0\n\ + ble _080216D6\n\ + lsrs r0, r5, 16\n\ + mov r8, r0\n\ + adds r3, 0x1\n\ +_080216D6:\n\ + lsrs r4, 1\n\ + movs r1, 0x80\n\ + lsls r1, 9\n\ + adds r5, r1\n\ + adds r7, 0x1\n\ + cmp r4, 0\n\ + bne _0802164A\n\ +_080216E4:\n\ + ldr r0, _0802170C @ =gBattlescriptCurrInstr\n\ + mov r9, r0\n\ + cmp r3, 0x1\n\ + ble _08021772\n\ + ldr r0, [r0]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + movs r1, 0x39\n\ + mov r8, r1\n\ + cmp r0, 0\n\ + beq _08021772\n\ + movs r0, 0x3A\n\ + b _08021770\n\ + .align 2, 0\n\ +_08021700: .4byte gActiveBattler\n\ +_08021704: .4byte gSideTimers\n\ +_08021708: .4byte gBattleMons\n\ +_0802170C: .4byte gBattlescriptCurrInstr\n\ +_08021710:\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + movs r1, 0xE\n\ + cmp r0, 0\n\ + beq _0802171C\n\ + movs r1, 0x26\n\ +_0802171C:\n\ + mov r9, r5\n\ + cmp r4, 0\n\ + beq _08021758\n\ + ldr r6, _0802178C @ =gBattleMons+0x18 @ gBattleMons.statStages\n\ + adds r5, r2, 0\n\ + lsls r2, r1, 16\n\ +_08021728:\n\ + movs r0, 0x1\n\ + ands r0, r4\n\ + cmp r0, 0\n\ + beq _0802174A\n\ + ldrb r1, [r5]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r7, r0\n\ + adds r0, r6\n\ + ldrb r0, [r0]\n\ + lsls r0, 24\n\ + asrs r0, 24\n\ + cmp r0, 0xB\n\ + bgt _0802174A\n\ + lsrs r1, r2, 16\n\ + mov r8, r1\n\ + adds r3, 0x1\n\ +_0802174A:\n\ + lsrs r4, 1\n\ + movs r0, 0x80\n\ + lsls r0, 9\n\ + adds r2, r0\n\ + adds r7, 0x1\n\ + cmp r4, 0\n\ + bne _08021728\n\ +_08021758:\n\ + cmp r3, 0x1\n\ + ble _08021772\n\ + mov r1, r9\n\ + ldr r0, [r1]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x2\n\ + ands r0, r1\n\ + movs r1, 0x37\n\ + mov r8, r1\n\ + cmp r0, 0\n\ + beq _08021772\n\ + movs r0, 0x38\n\ +_08021770:\n\ + mov r8, r0\n\ +_08021772:\n\ + mov r1, r9\n\ + ldr r2, [r1]\n\ + ldrb r1, [r2, 0x3]\n\ + movs r0, 0x4\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08021790\n\ + cmp r3, 0x1\n\ + bgt _08021790\n\ + adds r0, r2, 0x4\n\ + mov r1, r9\n\ + b _080217E6\n\ + .align 2, 0\n\ +_0802178C: .4byte gBattleMons+0x18 @ gBattleMons.statStages\n\ +_08021790:\n\ + cmp r3, 0\n\ + beq _080217E0\n\ + ldr r0, _080217D0 @ =gSharedMem\n\ + ldr r1, _080217D4 @ =0x000160dc\n\ + adds r4, r0, r1\n\ + ldrb r0, [r4]\n\ + cmp r0, 0\n\ + bne _080217E0\n\ + movs r0, 0\n\ + movs r1, 0x1\n\ + mov r2, r8\n\ + str r3, [sp]\n\ + bl EmitBattleAnimation\n\ + ldr r0, _080217D8 @ =gActiveBattler\n\ + ldrb r0, [r0]\n\ + bl MarkBufferBankForExecution\n\ + ldr r0, _080217DC @ =gBattlescriptCurrInstr\n\ + ldr r0, [r0]\n\ + ldrb r1, [r0, 0x3]\n\ + movs r0, 0x4\n\ + ands r0, r1\n\ + ldr r3, [sp]\n\ + cmp r0, 0\n\ + beq _080217CC\n\ + cmp r3, 0x1\n\ + ble _080217CC\n\ + movs r0, 0x1\n\ + strb r0, [r4]\n\ +_080217CC:\n\ + ldr r1, _080217DC @ =gBattlescriptCurrInstr\n\ + b _080217E2\n\ + .align 2, 0\n\ +_080217D0: .4byte gSharedMem\n\ +_080217D4: .4byte 0x000160dc\n\ +_080217D8: .4byte gActiveBattler\n\ +_080217DC: .4byte gBattlescriptCurrInstr\n\ +_080217E0:\n\ + mov r1, r9\n\ +_080217E2:\n\ + ldr r0, [r1]\n\ + adds r0, 0x4\n\ +_080217E6:\n\ + str r0, [r1]\n\ + add sp, 0x4\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .syntax divided"); +} + +#endif // NONMATCHING + +#ifdef NONMATCHING +static void atk49_moveend(void) +{ + int i; + int effect = 0; + u16 last_move = 0, *choiced_move_atk; + int arg1, arg2, hold_effect_atk, move_type; + if (gLastUsedMove != 0xFFFF) + last_move = gLastUsedMove; + + arg1 = T2_READ_8(gBattlescriptCurrInstr + 1); + arg2 = T2_READ_8(gBattlescriptCurrInstr + 2); + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + hold_effect_atk = gEnigmaBerries[gBankAttacker].holdEffect; + else + hold_effect_atk = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + + choiced_move_atk = (u16*)(gBankAttacker * (ewram_addr + 0x160E8)); + if (gBattleStruct->dynamicMoveType) + move_type = gBattleStruct->dynamicMoveType & 0x3F; + else + move_type = gBattleMoves[gCurrentMove].type; + + do + { + switch (gBattleStruct->cmd49StateTracker) + { + case 0: //rage check + if (gBattleMons[gBankTarget].status2 & STATUS2_RAGE + && gBattleMons[gBankTarget].hp && gBankAttacker != gBankTarget + && GetBattlerSide(gBankAttacker) != GetBattlerSide(gBankTarget) + && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && TARGET_TURN_DAMAGED + && gBattleMoves[gCurrentMove].power && gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] <= 0xB) + { + gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK]++; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_RageIsBuilding; + effect = 1; + } + gBattleStruct->cmd49StateTracker++; + break; + case 1: //defrosting check + if (gBattleMons[gBankTarget].status1 & STATUS_FREEZE + && gBattleMons[gBankTarget].hp && gBankAttacker != gBankTarget + && gSpecialStatuses[gBankTarget].moveturnLostHP + && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && move_type == TYPE_FIRE) + { + gBattleMons[gBankTarget].status1 &= ~(STATUS_FREEZE); + gActiveBattler = gBankTarget; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBankTarget].status1); + MarkBufferBankForExecution(gActiveBattler); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_DefrostedViaFireMove; + effect = 1; + } + gBattleStruct->cmd49StateTracker++; + break; + case 2: //target synchronize + if (AbilityBattleEffects(ABILITYEFFECT_SYNCHRONIZE, gBankTarget, 0, 0, 0)) + effect = 1; + gBattleStruct->cmd49StateTracker++; + break; + case 3: //contact abilities + if (AbilityBattleEffects(ABILITYEFFECT_CONTACT, gBankTarget, 0, 0, 0)) + effect = 1; + gBattleStruct->cmd49StateTracker++; + break; + case 4: //status immunities + if (AbilityBattleEffects(ABILITYEFFECT_IMMUNITY, 0, 0, 0, 0)) + effect = 1; //it loops through 4 banks, so we increment after its done with all banks + else + gBattleStruct->cmd49StateTracker++; + break; + case 5: //attacker synchronize + if (AbilityBattleEffects(ABILITYEFFECT_ATK_SYNCHRONIZE, gBankAttacker, 0, 0, 0)) + effect = 1; + gBattleStruct->cmd49StateTracker++; + break; + case 6: //update choice band move + if (gHitMarker & HITMARKER_OBEYS && hold_effect_atk == HOLD_EFFECT_CHOICE_BAND + && gLastUsedMove != MOVE_STRUGGLE && (*choiced_move_atk == 0 || *choiced_move_atk == 0xFFF) + && gLastUsedMove != MOVE_BATON_PASS && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + { + *choiced_move_atk = gLastUsedMove; + for (i = 0; i < 4 && gBattleMons[gBankAttacker].moves[i] != *choiced_move_atk; i++){} + if (i == 4) + *choiced_move_atk = 0; + } + gBattleStruct->cmd49StateTracker++; + break; + case 7: //changed held items + for (i = 0; i < gBattlersCount; i++) + { + #define CHANGED_ITEM (((*u16)(gSharedMem + 0x160F0))) + if (CHANGED_ITEM(i)) + gBattleMons[i].item = CHANGED_ITEM(i); + } + gBattleStruct->cmd49StateTracker++; + break; + case 8: //make sprite invisible + if (gStatuses3[gBankAttacker] & (STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER) + && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) + { + gActiveBattler = gBankAttacker; + EmitSpriteInvisibility(0, 1); + MarkBufferBankForExecution(gActiveBattler); + } + gBattleStruct->cmd49StateTracker++; + break; + case 9: //semi-invlurneable attacker make visible + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) || !(gStatuses3[gBankAttacker] & (STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) + || WasUnableToUseMove(gBankAttacker)) + { + gActiveBattler = gBankAttacker; + EmitSpriteInvisibility(0, 0); + MarkBufferBankForExecution(gActiveBattler); + gStatuses3 &= ~(STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER); + gSpecialStatuses[gBankAttacker].restored_bank_sprite = 1; + } + gBattleStruct->cmd49StateTracker++; + break; + case 10: //semi-invlurneable target make visible + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) || !(gStatuses3[gBankTarget] & (STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) + || WasUnableToUseMove(gBankTarget)) + { + gActiveBattler = gBankTarget; + EmitSpriteInvisibility(0, 0); + MarkBufferBankForExecution(gActiveBattler); + gStatuses3 &= ~(STATUS3_ON_AIR | STATUS3_UNDERGROUND | STATUS3_UNDERWATER); + gSpecialStatuses[gBankTarget].restored_bank_sprite = 1; + } + gBattleStruct->cmd49StateTracker++; + break; + case 11: // + } + + } while (effect == 0) +} +#else +NAKED +void atk49_moveend(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x18\n\ + movs r0, 0\n\ + mov r10, r0\n\ + ldr r0, _08021834 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r0]\n\ + ldrb r1, [r0, 0x1]\n\ + str r1, [sp, 0x10]\n\ + ldrb r0, [r0, 0x2]\n\ + str r0, [sp, 0x14]\n\ + ldr r1, _08021838 @ =gBattleMons\n\ + ldr r0, _0802183C @ =gBankAttacker\n\ + ldrb r2, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + adds r1, r0, r1\n\ + ldrh r0, [r1, 0x2E]\n\ + cmp r0, 0xAF\n\ + bne _08021844\n\ + ldr r1, _08021840 @ =gEnigmaBerries\n\ + lsls r0, r2, 3\n\ + subs r0, r2\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x7]\n\ + b _0802184E\n\ + .align 2, 0\n\ +_08021834: .4byte gBattlescriptCurrInstr\n\ +_08021838: .4byte gBattleMons\n\ +_0802183C: .4byte gBankAttacker\n\ +_08021840: .4byte gEnigmaBerries\n\ +_08021844:\n\ + ldrh r0, [r1, 0x2E]\n\ + bl ItemId_GetHoldEffect\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ +_0802184E:\n\ + str r0, [sp, 0x8]\n\ + ldr r0, _0802186C @ =gBankAttacker\n\ + ldrb r1, [r0]\n\ + lsls r1, 1\n\ + ldr r0, _08021870 @ =gSharedMem + 0x160E8\n\ + adds r1, r0\n\ + str r1, [sp, 0xC]\n\ + subs r0, 0xCC\n\ + ldrb r0, [r0]\n\ + cmp r0, 0\n\ + beq _080218C0\n\ + movs r2, 0x3F\n\ + ands r2, r0\n\ + str r2, [sp, 0x4]\n\ + b _080218D2\n\ + .align 2, 0\n\ +_0802186C: .4byte gBankAttacker\n\ +_08021870: .4byte gSharedMem + 0x160E8\n\ +_08021874:\n\ + strb r2, [r7]\n\ + ldr r0, [r5]\n\ + orrs r0, r6\n\ + str r0, [r5]\n\ + ldr r0, _080218AC @ =gSharedMem\n\ + ldr r3, _080218B0 @ =0x0001600c\n\ + adds r0, r3\n\ + strb r4, [r0]\n\ + bl MoveValuesCleanUp\n\ + ldr r2, _080218B4 @ =gBattleScriptsForMoveEffects\n\ + mov r4, r8\n\ + ldrh r1, [r4]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + add r0, r9\n\ + ldrb r0, [r0]\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldr r0, [r0]\n\ + bl BattleScriptPush\n\ + ldr r1, _080218B8 @ =gBattlescriptCurrInstr\n\ + ldr r0, _080218BC @ =gUnknown_081D9B2D\n\ + bl _0802229C\n\ + .align 2, 0\n\ +_080218AC: .4byte gSharedMem\n\ +_080218B0: .4byte 0x0001600c\n\ +_080218B4: .4byte gBattleScriptsForMoveEffects\n\ +_080218B8: .4byte gBattlescriptCurrInstr\n\ +_080218BC: .4byte gUnknown_081D9B2D\n\ +_080218C0:\n\ + ldr r2, _080218D8 @ =gBattleMoves\n\ + ldr r0, _080218DC @ =gCurrentMove\n\ + ldrh r1, [r0]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r0, [r0, 0x2]\n\ + str r0, [sp, 0x4]\n\ +_080218D2:\n\ + ldr r5, _080218E0 @ =gSharedMem\n\ + mov r12, r5\n\ + b _080218EE\n\ + .align 2, 0\n\ +_080218D8: .4byte gBattleMoves\n\ +_080218DC: .4byte gCurrentMove\n\ +_080218E0: .4byte gSharedMem\n\ +_080218E4:\n\ + mov r0, r10\n\ + cmp r0, 0\n\ + beq _080218EE\n\ + bl _08022286\n\ +_080218EE:\n\ + ldr r0, _08021908 @ =0x0001600c\n\ + add r0, r12\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x11\n\ + bls _080218FC\n\ + bl _0802224E\n\ +_080218FC:\n\ + lsls r0, 2\n\ + ldr r1, _0802190C @ =_08021910\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .align 2, 0\n\ +_08021908: .4byte 0x0001600c\n\ +_0802190C: .4byte _08021910\n\ + .align 2, 0\n\ +_08021910:\n\ + .4byte _08021958\n\ + .4byte _08021A34\n\ + .4byte _08021AF0\n\ + .4byte _08021B20\n\ + .4byte _08021B44\n\ + .4byte _08021B78\n\ + .4byte _08021B9C\n\ + .4byte _08021C40\n\ + .4byte _08021C78\n\ + .4byte _08021CA8\n\ + .4byte _08021CCC\n\ + .4byte _08021D18\n\ + .4byte _08021DAC\n\ + .4byte _08021E30\n\ + .4byte _08021E70\n\ + .4byte _08022068\n\ + .4byte _080221C0\n\ + .4byte _0802224E\n\ +_08021958:\n\ + ldr r5, _08021A08 @ =gBattleMons\n\ + ldr r2, _08021A0C @ =gBankTarget\n\ + ldrb r4, [r2]\n\ + movs r6, 0x58\n\ + adds r3, r4, 0\n\ + muls r3, r6\n\ + adds r0, r5, 0\n\ + adds r0, 0x50\n\ + adds r0, r3, r0\n\ + ldr r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 16\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + beq _080219FE\n\ + adds r0, r3, r5\n\ + ldrh r0, [r0, 0x28]\n\ + cmp r0, 0\n\ + beq _080219FE\n\ + ldr r0, _08021A10 @ =gBankAttacker\n\ + ldrb r1, [r0]\n\ + cmp r1, r4\n\ + beq _080219FE\n\ + adds r0, r1, 0\n\ + bl GetBattlerSide\n\ + adds r4, r0, 0\n\ + ldr r1, _08021A0C @ =gBankTarget\n\ + ldrb r0, [r1]\n\ + bl GetBattlerSide\n\ + lsls r4, 24\n\ + lsls r0, 24\n\ + cmp r4, r0\n\ + beq _080219FE\n\ + ldr r0, _08021A14 @ =gMoveResultFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _080219FE\n\ + ldr r2, _08021A18 @ =gProtectStructs\n\ + ldr r4, _08021A0C @ =gBankTarget\n\ + ldrb r3, [r4]\n\ + lsls r1, r3, 4\n\ + adds r0, r2, 0x4\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _080219C8\n\ + adds r0, r2, 0\n\ + adds r0, 0x8\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + beq _080219FE\n\ +_080219C8:\n\ + ldr r2, _08021A1C @ =gBattleMoves\n\ + ldr r0, _08021A20 @ =gCurrentMove\n\ + ldrh r1, [r0]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r0, [r0, 0x1]\n\ + cmp r0, 0\n\ + beq _080219FE\n\ + adds r0, r3, 0\n\ + muls r0, r6\n\ + adds r1, r0, r5\n\ + ldrb r2, [r1, 0x19]\n\ + movs r0, 0x19\n\ + ldrsb r0, [r1, r0]\n\ + cmp r0, 0xB\n\ + bgt _080219FE\n\ + adds r0, r2, 0x1\n\ + strb r0, [r1, 0x19]\n\ + bl BattleScriptPushCursor\n\ + ldr r1, _08021A24 @ =gBattlescriptCurrInstr\n\ + ldr r0, _08021A28 @ =BattleScript_RageIsBuilding\n\ + str r0, [r1]\n\ + movs r5, 0x1\n\ + mov r10, r5\n\ +_080219FE:\n\ + ldr r2, _08021A2C @ =gSharedMem\n\ + ldr r0, _08021A30 @ =0x0001600c\n\ + adds r1, r2, r0\n\ + b _08021E00\n\ + .align 2, 0\n\ +_08021A08: .4byte gBattleMons\n\ +_08021A0C: .4byte gBankTarget\n\ +_08021A10: .4byte gBankAttacker\n\ +_08021A14: .4byte gMoveResultFlags\n\ +_08021A18: .4byte gProtectStructs\n\ +_08021A1C: .4byte gBattleMoves\n\ +_08021A20: .4byte gCurrentMove\n\ +_08021A24: .4byte gBattlescriptCurrInstr\n\ +_08021A28: .4byte BattleScript_RageIsBuilding\n\ +_08021A2C: .4byte gSharedMem\n\ +_08021A30: .4byte 0x0001600c\n\ +_08021A34:\n\ + ldr r2, _08021AD0 @ =gBattleMons\n\ + ldr r1, _08021AD4 @ =gBankTarget\n\ + ldrb r4, [r1]\n\ + movs r3, 0x58\n\ + mov r12, r3\n\ + mov r3, r12\n\ + muls r3, r4\n\ + adds r7, r2, 0\n\ + adds r7, 0x4C\n\ + adds r6, r3, r7\n\ + ldr r5, [r6]\n\ + movs r0, 0x20\n\ + ands r0, r5\n\ + cmp r0, 0\n\ + bne _08021A54\n\ + b _08021DFA\n\ +_08021A54:\n\ + adds r0, r3, r2\n\ + ldrh r0, [r0, 0x28]\n\ + cmp r0, 0\n\ + bne _08021A5E\n\ + b _08021DFA\n\ +_08021A5E:\n\ + ldr r0, _08021AD8 @ =gBankAttacker\n\ + ldrb r0, [r0]\n\ + cmp r0, r4\n\ + bne _08021A68\n\ + b _08021DFA\n\ +_08021A68:\n\ + ldr r0, _08021ADC @ =gSpecialStatuses\n\ + lsls r1, r4, 2\n\ + adds r1, r4\n\ + lsls r1, 2\n\ + adds r0, 0xC\n\ + adds r1, r0\n\ + ldr r0, [r1]\n\ + cmp r0, 0\n\ + bne _08021A7C\n\ + b _08021DFA\n\ +_08021A7C:\n\ + ldr r0, _08021AE0 @ =gMoveResultFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08021A8A\n\ + b _08021DFA\n\ +_08021A8A:\n\ + ldr r4, [sp, 0x4]\n\ + cmp r4, 0xA\n\ + beq _08021A92\n\ + b _08021DFA\n\ +_08021A92:\n\ + movs r0, 0x21\n\ + negs r0, r0\n\ + ands r5, r0\n\ + str r5, [r6]\n\ + ldr r4, _08021AE4 @ =gActiveBattler\n\ + ldr r5, _08021AD4 @ =gBankTarget\n\ + ldrb r0, [r5]\n\ + strb r0, [r4]\n\ + ldrb r0, [r5]\n\ + mov r1, r12\n\ + muls r1, r0\n\ + adds r0, r1, 0\n\ + adds r0, r7\n\ + str r0, [sp]\n\ + movs r0, 0\n\ + movs r1, 0x28\n\ + movs r2, 0\n\ + movs r3, 0x4\n\ + bl EmitSetMonData\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + bl BattleScriptPushCursor\n\ + ldr r1, _08021AE8 @ =gBattlescriptCurrInstr\n\ + ldr r0, _08021AEC @ =BattleScript_DefrostedViaFireMove\n\ + str r0, [r1]\n\ + movs r2, 0x1\n\ + mov r10, r2\n\ + b _08021DFA\n\ + .align 2, 0\n\ +_08021AD0: .4byte gBattleMons\n\ +_08021AD4: .4byte gBankTarget\n\ +_08021AD8: .4byte gBankAttacker\n\ +_08021ADC: .4byte gSpecialStatuses\n\ +_08021AE0: .4byte gMoveResultFlags\n\ +_08021AE4: .4byte gActiveBattler\n\ +_08021AE8: .4byte gBattlescriptCurrInstr\n\ +_08021AEC: .4byte BattleScript_DefrostedViaFireMove\n\ +_08021AF0:\n\ + ldr r0, _08021B14 @ =gBankTarget\n\ + ldrb r1, [r0]\n\ + movs r0, 0\n\ + str r0, [sp]\n\ + movs r0, 0x7\n\ + movs r2, 0\n\ + movs r3, 0\n\ + bl AbilityBattleEffects\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08021B0C\n\ + movs r4, 0x1\n\ + mov r10, r4\n\ +_08021B0C:\n\ + ldr r2, _08021B18 @ =gSharedMem\n\ + ldr r5, _08021B1C @ =0x0001600c\n\ + adds r1, r2, r5\n\ + b _08021E00\n\ + .align 2, 0\n\ +_08021B14: .4byte gBankTarget\n\ +_08021B18: .4byte gSharedMem\n\ +_08021B1C: .4byte 0x0001600c\n\ +_08021B20:\n\ + ldr r0, _08021B40 @ =gBankTarget\n\ + ldrb r1, [r0]\n\ + movs r0, 0\n\ + str r0, [sp]\n\ + movs r0, 0x4\n\ + movs r2, 0\n\ + movs r3, 0\n\ + bl AbilityBattleEffects\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _08021B3A\n\ + b _08021DFA\n\ +_08021B3A:\n\ + movs r0, 0x1\n\ + mov r10, r0\n\ + b _08021DFA\n\ + .align 2, 0\n\ +_08021B40: .4byte gBankTarget\n\ +_08021B44:\n\ + movs r0, 0\n\ + str r0, [sp]\n\ + movs r0, 0x5\n\ + movs r1, 0\n\ + movs r2, 0\n\ + movs r3, 0\n\ + bl AbilityBattleEffects\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08021B68\n\ + movs r4, 0x1\n\ + mov r10, r4\n\ + ldr r5, _08021B64 @ =gSharedMem\n\ + mov r12, r5\n\ + b _0802224E\n\ + .align 2, 0\n\ +_08021B64: .4byte gSharedMem\n\ +_08021B68:\n\ + ldr r2, _08021B70 @ =gSharedMem\n\ + ldr r0, _08021B74 @ =0x0001600c\n\ + adds r1, r2, r0\n\ + b _08021E00\n\ + .align 2, 0\n\ +_08021B70: .4byte gSharedMem\n\ +_08021B74: .4byte 0x0001600c\n\ +_08021B78:\n\ + ldr r0, _08021B98 @ =gBankAttacker\n\ + ldrb r1, [r0]\n\ + movs r0, 0\n\ + str r0, [sp]\n\ + movs r0, 0x8\n\ + movs r2, 0\n\ + movs r3, 0\n\ + bl AbilityBattleEffects\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _08021B92\n\ + b _08021DFA\n\ +_08021B92:\n\ + movs r1, 0x1\n\ + mov r10, r1\n\ + b _08021DFA\n\ + .align 2, 0\n\ +_08021B98: .4byte gBankAttacker\n\ +_08021B9C:\n\ + ldr r0, _08021C28 @ =gHitMarker\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 18\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08021BE0\n\ + ldr r4, [sp, 0x8]\n\ + cmp r4, 0x1D\n\ + bne _08021BE0\n\ + ldr r0, _08021C2C @ =gChosenMove\n\ + ldrh r2, [r0]\n\ + adds r7, r0, 0\n\ + cmp r2, 0xA5\n\ + beq _08021BE0\n\ + ldr r5, [sp, 0xC]\n\ + ldrh r1, [r5]\n\ + cmp r1, 0\n\ + beq _08021BC8\n\ + ldr r0, _08021C30 @ =0x0000ffff\n\ + cmp r1, r0\n\ + bne _08021BE0\n\ +_08021BC8:\n\ + cmp r2, 0xE2\n\ + bne _08021BDA\n\ + ldr r0, _08021C34 @ =gMoveResultFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x20\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08021BDA\n\ + b _08022244\n\ +_08021BDA:\n\ + ldrh r0, [r7]\n\ + ldr r1, [sp, 0xC]\n\ + strh r0, [r1]\n\ +_08021BE0:\n\ + movs r4, 0\n\ + ldr r2, _08021C38 @ =gBattleMons\n\ + ldr r3, _08021C3C @ =gBankAttacker\n\ + ldrb r1, [r3]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r2, 0xC\n\ + adds r0, r2\n\ + ldrh r0, [r0]\n\ + ldr r5, [sp, 0xC]\n\ + ldrh r1, [r5]\n\ + mov r9, r3\n\ + cmp r0, r1\n\ + beq _08021C18\n\ + mov r6, r9\n\ + movs r3, 0x58\n\ + adds r5, r1, 0\n\ +_08021C02:\n\ + adds r4, 0x1\n\ + cmp r4, 0x3\n\ + bgt _08021C18\n\ + lsls r0, r4, 1\n\ + ldrb r1, [r6]\n\ + muls r1, r3\n\ + adds r0, r1\n\ + adds r0, r2\n\ + ldrh r0, [r0]\n\ + cmp r0, r5\n\ + bne _08021C02\n\ +_08021C18:\n\ + cmp r4, 0x4\n\ + beq _08021C1E\n\ + b _08022244\n\ +_08021C1E:\n\ + movs r0, 0\n\ + ldr r1, [sp, 0xC]\n\ +_08021C22:\n\ + strh r0, [r1]\n\ + b _08022244\n\ + .align 2, 0\n\ +_08021C28: .4byte gHitMarker\n\ +_08021C2C: .4byte gChosenMove\n\ +_08021C30: .4byte 0x0000ffff\n\ +_08021C34: .4byte gMoveResultFlags\n\ +_08021C38: .4byte gBattleMons\n\ +_08021C3C: .4byte gBankAttacker\n\ +_08021C40:\n\ + movs r4, 0\n\ + ldr r0, _08021C6C @ =gBattlersCount\n\ + ldrb r2, [r0]\n\ + cmp r4, r2\n\ + blt _08021C4C\n\ + b _08022244\n\ +_08021C4C:\n\ + movs r5, 0\n\ + ldr r2, _08021C70 @ =gSharedMem + 0x160F0\n\ + ldr r3, _08021C74 @ =gBattleMons\n\ +_08021C52:\n\ + ldrh r1, [r2]\n\ + cmp r1, 0\n\ + beq _08021C5C\n\ + strh r1, [r3, 0x2E]\n\ + strh r5, [r2]\n\ +_08021C5C:\n\ + adds r2, 0x2\n\ + adds r3, 0x58\n\ + adds r4, 0x1\n\ + ldrb r1, [r0]\n\ + cmp r4, r1\n\ + blt _08021C52\n\ + b _08022244\n\ + .align 2, 0\n\ +_08021C6C: .4byte gBattlersCount\n\ +_08021C70: .4byte gSharedMem + 0x160F0\n\ +_08021C74: .4byte gBattleMons\n\ +_08021C78:\n\ + movs r0, 0x3\n\ + movs r1, 0\n\ + movs r2, 0\n\ + bl ItemBattleEffects\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08021C98\n\ + movs r2, 0x1\n\ + mov r10, r2\n\ + ldr r3, _08021C94 @ =gSharedMem\n\ + mov r12, r3\n\ + b _0802224E\n\ + .align 2, 0\n\ +_08021C94: .4byte gSharedMem\n\ +_08021C98:\n\ + ldr r2, _08021CA0 @ =gSharedMem\n\ + ldr r4, _08021CA4 @ =0x0001600c\n\ + adds r1, r2, r4\n\ + b _08021E00\n\ + .align 2, 0\n\ +_08021CA0: .4byte gSharedMem\n\ +_08021CA4: .4byte 0x0001600c\n\ +_08021CA8:\n\ + movs r0, 0x4\n\ + movs r1, 0\n\ + movs r2, 0\n\ + bl ItemBattleEffects\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08021CBC\n\ + movs r5, 0x1\n\ + mov r10, r5\n\ +_08021CBC:\n\ + ldr r2, _08021CC4 @ =gSharedMem\n\ + ldr r0, _08021CC8 @ =0x0001600c\n\ + adds r1, r2, r0\n\ + b _08021E00\n\ + .align 2, 0\n\ +_08021CC4: .4byte gSharedMem\n\ +_08021CC8: .4byte 0x0001600c\n\ +_08021CCC:\n\ + ldr r1, _08021D04 @ =gStatuses3\n\ + ldr r0, _08021D08 @ =gBankAttacker\n\ + ldrb r2, [r0]\n\ + lsls r0, r2, 2\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + ldr r1, _08021D0C @ =0x000400c0\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08021CE2\n\ + b _08021DFA\n\ +_08021CE2:\n\ + ldr r0, _08021D10 @ =gHitMarker\n\ + ldr r0, [r0]\n\ + movs r1, 0x80\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08021CF0\n\ + b _08021DFA\n\ +_08021CF0:\n\ + ldr r4, _08021D14 @ =gActiveBattler\n\ + strb r2, [r4]\n\ + movs r0, 0\n\ + movs r1, 0x1\n\ + bl EmitSpriteInvisibility\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + b _08021DFA\n\ + .align 2, 0\n\ +_08021D04: .4byte gStatuses3\n\ +_08021D08: .4byte gBankAttacker\n\ +_08021D0C: .4byte 0x000400c0\n\ +_08021D10: .4byte gHitMarker\n\ +_08021D14: .4byte gActiveBattler\n\ +_08021D18:\n\ + ldr r0, _08021D88 @ =gMoveResultFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08021D44\n\ + ldr r1, _08021D8C @ =gStatuses3\n\ + ldr r0, _08021D90 @ =gBankAttacker\n\ + ldrb r2, [r0]\n\ + lsls r0, r2, 2\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + ldr r1, _08021D94 @ =0x000400c0\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08021D44\n\ + adds r0, r2, 0\n\ + bl WasUnableToUseMove\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08021D7E\n\ +_08021D44:\n\ + ldr r4, _08021D98 @ =gActiveBattler\n\ + ldr r5, _08021D90 @ =gBankAttacker\n\ + ldrb r0, [r5]\n\ + strb r0, [r4]\n\ + movs r0, 0\n\ + movs r1, 0\n\ + bl EmitSpriteInvisibility\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + ldr r0, _08021D8C @ =gStatuses3\n\ + ldrb r2, [r5]\n\ + lsls r2, 2\n\ + adds r2, r0\n\ + ldr r0, [r2]\n\ + ldr r1, _08021D9C @ =0xfffbff3f\n\ + ands r0, r1\n\ + str r0, [r2]\n\ + ldr r2, _08021DA0 @ =gSpecialStatuses\n\ + ldrb r1, [r5]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r1, [r0]\n\ + movs r2, 0x4\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ +_08021D7E:\n\ + ldr r2, _08021DA4 @ =gSharedMem\n\ + ldr r4, _08021DA8 @ =0x0001600c\n\ + adds r1, r2, r4\n\ + b _08021E00\n\ + .align 2, 0\n\ +_08021D88: .4byte gMoveResultFlags\n\ +_08021D8C: .4byte gStatuses3\n\ +_08021D90: .4byte gBankAttacker\n\ +_08021D94: .4byte 0x000400c0\n\ +_08021D98: .4byte gActiveBattler\n\ +_08021D9C: .4byte 0xfffbff3f\n\ +_08021DA0: .4byte gSpecialStatuses\n\ +_08021DA4: .4byte gSharedMem\n\ +_08021DA8: .4byte 0x0001600c\n\ +_08021DAC:\n\ + ldr r2, _08021E0C @ =gSpecialStatuses\n\ + ldr r1, _08021E10 @ =gBankTarget\n\ + ldrb r3, [r1]\n\ + lsls r4, r3, 2\n\ + adds r0, r4, r3\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r0, [r0]\n\ + lsls r0, 29\n\ + cmp r0, 0\n\ + blt _08021DFA\n\ + ldr r0, _08021E14 @ =gBattlersCount\n\ + ldrb r0, [r0]\n\ + cmp r3, r0\n\ + bcs _08021DFA\n\ + ldr r5, _08021E18 @ =gStatuses3\n\ + adds r0, r4, r5\n\ + ldr r0, [r0]\n\ + ldr r1, _08021E1C @ =0x000400c0\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08021DFA\n\ + ldr r4, _08021E20 @ =gActiveBattler\n\ + strb r3, [r4]\n\ + movs r0, 0\n\ + movs r1, 0\n\ + bl EmitSpriteInvisibility\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + ldr r0, _08021E10 @ =gBankTarget\n\ + ldrb r2, [r0]\n\ + lsls r2, 2\n\ + adds r2, r5\n\ + ldr r0, [r2]\n\ + ldr r1, _08021E24 @ =0xfffbff3f\n\ + ands r0, r1\n\ + str r0, [r2]\n\ +_08021DFA:\n\ + ldr r2, _08021E28 @ =gSharedMem\n\ + ldr r3, _08021E2C @ =0x0001600c\n\ + adds r1, r2, r3\n\ +_08021E00:\n\ + ldrb r0, [r1]\n\ + adds r0, 0x1\n\ + strb r0, [r1]\n\ + mov r12, r2\n\ + b _0802224E\n\ + .align 2, 0\n\ +_08021E0C: .4byte gSpecialStatuses\n\ +_08021E10: .4byte gBankTarget\n\ +_08021E14: .4byte gBattlersCount\n\ +_08021E18: .4byte gStatuses3\n\ +_08021E1C: .4byte 0x000400c0\n\ +_08021E20: .4byte gActiveBattler\n\ +_08021E24: .4byte 0xfffbff3f\n\ +_08021E28: .4byte gSharedMem\n\ +_08021E2C: .4byte 0x0001600c\n\ +_08021E30:\n\ + movs r4, 0\n\ + ldr r0, _08021E60 @ =gBattlersCount\n\ + ldrb r5, [r0]\n\ + cmp r4, r5\n\ + blt _08021E3C\n\ + b _08022244\n\ +_08021E3C:\n\ + ldr r2, _08021E64 @ =gDisableStructs\n\ + ldr r5, _08021E68 @ =0xfeffffff\n\ + adds r3, r0, 0\n\ + ldr r1, _08021E6C @ =gBattleMons+0x50\n\ +_08021E44:\n\ + ldrb r0, [r2, 0xA]\n\ + cmp r0, 0\n\ + bne _08021E50\n\ + ldr r0, [r1]\n\ + ands r0, r5\n\ + str r0, [r1]\n\ +_08021E50:\n\ + adds r2, 0x1C\n\ + adds r1, 0x58\n\ + adds r4, 0x1\n\ + ldrb r0, [r3]\n\ + cmp r4, r0\n\ + blt _08021E44\n\ + b _08022244\n\ + .align 2, 0\n\ +_08021E60: .4byte gBattlersCount\n\ +_08021E64: .4byte gDisableStructs\n\ +_08021E68: .4byte 0xfeffffff\n\ +_08021E6C: .4byte gBattleMons+0x50\n\ +_08021E70:\n\ + ldr r1, _08021F2C @ =gHitMarker\n\ + ldr r3, [r1]\n\ + movs r0, 0x80\n\ + lsls r0, 5\n\ + ands r0, r3\n\ + ldr r2, _08021F30 @ =gBankAttacker\n\ + mov r9, r2\n\ + adds r5, r1, 0\n\ + cmp r0, 0\n\ + beq _08021E9A\n\ + ldr r0, _08021F34 @ =gActiveBattler\n\ + ldrb r2, [r2]\n\ + strb r2, [r0]\n\ + ldr r1, _08021F38 @ =gBankTarget\n\ + ldrb r0, [r1]\n\ + mov r4, r9\n\ + strb r0, [r4]\n\ + strb r2, [r1]\n\ + ldr r0, _08021F3C @ =0xffffefff\n\ + ands r3, r0\n\ + str r3, [r5]\n\ +_08021E9A:\n\ + ldr r1, _08021F40 @ =gBattleMoves\n\ + ldr r2, _08021F44 @ =gChosenMove\n\ + ldrh r3, [r2]\n\ + lsls r0, r3, 1\n\ + adds r0, r3\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r0, [r0]\n\ + mov r8, r1\n\ + adds r7, r2, 0\n\ + cmp r0, 0x7F\n\ + bne _08021EBE\n\ + ldr r0, _08021F48 @ =gMoveResultFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08021ECA\n\ +_08021EBE:\n\ + ldr r1, _08021F4C @ =gUnknown_02024C2C\n\ + mov r2, r9\n\ + ldrb r0, [r2]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + strh r3, [r0]\n\ +_08021ECA:\n\ + ldr r0, _08021F50 @ =gAbsentBattlerFlags\n\ + ldrb r1, [r0]\n\ + ldr r2, _08021F54 @ =gBitTable\n\ + mov r3, r9\n\ + ldrb r4, [r3]\n\ + lsls r0, r4, 2\n\ + adds r0, r2\n\ + ldr r3, [r0]\n\ + ands r1, r3\n\ + adds r6, r2, 0\n\ + cmp r1, 0\n\ + beq _08021EE4\n\ + b _08022244\n\ +_08021EE4:\n\ + ldr r0, _08021F58 @ =0x000160a6\n\ + add r0, r12\n\ + ldrb r0, [r0]\n\ + ands r0, r3\n\ + cmp r0, 0\n\ + beq _08021EF2\n\ + b _08022244\n\ +_08021EF2:\n\ + ldrh r2, [r7]\n\ + lsls r0, r2, 1\n\ + adds r0, r2\n\ + lsls r0, 2\n\ + add r0, r8\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x7F\n\ + bne _08021F04\n\ + b _08022244\n\ +_08021F04:\n\ + ldr r0, [r5]\n\ + movs r1, 0x80\n\ + lsls r1, 18\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08021F68\n\ + ldr r1, _08021F5C @ =gLastUsedMove\n\ + lsls r0, r4, 1\n\ + adds r0, r1\n\ + strh r2, [r0]\n\ + ldr r0, _08021F60 @ =gUnknown_02024C4C\n\ + mov r4, r9\n\ + ldrb r1, [r4]\n\ + lsls r1, 1\n\ + adds r1, r0\n\ + ldr r0, _08021F64 @ =gCurrentMove\n\ + ldrh r0, [r0]\n\ + strh r0, [r1]\n\ + b _08021F82\n\ + .align 2, 0\n\ +_08021F2C: .4byte gHitMarker\n\ +_08021F30: .4byte gBankAttacker\n\ +_08021F34: .4byte gActiveBattler\n\ +_08021F38: .4byte gBankTarget\n\ +_08021F3C: .4byte 0xffffefff\n\ +_08021F40: .4byte gBattleMoves\n\ +_08021F44: .4byte gChosenMove\n\ +_08021F48: .4byte gMoveResultFlags\n\ +_08021F4C: .4byte gUnknown_02024C2C\n\ +_08021F50: .4byte gAbsentBattlerFlags\n\ +_08021F54: .4byte gBitTable\n\ +_08021F58: .4byte 0x000160a6\n\ +_08021F5C: .4byte gLastUsedMove\n\ +_08021F60: .4byte gUnknown_02024C4C\n\ +_08021F64: .4byte gCurrentMove\n\ +_08021F68:\n\ + ldr r1, _08021FD0 @ =gLastUsedMove\n\ + lsls r0, r4, 1\n\ + adds r0, r1\n\ + ldr r1, _08021FD4 @ =0x0000ffff\n\ + strh r1, [r0]\n\ + ldr r1, _08021FD8 @ =gUnknown_02024C4C\n\ + mov r2, r9\n\ + ldrb r0, [r2]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + movs r1, 0x1\n\ + negs r1, r1\n\ + strh r1, [r0]\n\ +_08021F82:\n\ + ldr r2, _08021FDC @ =gBankTarget\n\ + ldrb r3, [r2]\n\ + lsls r0, r3, 2\n\ + adds r0, r6\n\ + ldr r0, [r0]\n\ + lsls r0, 28\n\ + ldr r1, [r5]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + bne _08021FA0\n\ + ldr r0, _08021FE0 @ =gLastHitBy\n\ + adds r0, r3, r0\n\ + mov r3, r9\n\ + ldrb r1, [r3]\n\ + strb r1, [r0]\n\ +_08021FA0:\n\ + ldr r0, [r5]\n\ + movs r1, 0x80\n\ + lsls r1, 18\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0802204C\n\ + ldr r0, _08021FE4 @ =gMoveResultFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0802204C\n\ + ldrh r2, [r7]\n\ + ldr r0, _08021FD4 @ =0x0000ffff\n\ + cmp r2, r0\n\ + bne _08021FEC\n\ + ldr r1, _08021FE8 @ =gLastLandedMoves\n\ + ldr r4, _08021FDC @ =gBankTarget\n\ + ldrb r0, [r4]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + strh r2, [r0]\n\ + b _08022244\n\ + .align 2, 0\n\ +_08021FD0: .4byte gLastUsedMove\n\ +_08021FD4: .4byte 0x0000ffff\n\ +_08021FD8: .4byte gUnknown_02024C4C\n\ +_08021FDC: .4byte gBankTarget\n\ +_08021FE0: .4byte gLastHitBy\n\ +_08021FE4: .4byte gMoveResultFlags\n\ +_08021FE8: .4byte gLastLandedMoves\n\ +_08021FEC:\n\ + ldr r0, _08022014 @ =gLastLandedMoves\n\ + ldr r5, _08022018 @ =gBankTarget\n\ + ldrb r1, [r5]\n\ + lsls r1, 1\n\ + adds r1, r0\n\ + ldr r4, _0802201C @ =gCurrentMove\n\ + ldrh r0, [r4]\n\ + strh r0, [r1]\n\ + ldr r0, _08022020 @ =0x0001601c\n\ + add r0, r12\n\ + ldrb r3, [r0]\n\ + cmp r3, 0\n\ + beq _08022028\n\ + ldr r0, _08022024 @ =gLastHitByType\n\ + ldrb r1, [r5]\n\ + lsls r1, 1\n\ + adds r1, r0\n\ + movs r0, 0x3F\n\ + ands r0, r3\n\ + b _08021C22\n\ + .align 2, 0\n\ +_08022014: .4byte gLastLandedMoves\n\ +_08022018: .4byte gBankTarget\n\ +_0802201C: .4byte gCurrentMove\n\ +_08022020: .4byte 0x0001601c\n\ +_08022024: .4byte gLastHitByType\n\ +_08022028:\n\ + ldr r0, _08022044 @ =gLastHitByType\n\ + ldr r1, _08022048 @ =gBankTarget\n\ + ldrb r2, [r1]\n\ + lsls r2, 1\n\ + adds r2, r0\n\ + ldrh r1, [r4]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + add r0, r8\n\ + ldrb r0, [r0, 0x2]\n\ + strh r0, [r2]\n\ + b _08022244\n\ + .align 2, 0\n\ +_08022044: .4byte gLastHitByType\n\ +_08022048: .4byte gBankTarget\n\ +_0802204C:\n\ + ldr r0, _0802205C @ =gLastLandedMoves\n\ + ldr r2, _08022060 @ =gBankTarget\n\ + ldrb r1, [r2]\n\ + lsls r1, 1\n\ + adds r1, r0\n\ + ldr r0, _08022064 @ =0x0000ffff\n\ + b _08021C22\n\ + .align 2, 0\n\ +_0802205C: .4byte gLastLandedMoves\n\ +_08022060: .4byte gBankTarget\n\ +_08022064: .4byte 0x0000ffff\n\ +_08022068:\n\ + ldr r0, _0802212C @ =gAbsentBattlerFlags\n\ + ldrb r1, [r0]\n\ + ldr r6, _08022130 @ =gBitTable\n\ + ldr r2, _08022134 @ =gBankAttacker\n\ + ldrb r5, [r2]\n\ + lsls r0, r5, 2\n\ + adds r0, r6\n\ + ldr r4, [r0]\n\ + ands r1, r4\n\ + mov r9, r2\n\ + cmp r1, 0\n\ + beq _08022082\n\ + b _08022244\n\ +_08022082:\n\ + ldr r0, _08022138 @ =0x000160a6\n\ + add r0, r12\n\ + ldrb r0, [r0]\n\ + ands r0, r4\n\ + cmp r0, 0\n\ + beq _08022090\n\ + b _08022244\n\ +_08022090:\n\ + ldr r1, _0802213C @ =gBattleMoves\n\ + ldr r4, _08022140 @ =gChosenMove\n\ + ldrh r3, [r4]\n\ + lsls r0, r3, 1\n\ + adds r0, r3\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r1, [r0, 0x8]\n\ + movs r0, 0x10\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0802215C\n\ + ldr r0, _08022144 @ =gHitMarker\n\ + ldr r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 18\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0802215C\n\ + ldr r2, _08022148 @ =gBankTarget\n\ + ldrb r0, [r2]\n\ + cmp r5, r0\n\ + bne _080220C0\n\ + b _08022244\n\ +_080220C0:\n\ + adds r2, r0, 0\n\ + lsls r0, r2, 2\n\ + adds r0, r6\n\ + ldr r0, [r0]\n\ + lsls r0, 28\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + bne _0802215C\n\ + ldr r0, _0802214C @ =gMoveResultFlags\n\ + ldrb r1, [r0]\n\ + movs r0, 0x29\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0802215C\n\ + lsls r0, r2, 1\n\ + ldr r5, _08022150 @ =0x000160ac\n\ + adds r0, r5\n\ + add r0, r12\n\ + strb r3, [r0]\n\ + ldr r0, _08022148 @ =gBankTarget\n\ + ldrb r1, [r0]\n\ + lsls r1, 1\n\ + ldr r2, _08022154 @ =0x000160ad\n\ + adds r1, r2\n\ + add r1, r12\n\ + ldrh r0, [r4]\n\ + lsrs r0, 8\n\ + strb r0, [r1]\n\ + ldr r3, _08022148 @ =gBankTarget\n\ + ldrb r2, [r3]\n\ + lsls r2, 2\n\ + mov r5, r9\n\ + ldrb r0, [r5]\n\ + lsrs r0, 1\n\ + lsls r0, 1\n\ + ldr r1, _08022158 @ =0x00016100\n\ + adds r0, r1\n\ + adds r2, r0\n\ + add r2, r12\n\ + ldrh r0, [r4]\n\ + strb r0, [r2]\n\ + ldrb r2, [r3]\n\ + lsls r2, 2\n\ + ldrb r0, [r5]\n\ + lsrs r0, 1\n\ + lsls r0, 1\n\ + adds r1, 0x1\n\ + adds r0, r1\n\ + adds r2, r0\n\ + add r2, r12\n\ + ldrh r0, [r4]\n\ + lsrs r0, 8\n\ + strb r0, [r2]\n\ + b _08022244\n\ + .align 2, 0\n\ +_0802212C: .4byte gAbsentBattlerFlags\n\ +_08022130: .4byte gBitTable\n\ +_08022134: .4byte gBankAttacker\n\ +_08022138: .4byte 0x000160a6\n\ +_0802213C: .4byte gBattleMoves\n\ +_08022140: .4byte gChosenMove\n\ +_08022144: .4byte gHitMarker\n\ +_08022148: .4byte gBankTarget\n\ +_0802214C: .4byte gMoveResultFlags\n\ +_08022150: .4byte 0x000160ac\n\ +_08022154: .4byte 0x000160ad\n\ +_08022158: .4byte 0x00016100\n\ +_0802215C:\n\ + mov r1, r9\n\ + ldrb r0, [r1]\n\ + ldr r2, _080221B4 @ =gBankTarget\n\ + ldrb r2, [r2]\n\ + cmp r0, r2\n\ + beq _08022244\n\ + ldr r3, _080221B4 @ =gBankTarget\n\ + ldrb r0, [r3]\n\ + lsls r0, 1\n\ + ldr r4, _080221B8 @ =0x000160ac\n\ + adds r0, r4\n\ + add r0, r12\n\ + movs r3, 0\n\ + strb r3, [r0]\n\ + ldr r5, _080221B4 @ =gBankTarget\n\ + ldrb r0, [r5]\n\ + lsls r0, 1\n\ + ldr r1, _080221BC @ =0x000160ad\n\ + adds r0, r1\n\ + add r0, r12\n\ + strb r3, [r0]\n\ + ldrb r2, [r5]\n\ + lsls r2, 2\n\ + mov r4, r9\n\ + ldrb r0, [r4]\n\ + lsrs r0, 1\n\ + lsls r0, 1\n\ + adds r1, 0x53\n\ + adds r0, r1\n\ + adds r2, r0\n\ + add r2, r12\n\ + strb r3, [r2]\n\ + ldrb r2, [r5]\n\ + lsls r2, 2\n\ + ldrb r0, [r4]\n\ + lsrs r0, 1\n\ + lsls r0, 1\n\ + adds r1, 0x1\n\ + adds r0, r1\n\ + adds r2, r0\n\ + add r2, r12\n\ + strb r3, [r2]\n\ + b _08022244\n\ + .align 2, 0\n\ +_080221B4: .4byte gBankTarget\n\ +_080221B8: .4byte 0x000160ac\n\ +_080221BC: .4byte 0x000160ad\n\ +_080221C0:\n\ + ldr r5, _080222B0 @ =gHitMarker\n\ + ldr r2, [r5]\n\ + movs r0, 0x80\n\ + lsls r0, 12\n\ + ands r0, r2\n\ + cmp r0, 0\n\ + bne _08022244\n\ + ldr r0, _080222B4 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08022244\n\ + ldr r1, _080222B8 @ =gProtectStructs\n\ + ldr r0, _080222BC @ =gBankAttacker\n\ + ldrb r0, [r0]\n\ + lsls r0, 4\n\ + adds r0, r1\n\ + ldrb r0, [r0, 0x1]\n\ + lsls r0, 29\n\ + cmp r0, 0\n\ + blt _08022244\n\ + ldr r0, _080222C0 @ =gBattleMoves\n\ + mov r9, r0\n\ + ldr r1, _080222C4 @ =gCurrentMove\n\ + mov r8, r1\n\ + ldrh r0, [r1]\n\ + lsls r1, r0, 1\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + add r1, r9\n\ + ldrb r0, [r1, 0x6]\n\ + cmp r0, 0x8\n\ + bne _08022244\n\ + movs r6, 0x80\n\ + lsls r6, 2\n\ + adds r4, r6, 0\n\ + ands r4, r2\n\ + cmp r4, 0\n\ + bne _08022244\n\ + ldr r7, _080222C8 @ =gBankTarget\n\ + ldrb r0, [r7]\n\ + bl GetBattlerPosition\n\ + movs r1, 0x2\n\ + eors r0, r1\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + bl GetBattlerAtPosition\n\ + lsls r0, 24\n\ + lsrs r2, r0, 24\n\ + ldr r1, _080222CC @ =gBattleMons\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + adds r0, r1\n\ + ldrh r0, [r0, 0x28]\n\ + cmp r0, 0\n\ + beq _0802223A\n\ + bl _08021874\n\ +_0802223A:\n\ + ldr r0, [r5]\n\ + orrs r0, r6\n\ + str r0, [r5]\n\ + ldr r2, _080222D0 @ =gSharedMem\n\ + mov r12, r2\n\ +_08022244:\n\ + ldr r1, _080222D4 @ =0x0001600c\n\ + add r1, r12\n\ + ldrb r0, [r1]\n\ + adds r0, 0x1\n\ + strb r0, [r1]\n\ +_0802224E:\n\ + ldr r3, [sp, 0x10]\n\ + cmp r3, 0x1\n\ + bne _08022262\n\ + mov r4, r10\n\ + cmp r4, 0\n\ + bne _08022262\n\ + ldr r1, _080222D4 @ =0x0001600c\n\ + add r1, r12\n\ + movs r0, 0x11\n\ + strb r0, [r1]\n\ +_08022262:\n\ + ldr r5, [sp, 0x10]\n\ + cmp r5, 0x2\n\ + bne _08022278\n\ + ldr r1, _080222D4 @ =0x0001600c\n\ + add r1, r12\n\ + ldr r0, [sp, 0x14]\n\ + ldrb r2, [r1]\n\ + cmp r0, r2\n\ + bne _08022278\n\ + movs r0, 0x11\n\ + strb r0, [r1]\n\ +_08022278:\n\ + ldr r0, _080222D4 @ =0x0001600c\n\ + add r0, r12\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x11\n\ + beq _08022286\n\ + bl _080218E4\n\ +_08022286:\n\ + ldr r0, _080222D4 @ =0x0001600c\n\ + add r0, r12\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x11\n\ + bne _0802229E\n\ + mov r3, r10\n\ + cmp r3, 0\n\ + bne _0802229E\n\ + ldr r1, _080222D8 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x3\n\ +_0802229C:\n\ + str r0, [r1]\n\ +_0802229E:\n\ + add sp, 0x18\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_080222B0: .4byte gHitMarker\n\ +_080222B4: .4byte gBattleTypeFlags\n\ +_080222B8: .4byte gProtectStructs\n\ +_080222BC: .4byte gBankAttacker\n\ +_080222C0: .4byte gBattleMoves\n\ +_080222C4: .4byte gCurrentMove\n\ +_080222C8: .4byte gBankTarget\n\ +_080222CC: .4byte gBattleMons\n\ +_080222D0: .4byte gSharedMem\n\ +_080222D4: .4byte 0x0001600c\n\ +_080222D8: .4byte gBattlescriptCurrInstr\n\ + .syntax divided" + ); +} +#endif // NONMATCHING + +static void atk4A_typecalc2(void) +{ + u8 flags = 0; + int i = 0; + u8 move_type = gBattleMoves[gCurrentMove].type; + + if (gBattleMons[gBankTarget].ability == ABILITY_LEVITATE && move_type == TYPE_GROUND) + { + gLastUsedAbility = gBattleMons[gBankTarget].ability; + gMoveResultFlags |= (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE); + gLastLandedMoves[gBankTarget] = 0; + gBattleCommunication[6] = move_type; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else + { + while (gTypeEffectiveness[i]!= TYPE_ENDTABLE) + { + if (gTypeEffectiveness[i] == TYPE_FORESIGHT) + { + if (gBattleMons[gBankTarget].status2 & STATUS2_FORESIGHT) {break;} + else {i += 3; continue;} + } + + if (gTypeEffectiveness[i] == move_type) + { + //check type1 + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type1) + { + if (gTypeEffectiveness[i + 2] == 0) + { + gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE; + break; + } + if (gTypeEffectiveness[i + 2] == 5) + flags |= MOVE_RESULT_NOT_VERY_EFFECTIVE; + if (gTypeEffectiveness[i + 2] == 20) + flags |= MOVE_RESULT_SUPER_EFFECTIVE; + } + //check type2 + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2) + { + if (gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 + && gTypeEffectiveness[i + 2] == 0) + { + gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE; + break; + } + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 && gTypeEffectiveness[i + 2] == 5) + flags |= MOVE_RESULT_NOT_VERY_EFFECTIVE; + if (gTypeEffectiveness[i + 1] == gBattleMons[gBankTarget].type2 + && gBattleMons[gBankTarget].type1 != gBattleMons[gBankTarget].type2 && gTypeEffectiveness[i + 2] == 20) + flags |= MOVE_RESULT_SUPER_EFFECTIVE; + } + } + i += 3; + } + } + + if (gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD && !(flags & MOVE_RESULT_NO_EFFECT) && AttacksThisTurn(gBankAttacker, gCurrentMove) == 2 && + (!(flags & MOVE_RESULT_SUPER_EFFECTIVE) || ((flags & (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE)) == (MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE))) && + gBattleMoves[gCurrentMove].power) + { + gLastUsedAbility = ABILITY_WONDER_GUARD; + gMoveResultFlags |= MOVE_RESULT_MISSED; + gLastLandedMoves[gBankTarget] = 0; + gBattleCommunication[6] = 3; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + if (gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) + gProtectStructs[gBankAttacker].notEffective = 1; + + gBattlescriptCurrInstr++; +} + +static void atk4B_returnatktoball(void) +{ + gActiveBattler = gBankAttacker; + if (!(gHitMarker & HITMARKER_FAINTED(gActiveBattler))) + { + EmitReturnPokeToBall(0, 0); + MarkBufferBankForExecution(gActiveBattler); + } + gBattlescriptCurrInstr++; +} + +static void atk4C_getswitchedmondata(void) +{ + if (gBattleExecBuffer) + return; + + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + + gBattlerPartyIndexes[gActiveBattler] = ewram16068arr(gActiveBattler); + + EmitGetAttributes(0, 0, gBitTable[gBattlerPartyIndexes[gActiveBattler]]); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 2; +} + +static void atk4D_switchindataupdate(void) +{ + struct BattlePokemon oldData; + s32 i; + u8 *monData; + + if (gBattleExecBuffer) + return; + + gActiveBattler = GetBattleBank(gBattlescriptCurrInstr[1]); + oldData = gBattleMons[gActiveBattler]; + monData = (u8*)(&gBattleMons[gActiveBattler]); + + for (i = 0; i < sizeof(struct BattlePokemon); i++) + { + monData[i] = gBattleBufferB[gActiveBattler][4 + i]; + } + + gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1; + gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2; + gBattleMons[gActiveBattler].ability = GetAbilityBySpecies(gBattleMons[gActiveBattler].species, gBattleMons[gActiveBattler].altAbility); + + // check knocked off item + i = GetBattlerSide(gActiveBattler); + if (gWishFutureKnock.knockedOffPokes[i] & gBitTable[gBattlerPartyIndexes[gActiveBattler]]) + { + gBattleMons[gActiveBattler].item = 0; + } + + if (gBattleMoves[gCurrentMove].effect == EFFECT_BATON_PASS) + { + for (i = 0; i < 8; i++) + { + gBattleMons[gActiveBattler].statStages[i] = oldData.statStages[i]; + } + gBattleMons[gActiveBattler].status2 = oldData.status2; + } + + SwitchInClearSetData(); + + gBattleStruct->scriptingActive = gActiveBattler; + + PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gActiveBattler, gBattlerPartyIndexes[gActiveBattler]); + + gBattlescriptCurrInstr += 2; +} + +static void atk4E_switchinanim(void) +{ + if (gBattleExecBuffer) + return; + + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + if (GetBattlerSide(gActiveBattler) == 1 && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_BATTLE_TOWER))) + { + GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gActiveBattler].species), 2); + } + gAbsentBattlerFlags &= ~(gBitTable[gActiveBattler]); + EmitSendOutPoke(0, gBattlerPartyIndexes[gActiveBattler], T2_READ_8(gBattlescriptCurrInstr + 2)); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 3; +} + +static void atk4F_jumpifcantswitch(void) +{ + int val, to_cmp; + register struct Pokemon *party; + u8 r7; + //0x80 byte is used as a way of telling the function whether to not check status2/status3 + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1) & 0x7F); + if (!(T2_READ_8(gBattlescriptCurrInstr + 1) & 0x80) + && ((gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) + || (gStatuses3[gActiveBattler] & STATUS3_ROOTED))) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + return; + } + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (GetBattlerSide(gActiveBattler) == 1) + party = gEnemyParty; + else + party = gPlayerParty; + val = 0; + if (sub_803FBFC(sub_803FC34(gActiveBattler)) == 1) + val = 3; + for (to_cmp = val + 3; val < to_cmp; val++) + { + if (GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[val], MON_DATA_IS_EGG) + && GetMonData(&party[val], MON_DATA_HP) != 0 + && gBattlerPartyIndexes[gActiveBattler] != val) + break; + } + if (val == to_cmp) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + } + else + { + if (GetBattlerSide(gActiveBattler) == 1) + { + r7 = GetBattlerAtPosition(1); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + to_cmp = GetBattlerAtPosition(3); + else + to_cmp = r7; + party = gEnemyParty; + } + else + { + r7 = GetBattlerAtPosition(0); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + to_cmp = GetBattlerAtPosition(2); + else + to_cmp = r7; + party = gPlayerParty; + } + for (val = 0; val < 6; val++) + { + if (GetMonData(&party[val], MON_DATA_HP) != 0 + && GetMonData(&party[val], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[val], MON_DATA_IS_EGG) + && val != gBattlerPartyIndexes[r7] && val != gBattlerPartyIndexes[to_cmp]) + break; + } + if (val == 6) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + } +} + +void sub_8022A3C(u8 unkown) +{ + BATTLE_PARTY_ID(gActiveBattler) = gBattlerPartyIndexes[gActiveBattler]; + EmitChoosePokemon(0, 1, unkown, 0, gBattleStruct->unk1606C[gActiveBattler]); + MarkBufferBankForExecution(gActiveBattler); +} + +/* +static void atk50_openpartyscreen(void) +{ + int i = 0; + int r9 = 0; + u8* fail_loc = T1_READ_PTR(gBattlescriptCurrInstr + 2); + + if (T2_READ_8(gBattlescriptCurrInstr + 1) == 5) + { + if ((gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI)) != BATTLE_TYPE_DOUBLE) + { + for (gActiveBattler = i; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (!(gHitMarker & HITMARKER_FAINTED(gActiveBattler))) + { + EmitLinkStandbyMsg(0, 2); + MarkBufferBankForExecution(gActiveBattler); + } + else if (sub_8018018(gActiveBattler, 6, 6) == 0 + && !gSpecialStatuses[gActiveBattler].flag40) + { + sub_8022A3C(6); + gSpecialStatuses[gActiveBattler].flag40 = 1; + } + else + { + gAbsentBattlerFlags |= gBitTable[gActiveBattler]; + gHitMarker &= (~HITMARKER_FAINTED(gActiveBattler)); + EmitLinkStandbyMsg(0, 2); + MarkBufferBankForExecution(gActiveBattler); + } + } + } + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + if (!(gHitMarker >> 0x1C & gBitTable[0])) + { + + } + else if (sub_8018018(gActiveBattler, 6, 6) == 0 + && !gSpecialStatuses[gActiveBattler].flag40) + { + + } + else + { + + } + } + } +} +*/ + +NAKED +static void atk50_openpartyscreen(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r9\n\ + mov r6, r8\n\ + push {r6,r7}\n\ + sub sp, 0x4\n\ + movs r7, 0\n\ + movs r0, 0\n\ + mov r9, r0\n\ + ldr r6, _08022B44 @ =gBattlescriptCurrInstr\n\ + ldr r1, [r6]\n\ + ldrb r2, [r1, 0x2]\n\ + ldrb r0, [r1, 0x3]\n\ + lsls r0, 8\n\ + orrs r2, r0\n\ + ldrb r0, [r1, 0x4]\n\ + lsls r0, 16\n\ + orrs r2, r0\n\ + ldrb r0, [r1, 0x5]\n\ + lsls r0, 24\n\ + orrs r2, r0\n\ + mov r8, r2\n\ + ldrb r2, [r1, 0x1]\n\ + adds r0, r2, 0\n\ + mov r12, r6\n\ + cmp r0, 0x5\n\ + beq _08022ACE\n\ + b _08022F74\n\ +_08022ACE:\n\ + ldr r0, _08022B48 @ =gBattleTypeFlags\n\ + ldrh r0, [r0]\n\ + movs r1, 0x41\n\ + ands r1, r0\n\ + cmp r1, 0x1\n\ + beq _08022BBC\n\ + ldr r1, _08022B4C @ =gActiveBattler\n\ + strb r7, [r1]\n\ + ldr r0, _08022B50 @ =gBattlersCount\n\ + ldrb r0, [r0]\n\ + cmp r7, r0\n\ + bcc _08022AE8\n\ + b _08022F62\n\ +_08022AE8:\n\ + ldr r7, _08022B54 @ =gHitMarker\n\ + ldr r6, _08022B58 @ =gBitTable\n\ + adds r4, r1, 0\n\ + ldr r0, _08022B5C @ =gAbsentBattlerFlags\n\ + mov r8, r0\n\ +_08022AF2:\n\ + ldrb r2, [r4]\n\ + lsls r0, r2, 2\n\ + adds r0, r6\n\ + ldr r1, [r0]\n\ + lsls r1, 28\n\ + ldr r0, [r7]\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08022B94\n\ + adds r0, r2, 0\n\ + movs r1, 0x6\n\ + movs r2, 0x6\n\ + bl sub_8018018\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08022B60\n\ + ldrb r0, [r4]\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldr r0, [r0]\n\ + mov r2, r8\n\ + ldrb r1, [r2]\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + ldrb r0, [r4]\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldr r1, [r0]\n\ + lsls r1, 28\n\ + ldr r0, [r7]\n\ + bics r0, r1\n\ + str r0, [r7]\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + bl EmitLinkStandbyMsg\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + b _08022BA2\n\ + .align 2, 0\n\ +_08022B44: .4byte gBattlescriptCurrInstr\n\ +_08022B48: .4byte gBattleTypeFlags\n\ +_08022B4C: .4byte gActiveBattler\n\ +_08022B50: .4byte gBattlersCount\n\ +_08022B54: .4byte gHitMarker\n\ +_08022B58: .4byte gBitTable\n\ +_08022B5C: .4byte gAbsentBattlerFlags\n\ +_08022B60:\n\ + ldr r5, _08022B90 @ =gSpecialStatuses\n\ + ldrb r0, [r4]\n\ + lsls r1, r0, 2\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + adds r1, r5\n\ + ldrb r0, [r1]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _08022BA2\n\ + movs r0, 0x6\n\ + bl sub_8022A3C\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r5\n\ + ldrb r1, [r0]\n\ + movs r2, 0x40\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ + b _08022BA2\n\ + .align 2, 0\n\ +_08022B90: .4byte gSpecialStatuses\n\ +_08022B94:\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + bl EmitLinkStandbyMsg\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ +_08022BA2:\n\ + ldrb r0, [r4]\n\ + adds r0, 0x1\n\ + strb r0, [r4]\n\ + ldr r1, _08022BB8 @ =gBattlersCount\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + ldrb r1, [r1]\n\ + cmp r0, r1\n\ + bcc _08022AF2\n\ + b _08022F62\n\ + .align 2, 0\n\ +_08022BB8: .4byte gBattlersCount\n\ +_08022BBC:\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + bne _08022BC4\n\ + b _08022F62\n\ +_08022BC4:\n\ + ldr r0, _08022C1C @ =gHitMarker\n\ + mov r8, r0\n\ + ldr r0, [r0]\n\ + lsrs r5, r0, 28\n\ + ldr r6, _08022C20 @ =gBitTable\n\ + ldr r0, [r6]\n\ + ands r0, r5\n\ + cmp r0, 0\n\ + beq _08022C7E\n\ + ldr r4, _08022C24 @ =gActiveBattler\n\ + strb r7, [r4]\n\ + movs r0, 0\n\ + movs r1, 0x6\n\ + movs r2, 0x6\n\ + bl sub_8018018\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08022C2C\n\ + ldr r2, _08022C28 @ =gAbsentBattlerFlags\n\ + ldrb r0, [r4]\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldr r0, [r0]\n\ + ldrb r1, [r2]\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + ldrb r0, [r4]\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldr r1, [r0]\n\ + lsls r1, 28\n\ + mov r2, r8\n\ + ldr r0, [r2]\n\ + bics r0, r1\n\ + str r0, [r2]\n\ + movs r0, 0\n\ + bl Emitcmd42\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + b _08022C7E\n\ + .align 2, 0\n\ +_08022C1C: .4byte gHitMarker\n\ +_08022C20: .4byte gBitTable\n\ +_08022C24: .4byte gActiveBattler\n\ +_08022C28: .4byte gAbsentBattlerFlags\n\ +_08022C2C:\n\ + ldr r6, _08022C60 @ =gSpecialStatuses\n\ + ldrb r0, [r4]\n\ + lsls r1, r0, 2\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + adds r1, r6\n\ + ldrb r0, [r1]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _08022C6C\n\ + ldr r0, _08022C64 @ =gSharedMem\n\ + ldr r1, _08022C68 @ =0x0001606a\n\ + adds r0, r1\n\ + ldrb r0, [r0]\n\ + bl sub_8022A3C\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldrb r1, [r0]\n\ + movs r2, 0x40\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ + b _08022C7E\n\ + .align 2, 0\n\ +_08022C60: .4byte gSpecialStatuses\n\ +_08022C64: .4byte gSharedMem\n\ +_08022C68: .4byte 0x0001606a\n\ +_08022C6C:\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + bl EmitLinkStandbyMsg\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + movs r2, 0x1\n\ + mov r9, r2\n\ +_08022C7E:\n\ + ldr r6, _08022CD8 @ =gBitTable\n\ + ldr r0, [r6, 0x8]\n\ + ands r0, r5\n\ + cmp r0, 0\n\ + beq _08022D40\n\ + ldr r0, [r6]\n\ + ands r0, r5\n\ + cmp r0, 0\n\ + bne _08022D40\n\ + ldr r4, _08022CDC @ =gActiveBattler\n\ + movs r0, 0x2\n\ + strb r0, [r4]\n\ + movs r0, 0x2\n\ + movs r1, 0x6\n\ + movs r2, 0x6\n\ + bl sub_8018018\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08022CE8\n\ + ldr r2, _08022CE0 @ =gAbsentBattlerFlags\n\ + ldrb r0, [r4]\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldr r0, [r0]\n\ + ldrb r1, [r2]\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + ldr r2, _08022CE4 @ =gHitMarker\n\ + ldrb r0, [r4]\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldr r1, [r0]\n\ + lsls r1, 28\n\ + ldr r0, [r2]\n\ + bics r0, r1\n\ + str r0, [r2]\n\ + movs r0, 0\n\ + bl Emitcmd42\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + b _08022D40\n\ + .align 2, 0\n\ +_08022CD8: .4byte gBitTable\n\ +_08022CDC: .4byte gActiveBattler\n\ +_08022CE0: .4byte gAbsentBattlerFlags\n\ +_08022CE4: .4byte gHitMarker\n\ +_08022CE8:\n\ + ldr r6, _08022D1C @ =gSpecialStatuses\n\ + ldrb r0, [r4]\n\ + lsls r1, r0, 2\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + adds r1, r6\n\ + ldrb r0, [r1]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _08022D28\n\ + ldr r0, _08022D20 @ =gSharedMem\n\ + ldr r1, _08022D24 @ =0x00016068\n\ + adds r0, r1\n\ + ldrb r0, [r0]\n\ + bl sub_8022A3C\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldrb r1, [r0]\n\ + movs r2, 0x40\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ + b _08022D40\n\ + .align 2, 0\n\ +_08022D1C: .4byte gSpecialStatuses\n\ +_08022D20: .4byte gSharedMem\n\ +_08022D24: .4byte 0x00016068\n\ +_08022D28:\n\ + movs r0, 0x1\n\ + mov r2, r9\n\ + ands r0, r2\n\ + cmp r0, 0\n\ + bne _08022D40\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + bl EmitLinkStandbyMsg\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ +_08022D40:\n\ + ldr r6, _08022D90 @ =gBitTable\n\ + ldr r0, [r6, 0x4]\n\ + ands r0, r5\n\ + cmp r0, 0\n\ + beq _08022DF6\n\ + ldr r4, _08022D94 @ =gActiveBattler\n\ + movs r0, 0x1\n\ + strb r0, [r4]\n\ + movs r0, 0x1\n\ + movs r1, 0x6\n\ + movs r2, 0x6\n\ + bl sub_8018018\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08022DA0\n\ + ldr r2, _08022D98 @ =gAbsentBattlerFlags\n\ + ldrb r0, [r4]\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldr r0, [r0]\n\ + ldrb r1, [r2]\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + ldr r2, _08022D9C @ =gHitMarker\n\ + ldrb r0, [r4]\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldr r1, [r0]\n\ + lsls r1, 28\n\ + ldr r0, [r2]\n\ + bics r0, r1\n\ + str r0, [r2]\n\ + movs r0, 0\n\ + bl Emitcmd42\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + b _08022DF6\n\ + .align 2, 0\n\ +_08022D90: .4byte gBitTable\n\ +_08022D94: .4byte gActiveBattler\n\ +_08022D98: .4byte gAbsentBattlerFlags\n\ +_08022D9C: .4byte gHitMarker\n\ +_08022DA0:\n\ + ldr r6, _08022DD4 @ =gSpecialStatuses\n\ + ldrb r0, [r4]\n\ + lsls r1, r0, 2\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + adds r1, r6\n\ + ldrb r0, [r1]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _08022DE0\n\ + ldr r0, _08022DD8 @ =gSharedMem\n\ + ldr r1, _08022DDC @ =0x0001606b\n\ + adds r0, r1\n\ + ldrb r0, [r0]\n\ + bl sub_8022A3C\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldrb r1, [r0]\n\ + movs r2, 0x40\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ + b _08022DF6\n\ + .align 2, 0\n\ +_08022DD4: .4byte gSpecialStatuses\n\ +_08022DD8: .4byte gSharedMem\n\ +_08022DDC: .4byte 0x0001606b\n\ +_08022DE0:\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + bl EmitLinkStandbyMsg\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + movs r0, 0x2\n\ + mov r2, r9\n\ + orrs r2, r0\n\ + mov r9, r2\n\ +_08022DF6:\n\ + ldr r6, _08022E50 @ =gBitTable\n\ + ldr r0, [r6, 0xC]\n\ + ands r0, r5\n\ + cmp r0, 0\n\ + beq _08022EB8\n\ + ldr r0, [r6, 0x4]\n\ + ands r0, r5\n\ + cmp r0, 0\n\ + bne _08022EB8\n\ + ldr r4, _08022E54 @ =gActiveBattler\n\ + movs r0, 0x3\n\ + strb r0, [r4]\n\ + movs r0, 0x3\n\ + movs r1, 0x6\n\ + movs r2, 0x6\n\ + bl sub_8018018\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08022E60\n\ + ldr r2, _08022E58 @ =gAbsentBattlerFlags\n\ + ldrb r0, [r4]\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldr r0, [r0]\n\ + ldrb r1, [r2]\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + ldr r2, _08022E5C @ =gHitMarker\n\ + ldrb r0, [r4]\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldr r1, [r0]\n\ + lsls r1, 28\n\ + ldr r0, [r2]\n\ + bics r0, r1\n\ + str r0, [r2]\n\ + movs r0, 0\n\ + bl Emitcmd42\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + b _08022EB8\n\ + .align 2, 0\n\ +_08022E50: .4byte gBitTable\n\ +_08022E54: .4byte gActiveBattler\n\ +_08022E58: .4byte gAbsentBattlerFlags\n\ +_08022E5C: .4byte gHitMarker\n\ +_08022E60:\n\ + ldr r6, _08022E94 @ =gSpecialStatuses\n\ + ldrb r0, [r4]\n\ + lsls r1, r0, 2\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + adds r1, r6\n\ + ldrb r0, [r1]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _08022EA0\n\ + ldr r0, _08022E98 @ =gSharedMem\n\ + ldr r1, _08022E9C @ =0x00016069\n\ + adds r0, r1\n\ + ldrb r0, [r0]\n\ + bl sub_8022A3C\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r6\n\ + ldrb r1, [r0]\n\ + movs r2, 0x40\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ + b _08022EB8\n\ + .align 2, 0\n\ +_08022E94: .4byte gSpecialStatuses\n\ +_08022E98: .4byte gSharedMem\n\ +_08022E9C: .4byte 0x00016069\n\ +_08022EA0:\n\ + movs r0, 0x2\n\ + mov r2, r9\n\ + ands r2, r0\n\ + cmp r2, 0\n\ + bne _08022EB8\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + bl EmitLinkStandbyMsg\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ +_08022EB8:\n\ + ldr r1, _08022EE8 @ =gSpecialStatuses\n\ + ldrb r0, [r1]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _08022F0C\n\ + adds r0, r1, 0\n\ + adds r0, 0x28\n\ + ldrb r0, [r0]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _08022F0C\n\ + cmp r5, 0\n\ + beq _08022F0C\n\ + ldr r0, _08022EEC @ =gAbsentBattlerFlags\n\ + ldrb r1, [r0]\n\ + ldr r0, _08022EF0 @ =gBitTable\n\ + ldr r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + beq _08022EF8\n\ + ldr r1, _08022EF4 @ =gActiveBattler\n\ + movs r0, 0x2\n\ + strb r0, [r1]\n\ + b _08022EFC\n\ + .align 2, 0\n\ +_08022EE8: .4byte gSpecialStatuses\n\ +_08022EEC: .4byte gAbsentBattlerFlags\n\ +_08022EF0: .4byte gBitTable\n\ +_08022EF4: .4byte gActiveBattler\n\ +_08022EF8:\n\ + ldr r0, _08022F3C @ =gActiveBattler\n\ + strb r1, [r0]\n\ +_08022EFC:\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + bl EmitLinkStandbyMsg\n\ + ldr r0, _08022F3C @ =gActiveBattler\n\ + ldrb r0, [r0]\n\ + bl MarkBufferBankForExecution\n\ +_08022F0C:\n\ + ldr r1, _08022F40 @ =gSpecialStatuses\n\ + ldrb r0, [r1, 0x14]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _08022F62\n\ + adds r0, r1, 0\n\ + adds r0, 0x3C\n\ + ldrb r0, [r0]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _08022F62\n\ + cmp r5, 0\n\ + beq _08022F62\n\ + ldr r0, _08022F44 @ =gAbsentBattlerFlags\n\ + ldrb r0, [r0]\n\ + ldr r1, _08022F48 @ =gBitTable\n\ + ldr r1, [r1, 0x4]\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08022F4C\n\ + ldr r1, _08022F3C @ =gActiveBattler\n\ + movs r0, 0x3\n\ + b _08022F50\n\ + .align 2, 0\n\ +_08022F3C: .4byte gActiveBattler\n\ +_08022F40: .4byte gSpecialStatuses\n\ +_08022F44: .4byte gAbsentBattlerFlags\n\ +_08022F48: .4byte gBitTable\n\ +_08022F4C:\n\ + ldr r1, _08022F6C @ =gActiveBattler\n\ + movs r0, 0x1\n\ +_08022F50:\n\ + strb r0, [r1]\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + bl EmitLinkStandbyMsg\n\ + ldr r0, _08022F6C @ =gActiveBattler\n\ + ldrb r0, [r0]\n\ + bl MarkBufferBankForExecution\n\ +_08022F62:\n\ + ldr r1, _08022F70 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x6\n\ + str r0, [r1]\n\ + b _08023302\n\ + .align 2, 0\n\ +_08022F6C: .4byte gActiveBattler\n\ +_08022F70: .4byte gBattlescriptCurrInstr\n\ +_08022F74:\n\ + cmp r0, 0x6\n\ + beq _08022F7A\n\ + b _08023170\n\ +_08022F7A:\n\ + ldr r0, _08022FF0 @ =gBattleTypeFlags\n\ + ldrh r2, [r0]\n\ + movs r0, 0x40\n\ + ands r0, r2\n\ + cmp r0, 0\n\ + beq _08022F88\n\ + b _0802310C\n\ +_08022F88:\n\ + movs r0, 0x1\n\ + ands r0, r2\n\ + cmp r0, 0\n\ + bne _08022F92\n\ + b _0802310C\n\ +_08022F92:\n\ + ldr r7, _08022FF4 @ =gHitMarker\n\ + ldr r0, [r7]\n\ + lsrs r5, r0, 28\n\ + ldr r4, _08022FF8 @ =gBitTable\n\ + ldr r0, [r4, 0x8]\n\ + ands r0, r5\n\ + cmp r0, 0\n\ + beq _0802303A\n\ + ldr r0, [r4]\n\ + ands r0, r5\n\ + cmp r0, 0\n\ + beq _0802303A\n\ + ldr r6, _08022FFC @ =gActiveBattler\n\ + movs r0, 0x2\n\ + strb r0, [r6]\n\ + ldr r0, _08023000 @ =gBattleBufferB\n\ + ldrb r1, [r0, 0x1]\n\ + movs r0, 0x2\n\ + movs r2, 0x6\n\ + bl sub_8018018\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08023008\n\ + ldr r2, _08023004 @ =gAbsentBattlerFlags\n\ + ldrb r0, [r6]\n\ + lsls r0, 2\n\ + adds r0, r4\n\ + ldr r0, [r0]\n\ + ldrb r1, [r2]\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + ldrb r0, [r6]\n\ + lsls r0, 2\n\ + adds r0, r4\n\ + ldr r1, [r0]\n\ + lsls r1, 28\n\ + ldr r0, [r7]\n\ + bics r0, r1\n\ + str r0, [r7]\n\ + movs r0, 0\n\ + bl Emitcmd42\n\ + ldrb r0, [r6]\n\ + bl MarkBufferBankForExecution\n\ + b _0802303A\n\ + .align 2, 0\n\ +_08022FF0: .4byte gBattleTypeFlags\n\ +_08022FF4: .4byte gHitMarker\n\ +_08022FF8: .4byte gBitTable\n\ +_08022FFC: .4byte gActiveBattler\n\ +_08023000: .4byte gBattleBufferB\n\ +_08023004: .4byte gAbsentBattlerFlags\n\ +_08023008:\n\ + ldr r4, _08023098 @ =gSpecialStatuses\n\ + ldrb r0, [r6]\n\ + lsls r1, r0, 2\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + adds r1, r4\n\ + ldrb r0, [r1]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _0802303A\n\ + ldr r0, _0802309C @ =gSharedMem\n\ + ldr r1, _080230A0 @ =0x00016068\n\ + adds r0, r1\n\ + ldrb r0, [r0]\n\ + bl sub_8022A3C\n\ + ldrb r1, [r6]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r4\n\ + ldrb r1, [r0]\n\ + movs r2, 0x40\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ +_0802303A:\n\ + ldr r4, _080230A4 @ =gBitTable\n\ + ldr r0, [r4, 0xC]\n\ + ands r0, r5\n\ + cmp r0, 0\n\ + beq _080230EE\n\ + ldr r0, [r4, 0x4]\n\ + ands r5, r0\n\ + cmp r5, 0\n\ + beq _080230EE\n\ + ldr r5, _080230A8 @ =gActiveBattler\n\ + movs r0, 0x3\n\ + strb r0, [r5]\n\ + ldr r0, _080230AC @ =gBattleBufferB\n\ + ldr r2, _080230B0 @ =0x00000201\n\ + adds r0, r2\n\ + ldrb r1, [r0]\n\ + movs r0, 0x3\n\ + movs r2, 0x6\n\ + bl sub_8018018\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _080230BC\n\ + ldr r2, _080230B4 @ =gAbsentBattlerFlags\n\ + ldrb r0, [r5]\n\ + lsls r0, 2\n\ + adds r0, r4\n\ + ldr r0, [r0]\n\ + ldrb r1, [r2]\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + ldr r2, _080230B8 @ =gHitMarker\n\ + ldrb r0, [r5]\n\ + lsls r0, 2\n\ + adds r0, r4\n\ + ldr r1, [r0]\n\ + lsls r1, 28\n\ + ldr r0, [r2]\n\ + bics r0, r1\n\ + str r0, [r2]\n\ + movs r0, 0\n\ + bl Emitcmd42\n\ + ldrb r0, [r5]\n\ + bl MarkBufferBankForExecution\n\ + b _080230EE\n\ + .align 2, 0\n\ +_08023098: .4byte gSpecialStatuses\n\ +_0802309C: .4byte gSharedMem\n\ +_080230A0: .4byte 0x00016068\n\ +_080230A4: .4byte gBitTable\n\ +_080230A8: .4byte gActiveBattler\n\ +_080230AC: .4byte gBattleBufferB\n\ +_080230B0: .4byte 0x00000201\n\ +_080230B4: .4byte gAbsentBattlerFlags\n\ +_080230B8: .4byte gHitMarker\n\ +_080230BC:\n\ + ldr r4, _080230FC @ =gSpecialStatuses\n\ + ldrb r0, [r5]\n\ + lsls r1, r0, 2\n\ + adds r1, r0\n\ + lsls r1, 2\n\ + adds r1, r4\n\ + ldrb r0, [r1]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + blt _080230EE\n\ + ldr r0, _08023100 @ =gSharedMem\n\ + ldr r1, _08023104 @ =0x00016069\n\ + adds r0, r1\n\ + ldrb r0, [r0]\n\ + bl sub_8022A3C\n\ + ldrb r1, [r5]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r4\n\ + ldrb r1, [r0]\n\ + movs r2, 0x40\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ +_080230EE:\n\ + ldr r1, _08023108 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x6\n\ + str r0, [r1]\n\ + mov r12, r1\n\ + b _08023110\n\ + .align 2, 0\n\ +_080230FC: .4byte gSpecialStatuses\n\ +_08023100: .4byte gSharedMem\n\ +_08023104: .4byte 0x00016069\n\ +_08023108: .4byte gBattlescriptCurrInstr\n\ +_0802310C:\n\ + adds r0, r1, 0x6\n\ + str r0, [r6]\n\ +_08023110:\n\ + ldr r0, _08023160 @ =gHitMarker\n\ + ldr r0, [r0]\n\ + lsrs r5, r0, 28\n\ + ldr r1, _08023164 @ =gBank1\n\ + movs r0, 0\n\ + strb r0, [r1]\n\ + ldr r4, _08023168 @ =gBitTable\n\ + ldr r2, [r4]\n\ + ands r2, r5\n\ + ldr r6, _0802316C @ =gBattlersCount\n\ + cmp r2, 0\n\ + bne _0802314C\n\ + adds r7, r6, 0\n\ + ldrb r0, [r6]\n\ + cmp r2, r0\n\ + bcs _0802314C\n\ + adds r3, r1, 0\n\ +_08023132:\n\ + ldrb r0, [r3]\n\ + adds r0, 0x1\n\ + strb r0, [r3]\n\ + ldrb r2, [r3]\n\ + lsls r0, r2, 2\n\ + adds r0, r4\n\ + ldr r0, [r0]\n\ + ands r0, r5\n\ + cmp r0, 0\n\ + bne _0802314C\n\ + ldrb r0, [r7]\n\ + cmp r2, r0\n\ + bcc _08023132\n\ +_0802314C:\n\ + ldrb r0, [r1]\n\ + ldrb r6, [r6]\n\ + cmp r0, r6\n\ + beq _08023156\n\ + b _08023302\n\ +_08023156:\n\ + mov r1, r8\n\ + mov r2, r12\n\ + str r1, [r2]\n\ + b _08023302\n\ + .align 2, 0\n\ +_08023160: .4byte gHitMarker\n\ +_08023164: .4byte gBank1\n\ +_08023168: .4byte gBitTable\n\ +_0802316C: .4byte gBattlersCount\n\ +_08023170:\n\ + movs r0, 0x80\n\ + ands r0, r2\n\ + movs r5, 0x1\n\ + cmp r0, 0\n\ + beq _0802317C\n\ + movs r5, 0\n\ +_0802317C:\n\ + movs r0, 0x7F\n\ + ands r0, r2\n\ + bl GetBattleBank\n\ + lsls r0, 24\n\ + lsrs r7, r0, 24\n\ + ldr r1, _080231A4 @ =gSpecialStatuses\n\ + lsls r0, r7, 2\n\ + adds r0, r7\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r0, [r0]\n\ + lsls r0, 25\n\ + cmp r0, 0\n\ + bge _080231A8\n\ + ldr r0, [r6]\n\ + adds r0, 0x6\n\ + str r0, [r6]\n\ + b _08023302\n\ + .align 2, 0\n\ +_080231A4: .4byte gSpecialStatuses\n\ +_080231A8:\n\ + adds r0, r7, 0\n\ + movs r1, 0x6\n\ + movs r2, 0x6\n\ + bl sub_8018018\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _080231F8\n\ + ldr r2, _080231E8 @ =gActiveBattler\n\ + strb r7, [r2]\n\ + ldr r3, _080231EC @ =gAbsentBattlerFlags\n\ + ldr r4, _080231F0 @ =gBitTable\n\ + ldrb r0, [r2]\n\ + lsls r0, 2\n\ + adds r0, r4\n\ + ldr r0, [r0]\n\ + ldrb r1, [r3]\n\ + orrs r0, r1\n\ + strb r0, [r3]\n\ + ldr r3, _080231F4 @ =gHitMarker\n\ + ldrb r0, [r2]\n\ + lsls r0, 2\n\ + adds r0, r4\n\ + ldr r1, [r0]\n\ + lsls r1, 28\n\ + ldr r0, [r3]\n\ + bics r0, r1\n\ + str r0, [r3]\n\ + mov r0, r8\n\ + str r0, [r6]\n\ + b _08023302\n\ + .align 2, 0\n\ +_080231E8: .4byte gActiveBattler\n\ +_080231EC: .4byte gAbsentBattlerFlags\n\ +_080231F0: .4byte gBitTable\n\ +_080231F4: .4byte gHitMarker\n\ +_080231F8:\n\ + ldr r4, _080232A0 @ =gActiveBattler\n\ + strb r7, [r4]\n\ + ldr r3, _080232A4 @ =gSharedMem\n\ + ldrb r0, [r4]\n\ + ldr r2, _080232A8 @ =0x00016064\n\ + adds r1, r0, r2\n\ + adds r1, r3\n\ + ldr r2, _080232AC @ =gBattlerPartyIndexes\n\ + lsls r0, 1\n\ + adds r0, r2\n\ + ldrh r0, [r0]\n\ + strb r0, [r1]\n\ + ldrb r1, [r4]\n\ + movs r0, 0x2\n\ + eors r0, r1\n\ + ldr r1, _080232B0 @ =0x00016068\n\ + adds r0, r1\n\ + adds r0, r3\n\ + ldrb r2, [r0]\n\ + ldrb r1, [r4]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + ldr r1, _080232B4 @ =0x0001606c\n\ + adds r3, r1\n\ + adds r0, r3\n\ + str r0, [sp]\n\ + movs r0, 0\n\ + adds r1, r5, 0\n\ + movs r3, 0\n\ + bl EmitChoosePokemon\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ + ldr r0, [r6]\n\ + adds r0, 0x6\n\ + str r0, [r6]\n\ + ldrb r0, [r4]\n\ + bl GetBattlerPosition\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + bne _0802325A\n\ + ldr r1, _080232B8 @ =gBattleResults\n\ + ldrb r0, [r1, 0x2]\n\ + cmp r0, 0xFE\n\ + bhi _0802325A\n\ + adds r0, 0x1\n\ + strb r0, [r1, 0x2]\n\ +_0802325A:\n\ + ldr r0, _080232BC @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + movs r0, 0x40\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _080232C4\n\ + ldr r1, _080232A0 @ =gActiveBattler\n\ + movs r0, 0\n\ + strb r0, [r1]\n\ + ldr r0, _080232C0 @ =gBattlersCount\n\ + ldrb r0, [r0]\n\ + cmp r0, 0\n\ + beq _08023302\n\ + adds r4, r1, 0\n\ +_08023276:\n\ + ldrb r0, [r4]\n\ + cmp r0, r7\n\ + beq _0802328A\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + bl EmitLinkStandbyMsg\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ +_0802328A:\n\ + ldrb r0, [r4]\n\ + adds r0, 0x1\n\ + strb r0, [r4]\n\ + ldr r1, _080232C0 @ =gBattlersCount\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + ldrb r1, [r1]\n\ + cmp r0, r1\n\ + bcc _08023276\n\ + b _08023302\n\ + .align 2, 0\n\ +_080232A0: .4byte gActiveBattler\n\ +_080232A4: .4byte gSharedMem\n\ +_080232A8: .4byte 0x00016064\n\ +_080232AC: .4byte gBattlerPartyIndexes\n\ +_080232B0: .4byte 0x00016068\n\ +_080232B4: .4byte 0x0001606c\n\ +_080232B8: .4byte gBattleResults\n\ +_080232BC: .4byte gBattleTypeFlags\n\ +_080232C0: .4byte gBattlersCount\n\ +_080232C4:\n\ + adds r0, r7, 0\n\ + bl GetBattlerPosition\n\ + movs r1, 0x1\n\ + eors r0, r1\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + bl GetBattlerAtPosition\n\ + ldr r4, _08023310 @ =gActiveBattler\n\ + strb r0, [r4]\n\ + ldr r0, _08023314 @ =gAbsentBattlerFlags\n\ + ldrb r1, [r0]\n\ + ldr r2, _08023318 @ =gBitTable\n\ + ldrb r3, [r4]\n\ + lsls r0, r3, 2\n\ + adds r0, r2\n\ + ldr r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + beq _080232F4\n\ + movs r0, 0x2\n\ + eors r3, r0\n\ + strb r3, [r4]\n\ +_080232F4:\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + bl EmitLinkStandbyMsg\n\ + ldrb r0, [r4]\n\ + bl MarkBufferBankForExecution\n\ +_08023302:\n\ + add sp, 0x4\n\ + pop {r3,r4}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08023310: .4byte gActiveBattler\n\ +_08023314: .4byte gAbsentBattlerFlags\n\ +_08023318: .4byte gBitTable\n\ + .syntax divided"); +} + +static void atk51_switchhandleorder(void) +{ + int i; + if (gBattleExecBuffer) + return; + + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + switch (T2_READ_8(gBattlescriptCurrInstr + 2)) + { + case 0: + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleBufferB[i][0] == 0x22) + ewram16068arr(i) = gBattleBufferB[i][1]; + } + break; + case 1: + if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + sub_8012258(gActiveBattler); + break; + case 2: + gBattleCommunication[0] = gBattleBufferB[gActiveBattler][1]; + ewram16068arr(gActiveBattler) = gBattleBufferB[gActiveBattler][1]; + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + ewram1606Carr(0, gActiveBattler) &= 0xF; + ewram1606Carr(0, gActiveBattler) |= (gBattleBufferB[gActiveBattler][2] & 0xF0); + ewram1606Carr(1, gActiveBattler) = gBattleBufferB[gActiveBattler][3]; + ewram1606Carr(0, (gActiveBattler ^ 2)) &= (0xF0); + ewram1606Carr(0, (gActiveBattler ^ 2)) |= (gBattleBufferB[gActiveBattler][2] & 0xF0) >> 4; + ewram1606Carr(2, (gActiveBattler ^ 2)) = gBattleBufferB[gActiveBattler][3]; + } + else + sub_8012258(gActiveBattler); + + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 6; + gBattleTextBuff1[2] = gBattleMons[gBankAttacker].species; + gBattleTextBuff1[3] = gBattleMons[gBankAttacker].species >> 8; + gBattleTextBuff1[4] = 0xFF; + + gBattleTextBuff2[0] = 0xFD; + gBattleTextBuff2[1] = 7; + gBattleTextBuff2[2] = gActiveBattler; + gBattleTextBuff2[3] = gBattleBufferB[gActiveBattler][1]; + gBattleTextBuff2[4] = 0xFF; + break; + } + gBattlescriptCurrInstr += 3; +} + +static void atk52_switchineffects(void) +{ + int i; + + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + sub_80157C4(gActiveBattler); + gHitMarker &= ~(HITMARKER_FAINTED(gActiveBattler)); + gSpecialStatuses[gActiveBattler].flag40 = 0; + + if (!(gSideAffecting[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES_DAMAGED) && (gSideAffecting[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_SPIKES) + && gBattleMons[gActiveBattler].type1 != TYPE_FLYING && gBattleMons[gActiveBattler].type2 != TYPE_FLYING && gBattleMons[gActiveBattler].ability != ABILITY_LEVITATE) + { + u8 spikesDmg; + + gSideAffecting[GetBattlerSide(gActiveBattler)] |= SIDE_STATUS_SPIKES_DAMAGED; + + spikesDmg = (5 - gSideTimers[GetBattlerSide(gActiveBattler)].spikesAmount) * 2; + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / (spikesDmg); + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + + gBattleStruct->scriptingActive = gActiveBattler; + BattleScriptPushCursor(); + + if (T2_READ_8(gBattlescriptCurrInstr + 1) == 0) + gBattlescriptCurrInstr = BattleScript_SpikesOnTarget; + else if (T2_READ_8(gBattlescriptCurrInstr + 1) == 1) + gBattlescriptCurrInstr = BattleScript_SpikesOnAttacker; + else + gBattlescriptCurrInstr = BattleScript_SpikesOngBank1; + } + else + { + if (gBattleMons[gActiveBattler].ability == ABILITY_TRUANT) + { + gDisableStructs[gActiveBattler].truantCounter = 1; + } + + if (AbilityBattleEffects(0, gActiveBattler, 0, 0, 0) == 0 && ItemBattleEffects(0, gActiveBattler, 0) == 0) + { + gSideAffecting[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_SPIKES_DAMAGED); + + for (i = 0; i < gBattlersCount; i++) + { + if (gBanksByTurnOrder[i] == gActiveBattler) + gActionsByTurnOrder[i] = 0xC; + } + + for (i = 0; i < gBattlersCount; i++) + { + *(HP_ON_SWITCHOUT + GetBattlerSide(i)) = gBattleMons[i].hp; + } + + if (T2_READ_8(gBattlescriptCurrInstr + 1) == 5) + { + u32 hitmark = gHitMarker >> 0x1C; + gBank1++; + while (1) + { + if (hitmark & gBitTable[gBank1] && !(gAbsentBattlerFlags & gBitTable[gBank1])) + break; + if (gBank1 >= gBattlersCount) + break; + gBank1++; + } + } + gBattlescriptCurrInstr += 2; + } + } +} + +static void atk53_trainerslidein(void) +{ + if (!T2_READ_8(gBattlescriptCurrInstr + 1)) + gActiveBattler = GetBattlerAtPosition(0); + else + gActiveBattler = GetBattlerAtPosition(1); + + EmitTrainerSlide(0); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 2; +} + +static void atk54_playse(void) +{ + gActiveBattler = gBankAttacker; + EmitEffectivenessSound(0, T2_READ_16(gBattlescriptCurrInstr + 1)); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 3; +} + +static void atk55_fanfare(void) +{ + gActiveBattler = gBankAttacker; + Emitcmd44(0, T2_READ_16(gBattlescriptCurrInstr + 1)); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 3; +} + +static void atk56_playfaintcry(void) +{ + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + EmitFaintingCry(0); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 2; +} + +static void atk57(void) +{ + gActiveBattler = GetBattlerAtPosition(0); + Emitcmd55(0, gBattleOutcome); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 1; +} + +static void atk58_returntoball(void) +{ + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + EmitReturnPokeToBall(0, 1); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 2; +} + +void atk59_handlelearnnewmove(void) +{ + u8* loc1 = T1_READ_PTR(gBattlescriptCurrInstr + 1); + u8* loc2 = T1_READ_PTR(gBattlescriptCurrInstr + 5); + + u16 ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterID], T2_READ_8(gBattlescriptCurrInstr + 9)); + while (ret == 0xFFFE) + ret = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterID], 0); + + if (ret == 0) + { + gBattlescriptCurrInstr = loc2; + } + else if (ret == 0xFFFF) + { + gBattlescriptCurrInstr += 10; + } + else + { + gActiveBattler = GetBattlerAtPosition(0); + if (gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterID && !(gBattleMons[gActiveBattler].status2 & STATUS2_TRANSFORMED)) + GiveMoveToBattleMon(&gBattleMons[gActiveBattler], ret); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) //what is else if + { + gActiveBattler = GetBattlerAtPosition(2); + if (gBattlerPartyIndexes[gActiveBattler] == gBattleStruct->expGetterID && !(gBattleMons[gActiveBattler].status2 & STATUS2_TRANSFORMED)) + GiveMoveToBattleMon(&gBattleMons[gActiveBattler], ret); + } + gBattlescriptCurrInstr = loc1; + } +} + +void sub_8023A80(void) +{ + sub_802BBD4(0x18, 8, 0x1D, 0xD, 0); + Text_InitWindow(&gUnknown_03004210, BattleText_YesNo, 0x100, 0x19, 0x9); + Text_PrintWindow8002F44(&gUnknown_03004210); + MenuCursor_Create814A5C0(0, 0xFFFF, 0xC, 0x2D9F, 0x20); +} + +void sub_8023AD8(void) +{ + sub_802BBD4(0x18, 8, 0x1D, 0xD, 1); + DestroyMenuCursor(); +} + +static void atk5A_yesnoboxlearnmove(void) +{ + gActiveBattler = 0; + switch (gBattleStruct->atk5A_StateTracker) + { + case 0: + sub_8023A80(); + gBattleStruct->atk5A_StateTracker++; + gBattleCommunication[1] = 0; + sub_802BC6C(); + break; + case 1: + if (gMain.newKeys & DPAD_UP && gBattleCommunication[1] != 0) + { + PlaySE(SE_SELECT); + nullsub_6(); + gBattleCommunication[1] = 0; + sub_802BC6C(); + } + if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[1] == 0) + { + PlaySE(SE_SELECT); + nullsub_6(); + gBattleCommunication[1] = 1; + sub_802BC6C(); + } + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + if (gBattleCommunication[1] == 0) + { + sub_8023AD8(); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); + gBattleStruct->atk5A_StateTracker++; + return; + } + goto state_tracker_4; + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + state_tracker_4: + gBattleStruct->atk5A_StateTracker = 4; + } + break; + case 2: + if (!gPaletteFade.active) + { + ShowSelectMovePokemonSummaryScreen(gPlayerParty, gBattleStruct->expGetterID, gPlayerPartyCount - 1, ReshowBattleScreenAfterMenu, gMoveToLearn); + gBattleStruct->atk5A_StateTracker++; + } + break; + case 3: + if (!gPaletteFade.active && gMain.callback2 == BattleMainCB2) + { + u8 move_pos = sub_809FA30(); + if (move_pos == 4) + { + gBattleStruct->atk5A_StateTracker = 4; + } + else + { + u16 move = GetMonData(&gPlayerParty[gBattleStruct->expGetterID], MON_DATA_MOVE1 + move_pos); + if (IsHMMove2(move)) + { + PrepareStringBattle(0x13F, gActiveBattler); + gBattleStruct->atk5A_StateTracker = 5; + } + else + { + u8 *ptr; + + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + ptr = gBattleTextBuff2; + { + ptr[0] = 0xFD; + ptr[1] = 2; + ptr[2] = move; + ptr[3] = ((move & 0xFF00) >> 8); + ptr += 4; + } + ptr[0] = 0xFF; + RemoveMonPPBonus(&gPlayerParty[gBattleStruct->expGetterID], move_pos); + SetMonMoveSlot(&gPlayerParty[gBattleStruct->expGetterID], gMoveToLearn, move_pos); + if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterID && !(gBattleMons[0].status2 & STATUS2_TRANSFORMED) + && !(gDisableStructs[0].unk18_b & gBitTable[move_pos])) + { + RemoveBattleMonPPBonus(&gBattleMons[0], move_pos); + SetBattleMonMoveSlot(&gBattleMons[0], gMoveToLearn, move_pos); + } + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlerPartyIndexes[2] == gBattleStruct->expGetterID && !(gBattleMons[2].status2 & STATUS2_TRANSFORMED) + && !(gDisableStructs[2].unk18_b & gBitTable[move_pos])) + { + RemoveBattleMonPPBonus(&gBattleMons[2], move_pos); + SetBattleMonMoveSlot(&gBattleMons[2], gMoveToLearn, move_pos); + } + } + } + } + break; + case 4: + sub_8023AD8(); + gBattlescriptCurrInstr += 5; + break; + case 5: + if (gBattleExecBuffer == 0) + { + gBattleStruct->atk5A_StateTracker = 2; + } + break; + } +} + +static void atk5B_yesnoboxstoplearningmove(void) +{ + switch (gBattleStruct->atk5A_StateTracker) + { + case 0: + sub_8023A80(); + gBattleStruct->atk5A_StateTracker++; + gBattleCommunication[1] = 0; + sub_802BC6C(); + break; + case 1: + if (gMain.newKeys & DPAD_UP && gBattleCommunication[1] != 0) + { + PlaySE(SE_SELECT); + nullsub_6(); + gBattleCommunication[1] = 0; + sub_802BC6C(); + } + if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[1] == 0) + { + PlaySE(SE_SELECT); + nullsub_6(); + gBattleCommunication[1] = 1; + sub_802BC6C(); + } + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + if (gBattleCommunication[1] != 0) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; + sub_8023AD8(); + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + sub_8023AD8(); + } + } +} + +static void atk5C_hitanimation(void) +{ + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + gBattlescriptCurrInstr += 2; + else if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE) || !(gBattleMons[gActiveBattler].status2 & STATUS2_SUBSTITUTE) || gDisableStructs[gActiveBattler].substituteHP == 0) + { + EmitHitAnimation(0); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 2; + } + else + gBattlescriptCurrInstr += 2; +} + +#define MONEY_UNKNOWN ((*(u8*)(ewram_addr + 0x17000 + 0x94))) + +#ifdef NONMATCHING +static void atk5D_getmoneyreward(void) +{ + int i = 0; + u8 r5 = 0; + u32 money_to_give; + if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) + { + money_to_give = 2 * gBattleStruct->moneyMultiplier * MONEY_UNKNOWN; + } + else + { + switch(gTrainers[gTrainerBattleOpponent].partyFlags) + { + case 0: + { + const struct PokeTrainerData1 *data = &gTrainers[gTrainerBattleOpponent].party->noItemNoMoves; + r5 = data[gTrainers[gTrainerBattleOpponent].partySize - 1].lvl; + } + break; + case 2: + { + const struct PokeTrainerData2 *data = &gTrainers[gTrainerBattleOpponent].party->itemNoMoves; + r5 = data[gTrainers[gTrainerBattleOpponent].partySize - 1].lvl; + } + break; + case 1: + case 3: + { + const struct PokeTrainerData3 *data = &gTrainers[gTrainerBattleOpponent].party->itemMoves; + r5 = data[gTrainers[gTrainerBattleOpponent].partySize - 1].lvl; + } + break; + } + for (; gTrainerMoney[i * 4] != 0xFF && gTrainerMoney[i * 4 + 1] != gTrainers[gTrainerBattleOpponent].trainerClass ; i++) {} + + money_to_give = (r5 << 2) * gBattleStruct->moneyMultiplier; + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + money_to_give = 2 * gTrainerMoney[i * 4 + 1] * money_to_give; + else + money_to_give = 1 * gTrainerMoney[i * 4 + 1] * money_to_give; + } + + AddMoney(&gSaveBlock1.money, money_to_give); + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 1; + gBattleTextBuff1[2] = 4; + gBattleTextBuff1[3] = 5; + gBattleTextBuff1[4] = BYTE0(money_to_give); + gBattleTextBuff1[5] = BYTE1(money_to_give); + gBattleTextBuff1[6] = BYTE2(money_to_give); + gBattleTextBuff1[7] = BYTE3(money_to_give); + gBattleTextBuff1[8] = 0xFF; + + gBattlescriptCurrInstr += 1; +} +#else +NAKED +static void atk5D_getmoneyreward(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r8\n\ + push {r7}\n\ + movs r6, 0\n\ + movs r5, 0\n\ + ldr r0, _08024048 @ =gTrainerBattleOpponent\n\ + ldrh r2, [r0]\n\ + movs r1, 0x80\n\ + lsls r1, 3\n\ + cmp r2, r1\n\ + bne _08024058\n\ + ldr r0, _0802404C @ =gSharedMem + 0x17000\n\ + adds r1, r0, 0\n\ + adds r1, 0x94\n\ + ldrb r2, [r1]\n\ + ldr r1, _08024050 @ =0xfffff056\n\ + adds r0, r1\n\ + ldrb r1, [r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r4, r2, 0\n\ + muls r4, r0\n\ + ldr r0, _08024054 @ =gSaveBlock1 + 0x490\n\ + mov r8, r0\n\ + b _08024140\n\ + .align 2, 0\n\ +_08024048: .4byte gTrainerBattleOpponent\n\ +_0802404C: .4byte gSharedMem + 0x17000\n\ +_08024050: .4byte 0xfffff056\n\ +_08024054: .4byte gSaveBlock1 + 0x490\n\ +_08024058:\n\ + ldr r2, _08024074 @ =gTrainers\n\ + ldrh r1, [r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r3, r0, 3\n\ + adds r4, r3, r2\n\ + ldrb r1, [r4]\n\ + cmp r1, 0x1\n\ + beq _080240AE\n\ + cmp r1, 0x1\n\ + bgt _08024078\n\ + cmp r1, 0\n\ + beq _08024082\n\ + b _080240C4\n\ + .align 2, 0\n\ +_08024074: .4byte gTrainers\n\ +_08024078:\n\ + cmp r1, 0x2\n\ + beq _08024098\n\ + cmp r1, 0x3\n\ + beq _080240AE\n\ + b _080240C4\n\ +_08024082:\n\ + adds r0, r2, 0\n\ + adds r0, 0x24\n\ + adds r0, r3, r0\n\ + ldr r1, [r0]\n\ + adds r0, r4, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + lsls r0, 3\n\ + adds r0, r1\n\ + subs r0, 0x8\n\ + b _080240C2\n\ +_08024098:\n\ + adds r0, r2, 0\n\ + adds r0, 0x24\n\ + adds r0, r3, r0\n\ + ldr r1, [r0]\n\ + adds r0, r4, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + lsls r0, 3\n\ + adds r0, r1\n\ + subs r0, 0x8\n\ + b _080240C2\n\ +_080240AE:\n\ + adds r0, r2, 0\n\ + adds r0, 0x24\n\ + adds r0, r3, r0\n\ + ldr r1, [r0]\n\ + adds r0, r4, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + lsls r0, 4\n\ + adds r0, r1\n\ + subs r0, 0x10\n\ +_080240C2:\n\ + ldrb r5, [r0, 0x2]\n\ +_080240C4:\n\ + ldr r0, _08024120 @ =gTrainerMoney\n\ + lsls r1, r6, 2\n\ + adds r3, r1, r0\n\ + ldrb r1, [r3]\n\ + mov r12, r0\n\ + lsls r4, r5, 2\n\ + ldr r5, _08024124 @ =gSharedMem\n\ + ldr r7, _08024128 @ =gBattleTypeFlags\n\ + ldr r0, _0802412C @ =gSaveBlock1 + 0x490\n\ + mov r8, r0\n\ + cmp r1, 0xFF\n\ + beq _080240FE\n\ + ldr r2, _08024130 @ =gTrainers\n\ + ldr r0, _08024134 @ =gTrainerBattleOpponent\n\ + ldrh r1, [r0]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 3\n\ + adds r0, r2\n\ + ldrb r2, [r0, 0x1]\n\ + adds r1, r3, 0\n\ +_080240EE:\n\ + ldrb r0, [r1]\n\ + cmp r0, r2\n\ + beq _080240FE\n\ + adds r1, 0x4\n\ + adds r6, 0x1\n\ + ldrb r0, [r1]\n\ + cmp r0, 0xFF\n\ + bne _080240EE\n\ +_080240FE:\n\ + ldr r1, _08024138 @ =0x00016056\n\ + adds r0, r5, r1\n\ + ldrb r0, [r0]\n\ + adds r3, r4, 0\n\ + muls r3, r0\n\ + lsls r0, r6, 2\n\ + add r0, r12\n\ + ldrb r2, [r0, 0x1]\n\ + ldrh r1, [r7]\n\ + movs r0, 0x1\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _0802413C\n\ + lsls r0, r2, 1\n\ + adds r4, r3, 0\n\ + muls r4, r0\n\ + b _08024140\n\ + .align 2, 0\n\ +_08024120: .4byte gTrainerMoney\n\ +_08024124: .4byte gSharedMem\n\ +_08024128: .4byte gBattleTypeFlags\n\ +_0802412C: .4byte gSaveBlock1 + 0x490\n\ +_08024130: .4byte gTrainers\n\ +_08024134: .4byte gTrainerBattleOpponent\n\ +_08024138: .4byte 0x00016056\n\ +_0802413C:\n\ + adds r4, r3, 0\n\ + muls r4, r2\n\ +_08024140:\n\ + mov r0, r8\n\ + adds r1, r4, 0\n\ + bl AddMoney\n\ + ldr r1, _0802418C @ =gBattleTextBuff1\n\ + movs r0, 0xFD\n\ + strb r0, [r1]\n\ + movs r0, 0x1\n\ + strb r0, [r1, 0x1]\n\ + movs r0, 0x4\n\ + strb r0, [r1, 0x2]\n\ + movs r0, 0x5\n\ + strb r0, [r1, 0x3]\n\ + strb r4, [r1, 0x4]\n\ + movs r0, 0xFF\n\ + lsls r0, 8\n\ + ands r0, r4\n\ + lsrs r0, 8\n\ + strb r0, [r1, 0x5]\n\ + movs r0, 0xFF\n\ + lsls r0, 16\n\ + ands r0, r4\n\ + lsrs r0, 16\n\ + strb r0, [r1, 0x6]\n\ + lsrs r0, r4, 24\n\ + strb r0, [r1, 0x7]\n\ + movs r0, 0xFF\n\ + strb r0, [r1, 0x8]\n\ + ldr r1, _08024190 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x1\n\ + str r0, [r1]\n\ + pop {r3}\n\ + mov r8, r3\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0802418C: .4byte gBattleTextBuff1\n\ +_08024190: .4byte gBattlescriptCurrInstr\n\ + .syntax divided"); +} +#endif //NONMATCHING + +/* +static u32 GetTrainerMoneyToGive(u16 trainerId) +{ + u32 i = 0; + u32 lastMonLevel = 0; + u32 moneyReward = 0; + + if (trainerId == SECRET_BASE_OPPONENT) + { + moneyReward = 20 * eSecretBaseRecord->partyLevels[0] * gBattleStruct->moneyMultiplier; + } + else + { + switch (gTrainers[trainerId].partyFlags) + { + case 0: + { + const struct TrainerMonNoItemDefaultMoves *party = gTrainers[trainerId].party.NoItemDefaultMoves; + lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; + } + break; + case F_TRAINER_PARTY_CUSTOM_MOVESET: + { + const struct TrainerMonNoItemCustomMoves *party = gTrainers[trainerId].party.NoItemCustomMoves; + lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; + } + break; + case F_TRAINER_PARTY_HELD_ITEM: + { + const struct TrainerMonItemDefaultMoves *party = gTrainers[trainerId].party.ItemDefaultMoves; + lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; + } + break; + case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM: + { + const struct TrainerMonItemCustomMoves *party = gTrainers[trainerId].party.ItemCustomMoves; + lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl; + } + break; + } + + for (; gTrainerMoneyTable[i].classId != 0xFF; i++) + { + if (gTrainerMoneyTable[i].classId == gTrainers[trainerId].trainerClass) + break; + } + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * 2 * gTrainerMoneyTable[i].value; + else + moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * gTrainerMoneyTable[i].value; + } + + return moneyReward; +} + +static void atk5D_getmoneyreward(void) +{ + u32 moneyReward = GetTrainerMoneyToGive(gTrainerBattleOpponent_A); + if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + moneyReward += GetTrainerMoneyToGive(gTrainerBattleOpponent_B); + + AddMoney(&gSaveBlock1Ptr->money, moneyReward); + + PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff1, 5, moneyReward) + + gBattlescriptCurrInstr++; +} +*/ + +static void atk5E_8025A70(void) +{ + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + switch (gBattleCommunication[0]) + { + case 0: + EmitGetAttributes(0, REQUEST_ALL_BATTLE, 0); + MarkBufferBankForExecution(gActiveBattler); + gBattleCommunication[0]++; + break; + case 1: + if (gBattleExecBuffer == 0) + { + int i; + struct BattlePokemon* bufferPoke = (struct BattlePokemon*) &gBattleBufferB[gActiveBattler][4]; + for (i = 0; i < 4; i++) + { + gBattleMons[gActiveBattler].moves[i] = bufferPoke->moves[i]; + gBattleMons[gActiveBattler].pp[i] = bufferPoke->pp[i]; + } + gBattlescriptCurrInstr += 2; + } + break; + } +} + +static void atk5F_8025B24(void) +{ + gActiveBattler = gBankAttacker; + gBankAttacker = gBankTarget; + gBankTarget = gActiveBattler; + //what is xor... + if (gHitMarker & HITMARKER_PURSUIT_TRAP) + gHitMarker &= ~(HITMARKER_PURSUIT_TRAP); + else + gHitMarker |= HITMARKER_PURSUIT_TRAP; + gBattlescriptCurrInstr++; +} + +static void atk60_incrementgamestat(void) +{ + if (GetBattlerSide(gBankAttacker) == 0) + { + IncrementGameStat(T2_READ_8(gBattlescriptCurrInstr + 1)); + } + gBattlescriptCurrInstr += 2; +} + +static void atk61_drawpartystatussummary(void) +{ + int i; + struct Pokemon* party; + struct HpAndStatus hpStatus[6]; + if (gBattleExecBuffer) + return; + + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + if (GetBattlerSide(gActiveBattler) == 0) + party = gPlayerParty; + else + party = gEnemyParty; + + for (i = 0; i < 6; i++) + { + if (GetMonData(&party[i], MON_DATA_SPECIES2) == 0 || GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_EGG) + { + hpStatus[i].hp = 0xFFFF; + hpStatus[i].status = 0; + } + else + { + hpStatus[i].hp = GetMonData(&party[i], MON_DATA_HP); + hpStatus[i].status = GetMonData(&party[i], MON_DATA_STATUS); + } + } + EmitDrawPartyStatusSummary(0, hpStatus, 1); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 2; +} + +static void atk62_08025C6C(void) +{ + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + Emitcmd49(0); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 2; +} + +static void atk63_jumptorandomattack(void) +{ + if (T2_READ_8(gBattlescriptCurrInstr + 1)) + gCurrentMove = gRandomMove; + else + gChosenMove = gCurrentMove = gRandomMove; + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; +} + +static void atk64_statusanimation(void) +{ + if (gBattleExecBuffer == 0) + { + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBattler].substituteHP == 0 && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) + { + EmitStatusAnimation(0, 0, gBattleMons[gActiveBattler].status1); + MarkBufferBankForExecution(gActiveBattler); + } + gBattlescriptCurrInstr += 2; + } +} + +static void atk65_status2animation(void) +{ + if (gBattleExecBuffer == 0) + { + u32 possible_to_anim; + gActiveBattler = GetBattleBank(T1_READ_8(gBattlescriptCurrInstr + 1)); + possible_to_anim = T1_READ_32(gBattlescriptCurrInstr + 2); + if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBattler].substituteHP == 0 && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) + { + EmitStatusAnimation(0, 1, gBattleMons[gActiveBattler].status2 & possible_to_anim); + MarkBufferBankForExecution(gActiveBattler); + } + gBattlescriptCurrInstr += 6; + } +} + +static void atk66_chosenstatusanimation(void) +{ + if (gBattleExecBuffer == 0) + { + u32 status; + gActiveBattler = GetBattleBank(T1_READ_8(gBattlescriptCurrInstr + 1)); + status = T1_READ_32(gBattlescriptCurrInstr + 3); + if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBattler].substituteHP == 0 && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) + { + EmitStatusAnimation(0, T1_READ_8(gBattlescriptCurrInstr + 2), status); + MarkBufferBankForExecution(gActiveBattler); + } + gBattlescriptCurrInstr += 7; + } +} + +static void atk67_yesnobox(void) +{ + switch (gBattleCommunication[0]) + { + case 0: + sub_8023A80(); + gBattleCommunication[0]++; + gBattleCommunication[1] = 0; + sub_802BC6C(); + break; + case 1: + if (gMain.newKeys & DPAD_UP && gBattleCommunication[1] != 0) + { + PlaySE(SE_SELECT); + nullsub_6(); + gBattleCommunication[1] = 0; + sub_802BC6C(); + } + if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[1] == 0) + { + PlaySE(SE_SELECT); + nullsub_6(); + gBattleCommunication[1] = 1; + sub_802BC6C(); + } + if (gMain.newKeys & B_BUTTON) + { + gBattleCommunication[1] = 1; + PlaySE(SE_SELECT); + sub_8023AD8(); + gBattlescriptCurrInstr++; + } + else if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + sub_8023AD8(); + gBattlescriptCurrInstr++; + } + break; + } +} + +static void atk68_cancelallactions(void) +{ + int i; + for (i = 0; i < gBattlersCount; i++) + { + gActionsByTurnOrder[i] = 0xC; + } + gBattlescriptCurrInstr++; +} + +static void atk69_adjustsetdamage(void) //literally a copy of atk07 except theres no rand dmg modifier... +{ + u8 hold_effect, quality; + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + hold_effect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; + else + { + hold_effect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (hold_effect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + { + RecordItemBattle(gBankTarget, hold_effect); + gSpecialStatuses[gBankTarget].focusBanded = 1; + } + if (gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE) + goto END; + if (gBattleMoves[gCurrentMove].effect != EFFECT_FALSE_SWIPE && !gProtectStructs[gBankTarget].endured + && !gSpecialStatuses[gBankTarget].focusBanded) + goto END; + if (gBattleMons[gBankTarget].hp > gBattleMoveDamage) + goto END; + + gBattleMoveDamage = gBattleMons[gBankTarget].hp - 1; + + if (gProtectStructs[gBankTarget].endured) + { + gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED; + goto END; + } + if (gSpecialStatuses[gBankTarget].focusBanded) + { + gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON; + gLastUsedItem = gBattleMons[gBankTarget].item; + } + + END: + gBattlescriptCurrInstr++; +} + +void atk6A_removeitem(void) +{ + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + USED_HELD_ITEMS(gActiveBattler) = gBattleMons[gActiveBattler].item; + + gBattleMons[gActiveBattler].item = 0; + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBattler].item); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 2; +} + +static void atk6B_atknameinbuff1(void) +{ + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 7; + gBattleTextBuff1[2] = gBankAttacker; + gBattleTextBuff1[3] = gBattlerPartyIndexes[gBankAttacker]; + gBattleTextBuff1[4] = 0xFF; + gBattlescriptCurrInstr++; +} + +#ifdef NONMATCHING +static void atk6C_drawlvlupbox(void) +{ + u8 r1 = 0; + u8 r7 = 0; + switch (gBattleStruct->atk6C_statetracker) + { + case 0: + sub_802BBD4(0xB, 0, 0x1D, 0x7, r1); + StringCopy(gStringVar4, BattleText_Format2); + + } +} + +#else +NAKED +static void atk6C_drawlvlupbox(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x4\n\ + movs r1, 0\n\ + movs r7, 0\n\ + ldr r0, _08024928 @ =gSharedMem\n\ + mov r10, r0\n\ + ldr r4, _0802492C @ =0x0001609c\n\ + add r4, r10\n\ + ldrb r0, [r4]\n\ + cmp r0, 0x1\n\ + bne _0802491C\n\ + b _08024AF4\n\ +_0802491C:\n\ + cmp r0, 0x1\n\ + bgt _08024930\n\ + cmp r0, 0\n\ + beq _0802493E\n\ + b _08024C38\n\ + .align 2, 0\n\ +_08024928: .4byte gSharedMem\n\ +_0802492C: .4byte 0x0001609c\n\ +_08024930:\n\ + cmp r0, 0x2\n\ + bne _08024936\n\ + b _08024C04\n\ +_08024936:\n\ + cmp r0, 0x3\n\ + bne _0802493C\n\ + b _08024C30\n\ +_0802493C:\n\ + b _08024C38\n\ +_0802493E:\n\ + str r1, [sp]\n\ + movs r0, 0xB\n\ + movs r1, 0\n\ + movs r2, 0x1D\n\ + movs r3, 0x7\n\ + bl sub_802BBD4\n\ + ldr r0, _0802499C @ =gStringVar4\n\ + ldr r1, _080249A0 @ =BattleText_Format2\n\ + bl StringCopy\n\ + adds r5, r0, 0\n\ + movs r1, 0\n\ + mov r8, r1\n\ +_0802495A:\n\ + movs r2, 0\n\ + mov r9, r2\n\ + ldr r0, _080249A4 @ =gUnknown_0840165C\n\ + mov r1, r8\n\ + lsls r4, r1, 2\n\ + adds r0, r4, r0\n\ + ldr r1, [r0]\n\ + adds r0, r5, 0\n\ + bl StringAppend\n\ + adds r5, r0, 0\n\ + ldr r0, _080249A8 @ =gSharedMem\n\ + ldr r2, _080249AC @ =0x00016018\n\ + adds r0, r2\n\ + ldrb r1, [r0]\n\ + movs r0, 0x64\n\ + muls r0, r1\n\ + ldr r1, _080249B0 @ =gPlayerParty\n\ + adds r0, r1\n\ + ldr r1, _080249B4 @ =gLevelUpStatBoxStats\n\ + add r1, r8\n\ + ldrb r1, [r1]\n\ + bl GetMonData\n\ + lsls r0, 16\n\ + lsrs r1, r0, 16\n\ + mov r0, r8\n\ + cmp r0, 0x5\n\ + bhi _08024A1A\n\ + ldr r0, _080249B8 @ =_080249BC\n\ + adds r0, r4, r0\n\ + ldr r0, [r0]\n\ + mov pc, r0\n\ + .align 2, 0\n\ +_0802499C: .4byte gStringVar4\n\ +_080249A0: .4byte BattleText_Format2\n\ +_080249A4: .4byte gUnknown_0840165C\n\ +_080249A8: .4byte gSharedMem\n\ +_080249AC: .4byte 0x00016018\n\ +_080249B0: .4byte gPlayerParty\n\ +_080249B4: .4byte gLevelUpStatBoxStats\n\ +_080249B8: .4byte _080249BC\n\ + .align 2, 0\n\ +_080249BC:\n\ + .4byte _080249D4\n\ + .4byte _080249E0\n\ + .4byte _080249EC\n\ + .4byte _080249F8\n\ + .4byte _08024A04\n\ + .4byte _08024A10\n\ +_080249D4:\n\ + ldr r0, _080249DC @ =gSharedMem + 0x17180\n\ + ldrh r0, [r0]\n\ + b _08024A14\n\ + .align 2, 0\n\ +_080249DC: .4byte gSharedMem + 0x17180\n\ +_080249E0:\n\ + ldr r0, _080249E8 @ =gSharedMem + 0x17180\n\ + ldrh r0, [r0, 0x8]\n\ + b _08024A14\n\ + .align 2, 0\n\ +_080249E8: .4byte gSharedMem + 0x17180\n\ +_080249EC:\n\ + ldr r0, _080249F4 @ =gSharedMem + 0x17180\n\ + ldrh r0, [r0, 0x2]\n\ + b _08024A14\n\ + .align 2, 0\n\ +_080249F4: .4byte gSharedMem + 0x17180\n\ +_080249F8:\n\ + ldr r0, _08024A00 @ =gSharedMem + 0x17180\n\ + ldrh r0, [r0, 0xA]\n\ + b _08024A14\n\ + .align 2, 0\n\ +_08024A00: .4byte gSharedMem + 0x17180\n\ +_08024A04:\n\ + ldr r0, _08024A0C @ =gSharedMem + 0x17180\n\ + ldrh r0, [r0, 0x4]\n\ + b _08024A14\n\ + .align 2, 0\n\ +_08024A0C: .4byte gSharedMem + 0x17180\n\ +_08024A10:\n\ + ldr r0, _08024A54 @ =gSharedMem + 0x17180\n\ + ldrh r0, [r0, 0x6]\n\ +_08024A14:\n\ + subs r0, r1, r0\n\ + lsls r0, 16\n\ + lsrs r7, r0, 16\n\ +_08024A1A:\n\ + lsls r0, r7, 16\n\ + asrs r0, 16\n\ + cmp r0, 0\n\ + bge _08024A2C\n\ + negs r0, r0\n\ + lsls r0, 16\n\ + lsrs r7, r0, 16\n\ + movs r1, 0x1\n\ + add r9, r1\n\ +_08024A2C:\n\ + movs r0, 0xFC\n\ + strb r0, [r5]\n\ + movs r0, 0x13\n\ + strb r0, [r5, 0x1]\n\ + movs r1, 0x1\n\ + mov r2, r8\n\ + ands r1, r2\n\ + lsls r0, r1, 3\n\ + adds r0, r1\n\ + adds r0, 0x5\n\ + lsls r0, 3\n\ + adds r0, 0x6\n\ + strb r0, [r5, 0x2]\n\ + adds r5, 0x3\n\ + mov r0, r9\n\ + cmp r0, 0\n\ + beq _08024A5C\n\ + ldr r1, _08024A58 @ =BattleText_Dash\n\ + b _08024A5E\n\ + .align 2, 0\n\ +_08024A54: .4byte gSharedMem + 0x17180\n\ +_08024A58: .4byte BattleText_Dash\n\ +_08024A5C:\n\ + ldr r1, _08024AA4 @ =BattleText_Plus\n\ +_08024A5E:\n\ + adds r0, r5, 0\n\ + bl StringCopy\n\ + adds r5, r0, 0\n\ + movs r6, 0xFC\n\ + strb r6, [r5]\n\ + movs r4, 0x14\n\ + strb r4, [r5, 0x1]\n\ + movs r0, 0x6\n\ + strb r0, [r5, 0x2]\n\ + adds r5, 0x3\n\ + lsls r1, r7, 16\n\ + asrs r1, 16\n\ + adds r0, r5, 0\n\ + movs r2, 0x1\n\ + movs r3, 0x2\n\ + bl ConvertIntToDecimalStringN\n\ + adds r5, r0, 0\n\ + strb r6, [r5]\n\ + strb r4, [r5, 0x1]\n\ + movs r0, 0\n\ + strb r0, [r5, 0x2]\n\ + adds r5, 0x3\n\ + movs r0, 0x1\n\ + mov r1, r8\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + beq _08024AA8\n\ + movs r0, 0xFE\n\ + strb r0, [r5]\n\ + movs r0, 0xFF\n\ + strb r0, [r5, 0x1]\n\ + adds r5, 0x1\n\ + b _08024AB8\n\ + .align 2, 0\n\ +_08024AA4: .4byte BattleText_Plus\n\ +_08024AA8:\n\ + strb r6, [r5]\n\ + movs r0, 0x11\n\ + strb r0, [r5, 0x1]\n\ + movs r0, 0x8\n\ + strb r0, [r5, 0x2]\n\ + adds r5, 0x3\n\ + movs r0, 0xFF\n\ + strb r0, [r5]\n\ +_08024AB8:\n\ + movs r2, 0x1\n\ + add r8, r2\n\ + mov r0, r8\n\ + cmp r0, 0x5\n\ + bgt _08024AC4\n\ + b _0802495A\n\ +_08024AC4:\n\ + ldr r4, _08024AE4 @ =gUnknown_03004210\n\ + ldr r1, _08024AE8 @ =gStringVar4\n\ + adds r2, 0xFF\n\ + movs r0, 0x1\n\ + str r0, [sp]\n\ + adds r0, r4, 0\n\ + movs r3, 0xC\n\ + bl Text_InitWindow\n\ + adds r0, r4, 0\n\ + bl Text_PrintWindow8002F44\n\ + ldr r1, _08024AEC @ =gSharedMem\n\ + ldr r2, _08024AF0 @ =0x0001609c\n\ + adds r1, r2\n\ + b _08024BEA\n\ + .align 2, 0\n\ +_08024AE4: .4byte gUnknown_03004210\n\ +_08024AE8: .4byte gStringVar4\n\ +_08024AEC: .4byte gSharedMem\n\ +_08024AF0: .4byte 0x0001609c\n\ +_08024AF4:\n\ + ldr r0, _08024B94 @ =gMain\n\ + ldrh r0, [r0, 0x2E]\n\ + cmp r0, 0\n\ + bne _08024AFE\n\ + b _08024C38\n\ +_08024AFE:\n\ + movs r0, 0x5\n\ + bl PlaySE\n\ + ldr r0, _08024B98 @ =gStringVar4\n\ + ldr r1, _08024B9C @ =BattleText_Format2\n\ + bl StringCopy\n\ + adds r5, r0, 0\n\ + movs r0, 0\n\ + mov r8, r0\n\ + mov r9, r0\n\ + movs r6, 0xFC\n\ + movs r7, 0x14\n\ + ldr r1, _08024BA0 @ =0x00016018\n\ + add r10, r1\n\ +_08024B1C:\n\ + ldr r1, _08024BA4 @ =gUnknown_0840165C\n\ + mov r2, r8\n\ + lsls r0, r2, 2\n\ + adds r0, r1\n\ + ldr r1, [r0]\n\ + adds r0, r5, 0\n\ + bl StringAppend\n\ + adds r5, r0, 0\n\ + mov r0, r10\n\ + ldrb r1, [r0]\n\ + movs r0, 0x64\n\ + muls r0, r1\n\ + ldr r1, _08024BA8 @ =gPlayerParty\n\ + adds r0, r1\n\ + ldr r1, _08024BAC @ =gLevelUpStatBoxStats\n\ + add r1, r8\n\ + ldrb r1, [r1]\n\ + bl GetMonData\n\ + adds r1, r0, 0\n\ + strb r6, [r5]\n\ + movs r0, 0x13\n\ + strb r0, [r5, 0x1]\n\ + movs r4, 0x1\n\ + mov r2, r8\n\ + ands r4, r2\n\ + lsls r0, r4, 3\n\ + adds r0, r4\n\ + adds r0, 0x5\n\ + lsls r0, 3\n\ + adds r0, 0x6\n\ + strb r0, [r5, 0x2]\n\ + adds r5, 0x3\n\ + strb r6, [r5]\n\ + strb r7, [r5, 0x1]\n\ + movs r0, 0x6\n\ + strb r0, [r5, 0x2]\n\ + adds r5, 0x3\n\ + lsls r1, 16\n\ + asrs r1, 16\n\ + adds r0, r5, 0\n\ + movs r2, 0x1\n\ + movs r3, 0x3\n\ + bl ConvertIntToDecimalStringN\n\ + adds r5, r0, 0\n\ + strb r6, [r5]\n\ + strb r7, [r5, 0x1]\n\ + mov r0, r9\n\ + strb r0, [r5, 0x2]\n\ + adds r5, 0x3\n\ + cmp r4, 0\n\ + beq _08024BB0\n\ + movs r0, 0xFE\n\ + strb r0, [r5]\n\ + movs r0, 0xFF\n\ + strb r0, [r5, 0x1]\n\ + adds r5, 0x1\n\ + b _08024BC0\n\ + .align 2, 0\n\ +_08024B94: .4byte gMain\n\ +_08024B98: .4byte gStringVar4\n\ +_08024B9C: .4byte BattleText_Format2\n\ +_08024BA0: .4byte 0x00016018\n\ +_08024BA4: .4byte gUnknown_0840165C\n\ +_08024BA8: .4byte gPlayerParty\n\ +_08024BAC: .4byte gLevelUpStatBoxStats\n\ +_08024BB0:\n\ + strb r6, [r5]\n\ + movs r0, 0x11\n\ + strb r0, [r5, 0x1]\n\ + movs r0, 0x8\n\ + strb r0, [r5, 0x2]\n\ + adds r5, 0x3\n\ + movs r0, 0xFF\n\ + strb r0, [r5]\n\ +_08024BC0:\n\ + movs r1, 0x1\n\ + add r8, r1\n\ + mov r2, r8\n\ + cmp r2, 0x5\n\ + ble _08024B1C\n\ + ldr r4, _08024BF4 @ =gUnknown_03004210\n\ + ldr r1, _08024BF8 @ =gStringVar4\n\ + movs r2, 0x80\n\ + lsls r2, 1\n\ + movs r0, 0x1\n\ + str r0, [sp]\n\ + adds r0, r4, 0\n\ + movs r3, 0xC\n\ + bl Text_InitWindow\n\ + adds r0, r4, 0\n\ + bl Text_PrintWindow8002F44\n\ + ldr r1, _08024BFC @ =gSharedMem\n\ + ldr r0, _08024C00 @ =0x0001609c\n\ + adds r1, r0\n\ +_08024BEA:\n\ + ldrb r0, [r1]\n\ + adds r0, 0x1\n\ + strb r0, [r1]\n\ + b _08024C38\n\ + .align 2, 0\n\ +_08024BF4: .4byte gUnknown_03004210\n\ +_08024BF8: .4byte gStringVar4\n\ +_08024BFC: .4byte gSharedMem\n\ +_08024C00: .4byte 0x0001609c\n\ +_08024C04:\n\ + ldr r0, _08024C2C @ =gMain\n\ + ldrh r0, [r0, 0x2E]\n\ + cmp r0, 0\n\ + beq _08024C38\n\ + movs r0, 0x5\n\ + bl PlaySE\n\ + movs r0, 0x1\n\ + str r0, [sp]\n\ + movs r0, 0xB\n\ + movs r1, 0\n\ + movs r2, 0x1D\n\ + movs r3, 0x7\n\ + bl sub_802BBD4\n\ + ldrb r0, [r4]\n\ + adds r0, 0x1\n\ + strb r0, [r4]\n\ + b _08024C38\n\ + .align 2, 0\n\ +_08024C2C: .4byte gMain\n\ +_08024C30:\n\ + ldr r1, _08024C48 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x1\n\ + str r0, [r1]\n\ +_08024C38:\n\ + add sp, 0x4\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08024C48: .4byte gBattlescriptCurrInstr\n\ + .syntax divided"); +} + +#endif + +static void atk6D_resetsentmonsvalue(void) +{ + ResetSentPokesToOpponentValue(); + gBattlescriptCurrInstr++; +} + +static void atk6E_setatktoplayer0(void) +{ + gBankAttacker = GetBattlerAtPosition(0); + gBattlescriptCurrInstr++; +} + +static void atk6F_makevisible(void) +{ + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + EmitSpriteInvisibility(0, 0); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 2; +} + +static void atk70_recordlastability(void) +{ + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + RecordAbilityBattle(gActiveBattler, gLastUsedAbility); + gBattlescriptCurrInstr += 1; //buggy, should be += 2, one byte for command, one byte for argument... +} + +void sub_8024CEC(void) +{ + gBattleTextBuff2[0] = 0xFD; + gBattleTextBuff2[1] = 2; + gBattleTextBuff2[2] = (gMoveToLearn); + gBattleTextBuff2[3] = uBYTE1_16(gMoveToLearn); + gBattleTextBuff2[4] = 0xFF; +} + +static void atk71_buffermovetolearn(void) +{ + sub_8024CEC(); + gBattlescriptCurrInstr++; +} + +static void atk72_jumpifplayerran(void) +{ + if (TryRunFromBattle(gBank1)) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; +} + +static void atk73_hpthresholds(void) +{ + u8 opposing_bank; + s32 result; + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + opposing_bank = gActiveBattler ^ 1; + + result = gBattleMons[opposing_bank].hp * 100 / gBattleMons[opposing_bank].maxHP; + if (result == 0) + result = 1; + + if (result >= 70 || !gBattleMons[opposing_bank].hp) + gBattleStruct->hpScale = 0; + else if (result >= 40) + gBattleStruct->hpScale = 1; + else if (result >= 10) + gBattleStruct->hpScale = 2; + else + gBattleStruct->hpScale = 3; + } + + gBattlescriptCurrInstr += 2; +} + +static void atk74_hpthresholds2(void) +{ + u8 opposing_bank; + u8 hp_switchout; + s32 result; + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + opposing_bank = gActiveBattler ^ 1; + hp_switchout = ewram160BCarr(GetBattlerSide(opposing_bank)); //gBattleStruct->HP_OnSwitchout[GetBattlerSide(opposing_bank)]; + result = (hp_switchout - gBattleMons[opposing_bank].hp) * 100 / hp_switchout; + + if (gBattleMons[opposing_bank].hp >= hp_switchout) + gBattleStruct->hpScale = 0; + else if (result <= 29) + gBattleStruct->hpScale = 1; + else if (result <= 69) + gBattleStruct->hpScale = 2; + else + gBattleStruct->hpScale = 3; + } + + gBattlescriptCurrInstr += 2; +} + +static void atk75_useitemonopponent(void) +{ + gBankInMenu = gBankAttacker; + PokemonUseItemEffects(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker]], gLastUsedItem, gBattlerPartyIndexes[gBankAttacker], 0, 1); + gBattlescriptCurrInstr += 1; +} + +static void atk76_various(void) +{ + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + switch (T2_READ_8(gBattlescriptCurrInstr + 2)) + { + case 0: + CancelMultiTurnMoves(gActiveBattler); + break; + case 1: + { + u8 side; + gBankAttacker = gBankTarget; + side = GetBattlerSide(gBankAttacker) ^ 1; + if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp) + gBankTarget = gSideTimers[side].followmeTarget; + else + gBankTarget = gActiveBattler; + } + break; + case 2: + gBattleCommunication[0] = CanRunFromBattle(); + break; + case 3: + gBankTarget = GetMoveTarget(gCurrentMove, 0); + break; + case 4: + if (gHitMarker & HITMARKER_FAINTED(gActiveBattler)) + gBattleCommunication[0] = 1; + else + gBattleCommunication[0] = 0; + break; + case 5: + gSpecialStatuses[gActiveBattler].intimidatedPoke = 0; + gSpecialStatuses[gActiveBattler].traced = 0; + break; + case 6: + { + int i; + u16* choiced_move; + if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterID) + goto ACTIVE_0; + if (gBattlerPartyIndexes[2] != gBattleStruct->expGetterID) + break; + if (gBattlerPartyIndexes[0] == gBattlerPartyIndexes[2]) + { + ACTIVE_0: + gActiveBattler = 0; + } + else + gActiveBattler = 2; + + choiced_move = CHOICED_MOVE(gActiveBattler); + for (i = 0; i < 4; i++) + { + if (gBattleMons[gActiveBattler].moves[i] == *choiced_move) + break; + } + if (i == 4) + *choiced_move = 0; + } + break; + } + + gBattlescriptCurrInstr += 3; +} + +static void atk77_setprotectlike(void) //protect and endure +{ + bool8 not_last_turn = 1; + u16 last_move = gUnknown_02024C4C[gBankAttacker]; + + if (last_move != MOVE_PROTECT && last_move != MOVE_DETECT && last_move != MOVE_ENDURE) + gDisableStructs[gBankAttacker].protectUses = 0; + if (gCurrentTurnActionNumber == (gBattlersCount - 1)) + not_last_turn = 0; + + if (sProtectSuccessRates[gDisableStructs[gBankAttacker].protectUses] > Random() && not_last_turn) + { + if (gBattleMoves[gCurrentMove].effect == EFFECT_PROTECT) + { + gProtectStructs[gBankAttacker].protected = 1; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + if (gBattleMoves[gCurrentMove].effect == EFFECT_ENDURE) //what is else if + { + gProtectStructs[gBankAttacker].endured = 1; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + gDisableStructs[gBankAttacker].protectUses++; + } + else + { + gDisableStructs[gBankAttacker].protectUses = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + gMoveResultFlags |= MOVE_RESULT_MISSED; + } + + gBattlescriptCurrInstr++; +} + +static void atk78_faintifabilitynotdamp(void) +{ + if (gBattleExecBuffer) + return; + + for (gBankTarget = 0; gBankTarget < gBattlersCount; gBankTarget++) + { + if (gBattleMons[gBankTarget].ability == ABILITY_DAMP) + break; + } + + if (gBankTarget == gBattlersCount) + { + gActiveBattler = gBankAttacker; + gBattleMoveDamage = gBattleMons[gActiveBattler].hp; + EmitHealthBarUpdate(0, 0x7FFF); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr++; + + for (gBankTarget = 0; gBankTarget < gBattlersCount; gBankTarget++) + { + if (gBankTarget == gBankAttacker) + continue; + if (!(gAbsentBattlerFlags & gBitTable[gBankTarget])) + break; + } + } + else + { + gLastUsedAbility = ABILITY_DAMP; + RecordAbilityBattle(gBankTarget, gBattleMons[gBankTarget].ability); + gBattlescriptCurrInstr = BattleScript_DampStopsExplosion; + } +} + +static void atk79_setatkhptozero(void) +{ + if (gBattleExecBuffer) + return; + + gActiveBattler = gBankAttacker; + gBattleMons[gActiveBattler].hp = 0; + EmitSetMonData(0, REQUEST_HP_BATTLE, 0, 2, &gBattleMons[gActiveBattler].hp); + MarkBufferBankForExecution(gActiveBattler); + + gBattlescriptCurrInstr++; +} + +static void atk7A_jumpifnexttargetvalid(void) //used by intimidate to loop through all targets +{ + u8* jump_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + for (gBankTarget++; ; gBankTarget++) + { + if (gBankTarget == gBankAttacker) + continue; + if (!(gAbsentBattlerFlags & gBitTable[gBankTarget])) + break; + } + + if (gBankTarget >= gBattlersCount) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = jump_loc; + } + else + gBattlescriptCurrInstr += 5; +} + +static void atk7B_tryhealhalfhealth(void) +{ + u8* fail_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); + + if (T2_READ_8(gBattlescriptCurrInstr + 5) == 1) + gBankTarget = gBankAttacker; + + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + + if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) + gBattlescriptCurrInstr = fail_loc; + else + gBattlescriptCurrInstr += 6; +} + +static void atk7C_trymirrormove(void) +{ + u16 r7 = ewram160ACarr2(0, gBankAttacker) | (ewram160ACarr2(1, gBankAttacker) << 8); + u16 r6 = ewram16100arr2(0, gBankAttacker) | (ewram16100arr2(1, gBankAttacker) << 8); + u16 r5 = ewram16100arr2(2, gBankAttacker) | (ewram16100arr2(3, gBankAttacker) << 8); + + if (r7 != 0 && r7 != 0xFFFF) + { + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gCurrentMove = r7; + gBankTarget = GetMoveTarget(gCurrentMove, 0); + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + } + else if (r6 != 0 && r5 != 0 && r6 != 0xFFFF && r5 != 0xFFFF) + { + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + if (Random() & 1) + gCurrentMove = r6; + else + gCurrentMove = r5; + gBankTarget = GetMoveTarget(gCurrentMove, 0); + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + } + else if (r6 != 0 && r6 != 0xFFFF) + { + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gCurrentMove = r6; + gBankTarget = GetMoveTarget(gCurrentMove, 0); + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + } + else if (r5 != 0 && r5 != 0xFFFF) + { + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gCurrentMove = r5; + gBankTarget = GetMoveTarget(gCurrentMove, 0); + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + } + else + { + gSpecialStatuses[gBankAttacker].flag20 = 1; + gBattlescriptCurrInstr++; + } +} + +static void atk7D_setrain(void) +{ + if (gBattleWeather & WEATHER_RAIN_ANY) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gBattleWeather = WEATHER_RAIN_TEMPORARY; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gWishFutureKnock.weatherDuration = 5; + } + gBattlescriptCurrInstr++; +} + +static void atk7E_setreflect(void) +{ + if (gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] & SIDE_STATUS_REFLECT) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else + { + gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] |= SIDE_STATUS_REFLECT; + gSideTimers[GetBattlerPosition(gBankAttacker) & 1].reflectTimer = 5; + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMons(1) == 2) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + gBattlescriptCurrInstr++; +} + +static void atk7F_setseeded(void) +{ + if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT || gStatuses3[gBankTarget] & STATUS3_LEECHSEED) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else if (gBattleMons[gBankTarget].type1 == TYPE_GRASS || gBattleMons[gBankTarget].type2 == TYPE_GRASS) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gStatuses3[gBankTarget] |= gBankAttacker; + gStatuses3[gBankTarget] |= STATUS3_LEECHSEED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + + gBattlescriptCurrInstr++; +} + +static void atk80_manipulatedamage(void) +{ + switch (T2_READ_8(gBattlescriptCurrInstr + 1)) + { + case 0: + gBattleMoveDamage *= -1; + break; + case 1: + gBattleMoveDamage /= 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if ((gBattleMons[gBankTarget].maxHP / 2) < gBattleMoveDamage) + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; + break; + case 2: + gBattleMoveDamage *= 2; + break; + } + + gBattlescriptCurrInstr += 2; +} + +static void atk81_trysetrest(void) +{ + u8* fail_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gActiveBattler = gBankTarget = gBankAttacker; + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP * (-1); + if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) + gBattlescriptCurrInstr = fail_loc; + else + { + if (gBattleMons[gBankTarget].status1 & ((u8)(~STATUS_SLEEP))) + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + + gBattleMons[gBankTarget].status1 = 3; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 5; + } +} + +static void atk82_jumpifnotfirstturn(void) +{ + u8* jump_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); + + if (gDisableStructs[gBankAttacker].isFirstTurn) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = jump_loc; +} + +static void atk83_nop(void) +{ + gBattlescriptCurrInstr++; +} + +bool8 UproarWakeUpCheck(u8 bank) +{ + int i; + for (i = 0; i < gBattlersCount; i++) + { + if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || gBattleMons[bank].ability == ABILITY_SOUNDPROOF) //wtf gamefreak, you should check this only once, not every time in a loop... + continue; + gBattleStruct->scriptingActive = i; + if (gBankTarget == 0xFF) + gBankTarget = i; + else if (gBankTarget == i) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + break; + } + if (i == gBattlersCount) + return 0; + else + return 1; +} + +static void atk84_jumpifcantmakeasleep(void) +{ + u8* jump_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); + if (UproarWakeUpCheck(gBankTarget)) + gBattlescriptCurrInstr = jump_loc; + else if (gBattleMons[gBankTarget].ability == ABILITY_INSOMNIA || gBattleMons[gBankTarget].ability == ABILITY_VITAL_SPIRIT) + { + gLastUsedAbility = gBattleMons[gBankTarget].ability; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + gBattlescriptCurrInstr = jump_loc; + RecordAbilityBattle(gBankTarget, gLastUsedAbility); + } + else + { + gBattlescriptCurrInstr += 5; + } +} + +static void atk85_stockpile(void) +{ + if (gDisableStructs[gBankAttacker].stockpileCounter == 3) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gDisableStructs[gBankAttacker].stockpileCounter++; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 1; + gBattleTextBuff1[2] = 1; + gBattleTextBuff1[3] = 1; + gBattleTextBuff1[4] = gDisableStructs[gBankAttacker].stockpileCounter; + gBattleTextBuff1[5] = 0xFF; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + gBattlescriptCurrInstr++; +} + +static void atk86_stockpiletobasedamage(void) +{ + u8* jump_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); + if (gDisableStructs[gBankAttacker].stockpileCounter == 0) + { + gBattlescriptCurrInstr = jump_loc; + } + else + { + if (gBattleCommunication[6] != 1) + { + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, + gSideAffecting[GetBattlerPosition(gBankTarget) & 1], 0, + 0, gBankAttacker, gBankTarget) + * gDisableStructs[gBankAttacker].stockpileCounter; + gBattleStruct->animTurn = gDisableStructs[gBankAttacker].stockpileCounter; + + if (gProtectStructs[gBankAttacker].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; + } + gDisableStructs[gBankAttacker].stockpileCounter = 0; + gBattlescriptCurrInstr += 5; + } +} + +static void atk87_stockpiletohpheal(void) +{ + u8* jump_loc = T1_READ_PTR(gBattlescriptCurrInstr + 1); + if (gDisableStructs[gBankAttacker].stockpileCounter == 0) + { + gBattlescriptCurrInstr = jump_loc; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else if (gBattleMons[gBankAttacker].maxHP == gBattleMons[gBankAttacker].hp) + { + gDisableStructs[gBankAttacker].stockpileCounter = 0; + gBattlescriptCurrInstr = jump_loc; + gBankTarget = gBankAttacker; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / (1 << (3 - gDisableStructs[gBankAttacker].stockpileCounter)); + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + gBattleStruct->animTurn = gDisableStructs[gBankAttacker].stockpileCounter; + gDisableStructs[gBankAttacker].stockpileCounter = 0; + gBattlescriptCurrInstr += 5; + gBankTarget = gBankAttacker; + } +} + +static void atk88_negativedamage(void) +{ + gBattleMoveDamage = -(gHpDealt / 2); + if (gBattleMoveDamage == 0) + gBattleMoveDamage = -1; + gBattlescriptCurrInstr++; +} + +static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8 *BS_ptr) +{ + bool8 certain = FALSE; + bool8 notProtectAffected = FALSE; + u32 index; + + if (flags & MOVE_EFFECT_AFFECTS_USER) + gActiveBattler = gBankAttacker; + else + gActiveBattler = gBankTarget; + + flags &= ~(MOVE_EFFECT_AFFECTS_USER); + + if (flags & MOVE_EFFECT_CERTAIN) + certain++; + flags &= ~(MOVE_EFFECT_CERTAIN); + + if (flags & STAT_CHANGE_NOT_PROTECT_AFFECTED) + notProtectAffected++; + flags &= ~(STAT_CHANGE_NOT_PROTECT_AFFECTED); + + PREPARE_STAT_BUFFER(gBattleTextBuff1, statId) + + if ((statValue << 0x18) < 0) // stat decrease + { + if (gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].mistTimer + && !certain && gCurrentMove != MOVE_CURSE) + { + if (flags == STAT_CHANGE_BS_PTR) + { + if (gSpecialStatuses[gActiveBattler].statLowered) + { + gBattlescriptCurrInstr = BS_ptr; + } + else + { + BattleScriptPush(BS_ptr); + gBattleStruct->scriptingActive = gActiveBattler; + gBattlescriptCurrInstr = BattleScript_MistProtected; + gSpecialStatuses[gActiveBattler].statLowered = 1; + } + } + return STAT_CHANGE_DIDNT_WORK; + } + else if (gCurrentMove != MOVE_CURSE + && notProtectAffected != TRUE && JumpIfMoveAffectedByProtect(0)) + { + gBattlescriptCurrInstr = BattleScript_ButItFailed; + return STAT_CHANGE_DIDNT_WORK; + } + else if ((gBattleMons[gActiveBattler].ability == ABILITY_CLEAR_BODY + || gBattleMons[gActiveBattler].ability == ABILITY_WHITE_SMOKE) + && !certain && gCurrentMove != MOVE_CURSE) + { + if (flags == STAT_CHANGE_BS_PTR) + { + if (gSpecialStatuses[gActiveBattler].statLowered) + { + gBattlescriptCurrInstr = BS_ptr; + } + else + { + BattleScriptPush(BS_ptr); + gBattleStruct->scriptingActive = gActiveBattler; + gBattlescriptCurrInstr = BattleScript_AbilityNoStatLoss; + gLastUsedAbility = gBattleMons[gActiveBattler].ability; + RecordAbilityBattle(gActiveBattler, gLastUsedAbility); + gSpecialStatuses[gActiveBattler].statLowered = 1; + } + } + return STAT_CHANGE_DIDNT_WORK; + } + else if (gBattleMons[gActiveBattler].ability == ABILITY_KEEN_EYE + && !certain && statId == STAT_STAGE_ACC) + { + if (flags == STAT_CHANGE_BS_PTR) + { + BattleScriptPush(BS_ptr); + gBattleStruct->scriptingActive = gActiveBattler; + gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss; + gLastUsedAbility = gBattleMons[gActiveBattler].ability; + RecordAbilityBattle(gActiveBattler, gLastUsedAbility); + } + return STAT_CHANGE_DIDNT_WORK; + } + else if (gBattleMons[gActiveBattler].ability == ABILITY_HYPER_CUTTER + && !certain && statId == STAT_STAGE_ATK) + { + if (flags == STAT_CHANGE_BS_PTR) + { + BattleScriptPush(BS_ptr); + gBattleStruct->scriptingActive = gActiveBattler; + gBattlescriptCurrInstr = BattleScript_AbilityNoSpecificStatLoss; + gLastUsedAbility = gBattleMons[gActiveBattler].ability; + RecordAbilityBattle(gActiveBattler, gLastUsedAbility); + } + return STAT_CHANGE_DIDNT_WORK; + } + else if (gBattleMons[gActiveBattler].ability == ABILITY_SHIELD_DUST && flags == 0) + { + return STAT_CHANGE_DIDNT_WORK; + } + else // try to decrease + { + statValue = -GET_STAT_BUFF_VALUE(statValue); + gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; + index = 1; + if (statValue == -2) + { + gBattleTextBuff2[1] = B_BUFF_STRING; + gBattleTextBuff2[2] = STRINGID_STATHARSHLY; + gBattleTextBuff2[3] = STRINGID_STATHARSHLY >> 8; + index = 4; + } + gBattleTextBuff2[index] = B_BUFF_STRING; + index++; + gBattleTextBuff2[index] = STRINGID_STATFELL; + index++; + gBattleTextBuff2[index] = STRINGID_STATFELL >> 8; + index++; + gBattleTextBuff2[index] = B_BUFF_EOS; + + if (gBattleMons[gActiveBattler].statStages[statId] == 0) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + else + gBattleCommunication[MULTISTRING_CHOOSER] = (gBankTarget == gActiveBattler); + + } + } + else // stat increase + { + statValue = GET_STAT_BUFF_VALUE(statValue); + gBattleTextBuff2[0] = B_BUFF_PLACEHOLDER_BEGIN; + index = 1; + if (statValue == 2) + { + gBattleTextBuff2[1] = B_BUFF_STRING; + gBattleTextBuff2[2] = STRINGID_STATSHARPLY; + gBattleTextBuff2[3] = STRINGID_STATSHARPLY >> 8; + index = 4; + } + gBattleTextBuff2[index] = B_BUFF_STRING; + index++; + gBattleTextBuff2[index] = STRINGID_STATROSE; + index++; + gBattleTextBuff2[index] = STRINGID_STATROSE >> 8; + index++; + gBattleTextBuff2[index] = B_BUFF_EOS; + + if (gBattleMons[gActiveBattler].statStages[statId] == 0xC) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + else + gBattleCommunication[MULTISTRING_CHOOSER] = (gBankTarget == gActiveBattler); + } + + gBattleMons[gActiveBattler].statStages[statId] += statValue; + if (gBattleMons[gActiveBattler].statStages[statId] < 0) + gBattleMons[gActiveBattler].statStages[statId] = 0; + if (gBattleMons[gActiveBattler].statStages[statId] > 0xC) + gBattleMons[gActiveBattler].statStages[statId] = 0xC; + + if (gBattleCommunication[MULTISTRING_CHOOSER] == 2 && flags & STAT_CHANGE_BS_PTR) + gMoveResultFlags |= MOVE_RESULT_MISSED; + + if (gBattleCommunication[MULTISTRING_CHOOSER] == 2 && !(flags & STAT_CHANGE_BS_PTR)) + return STAT_CHANGE_DIDNT_WORK; + + return STAT_CHANGE_WORKED; +} + +static void atk89_statbuffchange(void) +{ + u8* jump_loc = T1_READ_PTR(gBattlescriptCurrInstr + 2); + if (ChangeStatBuffs(gBattleStruct->statChanger & 0xF0, gBattleStruct->statChanger & 0xF, T2_READ_8(gBattlescriptCurrInstr + 1), jump_loc) == 0) + gBattlescriptCurrInstr += 6; +} + +static void atk8A_normalisebuffs(void) //haze +{ + int i, j; + for (i = 0; i < gBattlersCount; i++) + { + for (j = 0; j < 8; j++) + { + gBattleMons[i].statStages[j] = 6; + } + } + gBattlescriptCurrInstr++; +} + +static void atk8B_setbide(void) +{ + gBattleMons[gBankAttacker].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gBankAttacker] = gCurrentMove; + gTakenDmg[gBankAttacker] = 0; + gBattleMons[gBankAttacker].status2 |= (STATUS2_BIDE - 0x100); //2 turns + gBattlescriptCurrInstr++; +} + +static void atk8C_confuseifrepeatingattackends(void) +{ + if (!(gBattleMons[gBankAttacker].status2 & STATUS2_LOCK_CONFUSE)) + gBattleCommunication[MOVE_EFFECT_BYTE] = 0x75; + gBattlescriptCurrInstr++; +} + +static void atk8D_setmultihitcounter(void) +{ + if (T2_READ_8(gBattlescriptCurrInstr + 1)) + gMultiHitCounter = T2_READ_8(gBattlescriptCurrInstr + 1); + else + { + gMultiHitCounter = Random() & 3; + if (gMultiHitCounter > 1) + gMultiHitCounter = (Random() & 3) + 2; + else + gMultiHitCounter += 2; + } + gBattlescriptCurrInstr += 2; +} + +static void atk8E_initmultihitstring(void) +{ + ewram160E0(0) = 0xFD; + ewram160E0(1) = 1; + ewram160E0(2) = 1; + ewram160E0(3) = 1; + ewram160E0(4) = 0; + ewram160E0(5) = 0xFF; + gBattlescriptCurrInstr++; +} + +static bool8 sub_80264C0(void) +{ + if (gBattleMons[gBankAttacker].level >= gBattleMons[gBankTarget].level) + { + ewram16064arr(gBankTarget) = gBattlerPartyIndexes[gBankTarget]; + } + else + { + u16 random = Random() & 0xFF; + if ((u32)((random * (gBattleMons[gBankAttacker].level + gBattleMons[gBankTarget].level) >> 8) + 1) <= (gBattleMons[gBankTarget].level / 4)) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + return 0; + } + ewram16064arr(gBankTarget) = gBattlerPartyIndexes[gBankTarget]; + } + gBattlescriptCurrInstr = BattleScript_SuccessForceOut; + return 1; +} + +static void atk8F_forcerandomswitch(void) +{ + if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER)) + { + u8 i; + struct Pokemon* party; + u8 valid; + u8 val; + if (!GetBattlerSide(gBankTarget)) + party = gPlayerParty; + else + party = gEnemyParty; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + valid = 0; + val = 0; + if (sub_803FBFC(sub_803FC34(gBankTarget)) == 1) + val = 3; + for (i = val; i < val + 3; i++) + { + if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[i], MON_DATA_IS_EGG) + && GetMonData(&party[i], MON_DATA_HP) != 0) + valid++; + } + } + else + { + valid = 0; + for (i = 0; i < 6; i++) + { + if (GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE + && !GetMonData(&party[i], MON_DATA_IS_EGG) + && GetMonData(&party[i], MON_DATA_HP) != 0) + valid++; + } + } + + if ((valid < 2 && (gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_MULTI)) != BATTLE_TYPE_DOUBLE) + || (valid < 3 && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else if (sub_80264C0()) + { +#define MON_CAN_BATTLE(mon) (((GetMonData(mon, MON_DATA_SPECIES) && GetMonData(mon, MON_DATA_IS_EGG) != 1 && GetMonData(mon, MON_DATA_HP)))) + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + do + { + val = Random() % 3; + if (sub_803FBFC(sub_803FC34(gBankTarget)) == 1) + i = val + 3; + else + i = val; + } while (i == gBattlerPartyIndexes[gBankTarget] || i == gBattlerPartyIndexes[gBankTarget ^ 2] || !MON_CAN_BATTLE(&party[i])); + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + do + { + i = Random() % 6; + } while (i == gBattlerPartyIndexes[gBankTarget] || i == gBattlerPartyIndexes[gBankTarget ^ 2] || !MON_CAN_BATTLE(&party[i])); + } + else + { + do + { + i = Random() % 6; + } while (i == gBattlerPartyIndexes[gBankTarget] || !MON_CAN_BATTLE(&party[i])); + } + } + ewram16068arr(gBankTarget) = i; + if (!IsLinkDoubleBattle()) + sub_8012258(gBankTarget); + sub_8094B6C(gBankTarget, i, 0); + sub_8094B6C(gBankTarget ^ 2, i, 1); +#undef MON_CAN_BATTLE + } + } + else + { + sub_80264C0(); + } +} + +static void atk90_tryconversiontypechange(void) +{ + //randomly changes user's type to one of its moves' type + u8 valid_moves = 0; + u8 checked_move; + u8 move_type; + while (valid_moves < 4) + { + if (gBattleMons[gBankAttacker].moves[valid_moves] == 0) + break; + valid_moves++; + } + + for (checked_move = 0; checked_move < valid_moves; checked_move++) + { + move_type = gBattleMoves[gBattleMons[gBankAttacker].moves[checked_move]].type; + if (move_type == TYPE_MYSTERY) + { + if (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST) + move_type = TYPE_GHOST; + else + move_type = TYPE_NORMAL; + } + if (move_type != gBattleMons[gBankAttacker].type1 && move_type != gBattleMons[gBankAttacker].type2) + break; + } + + if (checked_move == valid_moves) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else + { + do + { + + while ((checked_move = Random() & 3) >= valid_moves); + + move_type = gBattleMoves[gBattleMons[gBankAttacker].moves[checked_move]].type; + if (move_type == TYPE_MYSTERY) + { + if (gBattleMons[gBankAttacker].type1 == TYPE_GHOST || gBattleMons[gBankAttacker].type2 == TYPE_GHOST) + move_type = TYPE_GHOST; + else + move_type = TYPE_NORMAL; + } + } while (move_type == gBattleMons[gBankAttacker].type1 || move_type == gBattleMons[gBankAttacker].type2); + + gBattleMons[gBankAttacker].type1 = move_type; + gBattleMons[gBankAttacker].type2 = move_type; + + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 3; + gBattleTextBuff1[2] = move_type; + gBattleTextBuff1[3] = 0xFF; + + gBattlescriptCurrInstr += 5; + } +} + +static void atk91_givepaydaymoney(void) +{ + if (!(gBattleTypeFlags & BATTLE_TYPE_LINK) && gPaydayMoney) + { + AddMoney(&gSaveBlock1.money, gPaydayMoney * gBattleStruct->moneyMultiplier); + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 1; + gBattleTextBuff1[2] = 2; + gBattleTextBuff1[3] = 5; + gBattleTextBuff1[4] = gPaydayMoney; + gBattleTextBuff1[5] = uBYTE1_16(gPaydayMoney); + gBattleTextBuff1[6] = 0xFF; + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_PrintPayDayMoneyString; + } + else + gBattlescriptCurrInstr++; +} + +static void atk92_setlightscreen(void) +{ + if (gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] & SIDE_STATUS_LIGHTSCREEN) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else + { + gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] |= SIDE_STATUS_LIGHTSCREEN; + gSideTimers[GetBattlerPosition(gBankAttacker) & 1].lightscreenTimer = 5; + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMons(1) == 2) + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 3; + } + gBattlescriptCurrInstr++; +} + +#ifdef NOTMATCHING +static void atk93_tryKO(void) +{ + if (gBattleMons[gBankTarget].item == ITEM_ENIGMA_BERRY) + hold_effect = gEnigmaBerries[gBankTarget].holdEffect, quality = gEnigmaBerries[gBankTarget].holdEffectParam; + else + { + hold_effect = ItemId_GetHoldEffect(gBattleMons[gBankTarget].item); + quality = ItemId_GetHoldEffectParam(gBattleMons[gBankTarget].item); + } + + gStringBank = gBankTarget; + + if (hold_effect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < quality) + { + RecordItemBattle(gBankTarget, hold_effect); + gSpecialStatuses[gBankTarget].focusBanded = 1; + } + + if (gBattleMons[gBankTarget].ability == ABILITY_STURDY) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + gLastUsedAbility = ABILITY_STURDY; + gBattlescriptCurrInstr = x; + RecordAbilityBattle(gBankTarget, ABILITY_STURDY); + return; + } + + if (!(gStatuses3[gBankTarget] & STATUS3_ALWAYS_HITS)) + { + u16 to_cmp = gBattleMons[gBankAttacker].level - gBattleMons[gBankTarget].level + gBattleMoves[gCurrentMove].accuracy; + if (Random() % 0x64 + 1 < to_cmp || gBattleMons[gBankAttacker].level < gBattleMons[gBankTarget].level) + { + goto MOVE_RESULT_MISSED_LABEL; + } + } + else + { + if (gDisableStructs[gBankTarget].bankWithSureHit != gBankAttacker || gBattleMons[gBankAttacker].level < gBattleMons[gBankTarget].level) + { + + } + } + +MOVE_RESULT_MISSED_LABEL: + gBattleTypeFlags |= MOVE_RESULT_MISSED; + if (gBattleMons[gBankAttacker].level < gBattleMons[gBankTarget].level) + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +#else +__attribute((naked)) +static void atk93_tryKO(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + ldr r7, _08026BA8 @ =gBattleMons\n\ + ldr r6, _08026BAC @ =gBankTarget\n\ + ldrb r2, [r6]\n\ + movs r5, 0x58\n\ + adds r0, r2, 0\n\ + muls r0, r5\n\ + adds r1, r0, r7\n\ + ldrh r0, [r1, 0x2E]\n\ + cmp r0, 0xAF\n\ + bne _08026BB4\n\ + ldr r1, _08026BB0 @ =gEnigmaBerries\n\ + lsls r0, r2, 3\n\ + subs r0, r2\n\ + lsls r0, 2\n\ + adds r0, r1\n\ + ldrb r4, [r0, 0x7]\n\ + ldrb r6, [r0, 0x1A]\n\ + b _08026BCE\n\ + .align 2, 0\n\ +_08026BA8: .4byte gBattleMons\n\ +_08026BAC: .4byte gBankTarget\n\ +_08026BB0: .4byte gEnigmaBerries\n\ +_08026BB4:\n\ + ldrh r0, [r1, 0x2E]\n\ + bl ItemId_GetHoldEffect\n\ + lsls r0, 24\n\ + lsrs r4, r0, 24\n\ + ldrb r0, [r6]\n\ + muls r0, r5\n\ + adds r0, r7\n\ + ldrh r0, [r0, 0x2E]\n\ + bl ItemId_GetHoldEffectParam\n\ + lsls r0, 24\n\ + lsrs r6, r0, 24\n\ +_08026BCE:\n\ + ldr r1, _08026C4C @ =gStringBank\n\ + ldr r5, _08026C50 @ =gBankTarget\n\ + ldrb r0, [r5]\n\ + strb r0, [r1]\n\ + cmp r4, 0x27\n\ + bne _08026C0C\n\ + bl Random\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0x64\n\ + bl __umodsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r0, r6\n\ + bcs _08026C0C\n\ + ldrb r0, [r5]\n\ + movs r1, 0x27\n\ + bl RecordItemBattle\n\ + ldr r2, _08026C54 @ =gSpecialStatuses\n\ + ldrb r1, [r5]\n\ + lsls r0, r1, 2\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r1, [r0]\n\ + movs r2, 0x80\n\ + orrs r1, r2\n\ + strb r1, [r0]\n\ +_08026C0C:\n\ + ldr r0, _08026C58 @ =gBattleMons\n\ + mov r8, r0\n\ + ldr r1, _08026C50 @ =gBankTarget\n\ + ldrb r2, [r1]\n\ + movs r6, 0x58\n\ + adds r0, r2, 0\n\ + muls r0, r6\n\ + mov r3, r8\n\ + adds r5, r0, r3\n\ + adds r0, r5, 0\n\ + adds r0, 0x20\n\ + ldrb r3, [r0]\n\ + mov r10, r8\n\ + cmp r3, 0x5\n\ + bne _08026C6C\n\ + ldr r2, _08026C5C @ =gMoveResultFlags\n\ + ldrb r0, [r2]\n\ + movs r1, 0x1\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + ldr r0, _08026C60 @ =gLastUsedAbility\n\ + strb r3, [r0]\n\ + ldr r1, _08026C64 @ =gBattlescriptCurrInstr\n\ + ldr r0, _08026C68 @ =BattleScript_SturdyPreventsOHKO\n\ + str r0, [r1]\n\ + ldr r1, _08026C50 @ =gBankTarget\n\ + ldrb r0, [r1]\n\ + movs r1, 0x5\n\ + bl RecordAbilityBattle\n\ + b _08026E40\n\ + .align 2, 0\n\ +_08026C4C: .4byte gStringBank\n\ +_08026C50: .4byte gBankTarget\n\ +_08026C54: .4byte gSpecialStatuses\n\ +_08026C58: .4byte gBattleMons\n\ +_08026C5C: .4byte gMoveResultFlags\n\ +_08026C60: .4byte gLastUsedAbility\n\ +_08026C64: .4byte gBattlescriptCurrInstr\n\ +_08026C68: .4byte BattleScript_SturdyPreventsOHKO\n\ +_08026C6C:\n\ + ldr r1, _08026CE0 @ =gStatuses3\n\ + lsls r0, r2, 2\n\ + adds r0, r1\n\ + ldr r0, [r0]\n\ + movs r1, 0x18\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _08026CF4\n\ + ldr r1, _08026CE4 @ =gBattleMoves\n\ + ldr r0, _08026CE8 @ =gCurrentMove\n\ + ldrh r0, [r0]\n\ + lsls r2, r0, 1\n\ + adds r2, r0\n\ + lsls r2, 2\n\ + adds r2, r1\n\ + ldr r7, _08026CEC @ =gBankAttacker\n\ + ldrb r0, [r7]\n\ + muls r0, r6\n\ + add r0, r10\n\ + adds r0, 0x2A\n\ + ldrb r0, [r0]\n\ + adds r1, r5, 0\n\ + adds r1, 0x2A\n\ + ldrb r1, [r1]\n\ + subs r0, r1\n\ + ldrb r2, [r2, 0x3]\n\ + adds r0, r2\n\ + lsls r0, 16\n\ + lsrs r4, r0, 16\n\ + bl Random\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + movs r1, 0x64\n\ + bl __umodsi3\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + adds r0, 0x1\n\ + cmp r0, r4\n\ + bge _08026CDC\n\ + ldrb r0, [r7]\n\ + adds r1, r0, 0\n\ + muls r1, r6\n\ + add r1, r10\n\ + adds r1, 0x2A\n\ + ldr r2, _08026CF0 @ =gBankTarget\n\ + ldrb r0, [r2]\n\ + muls r0, r6\n\ + add r0, r10\n\ + adds r0, 0x2A\n\ + ldrb r1, [r1]\n\ + movs r4, 0x1\n\ + ldrb r0, [r0]\n\ + cmp r1, r0\n\ + bcs _08026D20\n\ +_08026CDC:\n\ + mov r10, r8\n\ + b _08026DE0\n\ + .align 2, 0\n\ +_08026CE0: .4byte gStatuses3\n\ +_08026CE4: .4byte gBattleMoves\n\ +_08026CE8: .4byte gCurrentMove\n\ +_08026CEC: .4byte gBankAttacker\n\ +_08026CF0: .4byte gBankTarget\n\ +_08026CF4:\n\ + ldr r0, _08026D4C @ =gDisableStructs\n\ + lsls r1, r2, 3\n\ + subs r1, r2\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + ldr r2, _08026D50 @ =gBankAttacker\n\ + ldrb r0, [r1, 0x15]\n\ + movs r4, 0\n\ + ldrb r3, [r2]\n\ + cmp r0, r3\n\ + bne _08026D20\n\ + ldrb r0, [r2]\n\ + muls r0, r6\n\ + add r0, r10\n\ + adds r0, 0x2A\n\ + adds r1, r5, 0\n\ + adds r1, 0x2A\n\ + ldrb r0, [r0]\n\ + ldrb r1, [r1]\n\ + cmp r0, r1\n\ + bcc _08026D20\n\ + movs r4, 0x1\n\ +_08026D20:\n\ + cmp r4, 0\n\ + beq _08026DE0\n\ + ldr r0, _08026D54 @ =gProtectStructs\n\ + ldr r1, _08026D58 @ =gBankTarget\n\ + ldrb r2, [r1]\n\ + lsls r1, r2, 4\n\ + adds r1, r0\n\ + ldrb r0, [r1]\n\ + lsls r0, 30\n\ + cmp r0, 0\n\ + bge _08026D64\n\ + ldr r1, _08026D5C @ =gBattleMoveDamage\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + add r0, r10\n\ + ldrh r0, [r0, 0x28]\n\ + subs r0, 0x1\n\ + str r0, [r1]\n\ + ldr r2, _08026D60 @ =gMoveResultFlags\n\ + ldrb r0, [r2]\n\ + movs r1, 0x40\n\ + b _08026DC6\n\ + .align 2, 0\n\ +_08026D4C: .4byte gDisableStructs\n\ +_08026D50: .4byte gBankAttacker\n\ +_08026D54: .4byte gProtectStructs\n\ +_08026D58: .4byte gBankTarget\n\ +_08026D5C: .4byte gBattleMoveDamage\n\ +_08026D60: .4byte gMoveResultFlags\n\ +_08026D64:\n\ + ldr r0, _08026DA0 @ =gSpecialStatuses\n\ + lsls r1, r2, 2\n\ + adds r1, r2\n\ + lsls r1, 2\n\ + adds r1, r0\n\ + ldrb r0, [r1]\n\ + lsrs r0, 7\n\ + cmp r0, 0\n\ + beq _08026DB4\n\ + ldr r1, _08026DA4 @ =gBattleMoveDamage\n\ + movs r3, 0x58\n\ + adds r0, r2, 0\n\ + muls r0, r3\n\ + add r0, r10\n\ + ldrh r0, [r0, 0x28]\n\ + subs r0, 0x1\n\ + str r0, [r1]\n\ + ldr r2, _08026DA8 @ =gMoveResultFlags\n\ + ldrb r0, [r2]\n\ + movs r1, 0x80\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + ldr r1, _08026DAC @ =gLastUsedItem\n\ + ldr r2, _08026DB0 @ =gBankTarget\n\ + ldrb r0, [r2]\n\ + muls r0, r3\n\ + add r0, r10\n\ + ldrh r0, [r0, 0x2E]\n\ + strh r0, [r1]\n\ + b _08026DCA\n\ + .align 2, 0\n\ +_08026DA0: .4byte gSpecialStatuses\n\ +_08026DA4: .4byte gBattleMoveDamage\n\ +_08026DA8: .4byte gMoveResultFlags\n\ +_08026DAC: .4byte gLastUsedItem\n\ +_08026DB0: .4byte gBankTarget\n\ +_08026DB4:\n\ + ldr r1, _08026DD4 @ =gBattleMoveDamage\n\ + movs r0, 0x58\n\ + muls r0, r2\n\ + add r0, r10\n\ + ldrh r0, [r0, 0x28]\n\ + str r0, [r1]\n\ + ldr r2, _08026DD8 @ =gMoveResultFlags\n\ + ldrb r0, [r2]\n\ + movs r1, 0x10\n\ +_08026DC6:\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ +_08026DCA:\n\ + ldr r1, _08026DDC @ =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x5\n\ + str r0, [r1]\n\ + b _08026E40\n\ + .align 2, 0\n\ +_08026DD4: .4byte gBattleMoveDamage\n\ +_08026DD8: .4byte gMoveResultFlags\n\ +_08026DDC: .4byte gBattlescriptCurrInstr\n\ +_08026DE0:\n\ + ldr r2, _08026E10 @ =gMoveResultFlags\n\ + ldrb r0, [r2]\n\ + movs r1, 0x1\n\ + orrs r0, r1\n\ + strb r0, [r2]\n\ + ldr r0, _08026E14 @ =gBankAttacker\n\ + ldrb r0, [r0]\n\ + movs r2, 0x58\n\ + adds r1, r0, 0\n\ + muls r1, r2\n\ + add r1, r10\n\ + adds r1, 0x2A\n\ + ldr r3, _08026E18 @ =gBankTarget\n\ + ldrb r0, [r3]\n\ + muls r0, r2\n\ + add r0, r10\n\ + adds r0, 0x2A\n\ + ldrb r1, [r1]\n\ + ldrb r0, [r0]\n\ + cmp r1, r0\n\ + bcc _08026E20\n\ + ldr r1, _08026E1C @ =gBattleCommunication\n\ + movs r0, 0\n\ + b _08026E24\n\ + .align 2, 0\n\ +_08026E10: .4byte gMoveResultFlags\n\ +_08026E14: .4byte gBankAttacker\n\ +_08026E18: .4byte gBankTarget\n\ +_08026E1C: .4byte gBattleCommunication\n\ +_08026E20:\n\ + ldr r1, _08026E50 @ =gBattleCommunication\n\ + movs r0, 0x1\n\ +_08026E24:\n\ + strb r0, [r1, 0x5]\n\ + ldr r3, _08026E54 @ =gBattlescriptCurrInstr\n\ + ldr r2, [r3]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 24\n\ + orrs r1, r0\n\ + str r1, [r3]\n\ +_08026E40:\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08026E50: .4byte gBattleCommunication\n\ +_08026E54: .4byte gBattlescriptCurrInstr\n\ + .syntax divided"); +} +#endif // NOTMATCHING + +static void atk94_damagetohalftargethp(void) //super fang +{ + gBattleMoveDamage = gBattleMons[gBankTarget].hp / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattlescriptCurrInstr++; +} + +static void atk95_setsandstorm(void) +{ + if (gBattleWeather & WEATHER_SANDSTORM_ANY) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gBattleWeather = WEATHER_SANDSTORM_TEMPORARY; + gBattleCommunication[MULTISTRING_CHOOSER] = 3; + gWishFutureKnock.weatherDuration = 5; + } + gBattlescriptCurrInstr++; +} + +static void atk96_weatherdamage(void) +{ + if (WEATHER_HAS_EFFECT) + { + if (gBattleWeather & WEATHER_SANDSTORM_ANY) + { + if (gBattleMons[gBankAttacker].type1 != TYPE_ROCK && gBattleMons[gBankAttacker].type1 != TYPE_STEEL && gBattleMons[gBankAttacker].type1 != TYPE_GROUND + && gBattleMons[gBankAttacker].type2 != TYPE_ROCK && gBattleMons[gBankAttacker].type2 != TYPE_STEEL && gBattleMons[gBankAttacker].type2 != TYPE_GROUND + && gBattleMons[gBankAttacker].ability != ABILITY_SAND_VEIL && !(gStatuses3[gBankAttacker] & STATUS3_UNDERGROUND) && !(gStatuses3[gBankAttacker] & STATUS3_UNDERWATER)) + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } + else + { + gBattleMoveDamage = 0; + } + } + if (gBattleWeather & WEATHER_HAIL) + { + if (gBattleMons[gBankAttacker].type1 != TYPE_ICE && gBattleMons[gBankAttacker].type2 != TYPE_ICE && !(gStatuses3[gBankAttacker] & STATUS3_UNDERGROUND) && !(gStatuses3[gBankAttacker] & STATUS3_UNDERWATER)) + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } + else + { + gBattleMoveDamage = 0; + } + } + } + else + gBattleMoveDamage = 0; + + if (gAbsentBattlerFlags & gBitTable[gBankAttacker]) + gBattleMoveDamage = 0; + + gBattlescriptCurrInstr++; +} + +static void atk97_tryinfatuating(void) +{ + struct Pokemon *attacker, *target; + u16 atk_species, def_species; + u32 atk_pid, def_pid; + if (!GetBattlerSide(gBankAttacker)) + attacker = &gPlayerParty[gBattlerPartyIndexes[gBankAttacker]]; + else + attacker = &gEnemyParty[gBattlerPartyIndexes[gBankAttacker]]; + + if (!GetBattlerSide(gBankTarget)) + target = &gPlayerParty[gBattlerPartyIndexes[gBankTarget]]; + else + target = &gEnemyParty[gBattlerPartyIndexes[gBankTarget]]; + + atk_species = GetMonData(attacker, MON_DATA_SPECIES); + atk_pid = GetMonData(attacker, MON_DATA_PERSONALITY); + + def_species = GetMonData(target, MON_DATA_SPECIES); + def_pid = GetMonData(target, MON_DATA_PERSONALITY); + + if (gBattleMons[gBankTarget].ability == ABILITY_OBLIVIOUS) + { + gBattlescriptCurrInstr = BattleScript_ObliviousPreventsAttraction; + gLastUsedAbility = ABILITY_OBLIVIOUS; + RecordAbilityBattle(gBankTarget, ABILITY_OBLIVIOUS); + } + else + { + if (GetGenderFromSpeciesAndPersonality(atk_species, atk_pid) == GetGenderFromSpeciesAndPersonality(def_species, def_pid) + || gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE || gBattleMons[gBankTarget].status2 & STATUS2_INFATUATION || GetGenderFromSpeciesAndPersonality(atk_species, atk_pid) == 0xFF + || GetGenderFromSpeciesAndPersonality(def_species, def_pid) == 0xFF) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else + { + gBattleMons[gBankTarget].status2 |= (gBitTable[gBankAttacker] << 16); + gBattlescriptCurrInstr += 5; + } + } +} + +static void atk98_updatestatusicon(void) +{ + if (gBattleExecBuffer) + return; + + if (T2_READ_8(gBattlescriptCurrInstr + 1) != 4) + { + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + EmitStatusIconUpdate(0, gBattleMons[gActiveBattler].status1, gBattleMons[gActiveBattler].status2); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 2; + } + else + { + gActiveBattler = gBankAttacker; + if (!(gAbsentBattlerFlags & gBitTable[gActiveBattler])) + { + EmitStatusIconUpdate(0, gBattleMons[gActiveBattler].status1, gBattleMons[gActiveBattler].status2); + MarkBufferBankForExecution(gActiveBattler); + } + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + { + gActiveBattler = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ 2); + if (!(gAbsentBattlerFlags & gBitTable[gActiveBattler])) + { + EmitStatusIconUpdate(0, gBattleMons[gActiveBattler].status1, gBattleMons[gActiveBattler].status2); + MarkBufferBankForExecution(gActiveBattler); + } + } + gBattlescriptCurrInstr += 2; + } +} + +static void atk99_setmist(void) +{ + if (gSideTimers[GetBattlerPosition(gBankAttacker) & 1].mistTimer) + { + gMoveResultFlags |= MOVE_RESULT_FAILED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gSideTimers[GetBattlerPosition(gBankAttacker) & 1].mistTimer = 5; + gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] |= SIDE_STATUS_MIST; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + gBattlescriptCurrInstr++; +} + +static void atk9A_setfocusenergy(void) +{ + if (gBattleMons[gBankAttacker].status2 & STATUS2_FOCUS_ENERGY) + { + gMoveResultFlags |= MOVE_RESULT_FAILED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gBattleMons[gBankAttacker].status2 |= STATUS2_FOCUS_ENERGY; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + gBattlescriptCurrInstr++; +} + +static void atk9B_transformdataexecution(void) +{ + gChosenMove = 0xFFFF; + gBattlescriptCurrInstr++; + if (gBattleMons[gBankTarget].status2 & STATUS2_TRANSFORMED || gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE) + { + gMoveResultFlags |= MOVE_RESULT_FAILED; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + u32 i; s32 j; + u8 *atk_data, *def_data; + gBattleMons[gBankAttacker].status2 |= STATUS2_TRANSFORMED; + gDisableStructs[gBankAttacker].disabledMove = 0; + gDisableStructs[gBankAttacker].disableTimer1 = 0; + gDisableStructs[gBankAttacker].transformedMonPersonality = gBattleMons[gBankTarget].personality; + gDisableStructs[gBankAttacker].unk18_b = 0; + + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 6; + gBattleTextBuff1[2] = (gBattleMons[gBankTarget].species); + gBattleTextBuff1[3] = uBYTE1_16(gBattleMons[gBankTarget].species); + gBattleTextBuff1[4] = 0xFF; + + atk_data = (u8*)(&gBattleMons[gBankAttacker]); + def_data = (u8*)(&gBattleMons[gBankTarget]); + + for (i = 0; i < 0x24; i++) + atk_data[i] = def_data[i]; + + for (j = 0; j < 4; j++) + { + if (gBattleMoves[gBattleMons[gBankAttacker].moves[j]].pp < 5) + gBattleMons[gBankAttacker].pp[j] = gBattleMoves[gBattleMons[gBankAttacker].moves[j]].pp; + else + gBattleMons[gBankAttacker].pp[j] = 5; + } + + gActiveBattler = gBankAttacker; + EmitResetActionMoveSelection(0, 2); + MarkBufferBankForExecution(gActiveBattler); + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } +} + +static void atk9C_setsubstitute(void) +{ + u32 hp = gBattleMons[gBankAttacker].maxHP / 4; + if (gBattleMons[gBankAttacker].maxHP / 4 == 0) + hp = 1; + if (gBattleMons[gBankAttacker].hp <= hp) + { + gBattleMoveDamage = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMons[gBankAttacker].status2 |= STATUS2_SUBSTITUTE; + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_WRAPPED); + gDisableStructs[gBankAttacker].substituteHP = gBattleMoveDamage; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE; + } + gBattlescriptCurrInstr++; +} + +static bool8 IsMoveUncopyable(u16 move) +{ + int i; + for (i = 0; sMovesForbiddenToCopy[i] != 0xFFFE && sMovesForbiddenToCopy[i] != move; i++) {} + return (sMovesForbiddenToCopy[i] != 0xFFFE); +} + +static void atk9D_mimicattackcopy(void) +{ + gChosenMove = 0xFFFF; + if (IsMoveUncopyable(gLastUsedMove[gBankTarget]) || gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED + || gLastUsedMove[gBankTarget] == 0 || gLastUsedMove[gBankTarget] == 0xFFFF) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else + { + int i; + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankAttacker].moves[i] == gLastUsedMove[gBankTarget]) + break; + } + if (i == 4) + { + gBattleMons[gBankAttacker].moves[gCurrMovePos] = gLastUsedMove[gBankTarget]; + if (gBattleMoves[gLastUsedMove[gBankTarget]].pp < 5) + gBattleMons[gBankAttacker].pp[gCurrMovePos] = gBattleMoves[gLastUsedMove[gBankTarget]].pp; + else + gBattleMons[gBankAttacker].pp[gCurrMovePos] = 5; + + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = gLastUsedMove[gBankTarget]; + gBattleTextBuff1[3] = uBYTE1_16(gLastUsedMove[gBankTarget]); + gBattleTextBuff1[4] = 0xFF; + + gDisableStructs[gBankAttacker].unk18_b |= gBitTable[gCurrMovePos]; + gBattlescriptCurrInstr += 5; + } + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } +} + +#if DEBUG +NAKED +static void atk9E_metronome(void) +{ + asm("\ + push {r4, r5, r6, r7, lr}\n\ + mov r7, r8\n\ + push {r7}\n\ + ldr r6, ._3076 @ gBankAttacker\n\ + ldrb r2, [r6]\n\ + lsl r1, r2, #0x1\n\ + ldr r0, ._3076 + 4 @ \n\ + add r3, r1, r0\n\ + ldr r5, ._3076 + 8 @ \n\ + mov r4, #0x58\n\ + add r0, r2, #0\n\ + mul r0, r0, r4\n\ + add r1, r0, r5\n\ + ldrh r0, [r1, #0xe]\n\ + cmp r0, #0\n\ + bne ._3071 @cond_branch\n\ + ldrh r2, [r1, #0x10]\n\ + cmp r2, #0\n\ + beq ._3071 @cond_branch\n\ + ldrh r0, [r1, #0x12]\n\ + cmp r0, #0\n\ + beq ._3071 @cond_branch\n\ + ldrh r0, [r3]\n\ + cmp r0, #0\n\ + bne ._3072 @cond_branch\n\ + strh r2, [r3]\n\ +._3072:\n\ + ldr r1, ._3076 + 12 @ \n\ + ldrh r0, [r3]\n\ + strh r0, [r1]\n\ + ldrb r0, [r6]\n\ + mul r0, r0, r4\n\ + add r0, r0, r5\n\ + ldrh r5, [r0, #0x10]\n\ + ldrh r2, [r0, #0x12]\n\ + add r7, r1, #0\n\ + cmp r5, r2\n\ + bcs ._3073 @cond_branch\n\ + ldrh r0, [r3]\n\ + cmp r0, r2\n\ + beq ._3074 @cond_branch\n\ + add r0, r0, #0x1\n\ + b ._3079\n\ +._3077:\n\ + .align 2, 0\n\ +._3076:\n\ + .word gBankAttacker\n\ + .word +0x20160b4\n\ + .word gBattleMons\n\ + .word gCurrentMove\n\ +._3073:\n\ + ldrh r4, [r3]\n\ + add r1, r4, #0\n\ + mov r0, #0xb1\n\ + lsl r0, r0, #0x1\n\ + cmp r1, r0\n\ + bne ._3078 @cond_branch\n\ + mov r0, #0x1\n\ + b ._3079\n\ +._3078:\n\ + cmp r1, r2\n\ + bne ._3080 @cond_branch\n\ +._3074:\n\ + strh r5, [r3]\n\ + b ._3081\n\ +._3080:\n\ + add r0, r4, #1\n\ +._3079:\n\ + strh r0, [r3]\n\ +._3081:\n\ + ldr r4, ._3083 @ gHitMarker\n\ + ldr r2, [r4]\n\ + ldr r0, ._3083 + 4 @ 0xfffffbff\n\ + and r2, r2, r0\n\ + str r2, [r4]\n\ + ldr r6, ._3083 + 8 @ gBattlescriptCurrInstr\n\ + ldr r5, ._3083 + 12 @ gBattleScriptsForMoveEffects\n\ + ldr r3, ._3083 + 16 @ gBattleMoves\n\ + ldrh r1, [r7]\n\ + lsl r0, r1, #0x1\n\ + add r0, r0, r1\n\ + lsl r0, r0, #0x2\n\ + add r0, r0, r3\n\ + ldrb r0, [r0]\n\ + lsl r0, r0, #0x2\n\ + add r0, r0, r5\n\ + ldr r0, [r0]\n\ + str r0, [r6]\n\ + mov r0, #0x80\n\ + lsl r0, r0, #0x4\n\ + orr r2, r2, r0\n\ + str r2, [r4]\n\ + ldrh r0, [r7]\n\ + b ._3082\n\ +._3084:\n\ + .align 2, 0\n\ +._3083:\n\ + .word gHitMarker\n\ + .word 0xfffffbff\n\ + .word gBattlescriptCurrInstr\n\ + .word gBattleScriptsForMoveEffects\n\ + .word gBattleMoves\n\ +._3071:\n\ + ldr r7, ._3090 @ gCurrentMove\n\ + mov r6, #0xb1\n\ + lsl r6, r6, #0x1\n\ + ldr r5, ._3090 + 4 @ sMovesForbiddenToCopy\n\ + ldr r0, ._3090 + 8 @ gBattlescriptCurrInstr\n\ + mov r8, r0\n\ +._3089:\n\ + bl Random\n\ + ldr r2, ._3090 + 12 @ 0x1ff\n\ + add r1, r2, #0\n\ + and r0, r0, r1\n\ + add r0, r0, #0x1\n\ + strh r0, [r7]\n\ + cmp r0, r6\n\ + bhi ._3089 @cond_branch\n\ + mov r0, #0x3\n\ +._3086:\n\ + sub r0, r0, #0x1\n\ + cmp r0, #0\n\ + bge ._3086 @cond_branch\n\ + ldr r4, ._3090 @ gCurrentMove\n\ + ldrh r2, [r4]\n\ + ldr r3, ._3090 + 16 @ 0xffff\n\ + sub r0, r5, #2\n\ +._3088:\n\ + add r0, r0, #0x2\n\ + ldrh r1, [r0]\n\ + cmp r1, r2\n\ + beq ._3087 @cond_branch\n\ + cmp r1, r3\n\ + bne ._3088 @cond_branch\n\ +._3087:\n\ + ldr r0, ._3090 + 16 @ 0xffff\n\ + cmp r1, r0\n\ + bne ._3089 @cond_branch\n\ + ldr r2, ._3090 + 20 @ gHitMarker\n\ + ldr r0, [r2]\n\ + ldr r1, ._3090 + 24 @ 0xfffffbff\n\ + and r0, r0, r1\n\ + str r0, [r2]\n\ + ldr r3, ._3090 + 28 @ gBattleScriptsForMoveEffects\n\ + ldr r2, ._3090 + 32 @ gBattleMoves\n\ + ldrh r1, [r4]\n\ + lsl r0, r1, #0x1\n\ + add r0, r0, r1\n\ + lsl r0, r0, #0x2\n\ + add r0, r0, r2\n\ + ldrb r0, [r0]\n\ + lsl r0, r0, #0x2\n\ + add r0, r0, r3\n\ + ldr r0, [r0]\n\ + mov r1, r8\n\ + str r0, [r1]\n\ + ldrh r0, [r4]\n\ +._3082:\n\ + mov r1, #0x0\n\ + bl GetMoveTarget\n\ + ldr r1, ._3090 + 36 @ gBankTarget\n\ + strb r0, [r1]\n\ + pop {r3}\n\ + mov r8, r3\n\ + pop {r4, r5, r6, r7}\n\ + pop {r0}\n\ + bx r0\n\ +._3091:\n\ + .align 2, 0\n\ +._3090:\n\ + .word gCurrentMove\n\ + .word sMovesForbiddenToCopy\n\ + .word gBattlescriptCurrInstr\n\ + .word 0x1ff\n\ + .word 0xffff\n\ + .word gHitMarker\n\ + .word 0xfffffbff\n\ + .word gBattleScriptsForMoveEffects\n\ + .word gBattleMoves\n\ + .word gBankTarget"); +} +#else +#ifdef NONMATCHING +static void atk9E_metronome(void) +{ + // sMovesForbiddenToCopy + int i; + do + { + while ((gCurrentMove = (Random() & 0x1FF) + 1) > 0x162); + for (i = 0; sMovesForbiddenToCopy[i] != gCurrentMove && sMovesForbiddenToCopy[i] != 0xFFFF; i++); + } while (sMovesForbiddenToCopy[i] != 0xFFFF); + + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + gBankTarget = GetMoveTarget(gCurrentMove, 0); +} + +#else +NAKED +static void atk9E_metronome(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r8\n\ + push {r7}\n\ + ldr r7, _08027938 @ =gCurrentMove\n\ + movs r6, 0xB1\n\ + lsls r6, 1\n\ + ldr r5, _0802793C @ =sMovesForbiddenToCopy\n\ + ldr r0, _08027940 @ =gBattlescriptCurrInstr\n\ + mov r8, r0\n\ +_080278CA:\n\ + bl Random\n\ + ldr r2, _08027944 @ =0x000001ff\n\ + adds r1, r2, 0\n\ + ands r0, r1\n\ + adds r0, 0x1\n\ + strh r0, [r7]\n\ + cmp r0, r6\n\ + bhi _080278CA\n\ + movs r0, 0x3\n\ +_080278DE:\n\ + subs r0, 0x1\n\ + cmp r0, 0\n\ + bge _080278DE\n\ + ldr r4, _08027938 @ =gCurrentMove\n\ + ldrh r2, [r4]\n\ + ldr r3, _08027948 @ =0x0000ffff\n\ + subs r0, r5, 0x2\n\ +_080278EC:\n\ + adds r0, 0x2\n\ + ldrh r1, [r0]\n\ + cmp r1, r2\n\ + beq _080278F8\n\ + cmp r1, r3\n\ + bne _080278EC\n\ +_080278F8:\n\ + ldr r0, _08027948 @ =0x0000ffff\n\ + cmp r1, r0\n\ + bne _080278CA\n\ + ldr r2, _0802794C @ =gHitMarker\n\ + ldr r0, [r2]\n\ + ldr r1, _08027950 @ =0xfffffbff\n\ + ands r0, r1\n\ + str r0, [r2]\n\ + ldr r3, _08027954 @ =gBattleScriptsForMoveEffects\n\ + ldr r2, _08027958 @ =gBattleMoves\n\ + ldrh r1, [r4]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r0, [r0]\n\ + lsls r0, 2\n\ + adds r0, r3\n\ + ldr r0, [r0]\n\ + mov r1, r8\n\ + str r0, [r1]\n\ + ldrh r0, [r4]\n\ + movs r1, 0\n\ + bl GetMoveTarget\n\ + ldr r1, _0802795C @ =gBankTarget\n\ + strb r0, [r1]\n\ + pop {r3}\n\ + mov r8, r3\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08027938: .4byte gCurrentMove\n\ +_0802793C: .4byte sMovesForbiddenToCopy\n\ +_08027940: .4byte gBattlescriptCurrInstr\n\ +_08027944: .4byte 0x000001ff\n\ +_08027948: .4byte 0x0000ffff\n\ +_0802794C: .4byte gHitMarker\n\ +_08027950: .4byte 0xfffffbff\n\ +_08027954: .4byte gBattleScriptsForMoveEffects\n\ +_08027958: .4byte gBattleMoves\n\ +_0802795C: .4byte gBankTarget\n\ + .syntax divided"); +} +#endif // NONMATCHING +#endif + +static void atk9F_dmgtolevel(void) +{ + gBattleMoveDamage = gBattleMons[gBankAttacker].level; + gBattlescriptCurrInstr++; +} + +static void atkA0_psywavedamageeffect(void) +{ + s32 rand_dmg; + while ((rand_dmg = (Random() & 0xF)) > 0xA); + rand_dmg *= 10; + gBattleMoveDamage = gBattleMons[gBankAttacker].level * (rand_dmg + 50) / 100; + gBattlescriptCurrInstr++; +} + +static void atkA1_counterdamagecalculator(void) +{ + u8 atk_side = GetBattlerSide(gBankAttacker); + u8 def_side = GetBattlerSide(gProtectStructs[gBankAttacker].physicalBank); + if (gProtectStructs[gBankAttacker].physicalDmg && atk_side != def_side && gBattleMons[gProtectStructs[gBankAttacker].physicalBank].hp) + { + gBattleMoveDamage = gProtectStructs[gBankAttacker].physicalDmg * 2; + if (gSideTimers[def_side].followmeTimer && gBattleMons[gSideTimers[def_side].followmeTarget].hp) + gBankTarget = gSideTimers[def_side].followmeTarget; + else + gBankTarget = gProtectStructs[gBankAttacker].physicalBank; + gBattlescriptCurrInstr += 5; + } + else + { + gSpecialStatuses[gBankAttacker].flag20 = 1; + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } +} + +static void atkA2_mirrorcoatdamagecalculator(void) //a copy of atkA1 with the physical -> special field changes +{ + u8 atk_side = GetBattlerSide(gBankAttacker); + u8 def_side = GetBattlerSide(gProtectStructs[gBankAttacker].specialBank); + if (gProtectStructs[gBankAttacker].specialDmg && atk_side != def_side && gBattleMons[gProtectStructs[gBankAttacker].specialBank].hp) + { + gBattleMoveDamage = gProtectStructs[gBankAttacker].specialDmg * 2; + if (gSideTimers[def_side].followmeTimer && gBattleMons[gSideTimers[def_side].followmeTarget].hp) + gBankTarget = gSideTimers[def_side].followmeTarget; + else + gBankTarget = gProtectStructs[gBankAttacker].specialBank; + gBattlescriptCurrInstr += 5; + } + else + { + gSpecialStatuses[gBankAttacker].flag20 = 1; + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } +} + +static void atkA3_disablelastusedattack(void) +{ + int i; + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankTarget].moves[i] == gLastUsedMove[gBankTarget]) + break; + } + if (gDisableStructs[gBankTarget].disabledMove == 0 && i != 4 && gBattleMons[gBankTarget].pp[i] != 0) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = gBattleMons[gBankTarget].moves[i]; + gBattleTextBuff1[3] = uBYTE1_16(gBattleMons[gBankTarget].moves[i]); + gBattleTextBuff1[4] = 0xFF; + + gDisableStructs[gBankTarget].disabledMove = gBattleMons[gBankTarget].moves[i]; + gDisableStructs[gBankTarget].disableTimer1 = (Random() & 3) + 2; + gDisableStructs[gBankTarget].disableTimer2 = gDisableStructs[gBankTarget].disableTimer1; //that's interesting + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } +} + +static void atkA4_trysetencore(void) +{ + int i; + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankTarget].moves[i] == gLastUsedMove[gBankTarget]) + break; + } + if (gLastUsedMove[gBankTarget] == MOVE_STRUGGLE || gLastUsedMove[gBankTarget] == MOVE_ENCORE || gLastUsedMove[gBankTarget] == MOVE_MIRROR_MOVE) + i = 4; + if (gDisableStructs[gBankTarget].encoredMove == 0 && i != 4 && gBattleMons[gBankTarget].pp[i] != 0) + { + gDisableStructs[gBankTarget].encoredMove = gBattleMons[gBankTarget].moves[i]; + gDisableStructs[gBankTarget].encoredMovePos = i; + gDisableStructs[gBankTarget].encoreTimer1 = (Random() & 3) + 3; + gDisableStructs[gBankTarget].encoreTimer2 = gDisableStructs[gBankTarget].encoreTimer1; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } +} + +static void atkA5_painsplitdmgcalc(void) +{ + if (!(gBattleMons[gBankTarget].status2 & STATUS2_SUBSTITUTE)) + { + s32 hp_diff = (gBattleMons[gBankAttacker].hp + gBattleMons[gBankTarget].hp) / 2; + s32 to_store = gBattleMoveDamage = gBattleMons[gBankTarget].hp - hp_diff; + gBattleStruct->unk16014 = sBYTE0_32(to_store); + gBattleStruct->unk16015 = sBYTE1_32(to_store); + gBattleStruct->unk16016 = sBYTE2_32(to_store); + gBattleStruct->unk16017 = sBYTE3_32(to_store); + + gBattleMoveDamage = gBattleMons[gBankAttacker].hp - hp_diff; + gSpecialStatuses[gBankTarget].moveturnLostHP = 0xFFFF; + + gBattlescriptCurrInstr += 5; + } + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +#ifdef NONMATCHING +static void atkA6_settypetorandomresistance(void) +{ + if (gLastLandedMoves[gBankAttacker] == 0 || gLastLandedMoves[gBankAttacker] == 0xFFFF || (IsTwoTurnsMove(gLastLandedMoves[gBankAttacker]) && !gProtectStructs[gBankAttacker].physicalDmg && !gProtectStructs[gBankAttacker].specialDmg)) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + { + int type = 0, rands = 0; + do + { + while (((type = (Random() & 0x7F)) > 0x70)); + type *= 3; + if (gTypeEffectiveness[type] == gLastHitByType[gBankAttacker] && gTypeEffectiveness[type + 2] <= 5 && gBattleMons[gBankAttacker].type1 != gTypeEffectiveness[type + 1] && gBattleMons[gBankAttacker].type2 != gTypeEffectiveness[type + 1]) + { + gBattleMons[gBankAttacker].type1 = type; + gBattleMons[gBankAttacker].type2 = type; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 3; + gBattleTextBuff1[2] = type; + gBattleTextBuff1[3] = 0xFF; + gBattlescriptCurrInstr += 5; + return; + } + rands++; + } while (rands <= 999); + + type = 0, rands = 0; + do + { + if (gTypeEffectiveness[type] == 0xFE || gTypeEffectiveness[type] != 0xFF) + { + if (gTypeEffectiveness[type] == gLastHitByType[gBankAttacker] && gTypeEffectiveness[type + 2] <= 5 && gBattleMons[gBankAttacker].type1 != gTypeEffectiveness[type + 1] && gBattleMons[gBankAttacker].type2 != gTypeEffectiveness[type + 1]) + { + gBattleMons[gBankAttacker].type1 = gTypeEffectiveness[rands + 1]; + gBattleMons[gBankAttacker].type2 = gTypeEffectiveness[rands + 1]; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 3; + gBattleTextBuff1[2] = gTypeEffectiveness[rands + 1]; + gBattleTextBuff1[3] = 0xFF; + gBattlescriptCurrInstr += 5; + return; + } + } + type += 3, rands += 3; + } while (rands < 336); + + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } +} + +#else +NAKED +static void atkA6_settypetorandomresistance(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + ldr r1, _08027FA8 @ =gLastLandedMoves\n\ + ldr r4, _08027FAC @ =gBankAttacker\n\ + ldrb r0, [r4]\n\ + lsls r0, 1\n\ + adds r2, r0, r1\n\ + ldrh r1, [r2]\n\ + cmp r1, 0\n\ + beq _08027F8C\n\ + ldr r0, _08027FB0 @ =0x0000ffff\n\ + cmp r1, r0\n\ + beq _08027F8C\n\ + ldrh r0, [r2]\n\ + bl IsTwoTurnsMove\n\ + lsls r0, 24\n\ + cmp r0, 0\n\ + beq _08028024\n\ + ldr r2, _08027FB4 @ =gProtectStructs\n\ + ldrb r0, [r4]\n\ + lsls r1, r0, 4\n\ + adds r0, r2, 0x4\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _08028024\n\ + adds r0, r2, 0\n\ + adds r0, 0x8\n\ + adds r0, r1, r0\n\ + ldr r0, [r0]\n\ + cmp r0, 0\n\ + bne _08028024\n\ +_08027F8C:\n\ + ldr r3, _08027FB8 @ =gBattlescriptCurrInstr\n\ + ldr r2, [r3]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 24\n\ + orrs r1, r0\n\ + str r1, [r3]\n\ + b _08028110\n\ + .align 2, 0\n\ +_08027FA8: .4byte gLastLandedMoves\n\ +_08027FAC: .4byte gBankAttacker\n\ +_08027FB0: .4byte 0x0000ffff\n\ +_08027FB4: .4byte gProtectStructs\n\ +_08027FB8: .4byte gBattlescriptCurrInstr\n\ +_08027FBC:\n\ + mov r0, r12\n\ + strb r5, [r0]\n\ + mov r1, r10\n\ + ldrb r0, [r1]\n\ + muls r0, r2\n\ + adds r0, r7\n\ + adds r0, 0x22\n\ + strb r5, [r0]\n\ + ldr r1, _08027FE0 @ =gBattleTextBuff1\n\ + movs r0, 0xFD\n\ + strb r0, [r1]\n\ + movs r0, 0x3\n\ + strb r0, [r1, 0x1]\n\ + strb r5, [r1, 0x2]\n\ + movs r0, 0xFF\n\ + strb r0, [r1, 0x3]\n\ + ldr r1, _08027FE4 @ =gBattlescriptCurrInstr\n\ + b _08028012\n\ + .align 2, 0\n\ +_08027FE0: .4byte gBattleTextBuff1\n\ +_08027FE4: .4byte gBattlescriptCurrInstr\n\ +_08027FE8:\n\ + mov r0, r8\n\ + adds r0, 0x1\n\ + adds r0, r3\n\ + ldrb r2, [r0]\n\ + strb r2, [r4]\n\ + mov r4, r10\n\ + ldrb r0, [r4]\n\ + muls r0, r6\n\ + ldr r7, _0802801C @ =gBattleMons\n\ + adds r0, r7\n\ + adds r0, 0x22\n\ + strb r2, [r0]\n\ + ldr r1, _08028020 @ =gBattleTextBuff1\n\ + movs r0, 0xFD\n\ + strb r0, [r1]\n\ + movs r0, 0x3\n\ + strb r0, [r1, 0x1]\n\ + strb r2, [r1, 0x2]\n\ + movs r0, 0xFF\n\ + strb r0, [r1, 0x3]\n\ + mov r1, r12\n\ +_08028012:\n\ + ldr r0, [r1]\n\ + adds r0, 0x5\n\ + str r0, [r1]\n\ + b _08028110\n\ + .align 2, 0\n\ +_0802801C: .4byte gBattleMons\n\ +_08028020: .4byte gBattleTextBuff1\n\ +_08028024:\n\ + movs r4, 0\n\ + mov r8, r4\n\ + movs r7, 0x7F\n\ + mov r9, r7\n\ +_0802802C:\n\ + bl Random\n\ + mov r4, r9\n\ + ands r4, r0\n\ + cmp r4, 0x70\n\ + bhi _0802802C\n\ + lsls r0, r4, 1\n\ + adds r4, r0, r4\n\ + ldr r6, _08028120 @ =gTypeEffectiveness\n\ + adds r3, r4, r6\n\ + ldr r1, _08028124 @ =gLastHitByType\n\ + ldr r2, _08028128 @ =gBankAttacker\n\ + ldrb r5, [r2]\n\ + lsls r0, r5, 1\n\ + adds r0, r1\n\ + ldrb r1, [r3]\n\ + mov r10, r2\n\ + ldrh r0, [r0]\n\ + cmp r1, r0\n\ + bne _08028088\n\ + adds r0, r4, 0x2\n\ + adds r0, r6\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x5\n\ + bhi _08028088\n\ + ldr r7, _0802812C @ =gBattleMons\n\ + movs r2, 0x58\n\ + adds r0, r5, 0\n\ + muls r0, r2\n\ + adds r3, r0, r7\n\ + movs r0, 0x21\n\ + adds r0, r3\n\ + mov r12, r0\n\ + adds r0, r4, 0x1\n\ + adds r0, r6\n\ + ldrb r5, [r0]\n\ + mov r1, r12\n\ + ldrb r0, [r1]\n\ + adds r1, r5, 0\n\ + cmp r0, r1\n\ + beq _08028088\n\ + adds r0, r3, 0\n\ + adds r0, 0x22\n\ + ldrb r0, [r0]\n\ + cmp r0, r1\n\ + bne _08027FBC\n\ +_08028088:\n\ + movs r7, 0x1\n\ + add r8, r7\n\ + ldr r0, _08028130 @ =0x000003e7\n\ + cmp r8, r0\n\ + ble _0802802C\n\ + movs r0, 0\n\ + mov r8, r0\n\ + ldr r1, _08028134 @ =gBattlescriptCurrInstr\n\ + mov r12, r1\n\ + ldr r3, _08028120 @ =gTypeEffectiveness\n\ + adds r0, r4, 0x1\n\ + adds r0, r3\n\ + mov r9, r0\n\ + adds r5, r3, 0\n\ +_080280A4:\n\ + ldrb r1, [r5]\n\ + cmp r1, 0xFF\n\ + bgt _080280AE\n\ + cmp r1, 0xFE\n\ + bge _080280E8\n\ +_080280AE:\n\ + mov r4, r10\n\ + ldrb r2, [r4]\n\ + lsls r0, r2, 1\n\ + ldr r7, _08028124 @ =gLastHitByType\n\ + adds r0, r7\n\ + ldrh r0, [r0]\n\ + cmp r1, r0\n\ + bne _080280E8\n\ + ldrb r0, [r5, 0x2]\n\ + cmp r0, 0x5\n\ + bhi _080280E8\n\ + movs r6, 0x58\n\ + adds r0, r2, 0\n\ + muls r0, r6\n\ + ldr r1, _0802812C @ =gBattleMons\n\ + adds r2, r0, r1\n\ + adds r4, r2, 0\n\ + adds r4, 0x21\n\ + ldrb r0, [r4]\n\ + mov r7, r9\n\ + ldrb r1, [r7]\n\ + cmp r0, r1\n\ + beq _080280E8\n\ + adds r0, r2, 0\n\ + adds r0, 0x22\n\ + ldrb r0, [r0]\n\ + cmp r0, r1\n\ + beq _080280E8\n\ + b _08027FE8\n\ +_080280E8:\n\ + adds r5, 0x3\n\ + movs r0, 0x3\n\ + add r8, r0\n\ + ldr r0, _08028138 @ =0x0000014f\n\ + cmp r8, r0\n\ + bls _080280A4\n\ + mov r1, r12\n\ + ldr r2, [r1]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 24\n\ + orrs r1, r0\n\ + mov r4, r12\n\ + str r1, [r4]\n\ +_08028110:\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08028120: .4byte gTypeEffectiveness\n\ +_08028124: .4byte gLastHitByType\n\ +_08028128: .4byte gBankAttacker\n\ +_0802812C: .4byte gBattleMons\n\ +_08028130: .4byte 0x000003e7\n\ +_08028134: .4byte gBattlescriptCurrInstr\n\ +_08028138: .4byte 0x0000014f\n\ + .syntax divided"); +} +#endif // NONMATCHING + +static void atkA7_setalwayshitflag(void) +{ + gStatuses3[gBankTarget] &= ~(STATUS3_ALWAYS_HITS); + gStatuses3[gBankTarget] |= 0x10; + gDisableStructs[gBankTarget].bankWithSureHit = gBankAttacker; + gBattlescriptCurrInstr++; +} + +struct move_pp +{ + u16 move[4]; + u8 pp[4]; + u8 ppBonuses; +}; + +static void atkA8_copymovepermanently(void) +{ + gChosenMove = 0xFFFF; + if (!(gBattleMons[gBankAttacker].status2 & STATUS2_TRANSFORMED) && gUnknown_02024C2C[gBankTarget] != MOVE_STRUGGLE && gUnknown_02024C2C[gBankTarget] != 0 && gUnknown_02024C2C[gBankTarget] != 0xFFFF && gUnknown_02024C2C[gBankTarget] != MOVE_SKETCH) + { + int i; + for (i = 0; i < 4; i++) + { + if (gBattleMons[gBankAttacker].moves[i] == MOVE_SKETCH) + continue; + if (gBattleMons[gBankAttacker].moves[i] == gUnknown_02024C2C[gBankTarget]) + break; + } + if (i != 4) //sketch fail + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else //sketch worked + { + struct move_pp moves_data; + gBattleMons[gBankAttacker].moves[gCurrMovePos] = gUnknown_02024C2C[gBankTarget]; + gBattleMons[gBankAttacker].pp[gCurrMovePos] = gBattleMoves[gUnknown_02024C2C[gBankTarget]].pp; + gActiveBattler = gBankAttacker; + for (i = 0; i < 4; i++) + { + moves_data.move[i] = gBattleMons[gBankAttacker].moves[i]; + moves_data.pp[i] = gBattleMons[gBankAttacker].pp[i]; + } + moves_data.ppBonuses = gBattleMons[gBankAttacker].ppBonuses; + EmitSetMonData(0, REQUEST_MOVES_PP_BATTLE, 0, sizeof(struct move_pp), &moves_data); + MarkBufferBankForExecution(gActiveBattler); + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = gUnknown_02024C2C[gBankTarget]; + gBattleTextBuff1[3] = gUnknown_02024C2C[gBankTarget] >> 8; + gBattleTextBuff1[4] = 0xFF; + gBattlescriptCurrInstr += 5; + } + } + else //sketch fail + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static bool8 IsTwoTurnsMove(u16 move) +{ + u8 effect = gBattleMoves[move].effect; + if (effect == EFFECT_SKULL_BASH || effect == EFFECT_RAZOR_WIND || effect == EFFECT_SKY_ATTACK || effect == EFFECT_SOLARBEAM || effect == EFFECT_FLY || effect == EFFECT_BIDE) + return 1; + else + return 0; +} + +static bool8 IsMoveUnchoosable(u16 move) +{ + if (move == 0 || move == MOVE_SLEEP_TALK || move == MOVE_ASSIST || move == MOVE_MIRROR_MOVE || move == MOVE_METRONOME) + return 1; + else + return 0; +} + +static u8 AttacksThisTurn(u8 bank, u16 move) //Note: returns 1 if it's a charging turn, otherwise 2 +{ + //first argument is unused + u8 effect; + if (gBattleMoves[move].effect == EFFECT_SOLARBEAM && (gBattleWeather & WEATHER_SUN_ANY)) + return 2; + effect = gBattleMoves[move].effect; + if (effect == EFFECT_SKULL_BASH || effect == EFFECT_RAZOR_WIND || effect == EFFECT_SKY_ATTACK || effect == EFFECT_SOLARBEAM || effect == EFFECT_FLY || effect == EFFECT_BIDE) + { + if ((gHitMarker & HITMARKER_x8000000)) + return 1; + } + return 2; +} + +static void atkA9_trychoosesleeptalkmove(void) +{ + u8 unusable_moves = 0; + int i; + + for (i = 0; i < 4; i++) + { + if (IsMoveUnchoosable(gBattleMons[gBankAttacker].moves[i]) || gBattleMons[gBankAttacker].moves[i] == MOVE_FOCUS_PUNCH + || gBattleMons[gBankAttacker].moves[i] == MOVE_UPROAR || IsTwoTurnsMove(gBattleMons[gBankAttacker].moves[i])) + unusable_moves |= gBitTable[i]; + } + unusable_moves = CheckMoveLimitations(gBankAttacker, unusable_moves, 0xFD); + if (unusable_moves == 0xF) //all 4 moves cannot be chosen + gBattlescriptCurrInstr += 5; + else //at least one move can be chosen + { + u32 random_pos; + do + { + random_pos = Random() & 3; + } while ((gBitTable[random_pos] & unusable_moves)); + + gRandomMove = gBattleMons[gBankAttacker].moves[random_pos]; + gCurrMovePos = random_pos; + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gBankTarget = GetMoveTarget(gRandomMove, 0); + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } +} + +static void atkAA_setdestinybond(void) +{ + gBattleMons[gBankAttacker].status2 |= STATUS2_DESTINY_BOND; + gBattlescriptCurrInstr++; +} + +static void TrySetDestinyBondToHappen(void) +{ + u8 atk_side = GetBattlerSide(gBankAttacker); + u8 def_side = GetBattlerSide(gBankTarget); + if (gBattleMons[gBankTarget].status2 & STATUS2_DESTINY_BOND && atk_side != def_side && !(gHitMarker & HITMARKER_GRUDGE)) + gHitMarker |= HITMARKER_DESTINYBOND; +} + +static void atkAB_trysetdestinybondtohappen(void) +{ + TrySetDestinyBondToHappen(); + gBattlescriptCurrInstr++; +} + +static void atkAC_remaininghptopower(void) +{ + s32 hp_fraction = GetScaledHPFraction(gBattleMons[gBankAttacker].hp, gBattleMons[gBankAttacker].maxHP, 48); + int i; + for (i = 0; i < 12; i += 2) + { + if (hp_fraction <= sFlailHpScaleToPowerTable[i]) + break; + } + gDynamicBasePower = sFlailHpScaleToPowerTable[i + 1]; + gBattlescriptCurrInstr++; +} + +static void atkAD_tryspiteppreduce(void) +{ + if (gLastUsedMove[gBankTarget] != 0 && gLastUsedMove[gBankTarget] != 0xFFFF && !(gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE)) + { + int i; + for (i = 0; i < 4; i++) + { + if (gLastUsedMove[gBankTarget] == gBattleMons[gBankTarget].moves[i]) + break; + } + if (i != 4 && gBattleMons[gBankTarget].pp[i] > 1) + { + s32 lost_pp = (Random() & 3) + 2; + if (gBattleMons[gBankTarget].pp[i] < lost_pp) + lost_pp = gBattleMons[gBankTarget].pp[i]; + + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = gLastUsedMove[gBankTarget]; + gBattleTextBuff1[3] = gLastUsedMove[gBankTarget] >> 8; + gBattleTextBuff1[4] = 0xFF; + ConvertIntToDecimalStringN(gBattleTextBuff2, lost_pp, 0, 1); + gBattleTextBuff2[0] = 0xFD; + gBattleTextBuff2[1] = 1; + gBattleTextBuff2[2] = 1; + gBattleTextBuff2[3] = 1; + gBattleTextBuff2[4] = lost_pp; + gBattleTextBuff2[5] = 0xFF; + + gBattleMons[gBankTarget].pp[i] -= lost_pp; + gActiveBattler = gBankTarget; + if (!(gDisableStructs[gActiveBattler].unk18_b & gBitTable[i]) + && !(gBattleMons[gActiveBattler].status2 & STATUS2_TRANSFORMED)) + { + EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + i, 0, 1, &gBattleMons[gActiveBattler].pp[i]); + MarkBufferBankForExecution(gActiveBattler); + } + gBattlescriptCurrInstr += 5; + if (gBattleMons[gBankTarget].pp[i] == 0) + CancelMultiTurnMoves(gBankTarget); + return; + } + } + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atkAE_healpartystatus(void) +{ + register u32 zero2 asm("r4") = 0; + u32 zero = zero2; + u8 to_heal = 0; + if (gCurrentMove == MOVE_HEAL_BELL) + { + struct Pokemon* party; + int i; + + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + if (GetBattlerSide(gBankAttacker) == 0) + party = gPlayerParty; + else + party = gEnemyParty; + + if (gBattleMons[gBankAttacker].ability != ABILITY_SOUNDPROOF) + { + gBattleMons[gBankAttacker].status1 = 0; + } + else + { + RecordAbilityBattle(gBankAttacker, gBattleMons[gBankAttacker].ability); + gBattleCommunication[MULTISTRING_CHOOSER] |= 1; + } + + gActiveBattler = gBattleStruct->scriptingActive = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ 2); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gAbsentBattlerFlags & gBitTable[gActiveBattler])) + { + if (gBattleMons[gActiveBattler].ability != ABILITY_SOUNDPROOF) + { + gBattleMons[gActiveBattler].status1 = 0; + } + else + { + RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability); + gBattleCommunication[MULTISTRING_CHOOSER] |= 2; + } + } + + for (i = 0; i < 6; i++) + { + u16 species = GetMonData(&party[i], MON_DATA_SPECIES2); + u8 abilityBit = GetMonData(&party[i], MON_DATA_ALT_ABILITY); + if (species != 0 && species != SPECIES_EGG) + { + u8 ability; + if (gBattlerPartyIndexes[gBankAttacker] == i) + ability = gBattleMons[gBankAttacker].ability; + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlerPartyIndexes[gActiveBattler] == i && !(gAbsentBattlerFlags & gBitTable[gActiveBattler])) + ability = gBattleMons[gActiveBattler].ability; + else + ability = GetAbilityBySpecies(species, abilityBit); + if (ability != ABILITY_SOUNDPROOF) + to_heal |= (1 << i); + } + } + } + else //Aromatherapy + { + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + to_heal = 0x3F; + gBattleMons[gBankAttacker].status1 = zero2; + + gActiveBattler = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ 2); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gAbsentBattlerFlags & gBitTable[gActiveBattler])) + gBattleMons[gActiveBattler].status1 = 0; + + } + //missing check? + gActiveBattler = gBankAttacker; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, to_heal, 4, &zero); + MarkBufferBankForExecution(gActiveBattler); + + gBattlescriptCurrInstr++; +} + +static void atkAF_cursetarget(void) +{ + if (gBattleMons[gBankTarget].status2 & STATUS2_CURSED || gStatuses3[gBankTarget] & STATUS3_SEMI_INVULNERABLE) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else + { + gBattleMons[gBankTarget].status2 |= STATUS2_CURSED; + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattlescriptCurrInstr += 5; + } +} + +static void atkB0_trysetspikes(void) +{ + u8 side = GetBattlerSide(gBankAttacker) ^ 1; + if (gSideTimers[side].spikesAmount == 3) + { + gSpecialStatuses[gBankAttacker].flag20 = 1; + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else + { + gSideAffecting[side] |= SIDE_STATUS_SPIKES; + gSideTimers[side].spikesAmount++; + gBattlescriptCurrInstr += 5; + } +} + +static void atkB1_setforesight(void) +{ + gBattleMons[gBankTarget].status2 |= STATUS2_FORESIGHT; + gBattlescriptCurrInstr++; +} + +static void atkB2_trysetperishsong(void) +{ + int not_affected_pokes = 0, i; + + for (i = 0; i < gBattlersCount; i++) + { + if (gStatuses3[i] & STATUS3_PERISH_SONG || gBattleMons[i].ability == ABILITY_SOUNDPROOF) + not_affected_pokes++; + else + { + gStatuses3[i] |= STATUS3_PERISH_SONG; + gDisableStructs[i].perishSongTimer1 = 3; + gDisableStructs[i].perishSongTimer2 = 3; + } + } + + PressurePPLoseOnUsingPerishSong(gBankAttacker); + if (not_affected_pokes == gBattlersCount) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; +} + +static void atkB3_rolloutdamagecalculation(void) +{ + if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + { + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveMissedPause; + } + else + { + int i; + if (!(gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS)) //first hit + { + gDisableStructs[gBankAttacker].rolloutTimer1 = 5; + gDisableStructs[gBankAttacker].rolloutTimer2 = 5; + gBattleMons[gBankAttacker].status2 |= STATUS2_MULTIPLETURNS; + gLockedMoves[gBankAttacker] = gCurrentMove; + } + if (--gDisableStructs[gBankAttacker].rolloutTimer1 == 0) + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_MULTIPLETURNS); + + gDynamicBasePower = gBattleMoves[gCurrentMove].power; + for (i = 1; i < (5 - gDisableStructs[gBankAttacker].rolloutTimer1); i++) + gDynamicBasePower *= 2; + + if (gBattleMons[gBankAttacker].status2 & STATUS2_DEFENSE_CURL) + gDynamicBasePower *= 2; + + gBattlescriptCurrInstr++; + } +} + +static void atkB4_jumpifconfusedandstatmaxed(void) +{ + if (gBattleMons[gBankTarget].status2 & STATUS2_CONFUSION && gBattleMons[gBankTarget].statStages[T2_READ_8(gBattlescriptCurrInstr + 1)] == 0xC) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; +} + +static void atkB5_furycuttercalc(void) +{ + if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + { + gDisableStructs[gBankAttacker].furyCutterCounter = 0; + gBattlescriptCurrInstr = BattleScript_MoveMissedPause; + } + else + { + int i; + + if (gDisableStructs[gBankAttacker].furyCutterCounter != 5) + gDisableStructs[gBankAttacker].furyCutterCounter++; + + gDynamicBasePower = gBattleMoves[gCurrentMove].power; + for (i = 1; i < gDisableStructs[gBankAttacker].furyCutterCounter; i++) + gDynamicBasePower *= 2; + + gBattlescriptCurrInstr++; + } +} + +static void atkB6_happinesstodamagecalculation(void) +{ + if (gBattleMoves[gCurrentMove].effect == EFFECT_RETURN) + gDynamicBasePower = 10 * (gBattleMons[gBankAttacker].friendship) / 25; + else //EFFECT_FRUSTRATION + gDynamicBasePower = 10 * (255 - gBattleMons[gBankAttacker].friendship) / 25; + gBattlescriptCurrInstr++; +} + +static void atkB7_presentdamagecalculation(void) +{ + s32 rand = Random() & 0xFF; + if (rand < 102) + gDynamicBasePower = 40; + else if (rand < 178) + gDynamicBasePower = 80; + else if (rand < 204) + gDynamicBasePower = 120; + else + { + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + } + if (rand < 204) + gBattlescriptCurrInstr = BattleScript_HitFromCritCalc; + else if (gBattleMons[gBankTarget].maxHP == gBattleMons[gBankTarget].hp) + gBattlescriptCurrInstr = BattleScript_AlreadyAtFullHp; + else + { + //gMoveResultFlags &= ~(MOVE_RESULT_DOESNT_AFFECT_FOE); only in Emerald + gBattlescriptCurrInstr = BattleScript_PresentHealTarget; + } +} + +static void atkB8_setsafeguard(void) +{ + if (gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] & SIDE_STATUS_SAFEGUARD) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else + { + gSideAffecting[GetBattlerPosition(gBankAttacker) & 1] |= SIDE_STATUS_SAFEGUARD; + gSideTimers[GetBattlerPosition(gBankAttacker) & 1].safeguardTimer = 5; + gBattleCommunication[MULTISTRING_CHOOSER] = 5; + } + gBattlescriptCurrInstr++; +} + +static void atkB9_magnitudedamagecalculation(void) +{ + s32 magnitude = Random() % 100; + if (magnitude < 5) + { + gDynamicBasePower = 10; + magnitude = 4; + } + else if (magnitude < 15) + { + gDynamicBasePower = 30; + magnitude = 5; + } + else if (magnitude < 35) + { + gDynamicBasePower = 50; + magnitude = 6; + } + else if (magnitude < 65) + { + gDynamicBasePower = 70; + magnitude = 7; + } + else if (magnitude < 85) + { + gDynamicBasePower = 90; + magnitude = 8; + } + else if (magnitude < 95) + { + gDynamicBasePower = 110; + magnitude = 9; + } + else + { + gDynamicBasePower = 150; + magnitude = 10; + } + + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 1; + gBattleTextBuff1[2] = 1; + gBattleTextBuff1[3] = 2; + gBattleTextBuff1[4] = magnitude; + gBattleTextBuff1[5] = 0xFF; + + for (gBankTarget = 0; gBankTarget < gBattlersCount; gBankTarget++) + { + if (gBankTarget == gBankAttacker) + continue; + if (!(gAbsentBattlerFlags & gBitTable[gBankTarget])) //a valid target was found + break; + } + gBattlescriptCurrInstr++; +} + +static void atkBA_jumpifnopursuitswitchdmg(void) +{ + if (gMultiHitCounter == 1) + { + if (GetBattlerSide(gBankAttacker) == 0) + gBankTarget = GetBattlerAtPosition(1); + else + gBankTarget = GetBattlerAtPosition(0); + } + else + { + if (GetBattlerSide(gBankAttacker) == 0) + gBankTarget = GetBattlerAtPosition(3); + else + gBankTarget = GetBattlerAtPosition(2); + } + + if (gActionForBanks[gBankTarget] == 0 && gBankAttacker == ewram16010arr(gBankTarget) && !(gBattleMons[gBankTarget].status1 & (STATUS_SLEEP | STATUS_FREEZE)) + && gBattleMons[gBankAttacker].hp && !gDisableStructs[gBankTarget].truantCounter && gChosenMovesByBanks[gBankTarget] == MOVE_PURSUIT) + { + int i; + for (i = 0; i < gBattlersCount; i++) + { + if (gBanksByTurnOrder[i] == gBankTarget) + gActionsByTurnOrder[i] = 11; + } + gCurrentMove = MOVE_PURSUIT; + gBattlescriptCurrInstr += 5; + gBattleStruct->animTurn = 1; + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + } + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atkBB_setsunny(void) +{ + if (gBattleWeather & WEATHER_SUN_ANY) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gBattleWeather = WEATHER_SUN_TEMPORARY; + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + gWishFutureKnock.weatherDuration = 5; + } + gBattlescriptCurrInstr++; +} + +static void atkBC_maxattackhalvehp(void) //belly drum +{ + u32 half_hp = gBattleMons[gBankAttacker].maxHP / 2; + if (!(gBattleMons[gBankAttacker].maxHP / 2)) + half_hp = 1; + + if (gBattleMons[gBankAttacker].statStages[STAT_STAGE_ATK] < 12 && gBattleMons[gBankAttacker].hp > half_hp) + { + gBattleMons[gBankAttacker].statStages[STAT_STAGE_ATK] = 12; + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } +} + +static void atkBD_copyfoestats(void) //psych up +{ + int i; + for (i = 0; i < 8; i++) + { + gBattleMons[gBankAttacker].statStages[i] = gBattleMons[gBankTarget].statStages[i]; + } + gBattlescriptCurrInstr += 5; //why not 1? possible unused fail possibility? +} + +static void atkBE_rapidspinfree(void) //rapid spin +{ + if (gBattleMons[gBankAttacker].status2 & STATUS2_WRAPPED) + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_WRAPPED); + gBankTarget = ewram16020arr(gBankAttacker); + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = ewram16004arr(0, gBankAttacker); + gBattleTextBuff1[3] = ewram16004arr(1, gBankAttacker); + gBattleTextBuff1[4] = 0xFF; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_WrapFree; + } + else if (gStatuses3[gBankAttacker] & STATUS3_LEECHSEED) + { + gStatuses3[gBankAttacker] &= ~(STATUS3_LEECHSEED); + gStatuses3[gBankAttacker] &= ~(STATUS3_LEECHSEED_BANK); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_LeechSeedFree; + } + else if (gSideAffecting[GetBattlerSide(gBankAttacker)] & SIDE_STATUS_SPIKES) + { + gSideAffecting[GetBattlerSide(gBankAttacker)] &= ~(SIDE_STATUS_SPIKES); + gSideTimers[GetBattlerSide(gBankAttacker)].spikesAmount = 0; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_SpikesFree; + } + else + gBattlescriptCurrInstr++; +} + +static void atkBF_setdefensecurlbit(void) +{ + gBattleMons[gBankAttacker].status2 |= STATUS2_DEFENSE_CURL; + gBattlescriptCurrInstr++; +} + +static void atkC0_recoverbasedonsunlight(void) +{ + gBankTarget = gBankAttacker; + if (gBattleMons[gBankAttacker].hp != gBattleMons[gBankAttacker].maxHP) + { + if (!gBattleWeather || !WEATHER_HAS_EFFECT) + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 2; + else if (gBattleWeather & WEATHER_SUN_ANY) + gBattleMoveDamage = 20 * gBattleMons[gBankAttacker].maxHP / 30; + else //not sunny weather + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + gBattlescriptCurrInstr += 5; + } + else + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } +} + +static void atkC1_hiddenpowercalc(void) +{ + u8 power = ((gBattleMons[gBankAttacker].hpIV & 2) >> 1) | + ((gBattleMons[gBankAttacker].attackIV & 2)) | + ((gBattleMons[gBankAttacker].defenseIV & 2) << 1) | + ((gBattleMons[gBankAttacker].speedIV & 2) << 2) | + ((gBattleMons[gBankAttacker].spAttackIV & 2) << 3) | + ((gBattleMons[gBankAttacker].spDefenseIV & 2) << 4); + u8 type = ((gBattleMons[gBankAttacker].hpIV & 1)) | + ((gBattleMons[gBankAttacker].attackIV & 1) << 1) | + ((gBattleMons[gBankAttacker].defenseIV & 1) << 2) | + ((gBattleMons[gBankAttacker].speedIV & 1) << 3) | + ((gBattleMons[gBankAttacker].spAttackIV & 1) << 4) | + ((gBattleMons[gBankAttacker].spDefenseIV & 1) << 5); + + gDynamicBasePower = 30 + (power * 40 / 63); + + gBattleStruct->dynamicMoveType = ((type * 15) / 63) + 1; + if (gBattleStruct->dynamicMoveType >= TYPE_MYSTERY) + gBattleStruct->dynamicMoveType++; + + gBattleStruct->dynamicMoveType |= 0xC0; + + gBattlescriptCurrInstr++; +} + +static void atkC2_selectfirstvalidtarget(void) +{ + for (gBankTarget = 0; gBankTarget < gBattlersCount; gBankTarget++) + { + if (gBankTarget == gBankAttacker) + continue; + if (!(gAbsentBattlerFlags & gBitTable[gBankTarget])) + break; + } + gBattlescriptCurrInstr++; +} + +static void atkC3_trysetfutureattack(void) +{ + if (gWishFutureKnock.futureSightCounter[gBankTarget] != 0) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else + { + gWishFutureKnock.futureSightMove[gBankTarget] = gCurrentMove; + gWishFutureKnock.futureSightAttacker[gBankTarget] = gBankAttacker; + gWishFutureKnock.futureSightCounter[gBankTarget] = 3; + gWishFutureKnock.futureSightDmg[gBankTarget] = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankTarget], gCurrentMove, + gSideAffecting[GetBattlerPosition(gBankTarget) & 1], 0, + 0, gBankAttacker, gBankTarget); + + if (gProtectStructs[gBankAttacker].helpingHand) + gWishFutureKnock.futureSightDmg[gBankTarget] = gWishFutureKnock.futureSightDmg[gBankTarget] * 15 / 10; + + if (gCurrentMove == MOVE_DOOM_DESIRE) + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + + gBattlescriptCurrInstr += 5; + } +} + +#ifdef NONMATCHING +static void atkC4_trydobeatup(void) +{ + register struct Pokemon* party asm("r7"); + if (GetBattlerSide(gBankAttacker) == 0) + party = gPlayerParty; + else + party = gEnemyParty; + + if (gBattleMons[gBankTarget].hp == 0) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + { + while (gBattleCommunication[0] < 6) + { + if (GetMonData(&party[gBattleCommunication[0]], MON_DATA_HP) && GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2) + && GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2) != SPECIES_EGG && !GetMonData(&party[gBattleCommunication[0]], MON_DATA_STATUS)) + break; + gBattleCommunication[0]++; + } + if (gBattleCommunication[0] < 6) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 4; + gBattleTextBuff1[2] = gBankAttacker; + gBattleTextBuff1[3] = gBattleCommunication[0]; + gBattleTextBuff1[4] = 0xFF; + gBattlescriptCurrInstr += 9; + + gBattleMoveDamage = gBaseStats[GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES)].baseAttack; + gBattleMoveDamage *= gBattleMoves[gCurrentMove].power; + gBattleMoveDamage *= (GetMonData(&party[gBattleCommunication[0]], MON_DATA_LEVEL) * 2 / 5 + 2); + gBattleMoveDamage /= gBaseStats[gBattleMons[gBankTarget].species].baseDefense; + gBattleMoveDamage = (gBattleMoveDamage / 50) + 2; + if (gProtectStructs[gBankAttacker].helpingHand) + gBattleMoveDamage = gBattleMoveDamage * 15 / 10; + + gBattleCommunication[0]++; + } + else if (gBattleCommunication[0] != 0) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 5); + } +} +#else +NAKED +static void atkC4_trydobeatup(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r9\n\ + mov r6, r8\n\ + push {r6,r7}\n\ + ldr r0, _08029A8C @ =gBankAttacker\n\ + ldrb r0, [r0]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + ldr r7, _08029A90 @ =gEnemyParty\n\ + cmp r0, 0\n\ + bne _08029A62\n\ + ldr r7, _08029A94 @ =gPlayerParty\n\ +_08029A62:\n\ + ldr r2, _08029A98 @ =gBattleMons\n\ + ldr r0, _08029A9C @ =gBankTarget\n\ + ldrb r1, [r0]\n\ + movs r0, 0x58\n\ + muls r0, r1\n\ + adds r0, r2\n\ + ldrh r0, [r0, 0x28]\n\ + cmp r0, 0\n\ + bne _08029AA4\n\ + ldr r3, _08029AA0 @ =gBattlescriptCurrInstr\n\ + ldr r2, [r3]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + b _08029C40\n\ + .align 2, 0\n\ +_08029A8C: .4byte gBankAttacker\n\ +_08029A90: .4byte gEnemyParty\n\ +_08029A94: .4byte gPlayerParty\n\ +_08029A98: .4byte gBattleMons\n\ +_08029A9C: .4byte gBankTarget\n\ +_08029AA0: .4byte gBattlescriptCurrInstr\n\ +_08029AA4:\n\ + ldr r6, _08029BE0 @ =gBattleCommunication\n\ + ldrb r0, [r6]\n\ + mov r8, r0\n\ + cmp r0, 0x5\n\ + bls _08029AB0\n\ + b _08029C0C\n\ +_08029AB0:\n\ + adds r4, r6, 0\n\ + movs r5, 0x64\n\ +_08029AB4:\n\ + ldrb r0, [r4]\n\ + muls r0, r5\n\ + adds r0, r7, r0\n\ + movs r1, 0x39\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _08029AF8\n\ + ldrb r0, [r6]\n\ + muls r0, r5\n\ + adds r0, r7, r0\n\ + movs r1, 0x41\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _08029AF8\n\ + ldrb r0, [r4]\n\ + muls r0, r5\n\ + adds r0, r7, r0\n\ + movs r1, 0x41\n\ + bl GetMonData\n\ + movs r1, 0xCE\n\ + lsls r1, 1\n\ + cmp r0, r1\n\ + beq _08029AF8\n\ + ldrb r0, [r4]\n\ + muls r0, r5\n\ + adds r0, r7, r0\n\ + movs r1, 0x37\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _08029B08\n\ +_08029AF8:\n\ + ldrb r0, [r4]\n\ + adds r0, 0x1\n\ + strb r0, [r4]\n\ + adds r6, r4, 0\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x5\n\ + bls _08029AB4\n\ +_08029B08:\n\ + ldr r1, _08029BE0 @ =gBattleCommunication\n\ + mov r9, r1\n\ + ldrb r2, [r1]\n\ + cmp r2, 0x5\n\ + bhi _08029C0C\n\ + ldr r1, _08029BE4 @ =gBattleTextBuff1\n\ + movs r0, 0xFD\n\ + strb r0, [r1]\n\ + movs r0, 0x4\n\ + strb r0, [r1, 0x1]\n\ + ldr r6, _08029BE8 @ =gBankAttacker\n\ + ldrb r0, [r6]\n\ + strb r0, [r1, 0x2]\n\ + strb r2, [r1, 0x3]\n\ + movs r0, 0xFF\n\ + strb r0, [r1, 0x4]\n\ + ldr r1, _08029BEC @ =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x9\n\ + str r0, [r1]\n\ + ldr r2, _08029BF0 @ =gBattleMoveDamage\n\ + mov r8, r2\n\ + ldr r5, _08029BF4 @ =gBaseStats\n\ + mov r1, r9\n\ + ldrb r0, [r1]\n\ + movs r4, 0x64\n\ + muls r0, r4\n\ + adds r0, r7, r0\n\ + movs r1, 0xB\n\ + bl GetMonData\n\ + lsls r1, r0, 3\n\ + subs r1, r0\n\ + lsls r1, 2\n\ + adds r1, r5\n\ + ldrb r3, [r1, 0x1]\n\ + mov r2, r8\n\ + str r3, [r2]\n\ + ldr r2, _08029BF8 @ =gBattleMoves\n\ + ldr r0, _08029BFC @ =gCurrentMove\n\ + ldrh r1, [r0]\n\ + lsls r0, r1, 1\n\ + adds r0, r1\n\ + lsls r0, 2\n\ + adds r0, r2\n\ + ldrb r0, [r0, 0x1]\n\ + muls r0, r3\n\ + mov r1, r8\n\ + str r0, [r1]\n\ + mov r2, r9\n\ + ldrb r0, [r2]\n\ + muls r0, r4\n\ + adds r0, r7, r0\n\ + movs r1, 0x38\n\ + bl GetMonData\n\ + lsls r0, 1\n\ + movs r1, 0x5\n\ + bl __udivsi3\n\ + adds r0, 0x2\n\ + mov r2, r8\n\ + ldr r1, [r2]\n\ + muls r0, r1\n\ + str r0, [r2]\n\ + ldr r3, _08029C00 @ =gBattleMons\n\ + ldr r1, _08029C04 @ =gBankTarget\n\ + ldrb r2, [r1]\n\ + movs r1, 0x58\n\ + muls r1, r2\n\ + adds r1, r3\n\ + ldrh r2, [r1]\n\ + lsls r1, r2, 3\n\ + subs r1, r2\n\ + lsls r1, 2\n\ + adds r1, r5\n\ + ldrb r1, [r1, 0x2]\n\ + bl __divsi3\n\ + mov r1, r8\n\ + str r0, [r1]\n\ + movs r1, 0x32\n\ + bl __divsi3\n\ + adds r2, r0, 0x2\n\ + mov r0, r8\n\ + str r2, [r0]\n\ + ldr r1, _08029C08 @ =gProtectStructs\n\ + ldrb r0, [r6]\n\ + lsls r0, 4\n\ + adds r0, r1\n\ + ldrb r0, [r0]\n\ + lsls r0, 28\n\ + cmp r0, 0\n\ + bge _08029BD4\n\ + lsls r0, r2, 4\n\ + subs r0, r2\n\ + movs r1, 0xA\n\ + bl __divsi3\n\ + mov r1, r8\n\ + str r0, [r1]\n\ +_08029BD4:\n\ + mov r2, r9\n\ + ldrb r0, [r2]\n\ + adds r0, 0x1\n\ + strb r0, [r2]\n\ + b _08029C46\n\ + .align 2, 0\n\ +_08029BE0: .4byte gBattleCommunication\n\ +_08029BE4: .4byte gBattleTextBuff1\n\ +_08029BE8: .4byte gBankAttacker\n\ +_08029BEC: .4byte gBattlescriptCurrInstr\n\ +_08029BF0: .4byte gBattleMoveDamage\n\ +_08029BF4: .4byte gBaseStats\n\ +_08029BF8: .4byte gBattleMoves\n\ +_08029BFC: .4byte gCurrentMove\n\ +_08029C00: .4byte gBattleMons\n\ +_08029C04: .4byte gBankTarget\n\ +_08029C08: .4byte gProtectStructs\n\ +_08029C0C:\n\ + mov r0, r8\n\ + cmp r0, 0\n\ + beq _08029C2C\n\ + ldr r3, _08029C28 @ =gBattlescriptCurrInstr\n\ + ldr r2, [r3]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + b _08029C40\n\ + .align 2, 0\n\ +_08029C28: .4byte gBattlescriptCurrInstr\n\ +_08029C2C:\n\ + ldr r3, _08029C54 @ =gBattlescriptCurrInstr\n\ + ldr r2, [r3]\n\ + ldrb r1, [r2, 0x5]\n\ + ldrb r0, [r2, 0x6]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x7]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x8]\n\ +_08029C40:\n\ + lsls r0, 24\n\ + orrs r1, r0\n\ + str r1, [r3]\n\ +_08029C46:\n\ + pop {r3,r4}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_08029C54: .4byte gBattlescriptCurrInstr\n\ + .syntax divided"); +} +#endif // NONMATCHING + +static void atkC5_setsemiinvulnerablebit(void) +{ + switch (gCurrentMove) + { + case MOVE_FLY: + case MOVE_BOUNCE: + gStatuses3[gBankAttacker] |= STATUS3_ON_AIR; + break; + case MOVE_DIG: + gStatuses3[gBankAttacker] |= STATUS3_UNDERGROUND; + break; + case MOVE_DIVE: + gStatuses3[gBankAttacker] |= STATUS3_UNDERWATER; + break; + } + gBattlescriptCurrInstr++; +} + +static void atkC6_clearsemiinvulnerablebit(void) +{ + switch (gCurrentMove) + { + case MOVE_FLY: + case MOVE_BOUNCE: + gStatuses3[gBankAttacker] &= ~STATUS3_ON_AIR; + break; + case MOVE_DIG: + gStatuses3[gBankAttacker] &= ~STATUS3_UNDERGROUND; + break; + case MOVE_DIVE: + gStatuses3[gBankAttacker] &= ~STATUS3_UNDERWATER; + break; + } + gBattlescriptCurrInstr++; +} + +static void atkC7_setminimize(void) +{ + if (gHitMarker & HITMARKER_OBEYS) + gStatuses3[gBankAttacker] |= STATUS3_MINIMIZED; + gBattlescriptCurrInstr++; +} + +static void atkC8_sethail(void) +{ + if (gBattleWeather & WEATHER_HAIL) + { + gMoveResultFlags |= MOVE_RESULT_MISSED; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else + { + gBattleWeather = WEATHER_HAIL; + gBattleCommunication[MULTISTRING_CHOOSER] = 5; + gWishFutureKnock.weatherDuration = 5; + } + gBattlescriptCurrInstr++; +} + +static void atkC9_jumpifattackandspecialattackcannotfall(void) //memento +{ + if (gBattleMons[gBankTarget].statStages[STAT_STAGE_ATK] == 0 + && gBattleMons[gBankTarget].statStages[STAT_STAGE_SPATK] == 0 + && gBattleCommunication[6] != 1) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + { + gActiveBattler = gBankAttacker; + gBattleMoveDamage = gBattleMons[gActiveBattler].hp; + EmitHealthBarUpdate(0, 0x7FFF); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 5; + } +} + +static void atkCA_setforcedtarget(void) //follow me +{ + gSideTimers[GetBattlerSide(gBankAttacker)].followmeTimer = 1; + gSideTimers[GetBattlerSide(gBankAttacker)].followmeTarget = gBankAttacker; + gBattlescriptCurrInstr++; +} + +static void atkCB_setcharge(void) +{ + gStatuses3[gBankAttacker] |= STATUS3_CHARGED_UP; + gDisableStructs[gBankAttacker].chargeTimer1 = 2; + gDisableStructs[gBankAttacker].chargeTimer2 = 2; + gBattlescriptCurrInstr++; +} + +static void atkCC_callterrainattack(void) //nature power +{ + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gCurrentMove = sNaturePowerMoves[gBattleTerrain]; + gBankTarget = GetMoveTarget(gCurrentMove, 0); + BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]); + gBattlescriptCurrInstr++; +} + +static void atkCD_cureifburnedparalysedorpoisoned(void) //refresh +{ + if (gBattleMons[gBankAttacker].status1 & (STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS | STATUS_TOXIC_POISON)) + { + gBattleMons[gBankAttacker].status1 = 0; + gBattlescriptCurrInstr += 5; + gActiveBattler = gBankAttacker; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); + MarkBufferBankForExecution(gActiveBattler); + } + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atkCE_settorment(void) +{ + if (gBattleMons[gBankTarget].status2 & STATUS2_TORMENT) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + { + gBattleMons[gBankTarget].status2 |= STATUS2_TORMENT; + gBattlescriptCurrInstr += 5; + } +} + +static void atkCF_jumpifnodamage(void) +{ + if (gProtectStructs[gBankAttacker].physicalDmg || gProtectStructs[gBankAttacker].specialDmg) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atkD0_settaunt(void) +{ + if (gDisableStructs[gBankTarget].tauntTimer1 == 0) + { + gDisableStructs[gBankTarget].tauntTimer1 = 2; + gDisableStructs[gBankTarget].tauntTimer2 = 2; + gBattlescriptCurrInstr += 5; + } + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atkD1_trysethelpinghand(void) +{ + gBankTarget = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ 2); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gAbsentBattlerFlags & gBitTable[gBankTarget]) + && !gProtectStructs[gBankAttacker].helpingHand && !gProtectStructs[gBankTarget].helpingHand) + { + gProtectStructs[gBankTarget].helpingHand = 1; + gBattlescriptCurrInstr += 5; + } + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +#ifdef NONMATCHING +static void atkD2_tryswapitems(void) +{ + if ((GetBattlerSide(gBankAttacker) != 1 || gBattleTypeFlags & (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER) || gTrainerBattleOpponent == SECRET_BASE_OPPONENT)) + { + u8 side = GetBattlerSide(gBankAttacker); + if (gBattleTypeFlags) + } + + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +#else +NAKED +static void atkD2_tryswapitems(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x4\n\ + ldr r0, _0802A30C @ =gBankAttacker\n\ + ldrb r0, [r0]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + cmp r0, 0x1\n\ + bne _0802A24C\n\ + ldr r0, _0802A310 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + ldr r0, _0802A314 @ =0x00000902\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0802A24C\n\ + ldr r0, _0802A318 @ =gTrainerBattleOpponent\n\ + ldrh r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 3\n\ + cmp r1, r0\n\ + bne _0802A2EE\n\ +_0802A24C:\n\ + ldr r4, _0802A30C @ =gBankAttacker\n\ + ldrb r0, [r4]\n\ + bl GetBattlerSide\n\ + lsls r0, 24\n\ + lsrs r2, r0, 24\n\ + ldr r0, _0802A310 @ =gBattleTypeFlags\n\ + ldrh r1, [r0]\n\ + ldr r0, _0802A314 @ =0x00000902\n\ + ands r0, r1\n\ + cmp r0, 0\n\ + bne _0802A290\n\ + ldr r0, _0802A318 @ =gTrainerBattleOpponent\n\ + ldrh r1, [r0]\n\ + movs r0, 0x80\n\ + lsls r0, 3\n\ + cmp r1, r0\n\ + beq _0802A290\n\ + ldr r0, _0802A31C @ =gWishFutureKnock\n\ + adds r0, 0x29\n\ + adds r0, r2, r0\n\ + ldrb r1, [r0]\n\ + ldr r3, _0802A320 @ =gBitTable\n\ + ldr r2, _0802A324 @ =gBattlerPartyIndexes\n\ + ldrb r0, [r4]\n\ + lsls r0, 1\n\ + adds r0, r2\n\ + ldrh r0, [r0]\n\ + lsls r0, 2\n\ + adds r0, r3\n\ + ldr r0, [r0]\n\ + ands r1, r0\n\ + cmp r1, 0\n\ + bne _0802A2EE\n\ +_0802A290:\n\ + ldr r0, _0802A328 @ =gBattleMons\n\ + mov r9, r0\n\ + ldr r1, _0802A30C @ =gBankAttacker\n\ + ldrb r4, [r1]\n\ + movs r2, 0x58\n\ + mov r8, r2\n\ + mov r0, r8\n\ + muls r0, r4\n\ + mov r3, r9\n\ + adds r5, r0, r3\n\ + ldrh r3, [r5, 0x2E]\n\ + adds r1, r3, 0\n\ + cmp r1, 0\n\ + bne _0802A2BE\n\ + ldr r0, _0802A32C @ =gBankTarget\n\ + ldrb r0, [r0]\n\ + mov r2, r8\n\ + muls r2, r0\n\ + adds r0, r2, 0\n\ + add r0, r9\n\ + ldrh r0, [r0, 0x2E]\n\ + cmp r0, 0\n\ + beq _0802A2EE\n\ +_0802A2BE:\n\ + cmp r1, 0xAF\n\ + beq _0802A2EE\n\ + ldr r7, _0802A32C @ =gBankTarget\n\ + ldrb r0, [r7]\n\ + mov r1, r8\n\ + muls r1, r0\n\ + adds r0, r1, 0\n\ + mov r1, r9\n\ + adds r2, r0, r1\n\ + ldrh r1, [r2, 0x2E]\n\ + cmp r1, 0xAF\n\ + beq _0802A2EE\n\ + adds r0, r3, 0\n\ + subs r0, 0x79\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r0, 0xB\n\ + bls _0802A2EE\n\ + adds r0, r1, 0\n\ + subs r0, 0x79\n\ + lsls r0, 16\n\ + lsrs r0, 16\n\ + cmp r0, 0xB\n\ + bhi _0802A334\n\ +_0802A2EE:\n\ + ldr r3, _0802A330 @ =gBattlescriptCurrInstr\n\ + ldr r2, [r3]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 24\n\ + orrs r1, r0\n\ + str r1, [r3]\n\ + b _0802A49A\n\ + .align 2, 0\n\ +_0802A30C: .4byte gBankAttacker\n\ +_0802A310: .4byte gBattleTypeFlags\n\ +_0802A314: .4byte 0x00000902\n\ +_0802A318: .4byte gTrainerBattleOpponent\n\ +_0802A31C: .4byte gWishFutureKnock\n\ +_0802A320: .4byte gBitTable\n\ +_0802A324: .4byte gBattlerPartyIndexes\n\ +_0802A328: .4byte gBattleMons\n\ +_0802A32C: .4byte gBankTarget\n\ +_0802A330: .4byte gBattlescriptCurrInstr\n\ +_0802A334:\n\ + adds r0, r2, 0\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + cmp r0, 0x3C\n\ + bne _0802A36C\n\ + ldr r1, _0802A360 @ =gBattlescriptCurrInstr\n\ + ldr r0, _0802A364 @ =BattleScript_NoItemSteal\n\ + str r0, [r1]\n\ + ldr r1, _0802A368 @ =gLastUsedAbility\n\ + ldrb r0, [r7]\n\ + mov r2, r8\n\ + muls r2, r0\n\ + adds r0, r2, 0\n\ + add r0, r9\n\ + adds r0, 0x20\n\ + ldrb r0, [r0]\n\ + strb r0, [r1]\n\ + ldrb r0, [r7]\n\ + ldrb r1, [r1]\n\ + bl RecordAbilityBattle\n\ + b _0802A49A\n\ + .align 2, 0\n\ +_0802A360: .4byte gBattlescriptCurrInstr\n\ +_0802A364: .4byte BattleScript_NoItemSteal\n\ +_0802A368: .4byte gLastUsedAbility\n\ +_0802A36C:\n\ + lsls r0, r4, 1\n\ + ldr r4, _0802A458 @ =gSharedMem + 0x160F0\n\ + adds r6, r0, r4\n\ + ldrh r5, [r5, 0x2E]\n\ + mov r10, r5\n\ + strh r1, [r6]\n\ + ldr r3, _0802A45C @ =gBankAttacker\n\ + ldrb r0, [r3]\n\ + mov r1, r8\n\ + muls r1, r0\n\ + adds r0, r1, 0\n\ + add r0, r9\n\ + movs r1, 0\n\ + strh r1, [r0, 0x2E]\n\ + ldrb r0, [r7]\n\ + mov r2, r8\n\ + muls r2, r0\n\ + adds r0, r2, 0\n\ + add r0, r9\n\ + mov r3, r10\n\ + strh r3, [r0, 0x2E]\n\ + ldr r5, _0802A460 @ =gActiveBattler\n\ + ldr r1, _0802A45C @ =gBankAttacker\n\ + ldrb r0, [r1]\n\ + strb r0, [r5]\n\ + str r6, [sp]\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + movs r2, 0\n\ + movs r3, 0x2\n\ + bl EmitSetMonData\n\ + ldr r2, _0802A45C @ =gBankAttacker\n\ + ldrb r0, [r2]\n\ + bl MarkBufferBankForExecution\n\ + ldrb r0, [r7]\n\ + strb r0, [r5]\n\ + ldrb r0, [r7]\n\ + mov r3, r8\n\ + muls r3, r0\n\ + adds r0, r3, 0\n\ + mov r1, r9\n\ + adds r1, 0x2E\n\ + adds r0, r1\n\ + str r0, [sp]\n\ + movs r0, 0\n\ + movs r1, 0x2\n\ + movs r2, 0\n\ + movs r3, 0x2\n\ + bl EmitSetMonData\n\ + ldrb r0, [r7]\n\ + bl MarkBufferBankForExecution\n\ + ldr r0, _0802A464 @ =0xfffe9f10\n\ + adds r4, r0\n\ + ldrb r0, [r7]\n\ + lsls r0, 1\n\ + ldr r2, _0802A468 @ =0x000160e8\n\ + adds r0, r2\n\ + adds r0, r4\n\ + movs r1, 0\n\ + strb r1, [r0]\n\ + ldrb r0, [r7]\n\ + lsls r0, 1\n\ + ldr r1, _0802A46C @ =0x000160e9\n\ + adds r0, r1\n\ + adds r0, r4\n\ + movs r3, 0\n\ + strb r3, [r0]\n\ + ldr r3, _0802A45C @ =gBankAttacker\n\ + ldrb r0, [r3]\n\ + lsls r0, 1\n\ + adds r0, r2\n\ + adds r0, r4\n\ + movs r2, 0\n\ + strb r2, [r0]\n\ + ldrb r0, [r3]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + adds r0, r4\n\ + strb r2, [r0]\n\ + ldr r1, _0802A470 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x5\n\ + str r0, [r1]\n\ + ldr r1, _0802A474 @ =gBattleTextBuff1\n\ + movs r3, 0xFD\n\ + strb r3, [r1]\n\ + movs r2, 0xA\n\ + strb r2, [r1, 0x1]\n\ + ldrh r0, [r6]\n\ + strb r0, [r1, 0x2]\n\ + ldrh r0, [r6]\n\ + lsrs r0, 8\n\ + strb r0, [r1, 0x3]\n\ + movs r0, 0xFF\n\ + strb r0, [r1, 0x4]\n\ + ldr r1, _0802A478 @ =gBattleTextBuff2\n\ + strb r3, [r1]\n\ + strb r2, [r1, 0x1]\n\ + mov r3, r10\n\ + strb r3, [r1, 0x2]\n\ + mov r2, r10\n\ + lsrs r0, r2, 8\n\ + strb r0, [r1, 0x3]\n\ + movs r0, 0x1\n\ + negs r0, r0\n\ + strb r0, [r1, 0x4]\n\ + cmp r2, 0\n\ + beq _0802A480\n\ + ldrh r0, [r6]\n\ + cmp r0, 0\n\ + beq _0802A494\n\ + ldr r1, _0802A47C @ =gBattleCommunication\n\ + movs r0, 0x2\n\ + b _0802A498\n\ + .align 2, 0\n\ +_0802A458: .4byte gSharedMem + 0x160F0\n\ +_0802A45C: .4byte gBankAttacker\n\ +_0802A460: .4byte gActiveBattler\n\ +_0802A464: .4byte 0xfffe9f10\n\ +_0802A468: .4byte 0x000160e8\n\ +_0802A46C: .4byte 0x000160e9\n\ +_0802A470: .4byte gBattlescriptCurrInstr\n\ +_0802A474: .4byte gBattleTextBuff1\n\ +_0802A478: .4byte gBattleTextBuff2\n\ +_0802A47C: .4byte gBattleCommunication\n\ +_0802A480:\n\ + ldrh r0, [r6]\n\ + cmp r0, 0\n\ + beq _0802A494\n\ + ldr r0, _0802A490 @ =gBattleCommunication\n\ + movs r3, 0\n\ + strb r3, [r0, 0x5]\n\ + b _0802A49A\n\ + .align 2, 0\n\ +_0802A490: .4byte gBattleCommunication\n\ +_0802A494:\n\ + ldr r1, _0802A4AC @ =gBattleCommunication\n\ + movs r0, 0x1\n\ +_0802A498:\n\ + strb r0, [r1, 0x5]\n\ +_0802A49A:\n\ + add sp, 0x4\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0802A4AC: .4byte gBattleCommunication\n\ + .syntax divided"); +} +#endif // NONMATCHING + +static void atkD3_trycopyability(void) //role play +{ + if (gBattleMons[gBankTarget].ability != 0 && gBattleMons[gBankTarget].ability != ABILITY_WONDER_GUARD) + { + gBattleMons[gBankAttacker].ability = gBattleMons[gBankTarget].ability; + gLastUsedAbility = gBattleMons[gBankTarget].ability; + gBattlescriptCurrInstr += 5; + } + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atkD4_trywish(void) +{ + switch (T2_READ_8(gBattlescriptCurrInstr + 1)) + { + case 0: //use wish + if (gWishFutureKnock.wishCounter[gBankAttacker] == 0) + { + gWishFutureKnock.wishCounter[gBankAttacker] = 2; + gWishFutureKnock.wishUserID[gBankAttacker] = gBattlerPartyIndexes[gBankAttacker]; + gBattlescriptCurrInstr += 6; + } + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + break; + case 1: //heal effect + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 4; + gBattleTextBuff1[2] = gBankTarget; + gBattleTextBuff1[3] = gWishFutureKnock.wishUserID[gBankTarget]; + gBattleTextBuff1[4] = 0xFF; + gBattleMoveDamage = gBattleMons[gBankTarget].maxHP / 2; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + if (gBattleMons[gBankTarget].hp == gBattleMons[gBankTarget].maxHP) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; + break; + } +} + +static void atkD5_trysetroots(void) //ingrain +{ + if (gStatuses3[gBankAttacker] & STATUS3_ROOTED) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + { + gStatuses3[gBankAttacker] |= STATUS3_ROOTED; + gBattlescriptCurrInstr += 5; + } +} + +static void atkD6_doubledamagedealtifdamaged(void) +{ + if ((gProtectStructs[gBankAttacker].physicalDmg && gProtectStructs[gBankAttacker].physicalBank == gBankTarget) + || (gProtectStructs[gBankAttacker].specialDmg && gProtectStructs[gBankAttacker].specialBank == gBankTarget)) + gBattleStruct->dmgMultiplier = 2; + gBattlescriptCurrInstr++; +} + +static void atkD7_setyawn(void) +{ + if (gStatuses3[gBankTarget] & STATUS3_YAWN || (u8) gBattleMons[gBankTarget].status1) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + { + gStatuses3[gBankTarget] |= 0x1000; + gBattlescriptCurrInstr += 5; + } +} + +static void atkD8_setdamagetohealthdifference(void) +{ + if (gBattleMons[gBankTarget].hp <= gBattleMons[gBankAttacker].hp) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else + { + gBattleMoveDamage = gBattleMons[gBankTarget].hp - gBattleMons[gBankAttacker].hp; + gBattlescriptCurrInstr += 5; + } +} + +static void atkD9_scaledamagebyhealthratio(void) +{ + if (gDynamicBasePower == 0) + { + u8 power = gBattleMoves[gCurrentMove].power; + gDynamicBasePower = gBattleMons[gBankAttacker].hp * power / gBattleMons[gBankAttacker].maxHP; + if (gDynamicBasePower == 0) + gDynamicBasePower = 1; + } + gBattlescriptCurrInstr++; +} + +static void atkDA_tryswapabilities(void) +{ + if ((gBattleMons[gBankAttacker].ability == 0 && gBattleMons[gBankTarget].ability == 0) + || gBattleMons[gBankAttacker].ability == ABILITY_WONDER_GUARD || gBattleMons[gBankTarget].ability == ABILITY_WONDER_GUARD + || gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + { + u8 atk_ability = gBattleMons[gBankAttacker].ability; + gBattleMons[gBankAttacker].ability = gBattleMons[gBankTarget].ability; + gBattleMons[gBankTarget].ability = atk_ability; + gBattlescriptCurrInstr += 5; + } +} + +static void atkDB_tryimprision(void) +{ + u8 r8 = 0; + if ((gStatuses3[gBankAttacker] & STATUS3_IMPRISIONED)) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else + { + u8 bank; + PressurePPLoseOnUsingImprision(gBankAttacker); + for (bank = 0; bank < gBattlersCount; bank++) + { + if (r8 != GetBattlerSide(bank)) + { + int j; + for (j = 0; j < 4; j++) + { + int k; + for (k = 0; k < 4; k++) + { + if (gBattleMons[gBankAttacker].moves[j] == gBattleMons[bank].moves[k] && gBattleMons[gBankAttacker].moves[j]) + break; + } + if (k != 4) + break; + } + if (j != 4) + { + gStatuses3[gBankAttacker] |= STATUS3_IMPRISIONED; + gBattlescriptCurrInstr += 5; + break; + } + } + } + if (bank == gBattlersCount) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } +} + +static void atkDC_trysetgrudge(void) +{ + if (gStatuses3[gBankAttacker] & STATUS3_GRUDGE) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + { + gStatuses3[gBankAttacker] |= STATUS3_GRUDGE; + gBattlescriptCurrInstr += 5; + } +} + +static void atkDD_weightdamagecalculation(void) +{ + int i; + for (i = 0; sWeightToDamageTable[i] != 0xFFFF; i += 2) + { + if (sWeightToDamageTable[i] > GetPokedexHeightWeight(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), 1)) + break; + } + if (sWeightToDamageTable[i] != 0xFFFF) + gDynamicBasePower = sWeightToDamageTable[i + 1]; + else + gDynamicBasePower = 120; + gBattlescriptCurrInstr++; +} + +#ifdef NONMATCHING +static void atkDE_asistattackselect(void) +{ + u32 chooseable_moves_no = 0; + struct Pokemon* party; + int i, j; + u16* chooseable_moves; + if (GetBattlerPosition(gBankAttacker) & 1) + party = gEnemyParty; + else + party = gPlayerParty; + + for (i = 0; i < 6; i++) + { + if (i == gBattlerPartyIndexes[gBankAttacker]) + break; + if (!GetMonData(&party[i], MON_DATA_SPECIES2) || GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_EGG) + break; + chooseable_moves = &gBattleStruct->assistMove[chooseable_moves_no]; + for (j = 0; j < 4; j++) + { + int k; + u16 move = GetMonData(&party[i], MON_DATA_MOVE1 + i); + if (IsMoveUnchoosable(move)) + break; + //sMovesForbiddenToCopy[k] + for (k = 0; ;k++) + { + if (sMovesForbiddenToCopy[k] == 0xFFFF) + { + if (move) + { + *chooseable_moves = move; + chooseable_moves++; + chooseable_moves_no++; + } + break; + } + if (sMovesForbiddenToCopy[k] == move) + break; + } + } + } + if (chooseable_moves_no) + { + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gRandomMove = gBattleStruct->assistMove[Random() % chooseable_moves_no]; + gBankTarget = GetMoveTarget(gRandomMove, 0); + gBattlescriptCurrInstr += 5; + } + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +#else +NAKED +static void atkDE_asistattackselect(void) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x8\n\ + movs r0, 0\n\ + mov r10, r0\n\ + ldr r0, _0802AB9C @ =gBankAttacker\n\ + ldrb r0, [r0]\n\ + bl GetBattlerPosition\n\ + movs r1, 0x1\n\ + ands r1, r0\n\ + ldr r0, _0802ABA0 @ =gPlayerParty\n\ + str r0, [sp]\n\ + cmp r1, 0\n\ + beq _0802AAAC\n\ + ldr r1, _0802ABA4 @ =gEnemyParty\n\ + str r1, [sp]\n\ +_0802AAAC:\n\ + movs r2, 0\n\ +_0802AAAE:\n\ + ldr r1, _0802ABA8 @ =gBattlerPartyIndexes\n\ + ldr r0, _0802AB9C @ =gBankAttacker\n\ + ldrb r0, [r0]\n\ + lsls r0, 1\n\ + adds r0, r1\n\ + adds r1, r2, 0x1\n\ + str r1, [sp, 0x4]\n\ + ldrh r0, [r0]\n\ + cmp r2, r0\n\ + beq _0802AB54\n\ + movs r0, 0x64\n\ + adds r6, r2, 0\n\ + muls r6, r0\n\ + ldr r0, [sp]\n\ + adds r4, r0, r6\n\ + adds r0, r4, 0\n\ + movs r1, 0x41\n\ + bl GetMonData\n\ + cmp r0, 0\n\ + beq _0802AB54\n\ + adds r0, r4, 0\n\ + movs r1, 0x41\n\ + bl GetMonData\n\ + movs r1, 0xCE\n\ + lsls r1, 1\n\ + cmp r0, r1\n\ + beq _0802AB54\n\ + movs r5, 0\n\ + ldr r1, _0802ABAC @ =0x0000ffff\n\ + mov r8, r1\n\ + mov r9, r6\n\ + mov r1, r10\n\ + lsls r0, r1, 1\n\ + ldr r1, _0802ABB0 @ =gSharedMem + 0x16024\n\ + adds r6, r0, r1\n\ +_0802AAF8:\n\ + movs r7, 0\n\ + adds r1, r5, 0\n\ + adds r1, 0xD\n\ + ldr r0, [sp]\n\ + add r0, r9\n\ + bl GetMonData\n\ + lsls r0, 16\n\ + lsrs r4, r0, 16\n\ + adds r0, r4, 0\n\ + bl IsMoveUnchoosable\n\ + lsls r0, 24\n\ + adds r1, r5, 0x1\n\ + cmp r0, 0\n\ + bne _0802AB4E\n\ + ldr r0, _0802ABB4 @ =sMovesForbiddenToCopy\n\ + ldrh r2, [r0]\n\ + adds r3, r0, 0\n\ + cmp r2, r8\n\ + beq _0802AB42\n\ + cmp r4, r2\n\ + beq _0802AB38\n\ + ldr r5, _0802ABAC @ =0x0000ffff\n\ + adds r2, r3, 0\n\ +_0802AB2A:\n\ + adds r2, 0x2\n\ + adds r7, 0x1\n\ + ldrh r0, [r2]\n\ + cmp r0, r5\n\ + beq _0802AB42\n\ + cmp r4, r0\n\ + bne _0802AB2A\n\ +_0802AB38:\n\ + lsls r0, r7, 1\n\ + adds r0, r3\n\ + ldrh r0, [r0]\n\ + cmp r0, r8\n\ + bne _0802AB4E\n\ +_0802AB42:\n\ + cmp r4, 0\n\ + beq _0802AB4E\n\ + strh r4, [r6]\n\ + adds r6, 0x2\n\ + movs r0, 0x1\n\ + add r10, r0\n\ +_0802AB4E:\n\ + adds r5, r1, 0\n\ + cmp r5, 0x3\n\ + ble _0802AAF8\n\ +_0802AB54:\n\ + ldr r2, [sp, 0x4]\n\ + cmp r2, 0x5\n\ + ble _0802AAAE\n\ + mov r1, r10\n\ + cmp r1, 0\n\ + beq _0802ABCC\n\ + ldr r2, _0802ABB8 @ =gHitMarker\n\ + ldr r0, [r2]\n\ + ldr r1, _0802ABBC @ =0xfffffbff\n\ + ands r0, r1\n\ + str r0, [r2]\n\ + ldr r4, _0802ABC0 @ =gRandomMove\n\ + bl Random\n\ + movs r1, 0xFF\n\ + ands r1, r0\n\ + mov r0, r10\n\ + muls r0, r1\n\ + asrs r0, 8\n\ + lsls r0, 1\n\ + ldr r1, _0802ABB0 @ =gSharedMem + 0x16024\n\ + adds r0, r1\n\ + ldrh r0, [r0]\n\ + strh r0, [r4]\n\ + ldrh r0, [r4]\n\ + movs r1, 0\n\ + bl GetMoveTarget\n\ + ldr r1, _0802ABC4 @ =gBankTarget\n\ + strb r0, [r1]\n\ + ldr r1, _0802ABC8 @ =gBattlescriptCurrInstr\n\ + ldr r0, [r1]\n\ + adds r0, 0x5\n\ + str r0, [r1]\n\ + b _0802ABE6\n\ + .align 2, 0\n\ +_0802AB9C: .4byte gBankAttacker\n\ +_0802ABA0: .4byte gPlayerParty\n\ +_0802ABA4: .4byte gEnemyParty\n\ +_0802ABA8: .4byte gBattlerPartyIndexes\n\ +_0802ABAC: .4byte 0x0000ffff\n\ +_0802ABB0: .4byte gSharedMem + 0x16024\n\ +_0802ABB4: .4byte sMovesForbiddenToCopy\n\ +_0802ABB8: .4byte gHitMarker\n\ +_0802ABBC: .4byte 0xfffffbff\n\ +_0802ABC0: .4byte gRandomMove\n\ +_0802ABC4: .4byte gBankTarget\n\ +_0802ABC8: .4byte gBattlescriptCurrInstr\n\ +_0802ABCC:\n\ + ldr r3, _0802ABF8 @ =gBattlescriptCurrInstr\n\ + ldr r2, [r3]\n\ + ldrb r1, [r2, 0x1]\n\ + ldrb r0, [r2, 0x2]\n\ + lsls r0, 8\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x3]\n\ + lsls r0, 16\n\ + orrs r1, r0\n\ + ldrb r0, [r2, 0x4]\n\ + lsls r0, 24\n\ + orrs r1, r0\n\ + str r1, [r3]\n\ +_0802ABE6:\n\ + add sp, 0x8\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0802ABF8: .4byte gBattlescriptCurrInstr\n\ + .syntax divided"); +} + +#endif // NONMATCHING + +static void atkDF_trysetmagiccoat(void) +{ + gBankTarget = gBankAttacker; + gSpecialStatuses[gBankAttacker].flag20 = 1; + if (gCurrentTurnActionNumber == gBattlersCount - 1) //last turn + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + { + gProtectStructs[gBankAttacker].bounceMove = 1; + gBattlescriptCurrInstr += 5; + } +} + +static void atkE0_trysetsnatch(void) +{ + gSpecialStatuses[gBankAttacker].flag20 = 1; + if (gCurrentTurnActionNumber == gBattlersCount - 1) //last turn + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + { + gProtectStructs[gBankAttacker].stealMove = 1; + gBattlescriptCurrInstr += 5; + } +} + +static void atkE1_trygetintimidatetarget(void) +{ + u8 side; + + gBattleStruct->scriptingActive = ewram160DD; + side = GetBattlerSide(gBattleStruct->scriptingActive); + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 9; + gBattleTextBuff1[2] = gBattleMons[gBattleStruct->scriptingActive].ability; + gBattleTextBuff1[3] = 0xFF; + + for (;gBankTarget < gBattlersCount; gBankTarget++) + { + if (GetBattlerSide(gBankTarget) == side) + continue; + if (!(gAbsentBattlerFlags & gBitTable[gBankTarget])) + break; + } + + if (gBankTarget >= gBattlersCount) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + gBattlescriptCurrInstr += 5; +} + +static void atkE2_switchoutabilities(void) +{ + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + switch (gBattleMons[gActiveBattler].ability) + { + case ABILITY_NATURAL_CURE: + gBattleMons[gActiveBattler].status1 = 0; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, gBitTable[ewram16064arr(gActiveBattler)], 4, &gBattleMons[gActiveBattler].status1); + MarkBufferBankForExecution(gActiveBattler); + break; + } + gBattlescriptCurrInstr += 2; +} + +static void atkE3_jumpifhasnohp(void) +{ + gActiveBattler = GetBattleBank(T2_READ_8(gBattlescriptCurrInstr + 1)); + if (gBattleMons[gActiveBattler].hp == 0) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + else + gBattlescriptCurrInstr += 6; +} + +static void atkE4_getsecretpowereffect(void) +{ + switch (gBattleTerrain) + { + case BATTLE_TERRAIN_GRASS: + gBattleCommunication[MOVE_EFFECT_BYTE] = 2; + break; + case BATTLE_TERRAIN_LONG_GRASS: + gBattleCommunication[MOVE_EFFECT_BYTE] = 1; + break; + case BATTLE_TERRAIN_SAND: + gBattleCommunication[MOVE_EFFECT_BYTE] = 27; + break; + case BATTLE_TERRAIN_UNDERWATER: + gBattleCommunication[MOVE_EFFECT_BYTE] = 23; + break; + case BATTLE_TERRAIN_WATER: + gBattleCommunication[MOVE_EFFECT_BYTE] = 22; + break; + case BATTLE_TERRAIN_POND: + gBattleCommunication[MOVE_EFFECT_BYTE] = 24; + break; + case BATTLE_TERRAIN_MOUNTAIN: + gBattleCommunication[MOVE_EFFECT_BYTE] = 7; + break; + case BATTLE_TERRAIN_CAVE: + gBattleCommunication[MOVE_EFFECT_BYTE] = 8; + break; + default: + gBattleCommunication[MOVE_EFFECT_BYTE] = 5; + break; + } + gBattlescriptCurrInstr++; +} + +static void atkE5_pickup(void) +{ + int i; + for (i = 0; i < 6; i++) + { + u16 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); + u16 held_item = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); + u8 ability; + if (GetMonData(&gPlayerParty[i], MON_DATA_ALT_ABILITY)) + ability = gBaseStats[species].ability2; + else + ability = gBaseStats[species].ability1; + + if (ability == ABILITY_PICKUP && species != 0 && species != SPECIES_EGG && held_item == 0 && (Random() % 10) == 0) + { + s32 chance = Random() % 100; + s32 j; + for (j = 0; j < 18; j += 2) + { + if (sPickupItems[j + 1] > chance) + break; + } + SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, (const void*) &sPickupItems[j]); + } + } + gBattlescriptCurrInstr++; +} + +static void atkE6_docastformchangeanimation(void) +{ + gActiveBattler = gBattleStruct->scriptingActive; + if (gBattleMons[gActiveBattler].status2 & STATUS2_SUBSTITUTE) + gBattleStruct->castformToChangeInto |= 0x80; + EmitBattleAnimation(0, B_ANIM_CASTFORM_CHANGE, gBattleStruct->castformToChangeInto); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr++; +} + +static void atkE7_trycastformdatachange(void) +{ + u8 form; + gBattlescriptCurrInstr++; + form = CastformDataTypeChange(gBattleStruct->scriptingActive); + if (form) + { + BattleScriptPushCursorAndCallback(BattleScript_CastformChange); + gBattleStruct->castformToChangeInto = form - 1; + } +} + +static void atkE8_settypebasedhalvers(void) //water/mud sport +{ + bool8 worked = FALSE; + if (gBattleMoves[gCurrentMove].effect == EFFECT_MUD_SPORT) + { + if (!(gStatuses3[gBankAttacker] & STATUS3_MUDSPORT)) + { + gStatuses3[gBankAttacker] |= STATUS3_MUDSPORT; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + worked = TRUE; + } + } + else //water sport + { + if (!(gStatuses3[gBankAttacker] & STATUS3_WATERSPORT)) + { + gStatuses3[gBankAttacker] |= STATUS3_WATERSPORT; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + worked = TRUE; + } + } + if (worked) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atkE9_setweatherballtype(void) +{ + if (WEATHER_HAS_EFFECT) + { + if ((u8)(gBattleWeather)) + gBattleStruct->dmgMultiplier = 2; + if (gBattleWeather & WEATHER_RAIN_ANY) + gBattleStruct->dynamicMoveType = TYPE_WATER | 0x80; + else if (gBattleWeather & WEATHER_SANDSTORM_ANY) + gBattleStruct->dynamicMoveType = TYPE_ROCK | 0x80; + else if (gBattleWeather & WEATHER_SUN_ANY) + gBattleStruct->dynamicMoveType = TYPE_FIRE | 0x80; + else if (gBattleWeather & WEATHER_HAIL) + gBattleStruct->dynamicMoveType = TYPE_ICE | 0x80; + else + gBattleStruct->dynamicMoveType = TYPE_NORMAL | 0x80; + } + gBattlescriptCurrInstr++; +} + +static void atkEA_tryrecycleitem(void) +{ + u16* used_item; + gActiveBattler = gBankAttacker; + used_item = USED_HELD_ITEM(gActiveBattler); + if (*used_item && gBattleMons[gActiveBattler].item == 0) + { + gLastUsedItem = *used_item; + *used_item = 0; + gBattleMons[gActiveBattler].item = gLastUsedItem; + EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBattler].item); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr += 5; + } + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atkEB_settypetoterrain(void) +{ + if (gBattleMons[gBankAttacker].type1 != sTerrainToType[gBattleTerrain] && gBattleMons[gBankAttacker].type2 != sTerrainToType[gBattleTerrain]) + { + gBattleMons[gBankAttacker].type1 = sTerrainToType[gBattleTerrain]; + gBattleMons[gBankAttacker].type2 = sTerrainToType[gBattleTerrain]; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 3; + gBattleTextBuff1[2] = sTerrainToType[gBattleTerrain]; + gBattleTextBuff1[3] = 0xFF; + gBattlescriptCurrInstr += 5; + } + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atkEC_pursuitrelated(void) +{ + gActiveBattler = GetBattlerAtPosition(GetBattlerPosition(gBankAttacker) ^ 2); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !(gAbsentBattlerFlags & gBitTable[gActiveBattler]) && gActionForBanks[gActiveBattler] == 0 && gChosenMovesByBanks[gActiveBattler] == MOVE_PURSUIT) + { + gActionsByTurnOrder[gActiveBattler] = 11; + gCurrentMove = MOVE_PURSUIT; + gBattlescriptCurrInstr += 5; + gBattleStruct->animTurn = 1; + gBattleStruct->unk160A7 = gBankAttacker; + gBankAttacker = gActiveBattler; + } + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); +} + +static void atkED_snatchsetbanks(void) +{ + gEffectBank = gBankAttacker; + if (gBankAttacker == gBankTarget) + gBankAttacker = gBankTarget = gBattleStruct->scriptingActive; + else + gBankTarget = gBattleStruct->scriptingActive; + gBattleStruct->scriptingActive = gEffectBank; + gBattlescriptCurrInstr++; +} + +static void atkEE_removelightscreenreflect(void) //brick break +{ + u8 side = GetBattlerSide(gBankAttacker) ^ 1; + if (gSideTimers[side].reflectTimer || gSideTimers[side].lightscreenTimer) + { + gSideAffecting[side] &= ~(SIDE_STATUS_REFLECT); + gSideAffecting[side] &= ~(SIDE_STATUS_LIGHTSCREEN); + gSideTimers[side].reflectTimer = 0; + gSideTimers[side].lightscreenTimer = 0; + gBattleStruct->animTurn = 1; + gBattleStruct->animTargetsHit = 1; + } + else + { + gBattleStruct->animTurn = 0; + gBattleStruct->animTargetsHit = 0; + } + gBattlescriptCurrInstr++; +} + +void atkEF_handleballthrow(void) +{ + u8 ball_multiplier = 0; + if (gBattleExecBuffer) + return; + + gActiveBattler = gBankAttacker; + gBankTarget = gBankAttacker ^ 1; + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + { + EmitBallThrow(0, 5); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr = BattleScript_TrainerBallBlock; + } + else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) + { + EmitBallThrow(0, 4); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr = BattleScript_WallyBallThrow; + } + else + { + u32 odds; + u8 catch_rate; + if (gLastUsedItem == ITEM_SAFARI_BALL) + catch_rate = gBattleStruct->unk16089 * 1275 / 100; //correct the name to safariFleeRate + else + catch_rate = gBaseStats[gBattleMons[gBankTarget].species].catchRate; + if (gLastUsedItem > 5) + { + switch (gLastUsedItem) + { + case ITEM_NET_BALL: + if (gBattleMons[gBankTarget].type1 == TYPE_WATER || gBattleMons[gBankTarget].type2 == TYPE_WATER || gBattleMons[gBankTarget].type1 == TYPE_BUG || gBattleMons[gBankTarget].type2 == TYPE_BUG) + ball_multiplier = 30; + else + ball_multiplier = 10; + break; + case ITEM_DIVE_BALL: + if (Overworld_GetMapTypeOfSaveblockLocation() == 5) + ball_multiplier = 35; + else + ball_multiplier = 10; + break; + case ITEM_NEST_BALL: + if (gBattleMons[gBankTarget].level <= 39) + { + ball_multiplier = 40 - gBattleMons[gBankTarget].level; + if (ball_multiplier <= 9) + ball_multiplier = 10; + } + else + ball_multiplier = 10; + break; + case ITEM_REPEAT_BALL: + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), 1)) + ball_multiplier = 30; + else + ball_multiplier = 10; + break; + case ITEM_TIMER_BALL: + ball_multiplier = gBattleResults.battleTurnCounter + 10; + if (ball_multiplier > 40) + ball_multiplier = 40; + break; + case ITEM_LUXURY_BALL: + case ITEM_PREMIER_BALL: + ball_multiplier = 10; + break; + } + } + else + ball_multiplier = sBallCatchBonuses[gLastUsedItem - 2]; + + odds = (catch_rate * ball_multiplier / 10) * (gBattleMons[gBankTarget].maxHP * 3 - gBattleMons[gBankTarget].hp * 2) / (3 * gBattleMons[gBankTarget].maxHP); + if (gBattleMons[gBankTarget].status1 & (STATUS_SLEEP | STATUS_FREEZE)) + odds *= 2; + if (gBattleMons[gBankTarget].status1 & (STATUS_POISON | STATUS_BURN | STATUS_PARALYSIS /*| STATUS_TOXIC_POISON */)) //nice one gf + odds = (odds * 15) / 10; + + if (gLastUsedItem != ITEM_SAFARI_BALL) + { + if (gLastUsedItem == ITEM_MASTER_BALL) + { + gBattleResults.unk5_1 = 1; + } + else + { + if (gBattleResults.usedBalls[gLastUsedItem - ITEM_ULTRA_BALL] < 0xFF) + gBattleResults.usedBalls[gLastUsedItem - ITEM_ULTRA_BALL]++; + } + } + if (odds > 254) //poke caught + { + EmitBallThrow(0, 4); + MarkBufferBankForExecution(gActiveBattler); + gBattlescriptCurrInstr = BattleScript_SuccessBallThrow; + SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankTarget]], MON_DATA_POKEBALL, (const void*) &gLastUsedItem); + if (CalculatePlayerPartyCount() == 6) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else //poke may be caught, calculate shakes + { + u8 shakes; + odds = Sqrt(Sqrt(16711680 / odds)); + odds = 1048560 / odds; + for (shakes = 0; shakes < 4 && Random() < odds; shakes++) {} + if (gLastUsedItem == ITEM_MASTER_BALL) + shakes = 4; //why calculate the shakes before that check? + EmitBallThrow(0, shakes); + MarkBufferBankForExecution(gActiveBattler); + if (shakes == 4) //poke caught, copy of the code above + { + gBattlescriptCurrInstr = BattleScript_SuccessBallThrow; + SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankTarget]], MON_DATA_POKEBALL, (const void*) &gLastUsedItem); + if (CalculatePlayerPartyCount() == 6) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else //rip + { + gBattleCommunication[MULTISTRING_CHOOSER] = shakes; + gBattlescriptCurrInstr = BattleScript_ShakeBallThrow; + } + } + } +} + +static void atkF0_givecaughtmon(void) +{ + GiveMonToPlayer(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]]); + gBattleResults.caughtPoke = gBattleMons[gBankAttacker ^ 1].species; + GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]], MON_DATA_NICKNAME, gBattleResults.caughtNick); + gBattlescriptCurrInstr++; +} + +static void atkF1_trysetcaughtmondexflags(void) +{ + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), 1)) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + else + { + GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), 3); + if (gBattleMons[gBankTarget].species == SPECIES_UNOWN) + gSaveBlock2.pokedex.unownPersonality = gBattleMons[gBankTarget].personality; + if (gBattleMons[gBankTarget].species == SPECIES_SPINDA) //else if + gSaveBlock2.pokedex.spindaPersonality = gBattleMons[gBankTarget].personality; + gBattlescriptCurrInstr += 5; + } +} + +extern const u32 gBattleTerrainTiles_Building[]; +extern const u32 gBattleTerrainTilemap_Building[]; +extern const u32 gBattleTerrainPalette_BattleTower[]; + +static void atkF2_displaydexinfo(void) +{ + switch (gBattleCommunication[0]) + { + case 0: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB(0, 0, 0)); + gBattleCommunication[0]++; + break; + case 1: + if (!gPaletteFade.active) + { + gBattleCommunication[1] = sub_809070C(SpeciesToNationalPokedexNum(gBattleMons[gBankTarget].species), gBattleMons[gBankTarget].otId, gBattleMons[gBankTarget].personality); + gBattleCommunication[0]++; + } + break; + case 2: + if (!gPaletteFade.active && gMain.callback2 == BattleMainCB2 && !gTasks[gBattleCommunication[1]].isActive) + { + LZDecompressVram(gBattleTerrainTiles_Building, (void*)(0x06008000)); + LZDecompressVram(gBattleTerrainTilemap_Building, (void*)(0x0600d000)); + LoadCompressedPalette(gBattleTerrainPalette_BattleTower, 0x20, 0x60); + REG_BG3CNT = 0x5a0b; + gBattle_BG3_X = 0x100; + BeginNormalPaletteFade(0xFFFC, 0, 16, 0, RGB(0, 0, 0)); + gBattleCommunication[0]++; + } + break; + case 3: + if (!gPaletteFade.active) + gBattlescriptCurrInstr++; + break; + } +} + +NAKED +void sub_802BBD4(u8 r0, u8 r1, u8 r2, u8 r3, u8 sp0) +{ + asm(".syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + ldr r4, [sp, 0x20]\n\ + lsls r0, 24\n\ + lsrs r6, r0, 24\n\ + lsls r1, 24\n\ + lsrs r1, 24\n\ + mov r12, r1\n\ + lsls r2, 24\n\ + lsrs r5, r2, 24\n\ + lsls r3, 24\n\ + lsrs r7, r3, 24\n\ + lsls r4, 24\n\ + lsrs r4, 24\n\ + mov r8, r4\n\ + mov r2, r12\n\ + cmp r2, r7\n\ + bgt _0802BC5A\n\ + lsls r1, r6, 1\n\ + ldr r0, _0802BC20 @ =0x0600c000\n\ + adds r1, r0\n\ + mov r9, r1\n\ +_0802BC06:\n\ + adds r1, r6, 0\n\ + adds r0, r2, 0x1\n\ + mov r10, r0\n\ + cmp r1, r5\n\ + bgt _0802BC54\n\ + lsls r0, r2, 6\n\ + mov r4, r9\n\ + adds r3, r4, r0\n\ +_0802BC16:\n\ + cmp r2, r12\n\ + bne _0802BC28\n\ + ldr r0, _0802BC24 @ =0x00001022\n\ + b _0802BC36\n\ + .align 2, 0\n\ +_0802BC20: .4byte 0x0600c000\n\ +_0802BC24: .4byte 0x00001022\n\ +_0802BC28:\n\ + cmp r2, r7\n\ + bne _0802BC34\n\ + ldr r0, _0802BC30 @ =0x00001028\n\ + b _0802BC36\n\ + .align 2, 0\n\ +_0802BC30: .4byte 0x00001028\n\ +_0802BC34:\n\ + ldr r0, _0802BC68 @ =0x00001025\n\ +_0802BC36:\n\ + cmp r1, r6\n\ + beq _0802BC42\n\ + adds r0, 0x1\n\ + cmp r1, r5\n\ + bne _0802BC42\n\ + adds r0, 0x1\n\ +_0802BC42:\n\ + mov r4, r8\n\ + cmp r4, 0\n\ + beq _0802BC4A\n\ + movs r0, 0\n\ +_0802BC4A:\n\ + strh r0, [r3]\n\ + adds r3, 0x2\n\ + adds r1, 0x1\n\ + cmp r1, r5\n\ + ble _0802BC16\n\ +_0802BC54:\n\ + mov r2, r10\n\ + cmp r2, r7\n\ + ble _0802BC06\n\ +_0802BC5A:\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .align 2, 0\n\ +_0802BC68: .4byte 0x00001025\n\ + .syntax divided"); +} + +void sub_802BC6C(void) +{ + MenuCursor_SetPos814A880(0xC8, ((gBattleCommunication[1] << 28) + 1207959552) >> 24); //what could that be? +} + +void nullsub_6(void) +{ + return; +} + +static void atkF3_trygivecaughtmonnick(void) +{ + switch (gBattleCommunication[0]) + { + case 0: + sub_8023A80(); + gBattleCommunication[0]++; + gBattleCommunication[1] = 0; + sub_802BC6C(); + break; + case 1: + if (gMain.newKeys & DPAD_UP && gBattleCommunication[1] != 0) + { + PlaySE(SE_SELECT); + nullsub_6(); + gBattleCommunication[1] = 0; + sub_802BC6C(); + } + if (gMain.newKeys & DPAD_DOWN && gBattleCommunication[1] == 0) + { + PlaySE(SE_SELECT); + nullsub_6(); + gBattleCommunication[1] = 1; + sub_802BC6C(); + } + if (gMain.newKeys & A_BUTTON) + { + PlaySE(SE_SELECT); + if (gBattleCommunication[1] == 0) + { + gBattleCommunication[0]++; + BeginFastPaletteFade(3); + } + else + gBattleCommunication[0] = 4; + } + else if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_SELECT); + gBattleCommunication[0] = 4; + } + break; + case 2: + if (!gPaletteFade.active) + { + GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]], MON_DATA_NICKNAME, gBattleStruct->caughtNick); + DoNamingScreen(2, gBattleStruct->caughtNick, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]], MON_DATA_SPECIES), GetMonGender(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]]), GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]], MON_DATA_PERSONALITY, 0), BattleMainCB2); + gBattleCommunication[0]++; + } + break; + case 3: + if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active ) + { + SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBankAttacker ^ 1]], MON_DATA_NICKNAME, gBattleStruct->caughtNick); + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + break; + case 4: + if (CalculatePlayerPartyCount() == 6) + gBattlescriptCurrInstr += 5; + else + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + break; + } +} + +static void atkF4_subattackerhpbydmg(void) +{ + gBattleMons[gBankAttacker].hp -= gBattleMoveDamage; + gBattlescriptCurrInstr++; +} + +static void atkF5_removeattackerstatus1(void) +{ + gBattleMons[gBankAttacker].status1 = 0; + gBattlescriptCurrInstr++; +} + +static void atkF6_finishaction(void) +{ + gCurrentActionFuncId = 0xC; +} + +static void atkF7_finishturn(void) +{ + gCurrentActionFuncId = 0xC; + gCurrentTurnActionNumber = gBattlersCount; +} diff --git a/src/battle_setup.c b/src/battle_setup.c new file mode 100644 index 000000000..c457cc8ec --- /dev/null +++ b/src/battle_setup.c @@ -0,0 +1,1482 @@ +#include "global.h" +#include "battle_setup.h" +#include "battle.h" +#include "battle_transition.h" +#include "data2.h" +#include "event_data.h" +#include "field_control_avatar.h" +#include "field_fadetransition.h" +#include "field_message_box.h" +#include "field_player_avatar.h" +#include "field_weather.h" +#include "fieldmap.h" +#include "fldeff_poison.h" +#include "main.h" +#include "metatile_behavior.h" +#include "palette.h" +#include "random.h" +#include "overworld.h" +#include "safari_zone.h" +#include "script.h" +#include "script_pokemon_80C4.h" +#include "secret_base.h" +#include "sound.h" +#include "starter_choose.h" +#include "string_util.h" +#include "strings.h" +#include "task.h" +#include "text.h" +#include "trainer.h" +#include "constants/map_types.h" +#include "constants/maps.h" +#include "constants/opponents.h" +#include "constants/songs.h" +#include "constants/species.h" + +extern u16 gSpecialVar_Result; + +extern void (*gFieldCallback)(void); + +EWRAM_DATA static u16 sTrainerBattleMode = 0; +EWRAM_DATA u16 gTrainerBattleOpponent = 0; +EWRAM_DATA static u16 sTrainerEventObjectLocalId = 0; +EWRAM_DATA static u8 *sTrainerIntroSpeech = NULL; +EWRAM_DATA static u8 *sTrainerDefeatSpeech = NULL; +EWRAM_DATA static u8 *sTrainerVictorySpeech = NULL; +EWRAM_DATA static u8 *sTrainerCannotBattleSpeech = NULL; +EWRAM_DATA static u8 *sTrainerBattleScriptRetAddr = NULL; +EWRAM_DATA static u8 *sTrainerBattleEndScript = NULL; + +extern u16 gBattleTypeFlags; +extern u16 gSpecialVar_LastTalked; +extern u8 gBattleOutcome; + +extern struct EventObject gEventObjects[]; + +extern u8 gUnknown_0819F818[]; +extern u8 gUnknown_0819F840[]; +extern u8 gUnknown_0819F878[]; +extern u8 gUnknown_0819F887[]; +extern u8 gUnknown_0819F8AE[]; + +extern u8 gUnknown_0819F80B[]; +extern u8 gUnknown_081C6C02[]; + +// The first transition is used if the enemy pokemon are lower level than our pokemon. +// Otherwise, the second transition is used. +static const u8 gBattleTransitionTable_Wild[][2] = +{ + {B_TRANSITION_SLICE, B_TRANSITION_WHITEFADE}, // Normal + {B_TRANSITION_CLOCKWISE_BLACKFADE, B_TRANSITION_GRID_SQUARES}, // Cave + {B_TRANSITION_BLUR, B_TRANSITION_GRID_SQUARES}, // Cave with flash used + {B_TRANSITION_WAVE, B_TRANSITION_RIPPLE}, // Water +}; +static const u8 gBattleTransitionTable_Trainer[][2] = +{ + {B_TRANSITION_POKEBALLS_TRAIL, B_TRANSITION_SHARDS}, // Normal + {B_TRANSITION_SHUFFLE, B_TRANSITION_BIG_POKEBALL}, // Cave + {B_TRANSITION_BLUR, B_TRANSITION_GRID_SQUARES}, // Cave with flash used + {B_TRANSITION_SWIRL, B_TRANSITION_RIPPLE}, // Water +}; + +enum +{ + TRAINER_PARAM_LOAD_VAL_8BIT, + TRAINER_PARAM_LOAD_VAL_16BIT, + TRAINER_PARAM_LOAD_VAL_32BIT, + TRAINER_PARAM_CLEAR_VAL_8BIT, + TRAINER_PARAM_CLEAR_VAL_16BIT, + TRAINER_PARAM_CLEAR_VAL_32BIT, + TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR, +}; + +struct TrainerBattleParameter +{ + void *varPtr; + u8 ptrType; +}; + +static const struct TrainerBattleParameter gTrainerBattleSpecs_0[] = +{ + {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, + {&gTrainerBattleOpponent, TRAINER_PARAM_LOAD_VAL_16BIT}, + {&sTrainerEventObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, + {&sTrainerIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerDefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, + {&sTrainerCannotBattleSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, + {&sTrainerBattleEndScript, TRAINER_PARAM_CLEAR_VAL_32BIT}, + {&sTrainerBattleScriptRetAddr, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR}, +}; +static const struct TrainerBattleParameter gTrainerBattleSpecs_1[] = +{ + {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, + {&gTrainerBattleOpponent, TRAINER_PARAM_LOAD_VAL_16BIT}, + {&sTrainerEventObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, + {&sTrainerIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerDefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, + {&sTrainerCannotBattleSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, + {&sTrainerBattleEndScript, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerBattleScriptRetAddr, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR}, +}; +static const struct TrainerBattleParameter gTrainerBattleSpecs_2[] = +{ + {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, + {&gTrainerBattleOpponent, TRAINER_PARAM_LOAD_VAL_16BIT}, + {&sTrainerEventObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, + {&sTrainerIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerDefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, + {&sTrainerCannotBattleSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerBattleEndScript, TRAINER_PARAM_CLEAR_VAL_32BIT}, + {&sTrainerBattleScriptRetAddr, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR}, +}; +static const struct TrainerBattleParameter gTrainerBattleSpecs_3[] = +{ + {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, + {&gTrainerBattleOpponent, TRAINER_PARAM_LOAD_VAL_16BIT}, + {&sTrainerEventObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, + {&sTrainerIntroSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, + {&sTrainerDefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, + {&sTrainerCannotBattleSpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, + {&sTrainerBattleEndScript, TRAINER_PARAM_CLEAR_VAL_32BIT}, + {&sTrainerBattleScriptRetAddr, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR}, +}; +static const struct TrainerBattleParameter gTrainerBattleSpecs_4[] = +{ + {&sTrainerBattleMode, TRAINER_PARAM_LOAD_VAL_8BIT}, + {&gTrainerBattleOpponent, TRAINER_PARAM_LOAD_VAL_16BIT}, + {&sTrainerEventObjectLocalId, TRAINER_PARAM_LOAD_VAL_16BIT}, + {&sTrainerIntroSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerDefeatSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerVictorySpeech, TRAINER_PARAM_CLEAR_VAL_32BIT}, + {&sTrainerCannotBattleSpeech, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerBattleEndScript, TRAINER_PARAM_LOAD_VAL_32BIT}, + {&sTrainerBattleScriptRetAddr, TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR}, +}; + +const struct TrainerEyeTrainer gTrainerEyeTrainers[] = +{ + { + {TRAINER_ROSE_1, TRAINER_ROSE_2, TRAINER_ROSE_3, TRAINER_ROSE_4, TRAINER_ROSE_5}, + MAP_GROUP(ROUTE118), + MAP_NUM(ROUTE118), + }, + { + {TRAINER_DUSTY_1, TRAINER_DUSTY_2, TRAINER_DUSTY_3, TRAINER_DUSTY_4, TRAINER_DUSTY_5}, + MAP_GROUP(ROUTE111), + MAP_NUM(ROUTE111), + }, + { + {TRAINER_LOLA_1, TRAINER_LOLA_2, TRAINER_LOLA_3, TRAINER_LOLA_4, TRAINER_LOLA_5}, + MAP_GROUP(ROUTE109), + MAP_NUM(ROUTE109), + }, + { + {TRAINER_RICKY_1, TRAINER_RICKY_2, TRAINER_RICKY_3, TRAINER_RICKY_4, TRAINER_RICKY_5}, + MAP_GROUP(ROUTE109), + MAP_NUM(ROUTE109), + }, + { + {TRAINER_RITA_AND_SAM_1, TRAINER_RITA_AND_SAM_2, TRAINER_RITA_AND_SAM_3, TRAINER_RITA_AND_SAM_4, TRAINER_RITA_AND_SAM_5}, + MAP_GROUP(ROUTE124), + MAP_NUM(ROUTE124), + }, + { + {TRAINER_BROOKE_1, TRAINER_BROOKE_2, TRAINER_BROOKE_3, TRAINER_BROOKE_4, TRAINER_BROOKE_5}, + MAP_GROUP(ROUTE111), + MAP_NUM(ROUTE111), + }, + { + {TRAINER_WILTON_1, TRAINER_WILTON_2, TRAINER_WILTON_3, TRAINER_WILTON_4, TRAINER_WILTON_5}, + MAP_GROUP(ROUTE111), + MAP_NUM(ROUTE111), + }, + { + {TRAINER_VALERIE_1, TRAINER_VALERIE_2, TRAINER_VALERIE_3, TRAINER_VALERIE_4, TRAINER_VALERIE_5}, + MAP_GROUP(MT_PYRE_6F), + MAP_NUM(MT_PYRE_6F), + }, + { + {TRAINER_CINDY_1, TRAINER_CINDY_3, TRAINER_CINDY_4, TRAINER_CINDY_5, TRAINER_CINDY_6}, + MAP_GROUP(ROUTE104), + MAP_NUM(ROUTE104), + }, + { + {TRAINER_JESSICA_1, TRAINER_JESSICA_2, TRAINER_JESSICA_3, TRAINER_JESSICA_4, TRAINER_JESSICA_5}, + MAP_GROUP(ROUTE121), + MAP_NUM(ROUTE121), + }, + { + {TRAINER_WINSTON_1, TRAINER_WINSTON_2, TRAINER_WINSTON_3, TRAINER_WINSTON_4, TRAINER_WINSTON_5}, + MAP_GROUP(ROUTE104), + MAP_NUM(ROUTE104), + }, + { + {TRAINER_STEVE_1, TRAINER_STEVE_2, TRAINER_STEVE_3, TRAINER_STEVE_4, TRAINER_STEVE_5}, + MAP_GROUP(ROUTE114), + MAP_NUM(ROUTE114), + }, + { + {TRAINER_TONY_1, TRAINER_TONY_2, TRAINER_TONY_3, TRAINER_TONY_4, TRAINER_TONY_5}, + MAP_GROUP(ROUTE107), + MAP_NUM(ROUTE107), + }, + { + {TRAINER_NOB_1, TRAINER_NOB_2, TRAINER_NOB_3, TRAINER_NOB_4, TRAINER_NOB_5}, + MAP_GROUP(ROUTE115), + MAP_NUM(ROUTE115), + }, + { + {TRAINER_DALTON_1, TRAINER_DALTON_2, TRAINER_DALTON_3, TRAINER_DALTON_4, TRAINER_DALTON_5}, + MAP_GROUP(ROUTE118), + MAP_NUM(ROUTE118), + }, + { + {TRAINER_BERNIE_1, TRAINER_BERNIE_2, TRAINER_BERNIE_3, TRAINER_BERNIE_4, TRAINER_BERNIE_5}, + MAP_GROUP(ROUTE114), + MAP_NUM(ROUTE114), + }, + { + {TRAINER_ETHAN_1, TRAINER_ETHAN_2, TRAINER_ETHAN_3, TRAINER_ETHAN_4, TRAINER_ETHAN_5}, + MAP_GROUP(JAGGED_PASS), + MAP_NUM(JAGGED_PASS), + }, + { + {TRAINER_JOHN_AND_JAY_1, TRAINER_JOHN_AND_JAY_2, TRAINER_JOHN_AND_JAY_3, TRAINER_JOHN_AND_JAY_4, TRAINER_JOHN_AND_JAY_5}, + MAP_GROUP(METEOR_FALLS_1F_2R), + MAP_NUM(METEOR_FALLS_1F_2R), + }, + { + {TRAINER_BRANDON_1, TRAINER_BRANDON_2, TRAINER_BRANDON_3, TRAINER_BRANDON_4, TRAINER_BRANDON_5}, + MAP_GROUP(ROUTE120), + MAP_NUM(ROUTE120), + }, + { + {TRAINER_CAMERON_1, TRAINER_CAMERON_2, TRAINER_CAMERON_3, TRAINER_CAMERON_4, TRAINER_CAMERON_5}, + MAP_GROUP(ROUTE123), + MAP_NUM(ROUTE123), + }, + { + {TRAINER_JACKI_1, TRAINER_JACKI_2, TRAINER_JACKI_3, TRAINER_JACKI_4, TRAINER_JACKI_5}, + MAP_GROUP(ROUTE123), + MAP_NUM(ROUTE123), + }, + { + {TRAINER_WALTER_1, TRAINER_WALTER_2, TRAINER_WALTER_3, TRAINER_WALTER_4, TRAINER_WALTER_5}, + MAP_GROUP(ROUTE121), + MAP_NUM(ROUTE121), + }, + { + {TRAINER_KAREN_1, TRAINER_KAREN_2, TRAINER_KAREN_3, TRAINER_KAREN_4, TRAINER_KAREN_5}, + MAP_GROUP(ROUTE116), + MAP_NUM(ROUTE116), + }, + { + {TRAINER_JERRY_1, TRAINER_JERRY_2, TRAINER_JERRY_3, TRAINER_JERRY_4, TRAINER_JERRY_5}, + MAP_GROUP(ROUTE116), + MAP_NUM(ROUTE116), + }, + { + {TRAINER_ANNA_AND_MEG_1, TRAINER_ANNA_AND_MEG_2, TRAINER_ANNA_AND_MEG_3, TRAINER_ANNA_AND_MEG_4, TRAINER_ANNA_AND_MEG_5}, + MAP_GROUP(ROUTE117), + MAP_NUM(ROUTE117), + }, + { + {TRAINER_ISABEL_1, TRAINER_ISABEL_2, TRAINER_ISABEL_3, TRAINER_ISABEL_4, TRAINER_ISABEL_5}, + MAP_GROUP(ROUTE110), + MAP_NUM(ROUTE110), + }, + { + {TRAINER_MIGUEL_1, TRAINER_MIGUEL_2, TRAINER_MIGUEL_3, TRAINER_MIGUEL_4, TRAINER_MIGUEL_5}, + MAP_GROUP(ROUTE103), + MAP_NUM(ROUTE103), + }, + { + {TRAINER_TIMOTHY_1, TRAINER_TIMOTHY_2, TRAINER_TIMOTHY_3, TRAINER_TIMOTHY_4, TRAINER_TIMOTHY_5}, + MAP_GROUP(ROUTE115), + MAP_NUM(ROUTE115), + }, + { + {TRAINER_SHELBY_1, TRAINER_SHELBY_2, TRAINER_SHELBY_3, TRAINER_SHELBY_4, TRAINER_SHELBY_5}, + MAP_GROUP(MT_CHIMNEY), + MAP_NUM(MT_CHIMNEY), + }, + { + {TRAINER_CALVIN_1, TRAINER_CALVIN_2, TRAINER_CALVIN_3, TRAINER_CALVIN_4, TRAINER_CALVIN_5}, + MAP_GROUP(ROUTE102), + MAP_NUM(ROUTE102), + }, + { + {TRAINER_ELLIOT_1, TRAINER_ELLIOT_2, TRAINER_ELLIOT_3, TRAINER_ELLIOT_4, TRAINER_ELLIOT_5}, + MAP_GROUP(ROUTE106), + MAP_NUM(ROUTE106), + }, + { + {TRAINER_ABIGAIL_1, TRAINER_ABIGAIL_2, TRAINER_ABIGAIL_3, TRAINER_ABIGAIL_4, TRAINER_ABIGAIL_5}, + MAP_GROUP(ROUTE110), + MAP_NUM(ROUTE110), + }, + { + {TRAINER_BENJAMIN_1, TRAINER_BENJAMIN_2, TRAINER_BENJAMIN_3, TRAINER_BENJAMIN_4, TRAINER_BENJAMIN_5}, + MAP_GROUP(ROUTE110), + MAP_NUM(ROUTE110), + }, + { + {TRAINER_ISAIAH_1, TRAINER_ISAIAH_2, TRAINER_ISAIAH_3, TRAINER_ISAIAH_4, TRAINER_ISAIAH_5}, + MAP_GROUP(ROUTE128), + MAP_NUM(ROUTE128), + }, + { + {TRAINER_KATELYN_1, TRAINER_KATELYN_2, TRAINER_KATELYN_3, TRAINER_KATELYN_4, TRAINER_KATELYN_5}, + MAP_GROUP(ROUTE128), + MAP_NUM(ROUTE128), + }, + { + {TRAINER_MARIA_1, TRAINER_MARIA_2, TRAINER_MARIA_3, TRAINER_MARIA_4, TRAINER_MARIA_5}, + MAP_GROUP(ROUTE117), + MAP_NUM(ROUTE117), + }, + { + {TRAINER_DYLAN_1, TRAINER_DYLAN_2, TRAINER_DYLAN_3, TRAINER_DYLAN_4, TRAINER_DYLAN_5}, + MAP_GROUP(ROUTE117), + MAP_NUM(ROUTE117), + }, + { + {TRAINER_NICOLAS_1, TRAINER_NICOLAS_2, TRAINER_NICOLAS_3, TRAINER_NICOLAS_4, TRAINER_NICOLAS_5}, + MAP_GROUP(METEOR_FALLS_1F_2R), + MAP_NUM(METEOR_FALLS_1F_2R), + }, + { + {TRAINER_ROBERT_1, TRAINER_ROBERT_2, TRAINER_ROBERT_3, TRAINER_ROBERT_4, TRAINER_ROBERT_5}, + MAP_GROUP(ROUTE120), + MAP_NUM(ROUTE120), + }, + { + {TRAINER_LAO_1, TRAINER_LAO_2, TRAINER_LAO_3, TRAINER_LAO_4, TRAINER_LAO_5}, + MAP_GROUP(ROUTE113), + MAP_NUM(ROUTE113), + }, + { + {TRAINER_CYNDY_1, TRAINER_CYNDY_2, TRAINER_CYNDY_3, TRAINER_CYNDY_4, TRAINER_CYNDY_5}, + MAP_GROUP(ROUTE115), + MAP_NUM(ROUTE115), + }, + { + {TRAINER_MADELINE_1, TRAINER_MADELINE_2, TRAINER_MADELINE_3, TRAINER_MADELINE_4, TRAINER_MADELINE_5}, + MAP_GROUP(ROUTE113), + MAP_NUM(ROUTE113), + }, + { + {TRAINER_JENNY_1, TRAINER_JENNY_2, TRAINER_JENNY_3, TRAINER_JENNY_4, TRAINER_JENNY_5}, + MAP_GROUP(ROUTE124), + MAP_NUM(ROUTE124), + }, + { + {TRAINER_DIANA_1, TRAINER_DIANA_2, TRAINER_DIANA_3, TRAINER_DIANA_4, TRAINER_DIANA_5}, + MAP_GROUP(JAGGED_PASS), + MAP_NUM(JAGGED_PASS), + }, + { + {TRAINER_AMY_AND_LIV_1, TRAINER_AMY_AND_LIV_2, TRAINER_AMY_AND_LIV_4, TRAINER_AMY_AND_LIV_5, TRAINER_AMY_AND_LIV_6}, + MAP_GROUP(ROUTE103), + MAP_NUM(ROUTE103), + }, + { + {TRAINER_ERNEST_1, TRAINER_ERNEST_2, TRAINER_ERNEST_3, TRAINER_ERNEST_4, TRAINER_ERNEST_5}, + MAP_GROUP(ROUTE125), + MAP_NUM(ROUTE125), + }, + { + {TRAINER_EDWIN_1, TRAINER_EDWIN_2, TRAINER_EDWIN_3, TRAINER_EDWIN_4, TRAINER_EDWIN_5}, + MAP_GROUP(ROUTE110), + MAP_NUM(ROUTE110), + }, + { + {TRAINER_LYDIA_1, TRAINER_LYDIA_2, TRAINER_LYDIA_3, TRAINER_LYDIA_4, TRAINER_LYDIA_5}, + MAP_GROUP(ROUTE117), + MAP_NUM(ROUTE117), + }, + { + {TRAINER_ISAAC_1, TRAINER_ISAAC_2, TRAINER_ISAAC_3, TRAINER_ISAAC_4, TRAINER_ISAAC_5}, + MAP_GROUP(ROUTE117), + MAP_NUM(ROUTE117), + }, + { + {TRAINER_CATHERINE_1, TRAINER_CATHERINE_2, TRAINER_CATHERINE_3, TRAINER_CATHERINE_4, TRAINER_CATHERINE_5}, + MAP_GROUP(ROUTE119), + MAP_NUM(ROUTE119), + }, + { + {TRAINER_JACKSON_1, TRAINER_JACKSON_2, TRAINER_JACKSON_3, TRAINER_JACKSON_4, TRAINER_JACKSON_5}, + MAP_GROUP(ROUTE119), + MAP_NUM(ROUTE119), + }, + { + {TRAINER_HALEY_1, TRAINER_HALEY_2, TRAINER_HALEY_3, TRAINER_HALEY_4, TRAINER_HALEY_5}, + MAP_GROUP(ROUTE104), + MAP_NUM(ROUTE104), + }, + { + {TRAINER_JAMES_1, TRAINER_JAMES_2, TRAINER_JAMES_3, TRAINER_JAMES_4, TRAINER_JAMES_5}, + MAP_GROUP(PETALBURG_WOODS), + MAP_NUM(PETALBURG_WOODS), + }, + { + {TRAINER_TRENT_1, TRAINER_TRENT_2, TRAINER_TRENT_3, TRAINER_TRENT_4, TRAINER_TRENT_5}, + MAP_GROUP(ROUTE112), + MAP_NUM(ROUTE112), + }, + { + {TRAINER_LOIS_AND_HAL_1, TRAINER_LOIS_AND_HAL_2, TRAINER_LOIS_AND_HAL_3, TRAINER_LOIS_AND_HAL_4, TRAINER_LOIS_AND_HAL_5}, + MAP_GROUP(ABANDONED_SHIP_ROOMS2_1F), + MAP_NUM(ABANDONED_SHIP_ROOMS2_1F), + }, + { + {TRAINER_WALLY_3, TRAINER_WALLY_4, TRAINER_WALLY_5, TRAINER_WALLY_6, TRAINER_NONE}, + MAP_GROUP(VICTORY_ROAD_1F), + MAP_NUM(VICTORY_ROAD_1F), + }, +}; + +static const u16 sBadgeFlags[] = +{ + FLAG_BADGE01_GET, + FLAG_BADGE02_GET, + FLAG_BADGE03_GET, + FLAG_BADGE04_GET, + FLAG_BADGE05_GET, + FLAG_BADGE06_GET, + FLAG_BADGE07_GET, + FLAG_BADGE08_GET, +}; + +static void DoStandardWildBattle(void); +static void DoSafariBattle(void); +static void SetTrainerFlagsAfterTrainerEyeRematch(void); +static void CB2_EndWildBattle(void); +static void CB2_EndScriptedWildBattle(void); +static u8 GetWildBattleTransition(void); +static u8 GetTrainerBattleTransition(void); +static void CB2_GiveStarter(void); +static void CB2_StartFirstBattle(void); +static void CB2_EndFirstBattle(void); +static bool32 IsPlayerDefeated(u32 a1); + +#define tState data[0] +#define tTransition data[1] + +static void Task_BattleStart(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + + switch (tState) + { + case 0: + if (!FldeffPoison_IsActive()) // is poison not active? + { + BattleTransition_StartOnField(tTransition); + tState++; // go to case 1. + } + break; + case 1: + if (IsBattleTransitionDone() == TRUE) + { + SetMainCallback2(sub_800E7C4); + RestartWildEncounterImmunitySteps(); + ClearPoisonStepCounter(); + DestroyTask(taskId); + } + break; + } +} + +static void CreateBattleStartTask(u8 transition, u16 song) +{ + u8 taskId = CreateTask(Task_BattleStart, 1); + + gTasks[taskId].tTransition = transition; + current_map_music_set__default_for_battle(song); +} + +#undef tState +#undef tTransition + +void BattleSetup_StartWildBattle(void) +{ + if (GetSafariZoneFlag()) + DoSafariBattle(); + else + DoStandardWildBattle(); +} + +static void DoStandardWildBattle(void) +{ + ScriptContext2_Enable(); + FreezeEventObjects(); + sub_80597F4(); + gMain.savedCallback = CB2_EndWildBattle; + gBattleTypeFlags = 0; + CreateBattleStartTask(GetWildBattleTransition(), 0); + IncrementGameStat(GAME_STAT_TOTAL_BATTLES); + IncrementGameStat(GAME_STAT_WILD_BATTLES); +} + +void BattleSetup_StartRoamerBattle(void) +{ + ScriptContext2_Enable(); + FreezeEventObjects(); + sub_80597F4(); + gMain.savedCallback = CB2_EndWildBattle; + gBattleTypeFlags = BATTLE_TYPE_ROAMER; + CreateBattleStartTask(GetWildBattleTransition(), 0); + IncrementGameStat(GAME_STAT_TOTAL_BATTLES); + IncrementGameStat(GAME_STAT_WILD_BATTLES); +} + +static void DoSafariBattle(void) +{ + ScriptContext2_Enable(); + FreezeEventObjects(); + sub_80597F4(); + gMain.savedCallback = sub_80C824C; + gBattleTypeFlags = BATTLE_TYPE_SAFARI; + CreateBattleStartTask(GetWildBattleTransition(), 0); +} + +static void StartTheBattle(void) +{ + CreateBattleStartTask(GetTrainerBattleTransition(), 0); + IncrementGameStat(GAME_STAT_TOTAL_BATTLES); + IncrementGameStat(GAME_STAT_TRAINER_BATTLES); +} + +//Initiates battle where Wally catches Ralts +void ScrSpecial_StartWallyTutorialBattle(void) +{ + CreateMaleMon(&gEnemyParty[0], SPECIES_RALTS, 5); + ScriptContext2_Enable(); + gMain.savedCallback = c2_exit_to_overworld_1_continue_scripts_restart_music; + gBattleTypeFlags = BATTLE_TYPE_WALLY_TUTORIAL; + CreateBattleStartTask(B_TRANSITION_SLICE, 0); +} + +void BattleSetup_StartScriptedWildBattle(void) +{ + ScriptContext2_Enable(); + gMain.savedCallback = CB2_EndScriptedWildBattle; + gBattleTypeFlags = 0; + CreateBattleStartTask(GetWildBattleTransition(), 0); + IncrementGameStat(GAME_STAT_TOTAL_BATTLES); + IncrementGameStat(GAME_STAT_WILD_BATTLES); +} + +void ScrSpecial_StartSouthernIslandBattle(void) +{ + ScriptContext2_Enable(); + gMain.savedCallback = CB2_EndScriptedWildBattle; + gBattleTypeFlags = BATTLE_TYPE_LEGENDARY; + CreateBattleStartTask(GetWildBattleTransition(), 0); + IncrementGameStat(GAME_STAT_TOTAL_BATTLES); + IncrementGameStat(GAME_STAT_WILD_BATTLES); +} + +void ScrSpecial_StartRayquazaBattle(void) +{ + ScriptContext2_Enable(); + gMain.savedCallback = CB2_EndScriptedWildBattle; + gBattleTypeFlags = BATTLE_TYPE_LEGENDARY; + CreateBattleStartTask(B_TRANSITION_BLUR, MUS_BATTLE34); + IncrementGameStat(GAME_STAT_TOTAL_BATTLES); + IncrementGameStat(GAME_STAT_WILD_BATTLES); +} + +void ScrSpecial_StartGroudonKyogreBattle(void) +{ + ScriptContext2_Enable(); + gMain.savedCallback = CB2_EndScriptedWildBattle; + gBattleTypeFlags = BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_KYOGRE_GROUDON; + if (gGameVersion == VERSION_RUBY) + CreateBattleStartTask(B_TRANSITION_SHARDS, MUS_BATTLE34); // GROUDON + else + CreateBattleStartTask(B_TRANSITION_RIPPLE, MUS_BATTLE34); // KYOGRE + IncrementGameStat(GAME_STAT_TOTAL_BATTLES); + IncrementGameStat(GAME_STAT_WILD_BATTLES); +} + +void ScrSpecial_StartRegiBattle(void) +{ + ScriptContext2_Enable(); + gMain.savedCallback = CB2_EndScriptedWildBattle; + gBattleTypeFlags = BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_REGI; + CreateBattleStartTask(B_TRANSITION_GRID_SQUARES, MUS_BATTLE36); + IncrementGameStat(GAME_STAT_TOTAL_BATTLES); + IncrementGameStat(GAME_STAT_WILD_BATTLES); +} + +static void CB2_EndWildBattle(void) +{ + CpuFill16(0, (void *)BG_PLTT, BG_PLTT_SIZE); + ResetOamRange(0, 128); + + if (IsPlayerDefeated(gBattleOutcome) == TRUE) + { + SetMainCallback2(CB2_WhiteOut); + } + else + { + SetMainCallback2(CB2_ReturnToField); + gFieldCallback = sub_8080E44; + } +} + +void CB2_EndScriptedWildBattle(void) +{ + CpuFill16(0, (void *)BG_PLTT, BG_PLTT_SIZE); + ResetOamRange(0, 128); + + if (IsPlayerDefeated(gBattleOutcome) == TRUE) + SetMainCallback2(CB2_WhiteOut); + else + SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); +} + +s8 BattleSetup_GetTerrain(void) +{ + u16 tileBehavior; + s16 x, y; + + PlayerGetDestCoords(&x, &y); + tileBehavior = MapGridGetMetatileBehaviorAt(x, y); + + if (MetatileBehavior_IsTallGrass(tileBehavior)) + return BATTLE_TERRAIN_GRASS; + if (MetatileBehavior_IsLongGrass(tileBehavior)) + return BATTLE_TERRAIN_LONG_GRASS; + if (MetatileBehavior_IsSandOrDeepSand(tileBehavior)) + return BATTLE_TERRAIN_SAND; + switch (gMapHeader.mapType) + { + case MAP_TYPE_TOWN: + case MAP_TYPE_CITY: + case MAP_TYPE_ROUTE: + break; + case MAP_TYPE_UNDERGROUND: + if (MetatileBehavior_IsIndoorEncounter(tileBehavior)) + return BATTLE_TERRAIN_BUILDING; + if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) + return BATTLE_TERRAIN_POND; + return BATTLE_TERRAIN_CAVE; + case MAP_TYPE_INDOOR: + case MAP_TYPE_SECRET_BASE: + return BATTLE_TERRAIN_BUILDING; + case MAP_TYPE_UNDERWATER: + return BATTLE_TERRAIN_UNDERWATER; + case MAP_TYPE_6: + if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) + return BATTLE_TERRAIN_WATER; + return BATTLE_TERRAIN_PLAIN; + } + if (MetatileBehavior_IsOceanWater(tileBehavior)) + return BATTLE_TERRAIN_WATER; + if (MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) + return BATTLE_TERRAIN_POND; + if (MetatileBehavior_IsMountainTop(tileBehavior)) + return BATTLE_TERRAIN_MOUNTAIN; + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) + { + if (MetatileBehavior_GetBridgeType(tileBehavior)) + return BATTLE_TERRAIN_POND; + if (MetatileBehavior_IsBridge(tileBehavior) == TRUE) + return BATTLE_TERRAIN_WATER; + } + if (gSaveBlock1.location.mapGroup == MAP_GROUP(ROUTE113) && gSaveBlock1.location.mapNum == MAP_NUM(ROUTE113)) + return BATTLE_TERRAIN_SAND; + if (GetSav1Weather() == 8) + return BATTLE_TERRAIN_SAND; + return BATTLE_TERRAIN_PLAIN; +} + +static s8 GetBattleTransitionTypeByMap(void) +{ + u16 tileBehavior; + s16 x, y; + + PlayerGetDestCoords(&x, &y); + tileBehavior = MapGridGetMetatileBehaviorAt(x, y); + if (Overworld_GetFlashLevel()) + return 2; + if (!MetatileBehavior_IsSurfableWaterOrUnderwater(tileBehavior)) + { + switch (gMapHeader.mapType) + { + case MAP_TYPE_UNDERGROUND: + return 1; + case MAP_TYPE_UNDERWATER: + return 3; + default: + return 0; + } + } + return 3; +} + +static u16 GetSumOfPlayerPartyLevel(u8 numMons) +{ + u8 sum = 0; + int i; + + for (i = 0; i < 6; i++) + { + u32 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); + + if (species != SPECIES_EGG && species != SPECIES_NONE && GetMonData(&gPlayerParty[i], MON_DATA_HP) != 0) + { + sum += GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); + numMons--; + if (numMons == 0) + break; + } + } + return sum; +} + +static u8 GetSumOfEnemyPartyLevel(u16 opponentId, u8 numMons) +{ + u8 i; + u8 sum; + u32 count = numMons; + + if (gTrainers[opponentId].partySize < count) + count = gTrainers[opponentId].partySize; + + sum = 0; + + switch (gTrainers[opponentId].partyFlags) + { + case 0: + { + const struct TrainerMonNoItemDefaultMoves *party; + party = gTrainers[opponentId].party.NoItemDefaultMoves; + for (i = 0; i < count; i++) + sum += party[i].level; + } + break; + case F_TRAINER_PARTY_CUSTOM_MOVESET: + { + const struct TrainerMonNoItemCustomMoves *party; + party = gTrainers[opponentId].party.NoItemCustomMoves; + for (i = 0; i < count; i++) + sum += party[i].level; + } + break; + case F_TRAINER_PARTY_HELD_ITEM: + { + const struct TrainerMonItemDefaultMoves *party; + party = gTrainers[opponentId].party.ItemDefaultMoves; + for (i = 0; i < count; i++) + sum += party[i].level; + } + break; + case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM: + { + const struct TrainerMonItemCustomMoves *party; + party = gTrainers[opponentId].party.ItemCustomMoves; + for (i = 0; i < count; i++) + sum += party[i].level; + } + break; + } + + return sum; +} + +static u8 GetWildBattleTransition(void) +{ + u8 transitionType = GetBattleTransitionTypeByMap(); + u8 enemyLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL); + u8 playerLevel = GetSumOfPlayerPartyLevel(1); + + if (enemyLevel < playerLevel) + return gBattleTransitionTable_Wild[transitionType][0]; + else + return gBattleTransitionTable_Wild[transitionType][1]; +} + +static u8 GetTrainerBattleTransition(void) +{ + const struct Trainer *trainer; + u8 minPartyCount; + u8 transitionType; + u8 enemyLevel; + u8 playerLevel; + + if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) + return B_TRANSITION_STEVEN; + + trainer = gTrainers; + + if (trainer[gTrainerBattleOpponent].trainerClass == TRAINER_CLASS_ELITE_FOUR) + { + if (gTrainerBattleOpponent == TRAINER_SIDNEY) + return B_TRANSITION_SYDNEY; + if (gTrainerBattleOpponent == TRAINER_PHOEBE) + return B_TRANSITION_PHOEBE; + if (gTrainerBattleOpponent == TRAINER_GLACIA) + return B_TRANSITION_GLACIA; + if (gTrainerBattleOpponent == TRAINER_DRAKE) + return B_TRANSITION_DRAKE; + return B_TRANSITION_STEVEN; + } + + if (trainer[gTrainerBattleOpponent].trainerClass == TRAINER_CLASS_CHAMPION) + return B_TRANSITION_STEVEN; + + if (trainer[gTrainerBattleOpponent].doubleBattle == TRUE) + minPartyCount = 2; // double battles always at least have 2 pokemon. + else + minPartyCount = 1; + + transitionType = GetBattleTransitionTypeByMap(); + enemyLevel = GetSumOfEnemyPartyLevel(gTrainerBattleOpponent, minPartyCount); + playerLevel = GetSumOfPlayerPartyLevel(minPartyCount); + if (enemyLevel < playerLevel) // is wild mon level than the player's mon level? + return gBattleTransitionTable_Trainer[transitionType][0]; + else + return gBattleTransitionTable_Trainer[transitionType][1]; +} + +u8 BattleSetup_GetBattleTowerBattleTransition(void) +{ + u8 enemyLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL); + u8 playerLevel = GetSumOfPlayerPartyLevel(1); + + if (enemyLevel < playerLevel) + return B_TRANSITION_POKEBALLS_TRAIL; + else + return B_TRANSITION_BIG_POKEBALL; +} + +void ScrSpecial_ChooseStarter(void) +{ + SetMainCallback2(CB2_ChooseStarter); + gMain.savedCallback = CB2_GiveStarter; +} + +static void CB2_GiveStarter(void) +{ + u16 starterPoke; + + *GetVarPointer(VAR_STARTER_MON) = gSpecialVar_Result; + starterPoke = GetStarterPokemon(gSpecialVar_Result); + ScriptGiveMon(starterPoke, 5, 0, 0, 0, 0); + ResetTasks(); + sub_80408BC(); + SetMainCallback2(CB2_StartFirstBattle); + BattleTransition_Start(0); +} + +static void CB2_StartFirstBattle(void) +{ + UpdatePaletteFade(); + RunTasks(); + + if (IsBattleTransitionDone() == TRUE) + { + gBattleTypeFlags = BATTLE_TYPE_FIRST_BATTLE; + gMain.savedCallback = CB2_EndFirstBattle; + SetMainCallback2(sub_800E7C4); + RestartWildEncounterImmunitySteps(); + ClearPoisonStepCounter(); + IncrementGameStat(GAME_STAT_TOTAL_BATTLES); + IncrementGameStat(GAME_STAT_WILD_BATTLES); + } +} + +static void CB2_EndFirstBattle(void) +{ + Overworld_ClearSavedMusic(); + SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); +} + +// why not just use the macros? maybe its because they didnt want to uncast const every time? +static u32 TrainerBattleLoadArg32(const u8 *ptr) +{ + return T1_READ_32(ptr); +} + +static u16 TrainerBattleLoadArg16(const u8 *ptr) +{ + return T1_READ_16(ptr); +} + +static u8 TrainerBattleLoadArg8(const u8 *ptr) +{ + return T1_READ_8(ptr); +} + +static u16 CurrentOpponentTrainerFlag(void) +{ + return TRAINER_FLAG_START + gTrainerBattleOpponent; +} + +static bool32 IsPlayerDefeated(u32 battleOutcome) +{ + switch (battleOutcome) + { + case BATTLE_LOST: + case BATTLE_DREW: + return TRUE; + case BATTLE_WON: + case BATTLE_RAN: + case BATTLE_PLAYER_TELEPORTED: + case BATTLE_POKE_FLED: + case BATTLE_CAUGHT: + return FALSE; + default: + return FALSE; + } +} + +static void ResetTrainerOpponentIds(void) +{ + sTrainerBattleMode = 0; + gTrainerBattleOpponent = 0; + sTrainerEventObjectLocalId = 0; + sTrainerIntroSpeech = 0; + sTrainerDefeatSpeech = 0; + sTrainerVictorySpeech = 0; + sTrainerCannotBattleSpeech = 0; + sTrainerBattleScriptRetAddr = 0; + sTrainerBattleEndScript = 0; +} + +static void TrainerBattleLoadArgs(const struct TrainerBattleParameter *specs, const u8 *data) +{ + while (1) + { + switch (specs->ptrType) + { + case TRAINER_PARAM_LOAD_VAL_8BIT: + *(u8 *)specs->varPtr = TrainerBattleLoadArg8(data); + data += 1; + break; + case TRAINER_PARAM_LOAD_VAL_16BIT: + *(u16 *)specs->varPtr = TrainerBattleLoadArg16(data); + data += 2; + break; + case TRAINER_PARAM_LOAD_VAL_32BIT: + *(u32 *)specs->varPtr = TrainerBattleLoadArg32(data); + data += 4; + break; + case TRAINER_PARAM_CLEAR_VAL_8BIT: + *(u8 *)specs->varPtr = 0; + break; + case TRAINER_PARAM_CLEAR_VAL_16BIT: + *(u16 *)specs->varPtr = 0; + break; + case TRAINER_PARAM_CLEAR_VAL_32BIT: + *(u32 *)specs->varPtr = 0; + break; + case TRAINER_PARAM_LOAD_SCRIPT_RET_ADDR: + *(const u8 **)specs->varPtr = data; + return; + } + specs++; + } +} + +static void SetMapVarsToTrainer(void) +{ + if (sTrainerEventObjectLocalId) + { + gSpecialVar_LastTalked = sTrainerEventObjectLocalId; + gSelectedEventObject = GetEventObjectIdByLocalIdAndMap(sTrainerEventObjectLocalId, gSaveBlock1.location.mapNum, gSaveBlock1.location.mapGroup); + } +} + +u8 *BattleSetup_ConfigureTrainerBattle(const u8 *data) +{ + ResetTrainerOpponentIds(); + sTrainerBattleMode = TrainerBattleLoadArg8(data); + + switch (sTrainerBattleMode) + { + case 3: + TrainerBattleLoadArgs(gTrainerBattleSpecs_3, data); + return gUnknown_0819F878; + case 4: + TrainerBattleLoadArgs(gTrainerBattleSpecs_2, data); + SetMapVarsToTrainer(); + return gUnknown_0819F840; + case 1: + case 2: + TrainerBattleLoadArgs(gTrainerBattleSpecs_1, data); + SetMapVarsToTrainer(); + return gUnknown_0819F818; + case 6: + case 8: + TrainerBattleLoadArgs(gTrainerBattleSpecs_4, data); + SetMapVarsToTrainer(); + return gUnknown_0819F840; + case 7: + TrainerBattleLoadArgs(gTrainerBattleSpecs_2, data); + SetMapVarsToTrainer(); + gTrainerBattleOpponent = GetRematchTrainerId(gTrainerBattleOpponent); + return gUnknown_0819F8AE; + case 5: + TrainerBattleLoadArgs(gTrainerBattleSpecs_0, data); + SetMapVarsToTrainer(); + gTrainerBattleOpponent = GetRematchTrainerId(gTrainerBattleOpponent); + return gUnknown_0819F887; + default: + TrainerBattleLoadArgs(gTrainerBattleSpecs_0, data); + SetMapVarsToTrainer(); + return gUnknown_0819F818; + } +} + +void TrainerWantsBattle(u8 trainerEventObjId, const u8 *trainerScript) +{ + gSelectedEventObject = trainerEventObjId; + gSpecialVar_LastTalked = gEventObjects[trainerEventObjId].localId; + BattleSetup_ConfigureTrainerBattle(trainerScript + 1); + ScriptContext1_SetupScript(gUnknown_0819F80B); + ScriptContext2_Enable(); +} + +bool32 GetTrainerFlagFromScriptPointer(const u8 *data) +{ + u32 flag = TrainerBattleLoadArg16(data + 2); + return FlagGet(TRAINER_FLAG_START + flag); +} + +void sub_8082524(void) +{ + struct EventObject *eventObject = &gEventObjects[gSelectedEventObject]; + + SetTrainerMovementType(eventObject, GetTrainerFacingDirectionMovementType(eventObject->facingDirection)); +} + +u8 ScrSpecial_GetTrainerBattleMode(void) +{ + return sTrainerBattleMode; +} + +u8 ScrSpecial_HasTrainerBeenFought(void) +{ + return FlagGet(CurrentOpponentTrainerFlag()); +} + +void SetCurrentTrainerBattledFlag(void) +{ + FlagSet(CurrentOpponentTrainerFlag()); +} + +void unref_sub_8082590(void) +{ + FlagSet(CurrentOpponentTrainerFlag()); // duplicate function +} + +u8 HasTrainerAlreadyBeenFought(u16 flag) +{ + return FlagGet(TRAINER_FLAG_START + flag); +} + +void SetTrainerFlag(u16 flag) +{ + FlagSet(TRAINER_FLAG_START + flag); +} + +void ClearTrainerFlag(u16 flag) +{ + FlagClear(TRAINER_FLAG_START + flag); +} + +void BattleSetup_StartTrainerBattle(void) +{ + gBattleTypeFlags = BATTLE_TYPE_TRAINER; + gMain.savedCallback = CB2_EndTrainerBattle; + StartTheBattle(); + ScriptContext1_Stop(); +} + +void CB2_EndTrainerBattle(void) +{ + if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) + { + SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + } + else if (IsPlayerDefeated(gBattleOutcome) == TRUE) + { + SetMainCallback2(CB2_WhiteOut); + } + else + { + SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetCurrentTrainerBattledFlag(); + } +} + +void CB2_EndTrainerEyeRematchBattle(void) +{ + if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) + { + SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + } + else if (IsPlayerDefeated(gBattleOutcome) == TRUE) + { + SetMainCallback2(CB2_WhiteOut); + } + else + { + SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + SetCurrentTrainerBattledFlag(); + SetTrainerFlagsAfterTrainerEyeRematch(); + } +} + +void ScrSpecial_StartTrainerEyeRematch(void) +{ + gBattleTypeFlags = BATTLE_TYPE_TRAINER; + gMain.savedCallback = CB2_EndTrainerEyeRematchBattle; + StartTheBattle(); + ScriptContext1_Stop(); +} + +static const u8 *GetTrainerIntroSpeech(void); +static const u8 *GetTrainerNonBattlingSpeech(void); + +void ScrSpecial_ShowTrainerIntroSpeech(void) +{ + ShowFieldMessage(GetTrainerIntroSpeech()); +} + +u8 *BattleSetup_GetScriptAddrAfterBattle(void) +{ + if (sTrainerBattleScriptRetAddr) + return sTrainerBattleScriptRetAddr; + else + return gUnknown_081C6C02; +} + +u8 *BattleSetup_GetTrainerPostBattleScript(void) +{ + if (sTrainerBattleEndScript) + return sTrainerBattleEndScript; + else + return gUnknown_081C6C02; +} + +void ScrSpecial_ShowTrainerNonBattlingSpeech(void) +{ + ShowFieldMessage(GetTrainerNonBattlingSpeech()); +} + +void PlayTrainerEncounterMusic(void) +{ + u16 music; + + if (sTrainerBattleMode != 1 && sTrainerBattleMode != 8) + { + switch (sub_803FC58(gTrainerBattleOpponent)) + { + case TRAINER_ENCOUNTER_MUSIC_MALE: + music = MUS_BOYEYE; + break; + case TRAINER_ENCOUNTER_MUSIC_FEMALE: + music = MUS_GIRLEYE; + break; + case TRAINER_ENCOUNTER_MUSIC_GIRL: + music = MUS_SYOUJOEYE; + break; + case TRAINER_ENCOUNTER_MUSIC_INTENSE: + music = MUS_HAGESHII; + break; + case TRAINER_ENCOUNTER_MUSIC_COOL: + music = MUS_KAKKOII; + break; + case TRAINER_ENCOUNTER_MUSIC_AQUA: + music = MUS_AQA_0; + break; + case TRAINER_ENCOUNTER_MUSIC_MAGMA: + music = MUS_MGM0; + break; + case TRAINER_ENCOUNTER_MUSIC_SWIMMER: + music = MUS_SWIMEYE; + break; + case TRAINER_ENCOUNTER_MUSIC_TWINS: + music = MUS_HUTAGO; + break; + case TRAINER_ENCOUNTER_MUSIC_ELITE_FOUR: + music = MUS_SITENNOU; + break; + case TRAINER_ENCOUNTER_MUSIC_HIKER: + music = MUS_YAMA_EYE; + break; + case TRAINER_ENCOUNTER_MUSIC_INTERVIEWER: + music = MUS_INTER_V; + break; + case TRAINER_ENCOUNTER_MUSIC_RICH: + music = MUS_TEST; + break; + default: + music = MUS_AYASII; + } + PlayNewMapMusic(music); + } +} + +//Returns an empty string if a null pointer was passed, otherwise returns str +static const u8 *SanitizeString(const u8 *str) +{ + if (str) + return str; + else + return gOtherText_CancelWithTerminator; +} + +static const u8 *GetTrainerIntroSpeech(void) +{ + return SanitizeString(sTrainerIntroSpeech); +} + +u8 *GetTrainerLoseText(void) +{ + const u8 *str; + + if (gTrainerBattleOpponent == SECRET_BASE_OPPONENT) + str = GetSecretBaseTrainerLoseText(); + else + str = sTrainerDefeatSpeech; + + StringExpandPlaceholders(gStringVar4, SanitizeString(str)); + return gStringVar4; +} + +const u8 *unref_sub_808286C(void) +{ + return SanitizeString(sTrainerVictorySpeech); +} + +static const u8 *GetTrainerNonBattlingSpeech(void) +{ + return SanitizeString(sTrainerCannotBattleSpeech); +} + +s32 FirstBattleTrainerIdToRematchTableId(const struct TrainerEyeTrainer *trainers, u16 opponentId) +{ + s32 i; + + for (i = 0; i < NUM_TRAINER_EYE_TRAINERS; i++) + { + if (trainers[i].opponentIDs[0] == opponentId) + return i; + } + return -1; +} + +s32 TrainerIdToRematchTableId(const struct TrainerEyeTrainer *trainers, u16 opponentId) +{ + s32 i; + s32 j; + + for (i = 0; i < NUM_TRAINER_EYE_TRAINERS; i++) + { + for (j = 0; j < 5 && trainers[i].opponentIDs[j] != 0; j++) + { + if (trainers[i].opponentIDs[j] == opponentId) + return i; + } + } + return -1; +} + +bool32 UpdateRandomTrainerEyeRematches(const struct TrainerEyeTrainer *trainers, u16 mapGroup, u16 mapNum) +{ + int i; + bool32 ret = FALSE; + + for (i = 0; i < NUM_TRAINER_EYE_TRAINERS; i++) + { + if (trainers[i].mapGroup == mapGroup && trainers[i].mapNum == mapNum) + { + if (gSaveBlock1.trainerRematches[i] != 0) + { + // Trainer already wants rematch. Don't bother updating it + ret = TRUE; + } + else if (HasTrainerAlreadyBeenFought(trainers[i].opponentIDs[0]) == TRUE + && (Random() % 100) <= 30) // 31% chance of getting a rematch + { + int rematches = 1; + + while (rematches < 5 && trainers[i].opponentIDs[rematches] != 0 + && HasTrainerAlreadyBeenFought(trainers[i].opponentIDs[rematches])) + rematches++; + gSaveBlock1.trainerRematches[i] = rematches; + ret = TRUE; + } + } + } + return ret; +} + +s32 DoesSomeoneWantRematchIn_(const struct TrainerEyeTrainer *trainers, u16 mapGroup, u16 mapNum) +{ + s32 i; + + for (i = 0; i < NUM_TRAINER_EYE_TRAINERS; i++) + { + if (trainers[i].mapGroup == mapGroup && trainers[i].mapNum == mapNum && gSaveBlock1.trainerRematches[i]) + return 1; + } + return 0; +} + +s32 IsRematchTrainerIn_(const struct TrainerEyeTrainer *trainers, u16 mapGroup, u16 mapNum) +{ + s32 i; + + for (i = 0; i < NUM_TRAINER_EYE_TRAINERS; i++) + { + if (trainers[i].mapGroup == mapGroup && trainers[i].mapNum == mapNum) + return 1; + } + return 0; +} + +bool8 IsFirstTrainerIdReadyForRematch(const struct TrainerEyeTrainer *trainers, u16 opponentId) +{ + s32 trainerEyeIndex = FirstBattleTrainerIdToRematchTableId(trainers, opponentId); + + if (trainerEyeIndex != -1 && trainerEyeIndex < 100 && gSaveBlock1.trainerRematches[trainerEyeIndex]) + return TRUE; + else + return FALSE; +} + +bool8 GetTrainerEyeRematchFlag(const struct TrainerEyeTrainer *trainers, u16 opponentId) +{ + s32 trainerEyeIndex = TrainerIdToRematchTableId(trainers, opponentId); + + if (trainerEyeIndex != -1 && trainerEyeIndex < 100 && gSaveBlock1.trainerRematches[trainerEyeIndex]) + return TRUE; + else + return FALSE; +} + +u16 GetRematchTrainerIdFromTable(const struct TrainerEyeTrainer *trainers, u16 opponentId) +{ + int i; + const struct TrainerEyeTrainer *trainer; + s32 trainerEyeIndex = FirstBattleTrainerIdToRematchTableId(trainers, opponentId); + + if (trainerEyeIndex == -1) + return 0; + trainer = &trainers[trainerEyeIndex]; + for (i = 1; i < 5; i++) + { + if (!trainer->opponentIDs[i]) + return trainer->opponentIDs[i - 1]; + if (!HasTrainerAlreadyBeenFought(trainer->opponentIDs[i])) + return trainer->opponentIDs[i]; + } + return trainer->opponentIDs[4]; +} + +void ClearTrainerEyeRematchFlag(const struct TrainerEyeTrainer *trainers, u16 opponentId) +{ + s32 trainerEyeIndex = TrainerIdToRematchTableId(trainers, opponentId); + + if (trainerEyeIndex != -1) + gSaveBlock1.trainerRematches[trainerEyeIndex] = 0; +} + +bool8 WasSecondRematchWon(const struct TrainerEyeTrainer *trainers, u16 opponentId) +{ + s32 trainerEyeIndex = FirstBattleTrainerIdToRematchTableId(trainers, opponentId); + + if (trainerEyeIndex != -1 && HasTrainerAlreadyBeenFought(trainers[trainerEyeIndex].opponentIDs[1])) + return TRUE; + else + return FALSE; +} + +bool32 HasAtLeastFiveBadges(void) +{ + int badgeCount = 0; + u32 i; + + for (i = 0; i < 8; i++) + { + if (FlagGet(sBadgeFlags[i]) == TRUE) + { + badgeCount++; + if (badgeCount >= 5) + return TRUE; + } + } + return FALSE; +} + +void IncrementRematchStepCounter(void) +{ + if (HasAtLeastFiveBadges()) + { + if (gSaveBlock1.trainerRematchStepCounter >= TRAINER_REMATCH_STEPS) + gSaveBlock1.trainerRematchStepCounter = TRAINER_REMATCH_STEPS; + else + gSaveBlock1.trainerRematchStepCounter++; + } +} + +bool32 IsRematchStepCounterMaxed(void) +{ + if (HasAtLeastFiveBadges() && gSaveBlock1.trainerRematchStepCounter >= TRAINER_REMATCH_STEPS) + return TRUE; + else + return FALSE; +} + +void TryUpdateRandomTrainerRematches(u16 mapGroup, u16 mapNum) +{ + if (IsRematchStepCounterMaxed() && UpdateRandomTrainerEyeRematches(gTrainerEyeTrainers, mapGroup, mapNum) == TRUE) + gSaveBlock1.trainerRematchStepCounter = 0; +} + +s32 DoesSomeoneWantRematchIn(u16 mapGroup, u16 mapNum) +{ + return DoesSomeoneWantRematchIn_(gTrainerEyeTrainers, mapGroup, mapNum); +} + +s32 IsRematchTrainerIn(u16 mapGroup, u16 mapNum) +{ + return IsRematchTrainerIn_(gTrainerEyeTrainers, mapGroup, mapNum); +} + +u16 GetRematchTrainerId(u16 opponentId) +{ + return GetRematchTrainerIdFromTable(gTrainerEyeTrainers, opponentId); +} + +bool8 ShouldTryRematchBattle(void) +{ + if (IsFirstTrainerIdReadyForRematch(gTrainerEyeTrainers, gTrainerBattleOpponent)) + return 1; + else + return WasSecondRematchWon(gTrainerEyeTrainers, gTrainerBattleOpponent); +} + +u8 ScrSpecial_GetTrainerEyeRematchFlag(void) +{ + return GetTrainerEyeRematchFlag(gTrainerEyeTrainers, gTrainerBattleOpponent); +} + +void SetTrainerFlagsAfterTrainerEyeRematch(void) +{ + ClearTrainerEyeRematchFlag(gTrainerEyeTrainers, gTrainerBattleOpponent); + SetCurrentTrainerBattledFlag(); +} diff --git a/src/battle_transition.c b/src/battle_transition.c new file mode 100644 index 000000000..a0c94f713 --- /dev/null +++ b/src/battle_transition.c @@ -0,0 +1,2511 @@ +#include "global.h" +#include "battle_transition.h" +#include "main.h" +#include "overworld.h" +#include "task.h" +#include "palette.h" +#include "trig.h" +#include "field_effect.h" +#include "field_weather.h" +#include "random.h" +#include "sprite.h" +#include "sound.h" +#include "trainer.h" +#include "field_camera.h" +#include "ewram.h" +#include "scanline_effect.h" +#include "constants/songs.h" +#include "constants/field_effects.h" + +void ScanlineEffect_Clear(void); + +extern const struct OamData gFieldOamData_32x32; + +struct TransitionData +{ + vs8 VBlank_DMA; + u16 WININ; + u16 WINOUT; + u16 field_6; + u16 WIN0V; + u16 field_A; + u16 field_C; + u16 BLDCNT; + u16 BLDALPHA; + u16 BLDY; + s16 field_14; + s16 field_16; + s16 field_18; + s16 field_1A; + s16 field_1C; + s16 field_1E; // unused + s16 field_20; + s16 field_22; // unused + s16 data[11]; +}; + +typedef bool8 (*TransitionState)(struct Task* task); +typedef bool8 (*TransitionSpriteCallback)(struct Sprite* sprite); + +// this file's functions +static void LaunchBattleTransitionTask(u8 transitionID); +static void Task_BattleTransitionMain(u8 taskID); +static void Phase1Task_TransitionAll(u8 taskID); +static void Phase2Task_Transition_Blur(u8 taskID); +static void Phase2Task_Transition_Swirl(u8 taskID); +static void Phase2Task_Transition_Shuffle(u8 taskID); +static void Phase2Task_Transition_BigPokeball(u8 taskID); +static void Phase2Task_Transition_PokeballsTrail(u8 taskID); +static void Phase2Task_Transition_Clockwise_BlackFade(u8 taskID); +static void Phase2Task_Transition_Ripple(u8 taskID); +static void Phase2Task_Transition_Wave(u8 taskID); +static void Phase2Task_Transition_Slice(u8 taskID); +static void Phase2Task_Transition_WhiteFade(u8 taskID); +static void Phase2Task_Transition_GridSquares(u8 taskID); +static void Phase2Task_Transition_Shards(u8 taskID); +static void Phase2Task_Transition_Sydney(u8 taskID); +static void Phase2Task_Transition_Phoebe(u8 taskID); +static void Phase2Task_Transition_Glacia(u8 taskID); +static void Phase2Task_Transition_Drake(u8 taskID); +static void Phase2Task_Transition_Steven(u8 taskID); +static bool8 Transition_Phase1(struct Task* task); +static bool8 Transition_WaitForPhase1(struct Task* task); +static bool8 Transition_Phase2(struct Task* task); +static bool8 Transition_WaitForPhase2(struct Task* task); +static void VBlankCB_Phase2_Transition_Swirl(void); +static void HBlankCB_Phase2_Transition_Swirl(void); +static void VBlankCB_Phase2_Transition_Shuffle(void); +static void HBlankCB_Phase2_Transition_Shuffle(void); +static void VBlankCB0_Phase2_Transition_BigPokeball(void); +static void VBlankCB1_Phase2_Transition_BigPokeball(void); +static void VBlankCB_Phase2_Transition_Clockwise_BlackFade(void); +static void VBlankCB_Phase2_Transition_Ripple(void); +static void HBlankCB_Phase2_Transition_Ripple(void); +static void VBlankCB_Phase2_Transition_Wave(void); +static void VBlankCB_Phase2_Transition_Slice(void); +static void HBlankCB_Phase2_Transition_Slice(void); +static void VBlankCB0_Phase2_Transition_WhiteFade(void); +static void VBlankCB1_Phase2_Transition_WhiteFade(void); +static void HBlankCB_Phase2_Transition_WhiteFade(void); +static void VBlankCB0_Phase2_Mugshots(void); +static void VBlankCB1_Phase2_Mugshots(void); +static void HBlankCB_Phase2_Mugshots(void); +static void VBlankCB_Phase2_Transition_Shards(void); +static bool8 Phase2_Transition_Blur_Func1(struct Task* task); +static bool8 Phase2_Transition_Blur_Func2(struct Task* task); +static bool8 Phase2_Transition_Blur_Func3(struct Task* task); +static bool8 Phase2_Transition_Swirl_Func1(struct Task* task); +static bool8 Phase2_Transition_Swirl_Func2(struct Task* task); +static bool8 Phase2_Transition_Shuffle_Func1(struct Task* task); +static bool8 Phase2_Transition_Shuffle_Func2(struct Task* task); +static bool8 Phase2_Transition_BigPokeball_Func1(struct Task* task); +static bool8 Phase2_Transition_BigPokeball_Func2(struct Task* task); +static bool8 Phase2_Transition_BigPokeball_Func3(struct Task* task); +static bool8 Phase2_Transition_BigPokeball_Func4(struct Task* task); +static bool8 Phase2_Transition_BigPokeball_Func5(struct Task* task); +static bool8 Phase2_Transition_BigPokeball_Func6(struct Task* task); +static bool8 Phase2_Transition_PokeballsTrail_Func1(struct Task* task); +static bool8 Phase2_Transition_PokeballsTrail_Func2(struct Task* task); +static bool8 Phase2_Transition_PokeballsTrail_Func3(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func1(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func2(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func3(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func4(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func5(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func6(struct Task* task); +static bool8 Phase2_Transition_Clockwise_BlackFade_Func7(struct Task* task); +static bool8 Phase2_Transition_Ripple_Func1(struct Task* task); +static bool8 Phase2_Transition_Ripple_Func2(struct Task* task); +static bool8 Phase2_Transition_Wave_Func1(struct Task* task); +static bool8 Phase2_Transition_Wave_Func2(struct Task* task); +static bool8 Phase2_Transition_Wave_Func3(struct Task* task); +static bool8 Phase2_Transition_Slice_Func1(struct Task* task); +static bool8 Phase2_Transition_Slice_Func2(struct Task* task); +static bool8 Phase2_Transition_Slice_Func3(struct Task* task); +static bool8 Phase2_Transition_WhiteFade_Func1(struct Task* task); +static bool8 Phase2_Transition_WhiteFade_Func2(struct Task* task); +static bool8 Phase2_Transition_WhiteFade_Func3(struct Task* task); +static bool8 Phase2_Transition_WhiteFade_Func4(struct Task* task); +static bool8 Phase2_Transition_WhiteFade_Func5(struct Task* task); +static bool8 Phase2_Transition_GridSquares_Func1(struct Task* task); +static bool8 Phase2_Transition_GridSquares_Func2(struct Task* task); +static bool8 Phase2_Transition_GridSquares_Func3(struct Task* task); +static bool8 Phase2_Transition_Shards_Func1(struct Task* task); +static bool8 Phase2_Transition_Shards_Func2(struct Task* task); +static bool8 Phase2_Transition_Shards_Func3(struct Task* task); +static bool8 Phase2_Transition_Shards_Func4(struct Task* task); +static bool8 Phase2_Transition_Shards_Func5(struct Task* task); +static bool8 Phase2_Mugshot_Func1(struct Task* task); +static bool8 Phase2_Mugshot_Func2(struct Task* task); +static bool8 Phase2_Mugshot_Func3(struct Task* task); +static bool8 Phase2_Mugshot_Func4(struct Task* task); +static bool8 Phase2_Mugshot_Func5(struct Task* task); +static bool8 Phase2_Mugshot_Func6(struct Task* task); +static bool8 Phase2_Mugshot_Func7(struct Task* task); +static bool8 Phase2_Mugshot_Func8(struct Task* task); +static bool8 Phase2_Mugshot_Func9(struct Task* task); +static bool8 Phase2_Mugshot_Func10(struct Task* task); +static void Phase2Task_MugShotTransition(u8 taskID); +static void Mugshots_CreateOpponentPlayerSprites(struct Task* task); +static void sub_811CA10(s16 spriteID, s16 value); +static void sub_811CA28(s16 spriteID); +static s16 sub_811CA44(s16 spriteID); +static bool8 sub_811C934(struct Sprite* sprite); +static bool8 sub_811C938(struct Sprite* sprite); +static bool8 sub_811C984(struct Sprite* sprite); +static bool8 sub_811C9B8(struct Sprite* sprite); +static bool8 sub_811C9E4(struct Sprite* sprite); +static void CreatePhase1Task(s16 a0, s16 a1, s16 a2, s16 a3, s16 a4); +static bool8 sub_811D52C(void); +static void Phase1_Task_RunFuncs(u8 taskID); +static bool8 Phase1_TransitionAll_Func1(struct Task* task); +static bool8 Phase1_TransitionAll_Func2(struct Task* task); +static void sub_811D658(void); +static void VBlankCB_BattleTransition(void); +static void sub_811D6A8(u16** a0, u16** a1); +static void sub_811D690(u16** a0); +static void sub_811D6D4(void); +static void sub_811D6E8(s16* array, s16 sinAdd, s16 index, s16 indexIncrementer, s16 amplitude, s16 arrSize); +static void sub_811D764(u16* a0, s16 a1, s16 a2, s16 a3); +static void sub_811D8FC(s16* a0, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6); +static bool8 sub_811D978(s16* a0, bool8 a1, bool8 a2); +static void sub_811CFD0(struct Sprite* sprite); +static void sub_811B720(struct Sprite* sprite); +static void sub_811C90C(struct Sprite* sprite); + +// const data + +static const u32 sBigPokeball_Tileset[] = INCBIN_U32("graphics/battle_transitions/big_pokeball.4bpp"); +static const u32 sPokeballTrail_Tileset[] = INCBIN_U32("graphics/battle_transitions/pokeball_trail.4bpp"); +static const u8 sSpriteImage_83FC148[] = INCBIN_U8("graphics/battle_transitions/pokeball.4bpp"); +static const u32 sUnknown_083FC348[] = INCBIN_U32("graphics/battle_transitions/elite_four_bg.4bpp"); +static const u8 sSpriteImage_83FC528[] = INCBIN_U8("graphics/battle_transitions/unused_brendan.4bpp"); +static const u8 sSpriteImage_83FCD28[] = INCBIN_U8("graphics/battle_transitions/unused_lass.4bpp"); +static const u32 sShrinkingBoxTileset[] = INCBIN_U32("graphics/battle_transitions/shrinking_box.4bpp"); + +static struct TransitionData * const sTransitionStructPtr = &TRANSITION_STRUCT; + +static const TaskFunc sPhase1_Tasks[TRANSITIONS_NO] = +{ + [0 ... TRANSITIONS_NO - 1] = &Phase1Task_TransitionAll +}; + +static const TaskFunc sPhase2_Tasks[TRANSITIONS_NO] = +{ + Phase2Task_Transition_Blur, // 0 + Phase2Task_Transition_Swirl, // 1 + Phase2Task_Transition_Shuffle, // 2 + Phase2Task_Transition_BigPokeball, // 3 + Phase2Task_Transition_PokeballsTrail, // 4 + Phase2Task_Transition_Clockwise_BlackFade, // 5 + Phase2Task_Transition_Ripple, // 6 + Phase2Task_Transition_Wave, // 7 + Phase2Task_Transition_Slice, // 8 + Phase2Task_Transition_WhiteFade, // 9 + Phase2Task_Transition_GridSquares, // 10 + Phase2Task_Transition_Shards, // 11 + Phase2Task_Transition_Sydney, // 12 + Phase2Task_Transition_Phoebe, // 13 + Phase2Task_Transition_Glacia, // 14 + Phase2Task_Transition_Drake, // 15 + Phase2Task_Transition_Steven, // 16 +}; + +static const TransitionState sMainTransitionPhases[] = +{ + &Transition_Phase1, + &Transition_WaitForPhase1, + &Transition_Phase2, + &Transition_WaitForPhase2 +}; + +static const TransitionState sPhase2_Transition_Blur_Funcs[] = +{ + Phase2_Transition_Blur_Func1, + Phase2_Transition_Blur_Func2, + Phase2_Transition_Blur_Func3 +}; + +static const TransitionState sPhase2_Transition_Swirl_Funcs[] = +{ + Phase2_Transition_Swirl_Func1, + Phase2_Transition_Swirl_Func2, +}; + +static const TransitionState sPhase2_Transition_Shuffle_Funcs[] = +{ + Phase2_Transition_Shuffle_Func1, + Phase2_Transition_Shuffle_Func2, +}; + +static const TransitionState sPhase2_Transition_BigPokeball_Funcs[] = +{ + Phase2_Transition_BigPokeball_Func1, + Phase2_Transition_BigPokeball_Func2, + Phase2_Transition_BigPokeball_Func3, + Phase2_Transition_BigPokeball_Func4, + Phase2_Transition_BigPokeball_Func5, + Phase2_Transition_BigPokeball_Func6 +}; + +static const TransitionState sPhase2_Transition_PokeballsTrail_Funcs[] = +{ + Phase2_Transition_PokeballsTrail_Func1, + Phase2_Transition_PokeballsTrail_Func2, + Phase2_Transition_PokeballsTrail_Func3 +}; + +static const s16 sUnknown_083FD7E4[2] = {-16, 256}; +static const s16 sUnknown_083FD7E8[5] = {0, 32, 64, 18, 48}; +static const s16 sUnknown_083FD7F2[2] = {8, -8}; + +static const TransitionState sPhase2_Transition_Clockwise_BlackFade_Funcs[] = +{ + Phase2_Transition_Clockwise_BlackFade_Func1, + Phase2_Transition_Clockwise_BlackFade_Func2, + Phase2_Transition_Clockwise_BlackFade_Func3, + Phase2_Transition_Clockwise_BlackFade_Func4, + Phase2_Transition_Clockwise_BlackFade_Func5, + Phase2_Transition_Clockwise_BlackFade_Func6, + Phase2_Transition_Clockwise_BlackFade_Func7 +}; + +static const TransitionState sPhase2_Transition_Ripple_Funcs[] = +{ + Phase2_Transition_Ripple_Func1, + Phase2_Transition_Ripple_Func2 +}; + +static const TransitionState sPhase2_Transition_Wave_Funcs[] = +{ + Phase2_Transition_Wave_Func1, + Phase2_Transition_Wave_Func2, + Phase2_Transition_Wave_Func3 +}; + +static const TransitionState sPhase2_Mugshot_Transition_Funcs[] = +{ + Phase2_Mugshot_Func1, + Phase2_Mugshot_Func2, + Phase2_Mugshot_Func3, + Phase2_Mugshot_Func4, + Phase2_Mugshot_Func5, + Phase2_Mugshot_Func6, + Phase2_Mugshot_Func7, + Phase2_Mugshot_Func8, + Phase2_Mugshot_Func9, + Phase2_Mugshot_Func10 +}; + +static const u8 sMugshotsTrainerPicIDsTable[MUGSHOTS_NO] = {TRAINER_PIC_SIDNEY, TRAINER_PIC_PHOEBE, TRAINER_PIC_GLACIA, TRAINER_PIC_DRAKE, TRAINER_PIC_STEVEN}; +static const s16 sMugshotsOpponentRotationScales[MUGSHOTS_NO][2] = +{ + {0x200, 0x200}, + {0x200, 0x200}, + {0x1B0, 0x1B0}, + {0x1A0, 0x1A0}, + {0x188, 0x188}, +}; +static const s16 sMugshotsOpponentCoords[MUGSHOTS_NO][2] = +{ + {0, 0}, + {0, 0}, + {-4, 4}, + {0, 5}, + {0, 7}, +}; + +static const TransitionSpriteCallback sUnknown_083FD880[] = +{ + sub_811C934, + sub_811C938, + sub_811C984, + sub_811C9B8, + sub_811C934, + sub_811C9E4, + sub_811C934 +}; + +static const s16 sUnknown_083FD89C[2] = {12, -12}; +static const s16 sUnknown_083FD8A0[2] = {-1, 1}; + +static const TransitionState sPhase2_Transition_Slice_Funcs[] = +{ + Phase2_Transition_Slice_Func1, + Phase2_Transition_Slice_Func2, + Phase2_Transition_Slice_Func3 +}; + +static const TransitionState sPhase2_Transition_WhiteFade_Funcs[] = +{ + Phase2_Transition_WhiteFade_Func1, + Phase2_Transition_WhiteFade_Func2, + Phase2_Transition_WhiteFade_Func3, + Phase2_Transition_WhiteFade_Func4, + Phase2_Transition_WhiteFade_Func5 +}; + +static const s16 sUnknown_083FD8C4[8] = {0, 20, 15, 40, 10, 25, 35, 5}; + +static const TransitionState sPhase2_Transition_GridSquares_Funcs[] = +{ + Phase2_Transition_GridSquares_Func1, + Phase2_Transition_GridSquares_Func2, + Phase2_Transition_GridSquares_Func3 +}; + +static const TransitionState sPhase2_Transition_Shards_Funcs[] = +{ + Phase2_Transition_Shards_Func1, + Phase2_Transition_Shards_Func2, + Phase2_Transition_Shards_Func3, + Phase2_Transition_Shards_Func4, + Phase2_Transition_Shards_Func5 +}; + +static const s16 sUnknown_083FD8F4[][5] = +{ + {56, 0, 0, 160, 0}, + {104, 160, 240, 88, 1}, + {240, 72, 56, 0, 1}, + {0, 32, 144, 160, 0}, + {144, 160, 184, 0, 1}, + {56, 0, 168, 160, 0}, + {168, 160, 48, 0, 1}, +}; + +static const s16 sUnknown_083FD93A[] = {8, 4, 2, 1, 1, 1, 0}; + +static const TransitionState sPhase1_TransitionAll_Funcs[] = +{ + Phase1_TransitionAll_Func1, + Phase1_TransitionAll_Func2 +}; + +static const struct SpriteFrameImage sSpriteImageTable_83FD950[] = +{ + sSpriteImage_83FC148, 0x200 +}; + +static const union AnimCmd sSpriteAnim_83FD958[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_83FD960[] = +{ + sSpriteAnim_83FD958 +}; + +static const union AffineAnimCmd sSpriteAffineAnim_83FD964[] = +{ + AFFINEANIMCMD_FRAME(0, 0, -4, 1), + AFFINEANIMCMD_JUMP(0) +}; + +static const union AffineAnimCmd sSpriteAffineAnim_83FD974[] = +{ + AFFINEANIMCMD_FRAME(0, 0, 4, 1), + AFFINEANIMCMD_JUMP(0) +}; + +static const union AffineAnimCmd *const sSpriteAffineAnimTable_83FD984[] = +{ + sSpriteAffineAnim_83FD964, + sSpriteAffineAnim_83FD974 +}; + +static const struct SpriteTemplate sSpriteTemplate_83FD98C = +{ + .tileTag = 0xFFFF, + .paletteTag = 4105, + .oam = &gFieldOamData_32x32, + .anims = sSpriteAnimTable_83FD960, + .images = sSpriteImageTable_83FD950, + .affineAnims = sSpriteAffineAnimTable_83FD984, + .callback = sub_811B720 +}; + +static const struct OamData gOamData_83FD9A4 = +{ + .y = 0, + .affineMode = 0, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 3, + .tileNum = 0, + .priority = 0, + .paletteNum = 0, + .affineParam = 0, +}; + +static const struct SpriteFrameImage sSpriteImageTable_83FD9AC[] = +{ + sSpriteImage_83FC528, 0x800 +}; + +static const struct SpriteFrameImage sSpriteImageTable_83FD9B4[] = +{ + sSpriteImage_83FCD28, 0x800 +}; + +static const union AnimCmd sSpriteAnim_83FD9BC[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_END +}; + +static const union AnimCmd *const sSpriteAnimTable_83FD9C4[] = +{ + sSpriteAnim_83FD9BC +}; + +static const struct SpriteTemplate sSpriteTemplate_83FD9C8 = +{ + .tileTag = 0xFFFF, + .paletteTag = 4106, + .oam = &gOamData_83FD9A4, + .anims = sSpriteAnimTable_83FD9C4, + .images = sSpriteImageTable_83FD9AC, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_811C90C +}; + +static const struct SpriteTemplate sSpriteTemplate_83FD9E0 = +{ + .tileTag = 0xFFFF, + .paletteTag = 4106, + .oam = &gOamData_83FD9A4, + .anims = sSpriteAnimTable_83FD9C4, + .images = sSpriteImageTable_83FD9B4, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_811C90C +}; + +static const u16 gFieldEffectObjectPalette10[] = INCBIN_U16("graphics/field_effect_objects/palettes/10.gbapal"); + +const struct SpritePalette gFieldEffectObjectPaletteInfo10 = +{ + gFieldEffectObjectPalette10, 0x1009 +}; + +static const u16 sMugshotPal_Sydney[] = INCBIN_U16("graphics/battle_transitions/sidney_bg.gbapal"); +static const u16 sMugshotPal_Phoebe[] = INCBIN_U16("graphics/battle_transitions/phoebe_bg.gbapal"); +static const u16 sMugshotPal_Glacia[] = INCBIN_U16("graphics/battle_transitions/glacia_bg.gbapal"); +static const u16 sMugshotPal_Drake[] = INCBIN_U16("graphics/battle_transitions/drake_bg.gbapal"); +static const u16 sMugshotPal_Steven[] = INCBIN_U16("graphics/battle_transitions/steven_bg.gbapal"); +static const u16 sMugshotPal_Brendan[] = INCBIN_U16("graphics/battle_transitions/brendan_bg.gbapal"); +static const u16 sMugshotPal_May[] = INCBIN_U16("graphics/battle_transitions/may_bg.gbapal"); + +static const u16 * const sOpponentMugshotsPals[MUGSHOTS_NO] = +{ + sMugshotPal_Sydney, + sMugshotPal_Phoebe, + sMugshotPal_Glacia, + sMugshotPal_Drake, + sMugshotPal_Steven +}; + +static const u16 * const sPlayerMugshotsPals[2] = +{ + sMugshotPal_Brendan, + sMugshotPal_May +}; + +static const u16 sUnusedTrainerPalette[] = INCBIN_U16("graphics/battle_transitions/unused_trainer.gbapal"); +static const struct SpritePalette sSpritePalette_UnusedTrainer = +{ + sUnusedTrainerPalette, 0x100A +}; + +static const u16 sBigPokeball_Tilemap[] = INCBIN_U16("graphics/battle_transitions/big_pokeball_map.bin"); +static const u16 sMugshotsTilemap[] = INCBIN_U16("graphics/battle_transitions/elite_four_bg_map.bin"); + +// actual code starts here + +void BattleTransition_StartOnField(u8 transitionID) +{ + gMain.callback2 = CB2_OverworldBasic; + LaunchBattleTransitionTask(transitionID); +} + +void BattleTransition_Start(u8 transitionID) +{ + LaunchBattleTransitionTask(transitionID); +} + +#define tState data[0] +#define tTransitionID data[1] +#define tTransitionDone data[15] + +bool8 IsBattleTransitionDone(void) +{ + u8 taskID = FindTaskIdByFunc(Task_BattleTransitionMain); + if (gTasks[taskID].tTransitionDone) + { + DestroyTask(taskID); + return TRUE; + } + else + return FALSE; +} + +static void LaunchBattleTransitionTask(u8 transitionID) +{ + u8 taskID = CreateTask(Task_BattleTransitionMain, 2); + gTasks[taskID].tTransitionID = transitionID; +} + +static void Task_BattleTransitionMain(u8 taskID) +{ + while (sMainTransitionPhases[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Transition_Phase1(struct Task* task) +{ + SetWeatherScreenFadeOut(); + CpuCopy32(gPlttBufferFaded, gPlttBufferUnfaded, 0x400); + if (sPhase1_Tasks[task->tTransitionID] != NULL) + { + CreateTask(sPhase1_Tasks[task->tTransitionID], 4); + task->tState++; + return FALSE; + } + else + { + task->tState = 2; + return TRUE; + } +} + +static bool8 Transition_WaitForPhase1(struct Task* task) +{ + if (FindTaskIdByFunc(sPhase1_Tasks[task->tTransitionID]) == 0xFF) + { + task->tState++; + return TRUE; + } + else + return FALSE; +} + +static bool8 Transition_Phase2(struct Task* task) +{ + CreateTask(sPhase2_Tasks[task->tTransitionID], 0); + task->tState++; + return FALSE; +} + +static bool8 Transition_WaitForPhase2(struct Task* task) +{ + task->tTransitionDone = 0; + if (FindTaskIdByFunc(sPhase2_Tasks[task->tTransitionID]) == 0xFF) + task->tTransitionDone = 1; + return FALSE; +} + +static void Phase1Task_TransitionAll(u8 taskID) +{ + if (gTasks[taskID].tState == 0) + { + gTasks[taskID].tState++; + CreatePhase1Task(0, 0, 3, 2, 2); + } + else if (sub_811D52C()) + DestroyTask(taskID); +} + +static void Phase2Task_Transition_Blur(u8 taskID) +{ + while (sPhase2_Transition_Blur_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Blur_Func1(struct Task* task) +{ + REG_MOSAIC = 0; + REG_BG1CNT |= BGCNT_MOSAIC; + REG_BG2CNT |= BGCNT_MOSAIC; + REG_BG3CNT |= BGCNT_MOSAIC; + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Blur_Func2(struct Task* task) +{ + if (task->data[1] != 0) + task->data[1]--; + else + { + task->data[1] = 4; + if (++task->data[2] == 10) + BeginNormalPaletteFade(0xFFFFFFFF, -1, 0, 16, RGB(0, 0, 0)); + REG_MOSAIC = (task->data[2] & 15) * 17; + if (task->data[2] > 14) + task->tState++; + } + return FALSE; +} + +static bool8 Phase2_Transition_Blur_Func3(struct Task* task) +{ + if (!gPaletteFade.active) + { + u8 taskID = FindTaskIdByFunc(Phase2Task_Transition_Blur); + DestroyTask(taskID); + } + return FALSE; +} + +static void Phase2Task_Transition_Swirl(u8 taskID) +{ + while (sPhase2_Transition_Swirl_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Swirl_Func1(struct Task* task) +{ + u16 savedIME; + + sub_811D658(); + ScanlineEffect_Clear(); + BeginNormalPaletteFade(0xFFFFFFFF, 4, 0, 16, RGB(0, 0, 0)); + sub_811D6E8(gScanlineEffectRegBuffers[1], TRANSITION_STRUCT.field_14, 0, 2, 0, 160); + + SetVBlankCallback(VBlankCB_Phase2_Transition_Swirl); + SetHBlankCallback(HBlankCB_Phase2_Transition_Swirl); + + savedIME = REG_IME; + REG_IME = 0; + REG_IE |= (INTR_FLAG_VBLANK | INTR_FLAG_HBLANK); + REG_IME = savedIME; + REG_DISPSTAT |= (DISPSTAT_VBLANK_INTR | DISPSTAT_HBLANK_INTR); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_Swirl_Func2(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + task->data[1] += 4; + task->data[2] += 8; + + sub_811D6E8(gScanlineEffectRegBuffers[0], TRANSITION_STRUCT.field_14, task->data[1], 2, task->data[2], 160); + + if (!gPaletteFade.active) + { + u8 taskID = FindTaskIdByFunc(Phase2Task_Transition_Swirl); + DestroyTask(taskID); + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Swirl(void) +{ + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); +} + +static void HBlankCB_Phase2_Transition_Swirl(void) +{ + u16 var = gScanlineEffectRegBuffers[1][REG_VCOUNT]; + REG_BG1HOFS = var; + REG_BG2HOFS = var; + REG_BG3HOFS = var; +} + +static void Phase2Task_Transition_Shuffle(u8 taskID) +{ + while (sPhase2_Transition_Shuffle_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Shuffle_Func1(struct Task* task) +{ + u16 savedIME; + + sub_811D658(); + ScanlineEffect_Clear(); + + BeginNormalPaletteFade(0xFFFFFFFF, 4, 0, 16, RGB(0, 0, 0)); + memset(gScanlineEffectRegBuffers[1], TRANSITION_STRUCT.field_16, 0x140); + + SetVBlankCallback(VBlankCB_Phase2_Transition_Shuffle); + SetHBlankCallback(HBlankCB_Phase2_Transition_Shuffle); + + savedIME = REG_IME; + REG_IME = 0; + REG_IE |= (INTR_FLAG_VBLANK | INTR_FLAG_HBLANK); + REG_IME = savedIME; + REG_DISPSTAT |= (DISPSTAT_VBLANK_INTR | DISPSTAT_HBLANK_INTR); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_Shuffle_Func2(struct Task* task) +{ + u8 i; + u16 r3, r4; + + TRANSITION_STRUCT.VBlank_DMA = 0; + r4 = task->data[1]; + r3 = task->data[2] >> 8; + task->data[1] += 4224; + task->data[2] += 384; + + for (i = 0; i < 160; i++, r4 += 4224) + { + u16 var = r4 / 256; + gScanlineEffectRegBuffers[0][i] = TRANSITION_STRUCT.field_16 + Sin(var, r3); + } + + if (!gPaletteFade.active) + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Shuffle)); + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Shuffle(void) +{ + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); +} + +static void HBlankCB_Phase2_Transition_Shuffle(void) +{ + u16 var = gScanlineEffectRegBuffers[1][REG_VCOUNT]; + REG_BG1VOFS = var; + REG_BG2VOFS = var; + REG_BG3VOFS = var; +} + +static void Phase2Task_Transition_BigPokeball(u8 taskID) +{ + while (sPhase2_Transition_BigPokeball_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_BigPokeball_Func1(struct Task* task) +{ + u16 i; + u16 *dst1, *dst2; + + sub_811D658(); + ScanlineEffect_Clear(); + + task->data[1] = 16; + task->data[2] = 0; + task->data[4] = 0; + task->data[5] = 0x4000; + TRANSITION_STRUCT.WININ = 63; + TRANSITION_STRUCT.WINOUT = 0; + TRANSITION_STRUCT.field_6 = 240; + TRANSITION_STRUCT.WIN0V = 160; + TRANSITION_STRUCT.BLDCNT = 0x3F41; + TRANSITION_STRUCT.BLDALPHA = task->data[1] * 256; // 16 * 256 = 0x1000 + + for (i = 0; i < 160; i++) + { + gScanlineEffectRegBuffers[1][i] = 240; + } + + SetVBlankCallback(VBlankCB0_Phase2_Transition_BigPokeball); + + sub_811D6A8(&dst1, & dst2); + CpuFill16(0, dst1, 0x800); + CpuSet(sBigPokeball_Tileset, dst2, 0x2C0); + LoadPalette(gFieldEffectObjectPalette10, 240, 32); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_BigPokeball_Func2(struct Task* task) +{ + s16 i, j; + u16 *dst1, *dst2; + const u16* BigPokeballMap; + + BigPokeballMap = sBigPokeball_Tilemap; + sub_811D6A8(&dst1, &dst2); + for (i = 0; i < 20; i++) + { + for (j = 0; j < 30; j++, BigPokeballMap++) + { + dst1[i * 32 + j] = *BigPokeballMap | 0xF000; + } + } + sub_811D6E8(gScanlineEffectRegBuffers[0], 0, task->data[4], 132, task->data[5], 160); + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_BigPokeball_Func3(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + if (task->data[3] == 0 || --task->data[3] == 0) + { + task->data[2]++; + task->data[3] = 2; + } + TRANSITION_STRUCT.BLDALPHA = (task->data[1] << 8) | task->data[2]; + if (task->data[2] > 15) + task->tState++; + task->data[4] += 8; + task->data[5] -= 256; + + sub_811D6E8(gScanlineEffectRegBuffers[0], 0, task->data[4], 132, task->data[5] >> 8, 160); + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_BigPokeball_Func4(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + if (task->data[3] == 0 || --task->data[3] == 0) + { + task->data[1]--; + task->data[3] = 2; + } + TRANSITION_STRUCT.BLDALPHA = (task->data[1] << 8) | task->data[2]; + if (task->data[1] == 0) + task->tState++; + task->data[4] += 8; + task->data[5] -= 256; + + sub_811D6E8(gScanlineEffectRegBuffers[0], 0, task->data[4], 132, task->data[5] >> 8, 160); + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_BigPokeball_Func5(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + task->data[4] += 8; + task->data[5] -= 256; + + sub_811D6E8(gScanlineEffectRegBuffers[0], 0, task->data[4], 132, task->data[5] >> 8, 160); + + if (task->data[5] <= 0) + { + task->tState++; + task->data[1] = 160; + task->data[2] = 256; + task->data[3] = 0; + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_BigPokeball_Func6(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + if (task->data[2] < 1024) + task->data[2] += 128; + if (task->data[1] != 0) + { + task->data[1] -= (task->data[2] >> 8); + if (task->data[1] < 0) + task->data[1] = 0; + } + sub_811D764(gScanlineEffectRegBuffers[0], 120, 80, task->data[1]); + if (task->data[1] == 0) + { + DmaStop(0); + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_BigPokeball)); + } + if (task->data[3] == 0) + { + task->data[3]++; + SetVBlankCallback(VBlankCB1_Phase2_Transition_BigPokeball); + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static void Transition_BigPokeball_Vblank(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; + REG_BLDCNT = TRANSITION_STRUCT.BLDCNT; + REG_BLDALPHA = TRANSITION_STRUCT.BLDALPHA; +} + +static void VBlankCB0_Phase2_Transition_BigPokeball(void) +{ + Transition_BigPokeball_Vblank(); + DmaSet(0, gScanlineEffectRegBuffers[1], ®_BG0HOFS, 0xA2400001); +} + +static void VBlankCB1_Phase2_Transition_BigPokeball(void) +{ + Transition_BigPokeball_Vblank(); + DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, 0xA2400001); +} + +static void Phase2Task_Transition_PokeballsTrail(u8 taskID) +{ + while (sPhase2_Transition_PokeballsTrail_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_PokeballsTrail_Func1(struct Task* task) +{ + u16 *dst1, *dst2; + + sub_811D6A8(&dst1, &dst2); + CpuSet(sPokeballTrail_Tileset, dst2, 0x20); + CpuFill32(0, dst1, 0x800); + LoadPalette(gFieldEffectObjectPalette10, 0xF0, 0x20); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_PokeballsTrail_Func2(struct Task* task) +{ + s16 i; + s16 rand; + s16 arr0[2]; + s16 arr1[5]; + + memcpy(arr0, sUnknown_083FD7E4, sizeof(sUnknown_083FD7E4)); + memcpy(arr1, sUnknown_083FD7E8, sizeof(sUnknown_083FD7E8)); + rand = Random() & 1; + for (i = 0; i <= 4; i++, rand ^= 1) + { + gFieldEffectArguments[0] = arr0[rand]; // x + gFieldEffectArguments[1] = (i * 32) + 16; // y + gFieldEffectArguments[2] = rand; + gFieldEffectArguments[3] = arr1[i]; + FieldEffectStart(FLDEFF_POKEBALL); + } + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_PokeballsTrail_Func3(struct Task* task) +{ + if (!FieldEffectActiveListContains(FLDEFF_POKEBALL)) + { + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_PokeballsTrail)); + } + return FALSE; +} + +bool8 FldEff_Pokeball(void) +{ + u8 spriteID = CreateSpriteAtEnd(&sSpriteTemplate_83FD98C, gFieldEffectArguments[0], gFieldEffectArguments[1], 0); + gSprites[spriteID].oam.priority = 0; + gSprites[spriteID].oam.affineMode = 1; + gSprites[spriteID].data[0] = gFieldEffectArguments[2]; + gSprites[spriteID].data[1] = gFieldEffectArguments[3]; + gSprites[spriteID].data[2] = -1; + InitSpriteAffineAnim(&gSprites[spriteID]); + StartSpriteAffineAnim(&gSprites[spriteID], gFieldEffectArguments[2]); + return FALSE; +} + +#define SOME_VRAM_STORE(ptr, posY, posX, toStore) \ +{ \ + u32 index = (posY) * 32 + posX; \ + ptr[index] = toStore; \ +} + +static void sub_811B720(struct Sprite* sprite) +{ + s16 arr0[2]; + + memcpy(arr0, sUnknown_083FD7F2, sizeof(sUnknown_083FD7F2)); + if (sprite->data[1] != 0) + sprite->data[1]--; + else + { + if (sprite->pos1.x >= 0 && sprite->pos1.x <= 240) + { + s16 posX = sprite->pos1.x >> 3; + s16 posY = sprite->pos1.y >> 3; + + if (posX != sprite->data[2]) + { + u32 var; + u16 *ptr; + + sprite->data[2] = posX; + var = (((REG_BG0CNT >> 8) & 0x1F) << 11); // r2 + ptr = (u16 *)(VRAM + var); + + SOME_VRAM_STORE(ptr, posY - 2, posX, 0xF001); + SOME_VRAM_STORE(ptr, posY - 1, posX, 0xF001); + SOME_VRAM_STORE(ptr, posY - 0, posX, 0xF001); + SOME_VRAM_STORE(ptr, posY + 1, posX, 0xF001); + } + } + sprite->pos1.x += arr0[sprite->data[0]]; + if (sprite->pos1.x < -15 || sprite->pos1.x > 255) + FieldEffectStop(sprite, FLDEFF_POKEBALL); + } +} + +static void Phase2Task_Transition_Clockwise_BlackFade(u8 taskID) +{ + while (sPhase2_Transition_Clockwise_BlackFade_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func1(struct Task* task) +{ + u16 i; + + sub_811D658(); + ScanlineEffect_Clear(); + + TRANSITION_STRUCT.WININ = 0; + TRANSITION_STRUCT.WINOUT = 63; + TRANSITION_STRUCT.field_6 = -3855; + TRANSITION_STRUCT.WIN0V = 160; + + for (i = 0; i < 160; i++) + { + gScanlineEffectRegBuffers[1][i] = 0xF3F4; + } + + SetVBlankCallback(VBlankCB_Phase2_Transition_Clockwise_BlackFade); + TRANSITION_STRUCT.data[4] = 120; + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func2(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + + sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, TRANSITION_STRUCT.data[4], -1, 1, 1); + do + { + gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (TRANSITION_STRUCT.data[2] + 1) | 0x7800; + } while (!sub_811D978(TRANSITION_STRUCT.data, 1, 1)); + + TRANSITION_STRUCT.data[4] += 16; + if (TRANSITION_STRUCT.data[4] >= 240) + { + TRANSITION_STRUCT.data[5] = 0; + task->tState++; + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func3(struct Task* task) +{ + s16 r1, r3; + vu8 var = 0; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, 240, TRANSITION_STRUCT.data[5], 1, 1); + + while (1) + { + r1 = 120, r3 = TRANSITION_STRUCT.data[2] + 1; + if (TRANSITION_STRUCT.data[5] >= 80) + r1 = TRANSITION_STRUCT.data[2], r3 = 240; + gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (r3) | (r1 << 8); + if (var != 0) + break; + var = sub_811D978(TRANSITION_STRUCT.data, 1, 1); + } + + TRANSITION_STRUCT.data[5] += 8; + if (TRANSITION_STRUCT.data[5] >= 160) + { + TRANSITION_STRUCT.data[4] = 240; + task->tState++; + } + else + { + while (TRANSITION_STRUCT.data[3] < TRANSITION_STRUCT.data[5]) + { + gScanlineEffectRegBuffers[0][++TRANSITION_STRUCT.data[3]] = (r3) | (r1 << 8); + } + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func4(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + + sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, TRANSITION_STRUCT.data[4], 160, 1, 1); + do + { + gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (TRANSITION_STRUCT.data[2] << 8) | 0xF0; + } while (!sub_811D978(TRANSITION_STRUCT.data, 1, 1)); + + TRANSITION_STRUCT.data[4] -= 16; + if (TRANSITION_STRUCT.data[4] <= 0) + { + TRANSITION_STRUCT.data[5] = 160; + task->tState++; + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func5(struct Task* task) +{ + s16 r1, r2, r3; + vu8 var = 0; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, 0, TRANSITION_STRUCT.data[5], 1, 1); + + while (1) + { + r1 = gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] & 0xFF, r2 = TRANSITION_STRUCT.data[2]; + if (TRANSITION_STRUCT.data[5] <= 80) + r2 = 120, r1 = TRANSITION_STRUCT.data[2]; + gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (r1) | (r2 << 8); + r3 = 0; + if (var != 0) + break; + var = sub_811D978(TRANSITION_STRUCT.data, 1, 1); + } + + TRANSITION_STRUCT.data[5] -= 8; + if (TRANSITION_STRUCT.data[5] <= 0) + { + TRANSITION_STRUCT.data[4] = r3; + task->tState++; + } + else + { + while (TRANSITION_STRUCT.data[3] > TRANSITION_STRUCT.data[5]) + { + gScanlineEffectRegBuffers[0][--TRANSITION_STRUCT.data[3]] = (r1) | (r2 << 8); + } + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func6(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + + sub_811D8FC(TRANSITION_STRUCT.data, 120, 80, TRANSITION_STRUCT.data[4], 0, 1, 1); + do + { + s16 r2, r3; + + r2 = 120, r3 = TRANSITION_STRUCT.data[2]; + if (TRANSITION_STRUCT.data[2] >= 120) + r2 = 0, r3 = 240; + gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (r3) | (r2 << 8); + + } while (!sub_811D978(TRANSITION_STRUCT.data, 1, 1)); + + TRANSITION_STRUCT.data[4] += 16; + if (TRANSITION_STRUCT.data[2] > 120) + task->tState++; + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Clockwise_BlackFade_Func7(struct Task* task) +{ + DmaStop(0); + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Clockwise_BlackFade)); + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Clockwise_BlackFade(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA != 0) + DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; + REG_WIN0H = gScanlineEffectRegBuffers[1][0]; + DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, 0xA2400001); +} + +static void Phase2Task_Transition_Ripple(u8 taskID) +{ + while (sPhase2_Transition_Ripple_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Ripple_Func1(struct Task* task) +{ + u8 i; + + sub_811D658(); + ScanlineEffect_Clear(); + + for (i = 0; i < 160; i++) + { + gScanlineEffectRegBuffers[1][i] = TRANSITION_STRUCT.field_16; + } + + SetVBlankCallback(VBlankCB_Phase2_Transition_Ripple); + SetHBlankCallback(HBlankCB_Phase2_Transition_Ripple); + + REG_IE |= INTR_FLAG_HBLANK; + REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Ripple_Func2(struct Task* task) +{ + u8 i; + s16 r3; + u16 r4, r8; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + r3 = task->data[2] >> 8; + r4 = task->data[1]; + r8 = 384; + task->data[1] += 0x400; + if (task->data[2] <= 0x1FFF) + task->data[2] += 0x180; + + for (i = 0; i < 160; i++, r4 += r8) + { + // todo: fix the asm + s16 var = r4 >> 8; + asm(""); + gScanlineEffectRegBuffers[0][i] = TRANSITION_STRUCT.field_16 + Sin(var, r3); + asm(""); + } + + if (++task->data[3] == 81) + { + task->data[4]++; + BeginNormalPaletteFade(0xFFFFFFFF, -2, 0, 16, RGB(0, 0, 0)); + } + + if (task->data[4] != 0 && !gPaletteFade.active) + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Ripple)); + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Ripple(void) +{ + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); +} + +static void HBlankCB_Phase2_Transition_Ripple(void) +{ + u16 var = gScanlineEffectRegBuffers[1][REG_VCOUNT]; + REG_BG1VOFS = var; + REG_BG2VOFS = var; + REG_BG3VOFS = var; +} + +static void Phase2Task_Transition_Wave(u8 taskID) +{ + while (sPhase2_Transition_Wave_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Wave_Func1(struct Task* task) +{ + u8 i; + + sub_811D658(); + ScanlineEffect_Clear(); + + TRANSITION_STRUCT.WININ = 63; + TRANSITION_STRUCT.WINOUT = 0; + TRANSITION_STRUCT.field_6 = 240; + TRANSITION_STRUCT.WIN0V = 160; + + for (i = 0; i < 160; i++) + { + gScanlineEffectRegBuffers[1][i] = 242; + } + + SetVBlankCallback(VBlankCB_Phase2_Transition_Wave); + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Wave_Func2(struct Task* task) +{ + u8 i, r5; + u16* toStore; + bool8 nextFunc; + + TRANSITION_STRUCT.VBlank_DMA = 0; + toStore = gScanlineEffectRegBuffers[0]; + r5 = task->data[2]; + task->data[2] += 16; + task->data[1] += 8; + + for (i = 0, nextFunc = TRUE; i < 160; i++, r5 += 4, toStore++) + { + s16 value = task->data[1] + Sin(r5, 40); + if (value < 0) + value = 0; + if (value > 240) + value = 240; + *toStore = (value << 8) | (0xF1); + if (value < 240) + nextFunc = FALSE; + } + if (nextFunc) + task->tState++; + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Wave_Func3(struct Task* task) +{ + DmaStop(0); + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Wave)); + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Wave(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA != 0) + DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; + DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, 0xA2400001); +} + +#define tMugshotOpponentID data[13] +#define tMugshotPlayerID data[14] +#define tMugshotID data[15] + +static void Phase2Task_Transition_Sydney(u8 taskID) +{ + gTasks[taskID].tMugshotID = MUGSHOT_SYDNEY; + Phase2Task_MugShotTransition(taskID); +} + +static void Phase2Task_Transition_Phoebe(u8 taskID) +{ + gTasks[taskID].tMugshotID = MUGSHOT_PHOEBE; + Phase2Task_MugShotTransition(taskID); +} + +static void Phase2Task_Transition_Glacia(u8 taskID) +{ + gTasks[taskID].tMugshotID = MUGSHOT_GLACIA; + Phase2Task_MugShotTransition(taskID); +} + +static void Phase2Task_Transition_Drake(u8 taskID) +{ + gTasks[taskID].tMugshotID = MUGSHOT_DRAKE; + Phase2Task_MugShotTransition(taskID); +} + +static void Phase2Task_Transition_Steven(u8 taskID) +{ + gTasks[taskID].tMugshotID = MUGSHOT_STEVEN; + Phase2Task_MugShotTransition(taskID); +} + +static void Phase2Task_MugShotTransition(u8 taskID) +{ + while (sPhase2_Mugshot_Transition_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Mugshot_Func1(struct Task* task) +{ + u8 i; + + sub_811D658(); + ScanlineEffect_Clear(); + Mugshots_CreateOpponentPlayerSprites(task); + + task->data[1] = 0; + task->data[2] = 1; + task->data[3] = 239; + TRANSITION_STRUCT.WININ = 63; + TRANSITION_STRUCT.WINOUT = 62; + TRANSITION_STRUCT.WIN0V = 160; + + for (i = 0; i < 160; i++) + { + gScanlineEffectRegBuffers[1][i] = 0xF0F1; + } + + SetVBlankCallback(VBlankCB0_Phase2_Mugshots); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Mugshot_Func2(struct Task* task) +{ + s16 i, j; + u16 *dst1, *dst2; + const u16* MugshotsMap; + + MugshotsMap = sMugshotsTilemap; + sub_811D6A8(&dst1, &dst2); + CpuSet(sUnknown_083FC348, dst2, 0xF0); + LoadPalette(sOpponentMugshotsPals[task->tMugshotID], 0xF0, 0x20); + LoadPalette(sPlayerMugshotsPals[gSaveBlock2.playerGender], 0xFA, 0xC); + + for (i = 0; i < 20; i++) + { + for (j = 0; j < 32; j++, MugshotsMap++) + { + dst1[i * 32 + j] = *MugshotsMap | 0xF000; + } + } + + REG_IE |= INTR_FLAG_HBLANK; + REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; + SetHBlankCallback(HBlankCB_Phase2_Mugshots); + task->tState++; + return FALSE; +} + +static bool8 Phase2_Mugshot_Func3(struct Task* task) +{ + u8 i, r5; + u16* toStore; + s16 value; + s32 mergedValue; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + toStore = gScanlineEffectRegBuffers[0]; + r5 = task->data[1]; + task->data[1] += 0x10; + + for (i = 0; i < 80; i++, toStore++, r5 += 0x10) + { + value = task->data[2] + Sin(r5, 0x10); + if (value < 0) + value = 1; + if (value > 0xF0) + value = 0xF0; + *toStore = value; + } + for (; i < 160; i++, toStore++, r5 += 0x10) + { + value = task->data[3] - Sin(r5, 0x10); + if (value < 0) + value = 0; + if (value > 0xEF) + value = 0xEF; + *toStore = (value << 8) | (0xF0); + } + + task->data[2] += 8; + task->data[3] -= 8; + if (task->data[2] > 0xF0) + task->data[2] = 0xF0; + if (task->data[3] < 0) + task->data[3] = 0; + mergedValue = *(s32*)(&task->data[2]); + if (mergedValue == 0xF0) + task->tState++; + + TRANSITION_STRUCT.field_18 -= 8; + TRANSITION_STRUCT.field_1A += 8; + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Mugshot_Func4(struct Task* task) +{ + u8 i; + u16* toStore; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + for (i = 0, toStore = gScanlineEffectRegBuffers[0]; i < 160; i++, toStore++) + { + *toStore = 0xF0; + } + + task->tState++; + task->data[1] = 0; + task->data[2] = 0; + task->data[3] = 0; + TRANSITION_STRUCT.field_18 -= 8; + TRANSITION_STRUCT.field_1A += 8; + + sub_811CA10(task->tMugshotOpponentID, 0); + sub_811CA10(task->tMugshotPlayerID, 1); + sub_811CA28(task->tMugshotOpponentID); + + PlaySE(SE_BT_START); + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Mugshot_Func5(struct Task* task) +{ + TRANSITION_STRUCT.field_18 -= 8; + TRANSITION_STRUCT.field_1A += 8; + if (sub_811CA44(task->tMugshotOpponentID)) + { + task->tState++; + sub_811CA28(task->tMugshotPlayerID); + } + return FALSE; +} + +static bool8 Phase2_Mugshot_Func6(struct Task* task) +{ + TRANSITION_STRUCT.field_18 -= 8; + TRANSITION_STRUCT.field_1A += 8; + if (sub_811CA44(task->tMugshotPlayerID)) + { + TRANSITION_STRUCT.VBlank_DMA = 0; + SetVBlankCallback(NULL); + DmaStop(0); + memset(gScanlineEffectRegBuffers[0], 0, 0x140); + memset(gScanlineEffectRegBuffers[1], 0, 0x140); + REG_WIN0H = 0xF0; + REG_BLDY = 0; + task->tState++; + task->data[3] = 0; + task->data[4] = 0; + TRANSITION_STRUCT.BLDCNT = 0xBF; + SetVBlankCallback(VBlankCB1_Phase2_Mugshots); + } + return FALSE; +} + +static bool8 Phase2_Mugshot_Func7(struct Task* task) +{ + bool32 r6; + + TRANSITION_STRUCT.VBlank_DMA = 0; + r6 = TRUE; + TRANSITION_STRUCT.field_18 -= 8; + TRANSITION_STRUCT.field_1A += 8; + + if (task->data[4] < 0x50) + task->data[4] += 2; + if (task->data[4] > 0x50) + task->data[4] = 0x50; + + if (++task->data[3] & 1) + { + s16 i; + for (i = 0, r6 = FALSE; i <= task->data[4]; i++) + { + s16 index1 = 0x50 - i; + s16 index2 = 0x50 + i; + if (gScanlineEffectRegBuffers[0][index1] <= 15) + { + r6 = TRUE; + gScanlineEffectRegBuffers[0][index1]++; + } + if (gScanlineEffectRegBuffers[0][index2] <= 15) + { + r6 = TRUE; + gScanlineEffectRegBuffers[0][index2]++; + } + } + } + + if (task->data[4] == 0x50 && !r6) + task->tState++; + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Mugshot_Func8(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + BlendPalettes(0xFFFFFFFF, 16, RGB(31, 31, 31)); + TRANSITION_STRUCT.BLDCNT = 0xFF; + task->data[3] = 0; + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Mugshot_Func9(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + + task->data[3]++; + memset(gScanlineEffectRegBuffers[0], task->data[3], 0x140); + if (task->data[3] > 15) + task->tState++; + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Mugshot_Func10(struct Task* task) +{ + DmaStop(0); + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(task->func)); + return FALSE; +} + +static void VBlankCB0_Phase2_Mugshots(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA != 0) + DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); + REG_BG0VOFS = TRANSITION_STRUCT.field_1C; + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; + DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, 0xA2400001); +} + +static void VBlankCB1_Phase2_Mugshots(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA != 0) + DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); + REG_BLDCNT = TRANSITION_STRUCT.BLDCNT; + DmaSet(0, gScanlineEffectRegBuffers[1], ®_BLDY, 0xA2400001); +} + +static void HBlankCB_Phase2_Mugshots(void) +{ + if (REG_VCOUNT < 80) + REG_BG0HOFS = TRANSITION_STRUCT.field_18; + else + REG_BG0HOFS = TRANSITION_STRUCT.field_1A; +} + +static void Mugshots_CreateOpponentPlayerSprites(struct Task* task) +{ + struct Sprite *opponentSprite, *playerSprite; + + s16 mugshotID = task->tMugshotID; + task->tMugshotOpponentID = CreateTrainerSprite(sMugshotsTrainerPicIDsTable[mugshotID], + sMugshotsOpponentCoords[mugshotID][0] - 32, + sMugshotsOpponentCoords[mugshotID][1] + 42, + 0, ewramC03C); + task->tMugshotPlayerID = CreateTrainerSprite(gSaveBlock2.playerGender, 272, 106, 0, ewramC03C); + + opponentSprite = &gSprites[task->tMugshotOpponentID]; + playerSprite = &gSprites[task->tMugshotPlayerID]; + + opponentSprite->callback = sub_811C90C; + playerSprite->callback = sub_811C90C; + + opponentSprite->oam.affineMode = 3; + playerSprite->oam.affineMode = 3; + + opponentSprite->oam.matrixNum = AllocOamMatrix(); + playerSprite->oam.matrixNum = AllocOamMatrix(); + + opponentSprite->oam.shape = 1; + playerSprite->oam.shape = 1; + + opponentSprite->oam.size = 3; + playerSprite->oam.size = 3; + + CalcCenterToCornerVec(opponentSprite, 1, 3, 3); + CalcCenterToCornerVec(playerSprite, 1, 3, 3); + + SetOamMatrixRotationScaling(opponentSprite->oam.matrixNum, sMugshotsOpponentRotationScales[mugshotID][0], sMugshotsOpponentRotationScales[mugshotID][1], 0); + SetOamMatrixRotationScaling(playerSprite->oam.matrixNum, -512, 0x200, 0); +} + +static void sub_811C90C(struct Sprite* sprite) +{ + while (sUnknown_083FD880[sprite->data[0]](sprite)); +} + +static bool8 sub_811C934(struct Sprite* sprite) +{ + return FALSE; +} + +static bool8 sub_811C938(struct Sprite* sprite) +{ + s16 arr0[2]; + s16 arr1[2]; + + memcpy(arr0, sUnknown_083FD89C, sizeof(sUnknown_083FD89C)); + memcpy(arr1, sUnknown_083FD8A0, sizeof(sUnknown_083FD8A0)); + + sprite->data[0]++; + sprite->data[1] = arr0[sprite->data[7]]; + sprite->data[2] = arr1[sprite->data[7]]; + return TRUE; +} + +static bool8 sub_811C984(struct Sprite* sprite) +{ + sprite->pos1.x += sprite->data[1]; + if (sprite->data[7] && sprite->pos1.x < 133) + sprite->data[0]++; + else if (!sprite->data[7] && sprite->pos1.x > 103) + sprite->data[0]++; + return FALSE; +} + +static bool8 sub_811C9B8(struct Sprite* sprite) +{ + sprite->data[1] += sprite->data[2]; + sprite->pos1.x += sprite->data[1]; + if (sprite->data[1] == 0) + { + sprite->data[0]++; + sprite->data[2] = -sprite->data[2]; + sprite->data[6] = 1; + } + return FALSE; +} + +static bool8 sub_811C9E4(struct Sprite* sprite) +{ + sprite->data[1] += sprite->data[2]; + sprite->pos1.x += sprite->data[1]; + if (sprite->pos1.x < -31 || sprite->pos1.x > 271) + sprite->data[0]++; + return FALSE; +} + +static void sub_811CA10(s16 spriteID, s16 value) +{ + gSprites[spriteID].data[7] = value; +} + +static void sub_811CA28(s16 spriteID) +{ + gSprites[spriteID].data[0]++; +} + +static s16 sub_811CA44(s16 spriteID) +{ + return gSprites[spriteID].data[6]; +} + +#undef tMugshotOpponentID +#undef tMugshotPlayerID +#undef tMugshotID + +static void Phase2Task_Transition_Slice(u8 taskID) +{ + while (sPhase2_Transition_Slice_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Slice_Func1(struct Task* task) +{ + u16 i; + + sub_811D658(); + ScanlineEffect_Clear(); + + task->data[2] = 256; + task->data[3] = 1; + TRANSITION_STRUCT.WININ = 63; + TRANSITION_STRUCT.WINOUT = 0; + TRANSITION_STRUCT.WIN0V = 160; + + for (i = 0; i < 160; i++) + { + gScanlineEffectRegBuffers[1][i] = TRANSITION_STRUCT.field_14; + gScanlineEffectRegBuffers[1][160 + i] = 0xF0; + } + + REG_IE |= INTR_FLAG_HBLANK; + REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; + + SetVBlankCallback(VBlankCB_Phase2_Transition_Slice); + SetHBlankCallback(HBlankCB_Phase2_Transition_Slice); + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Slice_Func2(struct Task* task) +{ + u16 i; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + task->data[1] += (task->data[2] >> 8); + if (task->data[1] > 0xF0) + task->data[1] = 0xF0; + if (task->data[2] <= 0xFFF) + task->data[2] += task->data[3]; + if (task->data[3] < 128) + task->data[3] <<= 1; // multiplying by two + + for (i = 0; i < 160; i++) + { + u16* storeLoc1 = &gScanlineEffectRegBuffers[0][i]; + u16* storeLoc2 = &gScanlineEffectRegBuffers[0][i + 160]; + if (1 & i) + { + *storeLoc1 = TRANSITION_STRUCT.field_14 + task->data[1]; + *storeLoc2 = 0xF0 - task->data[1]; + } + else + { + *storeLoc1 = TRANSITION_STRUCT.field_14 - task->data[1]; + *storeLoc2 = (task->data[1] << 8) | (0xF1); + } + } + + if (task->data[1] > 0xEF) + task->tState++; + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Slice_Func3(struct Task* task) +{ + DmaStop(0); + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Slice)); + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Slice(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 640); + DmaSet(0, &gScanlineEffectRegBuffers[1][160], ®_WIN0H, 0xA2400001); +} + +static void HBlankCB_Phase2_Transition_Slice(void) +{ + u16 var = gScanlineEffectRegBuffers[1][REG_VCOUNT]; + REG_BG1HOFS = var; + REG_BG2HOFS = var; + REG_BG3HOFS = var; +} + +static void Phase2Task_Transition_WhiteFade(u8 taskID) +{ + while (sPhase2_Transition_WhiteFade_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_WhiteFade_Func1(struct Task* task) +{ + u16 i; + + sub_811D658(); + ScanlineEffect_Clear(); + + TRANSITION_STRUCT.BLDCNT = 0xBF; + TRANSITION_STRUCT.BLDY = 0; + TRANSITION_STRUCT.WININ = 0x1E; + TRANSITION_STRUCT.WINOUT = 0x3F; + TRANSITION_STRUCT.WIN0V = 0xA0; + + for (i = 0; i < 160; i++) + { + gScanlineEffectRegBuffers[1][i] = 0; + gScanlineEffectRegBuffers[1][i + 160] = 0xF0; + } + + REG_IE |= INTR_FLAG_HBLANK; + REG_DISPSTAT |= DISPSTAT_HBLANK_INTR; + + SetHBlankCallback(HBlankCB_Phase2_Transition_WhiteFade); + SetVBlankCallback(VBlankCB0_Phase2_Transition_WhiteFade); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_WhiteFade_Func2(struct Task* task) +{ + s16 i, posY; + s16 arr1[8]; + struct Sprite* sprite; + + memcpy(arr1, sUnknown_083FD8C4, sizeof(sUnknown_083FD8C4)); + for (i = 0, posY = 0; i < 8; i++, posY += 0x14) + { + sprite = &gSprites[CreateInvisibleSprite(sub_811CFD0)]; + sprite->pos1.x = 0xF0; + sprite->pos1.y = posY; + sprite->data[5] = arr1[i]; + } + sprite->data[6]++; + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_WhiteFade_Func3(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + if (TRANSITION_STRUCT.field_20 > 7) + { + BlendPalettes(0xFFFFFFFF, 16, RGB(31, 31, 31)); + task->tState++; + } + return FALSE; +} + +static bool8 Phase2_Transition_WhiteFade_Func4(struct Task* task) +{ + TRANSITION_STRUCT.VBlank_DMA = 0; + + DmaStop(0); + SetVBlankCallback(0); + SetHBlankCallback(0); + + TRANSITION_STRUCT.field_6 = 0xF0; + TRANSITION_STRUCT.BLDY = 0; + TRANSITION_STRUCT.BLDCNT = 0xFF; + TRANSITION_STRUCT.WININ = 0x3F; + + SetVBlankCallback(VBlankCB1_Phase2_Transition_WhiteFade); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_WhiteFade_Func5(struct Task* task) +{ + if (++TRANSITION_STRUCT.BLDY > 16) + { + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_WhiteFade)); + } + return FALSE; +} + +static void VBlankCB0_Phase2_Transition_WhiteFade(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + REG_BLDCNT = TRANSITION_STRUCT.BLDCNT; + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.field_6; + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 640); + DmaSet(0, &gScanlineEffectRegBuffers[1][160], ®_WIN0H, 0xA2400001); +} + +static void VBlankCB1_Phase2_Transition_WhiteFade(void) +{ + VBlankCB_BattleTransition(); + REG_BLDY = TRANSITION_STRUCT.BLDY; + REG_BLDCNT = TRANSITION_STRUCT.BLDCNT; + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0H = TRANSITION_STRUCT.field_6; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; +} + +static void HBlankCB_Phase2_Transition_WhiteFade(void) +{ + REG_BLDY = gScanlineEffectRegBuffers[1][REG_VCOUNT]; +} + +static void sub_811CFD0(struct Sprite* sprite) +{ + if (sprite->data[5]) + { + sprite->data[5]--; + if (sprite->data[6]) + TRANSITION_STRUCT.VBlank_DMA = 1; + } + else + { + u16 i; + u16* ptr1 = &gScanlineEffectRegBuffers[0][sprite->pos1.y]; + u16* ptr2 = &gScanlineEffectRegBuffers[0][sprite->pos1.y + 160]; + for (i = 0; i < 20; i++) + { + ptr1[i] = sprite->data[0] >> 8; + ptr2[i] = (u8)(sprite->pos1.x); + } + if (sprite->pos1.x == 0 && sprite->data[0] == 0x1000) + sprite->data[1] = 1; + + sprite->pos1.x -= 16; + sprite->data[0] += 0x80; + + if (sprite->pos1.x < 0) + sprite->pos1.x = 0; + if (sprite->data[0] > 0x1000) + sprite->data[0] = 0x1000; + + if (sprite->data[6]) + TRANSITION_STRUCT.VBlank_DMA = 1; + + if (sprite->data[1]) + { + if (sprite->data[6] == 0 || (TRANSITION_STRUCT.field_20 > 6 && sprite->data[2]++ > 7)) + { + TRANSITION_STRUCT.field_20++; + DestroySprite(sprite); + } + } + } +} + +static void Phase2Task_Transition_GridSquares(u8 taskID) +{ + while (sPhase2_Transition_GridSquares_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_GridSquares_Func1(struct Task* task) +{ + u16 *dst1, *dst2; + + sub_811D6A8(&dst1, &dst2); + CpuSet(sShrinkingBoxTileset, dst2, 0x10); + CpuFill16(0xF000, dst1, 0x800); + LoadPalette(gFieldEffectObjectPalette10, 0xF0, 0x20); + + task->tState++; + return FALSE; +} + +static bool8 Phase2_Transition_GridSquares_Func2(struct Task* task) +{ + u16* dst1; + + if (task->data[1] == 0) + { + sub_811D690(&dst1); + task->data[1] = 3; + task->data[2]++; + CpuSet(sShrinkingBoxTileset + (task->data[2] * 8), dst1, 0x10); + if (task->data[2] > 0xD) + { + task->tState++; + task->data[1] = 16; + } + } + + task->data[1]--; + return FALSE; +} + +static bool8 Phase2_Transition_GridSquares_Func3(struct Task* task) +{ + if (--task->data[1] == 0) + { + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_GridSquares)); + } + return FALSE; +} + +static void Phase2Task_Transition_Shards(u8 taskID) +{ + while (sPhase2_Transition_Shards_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase2_Transition_Shards_Func1(struct Task* task) +{ + u16 i; + + sub_811D658(); + ScanlineEffect_Clear(); + + TRANSITION_STRUCT.WININ = 0x3F; + TRANSITION_STRUCT.WINOUT = 0; + TRANSITION_STRUCT.WIN0V = 0xA0; + + for (i = 0; i < 160; i++) + { + gScanlineEffectRegBuffers[0][i] = 0xF0; + } + + CpuSet(gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 0xA0); + SetVBlankCallback(VBlankCB_Phase2_Transition_Shards); + + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Shards_Func2(struct Task* task) +{ + sub_811D8FC(TRANSITION_STRUCT.data, + sUnknown_083FD8F4[task->data[1]][0], + sUnknown_083FD8F4[task->data[1]][1], + sUnknown_083FD8F4[task->data[1]][2], + sUnknown_083FD8F4[task->data[1]][3], + 1, 1); + task->data[2] = sUnknown_083FD8F4[task->data[1]][4]; + task->tState++; + return TRUE; +} + +static bool8 Phase2_Transition_Shards_Func3(struct Task* task) +{ + s16 i; + bool8 nextFunc; + + TRANSITION_STRUCT.VBlank_DMA = 0; + + for (i = 0, nextFunc = FALSE; i < 16; i++) + { + s16 r3 = gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] >> 8; + s16 r4 = gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] & 0xFF; + if (task->data[2] == 0) + { + if (r3 < TRANSITION_STRUCT.data[2]) + r3 = TRANSITION_STRUCT.data[2]; + if (r3 > r4) + r3 = r4; + } + else + { + if (r4 > TRANSITION_STRUCT.data[2]) + r4 = TRANSITION_STRUCT.data[2]; + if (r4 <= r3) + r4 = r3; + } + gScanlineEffectRegBuffers[0][TRANSITION_STRUCT.data[3]] = (r4) | (r3 << 8); + if (nextFunc) + { + task->tState++; + break; + } + else + nextFunc = sub_811D978(TRANSITION_STRUCT.data, 1, 1); + } + + TRANSITION_STRUCT.VBlank_DMA++; + return FALSE; +} + +static bool8 Phase2_Transition_Shards_Func4(struct Task* task) +{ + if (++task->data[1] < 7) + { + task->tState++; + task->data[3] = sUnknown_083FD93A[task->data[1] - 1]; + return TRUE; + } + else + { + DmaStop(0); + sub_811D6D4(); + DestroyTask(FindTaskIdByFunc(Phase2Task_Transition_Shards)); + return FALSE; + } +} + +static bool8 Phase2_Transition_Shards_Func5(struct Task* task) +{ + if (--task->data[3] == 0) + { + task->tState = 1; + return TRUE; + } + else + return FALSE; +} + +static void VBlankCB_Phase2_Transition_Shards(void) +{ + DmaStop(0); + VBlankCB_BattleTransition(); + if (TRANSITION_STRUCT.VBlank_DMA) + DmaCopy16(3, gScanlineEffectRegBuffers[0], gScanlineEffectRegBuffers[1], 320); + REG_WININ = TRANSITION_STRUCT.WININ; + REG_WINOUT = TRANSITION_STRUCT.WINOUT; + REG_WIN0V = TRANSITION_STRUCT.WIN0V; + REG_WIN0H = gScanlineEffectRegBuffers[1][0]; + DmaSet(0, gScanlineEffectRegBuffers[1], ®_WIN0H, 0xA2400001); +} + +static void CreatePhase1Task(s16 a0, s16 a1, s16 a2, s16 a3, s16 a4) +{ + u8 taskID = CreateTask(Phase1_Task_RunFuncs, 3); + gTasks[taskID].data[1] = a0; + gTasks[taskID].data[2] = a1; + gTasks[taskID].data[3] = a2; + gTasks[taskID].data[4] = a3; + gTasks[taskID].data[5] = a4; + gTasks[taskID].data[6] = a0; +} + +static bool8 sub_811D52C(void) +{ + if (FindTaskIdByFunc(Phase1_Task_RunFuncs) == 0xFF) + return TRUE; + else + return FALSE; +} + +static void Phase1_Task_RunFuncs(u8 taskID) +{ + while (sPhase1_TransitionAll_Funcs[gTasks[taskID].tState](&gTasks[taskID])); +} + +static bool8 Phase1_TransitionAll_Func1(struct Task* task) +{ + if (task->data[6] == 0 || --task->data[6] == 0) + { + task->data[6] = task->data[1]; + task->data[7] += task->data[4]; + if (task->data[7] > 16) + task->data[7] = 16; + BlendPalettes(0xFFFFFFFF, task->data[7], RGB(11, 11, 11)); + } + if (task->data[7] > 15) + { + task->tState++; + task->data[6] = task->data[2]; + } + return FALSE; +} + +static bool8 Phase1_TransitionAll_Func2(struct Task* task) +{ + if (task->data[6] == 0 || --task->data[6] == 0) + { + task->data[6] = task->data[2]; + task->data[7] -= task->data[5]; + if (task->data[7] < 0) + task->data[7] = 0; + BlendPalettes(0xFFFFFFFF, task->data[7], RGB(11, 11, 11)); + } + if (task->data[7] == 0) + { + if (--task->data[3] == 0) + DestroyTask(FindTaskIdByFunc(Phase1_Task_RunFuncs)); + else + { + task->data[6] = task->data[1]; + task->tState = 0; + } + } + return FALSE; +} + +static void sub_811D658(void) +{ + struct TransitionData* const* dummy = &sTransitionStructPtr; + memset(*dummy, 0, sizeof(struct TransitionData)); + sub_8057B14(&TRANSITION_STRUCT.field_14, &TRANSITION_STRUCT.field_16); +} + +static void VBlankCB_BattleTransition(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void sub_811D690(u16** a0) +{ + u16 reg, *vram; + + reg = REG_BG0CNT >> 2; + reg <<= 0xE; + vram = (u16*)(VRAM + reg); + + *a0 = vram; +} + +static void sub_811D6A8(u16** a0, u16** a1) +{ + u16 reg0, reg1, *vram0, *vram1; + + reg0 = REG_BG0CNT >> 8; + reg1 = REG_BG0CNT >> 2; + + reg0 <<= 0xB; + reg1 <<= 0xE; + + vram0 = (u16*)(VRAM + reg0); + *a0 = vram0; + + vram1 = (u16*)(VRAM + reg1); + *a1 = vram1; +} + +static void sub_811D6D4(void) +{ + BlendPalettes(0xFFFFFFFF, 16, RGB(0, 0, 0)); +} + +static void sub_811D6E8(s16* array, s16 sinAdd, s16 index, s16 indexIncrementer, s16 amplitude, s16 arrSize) +{ + u8 i; + for (i = 0; arrSize > 0; arrSize--, i++, index += indexIncrementer) + { + array[i] = sinAdd + Sin(0xFF & index, amplitude); + } +} + +static void sub_811D764(u16* array, s16 a1, s16 a2, s16 a3) +{ + s16 i; + + memset(array, 0xA, 160 * sizeof(s16)); + for (i = 0; i < 64; i++) + { + s16 sinResult, cosResult; + s16 toStoreOrr, r2, r3, toStore, r7, r8; + + sinResult = Sin(i, a3); + cosResult = Cos(i, a3); + + toStoreOrr = a1 - sinResult; + toStore = a1 + sinResult; + r7 = a2 - cosResult; + r8 = a2 + cosResult; + + if (toStoreOrr < 0) + toStoreOrr = 0; + if (toStore > 0xF0) + toStore = 0xF0; + if (r7 < 0) + r7 = 0; + if (r8 > 0x9F) + r8 = 0x9F; + + toStore |= (toStoreOrr << 8); + array[r7] = toStore; + array[r8] = toStore; + + cosResult = Cos(i + 1, a3); + r3 = a2 - cosResult; + r2 = a2 + cosResult; + + if (r3 < 0) + r3 = 0; + if (r2 > 0x9F) + r2 = 0x9F; + + while (r7 > r3) + array[--r7] = toStore; + while (r7 < r3) + array[++r7] = toStore; + + while (r8 > r2) + array[--r8] = toStore; + while (r8 < r2) + array[++r8] = toStore; + } +} + +static void sub_811D8FC(s16* data, s16 a1, s16 a2, s16 a3, s16 a4, s16 a5, s16 a6) +{ + data[0] = a1; + data[1] = a2; + data[2] = a1; + data[3] = a2; + data[4] = a3; + data[5] = a4; + data[6] = a5; + data[7] = a6; + data[8] = a3 - a1; + if (data[8] < 0) + { + data[8] = -data[8]; + data[6] = -a5; + } + data[9] = a4 - a2; + if (data[9] < 0) + { + data[9] = -data[9]; + data[7] = -a6; + } + data[10] = 0; +} + +static bool8 sub_811D978(s16* data, bool8 a1, bool8 a2) +{ + u8 var; + if (data[8] > data[9]) + { + data[2] += data[6]; + data[10] += data[9]; + if (data[10] > data[8]) + { + data[3] += data[7]; + data[10] -= data[8]; + } + } + else + { + data[3] += data[7]; + data[10] += data[8]; + if (data[10] > data[9]) + { + data[2] += data[6]; + data[10] -= data[9]; + } + } + var = 0; + if ((data[6] > 0 && data[2] >= data[4]) || (data[6] < 0 && data[2] <= data[4])) + { + var++; + if (a1) + data[2] = data[4]; + } + if ((data[7] > 0 && data[3] >= data[5]) || (data[7] < 0 && data[3] <= data[5])) + { + var++; + if (a2) + data[3] = data[5]; + } + if (var == 2) + return TRUE; + else + return FALSE; +} diff --git a/src/battle_util.c b/src/battle_util.c new file mode 100644 index 000000000..3d1770239 --- /dev/null +++ b/src/battle_util.c @@ -0,0 +1,3549 @@ +#include "global.h" +#include "battle.h" +#include "battle_util.h" +#include "data2.h" +#include "event_data.h" +#include "ewram.h" +#include "field_weather.h" +#include "item.h" +#include "link.h" +#include "pokemon.h" +#include "random.h" +#include "rom_8077ABC.h" +#include "string_util.h" +#include "text.h" +#include "util.h" +#include "constants/abilities.h" +#include "constants/battle_move_effects.h" +#include "constants/flags.h" +#include "constants/hold_effects.h" +#include "constants/items.h" +#include "constants/moves.h" +#include "constants/species.h" +#include "constants/weather.h" + +extern u8 gUnknown_02023A14_50; + +extern const u8* gBattlescriptCurrInstr; +extern u8 gActiveBattler; +extern u8 gBattleBufferB[4][0x200]; +extern u8* gSelectionBattleScripts[4]; //battlescript location when you try to choose a move you're not allowed to +extern u16 gLastUsedMove[4]; +extern struct BattlePokemon gBattleMons[4]; +extern struct BattleEnigmaBerry gEnigmaBerries[4]; +extern u8 gStringBank; +extern u16 gLastUsedItem; +extern u16 gCurrentMove; +extern const u32 gBitTable[]; +extern u16 gBattleTypeFlags; +extern u8 gBattlersCount; +extern u32 gStatuses3[4]; +extern u8 gBankAttacker; +extern u8 gBankTarget; +extern u8 gBanksByTurnOrder[4]; +extern u16 gSideAffecting[2]; +extern u16 gBattleWeather; +extern void (*gBattleMainFunc)(void); +extern u8 gAbsentBattlerFlags; +extern u8 gBattleCommunication[]; +extern u32 gHitMarker; +extern u8 gEffectBank; +extern u8 gBank1; +extern s32 gBattleMoveDamage; +extern u16 gBattlerPartyIndexes[4]; +extern u16 gChosenMovesByBanks[4]; +extern s32 gTakenDmg[4]; +extern u8 gTakenDmgBanks[4]; +extern u8 gMoveResultFlags; +extern u8 gLastUsedAbility; +extern u8 gBattleTextBuff2[]; +extern u8 gCurrentActionFuncId; +extern struct BattleEnigmaBerry gEnigmaBerries[4]; +extern u8 gUnknown_02024BE5; +extern u8 gCurrMovePos; +extern u16 gRandomMove; +extern s32 gBattleMoveDamage; +extern u16 gDynamicBasePower; +extern u32 gBattleExecBuffer; +extern u8 gSentPokesToOpponent[2]; +extern const u16 gSoundMovesTable[]; +extern const u8 gStatusConditionString_PoisonJpn[]; +extern const u8 gStatusConditionString_SleepJpn[]; +extern const u8 gStatusConditionString_ParalysisJpn[]; +extern const u8 gStatusConditionString_BurnJpn[]; +extern const u8 gStatusConditionString_IceJpn[]; +extern const u8 gStatusConditionString_ConfusionJpn[]; +extern const u8 gStatusConditionString_LoveJpn[]; +extern const BattleCmdFunc gBattleScriptingCommandsTable[]; + +u8 IsImprisoned(u8 bank, u16 move); +u8 GetBattlerAtPosition(u8 ID); +u8 GetBattlerPosition(u8 bank); +u8 GetBattlerSide(u8 bank); +void SetMoveEffect(bool8 primary, u8 certainArg); +bool8 UproarWakeUpCheck(u8 bank); +bool8 sub_8018018(u8 bank, u8, u8); +s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 a4, u16 powerOverride, u8 typeOverride, u8 bank_atk, u8 bank_def); +u8 CountTrailingZeroBits(u32 a); +u8 GetMoveTarget(u16 move, u8 useMoveTarget); +u8 sub_803FC34(u8 bank); +u16 sub_803FBFC(u8 a); +void RecordAbilityBattle(u8 bank, u8 ability); +void RecordItemBattle(u8 bank, u8 holdEffect); +s8 GetPokeFlavourRelation(u32 pid, u8 flavor); + +extern u8 BattleScript_MoveSelectionDisabledMove[]; +extern u8 BattleScript_MoveSelectionTormented[]; +extern u8 BattleScript_MoveSelectionTaunted[]; +extern u8 BattleScript_MoveSelectionImprisoned[]; +extern u8 BattleScript_MoveSelectionChoiceBanded[]; +extern u8 BattleScript_MoveSelectionNoPP[]; +extern u8 BattleScript_NoMovesLeft[]; +extern u8 BattleScript_WishComesTrue[]; +extern u8 BattleScript_IngrainTurnHeal[]; +extern u8 BattleScript_LeechSeedTurnDrain[]; +extern u8 BattleScript_PoisonTurnDmg[]; +extern u8 BattleScript_BurnTurnDmg[]; +extern u8 BattleScript_NightmareTurnDmg[]; +extern u8 BattleScript_CurseTurnDmg[]; +extern u8 BattleScript_WrapTurnDmg[]; +extern u8 BattleScript_WrapEnds[]; +extern u8 BattleScript_DisabledNoMore[]; +extern u8 BattleScript_EncoredNoMore[]; + +extern u8 BattleScript_SideStatusWoreOff[]; +extern u8 BattleScript_RainContinuesOrEnds[]; +extern u8 BattleScript_SandStormHailEnds[]; +extern u8 BattleScript_DamagingWeatherContinues[]; +extern u8 BattleScript_SunlightFaded[]; +extern u8 BattleScript_SunlightContinues[]; +extern u8 BattleScript_SafeguardEnds[]; +extern u8 BattleScript_MonWokeUpInUproar[]; //uproar wakeup BS +extern u8 BattleScript_PrintUproarOverTurns[]; //uproar BS +extern u8 BattleScript_ThrashConfuses[]; +extern u8 BattleScript_YawnMakesAsleep[]; +extern u8 BattleScript_MonTookFutureAttack[]; +extern u8 BattleScript_PerishSongHits[]; +extern u8 BattleScript_PerishSongTimerGoesDown[]; +extern u8 BattleScript_GiveExp[]; +extern u8 BattleScript_HandleFaintedMon[]; + +extern u8 BattleScript_MoveUsedIsAsleep[]; +extern u8 BattleScript_MoveUsedWokeUp[]; +extern u8 BattleScript_MoveUsedIsFrozen[]; +extern u8 BattleScript_MoveUsedUnfroze[]; +extern u8 BattleScript_MoveUsedLoafingAround[]; +extern u8 BattleScript_MoveUsedMustRecharge[]; +extern u8 BattleScript_MoveUsedFlinched[]; +extern u8 BattleScript_MoveUsedIsDisabled[]; +extern u8 BattleScript_MoveUsedIsTaunted[]; +extern u8 BattleScript_MoveUsedIsImprisoned[]; +extern u8 BattleScript_MoveUsedIsConfused[]; +extern u8 BattleScript_MoveUsedIsConfusedNoMore[]; +extern u8 BattleScript_MoveUsedIsParalyzed[]; +extern u8 BattleScript_MoveUsedIsParalyzedCantAttack[]; +extern u8 BattleScript_MoveUsedIsInLove[]; +extern u8 BattleScript_BideStoringEnergy[]; +extern u8 BattleScript_BideAttack[]; +extern u8 BattleScript_BideNoEnergyToAttack[]; + +extern u8 BattleScript_OverworldWeatherStarts[]; //load weather from overworld +extern u8 BattleScript_DrizzleActivates[]; +extern u8 BattleScript_SandstreamActivates[]; +extern u8 BattleScript_DroughtActivates[]; +extern u8 BattleScript_CastformChange[]; +extern u8 BattleScript_RainDishActivates[]; +extern u8 BattleScript_ShedSkinActivates[]; +extern u8 BattleScript_SpeedBoostActivates[]; +extern u8 BattleScript_SoundproofProtected[]; +extern u8 BattleScript_MoveHPDrain[]; +extern u8 BattleScript_MoveHPDrain_PPLoss[]; +extern u8 BattleScript_FlashFireBoost[]; +extern u8 BattleScript_FlashFireBoost_PPLoss[]; +extern u8 BattleScript_MoveHPDrain_FullHP[]; +extern u8 BattleScript_MoveHPDrain_FullHP_PPLoss[]; +extern u8 BattleScript_ColorChangeActivates[]; +extern u8 BattleScript_RoughSkinActivates[]; +extern u8 BattleScript_ApplySecondaryEffect[]; +extern u8 BattleScript_CuteCharmActivates[]; +extern u8 BattleScript_AbilityCuredStatus[]; //ability status clear +extern u8 BattleScript_SynchronizeActivates[]; +extern u8 gUnknown_081D978C[]; //intimidate1 +extern u8 gUnknown_081D9795[]; //intimidate2 +extern u8 BattleScript_TraceActivates[]; + +extern u8 BattleScript_WhiteHerbEnd2[]; +extern u8 BattleScript_WhiteHerbRet[]; +extern u8 BattleScript_ItemHealHP_RemoveItem[]; +extern u8 BattleScript_BerryPPHealEnd2[]; +extern u8 BattleScript_ItemHealHP_End2[]; +extern u8 BattleScript_BerryConfuseHealEnd2[]; +extern u8 BattleScript_BerryStatRaiseEnd2[]; +extern u8 BattleScript_BerryFocusEnergyEnd2[]; +extern u8 BattleScript_BerryCurePrlzEnd2[]; +extern u8 BattleScript_BerryCurePsnEnd2[]; +extern u8 BattleScript_BerryCureBrnEnd2[]; +extern u8 BattleScript_BerryCureFrzEnd2[]; +extern u8 BattleScript_BerryCureSlpEnd2[]; +extern u8 BattleScript_BerryCureConfusionEnd2[]; +extern u8 BattleScript_BerryCureChosenStatusEnd2[]; //berry cure any status end2 +extern u8 BattleScript_BerryCureParRet[]; +extern u8 BattleScript_BerryCurePsnRet[]; +extern u8 BattleScript_BerryCureBrnRet[]; +extern u8 BattleScript_BerryCureFrzRet[]; +extern u8 BattleScript_BerryCureSlpRet[]; +extern u8 BattleScript_BerryCureConfusionRet[]; +extern u8 BattleScript_BerryCureChosenStatusRet[]; //berry cure any status return + +extern u8 BattleScript_ItemHealHP_Ret[]; + +extern u8 gUnknown_081D995F[]; //disobedient while asleep +extern u8 BattleScript_IgnoresAndUsesRandomMove[]; //disobedient, uses a random move +extern u8 BattleScript_IgnoresAndFallsAsleep[]; //disobedient, went to sleep +extern u8 gUnknown_081D99A0[]; //disobedient, hits itself + +//array entries for battle communication +#define MOVE_EFFECT_BYTE 0x3 +#define MULTISTRING_CHOOSER 0x5 +#define MSG_DISPLAY 0x7 + +u8 GetBattleBank(u8 caseId) +{ + u8 ret = 0; + switch (caseId) + { + case BS_GET_TARGET: + ret = gBankTarget; + break; + case BS_GET_ATTACKER: + ret = gBankAttacker; + break; + case BS_GET_EFFECT_BANK: + ret = gEffectBank; + break; + case BS_GET_BANK_0: + ret = 0; + break; + case BS_GET_SCRIPTING_BANK: + ret = ewram16003; + break; + case BS_GET_gBank1: + ret = gBank1; + break; + case 5: + ret = gBank1; + break; + } + return ret; +} + +void PressurePPLose(u8 bankDef, u8 bankAtk, u16 move) +{ + s32 i; + + if (gBattleMons[bankDef].ability != ABILITY_PRESSURE) + return; + + for (i = 0; i < 4; i++) + { + if (gBattleMons[bankAtk].moves[i] == move) + break; + } + + if (i == 4) // mons don't share any moves + return; + + if (gBattleMons[bankAtk].pp[i] != 0) + gBattleMons[bankAtk].pp[i]--; + + if (!(gBattleMons[bankAtk].status2 & STATUS2_TRANSFORMED) + && !(gDisableStructs[bankAtk].unk18_b & gBitTable[i])) + { + gActiveBattler = bankAtk; + EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + i, 0, 1, &gBattleMons[gActiveBattler].pp[i]); + MarkBufferBankForExecution(gActiveBattler); + } +} + +void PressurePPLoseOnUsingImprision(u8 bankAtk) +{ + s32 i, j; + s32 imprisionPos = 4; + u8 atkSide = GetBattlerSide(bankAtk); + + for (i = 0; i < gBattlersCount; i++) + { + if (atkSide != GetBattlerSide(i) && gBattleMons[i].ability == ABILITY_PRESSURE) + { + for (j = 0; j < 4; j++) + { + if (gBattleMons[bankAtk].moves[j] == MOVE_IMPRISON) + break; + } + if (j != 4) + { + imprisionPos = j; + if (gBattleMons[bankAtk].pp[j] != 0) + gBattleMons[bankAtk].pp[j]--; + } + } + } + + if (imprisionPos != 4 + && !(gBattleMons[bankAtk].status2 & STATUS2_TRANSFORMED) + && !(gDisableStructs[bankAtk].unk18_b & gBitTable[imprisionPos])) + { + gActiveBattler = bankAtk; + EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + imprisionPos, 0, 1, &gBattleMons[gActiveBattler].pp[imprisionPos]); + MarkBufferBankForExecution(gActiveBattler); + } +} + +void PressurePPLoseOnUsingPerishSong(u8 bankAtk) +{ + s32 i, j; + s32 perishSongPos = 4; + + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].ability == ABILITY_PRESSURE && i != bankAtk) + { + for (j = 0; j < 4; j++) + { + if (gBattleMons[bankAtk].moves[j] == MOVE_PERISH_SONG) + break; + } + if (j != 4) + { + perishSongPos = j; + if (gBattleMons[bankAtk].pp[j] != 0) + gBattleMons[bankAtk].pp[j]--; + } + } + } + + if (perishSongPos != 4 + && !(gBattleMons[bankAtk].status2 & STATUS2_TRANSFORMED) + && !(gDisableStructs[bankAtk].unk18_b & gBitTable[perishSongPos])) + { + gActiveBattler = bankAtk; + EmitSetMonData(0, REQUEST_PPMOVE1_BATTLE + perishSongPos, 0, 1, &gBattleMons[gActiveBattler].pp[perishSongPos]); + MarkBufferBankForExecution(gActiveBattler); + } +} + + +void MarkAllBufferBanksForExecution(void) // unused +{ + s32 i; + + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + for (i = 0; i < gBattlersCount; i++) + gBattleExecBuffer |= gBitTable[i] << 0x1C; + } + else + { + for (i = 0; i < gBattlersCount; i++) + gBattleExecBuffer |= gBitTable[i]; + } +} + +void MarkBufferBankForExecution(u8 bank) +{ + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gBattleExecBuffer |= gBitTable[bank] << 0x1C; + } + else + { + gBattleExecBuffer |= gBitTable[bank]; + } +} + +void sub_80155A4(u8 arg0) +{ + s32 i; + + for (i = 0; i < GetLinkPlayerCount(); i++) + gBattleExecBuffer |= gBitTable[arg0] << (i << 2); + + gBattleExecBuffer &= ~(0x10000000 << arg0); +} + +void CancelMultiTurnMoves(u8 bank) +{ + gBattleMons[bank].status2 &= ~(STATUS2_MULTIPLETURNS); + gBattleMons[bank].status2 &= ~(STATUS2_LOCK_CONFUSE); + gBattleMons[bank].status2 &= ~(STATUS2_UPROAR); + gBattleMons[bank].status2 &= ~(STATUS2_BIDE); + + gStatuses3[bank] &= ~(STATUS3_SEMI_INVULNERABLE); + + gDisableStructs[bank].rolloutTimer1 = 0; + gDisableStructs[bank].furyCutterCounter = 0; +} + +bool8 WasUnableToUseMove(u8 bank) +{ + if (gProtectStructs[bank].prlzImmobility + || gProtectStructs[bank].notEffective + || gProtectStructs[bank].usedImprisionedMove + || gProtectStructs[bank].loveImmobility + || gProtectStructs[bank].usedDisabledMove + || gProtectStructs[bank].usedTauntedMove + || gProtectStructs[bank].flag2Unknown + || gProtectStructs[bank].flinchImmobility + || gProtectStructs[bank].confusionSelfDmg) + return TRUE; + else + return FALSE; +} + +void PrepareStringBattle(u16 stringId, u8 bank) +{ + gActiveBattler = bank; + EmitPrintString(0, stringId); + MarkBufferBankForExecution(gActiveBattler); +} + +void ResetSentPokesToOpponentValue(void) +{ + s32 i; + u32 bits = 0; + + gSentPokesToOpponent[0] = 0; + gSentPokesToOpponent[1] = 0; + + for (i = 0; i < gBattlersCount; i += 2) + bits |= gBitTable[gBattlerPartyIndexes[i]]; + + for (i = 1; i < gBattlersCount; i += 2) + gSentPokesToOpponent[(i & BIT_FLANK) >> 1] = bits; +} + +void sub_8015740(u8 bank) +{ + s32 i = 0; + u32 bits = 0; + + if (GetBattlerSide(bank) == B_SIDE_OPPONENT) + { + u8 id = ((bank & BIT_FLANK) >> 1); + gSentPokesToOpponent[id] = 0; + + for (i = 0; i < gBattlersCount; i += 2) + { + if (!(gAbsentBattlerFlags & gBitTable[i])) + bits |= gBitTable[gBattlerPartyIndexes[i]]; + } + + gSentPokesToOpponent[id] = bits; + } +} + +void sub_80157C4(u8 bank) +{ + if (GetBattlerSide(bank) == B_SIDE_OPPONENT) + { + sub_8015740(bank); + } + else + { + s32 i; + for (i = 1; i < gBattlersCount; i++) + gSentPokesToOpponent[(i & BIT_FLANK) >> 1] |= gBitTable[gBattlerPartyIndexes[bank]]; + } +} + +void BattleScriptPush(const u8* BS_ptr) +{ + B_BATTLESCRIPTS_STACK->ptr[B_BATTLESCRIPTS_STACK->size++] = BS_ptr; +} + +void BattleScriptPushCursor(void) +{ + B_BATTLESCRIPTS_STACK->ptr[B_BATTLESCRIPTS_STACK->size++] = gBattlescriptCurrInstr; +} + +void BattleScriptPop(void) +{ + gBattlescriptCurrInstr = B_BATTLESCRIPTS_STACK->ptr[--B_BATTLESCRIPTS_STACK->size]; +} + +u8 TrySetCantSelectMoveBattleScript(void) //msg can't select a move +{ + u8 limitations = 0; + u16 move = gBattleMons[gActiveBattler].moves[gBattleBufferB[gActiveBattler][2]]; + u8 holdEffect; + u16* choicedMove = CHOICED_MOVE(gActiveBattler); + if (gDisableStructs[gActiveBattler].disabledMove == move && move) + { + gBattleStruct->scriptingActive = gActiveBattler; + gCurrentMove = move; + gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionDisabledMove; + limitations++; + } + if (move == gLastUsedMove[gActiveBattler] && move != MOVE_STRUGGLE && gBattleMons[gActiveBattler].status2 & STATUS2_TORMENT) + { + CancelMultiTurnMoves(gActiveBattler); + gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionTormented; + limitations++; + } + if (gDisableStructs[gActiveBattler].tauntTimer1 && gBattleMoves[move].power == 0) + { + gCurrentMove = move; + gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionTaunted; + limitations++; + } + if (IsImprisoned(gActiveBattler, move)) + { + gCurrentMove = move; + gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionImprisoned; + limitations++; + } + if (gBattleMons[gActiveBattler].item == ITEM_ENIGMA_BERRY) + holdEffect = gEnigmaBerries[gActiveBattler].holdEffect; + else + holdEffect = ItemId_GetHoldEffect(gBattleMons[gActiveBattler].item); + gStringBank = gActiveBattler; + if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != move) + { + gCurrentMove = *choicedMove; + gLastUsedItem = gBattleMons[gActiveBattler].item; + gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionChoiceBanded; + limitations++; + } + if (gBattleMons[gActiveBattler].pp[gBattleBufferB[gActiveBattler][2]] == 0) + { + gSelectionBattleScripts[gActiveBattler] = BattleScript_MoveSelectionNoPP; + limitations++; + } + return limitations; +} + +#define MOVE_LIMITATION_ZEROMOVE (1 << 0) +#define MOVE_LIMITATION_PP (1 << 1) +#define MOVE_LIMITATION_DISABLED (1 << 2) +#define MOVE_LIMITATION_TORMENTED (1 << 3) +#define MOVE_LIMITATION_TAUNT (1 << 4) +#define MOVE_LIMITATION_IMPRISION (1 << 5) + +u8 CheckMoveLimitations(u8 bank, u8 unusableMoves, u8 check) +{ + u8 holdEffect; + u16* choicedMove = CHOICED_MOVE(bank); + s32 i; + if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY) + holdEffect = gEnigmaBerries[bank].holdEffect; + else + holdEffect = ItemId_GetHoldEffect(gBattleMons[bank].item); + gStringBank = bank; + for (i = 0; i < 4; i++) + { + if (gBattleMons[bank].moves[i] == 0 && check & MOVE_LIMITATION_ZEROMOVE) + unusableMoves |= gBitTable[i]; + if (gBattleMons[bank].pp[i] == 0 && check & MOVE_LIMITATION_PP) + unusableMoves |= gBitTable[i]; + if (gBattleMons[bank].moves[i] == gDisableStructs[bank].disabledMove && check & MOVE_LIMITATION_DISABLED) + unusableMoves |= gBitTable[i]; + if (gBattleMons[bank].moves[i] == gLastUsedMove[bank] && check & MOVE_LIMITATION_TORMENTED && gBattleMons[bank].status2 & STATUS2_TORMENT) + unusableMoves |= gBitTable[i]; + if (gDisableStructs[bank].tauntTimer1 && check & MOVE_LIMITATION_TAUNT && gBattleMoves[gBattleMons[bank].moves[i]].power == 0) + unusableMoves |= gBitTable[i]; + if (IsImprisoned(bank, gBattleMons[bank].moves[i]) && check & MOVE_LIMITATION_IMPRISION) + unusableMoves |= gBitTable[i]; + if (gDisableStructs[bank].encoreTimer1 && gDisableStructs[bank].encoredMove != gBattleMons[bank].moves[i]) + unusableMoves |= gBitTable[i]; + if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[bank].moves[i]) + unusableMoves |= gBitTable[i]; + } + return unusableMoves; +} + +bool8 AreAllMovesUnusable(void) +{ + u8 unusable; + unusable = CheckMoveLimitations(gActiveBattler, 0, 0xFF); + if (unusable == 0xF) //all moves are unusable + { + gProtectStructs[gActiveBattler].onlyStruggle = 1; + gSelectionBattleScripts[gActiveBattler] = BattleScript_NoMovesLeft; + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + gBattleBufferB[gActiveBattler][3] = GetBattlerAtPosition((GetBattlerPosition(gActiveBattler) ^ 1) | (Random() & 2)); + else + gBattleBufferB[gActiveBattler][3] = GetBattlerAtPosition(GetBattlerPosition(gActiveBattler) ^ 1); + } + else + gProtectStructs[gActiveBattler].onlyStruggle = 0; + return (unusable == 0xF); +} + +u8 IsImprisoned(u8 bank, u16 move) +{ + u8 imprisionedMoves = 0; + u8 bankSide = GetBattlerSide(bank); + s32 i; + for (i = 0; i < gBattlersCount; i++) + { + if (bankSide != GetBattlerSide(i) && gStatuses3[i] & STATUS3_IMPRISIONED) + { + s32 j; + for (j = 0; j < 4; j++) + { + if (move == gBattleMons[i].moves[j]) + break; + } + if (j < 4) + imprisionedMoves++; + } + } + return imprisionedMoves; +} + +u8 UpdateTurnCounters(void) +{ + u8 effect = 0; + s32 i; + + for (gBankAttacker = 0; gBankAttacker < gBattlersCount && gAbsentBattlerFlags & gBitTable[gBankAttacker]; gBankAttacker++) + { + } + for (gBankTarget = 0; gBankTarget < gBattlersCount && gAbsentBattlerFlags & gBitTable[gBankTarget]; gBankTarget++) + { + } + + do + { + u8 sideBank; + + switch (gBattleStruct->turncountersTracker) + { + case 0: + for (i = 0; i < gBattlersCount; i++) + { + gBanksByTurnOrder[i] = i; + } + for (i = 0; i < gBattlersCount - 1; i++) + { + s32 j; + for (j = i + 1; j < gBattlersCount; j++) + { + if (GetWhoStrikesFirst(gBanksByTurnOrder[i], gBanksByTurnOrder[j], 0)) + SwapTurnOrder(i, j); + } + } + gBattleStruct->turncountersTracker++; + gBattleStruct->turnSideTracker = 0; + case 1: + while (gBattleStruct->turnSideTracker < 2) + { + gActiveBattler = gBankAttacker = sideBank = gBattleStruct->turnSideTracker; + + if (gSideAffecting[sideBank] & SIDE_STATUS_REFLECT) + { + if (--gSideTimers[sideBank].reflectTimer == 0) + { + + gSideAffecting[sideBank] &= ~SIDE_STATUS_REFLECT; + BattleScriptExecute(BattleScript_SideStatusWoreOff); + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = MOVE_REFLECT; + gBattleTextBuff1[3] = MOVE_REFLECT >> 8; + gBattleTextBuff1[4] = EOS; + effect++; + } + } + gBattleStruct->turnSideTracker++; + if (effect) + break; + } + if (!effect) + { + gBattleStruct->turncountersTracker++; + gBattleStruct->turnSideTracker = 0; + } + break; + case 2: + while (gBattleStruct->turnSideTracker < 2) + { + gActiveBattler = gBankAttacker = sideBank = gBattleStruct->turnSideTracker; + if (gSideAffecting[sideBank] & SIDE_STATUS_LIGHTSCREEN) + { + if (--gSideTimers[sideBank].lightscreenTimer == 0) + { + gSideAffecting[sideBank] &= ~SIDE_STATUS_LIGHTSCREEN; + BattleScriptExecute(BattleScript_SideStatusWoreOff); + gBattleCommunication[MULTISTRING_CHOOSER] = sideBank; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = MOVE_LIGHT_SCREEN; + gBattleTextBuff1[3] = MOVE_LIGHT_SCREEN >> 8; + gBattleTextBuff1[4] = EOS; + effect++; + } + } + gBattleStruct->turnSideTracker++; + if (effect) + break; + } + if (!effect) + { + gBattleStruct->turncountersTracker++; + gBattleStruct->turnSideTracker = 0; + } + break; + case 3: + while (gBattleStruct->turnSideTracker < 2) + { + gActiveBattler = gBankAttacker = sideBank = gBattleStruct->turnSideTracker; + if (gSideTimers[sideBank].mistTimer && --gSideTimers[sideBank].mistTimer == 0) + { + gSideAffecting[sideBank] &= ~SIDE_STATUS_MIST; + BattleScriptExecute(BattleScript_SideStatusWoreOff); + gBattleCommunication[MULTISTRING_CHOOSER] = sideBank; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = MOVE_MIST; + gBattleTextBuff1[3] = MOVE_MIST >> 8; + gBattleTextBuff1[4] = EOS; + effect++; + } + gBattleStruct->turnSideTracker++; + if (effect) + break; + } + if (!effect) + { + gBattleStruct->turncountersTracker++; + gBattleStruct->turnSideTracker = 0; + } + break; + case 4: + while (gBattleStruct->turnSideTracker < 2) + { + gActiveBattler = gBankAttacker = sideBank = gBattleStruct->turnSideTracker; + if (gSideAffecting[sideBank] & SIDE_STATUS_SAFEGUARD) + { + if (--gSideTimers[sideBank].safeguardTimer == 0) + { + gSideAffecting[sideBank] &= ~SIDE_STATUS_SAFEGUARD; + BattleScriptExecute(BattleScript_SafeguardEnds); + effect++; + } + } + gBattleStruct->turnSideTracker++; + if (effect) + break; + } + if (!effect) + { + gBattleStruct->turncountersTracker++; + gBattleStruct->turnSideTracker = 0; + } + break; + case 5: + while (gBattleStruct->turnSideTracker < gBattlersCount) + { + gActiveBattler = gBanksByTurnOrder[gBattleStruct->turnSideTracker]; + if (gWishFutureKnock.wishCounter[gActiveBattler] && --gWishFutureKnock.wishCounter[gActiveBattler] == 0 && gBattleMons[gActiveBattler].hp) + { + gBankTarget = gActiveBattler; + BattleScriptExecute(BattleScript_WishComesTrue); + effect++; + } + gBattleStruct->turnSideTracker++; + if (effect) + break; + } + if (!effect) + { + gBattleStruct->turncountersTracker++; + } + break; + case 6: + if (gBattleWeather & WEATHER_RAIN_ANY) + { + if (!(gBattleWeather & WEATHER_RAIN_PERMANENT)) + { + if (--gWishFutureKnock.weatherDuration == 0) + { + gBattleWeather &= ~WEATHER_RAIN_TEMPORARY; + gBattleWeather &= ~WEATHER_RAIN_DOWNPOUR; + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + } + else if (gBattleWeather & WEATHER_RAIN_DOWNPOUR) + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else if (gBattleWeather & WEATHER_RAIN_DOWNPOUR) + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + BattleScriptExecute(BattleScript_RainContinuesOrEnds); + effect++; + } + gBattleStruct->turncountersTracker++; + break; + case 7: + if (gBattleWeather & WEATHER_SANDSTORM_ANY) + { + if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT) && --gWishFutureKnock.weatherDuration == 0) + { + gBattleWeather &= ~WEATHER_SANDSTORM_TEMPORARY; + gBattlescriptCurrInstr = BattleScript_SandStormHailEnds; + } + else + gBattlescriptCurrInstr = BattleScript_DamagingWeatherContinues; + + gBattleStruct->animArg1 = B_ANIM_SANDSTORM_CONTINUES; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + BattleScriptExecute(gBattlescriptCurrInstr); + effect++; + } + gBattleStruct->turncountersTracker++; + break; + case 8: + if (gBattleWeather & WEATHER_SUN_ANY) + { + if (!(gBattleWeather & WEATHER_SUN_PERMANENT) && --gWishFutureKnock.weatherDuration == 0) + { + gBattleWeather &= ~WEATHER_SUN_TEMPORARY; + gBattlescriptCurrInstr = BattleScript_SunlightFaded; + } + else + gBattlescriptCurrInstr = BattleScript_SunlightContinues; + + BattleScriptExecute(gBattlescriptCurrInstr); + effect++; + } + gBattleStruct->turncountersTracker++; + break; + case 9: + if (gBattleWeather & WEATHER_HAIL) + { + if (--gWishFutureKnock.weatherDuration == 0) + { + gBattleWeather &= ~WEATHER_HAIL; + gBattlescriptCurrInstr = BattleScript_SandStormHailEnds; + } + else + gBattlescriptCurrInstr = BattleScript_DamagingWeatherContinues; + + gBattleStruct->animArg1 = B_ANIM_HAIL_CONTINUES; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + BattleScriptExecute(gBattlescriptCurrInstr); + effect++; + } + gBattleStruct->turncountersTracker++; + break; + case 10: + effect++; + break; + } + } while (effect == 0); + return (gBattleMainFunc != BattleTurnPassed); +} + +#define TURNBASED_MAX_CASE 19 + +u8 TurnBasedEffects(void) +{ + u8 effect = 0; + + gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20); + while (gBattleStruct->turnEffectsBank < gBattlersCount && gBattleStruct->turnEffectsTracker <= TURNBASED_MAX_CASE) + { + gActiveBattler = gBankAttacker = gBanksByTurnOrder[gBattleStruct->turnEffectsBank]; + if (gAbsentBattlerFlags & gBitTable[gActiveBattler]) + { + gBattleStruct->turnEffectsBank++; + } + else + { + switch (gBattleStruct->turnEffectsTracker) + { + case 0: // ingrain + if ((gStatuses3[gActiveBattler] & STATUS3_ROOTED) + && gBattleMons[gActiveBattler].hp != gBattleMons[gActiveBattler].maxHP + && gBattleMons[gActiveBattler].hp != 0) + { + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + BattleScriptExecute(BattleScript_IngrainTurnHeal); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 1: // end turn abilities + if (AbilityBattleEffects(ABILITYEFFECT_ENDTURN, gActiveBattler, 0, 0, 0)) + effect++; + gBattleStruct->turnEffectsTracker++; + break; + case 2: // item effects + if (ItemBattleEffects(1, gActiveBattler, 0)) + effect++; + gBattleStruct->turnEffectsTracker++; + break; + case 18: // item effects again + if (ItemBattleEffects(1, gActiveBattler, 1)) + effect++; + gBattleStruct->turnEffectsTracker++; + break; + case 3: // leech seed + if (gStatuses3[gActiveBattler] & STATUS3_LEECHSEED && gBattleMons[gStatuses3[gActiveBattler] & STATUS3_LEECHSEED_BANK].hp != 0 && gBattleMons[gActiveBattler].hp != 0) + { + gBankTarget = gStatuses3[gActiveBattler] & STATUS3_LEECHSEED_BANK; //funny how the 'target' is actually the bank that receives HP + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleStruct->animArg1 = gBankTarget; + gBattleStruct->animArg2 = gBankAttacker; + BattleScriptExecute(BattleScript_LeechSeedTurnDrain); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 4: // poison + if ((gBattleMons[gActiveBattler].status1 & STATUS_POISON) && gBattleMons[gActiveBattler].hp != 0) + { + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + BattleScriptExecute(BattleScript_PoisonTurnDmg); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 5: // toxic poison + if ((gBattleMons[gActiveBattler].status1 & STATUS_TOXIC_POISON) && gBattleMons[gActiveBattler].hp != 0) + { + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if ((gBattleMons[gActiveBattler].status1 & 0xF00) != 0xF00) //not 16 turns + gBattleMons[gActiveBattler].status1 += 0x100; + gBattleMoveDamage *= (gBattleMons[gActiveBattler].status1 & 0xF00) >> 8; + BattleScriptExecute(BattleScript_PoisonTurnDmg); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 6: // burn + if ((gBattleMons[gActiveBattler].status1 & STATUS_BURN) && gBattleMons[gActiveBattler].hp != 0) + { + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 8; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + BattleScriptExecute(BattleScript_BurnTurnDmg); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 7: // spooky nightmares + if ((gBattleMons[gActiveBattler].status2 & STATUS2_NIGHTMARE) && gBattleMons[gActiveBattler].hp != 0) + { + // missing sleep check + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + BattleScriptExecute(BattleScript_NightmareTurnDmg); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 8: // curse + if ((gBattleMons[gActiveBattler].status2 & STATUS2_CURSED) && gBattleMons[gActiveBattler].hp != 0) + { + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + BattleScriptExecute(BattleScript_CurseTurnDmg); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 9: // wrap + if ((gBattleMons[gActiveBattler].status2 & STATUS2_WRAPPED) && gBattleMons[gActiveBattler].hp != 0) + { + gBattleMons[gActiveBattler].status2 -= 0x2000; + if (gBattleMons[gActiveBattler].status2 & STATUS2_WRAPPED) // damaged by wrap + { + gBattleStruct->animArg1 = ewram16004arr(0, gActiveBattler); + gBattleStruct->animArg2 = ewram16004arr(1, gActiveBattler); + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = ewram16004arr(0, gActiveBattler); + gBattleTextBuff1[3] = ewram16004arr(1, gActiveBattler); + gBattleTextBuff1[4] = EOS; + gBattlescriptCurrInstr = BattleScript_WrapTurnDmg; + gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + } + else // broke free + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = ewram16004arr(0, gActiveBattler); + gBattleTextBuff1[3] = ewram16004arr(1, gActiveBattler); + gBattleTextBuff1[4] = EOS; + gBattlescriptCurrInstr = BattleScript_WrapEnds; + } + BattleScriptExecute(gBattlescriptCurrInstr); + effect++; + } + gBattleStruct->turnEffectsTracker++; + break; + case 10: // uproar + if (gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR) + { + for (gBankAttacker = 0; gBankAttacker < gBattlersCount; gBankAttacker++) + { + if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) + && gBattleMons[gBankAttacker].ability != ABILITY_SOUNDPROOF) + { + gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + BattleScriptExecute(BattleScript_MonWokeUpInUproar); + gActiveBattler = gBankAttacker; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); + MarkBufferBankForExecution(gActiveBattler); + break; + } + } + if (gBankAttacker != gBattlersCount) + { + effect = 2; // a pokemon was awaken + break; + } + else + { + gBankAttacker = gActiveBattler; + gBattleMons[gActiveBattler].status2 -= 0x10; // uproar timer goes down + if (WasUnableToUseMove(gActiveBattler)) + { + CancelMultiTurnMoves(gActiveBattler); + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + else if (gBattleMons[gActiveBattler].status2 & STATUS2_UPROAR) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattleMons[gActiveBattler].status2 |= STATUS2_MULTIPLETURNS; + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + CancelMultiTurnMoves(gActiveBattler); + } + BattleScriptExecute(BattleScript_PrintUproarOverTurns); + effect = 1; + } + } + if (effect != 2) + gBattleStruct->turnEffectsTracker++; + break; + case 11: // thrash + if (gBattleMons[gActiveBattler].status2 & STATUS2_LOCK_CONFUSE) + { + gBattleMons[gActiveBattler].status2 -= 0x400; + if (WasUnableToUseMove(gActiveBattler)) + CancelMultiTurnMoves(gActiveBattler); + else if (!(gBattleMons[gActiveBattler].status2 & STATUS2_LOCK_CONFUSE) + && (gBattleMons[gActiveBattler].status2 & STATUS2_MULTIPLETURNS)) + { + gBattleMons[gActiveBattler].status2 &= ~(STATUS2_MULTIPLETURNS); + if (!(gBattleMons[gActiveBattler].status2 & STATUS2_CONFUSION)) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0x47; + SetMoveEffect(1, 0); + if (gBattleMons[gActiveBattler].status2 & STATUS2_CONFUSION) + BattleScriptExecute(BattleScript_ThrashConfuses); + effect++; + } + } + } + gBattleStruct->turnEffectsTracker++; + break; + case 12: // disable + if (gDisableStructs[gActiveBattler].disableTimer1 != 0) + { + int i; + for (i = 0; i < 4; i++) + { + if (gDisableStructs[gActiveBattler].disabledMove == gBattleMons[gActiveBattler].moves[i]) + break; + } + if (i == 4) // pokemon does not have the disabled move anymore + { + gDisableStructs[gActiveBattler].disabledMove = 0; + gDisableStructs[gActiveBattler].disableTimer1 = 0; + } + else if (--gDisableStructs[gActiveBattler].disableTimer1 == 0) // disable ends + { + gDisableStructs[gActiveBattler].disabledMove = 0; + BattleScriptExecute(BattleScript_DisabledNoMore); + effect++; + } + } + gBattleStruct->turnEffectsTracker++; + break; + case 13: // encore + if (gDisableStructs[gActiveBattler].encoreTimer1 != 0) + { + if (gBattleMons[gActiveBattler].moves[gDisableStructs[gActiveBattler].encoredMovePos] != gDisableStructs[gActiveBattler].encoredMove) // pokemon does not have the encored move anymore + { + gDisableStructs[gActiveBattler].encoredMove = 0; + gDisableStructs[gActiveBattler].encoreTimer1 = 0; + } + else if (--gDisableStructs[gActiveBattler].encoreTimer1 == 0 + || gBattleMons[gActiveBattler].pp[gDisableStructs[gActiveBattler].encoredMovePos] == 0) + { + gDisableStructs[gActiveBattler].encoredMove = 0; + gDisableStructs[gActiveBattler].encoreTimer1 = 0; + BattleScriptExecute(BattleScript_EncoredNoMore); + effect++; + } + } + gBattleStruct->turnEffectsTracker++; + break; + case 14: // lock-on decrement + if (gStatuses3[gActiveBattler] & STATUS3_ALWAYS_HITS) + gStatuses3[gActiveBattler] -= 0x8; + gBattleStruct->turnEffectsTracker++; + break; + case 15: // charge + if (gDisableStructs[gActiveBattler].chargeTimer1 && --gDisableStructs[gActiveBattler].chargeTimer1 == 0) + gStatuses3[gActiveBattler] &= ~STATUS3_CHARGED_UP; + gBattleStruct->turnEffectsTracker++; + break; + case 16: // taunt + if (gDisableStructs[gActiveBattler].tauntTimer1) + gDisableStructs[gActiveBattler].tauntTimer1--; + gBattleStruct->turnEffectsTracker++; + break; + case 17: // yawn + if (gStatuses3[gActiveBattler] & STATUS3_YAWN) + { + gStatuses3[gActiveBattler] -= 0x800; + if (!(gStatuses3[gActiveBattler] & STATUS3_YAWN) && !(gBattleMons[gActiveBattler].status1 & STATUS_ANY) + && gBattleMons[gActiveBattler].ability != ABILITY_VITAL_SPIRIT + && gBattleMons[gActiveBattler].ability != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBattler)) + { + CancelMultiTurnMoves(gActiveBattler); + gBattleMons[gActiveBattler].status1 |= (Random() & 3) + 2; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); + MarkBufferBankForExecution(gActiveBattler); + gEffectBank = gActiveBattler; + BattleScriptExecute(BattleScript_YawnMakesAsleep); + effect++; + } + } + gBattleStruct->turnEffectsTracker++; + break; + case 19: // done + gBattleStruct->turnEffectsTracker = 0; + gBattleStruct->turnEffectsBank++; + break; + } + if (effect != 0) + return effect; + } + } + gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20); + return 0; +} + +bool8 HandleWishPerishSongOnTurnEnd(void) +{ + gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20); + switch (gBattleStruct->sub80170DC_Tracker) + { + case 0: // future sight + while (gBattleStruct->sub80170DC_Bank < gBattlersCount) + { + gActiveBattler = gBattleStruct->sub80170DC_Bank; + if (gAbsentBattlerFlags & gBitTable[gActiveBattler]) + gBattleStruct->sub80170DC_Bank++; + else + { + gBattleStruct->sub80170DC_Bank++; + if (gWishFutureKnock.futureSightCounter[gActiveBattler] && --gWishFutureKnock.futureSightCounter[gActiveBattler] == 0 && gBattleMons[gActiveBattler].hp) + { + if (gWishFutureKnock.futureSightMove[gActiveBattler] == MOVE_FUTURE_SIGHT) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else //Doom Desire + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = gWishFutureKnock.futureSightMove[gActiveBattler]; + gBattleTextBuff1[3] = gWishFutureKnock.futureSightMove[gActiveBattler] >> 8; + gBattleTextBuff1[4] = 0xFF; + gBankTarget = gActiveBattler; + gBankAttacker = gWishFutureKnock.futureSightAttacker[gActiveBattler]; + gBattleMoveDamage = gWishFutureKnock.futureSightDmg[gActiveBattler]; + gSpecialStatuses[gBankTarget].moveturnLostHP = 0xFFFF; + BattleScriptExecute(BattleScript_MonTookFutureAttack); + return 1; + } + } + } + gBattleStruct->sub80170DC_Tracker = 1; + gBattleStruct->sub80170DC_Bank = 0; + case 1: // perish song + while (gBattleStruct->sub80170DC_Bank < gBattlersCount) + { + gActiveBattler = gBankAttacker = gBanksByTurnOrder[gBattleStruct->sub80170DC_Bank]; + if (gAbsentBattlerFlags & gBitTable[gActiveBattler]) + gBattleStruct->sub80170DC_Bank++; + else + { + gBattleStruct->sub80170DC_Bank++; + if (gStatuses3[gActiveBattler] & STATUS3_PERISH_SONG) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 1; + gBattleTextBuff1[2] = 1; + gBattleTextBuff1[3] = 1; + gBattleTextBuff1[4] = gDisableStructs[gActiveBattler].perishSongTimer1; + gBattleTextBuff1[5] = 0xFF; + if (gDisableStructs[gActiveBattler].perishSongTimer1 == 0) + { + gStatuses3[gActiveBattler] &= ~(STATUS3_PERISH_SONG); + gBattleMoveDamage = gBattleMons[gActiveBattler].hp; + gBattlescriptCurrInstr = BattleScript_PerishSongHits; + } + else + { + gDisableStructs[gActiveBattler].perishSongTimer1--; + gBattlescriptCurrInstr = BattleScript_PerishSongTimerGoesDown; + } + BattleScriptExecute(gBattlescriptCurrInstr); + return 1; + } + } + } + break; + } + gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20); + return 0; +} + +#define HandleFaintedMonActions_MAX_CASE 7 + +bool8 HandleFaintedMonActions(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + return 0; + do + { + int i; + switch (gBattleStruct->sub80173A4_Tracker) + { + case 0: + gBattleStruct->unk1605A = 0; + gBattleStruct->sub80173A4_Tracker++; + for (i = 0; i < gBattlersCount; i++) + { + if (gAbsentBattlerFlags & gBitTable[i] && !sub_8018018(i, 6, 6)) + gAbsentBattlerFlags &= ~(gBitTable[i]); + } + case 1: + do + { + gBank1 = gBankTarget = gBattleStruct->unk1605A; + if (gBattleMons[gBattleStruct->unk1605A].hp == 0 && !(gBattleStruct->unk16113 & gBitTable[gBattlerPartyIndexes[gBattleStruct->unk1605A]]) && !(gAbsentBattlerFlags & gBitTable[gBattleStruct->unk1605A])) + { + BattleScriptExecute(BattleScript_GiveExp); + gBattleStruct->sub80173A4_Tracker = 2; + return 1; + } + } while (++gBattleStruct->unk1605A != gBattlersCount); + gBattleStruct->sub80173A4_Tracker = 3; + break; + case 2: + sub_8015740(gBank1); + if (++gBattleStruct->unk1605A == gBattlersCount) + gBattleStruct->sub80173A4_Tracker = 3; + else + gBattleStruct->sub80173A4_Tracker = 1; + break; + case 3: + gBattleStruct->unk1605A = 0; + gBattleStruct->sub80173A4_Tracker++; + case 4: + do + { + gBank1 = gBankTarget = gBattleStruct->unk1605A; //or should banks be switched? + if (gBattleMons[gBattleStruct->unk1605A].hp == 0 && !(gAbsentBattlerFlags & gBitTable[gBattleStruct->unk1605A])) + { + BattleScriptExecute(BattleScript_HandleFaintedMon); + gBattleStruct->sub80173A4_Tracker = 5; + return 1; + } + } while (++gBattleStruct->unk1605A != gBattlersCount); + gBattleStruct->sub80173A4_Tracker = 6; + break; + case 5: + if (++gBattleStruct->unk1605A == gBattlersCount) + gBattleStruct->sub80173A4_Tracker = 6; + else + gBattleStruct->sub80173A4_Tracker = 4; + break; + case 6: + if (AbilityBattleEffects(9, 0, 0, 0, 0) || AbilityBattleEffects(0xB, 0, 0, 0, 0) || ItemBattleEffects(1, 0, 1) || AbilityBattleEffects(6, 0, 0, 0, 0)) + return 1; + gBattleStruct->sub80173A4_Tracker++; + break; + case 7: + break; + } + } while (gBattleStruct->sub80173A4_Tracker != HandleFaintedMonActions_MAX_CASE); + return 0; +} + +void TryClearRageStatuses(void) +{ + int i; + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].status2 & STATUS2_RAGE && gChosenMovesByBanks[i] != MOVE_RAGE) + gBattleMons[i].status2 &= ~(STATUS2_RAGE); + } +} + +#define ATKCANCELLER_MAX_CASE 14 + +u8 AtkCanceller_UnableToUseMove(void) +{ + u8 effect = 0; + s32* bideDmg = &gBattleStruct->bideDmg; + do + { + switch (gBattleStruct->atkCancellerTracker) + { + case 0: // flags clear + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_DESTINY_BOND); + gStatuses3[gBankAttacker] &= ~(STATUS3_GRUDGE); + gBattleStruct->atkCancellerTracker++; + break; + case 1: // check being asleep + if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) + { + if (UproarWakeUpCheck(gBankAttacker)) + { + gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); + BattleScriptPushCursor(); + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; + effect = 2; + } + else + { + u8 toSub; + if (gBattleMons[gBankAttacker].ability == ABILITY_EARLY_BIRD) + toSub = 2; + else + toSub = 1; + if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) < toSub) + gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP); + else + gBattleMons[gBankAttacker].status1 -= toSub; + if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) + { + if (gCurrentMove != MOVE_SNORE && gCurrentMove != MOVE_SLEEP_TALK) + { + gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 2; + } + } + else + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE); + BattleScriptPushCursor(); + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp; + effect = 2; + } + } + } + gBattleStruct->atkCancellerTracker++; + break; + case 2: // check being frozen + if (gBattleMons[gBankAttacker].status1 & STATUS_FREEZE) + { + if (Random() % 5) + { + if (gBattleMoves[gCurrentMove].effect != EFFECT_THAW_HIT) // unfreezing via a move effect happens in case 13 + { + gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen; + gHitMarker |= HITMARKER_NO_ATTACKSTRING; + } + else + { + gBattleStruct->atkCancellerTracker++; + break; + } + } + else // unfreeze + { + gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + effect = 2; + } + gBattleStruct->atkCancellerTracker++; + break; + case 3: // truant + if (gBattleMons[gBankAttacker].ability == ABILITY_TRUANT && gDisableStructs[gBankAttacker].truantCounter) + { + CancelMultiTurnMoves(gBankAttacker); + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; + gMoveResultFlags |= MOVE_RESULT_MISSED; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 4: // recharge + if (gBattleMons[gBankAttacker].status2 & STATUS2_RECHARGE) + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_RECHARGE); + gDisableStructs[gBankAttacker].rechargeCounter = 0; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 5: // flinch + if (gBattleMons[gBankAttacker].status2 & STATUS2_FLINCHED) + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_FLINCHED); + gProtectStructs[gBankAttacker].flinchImmobility = 1; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedFlinched; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 6: // disabled move + if (gDisableStructs[gBankAttacker].disabledMove == gCurrentMove && gDisableStructs[gBankAttacker].disabledMove != 0) + { + gProtectStructs[gBankAttacker].usedDisabledMove = 1; + gBattleStruct->scriptingActive = gBankAttacker; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsDisabled; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 7: // taunt + if (gDisableStructs[gBankAttacker].tauntTimer1 && gBattleMoves[gCurrentMove].power == 0) + { + gProtectStructs[gBankAttacker].usedTauntedMove = 1; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 8: // imprisoned + if (IsImprisoned(gBankAttacker, gCurrentMove)) + { + gProtectStructs[gBankAttacker].usedImprisionedMove = 1; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 9: // confusion + if (gBattleMons[gBankAttacker].status2 & STATUS2_CONFUSION) + { + gBattleMons[gBankAttacker].status2--; + if (gBattleMons[gBankAttacker].status2 & STATUS2_CONFUSION) + { + if (Random() & 1) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + BattleScriptPushCursor(); + } + else // confusion dmg + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBankTarget = gBankAttacker; + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankAttacker], MOVE_POUND, 0, 40, 0, gBankAttacker, gBankAttacker); + gProtectStructs[gBankAttacker].confusionSelfDmg = 1; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + } + gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfused; + } + else // snapped out of confusion + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfusedNoMore; + } + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 10: // paralysis + if (gBattleMons[gBankAttacker].status1 & STATUS_PARALYSIS && (Random() % 4) == 0) + { + gProtectStructs[gBankAttacker].prlzImmobility = 1; + CancelMultiTurnMoves(gBankAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 11: // infatuation + if (gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) + { + gBattleStruct->scriptingActive = CountTrailingZeroBits((gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) >> 0x10); + if (Random() & 1) + BattleScriptPushCursor(); + else + { + BattleScriptPush(BattleScript_MoveUsedIsParalyzedCantAttack); + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gProtectStructs[gBankAttacker].loveImmobility = 1; + CancelMultiTurnMoves(gBankAttacker); + } + gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 12: // bide + if (gBattleMons[gBankAttacker].status2 & STATUS2_BIDE) + { + gBattleMons[gBankAttacker].status2 -= 0x100; + if (gBattleMons[gBankAttacker].status2 & STATUS2_BIDE) + gBattlescriptCurrInstr = BattleScript_BideStoringEnergy; + else + { + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_MULTIPLETURNS); + if (gTakenDmg[gBankAttacker]) + { + gCurrentMove = MOVE_BIDE; + *bideDmg = gTakenDmg[gBankAttacker] * 2; + gBankTarget = gTakenDmgBanks[gBankAttacker]; + if (gAbsentBattlerFlags & gBitTable[gBankTarget]) + gBankTarget = GetMoveTarget(MOVE_BIDE, 1); + gBattlescriptCurrInstr = BattleScript_BideAttack; + } + else + gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack; + } + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case 13: // move thawing + if (gBattleMons[gBankAttacker].status1 & STATUS_FREEZE) + { + if (gBattleMoves[gCurrentMove].effect == EFFECT_THAW_HIT) + { + gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze; + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + effect = 2; + } + gBattleStruct->atkCancellerTracker++; + break; + case 14: // last case + break; + } + + } while (gBattleStruct->atkCancellerTracker != ATKCANCELLER_MAX_CASE && effect == 0); + + if (effect == 2) + { + gActiveBattler = gBankAttacker; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); + MarkBufferBankForExecution(gActiveBattler); + } + return effect; +} + +bool8 sub_8018018(u8 bank, u8 r1, u8 r2) +{ + struct Pokemon* party; + u8 r7; + u8 r6; + s32 i; + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + return 0; + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + r7 = sub_803FC34(bank); + if (GetBattlerSide(bank) == 0) + party = gPlayerParty; + else + party = gEnemyParty; + r6 = sub_803FBFC(r7); + for (i = r6 * 3; i < r6 * 3 + 3; i++) + { + if (GetMonData(&party[i], MON_DATA_HP) && GetMonData(&party[i], MON_DATA_SPECIES2) && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG) + break; + } + return (i == r6 * 3 + 3); + } + else + { + if (GetBattlerSide(bank) == 1) + { + r7 = GetBattlerAtPosition(1); + r6 = GetBattlerAtPosition(3); + party = gEnemyParty; + } + else + { + r7 = GetBattlerAtPosition(0); + r6 = GetBattlerAtPosition(2); + party = gPlayerParty; + } + if (r1 == 6) + r1 = gBattlerPartyIndexes[r7]; + if (r2 == 6) + r2 = gBattlerPartyIndexes[r6]; + for (i = 0; i < 6; i++) + { + if (GetMonData(&party[i], MON_DATA_HP) && GetMonData(&party[i], MON_DATA_SPECIES2) && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG && i != r1 && i != r2 && i != ewram16068arr(r7) && i != ewram16068arr(r6)) + break; + } + return (i == 6); + } +} + +enum +{ + CASTFORM_NO_CHANGE, //0 + CASTFORM_TO_NORMAL, //1 + CASTFORM_TO_FIRE, //2 + CASTFORM_TO_WATER, //3 + CASTFORM_TO_ICE, //4 +}; + +u8 CastformDataTypeChange(u8 bank) +{ + u8 formChange = 0; + if (gBattleMons[bank].species != SPECIES_CASTFORM || gBattleMons[bank].ability != ABILITY_FORECAST || gBattleMons[bank].hp == 0) + return CASTFORM_NO_CHANGE; + if (!WEATHER_HAS_EFFECT && gBattleMons[bank].type1 != TYPE_NORMAL && gBattleMons[bank].type2 != TYPE_NORMAL) + { + gBattleMons[bank].type1 = TYPE_NORMAL; + gBattleMons[bank].type2 = TYPE_NORMAL; + return CASTFORM_TO_NORMAL; + } + if (!WEATHER_HAS_EFFECT) + return CASTFORM_NO_CHANGE; + if (!(gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SUN_ANY | WEATHER_HAIL)) && gBattleMons[bank].type1 != TYPE_NORMAL && gBattleMons[bank].type2 != TYPE_NORMAL) + { + gBattleMons[bank].type1 = TYPE_NORMAL; + gBattleMons[bank].type2 = TYPE_NORMAL; + formChange = CASTFORM_TO_NORMAL; + } + if (gBattleWeather & WEATHER_SUN_ANY && gBattleMons[bank].type1 != TYPE_FIRE && gBattleMons[bank].type2 != TYPE_FIRE) + { + gBattleMons[bank].type1 = TYPE_FIRE; + gBattleMons[bank].type2 = TYPE_FIRE; + formChange = CASTFORM_TO_FIRE; + } + if (gBattleWeather & WEATHER_RAIN_ANY && gBattleMons[bank].type1 != TYPE_WATER && gBattleMons[bank].type2 != TYPE_WATER) + { + gBattleMons[bank].type1 = TYPE_WATER; + gBattleMons[bank].type2 = TYPE_WATER; + formChange = CASTFORM_TO_WATER; + } + if (gBattleWeather & WEATHER_HAIL && gBattleMons[bank].type1 != TYPE_ICE && gBattleMons[bank].type2 != TYPE_ICE) + { + gBattleMons[bank].type1 = TYPE_ICE; + gBattleMons[bank].type2 = TYPE_ICE; + formChange = CASTFORM_TO_ICE; + } + return formChange; +} + +u8 AbilityBattleEffects(u8 caseID, u8 bank, u8 ability, u8 special, u16 moveArg) +{ + u8 effect = 0; + struct Pokemon* pokeAtk; + struct Pokemon* pokeDef; + u16 speciesAtk; + u16 speciesDef; + u32 pidAtk; + u32 pidDef; + + if (gBankAttacker >= gBattlersCount) + gBankAttacker = bank; + if (GetBattlerSide(gBankAttacker) == 0) + pokeAtk = &gPlayerParty[gBattlerPartyIndexes[gBankAttacker]]; + else + pokeAtk = &gEnemyParty[gBattlerPartyIndexes[gBankAttacker]]; + + if (gBankTarget >= gBattlersCount) + gBankTarget = bank; + if (GetBattlerSide(gBankTarget) == 0) + pokeDef = &gPlayerParty[gBattlerPartyIndexes[gBankTarget]]; + else + pokeDef = &gEnemyParty[gBattlerPartyIndexes[gBankTarget]]; + + speciesAtk = GetMonData(pokeAtk, MON_DATA_SPECIES); + pidAtk = GetMonData(pokeAtk, MON_DATA_PERSONALITY); + + speciesDef = GetMonData(pokeDef, MON_DATA_SPECIES); + pidDef = GetMonData(pokeDef, MON_DATA_PERSONALITY); + + if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) // why isn't that check done at the beginning? + { + u8 moveType; + s32 i; + u16 move; + u8 side; + u8 target1; + + if (special) + gLastUsedAbility = special; + else + gLastUsedAbility = gBattleMons[bank].ability; + + if (moveArg) + move = moveArg; + else + move = gCurrentMove; + + if (gBattleStruct->dynamicMoveType) + moveType = gBattleStruct->dynamicMoveType & 0x3F; + else + moveType = gBattleMoves[move].type; + + switch (caseID) + { + case ABILITYEFFECT_ON_SWITCHIN: // 0 + if (gBankAttacker >= gBattlersCount) + gBankAttacker = bank; + switch (gLastUsedAbility) + { + case 0xFF: //weather from overworld + switch (GetCurrentWeather()) + { + case WEATHER_RAIN_LIGHT: + case WEATHER_RAIN_MED: + case WEATHER_RAIN_HEAVY: + if (!(gBattleWeather & WEATHER_RAIN_ANY)) + { + gBattleWeather = (WEATHER_RAIN_TEMPORARY | WEATHER_RAIN_PERMANENT); + gBattleStruct->animArg1 = B_ANIM_RAIN_CONTINUES; + gBattleStruct->scriptingActive = bank; + effect++; + } + break; + case WEATHER_SANDSTORM: + if (!(gBattleWeather & WEATHER_SANDSTORM_ANY)) + { + gBattleWeather = (WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY); + gBattleStruct->animArg1 = B_ANIM_SANDSTORM_CONTINUES; + gBattleStruct->scriptingActive = bank; + effect++; + } + break; + case WEATHER_DROUGHT: + if (!(gBattleWeather & WEATHER_SUN_ANY)) + { + gBattleWeather = (WEATHER_SUN_PERMANENT | WEATHER_SUN_TEMPORARY); + gBattleStruct->animArg1 = B_ANIM_SUN_CONTINUES; + gBattleStruct->scriptingActive = bank; + effect++; + } + break; + } + if (effect) + { + gBattleCommunication[MULTISTRING_CHOOSER] = GetCurrentWeather(); + BattleScriptPushCursorAndCallback(BattleScript_OverworldWeatherStarts); + } + break; + case ABILITY_DRIZZLE: + if (!(gBattleWeather & WEATHER_RAIN_PERMANENT)) + { + gBattleWeather = (WEATHER_RAIN_PERMANENT | WEATHER_RAIN_TEMPORARY); + BattleScriptPushCursorAndCallback(BattleScript_DrizzleActivates); + gBattleStruct->scriptingActive = bank; + effect++; + } + break; + case ABILITY_SAND_STREAM: + if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT)) + { + gBattleWeather = (WEATHER_SANDSTORM_PERMANENT | WEATHER_SANDSTORM_TEMPORARY); + BattleScriptPushCursorAndCallback(BattleScript_SandstreamActivates); + gBattleStruct->scriptingActive = bank; + effect++; + } + break; + case ABILITY_DROUGHT: + if (!(gBattleWeather & WEATHER_SUN_PERMANENT)) + { + gBattleWeather = (WEATHER_SUN_PERMANENT | WEATHER_SUN_TEMPORARY); + BattleScriptPushCursorAndCallback(BattleScript_DroughtActivates); + gBattleStruct->scriptingActive = bank; + effect++; + } + break; + case ABILITY_INTIMIDATE: + if (!(gSpecialStatuses[bank].intimidatedPoke)) + { + gStatuses3[bank] |= STATUS3_INTIMIDATE_POKES; + gSpecialStatuses[bank].intimidatedPoke = 1; + } + break; + case ABILITY_FORECAST: + effect = CastformDataTypeChange(bank); + if (effect != 0) + { + BattleScriptPushCursorAndCallback(BattleScript_CastformChange); + gBattleStruct->scriptingActive = bank; + gBattleStruct->castformToChangeInto = effect - 1; + } + break; + case ABILITY_TRACE: + if (!(gSpecialStatuses[bank].traced)) + { + gStatuses3[bank] |= STATUS3_TRACE; + gSpecialStatuses[bank].traced = 1; + } + break; + case ABILITY_CLOUD_NINE: + case ABILITY_AIR_LOCK: + { + // that's a weird choice for a variable, why not use i or bank? + for (target1 = 0; target1 < gBattlersCount; target1++) + { + effect = CastformDataTypeChange(target1); + if (effect != 0) + { + BattleScriptPushCursorAndCallback(BattleScript_CastformChange); + gBattleStruct->scriptingActive = target1; + gBattleStruct->castformToChangeInto = effect - 1; + break; + } + } + } + break; + } + break; + case ABILITYEFFECT_ENDTURN: // 1 + if (gBattleMons[bank].hp != 0) + { + gBankAttacker = bank; + switch (gLastUsedAbility) + { + case ABILITY_RAIN_DISH: + if (WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_RAIN_ANY) + && gBattleMons[bank].maxHP > gBattleMons[bank].hp) + { + gLastUsedAbility = ABILITY_RAIN_DISH; // why + BattleScriptPushCursorAndCallback(BattleScript_RainDishActivates); + gBattleMoveDamage = gBattleMons[bank].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + effect++; + } + break; + case ABILITY_SHED_SKIN: + if ((gBattleMons[bank].status1 & STATUS_ANY) && (Random() % 3) == 0) + { + if (gBattleMons[bank].status1 & (STATUS_POISON | STATUS_TOXIC_POISON)) + StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); + if (gBattleMons[bank].status1 & STATUS_SLEEP) + StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); + if (gBattleMons[bank].status1 & STATUS_PARALYSIS) + StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); + if (gBattleMons[bank].status1 & STATUS_BURN) + StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); + if (gBattleMons[bank].status1 & STATUS_FREEZE) + StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); + gBattleMons[bank].status1 = 0; + // BUG: The nightmare status does not get cleared here. This was fixed in Emerald. + //gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + gBattleStruct->scriptingActive = gActiveBattler = bank; + BattleScriptPushCursorAndCallback(BattleScript_ShedSkinActivates); + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1); + MarkBufferBankForExecution(gActiveBattler); + effect++; + } + break; + case ABILITY_SPEED_BOOST: + if (gBattleMons[bank].statStages[STAT_STAGE_SPEED] < 0xC && gDisableStructs[bank].isFirstTurn != 2) + { + gBattleMons[bank].statStages[STAT_STAGE_SPEED]++; + gBattleStruct->animArg1 = 0x11; + gBattleStruct->animArg2 = 0; + BattleScriptPushCursorAndCallback(BattleScript_SpeedBoostActivates); + gBattleStruct->scriptingActive = bank; + effect++; + } + break; + case ABILITY_TRUANT: + gDisableStructs[gBankAttacker].truantCounter ^= 1; + break; + } + } + break; + case ABILITYEFFECT_MOVES_BLOCK: // 2 + if (gLastUsedAbility == ABILITY_SOUNDPROOF) + { + for (i = 0; gSoundMovesTable[i] != 0xFFFF; i++) + { + if (gSoundMovesTable[i] == move) + break; + } + if (gSoundMovesTable[i] != 0xFFFF) + { + if (gBattleMons[gBankAttacker].status2 & STATUS2_MULTIPLETURNS) + gHitMarker |= HITMARKER_NO_PPDEDUCT; + gBattlescriptCurrInstr = BattleScript_SoundproofProtected; + effect = 1; + } + } + break; + case ABILITYEFFECT_ABSORBING: // 3 + if (move) + { + switch (gLastUsedAbility) + { + case ABILITY_VOLT_ABSORB: + if (moveType == TYPE_ELECTRIC && gBattleMoves[move].power != 0) + { + if (gProtectStructs[gBankAttacker].notFirstStrike) + gBattlescriptCurrInstr = BattleScript_MoveHPDrain; + else + gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss; + effect = 1; + } + break; + case ABILITY_WATER_ABSORB: + if (moveType == TYPE_WATER && gBattleMoves[move].power != 0) + { + if (gProtectStructs[gBankAttacker].notFirstStrike) + gBattlescriptCurrInstr = BattleScript_MoveHPDrain; + else + gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss; + effect = 1; + } + break; + case ABILITY_FLASH_FIRE: + if (moveType == TYPE_FIRE && !(gBattleMons[bank].status1 & STATUS_FREEZE)) + { + if (!(eFlashFireArr.arr[bank] & 1)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + if (gProtectStructs[gBankAttacker].notFirstStrike) + gBattlescriptCurrInstr = BattleScript_FlashFireBoost; + else + gBattlescriptCurrInstr = BattleScript_FlashFireBoost_PPLoss; + eFlashFireArr.arr[bank] |= 1; + effect = 2; + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + if (gProtectStructs[gBankAttacker].notFirstStrike) + gBattlescriptCurrInstr = BattleScript_FlashFireBoost; + else + gBattlescriptCurrInstr = BattleScript_FlashFireBoost_PPLoss; + effect = 2; + } + } + break; + } + if (effect == 1) + { + if (gBattleMons[bank].maxHP == gBattleMons[bank].hp) + { + if ((gProtectStructs[gBankAttacker].notFirstStrike)) + gBattlescriptCurrInstr = BattleScript_MoveHPDrain_FullHP; + else + gBattlescriptCurrInstr = BattleScript_MoveHPDrain_FullHP_PPLoss; + } + else + { + gBattleMoveDamage = gBattleMons[bank].maxHP / 4; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + gBattleMoveDamage *= -1; + } + } + } + break; + case ABILITYEFFECT_CONTACT: // 4 + switch (gLastUsedAbility) + { + case ABILITY_COLOR_CHANGE: + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && move != MOVE_STRUGGLE + && gBattleMoves[move].power != 0 + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && gBattleMons[bank].type1 != moveType + && gBattleMons[bank].type2 != moveType + && gBattleMons[bank].hp != 0) + { + gBattleMons[bank].type1 = moveType; + gBattleMons[bank].type2 = moveType; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 3; + gBattleTextBuff1[2] = moveType; + gBattleTextBuff1[3] = 0xFF; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ColorChangeActivates; + effect++; + } + break; + case ABILITY_ROUGH_SKIN: + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (gBattleMoves[move].flags & F_MAKES_CONTACT)) + { + gBattleMoveDamage = gBattleMons[gBankAttacker].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_RoughSkinActivates; + effect++; + } + break; + case ABILITY_EFFECT_SPORE: + if (DEBUG && (gUnknown_02023A14_50 & 4)) + { + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (gBattleMoves[move].flags & F_MAKES_CONTACT)) + { + do + { + gBattleCommunication[MOVE_EFFECT_BYTE] = Random() & 3; + } while (gBattleCommunication[MOVE_EFFECT_BYTE] == 0); + if (gBattleCommunication[MOVE_EFFECT_BYTE] == 3) + gBattleCommunication[MOVE_EFFECT_BYTE] += 2; + gBattleCommunication[MOVE_EFFECT_BYTE] += 0x40; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + } + else + { + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (gBattleMoves[move].flags & F_MAKES_CONTACT) + && (Random() % 10) == 0) + { + do + { + gBattleCommunication[MOVE_EFFECT_BYTE] = Random() & 3; + } while (gBattleCommunication[MOVE_EFFECT_BYTE] == 0); + if (gBattleCommunication[MOVE_EFFECT_BYTE] == 3) + gBattleCommunication[MOVE_EFFECT_BYTE] += 2; + gBattleCommunication[MOVE_EFFECT_BYTE] += 0x40; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + } + break; + case ABILITY_POISON_POINT: + if (DEBUG && (gUnknown_02023A14_50 & 4)) + { + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (gBattleMoves[move].flags & F_MAKES_CONTACT)) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0x42; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + } + else + { + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (gBattleMoves[move].flags & F_MAKES_CONTACT) + && (Random() % 3) == 0) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0x42; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + } + break; + case ABILITY_STATIC: + if (DEBUG && (gUnknown_02023A14_50 & 4)) + { + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (gBattleMoves[move].flags & F_MAKES_CONTACT)) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0x45; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + } + else + { + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (gBattleMoves[move].flags & F_MAKES_CONTACT) + && (Random() % 3) == 0) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0x45; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + } + break; + case ABILITY_FLAME_BODY: + if (DEBUG && (gUnknown_02023A14_50 & 4)) + { + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gBattleMoves[move].flags & F_MAKES_CONTACT) + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special)) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0x43; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + } + else + { + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gBattleMoves[move].flags & F_MAKES_CONTACT) + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (Random() % 3) == 0) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 0x43; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ApplySecondaryEffect; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + } + break; + case ABILITY_CUTE_CHARM: + if (DEBUG && (gUnknown_02023A14_50 & 4)) + { + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gBattleMoves[move].flags & F_MAKES_CONTACT) + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && gBattleMons[gBankTarget].hp != 0 + && gBattleMons[gBankAttacker].ability != ABILITY_OBLIVIOUS + && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) + && !(gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) + && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != 0xFF + && GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) != 0xFF) + { + gBattleMons[gBankAttacker].status2 |= (gBitTable[gBankTarget] << 0x10); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_CuteCharmActivates; + effect++; + } + } + else + { + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && gBattleMons[gBankAttacker].hp != 0 + && !gProtectStructs[gBankAttacker].confusionSelfDmg + && (gBattleMoves[move].flags & F_MAKES_CONTACT) + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && gBattleMons[gBankTarget].hp != 0 + && (Random() % 3) == 0 + && gBattleMons[gBankAttacker].ability != ABILITY_OBLIVIOUS + && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) + && !(gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) + && GetGenderFromSpeciesAndPersonality(speciesAtk, pidAtk) != 0xFF + && GetGenderFromSpeciesAndPersonality(speciesDef, pidDef) != 0xFF) + { + gBattleMons[gBankAttacker].status2 |= (gBitTable[gBankTarget] << 0x10); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_CuteCharmActivates; + effect++; + } + } + break; + } + break; + case ABILITYEFFECT_IMMUNITY: // 5 + { + for (bank = 0; bank < gBattlersCount; bank++) + { + switch (gBattleMons[bank].ability) + { + case ABILITY_IMMUNITY: + if (gBattleMons[bank].status1 & (STATUS_POISON | STATUS_TOXIC_POISON | 0xF00)) // TODO: what is 0xF00? + { + StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); + effect = 1; + } + break; + case ABILITY_OWN_TEMPO: + if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn); + effect = 2; + } + break; + case ABILITY_LIMBER: + if (gBattleMons[bank].status1 & STATUS_PARALYSIS) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); + effect = 1; + } + break; + case ABILITY_INSOMNIA: + case ABILITY_VITAL_SPIRIT: + if (gBattleMons[bank].status1 & STATUS_SLEEP) + { + gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); + effect = 1; + } + break; + case ABILITY_WATER_VEIL: + if (gBattleMons[bank].status1 & STATUS_BURN) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); + effect = 1; + } + break; + case ABILITY_MAGMA_ARMOR: + if (gBattleMons[bank].status1 & STATUS_FREEZE) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); + effect = 1; + } + break; + case ABILITY_OBLIVIOUS: + if (gBattleMons[bank].status2 & STATUS2_INFATUATION) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); + effect = 3; + } + break; + } + if (effect) + { + switch (effect) + { + case 1: // status cleared + gBattleMons[bank].status1 = 0; + break; + case 2: // get rid of confusion + gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + break; + case 3: // get rid of infatuation + gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION); + break; + } + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_AbilityCuredStatus; + gBattleStruct->scriptingActive = bank; + gActiveBattler = bank; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); + MarkBufferBankForExecution(gActiveBattler); + return effect; + } + } + } + break; + case ABILITYEFFECT_FORECAST: // 6 + { + for (bank = 0; bank < gBattlersCount; bank++) + { + if (gBattleMons[bank].ability == ABILITY_FORECAST) + { + effect = CastformDataTypeChange(bank); + if (effect) + { + BattleScriptPushCursorAndCallback(BattleScript_CastformChange); + gBattleStruct->scriptingActive = bank; + gBattleStruct->castformToChangeInto = effect - 1; + return effect; + } + } + } + } + break; + case ABILITYEFFECT_SYNCHRONIZE: // 7 + if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONISE_EFFECT)) + { + gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT); + gBattleStruct->synchroniseEffect &= 0x3F; + if (gBattleStruct->synchroniseEffect == 6) + gBattleStruct->synchroniseEffect = 2; + gBattleCommunication[MOVE_EFFECT_BYTE] = gBattleStruct->synchroniseEffect + 0x40; + gBattleStruct->scriptingActive = gBankTarget; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_SynchronizeActivates; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + break; + case ABILITYEFFECT_ATK_SYNCHRONIZE: // 8 + if (gLastUsedAbility == ABILITY_SYNCHRONIZE && (gHitMarker & HITMARKER_SYNCHRONISE_EFFECT)) + { + gHitMarker &= ~(HITMARKER_SYNCHRONISE_EFFECT); + gBattleStruct->synchroniseEffect &= 0x3F; + if (gBattleStruct->synchroniseEffect == 6) + gBattleStruct->synchroniseEffect = 2; + gBattleCommunication[MOVE_EFFECT_BYTE] = gBattleStruct->synchroniseEffect; + gBattleStruct->scriptingActive = gBankAttacker; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_SynchronizeActivates; + gHitMarker |= HITMARKER_IGNORE_SAFEGUARD; + effect++; + } + break; + case ABILITYEFFECT_INTIMIDATE1: // 9 + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].ability == ABILITY_INTIMIDATE && gStatuses3[i] & STATUS3_INTIMIDATE_POKES) + { + gLastUsedAbility = ABILITY_INTIMIDATE; + gStatuses3[i] &= ~(STATUS3_INTIMIDATE_POKES); + BattleScriptPushCursorAndCallback(gUnknown_081D978C); + gBattleStruct->intimidateBank = i; + effect++; + break; + } + } + break; + case ABILITYEFFECT_TRACE: // 11 + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].ability == ABILITY_TRACE && (gStatuses3[i] & STATUS3_TRACE)) + { + u8 target2; + side = (GetBattlerPosition(i) ^ 1) & 1; + target1 = GetBattlerAtPosition(side); + target2 = GetBattlerAtPosition(side + 2); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + if (gBattleMons[target1].ability != 0 && gBattleMons[target1].hp != 0 + && gBattleMons[target2].ability != 0 && gBattleMons[target2].hp != 0) + { + gActiveBattler = GetBattlerAtPosition(((Random() & 1) * 2) | side); + gBattleMons[i].ability = gBattleMons[gActiveBattler].ability; + gLastUsedAbility = gBattleMons[gActiveBattler].ability; + effect++; + } + else if (gBattleMons[target1].ability != 0 && gBattleMons[target1].hp != 0) + { + gActiveBattler = target1; + gBattleMons[i].ability = gBattleMons[gActiveBattler].ability; + gLastUsedAbility = gBattleMons[gActiveBattler].ability; + effect++; + } + else if (gBattleMons[target2].ability != 0 && gBattleMons[target2].hp != 0) + { + gActiveBattler = target2; + gBattleMons[i].ability = gBattleMons[gActiveBattler].ability; + gLastUsedAbility = gBattleMons[gActiveBattler].ability; + effect++; + } + } + else + { + gActiveBattler = target1; + if (gBattleMons[target1].ability && gBattleMons[target1].hp) + { + gBattleMons[i].ability = gBattleMons[target1].ability; + gLastUsedAbility = gBattleMons[target1].ability; + effect++; + } + } + if (effect) + { + BattleScriptPushCursorAndCallback(BattleScript_TraceActivates); + gStatuses3[i] &= ~(STATUS3_TRACE); + gBattleStruct->scriptingActive = i; + + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 4; + gBattleTextBuff1[2] = gActiveBattler; + gBattleTextBuff1[3] = gBattlerPartyIndexes[gActiveBattler]; + gBattleTextBuff1[4] = EOS; + + gBattleTextBuff2[0] = 0xFD; + gBattleTextBuff2[1] = 9; + gBattleTextBuff2[2] = gLastUsedAbility; + gBattleTextBuff2[3] = EOS; + break; + } + } + } + break; + case ABILITYEFFECT_INTIMIDATE2: // 10 + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].ability == ABILITY_INTIMIDATE && (gStatuses3[i] & STATUS3_INTIMIDATE_POKES)) + { + gLastUsedAbility = ABILITY_INTIMIDATE; + gStatuses3[i] &= ~(STATUS3_INTIMIDATE_POKES); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = gUnknown_081D9795; + gBattleStruct->intimidateBank = i; + effect++; + break; + } + } + break; + case ABILITYEFFECT_CHECK_OTHER_SIDE: // 12 + side = GetBattlerSide(bank); + for (i = 0; i < gBattlersCount; i++) + { + if (GetBattlerSide(i) != side && gBattleMons[i].ability == ability) + { + gLastUsedAbility = ability; + effect = i + 1; + } + } + break; + case ABILITYEFFECT_CHECK_BANK_SIDE: // 13 + side = GetBattlerSide(bank); + for (i = 0; i < gBattlersCount; i++) + { + if (GetBattlerSide(i) == side && gBattleMons[i].ability == ability) + { + gLastUsedAbility = ability; + effect = i + 1; + } + } + break; + case ABILITYEFFECT_FIELD_SPORT: // 14 + switch (gLastUsedAbility) + { + case 0xFD: + for (i = 0; i < gBattlersCount; i++) + { + if (gStatuses3[i] & STATUS3_MUDSPORT) + effect = i + 1; + } + break; + case 0xFE: + for (i = 0; i < gBattlersCount; i++) + { + if (gStatuses3[i] & STATUS3_WATERSPORT) + effect = i + 1; + } + break; + default: + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].ability == ability) + { + gLastUsedAbility = ability; + effect = i + 1; + } + } + break; + } + break; + case ABILITYEFFECT_CHECK_ON_FIELD: // 19 + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].ability == ability && gBattleMons[i].hp != 0) + { + gLastUsedAbility = ability; + effect = i + 1; + } + } + break; + case ABILITYEFFECT_CHECK_FIELD_EXCEPT_BANK: // 15 + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].ability == ability && i != bank) + { + gLastUsedAbility = ability; + effect = i + 1; + } + } + break; + case ABILITYEFFECT_COUNT_OTHER_SIZE: // 16 + side = GetBattlerSide(bank); + for (i = 0; i < gBattlersCount; i++) + { + if (GetBattlerSide(i) != side && gBattleMons[i].ability == ability) + { + gLastUsedAbility = ability; + effect++; + } + } + break; + case ABILITYEFFECT_COUNT_BANK_SIDE: // 17 + side = GetBattlerSide(bank); + for (i = 0; i < gBattlersCount; i++) + { + if (GetBattlerSide(i) == side && gBattleMons[i].ability == ability) + { + gLastUsedAbility = ability; + effect++; + } + } + break; + case ABILITYEFFECT_COUNT_ON_FIELD: // 18 + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].ability == ability && i != bank) + { + gLastUsedAbility = ability; + effect++; + } + } + break; + } + if (effect && caseID < 0xC && gLastUsedAbility != 0xFF) + RecordAbilityBattle(bank, gLastUsedAbility); + } + + return effect; +} + +void BattleScriptExecute(const u8* BS_ptr) +{ + gBattlescriptCurrInstr = BS_ptr; + B_FUNCTION_STACK->ptr[B_FUNCTION_STACK->size++] = gBattleMainFunc; + gBattleMainFunc = RunBattleScriptCommands_PopCallbacksStack; + gCurrentActionFuncId = 0; +} + +void BattleScriptPushCursorAndCallback(u8* BS_ptr) +{ + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BS_ptr; + B_FUNCTION_STACK->ptr[B_FUNCTION_STACK->size++] = gBattleMainFunc; + gBattleMainFunc = RunBattleScriptCommands; +} + +enum +{ + ITEM_NO_EFFECT, // 0 + ITEM_STATUS_CHANGE, // 1 + ITEM_EFFECT_OTHER, // 2 + ITEM_PP_CHANGE, // 3 + ITEM_HP_CHANGE, // 4 + ITEM_STATS_CHANGE, // 5 +}; + +enum +{ + FLAVOR_SPICY, // 0 + FLAVOR_DRY, // 1 + FLAVOR_SWEET, // 2 + FLAVOR_BITTER, // 3 + FLAVOR_SOUR, // 4 +}; + +u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn) +{ + int i = 0; + u8 effect = ITEM_NO_EFFECT; + u8 changedPP = 0; + u8 bankHoldEffect, atkHoldEffect, defHoldEffect; + u8 bankQuality, atkQuality, defQuality; + u16 atkItem, defItem; + + gLastUsedItem = gBattleMons[bank].item; + if (gLastUsedItem == ITEM_ENIGMA_BERRY) + { + bankHoldEffect = gEnigmaBerries[bank].holdEffect; + bankQuality = gEnigmaBerries[bank].holdEffectParam; + } + else + { + bankHoldEffect = ItemId_GetHoldEffect(gLastUsedItem); + bankQuality = ItemId_GetHoldEffectParam(gLastUsedItem); + } + + atkItem = gBattleMons[gBankAttacker].item; + if (atkItem == ITEM_ENIGMA_BERRY) + { + atkHoldEffect = gEnigmaBerries[gBankAttacker].holdEffect; + atkQuality = gEnigmaBerries[gBankAttacker].holdEffectParam; + } + else + { + atkHoldEffect = ItemId_GetHoldEffect(atkItem); + atkQuality = ItemId_GetHoldEffectParam(atkItem); + } + + // def variables are unused + defItem = gBattleMons[gBankTarget].item; + if (defItem == ITEM_ENIGMA_BERRY) + { + defHoldEffect = gEnigmaBerries[gBankTarget].holdEffect; + defQuality = gEnigmaBerries[gBankTarget].holdEffectParam; + } + else + { + defHoldEffect = ItemId_GetHoldEffect(defItem); + defQuality = ItemId_GetHoldEffectParam(defItem); + } + + switch (caseID) + { + case 0: + switch (bankHoldEffect) + { + case HOLD_EFFECT_DOUBLE_PRIZE: + gBattleStruct->moneyMultiplier = 2; + break; + case HOLD_EFFECT_RESTORE_STATS: + for (i = 0; i < 8; i++) + { + if (gBattleMons[bank].statStages[i] < 6) + { + gBattleMons[bank].statStages[i] = 6; + effect = ITEM_STATS_CHANGE; + } + } + if (effect) + { + gBattleStruct->scriptingActive = bank; + gStringBank = bank; + gActiveBattler = gBankAttacker = bank; + BattleScriptExecute(BattleScript_WhiteHerbEnd2); + } + break; + } + break; + case 1: + if (gBattleMons[bank].hp) + { + switch (bankHoldEffect) + { + case HOLD_EFFECT_RESTORE_HP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + { + gBattleMoveDamage = bankQuality; + if (gBattleMons[bank].hp + bankQuality > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); + effect = 4; + } + break; + case HOLD_EFFECT_RESTORE_PP: + if (!moveTurn) + { + struct Pokemon* poke; + u8 ppBonuses; + u16 move; + + if (GetBattlerSide(bank) == 0) + poke = &gPlayerParty[gBattlerPartyIndexes[bank]]; + else + poke = &gEnemyParty[gBattlerPartyIndexes[bank]]; + for (i = 0; i < 4; i++) + { + move = GetMonData(poke, MON_DATA_MOVE1 + i); + changedPP = GetMonData(poke, MON_DATA_PP1 + i); + ppBonuses = GetMonData(poke, MON_DATA_PP_BONUSES); + if (move && changedPP == 0) + break; + } + if (i != 4) + { + u8 maxPP = CalculatePPWithBonus(move, ppBonuses, i); + if (changedPP + bankQuality > maxPP) + changedPP = maxPP; + else + changedPP = changedPP + bankQuality; + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 2; + gBattleTextBuff1[2] = move; + gBattleTextBuff1[3] = move >> 8; + gBattleTextBuff1[4] = 0xFF; + BattleScriptExecute(BattleScript_BerryPPHealEnd2); + EmitSetMonData(0, i + REQUEST_PPMOVE1_BATTLE, 0, 1, &changedPP); + MarkBufferBankForExecution(gActiveBattler); + effect = ITEM_PP_CHANGE; + } + } + break; + case HOLD_EFFECT_RESTORE_STATS: + for (i = 0; i < 8; i++) + { + if (gBattleMons[bank].statStages[i] < 6) + { + gBattleMons[bank].statStages[i] = 6; + effect = ITEM_STATS_CHANGE; + } + } + if (effect) + { + gBattleStruct->scriptingActive = bank; + gStringBank = bank; + gActiveBattler = gBankAttacker = bank; + BattleScriptExecute(BattleScript_WhiteHerbEnd2); + } + break; + case HOLD_EFFECT_LEFTOVERS: + if (gBattleMons[bank].hp < gBattleMons[bank].maxHP && !moveTurn) + { + gBattleMoveDamage = gBattleMons[bank].maxHP / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + BattleScriptExecute(BattleScript_ItemHealHP_End2); + effect = ITEM_HP_CHANGE; + RecordItemBattle(bank, bankHoldEffect); + } + break; + // nice copy/paste there gamefreak, making a function for confuse berries was too much eh? + case HOLD_EFFECT_CONFUSE_SPICY: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 8; + gBattleTextBuff1[2] = FLAVOR_SPICY; + gBattleTextBuff1[3] = EOS; + gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_SPICY) < 0) + BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); + else + BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); + effect = ITEM_HP_CHANGE; + } + break; + case HOLD_EFFECT_CONFUSE_DRY: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 8; + gBattleTextBuff1[2] = FLAVOR_DRY; + gBattleTextBuff1[3] = EOS; + gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_DRY) < 0) + BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); + else + BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); + effect = ITEM_HP_CHANGE; + } + break; + case HOLD_EFFECT_CONFUSE_SWEET: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 8; + gBattleTextBuff1[2] = FLAVOR_SWEET; + gBattleTextBuff1[3] = EOS; + gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_SWEET) < 0) + BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); + else + BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); + effect = ITEM_HP_CHANGE; + } + break; + case HOLD_EFFECT_CONFUSE_BITTER: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 8; + gBattleTextBuff1[2] = FLAVOR_BITTER; + gBattleTextBuff1[3] = EOS; + gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_BITTER) < 0) + BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); + else + BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); + effect = ITEM_HP_CHANGE; + } + break; + case HOLD_EFFECT_CONFUSE_SOUR: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / 2 && !moveTurn) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 8; + gBattleTextBuff1[2] = FLAVOR_SOUR; + gBattleTextBuff1[3] = EOS; + gBattleMoveDamage = gBattleMons[bank].maxHP / bankQuality; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + if (gBattleMons[bank].hp + gBattleMoveDamage > gBattleMons[bank].maxHP) + gBattleMoveDamage = gBattleMons[bank].maxHP - gBattleMons[bank].hp; + gBattleMoveDamage *= -1; + if (GetPokeFlavourRelation(gBattleMons[bank].personality, FLAVOR_SOUR) < 0) + BattleScriptExecute(BattleScript_BerryConfuseHealEnd2); + else + BattleScriptExecute(BattleScript_ItemHealHP_RemoveItem); + effect = ITEM_HP_CHANGE; + } + break; + // copy/paste again, smh + case HOLD_EFFECT_ATTACK_UP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_ATK] < 0xC) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 5; + gBattleTextBuff1[2] = STAT_STAGE_ATK; + gBattleTextBuff1[3] = EOS; + + gBattleTextBuff2[0] = 0xFD; + gBattleTextBuff2[1] = 0; + gBattleTextBuff2[2] = 0xD2; + gBattleTextBuff2[3] = 0xD2 >> 8; + gBattleTextBuff2[4] = EOS; + + gEffectBank = bank; + gBattleStruct->statChanger = 0x10 + STAT_STAGE_ATK; + gBattleStruct->animArg1 = 0xE + STAT_STAGE_ATK; + gBattleStruct->animArg2 = 0; + BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); + effect = ITEM_STATS_CHANGE; + } + break; + case HOLD_EFFECT_DEFENSE_UP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_DEF] < 0xC) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 5; + gBattleTextBuff1[2] = STAT_STAGE_DEF; + gBattleTextBuff1[3] = EOS; + + gEffectBank = bank; + gBattleStruct->statChanger = 0x10 + STAT_STAGE_DEF; + gBattleStruct->animArg1 = 0xE + STAT_STAGE_DEF; + gBattleStruct->animArg2 = 0; + BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); + effect = ITEM_STATS_CHANGE; + } + break; + case HOLD_EFFECT_SPEED_UP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPEED] < 0xC) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 5; + gBattleTextBuff1[2] = STAT_STAGE_SPEED; + gBattleTextBuff1[3] = EOS; + + gEffectBank = bank; + gBattleStruct->statChanger = 0x10 + STAT_STAGE_SPEED; + gBattleStruct->animArg1 = 0xE + STAT_STAGE_SPEED; + gBattleStruct->animArg2 = 0; + BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); + effect = ITEM_STATS_CHANGE; + } + break; + case HOLD_EFFECT_SP_ATTACK_UP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPATK] < 0xC) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 5; + gBattleTextBuff1[2] = STAT_STAGE_SPATK; + gBattleTextBuff1[3] = EOS; + + gEffectBank = bank; + gBattleStruct->statChanger = 0x10 + STAT_STAGE_SPATK; + gBattleStruct->animArg1 = 0xE + STAT_STAGE_SPATK; + gBattleStruct->animArg2 = 0; + BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); + effect = ITEM_STATS_CHANGE; + } + break; + case HOLD_EFFECT_SP_DEFENSE_UP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && gBattleMons[bank].statStages[STAT_STAGE_SPDEF] < 0xC) + { + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 5; + gBattleTextBuff1[2] = STAT_STAGE_SPDEF; + gBattleTextBuff1[3] = EOS; + + gEffectBank = bank; + gBattleStruct->statChanger = 0x10 + STAT_STAGE_SPDEF; + gBattleStruct->animArg1 = 0xE + STAT_STAGE_SPDEF; + gBattleStruct->animArg2 = 0; + BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); + effect = ITEM_STATS_CHANGE; + } + break; + case HOLD_EFFECT_CRITICAL_UP: + if (gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality && !moveTurn && !(gBattleMons[bank].status2 & STATUS2_FOCUS_ENERGY)) + { + gBattleMons[bank].status2 |= STATUS2_FOCUS_ENERGY; + BattleScriptExecute(BattleScript_BerryFocusEnergyEnd2); + effect = ITEM_EFFECT_OTHER; + } + break; + case HOLD_EFFECT_RANDOM_STAT_UP: + if (!moveTurn && gBattleMons[bank].hp <= gBattleMons[bank].maxHP / bankQuality) + { + for (i = 0; i < 5; i++) + { + if (gBattleMons[bank].statStages[STAT_STAGE_ATK + i] < 0xC) + break; + } + if (i != 5) + { + do + { + i = Random() % 5; + } while (gBattleMons[bank].statStages[STAT_STAGE_ATK + i] == 0xC); + + gBattleTextBuff1[0] = 0xFD; + gBattleTextBuff1[1] = 5; + gBattleTextBuff1[2] = i + 1; + gBattleTextBuff1[3] = EOS; + + gBattleTextBuff2[0] = 0xFD; + gBattleTextBuff2[1] = 0; + gBattleTextBuff2[2] = 0xD1; + gBattleTextBuff2[3] = 0xD1 >> 8; + gBattleTextBuff2[4] = 0; + gBattleTextBuff2[5] = 0xD2; + gBattleTextBuff2[6] = 0xD2 >> 8; + gBattleTextBuff2[7] = EOS; + + gEffectBank = bank; + gBattleStruct->statChanger = 0x21 + i; + gBattleStruct->animArg1 = 0x21 + i + 6; + gBattleStruct->animArg2 = 0; + BattleScriptExecute(BattleScript_BerryStatRaiseEnd2); + effect = ITEM_STATS_CHANGE; + } + } + break; + case HOLD_EFFECT_CURE_PAR: + if (gBattleMons[bank].status1 & STATUS_PARALYSIS) + { + gBattleMons[bank].status1 &= ~(STATUS_PARALYSIS); + BattleScriptExecute(BattleScript_BerryCurePrlzEnd2); + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_PSN: + if (gBattleMons[bank].status1 & STATUS_PSN_ANY) + { + gBattleMons[bank].status1 &= ~(STATUS_PSN_ANY | STATUS_TOXIC_COUNTER); + BattleScriptExecute(BattleScript_BerryCurePsnEnd2); + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_BRN: + if (gBattleMons[bank].status1 & STATUS_BURN) + { + gBattleMons[bank].status1 &= ~(STATUS_BURN); + BattleScriptExecute(BattleScript_BerryCureBrnEnd2); + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_FRZ: + if (gBattleMons[bank].status1 & STATUS_FREEZE) + { + gBattleMons[bank].status1 &= ~(STATUS_FREEZE); + BattleScriptExecute(BattleScript_BerryCureFrzEnd2); + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_SLP: + if (gBattleMons[bank].status1 & STATUS_SLEEP) + { + gBattleMons[bank].status1 &= ~(STATUS_SLEEP); + gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + BattleScriptExecute(BattleScript_BerryCureSlpEnd2); + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_CONFUSION: + if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + BattleScriptExecute(BattleScript_BerryCureConfusionEnd2); + effect = ITEM_EFFECT_OTHER; + } + break; + case HOLD_EFFECT_CURE_STATUS: + if (gBattleMons[bank].status1 & STATUS_ANY || gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + i = 0; + if (gBattleMons[bank].status1 & STATUS_PSN_ANY) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); + i++; + } + if (gBattleMons[bank].status1 & STATUS_SLEEP) + { + gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); + i++; + } + if (gBattleMons[bank].status1 & STATUS_PARALYSIS) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); + i++; + } + if (gBattleMons[bank].status1 & STATUS_BURN) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); + i++; + } + if (gBattleMons[bank].status1 & STATUS_FREEZE) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); + i++; + } + if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn); + i++; + } + if (!(i > 1)) + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBattleMons[bank].status1 = 0; + gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2); + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_ATTRACT: + if (gBattleMons[bank].status2 & STATUS2_INFATUATION) + { + gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION); + StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); + BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2); + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + effect = ITEM_EFFECT_OTHER; + } + break; + } + if (effect) + { + gBattleStruct->scriptingActive = bank; + gStringBank = bank; + gActiveBattler = gBankAttacker = bank; + switch (effect) + { + case ITEM_STATUS_CHANGE: + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[bank].status1); + MarkBufferBankForExecution(gActiveBattler); + break; + case ITEM_PP_CHANGE: + if (!(gBattleMons[bank].status2 & STATUS2_TRANSFORMED) && !(gDisableStructs[bank].unk18_b & gBitTable[i])) + gBattleMons[bank].pp[i] = changedPP; + break; + } + } + } + break; + case 2: + break; + case 3: + for (bank = 0; bank < gBattlersCount; bank++) + { + gLastUsedItem = gBattleMons[bank].item; + if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY) + { + bankHoldEffect = gEnigmaBerries[bank].holdEffect; + bankQuality = gEnigmaBerries[bank].holdEffectParam; + } + else + { + bankHoldEffect = ItemId_GetHoldEffect(gLastUsedItem); + bankQuality = ItemId_GetHoldEffectParam(gLastUsedItem); + } + switch (bankHoldEffect) + { + case HOLD_EFFECT_CURE_PAR: + if (gBattleMons[bank].status1 & STATUS_PARALYSIS) + { + gBattleMons[bank].status1 &= ~(STATUS_PARALYSIS); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_BerryCureParRet; + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_PSN: + if (gBattleMons[bank].status1 & STATUS_PSN_ANY) + { + gBattleMons[bank].status1 &= ~(STATUS_PSN_ANY | STATUS_TOXIC_COUNTER); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_BerryCurePsnRet; + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_BRN: + if (gBattleMons[bank].status1 & STATUS_BURN) + { + gBattleMons[bank].status1 &= ~(STATUS_BURN); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_BerryCureBrnRet; + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_FRZ: + if (gBattleMons[bank].status1 & STATUS_FREEZE) + { + gBattleMons[bank].status1 &= ~(STATUS_FREEZE); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_BerryCureFrzRet; + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_SLP: + if (gBattleMons[bank].status1 & STATUS_SLEEP) + { + gBattleMons[bank].status1 &= ~(STATUS_SLEEP); + gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_BerryCureSlpRet; + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_CURE_CONFUSION: + if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_BerryCureConfusionRet; + effect = ITEM_EFFECT_OTHER; + } + break; + case HOLD_EFFECT_CURE_ATTRACT: + if (gBattleMons[bank].status2 & STATUS2_INFATUATION) + { + gBattleMons[bank].status2 &= ~(STATUS2_INFATUATION); + StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); + BattleScriptPushCursor(); + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet; + effect = ITEM_EFFECT_OTHER; + } + break; + case HOLD_EFFECT_CURE_STATUS: + if (gBattleMons[bank].status1 & STATUS_ANY || gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + if (gBattleMons[bank].status1 & STATUS_PSN_ANY) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn); + } + if (gBattleMons[bank].status1 & STATUS_SLEEP) + { + gBattleMons[bank].status2 &= ~(STATUS2_NIGHTMARE); + StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn); + } + if (gBattleMons[bank].status1 & STATUS_PARALYSIS) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn); + } + if (gBattleMons[bank].status1 & STATUS_BURN) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn); + } + if (gBattleMons[bank].status1 & STATUS_FREEZE) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn); + } + if (gBattleMons[bank].status2 & STATUS2_CONFUSION) + { + StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn); + } + gBattleMons[bank].status1 = 0; + gBattleMons[bank].status2 &= ~(STATUS2_CONFUSION); + BattleScriptPushCursor(); + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet; + effect = ITEM_STATUS_CHANGE; + } + break; + case HOLD_EFFECT_RESTORE_STATS: + for (i = 0; i < 8; i++) + { + if (gBattleMons[bank].statStages[i] < 6) + { + gBattleMons[bank].statStages[i] = 6; + effect = ITEM_STATS_CHANGE; + } + } + if (effect) + { + gBattleStruct->scriptingActive = bank; + gStringBank = bank; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_WhiteHerbRet; + return effect; // unnecessary return + } + break; + } + if (effect) + { + gBattleStruct->scriptingActive = bank; + gStringBank = bank; + gActiveBattler = bank; + EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); + MarkBufferBankForExecution(gActiveBattler); + break; + } + } + break; + case 4: + if (gBattleMoveDamage) + { + switch (atkHoldEffect) + { + case HOLD_EFFECT_FLINCH: + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && (gSpecialStatuses[gBankTarget].moveturnLostHP_physical || gSpecialStatuses[gBankTarget].moveturnLostHP_special) + && (Random() % 100) < bankQuality + && gBattleMoves[gCurrentMove].flags & F_AFFECTED_BY_KINGS_ROCK + && gBattleMons[gBankTarget].hp) + { + gBattleCommunication[MOVE_EFFECT_BYTE] = 8; + BattleScriptPushCursor(); + SetMoveEffect(0, 0); + BattleScriptPop(); + } + break; + case HOLD_EFFECT_SHELL_BELL: + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) + && gSpecialStatuses[gBankTarget].moveturnLostHP != 0 + && gSpecialStatuses[gBankTarget].moveturnLostHP != 0xFFFF + && gBankAttacker != gBankTarget + && gBattleMons[gBankAttacker].hp != gBattleMons[gBankAttacker].maxHP + && gBattleMons[gBankAttacker].hp != 0) + { + gLastUsedItem = atkItem; + gStringBank = gBankAttacker; + gBattleStruct->scriptingActive = gBankAttacker; + gBattleMoveDamage = (gSpecialStatuses[gBankTarget].moveturnLostHP / atkQuality) * -1; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = -1; + gSpecialStatuses[gBankTarget].moveturnLostHP = 0; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ItemHealHP_Ret; + effect++; + } + break; + } + } + break; + } + + return effect; +} + +struct CombinedMove +{ + u16 move1; + u16 move2; + u16 newMove; +}; + +static const struct CombinedMove sCombinedMoves[2] = +{ + {MOVE_EMBER, MOVE_GUST, MOVE_HEAT_WAVE}, + {0xFFFF, 0xFFFF, 0xFFFF} +}; + +void unref_sub_801B40C(void) +{ + int i = 0; + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + do + { + u8 bank = 0; + do + { + u8 absent = gAbsentBattlerFlags; + if (gBitTable[bank] & absent || absent & gBitTable[bank + 2]) + bank++; + else + { + if (sCombinedMoves[i].move1 == gChosenMovesByBanks[bank] && sCombinedMoves[i].move2 == gChosenMovesByBanks[bank + 2]) + { + gSideTimers[GetBattlerPosition(bank) & 1].field3 = (bank) | ((bank + 2) << 4); + gSideTimers[GetBattlerPosition(bank) & 1].field4 = sCombinedMoves[i].newMove; + gSideAffecting[GetBattlerPosition(bank) & 1] |= SIDE_STATUS_X4; + } + if (sCombinedMoves[i].move1 == gChosenMovesByBanks[bank + 2] && sCombinedMoves[i].move2 == gChosenMovesByBanks[bank]) + { + gSideTimers[GetBattlerPosition(bank) & 1].field3 = (bank + 2) | ((bank) << 4); + gSideTimers[GetBattlerPosition(bank) & 1].field4 = sCombinedMoves[i].newMove; + gSideAffecting[GetBattlerPosition(bank) & 1] |= SIDE_STATUS_X4; + } + bank++; + } + } while (bank < 2); + i++; + } while (sCombinedMoves[i].move1 != 0xFFFF); + } +} + +void sub_801B594(void) +{ + if (gBattleExecBuffer == 0) + gBattleScriptingCommandsTable[*gBattlescriptCurrInstr](); +} + +u8 GetMoveTarget(u16 move, u8 useMoveTarget) //get move target +{ + u8 targetBank = 0; + u8 moveTarget; + u8 side; + + if (useMoveTarget) + moveTarget = useMoveTarget - 1; + else + moveTarget = gBattleMoves[move].target; + + switch (moveTarget) + { + case 0: + side = GetBattlerSide(gBankAttacker) ^ 1; + if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp) + targetBank = gSideTimers[side].followmeTarget; + else + { + side = GetBattlerSide(gBankAttacker); + do + { + targetBank = Random() % gBattlersCount; + } while (targetBank == gBankAttacker || side == GetBattlerSide(targetBank) || gAbsentBattlerFlags & gBitTable[targetBank]); + if (gBattleMoves[move].type == TYPE_ELECTRIC + && AbilityBattleEffects(ABILITYEFFECT_COUNT_OTHER_SIZE, gBankAttacker, ABILITY_LIGHTNING_ROD, 0, 0) + && gBattleMons[targetBank].ability != ABILITY_LIGHTNING_ROD) + { + targetBank ^= 2; + RecordAbilityBattle(targetBank, gBattleMons[targetBank].ability); + gSpecialStatuses[targetBank].lightningRodRedirected = 1; + } + } + break; + case 1: + case 8: + case 32: + case 64: + targetBank = GetBattlerAtPosition((GetBattlerPosition(gBankAttacker) & 1) ^ 1); + if (gAbsentBattlerFlags & gBitTable[targetBank]) + targetBank ^= 2; + break; + case 4: + side = GetBattlerSide(gBankAttacker) ^ 1; + if (gSideTimers[side].followmeTimer && gBattleMons[gSideTimers[side].followmeTarget].hp) + targetBank = gSideTimers[side].followmeTarget; + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && moveTarget & 4) + { + if (GetBattlerSide(gBankAttacker) == 0) + { + if (Random() & 1) + targetBank = GetBattlerAtPosition(1); + else + targetBank = GetBattlerAtPosition(3); + } + else + { + if (Random() & 1) + targetBank = GetBattlerAtPosition(0); + else + targetBank = GetBattlerAtPosition(2); + } + if (gAbsentBattlerFlags & gBitTable[targetBank]) + targetBank ^= 2; + } + else + targetBank = GetBattlerAtPosition((GetBattlerPosition(gBankAttacker) & 1) ^ 1); + break; + case 2: + case 16: + targetBank = gBankAttacker; + break; + } + ewram16010arr(gBankAttacker) = targetBank; + return targetBank; +} + +u8 IsMonDisobedient(void) +{ + u8 obedienceLevel; + s32 rnd; + s32 calc; + + if (gBattleTypeFlags & BATTLE_TYPE_LINK + || GetBattlerSide(gBankAttacker) == 1 + || !IsOtherTrainer(gBattleMons[gBankAttacker].otId, gBattleMons[gBankAttacker].otName)) + return 0; + + if (DEBUG && (gUnknown_02023A14_50 & 0x40)) + { + obedienceLevel = 10; + } + else + { + if (FlagGet(FLAG_BADGE08_GET)) + return 0; + obedienceLevel = 10; + if (FlagGet(FLAG_BADGE02_GET)) + obedienceLevel = 30; + if (FlagGet(FLAG_BADGE04_GET)) + obedienceLevel = 50; + if (FlagGet(FLAG_BADGE06_GET)) + obedienceLevel = 70; + } + + if (gBattleMons[gBankAttacker].level <= obedienceLevel) + return 0; + rnd = (Random() & 255); + calc = (gBattleMons[gBankAttacker].level + obedienceLevel) * rnd >> 8; + if (calc < obedienceLevel) + return 0; + + // is not obedient + if (gCurrentMove == MOVE_RAGE) + gBattleMons[gBankAttacker].status2 &= ~(STATUS2_RAGE); + if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP && (gCurrentMove == MOVE_SNORE || gCurrentMove == MOVE_SLEEP_TALK)) + { + gBattlescriptCurrInstr = gUnknown_081D995F; + return 1; + } + + rnd = (Random() & 255); + calc = (gBattleMons[gBankAttacker].level + obedienceLevel) * rnd >> 8; + if (calc < obedienceLevel) + { + calc = CheckMoveLimitations(gBankAttacker, gBitTable[gCurrMovePos], 0xFF); + if (calc == 0xF) // all moves cannot be used + { + gBattleCommunication[MULTISTRING_CHOOSER] = Random() & 3; + gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; + return 1; + } + else // use a random move + { + do + { + gCurrMovePos = gUnknown_02024BE5 = Random() & 3; + } while (gBitTable[gCurrMovePos] & calc); + gRandomMove = gBattleMons[gBankAttacker].moves[gCurrMovePos]; + gBattleCommunication[3] = 0; + gDynamicBasePower = 0; + gBattleStruct->dynamicMoveType = 0; + gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove; + gBankTarget = GetMoveTarget(gRandomMove, 0); + gHitMarker |= HITMARKER_x200000; + return 2; + } + } + else + { + obedienceLevel = gBattleMons[gBankAttacker].level - obedienceLevel; + + calc = (Random() & 255); + if (calc < obedienceLevel && !(gBattleMons[gBankAttacker].status1 & STATUS_ANY) && gBattleMons[gBankAttacker].ability != ABILITY_VITAL_SPIRIT && gBattleMons[gBankAttacker].ability != ABILITY_INSOMNIA) + { + // try putting asleep + int i; + for (i = 0; i < gBattlersCount; i++) + { + if (gBattleMons[i].status2 & STATUS2_UPROAR) + break; + } + if (i == gBattlersCount) + { + gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep; + return 1; + } + } + calc -= obedienceLevel; + if (calc < obedienceLevel) + { + gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankAttacker], MOVE_POUND, 0, 40, 0, gBankAttacker, gBankAttacker); + gBankTarget = gBankAttacker; + gBattlescriptCurrInstr = gUnknown_081D99A0; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + return 2; + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = Random() & 3; + gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround; + return 1; + } + } +} diff --git a/src/calculate_base_damage.c b/src/calculate_base_damage.c new file mode 100644 index 000000000..e4ae70c0b --- /dev/null +++ b/src/calculate_base_damage.c @@ -0,0 +1,338 @@ +#include "global.h" +#include "constants/abilities.h" +#include "constants/battle_move_effects.h" +#include "constants/hold_effects.h" +#include "constants/items.h" +#include "constants/moves.h" +#include "constants/species.h" +#include "battle.h" +#include "berry.h" +#include "data2.h" +#include "event_data.h" +#include "item.h" +#include "pokemon.h" +#include "ewram.h" + +extern u16 gBattleTypeFlags; +extern struct BattlePokemon gBattleMons[4]; +extern u16 gCurrentMove; +extern u8 gCritMultiplier; +extern u16 gBattleWeather; +extern struct BattleEnigmaBerry gEnigmaBerries[]; +extern u16 gBattleMovePower; +extern u16 gTrainerBattleOpponent; + +// Masks for getting PP Up count, also PP Max values +const u8 gPPUpReadMasks[] = {0x03, 0x0c, 0x30, 0xc0}; + +// Masks for setting PP Up count +const u8 gPPUpWriteMasks[] = {0xFC, 0xF3, 0xCF, 0x3F}; + +// Values added to PP Up count +const u8 gPPUpValues[] = {0x01, 0x04, 0x10, 0x40}; + +const u8 gStatStageRatios[][2] = +{ + {10, 40}, // -6 + {10, 35}, // -5 + {10, 30}, // -4 + {10, 25}, // -3 + {10, 20}, // -2 + {10, 15}, // -1 + {10, 10}, // 0 + {15, 10}, // 1 + {20, 10}, // 2 + {25, 10}, // 3 + {30, 10}, // 4 + {35, 10}, // 5 + {40, 10} // 6 +}; + +const u8 unknownGameFreakAbbrev_820825E[] = _("ゲーフリ"); + +const u8 gHoldEffectToType[][2] = +{ + {HOLD_EFFECT_BUG_POWER, TYPE_BUG}, + {HOLD_EFFECT_STEEL_POWER, TYPE_STEEL}, + {HOLD_EFFECT_GROUND_POWER, TYPE_GROUND}, + {HOLD_EFFECT_ROCK_POWER, TYPE_ROCK}, + {HOLD_EFFECT_GRASS_POWER, TYPE_GRASS}, + {HOLD_EFFECT_DARK_POWER, TYPE_DARK}, + {HOLD_EFFECT_FIGHTING_POWER, TYPE_FIGHTING}, + {HOLD_EFFECT_ELECTRIC_POWER, TYPE_ELECTRIC}, + {HOLD_EFFECT_WATER_POWER, TYPE_WATER}, + {HOLD_EFFECT_FLYING_POWER, TYPE_FLYING}, + {HOLD_EFFECT_POISON_POWER, TYPE_POISON}, + {HOLD_EFFECT_ICE_POWER, TYPE_ICE}, + {HOLD_EFFECT_GHOST_POWER, TYPE_GHOST}, + {HOLD_EFFECT_PSYCHIC_POWER, TYPE_PSYCHIC}, + {HOLD_EFFECT_FIRE_POWER, TYPE_FIRE}, + {HOLD_EFFECT_DRAGON_POWER, TYPE_DRAGON}, + {HOLD_EFFECT_NORMAL_POWER, TYPE_NORMAL} +}; + +u8 GetBattlerSide(u8 bank); + +#define APPLY_STAT_MOD(var, mon, stat, statIndex) \ +{ \ + (var) = (stat) * (gStatStageRatios)[(mon)->statStages[(statIndex)]][0]; \ + (var) /= (gStatStageRatios)[(mon)->statStages[(statIndex)]][1]; \ +} + +#define BADGE_BOOST(badge, stat, bank) ({ \ +if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_EREADER_TRAINER))) \ +{ \ + if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) \ + && gTrainerBattleOpponent != SECRET_BASE_OPPONENT \ + && FlagGet(FLAG_BADGE0##badge##_GET) \ + && GetBattlerSide(bank) == B_SIDE_PLAYER) \ + (stat) = (110 * (stat)) / 100; \ +} \ +}) + +s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 sideStatus, u16 powerOverride, u8 typeOverride, u8 bankAtk, u8 bankDef) +{ + u32 i; + s32 damage = 0; + s32 damageHelper; + u8 type; + u16 attack, defense; + u16 spAttack, spDefense; + u8 defenderHoldEffect; + u8 defenderHoldEffectParam; + u8 attackerHoldEffect; + u8 attackerHoldEffectParam; + + if (!powerOverride) + gBattleMovePower = gBattleMoves[move].power; + else + gBattleMovePower = powerOverride; + + if (!typeOverride) + type = gBattleMoves[move].type; + else + type = typeOverride & 0x3F; + + attack = attacker->attack; + defense = defender->defense; + spAttack = attacker->spAttack; + spDefense = defender->spDefense; + + if (attacker->item == ITEM_ENIGMA_BERRY) + { + attackerHoldEffect = gEnigmaBerries[bankAtk].holdEffect; + attackerHoldEffectParam = gEnigmaBerries[bankAtk].holdEffectParam; + } + else + { + attackerHoldEffect = ItemId_GetHoldEffect(attacker->item); + attackerHoldEffectParam = ItemId_GetHoldEffectParam(attacker->item); + } + + if (defender->item == ITEM_ENIGMA_BERRY) + { + defenderHoldEffect = gEnigmaBerries[bankDef].holdEffect; + defenderHoldEffectParam = gEnigmaBerries[bankDef].holdEffectParam; + } + else + { + defenderHoldEffect = ItemId_GetHoldEffect(defender->item); + defenderHoldEffectParam = ItemId_GetHoldEffectParam(defender->item); + } + + if (attacker->ability == ABILITY_HUGE_POWER || attacker->ability == ABILITY_PURE_POWER) + attack *= 2; + + BADGE_BOOST(1, attack, bankAtk); + BADGE_BOOST(5, defense, bankDef); + BADGE_BOOST(7, spAttack, bankAtk); + BADGE_BOOST(7, spDefense, bankDef); + + for (i = 0; i < 17; i++) + { + if (attackerHoldEffect == gHoldEffectToType[i][0] + && type == gHoldEffectToType[i][1]) + { + if (TYPE_IS_PHYSICAL(type)) + attack = (attack * (attackerHoldEffectParam + 100)) / 100; + else + spAttack = (spAttack * (attackerHoldEffectParam + 100)) / 100; + break; + } + } + + if (attackerHoldEffect == HOLD_EFFECT_CHOICE_BAND) + attack = (150 * attack) / 100; + if (attackerHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) && (attacker->species == SPECIES_LATIAS || attacker->species == SPECIES_LATIOS)) + spAttack = (150 * spAttack) / 100; + if (defenderHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER) && (defender->species == SPECIES_LATIAS || defender->species == SPECIES_LATIOS)) + spDefense = (150 * spDefense) / 100; + if (attackerHoldEffect == HOLD_EFFECT_DEEP_SEA_TOOTH && attacker->species == SPECIES_CLAMPERL) + spAttack *= 2; + if (defenderHoldEffect == HOLD_EFFECT_DEEP_SEA_SCALE && defender->species == SPECIES_CLAMPERL) + spDefense *= 2; + if (attackerHoldEffect == HOLD_EFFECT_LIGHT_BALL && attacker->species == SPECIES_PIKACHU) + spAttack *= 2; + if (defenderHoldEffect == HOLD_EFFECT_METAL_POWDER && defender->species == SPECIES_DITTO) + defense *= 2; + if (attackerHoldEffect == HOLD_EFFECT_THICK_CLUB && (attacker->species == SPECIES_CUBONE || attacker->species == SPECIES_MAROWAK)) + attack *= 2; + if (defender->ability == ABILITY_THICK_FAT && (type == TYPE_FIRE || type == TYPE_ICE)) + spAttack /= 2; + if (attacker->ability == ABILITY_HUSTLE) + attack = (150 * attack) / 100; + if (attacker->ability == ABILITY_PLUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MINUS, 0, 0)) + spAttack = (150 * spAttack) / 100; + if (attacker->ability == ABILITY_MINUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_PLUS, 0, 0)) + spAttack = (150 * spAttack) / 100; + if (attacker->ability == ABILITY_GUTS && attacker->status1) + attack = (150 * attack) / 100; + if (defender->ability == ABILITY_MARVEL_SCALE && defender->status1) + defense = (150 * defense) / 100; + if (type == TYPE_ELECTRIC && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFD, 0)) + gBattleMovePower /= 2; + if (type == TYPE_FIRE && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFE, 0)) + gBattleMovePower /= 2; + if (type == TYPE_GRASS && attacker->ability == ABILITY_OVERGROW && attacker->hp <= (attacker->maxHP / 3)) + gBattleMovePower = (150 * gBattleMovePower) / 100; + if (type == TYPE_FIRE && attacker->ability == ABILITY_BLAZE && attacker->hp <= (attacker->maxHP / 3)) + gBattleMovePower = (150 * gBattleMovePower) / 100; + if (type == TYPE_WATER && attacker->ability == ABILITY_TORRENT && attacker->hp <= (attacker->maxHP / 3)) + gBattleMovePower = (150 * gBattleMovePower) / 100; + if (type == TYPE_BUG && attacker->ability == ABILITY_SWARM && attacker->hp <= (attacker->maxHP / 3)) + gBattleMovePower = (150 * gBattleMovePower) / 100; + if (gBattleMoves[gCurrentMove].effect == EFFECT_EXPLOSION) + defense /= 2; + + if (TYPE_IS_PHYSICAL(type)) // type < TYPE_MYSTERY + { + if (gCritMultiplier == 2) + { + if (attacker->statStages[STAT_STAGE_ATK] > 6) + APPLY_STAT_MOD(damage, attacker, attack, STAT_STAGE_ATK) + else + damage = attack; + } + else + APPLY_STAT_MOD(damage, attacker, attack, STAT_STAGE_ATK) + + damage = damage * gBattleMovePower; + damage *= (2 * attacker->level / 5 + 2); + + if (gCritMultiplier == 2) + { + if (defender->statStages[STAT_STAGE_DEF] < 6) + APPLY_STAT_MOD(damageHelper, defender, defense, STAT_STAGE_DEF) + else + damageHelper = defense; + } + else + APPLY_STAT_MOD(damageHelper, defender, defense, STAT_STAGE_DEF) + + damage = damage / damageHelper; + damage /= 50; + + if ((attacker->status1 & STATUS_BURN) && attacker->ability != ABILITY_GUTS) + damage /= 2; + + if ((sideStatus & SIDE_STATUS_REFLECT) && gCritMultiplier == 1) + { + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMons(2) == 2) + damage = 2 * (damage / 3); + else + damage /= 2; + } + + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMons(2) == 2) + damage /= 2; + + // moves always do at least 1 damage. + if (damage == 0) + damage = 1; + } + + if (type == TYPE_MYSTERY) + damage = 0; // is ??? type. does 0 damage. + + if (TYPE_IS_SPECIAL(type)) // type > TYPE_MYSTERY + { + if (gCritMultiplier == 2) + { + if (attacker->statStages[STAT_STAGE_SPATK] > 6) + APPLY_STAT_MOD(damage, attacker, spAttack, STAT_STAGE_SPATK) + else + damage = spAttack; + } + else + APPLY_STAT_MOD(damage, attacker, spAttack, STAT_STAGE_SPATK) + + damage = damage * gBattleMovePower; + damage *= (2 * attacker->level / 5 + 2); + + if (gCritMultiplier == 2) + { + if (defender->statStages[STAT_STAGE_SPDEF] < 6) + APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_STAGE_SPDEF) + else + damageHelper = spDefense; + } + else + APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_STAGE_SPDEF) + + damage = (damage / damageHelper); + damage /= 50; + + if ((sideStatus & SIDE_STATUS_LIGHTSCREEN) && gCritMultiplier == 1) + { + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMons(2) == 2) + damage = 2 * (damage / 3); + else + damage /= 2; + } + + if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMons(2) == 2) + damage /= 2; + + // are effects of weather negated with cloud nine or air lock + if (!AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_CLOUD_NINE, 0, 0) + && !AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_AIR_LOCK, 0, 0)) + { + if (gBattleWeather & WEATHER_RAIN_TEMPORARY) + { + switch (type) + { + case TYPE_FIRE: + damage /= 2; + break; + case TYPE_WATER: + damage = (15 * damage) / 10; + break; + } + } + + // any weather except sun weakens solar beam + if ((gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_HAIL)) && gCurrentMove == MOVE_SOLAR_BEAM) + damage /= 2; + + // sunny + if (gBattleWeather & WEATHER_SUN_ANY) + { + switch (type) + { + case TYPE_FIRE: + damage = (15 * damage) / 10; + break; + case TYPE_WATER: + damage /= 2; + break; + } + } + } + + // flash fire triggered + if ((eFlashFireArr.arr[bankAtk] & 1) && type == TYPE_FIRE) + damage = (15 * damage) / 10; + } + + return damage + 2; +} diff --git a/src/contest_link_80C2020.c b/src/contest_link_80C2020.c new file mode 100644 index 000000000..2dde3895c --- /dev/null +++ b/src/contest_link_80C2020.c @@ -0,0 +1,2906 @@ +#include "global.h" +#include "data2.h" +#include "util.h" +#include "random.h" +#include "overworld.h" +#include "constants/songs.h" +#include "ewram.h" +#include "main.h" +#include "scanline_effect.h" +#include "decompress.h" +#include "palette.h" +#include "blend_palette.h" +#include "graphics.h" +#include "strings2.h" +#include "text.h" +#include "string_util.h" +#include "menu.h" +#include "sound.h" +#include "pokedex.h" +#include "pokemon_icon.h" +#include "tv.h" +#include "battle.h" +#include "contest.h" +#include "link.h" +#include "field_effect.h" +#include "field_specials.h" +#include "contest_link_80C857C.h" +#include "contest_link_80C2020.h" +#include "pokemon_storage_system.h" +#include "event_data.h" +#include "script.h" +#include "trig.h" + +#define ABS(x) ((x) < 0 ? -(x) : (x)) + +#define GET_CONTEST_WINNER(var) { \ + for ((var) = 0; (var) < 4; (var)++) \ + { \ + if (gContestFinalStandings[i] == 0) \ + break; \ + } \ +} + +struct UnkEwramStruct18000 { + u8 unk_00; + u8 unk_01; + u8 unk_02; + u8 unk_03; + u8 unk_04; + u8 unk_05; + u8 unk_06; + u8 unk_07; + u8 unk_08; + u8 unk_09; + u8 unk_0a; + s16 unk_0c[4]; + u8 unk_14; +}; + +struct UnkEwramStruct18018 { + s32 unk_00; + s32 unk_04; + u32 unk_08; + u32 unk_0c; + u8 unk_10; + u8 unk_11; + u8 unk_12; +}; + +#define eContestLink80C2020Struct2018000 (*(struct UnkEwramStruct18000 *)(gSharedMem + 0x18000)) +#define eContestLink80C2020Struct2018018 ((struct UnkEwramStruct18018 *)(gSharedMem + 0x18018)) +#define eContestLink80C2020Struct2018068 (gSharedMem + 0x18068) + +static void sub_80C2430(void); +static void sub_80C2448(void); +static void sub_80C24F4(u8 taskId); +static void sub_80C255C(u8 taskId); +static void sub_80C25A4(u8 taskId); +static void sub_80C25C0(u8 taskId); +static void sub_80C2600(u8 taskId); +static void sub_80C26E4(u8 taskId); +static void sub_80C2770(u8 taskId); +static void sub_80C27EC(u8 taskId); +static void sub_80C2878(u8 taskId); +static void sub_80C2A8C(u8 taskId); +static void sub_80C2D1C(u8 taskId); +static void sub_80C2D80(u8 taskId); +static void sub_80C2DD8(u8 taskId); +static void sub_80C2E14(u8 taskId); +static void sub_80C2EA0(u8 taskId); +static void sub_80C2F28(u8 taskId); +static void sub_80C2F64(u8 taskId); +static void LoadAllContestMonIcons(u8 srcOffset, bool8 useDmaNow); +void sub_80C310C(void); +void sub_80C3158(const u8 *string, u8 spriteId); +void sub_80C33DC(void); +u16 sub_80C34AC(const u8 *string); +void sub_80C34CC(s16 data4, u16 pos0y, u16 data5, u16 data6); +void sub_80C3520(u16 a0); +void sub_80C3588(struct Sprite *sprite); +void sub_80C35FC(struct Sprite *sprite); +void sub_80C3630(struct Sprite *sprite); +void sub_80C3698(const u8 *string); +void sub_80C3764(void); +void sub_80C37E4(void); +u8 sub_80C3990(u8 a0, u8 a1); +s8 sub_80C39E4(u8 a0, u8 a1); +void sub_80C3A5C(u8 taskId); +void sub_80C3BD8(u8 taskId); +void sub_80C3B30(u8 taskId); +void sub_80C3C44(struct Sprite *sprite); +void sub_80C3CB8(struct Sprite *sprite); +void sub_80C3D04(u8 taskId); +void sub_80C3DF0(struct Sprite *sprite); +void sub_80C3E60(u8 a0, u8 a1); +void sub_80C3EA4(u8 taskId); +void sub_80C3F00(void); +void sub_80C40D4(u8 a0, u8 a1); +void sub_80C42C0(u8 taskId); +void sub_80C49C4(u8 taskId); +void sub_80C49F0(u8 taskId); +void sub_80C4A0C(u8 taskId); +void sub_80C4A28(u8 taskId); +void sub_80C4A44(u8 taskId); +void sub_80C4B0C(u8 taskId); +void sub_80C4B5C(u8 taskId); +void sub_80C4BA4(u8 taskId); +void sub_80C4BCC(u8 taskId); + +const u16 gUnknown_083D1624[] = INCBIN_U16("graphics/unknown/unknown_3D1624/0.4bpp"); +const u16 gUnknown_083D1644[] = INCBIN_U16("graphics/unknown/unknown_3D1624/1.4bpp"); +const u16 gUnknown_083D1664[] = INCBIN_U16("graphics/unknown/unknown_3D1624/2.4bpp"); +const u16 gUnknown_083D1684[] = INCBIN_U16("graphics/unknown/unknown_3D1624/3.4bpp"); +const u16 gUnknown_083D16A4[] = INCBIN_U16("graphics/unknown/unknown_3D1624/4.4bpp"); +const u16 gUnknown_083D16C4[] = INCBIN_U16("graphics/unknown/unknown_3D1624/5.4bpp"); +const u16 gUnknown_083D16E4[] = INCBIN_U16("graphics/unknown/unknown_3D1624/6.4bpp"); +const u16 gUnknown_083D1704[] = INCBIN_U16("graphics/unknown/unknown_3D1624/7.4bpp"); +const u16 gMiscBlank_Pal[] = INCBIN_U16("graphics/interface/blank.gbapal"); + +const struct OamData gOamData_83D1744 = { + .shape = ST_OAM_H_RECTANGLE, + .size = 3, + .priority = 3, + .paletteNum = 2 +}; + +const struct SpriteTemplate gSpriteTemplate_83D174C = { + 0xbc1, + 0xbc1, + &gOamData_83D1744, + gDummySpriteAnimTable, + NULL, + gDummySpriteAffineAnimTable, + SpriteCallbackDummy +}; + +const struct SpriteSheet gUnknown_083D1764[] = { + {gMiscBlank_Gfx, 0x400, 0xbc1}, + {gMiscBlank_Gfx, 0x400, 0xbc2}, + {gMiscBlank_Gfx, 0x400, 0xbc3}, + {gMiscBlank_Gfx, 0x400, 0xbc4}, + {gMiscBlank_Gfx, 0x400, 0xbc5}, + {gMiscBlank_Gfx, 0x400, 0xbc6}, + {gMiscBlank_Gfx, 0x400, 0xbc7}, + {gMiscBlank_Gfx, 0x400, 0xbc8}, +}; + +const struct SpritePalette gUnknown_083D17A4 = { + gMiscBlank_Pal, 0xbc1 +}; + +const struct OamData gOamData_83D17AC = {}; + +const struct SpriteTemplate gSpriteTemplate_83D17B4 = { + 0xbc9, + 0xbc9, + &gOamData_83D17AC, + gDummySpriteAnimTable, + NULL, + gDummySpriteAffineAnimTable, + sub_80C3DF0 +}; + +const struct CompressedSpriteSheet gUnknown_083D17CC = {gContestConfetti_Gfx, 0x220, 0xbc9}; + +const struct CompressedSpritePalette gUnknown_083D17D4 = {gContestConfetti_Pal, 0xbc9}; + +const u8 gUnknown_083D17DC[] = _("{COLOR RED}"); +const u8 gUnknown_083D17E0[] = _("/"); +const u8 gUnknown_083D17E2[] = _("{SIZE 3}{COLOR_HIGHLIGHT_SHADOW WHITE2 DARK_GREY LIGHT_BLUE}"); + +void sub_80C2020(void) +{ + REG_DISPCNT = DISPCNT_OBJ_1D_MAP; + Text_LoadWindowTemplate(&gWindowTemplate_81E6FA0); + Text_InitWindowWithTemplate(&gMenuWindow, &gWindowTemplate_81E6FA0); + REG_BG0CNT = BGCNT_WRAP | BGCNT_SCREENBASE(30); + REG_BG1CNT = BGCNT_PRIORITY(3) | BGCNT_SCREENBASE(24); + REG_BG2CNT = BGCNT_PRIORITY(3) | BGCNT_SCREENBASE(28); + REG_BG3CNT = BGCNT_WRAP | BGCNT_PRIORITY(3) | BGCNT_SCREENBASE(26); + REG_MOSAIC = 0; + REG_WININ = 0x3f3f; + REG_WINOUT = 0x3f2e; + REG_WIN0H = 0; + REG_WIN0V = 0; + REG_WIN1H = 0; + REG_WIN1V = 0; + REG_BLDCNT = 0; + REG_BLDALPHA = 0; + REG_BLDY = 0; + REG_BG0HOFS = 0; + REG_BG0VOFS = 0; + REG_BG1HOFS = 0; + REG_BG1VOFS = 0; + REG_BG2HOFS = 0; + REG_BG2VOFS = 0; + REG_BG3HOFS = 0; + REG_BG3VOFS = 0; + REG_DISPCNT |= DISPCNT_BG_ALL_ON | DISPCNT_OBJ_ON | DISPCNT_WIN0_ON | DISPCNT_WIN1_ON; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + gBattle_BG2_X = 0; + gBattle_BG2_Y = 0; + gBattle_BG3_X = 0; + gBattle_BG3_Y = 0; + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + gBattle_WIN1H = 0; + gBattle_WIN1V = 0; +} + +void sub_80C2144(void) +{ + int i; + int j; + s8 r7; + s8 r4; + u16 r6; + u16 r3; + + DmaFill32Large(3, 0, VRAM, VRAM_SIZE, 0x1000); + LZDecompressVram(gUnknown_08D1977C, BG_SCREEN_ADDR(0)); + LZDecompressVram(gUnknown_08D1A490, BG_SCREEN_ADDR(26)); + LZDecompressVram(gUnknown_08D1A364, BG_SCREEN_ADDR(28)); + LZDecompressVram(gUnknown_08D1A250, BG_SCREEN_ADDR(30)); + sub_80C37E4(); + LoadCompressedPalette(gUnknown_08D1A618, 0, 0x200); + LoadFontDefaultPalette(&gWindowTemplate_81E6FA0); + for (i = 0; i < 4; i++) + { + r7 = sub_80C3990(i, 1); + r4 = sub_80C39E4(i, 1); + for (j = 0; j < 10; j++) + { + r6 = 0x60b2; + if (j < r7) + r6 = 0x60b4; + if (j < ABS(r4)) + { + r3 = 0x60a4; + if (r4 < 0) + r3 = 0x60a6; + } + else + r3 = 0x60a2; + ((u16 *)BG_VRAM)[i * 0x60 + j + 0x60b3] = r6; + ((u16 *)BG_VRAM)[i * 0x60 + j + 0x60d3] = r3; + } + } +} + +void sub_80C226C(u8 a0) +{ + u8 *strbuf; + + if (a0 == gContestPlayerMonIndex) + strbuf = StringCopy(gDisplayedStringBattle, gUnknown_083D17DC); + else + strbuf = gDisplayedStringBattle; + strbuf[0] = EXT_CTRL_CODE_BEGIN; + strbuf[1] = 0x06; + strbuf[2] = 0x04; + strbuf += 3; + strbuf = StringCopy(strbuf, gContestMons[a0].nickname); + strbuf[0] = EXT_CTRL_CODE_BEGIN; + strbuf[1] = 0x13; + strbuf[2] = 0x32; + strbuf += 3; + strbuf = StringCopy(strbuf, gUnknown_083D17E0); + if (gIsLinkContest & 1) + StringCopy(strbuf, gLinkPlayers[a0].name); + else + StringCopy(strbuf, gContestMons[a0].trainerName); + Text_InitWindowAndPrintText(&gMenuWindow, gDisplayedStringBattle, a0 * 36 + 770, 7, a0 * 3 + 4); +} + +void sub_80C2340(void) +{ + int i; + + for (i = 0; i < 4; i++) + sub_80C226C(i); +} + +void sub_80C2358(void) +{ + gPaletteFade.bufferTransferDisabled = TRUE; + SetVBlankCallback(NULL); + sub_80C2020(); + ScanlineEffect_Clear(); + ResetPaletteFade(); + ResetSpriteData(); + ResetTasks(); + FreeAllSpritePalettes(); + sub_80C2144(); + sub_80C310C(); + LoadAllContestMonIcons(0, TRUE); + sub_80C2340(); + eContestLink80C2020Struct2018000 = (struct UnkEwramStruct18000){}; + memset(eContestLink80C2020Struct2018018, 0, 4 * sizeof(struct UnkEwramStruct18018)); + sub_80C33DC(); + BeginNormalPaletteFade(0xffffffff, 0, 16, 0, 0); + gPaletteFade.bufferTransferDisabled = FALSE; + eContestLink80C2020Struct2018000.unk_02 = CreateTask(sub_80C24F4, 5); + SetMainCallback2(sub_80C2430); + gBattle_WIN1H = 0xf0; + gBattle_WIN1V = 0x80a0; + CreateTask(sub_80C2F28, 20); + sub_80C3F00(); + PlayBGM(MUS_CON_K); + SetVBlankCallback(sub_80C2448); +} + +static void sub_80C2430(void) +{ + AnimateSprites(); + BuildOamBuffer(); + RunTasks(); + UpdatePaletteFade(); +} + +static void sub_80C2448(void) +{ + REG_BG0HOFS = gBattle_BG0_X; + REG_BG0VOFS = gBattle_BG0_Y; + REG_BG1HOFS = gBattle_BG1_X; + REG_BG1VOFS = gBattle_BG1_Y; + REG_BG2HOFS = gBattle_BG2_X; + REG_BG2VOFS = gBattle_BG2_Y; + REG_BG3HOFS = gBattle_BG3_X; + REG_BG3VOFS = gBattle_BG3_Y; + REG_WIN0H = gBattle_WIN0H; + REG_WIN0V = gBattle_WIN0V; + REG_WIN1H = gBattle_WIN1H; + REG_WIN1V = gBattle_WIN1V; + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); + ScanlineEffect_InitHBlankDmaTransfer(); +} + +static void sub_80C24F4(u8 taskId) +{ + if (!gPaletteFade.active) + { + if (gIsLinkContest & 1) + { + sub_80C3698(gOtherText_LinkStandby); + gTasks[taskId].func = sub_80C255C; + } + else + { + gTasks[taskId].func = sub_80C2600; + } + } +} + +static void sub_80C255C(u8 taskId) +{ + if (gReceivedRemoteLinkPlayers && GetLinkPlayerCount() == MAX_LINK_PLAYERS) + { + CreateTask(sub_80C25A4, 0); + gTasks[taskId].func = TaskDummy; + } +} + +static void sub_80C25A4(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_80C89DC, sub_80C25C0); +} + +static void sub_80C25C0(u8 taskId) +{ + if (IsLinkTaskFinished()) + { + DestroyTask(taskId); + gTasks[eContestLink80C2020Struct2018000.unk_02].func = sub_80C2600; + sub_80C3764(); + } +} + +static void sub_80C2600(u8 taskId) +{ + if (gTasks[taskId].data[0] == 0) + { + CreateTask(sub_80C2F64, 20); + sub_80C3158(gContestText_AnnounceResults, eContestLink80C2020Struct2018000.unk_00); + sub_80C34CC(sub_80C34AC(gContestText_AnnounceResults), 0x90, 0x78, 0x440); + gTasks[taskId].data[0]++; + } + else if (gTasks[taskId].data[0] == 1) + { + if (eContestLink80C2020Struct2018000.unk_04 == 0) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + } + } + else if (gTasks[taskId].data[0] == 2) + { + if (++gTasks[taskId].data[1] == 0x15) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + } + } + else if (gTasks[taskId].data[0] == 3) + { + sub_80C3158(gContestText_PreliminaryResults, eContestLink80C2020Struct2018000.unk_00); + sub_80C34CC(sub_80C34AC(gContestText_PreliminaryResults), 0x90, 0xffff, 0x440); + gTasks[taskId].data[0]++; + } + else if (gTasks[taskId].data[0] == 4) + { + if (eContestLink80C2020Struct2018000.unk_04 == 2) + { + gTasks[taskId].data[0] = 0; + gTasks[taskId].func = sub_80C26E4; + } + } +} + +static void sub_80C26E4(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + case 0: + if (eContestLink80C2020Struct2018000.unk_0a == 0) + { + sub_80C40D4(0, gTasks[taskId].data[2]++); + if (eContestLink80C2020Struct2018000.unk_14 == 0) + { + gTasks[taskId].data[0] = 2; + } + else + { + gTasks[taskId].data[0]++; + } + } + break; + case 1: + if (eContestLink80C2020Struct2018000.unk_14 == 0) + { + gTasks[taskId].data[0] = 0; + } + break; + case 2: + sub_80C3520(0x440); + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[2] = 0; + gTasks[taskId].func = sub_80C2770; + break; + } +} + +static void sub_80C2770(u8 taskId) +{ + if (eContestLink80C2020Struct2018000.unk_04 == 0) + { + if (++gTasks[taskId].data[1] == 21) + { + gTasks[taskId].data[1] = 0; + sub_80C3158(gContestText_Round2Results, eContestLink80C2020Struct2018000.unk_00); + sub_80C34CC(sub_80C34AC(gContestText_Round2Results), 0x90, 0xffff, 0x440); + } + } + else if (eContestLink80C2020Struct2018000.unk_04 == 2) + { + gTasks[taskId].func = sub_80C27EC; + } +} + +static void sub_80C27EC(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + case 0: + if (eContestLink80C2020Struct2018000.unk_0a == 0) + { + sub_80C40D4(1, gTasks[taskId].data[2]++); + if (eContestLink80C2020Struct2018000.unk_14 == 0) + { + gTasks[taskId].data[0] = 2; + } + else + { + gTasks[taskId].data[0]++; + } + } + break; + case 1: + if (eContestLink80C2020Struct2018000.unk_14 == 0) + { + gTasks[taskId].data[0] = 0; + } + break; + case 2: + sub_80C3520(0x440); + gTasks[taskId].data[0] = 0; + gTasks[taskId].func = sub_80C2878; + break; + } +} + +static void sub_80C2878(u8 taskId) +{ + int i; + u8 taskId2; + u8 strbuf[100]; + + switch (gTasks[taskId].data[0]) + { + case 0: + if (eContestLink80C2020Struct2018000.unk_04 == 0) + gTasks[taskId].data[0]++; + break; + case 1: + if (++gTasks[taskId].data[1] == 31) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + } + break; + case 2: + for (i = 0; i < 4; i++) + { + taskId2 = CreateTask(sub_80C3A5C, 10); + gTasks[taskId2].data[0] = gContestFinalStandings[i]; + gTasks[taskId2].data[1] = i; + } + gTasks[taskId].data[0]++; + break; + case 3: + if (eContestLink80C2020Struct2018000.unk_05 == 4) + { + if (++gTasks[taskId].data[1] == 31) + { + gTasks[taskId].data[1] = 0; + CreateTask(sub_80C3B30, 10); + gTasks[taskId].data[0]++; + GET_CONTEST_WINNER(i); + sub_80C3E60(i, 14); + } + } + break; + case 4: + if (++gTasks[taskId].data[1] == 21) + { + gTasks[taskId].data[1] = 0; + GET_CONTEST_WINNER(i); + if (gIsLinkContest & 1) + { + StringCopy(gStringVar1, gLinkPlayers[i].name); + } + else + { + StringCopy(gStringVar1, gContestMons[i].trainerName); + } + StringCopy(gStringVar2, gContestMons[i].nickname); + StringExpandPlaceholders(strbuf, gContestText_PokeWon); + sub_80C3158(strbuf, eContestLink80C2020Struct2018000.unk_00); + sub_80C34CC(sub_80C34AC(strbuf), 0x90, 0xffff, 0x440); + gTasks[taskId].data[0]++; + } + break; + case 5: + gTasks[taskId].data[0] = 0; + gTasks[taskId].func = sub_80C2A8C; + break; + } +} + +static void sub_80C2A8C(u8 taskId) +{ + int i; + u8 spriteId; + u16 species; + u32 personality; + u32 otId; + const struct CompressedSpritePalette *monPal; + + switch (gTasks[taskId].data[0]) + { + case 0: + gBattle_WIN0H = 0xf0; + gBattle_WIN0V = 0x5050; + GET_CONTEST_WINNER(i); + species = gContestMons[i].species; + personality = gContestMons[i].personality; + otId = gContestMons[i].otId; + HandleLoadSpecialPokePic(gMonFrontPicTable + species, gMonFrontPicCoords[species].coords, gMonFrontPicCoords[species].y_offset, (intptr_t)gSharedMem, gUnknown_081FAF4C[1], species, personality); + monPal = GetMonSpritePalStructFromOtIdPersonality(species, otId, personality); + LoadCompressedObjectPalette(monPal); + GetMonSpriteTemplate_803C56C(species, 1); + gUnknown_02024E8C.paletteTag = monPal->tag; + spriteId = CreateSprite(&gUnknown_02024E8C, 0x110, 0x50, 10); + gSprites[spriteId].data[1] = species; + gSprites[spriteId].oam.priority = 0; + gSprites[spriteId].callback = sub_80C3C44; + eContestLink80C2020Struct2018000.unk_08 = spriteId; + LoadCompressedObjectPic(&gUnknown_083D17CC); + LoadCompressedObjectPalette(&gUnknown_083D17D4); + CreateTask(sub_80C3D04, 10); + gTasks[taskId].data[0]++; + break; + case 1: + if (++gTasks[taskId].data[3] == 1) + { + u8 win0v; + gTasks[taskId].data[3] = 0; + gTasks[taskId].data[2] += 2; + if (gTasks[taskId].data[2] > 0x20) + gTasks[taskId].data[2] = 0x20; + win0v = gTasks[taskId].data[2]; + gBattle_WIN0V = ((0x50 - win0v) << 8) | (0x50 + win0v); + if (win0v == 0x20) + { + gTasks[taskId].data[0]++; + } + } + break; + case 2: + if (eContestLink80C2020Struct2018000.unk_06 == 1) + { + gTasks[taskId].data[0]++; + } + break; + case 3: + if (++gTasks[taskId].data[1] == 121) + { + gTasks[taskId].data[1] = 0; + gSprites[eContestLink80C2020Struct2018000.unk_08].callback = sub_80C3CB8; + gTasks[taskId].data[0]++; + } + break; + case 4: + if (eContestLink80C2020Struct2018000.unk_06 == 2) + { + u8 win0v = (gBattle_WIN0V >> 8); + win0v += 2; + if (win0v > 0x50) + win0v = 0x50; + gBattle_WIN0V = (win0v << 8) | (0xa0 - win0v); + if (win0v == 0x50) + { + gTasks[taskId].data[0]++; + } + } + break; + case 5: + if (eContestLink80C2020Struct2018000.unk_06 == 2) + { + eContestLink80C2020Struct2018000.unk_09 = 1; + gTasks[taskId].data[0] = 0; + gTasks[taskId].func = sub_80C2D1C; + } + break; + } +} + +static void sub_80C2D1C(u8 taskId) +{ + int i; + + if (gMain.newKeys & A_BUTTON) + { + if (!(gIsLinkContest & 1)) + { + for (i = 0; i < 4; i++) + { + GetSetPokedexFlag(SpeciesToNationalPokedexNum(gContestMons[i].species), FLAG_SET_SEEN); + } + } + gTasks[taskId].func = sub_80C2D80; + } +} + +static void sub_80C2D80(u8 taskId) +{ + if (gIsLinkContest & 1) + { + sub_80C3698(gOtherText_LinkStandby); + sub_800832C(); + gTasks[taskId].func = sub_80C2DD8; + } + else + { + gTasks[taskId].func = sub_80C2E14; + } +} + +static void sub_80C2DD8(u8 taskId) +{ + if (gReceivedRemoteLinkPlayers == 0) + { + gIsLinkContest = 0; + sub_80C3764(); + gTasks[taskId].func = sub_80C2E14; + } +} + +static void sub_80C2E14(u8 taskId) +{ + sub_80BE284(gContestFinalStandings[gContestPlayerMonIndex]); + sub_810FB10(2); + Contest_SaveWinner(gSpecialVar_ContestRank); + Contest_SaveWinner(0xFE); + ewram15DDF = 1; + ewram15DDE = sub_80B2C4C(0xfe, 0); + BeginHardwarePaletteFade(0xff, 0, 0, 16, 0); + gTasks[taskId].func = sub_80C2EA0; +} + +static void sub_80C2EA0(u8 taskId) +{ + if (!gPaletteFade.active) + { + if (gTasks[taskId].data[1] == 0) + { + DestroyTask(eContestLink80C2020Struct2018000.unk_03); + BlendPalettes(0x0000ffff, 16, 0); + gTasks[taskId].data[1]++; + } + else if (gTasks[taskId].data[1] == 1) + { + BlendPalettes(0xffff0000, 16, 0); + gTasks[taskId].data[1]++; + } + else + { + REG_BLDCNT = 0; + REG_BLDY = 0; + DestroyTask(taskId); + SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music); + } + } +} + +static void sub_80C2F28(u8 taskId) +{ + gBattle_BG3_X += 2; + gBattle_BG3_Y++; + if (gBattle_BG3_X > 0xff) + gBattle_BG3_X -= 0xff; + if (gBattle_BG3_Y > 0xff) + gBattle_BG3_Y -= 0xff; +} + +static void sub_80C2F64(u8 taskId) +{ + if (++gTasks[taskId].data[0] == 2) + { + gTasks[taskId].data[0] = 0; + if (gTasks[taskId].data[2] == 0) + gTasks[taskId].data[1]++; + else + gTasks[taskId].data[1]--; + if (gTasks[taskId].data[1] == 16) + gTasks[taskId].data[2] = 1; + else if (gTasks[taskId].data[1] == 0) + gTasks[taskId].data[2] = 0; + BlendPalette(0x6b, 0x01, gTasks[taskId].data[1], RGB(30, 22, 11)); + BlendPalette(0x68, 0x01, gTasks[taskId].data[1], RGB(31, 31, 31)); + BlendPalette(0x6e, 0x01, gTasks[taskId].data[1], RGB(30, 29, 29)); + } + if (gTasks[taskId].data[1] == 0) + eContestLink80C2020Struct2018000.unk_0a = 0; + else + eContestLink80C2020Struct2018000.unk_0a = 1; +} + +void sub_80C3024(u16 species, u8 destOffset, u8 srcOffset, bool8 useDmaNow, u32 personality) +{ + int i; + int j; + u16 tile; + u16 offset; + u16 var0; + u16 var1; + + if (useDmaNow) + { + DmaCopy32Defvars(3, GetMonIconPtr(species, personality) + (srcOffset << 9) + 0x80, BG_CHAR_ADDR(1) + (destOffset << 9), 0x180); + var0 = ((destOffset + 10) << 12); + var1 = (destOffset * 16 + 0x200); + tile = var1 | var0; + offset = destOffset * 0x60 + 0x83; + for (i = 0; i < 3; i++) + { + for (j = 0; j < 4; j++) + { + ((u16 *)BG_CHAR_ADDR(3))[(i << 5) + j + offset] = tile; + tile++; + } + } + } + else + { + RequestSpriteCopy(GetMonIconPtr(species, personality) + (srcOffset << 9) + 0x80, BG_CHAR_ADDR(1) + (destOffset << 9), 0x180); + } +} + +static void LoadAllContestMonIcons(u8 srcOffset, bool8 useDmaNow) +{ + int i; + + for (i = 0; i < 4; i++) + { + sub_80C3024(gContestMons[i].species, i, srcOffset, useDmaNow, gContestMons[i].personality); + } +} + +void sub_80C310C(void) +{ + int i; + register u16 species asm("r0"); + + for (i = 0; i < 4; i++) + { + species = mon_icon_convert_unown_species_id(gContestMons[i].species, 0); + LoadPalette(gMonIconPalettes[gMonIconPaletteIndices[species]], 0xa0 + 0x10 * i, 0x20); + } +} + +#ifdef NONMATCHING +void sub_80C3158(const u8 *string, u8 spriteId) +{ + int i, j; + u8 width; + u8 * displayedStringBattle; + void * dest; + u8 * d1; + u8 * d2; + void *d3; + void *d4; + void *d5; + void *d6; + int w; + u16 sp00[4]; + struct Sprite *sprite = &gSprites[spriteId]; + sp00[0] = gSprites[spriteId].oam.tileNum; + sp00[1] = gSprites[sprite->data[0]].oam.tileNum; + sp00[2] = gSprites[sprite->data[1]].oam.tileNum; + sp00[3] = gSprites[sprite->data[2]].oam.tileNum; + + for (i = 0; i < 4; i++) + { + DmaClear32(3, (void *)VRAM + 0x10000 + 32 * sp00[i], 0x400); + } + + width = Text_GetStringWidthFromWindowTemplate(&gWindowTemplate_81E7278, string); + displayedStringBattle = gDisplayedStringBattle; + displayedStringBattle = StringCopy(displayedStringBattle, gUnknown_083D17E2); + if ((~width + 1) & 7) + { + displayedStringBattle[0] = EXT_CTRL_CODE_BEGIN; + displayedStringBattle[1] = 0x11; + displayedStringBattle[2] = ((~width + 1) & 7) / 2; + displayedStringBattle += 3; + } + + width += -8 & (width + 7); + displayedStringBattle = StringCopy(displayedStringBattle, string); + + displayedStringBattle[0] = EXT_CTRL_CODE_BEGIN; + displayedStringBattle[1] = 0x13; + displayedStringBattle[2] = width; + displayedStringBattle[3] = EOS; + + sub_80034D4(eContestLink80C2020Struct2018068, gDisplayedStringBattle); + + CpuCopy32(&gUnknown_083D1624[0x0], (void *)0x6010000 + 32 * sp00[0], 32); + CpuCopy32(&gUnknown_083D1624[0x40], (void *)0x6010000 + 32 * sp00[0] + 0x100, 32); + CpuCopy32(&gUnknown_083D1624[0x40], (void *)0x6010000 + 32 * sp00[0] + 0x200, 32); + CpuCopy32(&gUnknown_083D1624[0x20], (void *)0x6010000 + 32 * sp00[0] + 0x300, 32); + + w = width / 8; + j = 0; + if (j <= w) + { + d2 = eContestLink80C2020Struct2018068 + 0x20; + d1 = eContestLink80C2020Struct2018068; + d3 = (void *)VRAM + 0x0FD20; + d4 = (void *)VRAM + 0x0FE20; + d5 = (void *)VRAM + 0x0FF20; + d6 = (void *)VRAM + 0x10020; + while (j <= w) + { + if (j < 7) + dest = 32 * sp00[0] + d6; + else if (j < 15) + dest = 32 * sp00[1] + d5; + else if (j < 23) + dest = 32 * sp00[2] + d4; + else + dest = 32 * sp00[3] + d3; + + if (j == w) + break; + + CpuCopy32(gUnknown_083D16E4, dest, 32); + CpuCopy32(gUnknown_083D16E4 + 0x10, dest + 0x300, 32); + CpuCopy32(j * 0x40 + d2, dest + 0x100, 32); + CpuCopy32(j * 0x40 + d1, dest + 0x200, 32); + + d3 += 0x20; + d4 += 0x20; + d5 += 0x20; + d6 += 0x20; + j++; + } + } + + CpuCopy32(gUnknown_083D1644, dest, 32); + CpuCopy32(gUnknown_083D1644 + 0x40, dest + 0x100, 32); + CpuCopy32(gUnknown_083D1644 + 0x40, dest + 0x200, 32); + CpuCopy32(gUnknown_083D1644 + 0x20, dest + 0x300, 32); +} +#else +asm(".include \"constants/gba_constants.inc\""); +asm(".include \"include/macros.inc\""); +NAKED +void sub_80C3158(const u8 * string, u8 spriteId) +{ + asm_unified("\tpush {r4-r7,lr}\n" + "\tmov r7, r10\n" + "\tmov r6, r9\n" + "\tmov r5, r8\n" + "\tpush {r5-r7}\n" + "\tsub sp, 0x1C\n" + "\tmov r9, r0\n" + "\tlsls r1, 24\n" + "\tlsrs r1, 24\n" + "\tlsls r2, r1, 4\n" + "\tadds r2, r1\n" + "\tlsls r2, 2\n" + "\tldr r3, _080C32C0 @ =gSprites\n" + "\tadds r2, r3\n" + "\tmov r1, sp\n" + "\tldrh r0, [r2, 0x4]\n" + "\tlsls r0, 22\n" + "\tlsrs r0, 22\n" + "\tstrh r0, [r1]\n" + "\tmov r4, sp\n" + "\tmovs r0, 0x2E\n" + "\tldrsh r1, [r2, r0]\n" + "\tlsls r0, r1, 4\n" + "\tadds r0, r1\n" + "\tlsls r0, 2\n" + "\tadds r0, r3\n" + "\tldrh r0, [r0, 0x4]\n" + "\tlsls r0, 22\n" + "\tlsrs r0, 22\n" + "\tstrh r0, [r4, 0x2]\n" + "\tmovs r0, 0x30\n" + "\tldrsh r1, [r2, r0]\n" + "\tlsls r0, r1, 4\n" + "\tadds r0, r1\n" + "\tlsls r0, 2\n" + "\tadds r0, r3\n" + "\tldrh r0, [r0, 0x4]\n" + "\tlsls r0, 22\n" + "\tlsrs r0, 22\n" + "\tstrh r0, [r4, 0x4]\n" + "\tmovs r0, 0x32\n" + "\tldrsh r1, [r2, r0]\n" + "\tlsls r0, r1, 4\n" + "\tadds r0, r1\n" + "\tlsls r0, 2\n" + "\tadds r0, r3\n" + "\tldrh r0, [r0, 0x4]\n" + "\tlsls r0, 22\n" + "\tlsrs r0, 22\n" + "\tstrh r0, [r4, 0x6]\n" + "\tldr r1, _080C32C4 @ =gWindowTemplate_81E7278\n" + "\tmov r8, r1\n" + "\tldr r7, _080C32C8 @ =0x06010000\n" + "\tldr r2, _080C32CC @ =0x040000d4\n" + "\tldr r6, _080C32D0 @ =0x85000100\n" + "\tmov r1, sp\n" + "\tmovs r5, 0\n" + "\tadd r3, sp, 0x8\n" + "\tmovs r4, 0x3\n" + "_080C31CE:\n" + "\tldrh r0, [r1]\n" + "\tlsls r0, 5\n" + "\tadds r0, r7\n" + "\tstr r5, [sp, 0x8]\n" + "\tstr r3, [r2]\n" + "\tstr r0, [r2, 0x4]\n" + "\tstr r6, [r2, 0x8]\n" + "\tldr r0, [r2, 0x8]\n" + "\tadds r1, 0x2\n" + "\tsubs r4, 0x1\n" + "\tcmp r4, 0\n" + "\tbge _080C31CE\n" + "\tmov r0, r8\n" + "\tmov r1, r9\n" + "\tbl Text_GetStringWidthFromWindowTemplate\n" + "\tlsls r0, 24\n" + "\tlsrs r5, r0, 24\n" + "\tldr r2, _080C32D4 @ =gDisplayedStringBattle\n" + "\tldr r1, _080C32D8 @ =gUnknown_083D17E2\n" + "\tadds r0, r2, 0\n" + "\tbl StringCopy\n" + "\tadds r2, r0, 0\n" + "\tmvns r0, r5\n" + "\tadds r1, r0, 0x1\n" + "\tmovs r0, 0x7\n" + "\tands r1, r0\n" + "\tcmp r1, 0\n" + "\tbeq _080C3218\n" + "\tmovs r0, 0xFC\n" + "\tstrb r0, [r2]\n" + "\tmovs r0, 0x11\n" + "\tstrb r0, [r2, 0x1]\n" + "\tlsrs r0, r1, 1\n" + "\tstrb r0, [r2, 0x2]\n" + "\tadds r2, 0x3\n" + "_080C3218:\n" + "\tadds r6, r5, 0x7\n" + "\tmovs r1, 0x8\n" + "\tnegs r1, r1\n" + "\tadds r0, r1, 0\n" + "\tands r6, r0\n" + "\tlsls r6, 24\n" + "\tlsrs r5, r6, 24\n" + "\tadds r0, r2, 0\n" + "\tmov r1, r9\n" + "\tbl StringCopy\n" + "\tadds r2, r0, 0\n" + "\tmovs r0, 0xFC\n" + "\tstrb r0, [r2]\n" + "\tmovs r0, 0x13\n" + "\tstrb r0, [r2, 0x1]\n" + "\tstrb r5, [r2, 0x2]\n" + "\tmovs r0, 0xFF\n" + "\tstrb r0, [r2, 0x3]\n" + "\tldr r0, _080C32DC @ =gSharedMem + 0x18068\n" + "\tmov r10, r0\n" + "\tldr r1, _080C32D4 @ =gDisplayedStringBattle\n" + "\tbl sub_80034D4\n" + "\tmov r0, sp\n" + "\tldrh r4, [r0]\n" + "\tlsls r4, 5\n" + "\tldr r1, _080C32C8 @ =0x06010000\n" + "\tadds r7, r4, r1\n" + "\tldr r0, _080C32E0 @ =gUnknown_083D1624\n" + "\tmov r9, r0\n" + "\tldr r1, _080C32E4 @ =REG_BG0CNT\n" + "\tmov r8, r1\n" + "\tadds r1, r7, 0\n" + "\tmov r2, r8\n" + "\tbl CpuSet\n" + "\tmov r5, r9\n" + "\tadds r5, 0x80\n" + "\tldr r0, _080C32E8 @ =0x06010100\n" + "\tadds r1, r4, r0\n" + "\tadds r0, r5, 0\n" + "\tmov r2, r8\n" + "\tbl CpuSet\n" + "\tldr r0, _080C32EC @ =0x06010200\n" + "\tadds r1, r4, r0\n" + "\tadds r0, r5, 0\n" + "\tmov r2, r8\n" + "\tbl CpuSet\n" + "\tmov r0, r9\n" + "\tadds r0, 0x40\n" + "\tldr r1, _080C32F0 @ =0x06010300\n" + "\tadds r4, r1\n" + "\tadds r1, r4, 0\n" + "\tmov r2, r8\n" + "\tbl CpuSet\n" + "\tlsrs r5, r6, 27\n" + "\tmovs r4, 0\n" + "\tcmp r4, r5\n" + "\tbgt _080C3382\n" + "\tmov r6, sp\n" + "\tmov r0, r10\n" + "\tadds r0, 0x20\n" + "\tstr r0, [sp, 0xC]\n" + "\tmov r1, r10\n" + "\tstr r1, [sp, 0x10]\n" + "\tldr r0, _080C32F4 @ =0x0600fd20\n" + "\tstr r0, [sp, 0x14]\n" + "\tldr r1, _080C32F8 @ =0x0600fe20\n" + "\tstr r1, [sp, 0x18]\n" + "\tldr r0, _080C32FC @ =0x0600ff20\n" + "\tmov r10, r0\n" + "\tldr r1, _080C3300 @ =0x06010020\n" + "\tmov r9, r1\n" + "_080C32B2:\n" + "\tcmp r4, 0x6\n" + "\tbgt _080C3304\n" + "\tldrh r0, [r6]\n" + "\tlsls r0, 5\n" + "\tmov r1, r9\n" + "\tb _080C3322\n" + "\t.align 2, 0\n" + "_080C32C0: .4byte gSprites\n" + "_080C32C4: .4byte gWindowTemplate_81E7278\n" + "_080C32C8: .4byte 0x06010000\n" + "_080C32CC: .4byte 0x040000d4\n" + "_080C32D0: .4byte 0x85000100\n" + "_080C32D4: .4byte gDisplayedStringBattle\n" + "_080C32D8: .4byte gUnknown_083D17E2\n" + "_080C32DC: .4byte gSharedMem + 0x18068\n" + "_080C32E0: .4byte gUnknown_083D1624\n" + "_080C32E4: .4byte REG_BG0CNT\n" + "_080C32E8: .4byte 0x06010100\n" + "_080C32EC: .4byte 0x06010200\n" + "_080C32F0: .4byte 0x06010300\n" + "_080C32F4: .4byte 0x0600fd20\n" + "_080C32F8: .4byte 0x0600fe20\n" + "_080C32FC: .4byte 0x0600ff20\n" + "_080C3300: .4byte 0x06010020\n" + "_080C3304:\n" + "\tcmp r4, 0xE\n" + "\tbgt _080C3310\n" + "\tldrh r0, [r6, 0x2]\n" + "\tlsls r0, 5\n" + "\tmov r1, r10\n" + "\tb _080C3322\n" + "_080C3310:\n" + "\tcmp r4, 0x16\n" + "\tbgt _080C331C\n" + "\tldrh r0, [r6, 0x4]\n" + "\tlsls r0, 5\n" + "\tldr r1, [sp, 0x18]\n" + "\tb _080C3322\n" + "_080C331C:\n" + "\tldrh r0, [r6, 0x6]\n" + "\tlsls r0, 5\n" + "\tldr r1, [sp, 0x14]\n" + "_080C3322:\n" + "\tadds r7, r0, r1\n" + "\tcmp r4, r5\n" + "\tbeq _080C3382\n" + "\tldr r0, _080C33D0 @ =gUnknown_083D16E4\n" + "\tadds r1, r7, 0\n" + "\tmov r2, r8\n" + "\tbl CpuSet\n" + "\tmovs r0, 0xC0\n" + "\tlsls r0, 2\n" + "\tadds r1, r7, r0\n" + "\tldr r0, _080C33D0 @ =gUnknown_083D16E4\n" + "\tadds r0, 0x20\n" + "\tmov r2, r8\n" + "\tbl CpuSet\n" + "\tmovs r0, 0x80\n" + "\tlsls r0, 1\n" + "\tadds r1, r7, r0\n" + "\tldr r0, [sp, 0x10]\n" + "\tmov r2, r8\n" + "\tbl CpuSet\n" + "\tmovs r0, 0x80\n" + "\tlsls r0, 2\n" + "\tadds r1, r7, r0\n" + "\tldr r0, [sp, 0xC]\n" + "\tmov r2, r8\n" + "\tbl CpuSet\n" + "\tldr r1, [sp, 0xC]\n" + "\tadds r1, 0x40\n" + "\tstr r1, [sp, 0xC]\n" + "\tldr r0, [sp, 0x10]\n" + "\tadds r0, 0x40\n" + "\tstr r0, [sp, 0x10]\n" + "\tldr r1, [sp, 0x14]\n" + "\tadds r1, 0x20\n" + "\tstr r1, [sp, 0x14]\n" + "\tldr r0, [sp, 0x18]\n" + "\tadds r0, 0x20\n" + "\tstr r0, [sp, 0x18]\n" + "\tmovs r1, 0x20\n" + "\tadd r10, r1\n" + "\tadd r9, r1\n" + "\tadds r4, 0x1\n" + "\tcmp r4, r5\n" + "\tble _080C32B2\n" + "_080C3382:\n" + "\tldr r4, _080C33D4 @ =gUnknown_083D1644\n" + "\tldr r5, _080C33D8 @ =REG_BG0CNT\n" + "\tadds r0, r4, 0\n" + "\tadds r1, r7, 0\n" + "\tadds r2, r5, 0\n" + "\tbl CpuSet\n" + "\tadds r6, r4, 0\n" + "\tadds r6, 0x80\n" + "\tmovs r0, 0x80\n" + "\tlsls r0, 1\n" + "\tadds r1, r7, r0\n" + "\tadds r0, r6, 0\n" + "\tadds r2, r5, 0\n" + "\tbl CpuSet\n" + "\tmovs r0, 0x80\n" + "\tlsls r0, 2\n" + "\tadds r1, r7, r0\n" + "\tadds r0, r6, 0\n" + "\tadds r2, r5, 0\n" + "\tbl CpuSet\n" + "\tadds r4, 0x40\n" + "\tmovs r0, 0xC0\n" + "\tlsls r0, 2\n" + "\tadds r1, r7, r0\n" + "\tadds r0, r4, 0\n" + "\tadds r2, r5, 0\n" + "\tbl CpuSet\n" + "\tadd sp, 0x1C\n" + "\tpop {r3-r5}\n" + "\tmov r8, r3\n" + "\tmov r9, r4\n" + "\tmov r10, r5\n" + "\tpop {r4-r7}\n" + "\tpop {r0}\n" + "\tbx r0\n" + "\t.align 2, 0\n" + "_080C33D0: .4byte gUnknown_083D16E4\n" + "_080C33D4: .4byte gUnknown_083D1644\n" + "_080C33D8: .4byte REG_BG0CNT"); +} +#endif //NONMATCHING + +void sub_80C33DC(void) +{ + int i; + struct SpriteTemplate template; + u8 spriteIds[8]; + + template = gSpriteTemplate_83D174C; + for (i = 0; i <8; i++) + LoadSpriteSheet(&gUnknown_083D1764[i]); + + LoadSpritePalette(&gUnknown_083D17A4); + for (i = 0; i < 8; i++) + { + spriteIds[i] = CreateSprite(&template, 272, 144, 10); + template.tileTag++; + } + + gSprites[spriteIds[0]].data[0] = spriteIds[1]; + gSprites[spriteIds[0]].data[1] = spriteIds[2]; + gSprites[spriteIds[0]].data[2] = spriteIds[3]; + + gSprites[spriteIds[4]].data[0] = spriteIds[5]; + gSprites[spriteIds[4]].data[1] = spriteIds[6]; + gSprites[spriteIds[4]].data[2] = spriteIds[7]; + + eContestLink80C2020Struct2018000.unk_00 = spriteIds[0]; + eContestLink80C2020Struct2018000.unk_04 = 0; + eContestLink80C2020Struct2018000.unk_01 = spriteIds[4]; + sub_80C3764(); +} + +u16 sub_80C34AC(const u8 * string) +{ + u8 width = (StringLength(string) * 6); + return 0x70 - (width / 2); +} + +void sub_80C34CC(s16 arg0, u16 y, u16 arg2, u16 arg3) +{ + struct Sprite *sprite = &gSprites[eContestLink80C2020Struct2018000.unk_00]; + sprite->pos1.x = 272; + sprite->pos1.y = y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + sprite->data[4] = arg0 + 32; + sprite->data[5] = arg2; + sprite->data[6] = arg3; + sprite->data[7] = 0; + sprite->callback = sub_80C3588; + eContestLink80C2020Struct2018000.unk_04 = 1; +} + +void sub_80C3520(u16 arg0) +{ + struct Sprite *sprite = &gSprites[eContestLink80C2020Struct2018000.unk_00]; + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + sprite->data[6] = arg0; + sprite->data[7] = 0; + sprite->callback = sub_80C3630; + eContestLink80C2020Struct2018000.unk_04 = 3; +} + +void sub_80C3564(struct Sprite *sprite) +{ + sprite->pos1.x = 272; + sprite->pos1.y = 144; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + sprite->callback = SpriteCallbackDummy; + eContestLink80C2020Struct2018000.unk_04 = 0; +} + + +void sub_80C3588(struct Sprite *sprite) +{ + int i; + s16 var0; + + var0 = (u16)sprite->data[7] + (u16)sprite->data[6]; + sprite->pos1.x -= var0 >> 8; + sprite->data[7] = (sprite->data[6] + sprite->data[7]) & 0xFF; + if (sprite->pos1.x < sprite->data[4]) + sprite->pos1.x = sprite->data[4]; + + for (i = 0; i < 3; i++) + { + struct Sprite *sprite2 = &gSprites[sprite->data[i]]; + sprite2->pos1.x = sprite->pos1.x + sprite->pos2.x + (i + 1) * 64; + } + + if (sprite->pos1.x == sprite->data[4]) + sprite->callback = sub_80C35FC; +} + +void sub_80C35FC(struct Sprite *sprite) +{ + eContestLink80C2020Struct2018000.unk_04 = 2; + if ((u16)sprite->data[5] != 0xFFFF) + { + if (--sprite->data[5] == -1) + sub_80C3520(sprite->data[6]); + } +} + +void sub_80C3630(struct Sprite *sprite) +{ + int i; + s16 var0; + + var0 = (u16)sprite->data[7] + (u16)sprite->data[6]; + sprite->pos1.x -= var0 >> 8; + sprite->data[7] = (sprite->data[6] + sprite->data[7]) & 0xFF; + for (i = 0; i < 3; i++) + { + struct Sprite *sprite2 = &gSprites[sprite->data[i]]; + sprite2->pos1.x = sprite->pos1.x + sprite->pos2.x + (i + 1) * 64; + } + + if (sprite->pos1.x + sprite->pos2.x < -224) + sub_80C3564(sprite); +} + +void sub_80C3698(const u8 *text) +{ + int i; + u16 x; + struct Sprite *sprite; + + sub_80C3158(text, eContestLink80C2020Struct2018000.unk_01); + x = sub_80C34AC(text); + sprite = &gSprites[eContestLink80C2020Struct2018000.unk_01]; + sprite->pos1.x = x + 32; + sprite->pos1.y = 80; + sprite->invisible = 0; + for (i = 0; i < 3; i++) + { + gSprites[sprite->data[i]].pos1.x = sprite->pos1.x + sprite->pos2.x + (i + 1) * 64; + gSprites[sprite->data[i]].pos1.y = sprite->pos1.y; + gSprites[sprite->data[i]].invisible = 0; + } + + gBattle_WIN0H = 0x00F0; + gBattle_WIN0V = ((sprite->pos1.y - 16) << 8) | (sprite->pos1.y + 16); + REG_WININ = WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR | WININ_WIN0_BG1 | WININ_WIN0_BG2 | WININ_WIN0_BG3 | WININ_WIN0_OBJ | WININ_WIN0_CLR; +} + +void sub_80C3764(void) +{ + int i; + struct Sprite *sprite; + + sprite = &gSprites[eContestLink80C2020Struct2018000.unk_01]; + sprite->invisible = 1; + for (i = 0; i < 3; i++) + gSprites[sprite->data[i]].invisible = 1; + + gBattle_WIN0H = 0; + gBattle_WIN0V = 0; + REG_WIN0H = gBattle_WIN0H; + REG_WIN0V = gBattle_WIN0V; + REG_WININ = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR; +} + +#ifdef ENGLISH +#ifdef NONMATCHING +static inline s32 de_sub_80C39A8(s32 a0) +{ + s32 result = 0; + if (gIsLinkContest & 0x1) + { + sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 9, 2, 8, 2); + result = 8; + } + else if (gSpecialVar_ContestRank == 0) + { + sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 0, 0, 9, 2); + result = 9; + } + else if (gSpecialVar_ContestRank == 1) + { + sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 9, 0, 8, 2); + result = 8; + } + else if (gSpecialVar_ContestRank == 2) + { + sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 17, 0, 8, 2); + result = 8; + } + else + { + sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 0, 2, 9, 2); + result = 9; + } + return result; +} + +static inline s32 de_sub_80C3A84(s32 a0, s32 * a1) +{ + s32 result; + if (gSpecialVar_ContestCategory == 0) + { + *a1 = 0; + sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 17, 2, 10, 2); + result = 10; + } + else if (gSpecialVar_ContestCategory == 1) + { + *a1 = 1; + sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 0, 4, 11, 2); + result = 11; + } + else if (gSpecialVar_ContestCategory == 2) + { + *a1 = 2; + sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 11, 4, 10, 2); + result = 10; + } + else if (gSpecialVar_ContestCategory == 3) + { + *a1 = 3; + sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 21, 4, 10, 2); + result = 10; + } + else + { + *a1 = 4; + sub_809D104((void *)0x0600E000, a0, 1, gUnknown_08E964B8, 0, 6, 10, 2); + result = 10; + } + return result; +} + +void sub_80C37E4(void) +{ + s32 sp0; + s32 i; + de_sub_80C3A84(de_sub_80C39A8(5) + 5, &sp0); + for (i = 0; i < 0x80; i++) + { + ((vu16 *)0x0600E000)[i] &= 0xFFF; + ((vu16 *)0x0600E000)[i] |= sp0 << 12;; + } +} +#else +NAKED +void sub_80C37E4(void) +{ + asm_unified("\tpush {r4-r6,lr}\n" + "\tsub sp, 0x10\n" + "\tmovs r5, 0x1\n" + "\tmovs r4, 0\n" + "\tldr r0, _080C3808 @ =gIsLinkContest\n" + "\tldrb r0, [r0]\n" + "\tadds r1, r5, 0\n" + "\tands r1, r0\n" + "\tcmp r1, 0\n" + "\tbeq _080C3814\n" + "\tldr r0, _080C380C @ =0x0600e000\n" + "\tldr r3, _080C3810 @ =gUnknown_08E964B8\n" + "\tmovs r1, 0x9\n" + "\tstr r1, [sp]\n" + "\tmovs r2, 0x2\n" + "\tstr r2, [sp, 0x4]\n" + "\tb _080C386A\n" + "\t.align 2, 0\n" + "_080C3808: .4byte gIsLinkContest\n" + "_080C380C: .4byte 0x0600e000\n" + "_080C3810: .4byte gUnknown_08E964B8\n" + "_080C3814:\n" + "\tldr r0, _080C3830 @ =gSpecialVar_ContestRank\n" + "\tldrh r2, [r0]\n" + "\tcmp r2, 0\n" + "\tbne _080C383C\n" + "\tmovs r4, 0x1\n" + "\tldr r0, _080C3834 @ =0x0600e000\n" + "\tldr r3, _080C3838 @ =gUnknown_08E964B8\n" + "\tstr r2, [sp]\n" + "\tstr r2, [sp, 0x4]\n" + "\tmovs r1, 0x9\n" + "\tstr r1, [sp, 0x8]\n" + "\tmovs r1, 0x2\n" + "\tstr r1, [sp, 0xC]\n" + "\tb _080C3870\n" + "\t.align 2, 0\n" + "_080C3830: .4byte gSpecialVar_ContestRank\n" + "_080C3834: .4byte 0x0600e000\n" + "_080C3838: .4byte gUnknown_08E964B8\n" + "_080C383C:\n" + "\tcmp r2, 0x1\n" + "\tbne _080C385C\n" + "\tldr r0, _080C3854 @ =0x0600e000\n" + "\tldr r3, _080C3858 @ =gUnknown_08E964B8\n" + "\tmovs r1, 0x9\n" + "\tstr r1, [sp]\n" + "\tstr r4, [sp, 0x4]\n" + "\tmovs r1, 0x8\n" + "\tstr r1, [sp, 0x8]\n" + "\tmovs r1, 0x2\n" + "\tstr r1, [sp, 0xC]\n" + "\tb _080C3870\n" + "\t.align 2, 0\n" + "_080C3854: .4byte 0x0600e000\n" + "_080C3858: .4byte gUnknown_08E964B8\n" + "_080C385C:\n" + "\tcmp r2, 0x2\n" + "\tbne _080C3884\n" + "\tldr r0, _080C387C @ =0x0600e000\n" + "\tldr r3, _080C3880 @ =gUnknown_08E964B8\n" + "\tmovs r1, 0x11\n" + "\tstr r1, [sp]\n" + "\tstr r4, [sp, 0x4]\n" + "_080C386A:\n" + "\tmovs r1, 0x8\n" + "\tstr r1, [sp, 0x8]\n" + "\tstr r2, [sp, 0xC]\n" + "_080C3870:\n" + "\tmovs r1, 0x5\n" + "\tmovs r2, 0x1\n" + "\tbl sub_809D104\n" + "\tb _080C389E\n" + "\t.align 2, 0\n" + "_080C387C: .4byte 0x0600e000\n" + "_080C3880: .4byte gUnknown_08E964B8\n" + "_080C3884:\n" + "\tmovs r4, 0x1\n" + "\tldr r0, _080C38C0 @ =0x0600e000\n" + "\tldr r3, _080C38C4 @ =gUnknown_08E964B8\n" + "\tstr r1, [sp]\n" + "\tmovs r2, 0x2\n" + "\tstr r2, [sp, 0x4]\n" + "\tmovs r1, 0x9\n" + "\tstr r1, [sp, 0x8]\n" + "\tstr r2, [sp, 0xC]\n" + "\tmovs r1, 0x5\n" + "\tmovs r2, 0x1\n" + "\tbl sub_809D104\n" + "_080C389E:\n" + "\tadds r4, 0xD\n" + "\tldr r0, _080C38C8 @ =gSpecialVar_ContestCategory\n" + "\tldrh r0, [r0]\n" + "\tcmp r0, 0\n" + "\tbne _080C38CC\n" + "\tmovs r6, 0\n" + "\tldr r0, _080C38C0 @ =0x0600e000\n" + "\tldr r3, _080C38C4 @ =gUnknown_08E964B8\n" + "\tmovs r1, 0x11\n" + "\tstr r1, [sp]\n" + "\tmovs r2, 0x2\n" + "\tstr r2, [sp, 0x4]\n" + "\tmovs r1, 0xA\n" + "\tstr r1, [sp, 0x8]\n" + "\tstr r2, [sp, 0xC]\n" + "\tb _080C392A\n" + "\t.align 2, 0\n" + "_080C38C0: .4byte 0x0600e000\n" + "_080C38C4: .4byte gUnknown_08E964B8\n" + "_080C38C8: .4byte gSpecialVar_ContestCategory\n" + "_080C38CC:\n" + "\tcmp r0, 0x1\n" + "\tbne _080C38EC\n" + "\tmovs r6, 0x1\n" + "\tldr r0, _080C38E4 @ =0x0600e000\n" + "\tldr r3, _080C38E8 @ =gUnknown_08E964B8\n" + "\tmovs r1, 0\n" + "\tstr r1, [sp]\n" + "\tmovs r1, 0x4\n" + "\tstr r1, [sp, 0x4]\n" + "\tmovs r1, 0xB\n" + "\tb _080C3924\n" + "\t.align 2, 0\n" + "_080C38E4: .4byte 0x0600e000\n" + "_080C38E8: .4byte gUnknown_08E964B8\n" + "_080C38EC:\n" + "\tcmp r0, 0x2\n" + "\tbne _080C3910\n" + "\tmovs r6, 0x2\n" + "\tldr r0, _080C3908 @ =0x0600e000\n" + "\tldr r3, _080C390C @ =gUnknown_08E964B8\n" + "\tmovs r1, 0xB\n" + "\tstr r1, [sp]\n" + "\tmovs r1, 0x4\n" + "\tstr r1, [sp, 0x4]\n" + "\tmovs r1, 0xA\n" + "\tstr r1, [sp, 0x8]\n" + "\tstr r6, [sp, 0xC]\n" + "\tb _080C392A\n" + "\t.align 2, 0\n" + "_080C3908: .4byte 0x0600e000\n" + "_080C390C: .4byte gUnknown_08E964B8\n" + "_080C3910:\n" + "\tcmp r0, 0x3\n" + "\tbne _080C393C\n" + "\tmovs r6, 0x3\n" + "\tldr r0, _080C3934 @ =0x0600e000\n" + "\tldr r3, _080C3938 @ =gUnknown_08E964B8\n" + "\tmovs r1, 0x15\n" + "\tstr r1, [sp]\n" + "\tmovs r1, 0x4\n" + "\tstr r1, [sp, 0x4]\n" + "\tmovs r1, 0xA\n" + "_080C3924:\n" + "\tstr r1, [sp, 0x8]\n" + "\tmovs r1, 0x2\n" + "\tstr r1, [sp, 0xC]\n" + "_080C392A:\n" + "\tadds r1, r4, 0\n" + "\tadds r2, r5, 0\n" + "\tbl sub_809D104\n" + "\tb _080C395A\n" + "\t.align 2, 0\n" + "_080C3934: .4byte 0x0600e000\n" + "_080C3938: .4byte gUnknown_08E964B8\n" + "_080C393C:\n" + "\tmovs r6, 0x4\n" + "\tldr r0, _080C3984 @ =0x0600e000\n" + "\tldr r3, _080C3988 @ =gUnknown_08E964B8\n" + "\tmovs r1, 0\n" + "\tstr r1, [sp]\n" + "\tmovs r1, 0x6\n" + "\tstr r1, [sp, 0x4]\n" + "\tmovs r1, 0xA\n" + "\tstr r1, [sp, 0x8]\n" + "\tmovs r1, 0x2\n" + "\tstr r1, [sp, 0xC]\n" + "\tadds r1, r4, 0\n" + "\tadds r2, r5, 0\n" + "\tbl sub_809D104\n" + "_080C395A:\n" + "\tldr r5, _080C398C @ =0x00000fff\n" + "\tlsls r4, r6, 12\n" + "\tldr r2, _080C3984 @ =0x0600e000\n" + "\tmovs r3, 0x7F\n" + "_080C3962:\n" + "\tldrh r1, [r2]\n" + "\tadds r0, r5, 0\n" + "\tands r0, r1\n" + "\tstrh r0, [r2]\n" + "\tldrh r1, [r2]\n" + "\tadds r0, r4, 0\n" + "\torrs r0, r1\n" + "\tstrh r0, [r2]\n" + "\tadds r2, 0x2\n" + "\tsubs r3, 0x1\n" + "\tcmp r3, 0\n" + "\tbge _080C3962\n" + "\tadd sp, 0x10\n" + "\tpop {r4-r6}\n" + "\tpop {r0}\n" + "\tbx r0\n" + "\t.align 2, 0\n" + "_080C3984: .4byte 0x0600e000\n" + "_080C3988: .4byte gUnknown_08E964B8\n" + "_080C398C: .4byte 0x00000fff"); +} +#endif // NONMATCHING + +#elif defined(GERMAN) +s16 de_sub_80C39A8(s32 a0) +{ + s16 result; + if (gIsLinkContest & 1) + { + sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 11, 3, 8, 3); + result = 8; + } + else if (gSpecialVar_ContestRank == 0) + { + sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 0, 0, 11, 3); + result = 11; + } + else if (gSpecialVar_ContestRank == 1) + { + sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 11, 0, 10, 3); + result = 10; + } + else if (gSpecialVar_ContestRank == 2) + { + sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 21, 0, 10, 3); + result = 10; + } + else + { + sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 0, 3, 11, 3); + result = 11; + } + return result; +} + +s16 de_sub_80C3A84(s32 a0, s32 * a1) +{ + s16 result; + if (gSpecialVar_ContestCategory == 0) + { + *a1 = 0; + sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 19, 3, 7, 3); + result = 7; + } + else if (gSpecialVar_ContestCategory == 1) + { + *a1 = 1; + sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 0, 6, 7, 3); + result = 7; + } + else if (gSpecialVar_ContestCategory == 2) + { + *a1 = 2; + sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 7, 6, 4, 3); + result = 4; + } + else if (gSpecialVar_ContestCategory == 3) + { + *a1 = 3; + sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 11, 6, 6, 3); + result = 6; + } + else + { + *a1 = 4; + sub_809D104((void *)0x0600E000, a0, 0, gUnknown_08E964B8, 17, 6, 5, 3); + result = 5; + } + return result; +} + +void sub_80C37E4(void) +{ + s32 sp0; + s32 i; + de_sub_80C3A84(de_sub_80C39A8(6) + 6, &sp0); + for (i = 0; i < 0x80; i++) + { + ((vu16 *)0x0600E000)[i] &= 0xFFF; + ((vu16 *)0x0600E000)[i] |= sp0 << 12;; + } +} +#endif + +// fakematching? +u8 sub_80C3990(u8 monIndex, u8 arg1) +{ + u32 var0; + u32 var1; + + var0 = gContestMonConditions[monIndex] << 16; + var1 = var0 / 0x3F; + if (var1 & 0xFFFF) + var1 += 0x10000; + + var1 >>= 16; + if (var1 == 0 && var0) + var1 = 1; + + if (arg1 && var1 > 10) + var1 = 10; + + return var1; +} + +s8 sub_80C39E4(u8 arg0, u8 arg1) +{ + u32 r4; + u32 r2; + s16 val; + s8 ret; + + val = gUnknown_02038688[arg0]; + if (val < 0) + r4 = -val << 16; + else + r4 = val << 16; + r2 = r4 / 80; + if (r2 & 0xFFFF) + r2 += 0x10000; + + r2 >>= 16; + if (r2 == 0 && r4 != 0) + r2 = 1; + + if (arg1 != 0 && r2 > 10) + r2 = 10; + + if (gUnknown_02038688[arg0] < 0) + ret = -r2; + else + ret = r2; + + return ret; +} + +void sub_80C3A5C(u8 taskId) +{ + u16 firstTileNum; + + if (gTasks[taskId].data[10] == 0) + { + gTasks[taskId].data[11] = (3 - gTasks[taskId].data[0]) * 40; + gTasks[taskId].data[10]++; + } + else if (gTasks[taskId].data[10] == 1) + { + if (--gTasks[taskId].data[11] == -1) + { + firstTileNum = gTasks[taskId].data[0] * 2 + 0x5043; + *(vu16 *)(0x0600E142 + gTasks[taskId].data[1] * 192) = firstTileNum + 0x00; + *(vu16 *)(0x0600E144 + gTasks[taskId].data[1] * 192) = firstTileNum + 0x01; + *(vu16 *)(0x0600E182 + gTasks[taskId].data[1] * 192) = firstTileNum + 0x10; + *(vu16 *)(0x0600E184 + gTasks[taskId].data[1] * 192) = firstTileNum + 0x11; + eContestLink80C2020Struct2018000.unk_05++; + DestroyTask(taskId); + PlaySE(SE_JYUNI); + } + } +} + +#ifdef NONMATCHING +void sub_80C3B30(u8 taskId) +{ + int i, j, k; + + for (i = 0; i < 4 && gContestFinalStandings[i] != 0; i++) + ; + + for (j = 0; j < 3; j++) + { + for (k = 0; k < 30; k++) + { + ((u16 *)(0x0600E100 + 2 * (96 * i + 32 * j)))[k] &= 0x0FFF; + ((u16 *)(0x0600E100 + 2 * (96 * i + 32 * j)))[k] |= 0x9000; + } + } + gTasks[taskId].data[10] = i; + gTasks[taskId].data[12] = 1; + gTasks[taskId].func = sub_80C3BD8; + eContestLink80C2020Struct2018000.unk_03 = taskId; +} +#else +NAKED +void sub_80C3B30(u8 taskId) +{ + asm_unified("\tpush {r4-r7,lr}\n" + "\tmov r7, r10\n" + "\tmov r6, r9\n" + "\tmov r5, r8\n" + "\tpush {r5-r7}\n" + "\tlsls r0, 24\n" + "\tlsrs r0, 24\n" + "\tmov r12, r0\n" + "\tmovs r5, 0\n" + "\tldr r1, _080C3BC0 @ =gContestFinalStandings\n" + "\tldrb r0, [r1]\n" + "\tldr r2, _080C3BC4 @ =gTasks\n" + "\tmov r10, r2\n" + "\tcmp r0, 0\n" + "\tbeq _080C3B5C\n" + "_080C3B4E:\n" + "\tadds r5, 0x1\n" + "\tcmp r5, 0x3\n" + "\tbgt _080C3B5C\n" + "\tadds r0, r5, r1\n" + "\tldrb r0, [r0]\n" + "\tcmp r0, 0\n" + "\tbne _080C3B4E\n" + "_080C3B5C:\n" + "\tmovs r1, 0\n" + "\tlsls r0, r5, 1\n" + "\tmov r2, r12\n" + "\tlsls r2, 2\n" + "\tmov r9, r2\n" + "\tadds r0, r5\n" + "\tlsls r0, 5\n" + "\tmov r8, r0\n" + "\tldr r7, _080C3BC8 @ =0x00000fff\n" + "\tmovs r0, 0x90\n" + "\tlsls r0, 8\n" + "\tadds r6, r0, 0\n" + "_080C3B74:\n" + "\tlsls r0, r1, 5\n" + "\tadds r4, r1, 0x1\n" + "\tadd r0, r8\n" + "\t@ the next two instructions are swapped\n" + "\tmovs r3, 0x1D\n" + "\tlsls r0, 1\n" + "\tldr r1, _080C3BCC @ =0x0600e100\n" + "\tadds r2, r0, r1\n" + "_080C3B82:\n" + "\tldrh r1, [r2]\n" + "\tadds r0, r7, 0\n" + "\tands r0, r1\n" + "\torrs r0, r6\n" + "\tstrh r0, [r2]\n" + "\tadds r2, 0x2\n" + "\tsubs r3, 0x1\n" + "\tcmp r3, 0\n" + "\tbge _080C3B82\n" + "\tadds r1, r4, 0\n" + "\tcmp r1, 0x2\n" + "\tble _080C3B74\n" + "\tmov r0, r9\n" + "\tadd r0, r12\n" + "\tlsls r0, 3\n" + "\tadd r0, r10\n" + "\tstrh r5, [r0, 0x1C]\n" + "\tmovs r1, 0x1\n" + "\tstrh r1, [r0, 0x20]\n" + "\tldr r2, _080C3BD0 @ =sub_80C3BD8\n" + "\tstr r2, [r0]\n" + "\tmov r1, r12\n" + "\tldr r0, _080C3BD4 @ =gSharedMem + 0x18000\n" + "\tstrb r1, [r0, 0x3]\n" + "\tpop {r3-r5}\n" + "\tmov r8, r3\n" + "\tmov r9, r4\n" + "\tmov r10, r5\n" + "\tpop {r4-r7}\n" + "\tpop {r0}\n" + "\tbx r0\n" + "\t.align 2, 0\n" + "_080C3BC0: .4byte gContestFinalStandings\n" + "_080C3BC4: .4byte gTasks\n" + "_080C3BC8: .4byte 0x00000fff\n" + "_080C3BCC: .4byte 0x0600e100\n" + "_080C3BD0: .4byte sub_80C3BD8\n" + "_080C3BD4: .4byte gSharedMem + 0x18000"); +} +#endif //NONMATCHING + +void sub_80C3BD8(u8 taskId) +{ + if (++gTasks[taskId].data[11] == 1) + { + gTasks[taskId].data[11] = 0; + BlendPalette(0x91, 1, gTasks[taskId].data[12], RGB(13, 28, 27)); + if (gTasks[taskId].data[13] == 0) + { + if (++gTasks[taskId].data[12] == 16) + gTasks[taskId].data[13] = 1; + } + else + { + if (--gTasks[taskId].data[12] == 0) + gTasks[taskId].data[13] = 0; + } + } +} + +void sub_80C3C44(struct Sprite *sprite) +{ + if (sprite->data[0] < 10) + { + if (++sprite->data[0] == 10) + { + PlayCry1(sprite->data[1], 0); + sprite->data[1] = 0; + } + } + else + { + s16 delta = (u16)sprite->data[1] + 0x600; + sprite->pos1.x -= delta >> 8; + sprite->data[1] = (sprite->data[1] + 0x600) & 0xFF; + if (sprite->pos1.x < 120) + sprite->pos1.x = 120; + + if (sprite->pos1.x == 120) + { + sprite->callback = SpriteCallbackDummy; + sprite->data[1] = 0; + eContestLink80C2020Struct2018000.unk_06 = 1; + } + } +} + +void sub_80C3CB8(struct Sprite *sprite) +{ + s16 delta = (u16)sprite->data[1] + 0x600; + sprite->pos1.x -= delta >> 8; + sprite->data[1] = (sprite->data[1] + 0x600) & 0xFF; + if (sprite->pos1.x < -32) + { + sprite->callback = SpriteCallbackDummy; + sprite->invisible = 1; + eContestLink80C2020Struct2018000.unk_06 = 2; + } +} + +void sub_80C3D04(u8 taskId) +{ + if (++gTasks[taskId].data[0] == 5) + { + gTasks[taskId].data[0] = 0; + if (eContestLink80C2020Struct2018000.unk_07 < 40) + { + u8 spriteId = CreateSprite(&gSpriteTemplate_83D17B4, (Random() % 240) - 20, 44, 5); + gSprites[spriteId].data[0] = Random() % 512; + gSprites[spriteId].data[1] = (Random() % 24) + 16; + gSprites[spriteId].data[2] = (Random() % 256) + 48; + gSprites[spriteId].oam.tileNum += Random() % 17; + eContestLink80C2020Struct2018000.unk_07++; + } + } + + if (eContestLink80C2020Struct2018000.unk_09) + DestroyTask(taskId); +} + +void sub_80C3DF0(struct Sprite *sprite) +{ + register s16 var0 asm("r1"); + + sprite->data[3] += sprite->data[0]; + sprite->pos2.x = Sin(sprite->data[3] >> 8, sprite->data[1]); + var0 = sprite->data[4] + sprite->data[2]; + sprite->pos1.x += var0 >> 8; + var0 = var0 & 0xFF; + sprite->data[4] = var0; + sprite->pos1.y++; + if (eContestLink80C2020Struct2018000.unk_09) + sprite->invisible = 1; + + if (sprite->pos1.x > 248 || sprite->pos1.y > 116) + { + DestroySprite(sprite); + eContestLink80C2020Struct2018000.unk_07--; + } +} + +void sub_80C3E60(u8 monIndex, u8 numFrames) +{ + u8 taskId = CreateTask(sub_80C3EA4, 8); + gTasks[taskId].data[0] = monIndex; + gTasks[taskId].data[1] = numFrames; + gTasks[taskId].data[2] = gContestMons[monIndex].species; +} + +void sub_80C3EA4(u8 taskId) +{ + u8 monIndex = gTasks[taskId].data[0]; + if (gTasks[taskId].data[10]++ == gTasks[taskId].data[1]) + { + gTasks[taskId].data[10] = 0; + sub_80C3024(gTasks[taskId].data[2], monIndex, gTasks[taskId].data[11], FALSE, gContestMons[monIndex].personality); + gTasks[taskId].data[11] ^= 1; + } +} + +void sub_80C3F00(void) +{ + s32 i; + s16 r2 = gUnknown_02038678[0]; + s32 r4; + u32 r5; + s8 r0; + + for (i = 1; i < 4; i++) + { + if (r2 < gUnknown_02038678[i]) + r2 = gUnknown_02038678[i]; + } + + if (r2 < 0) + { + r2 = gUnknown_02038678[0]; + + for (i = 1; i < 4; i++) + { + if (r2 > gUnknown_02038678[i]) + r2 = gUnknown_02038678[i]; + } + } + + for (i = 0; i < 4; i++) + { + r4 = 1000 * gContestMonConditions[i] / ABS(r2); + if ((r4 % 10) >= 5) + r4 += 10; + eContestLink80C2020Struct2018018[i].unk_00 = r4 / 10; + + r4 = 1000 * ABS(gUnknown_02038688[i]) / ABS(r2); + if ((r4 % 10) >= 5) + r4 += 10; + eContestLink80C2020Struct2018018[i].unk_04 = r4 / 10; + + if (gUnknown_02038688[i] < 0) + eContestLink80C2020Struct2018018[i].unk_10 = 1; + + r5 = 22528 * eContestLink80C2020Struct2018018[i].unk_00 / 100; + if ((r5 % 256) >= 128) + r5 += 256; + eContestLink80C2020Struct2018018[i].unk_08 = r5 / 256; + + r5 = eContestLink80C2020Struct2018018[i].unk_04 * 22528 / 100; + if ((r5 % 256) >= 128) + r5 += 256; + eContestLink80C2020Struct2018018[i].unk_0c = r5 / 256; + + eContestLink80C2020Struct2018018[i].unk_11 = sub_80C3990(i, 1); + r0 = sub_80C39E4(i, 1); + eContestLink80C2020Struct2018018[i].unk_12 = ABS(r0); + + if (gContestFinalStandings[i]) + { + s16 r2__ = eContestLink80C2020Struct2018018[i].unk_08; + s16 r1__ = eContestLink80C2020Struct2018018[i].unk_0c; + if (eContestLink80C2020Struct2018018[i].unk_10) + r1__ = -r1__; + if (r2__ + r1__ == 88) + { + if (r1__ > 0) + eContestLink80C2020Struct2018018[i].unk_0c--; + else if (r2__ > 0) + eContestLink80C2020Struct2018018[i].unk_08--; + } + } + } +} + +#ifdef NONMATCHING +void sub_80C40D4(u8 arg0, u8 arg1) +{ + int i; + u8 taskId; + u8 sp8, spC; + + sp8 = 0; + spC = 0; + if (!arg0) + { + u32 var0; + for (i = 0; i < 4; i++) + { + u8 var1 = eContestLink80C2020Struct2018018[i].unk_11; + if (arg1 < var1) + { + int x = var1 + 19; + x += 32 * (i * 3 + 5); + x -= arg1; + x--; + *(vu16 *)(0x0600C000 + 2 * x) = 0x60B3; + taskId = CreateTask(sub_80C42C0, 10); + var0 = ((eContestLink80C2020Struct2018018[i].unk_08 << 16) / eContestLink80C2020Struct2018018[i].unk_11) * (arg1 + 1); + if ((var0 % 0x10000) >= 0x8000) + var0 += 0x10000; + + gTasks[taskId].data[0] = i; + gTasks[taskId].data[1] = var0 >> 16; + eContestLink80C2020Struct2018000.unk_14++; + sp8++; + } + } + } + else + { + u32 var0; + for (i = 0; i < 4; i++) + { + int tile; + s8 var1 = eContestLink80C2020Struct2018018[i].unk_12; + tile = eContestLink80C2020Struct2018018[i].unk_10 ? 0x60A5 : 0x60A3; + if (arg1 < var1) + { + int x = var1 + 19; + x += 32 * (i * 3 + 6); + x -= arg1; + x--; + *(vu16 *)(0x0600C000 + 2 * x) = tile; + taskId = CreateTask(sub_80C42C0, 10); + var0 = ((eContestLink80C2020Struct2018018[i].unk_0c << 16) / eContestLink80C2020Struct2018018[i].unk_12) * (arg1 + 1); + if ((var0 % 0x10000) >= 0x8000) + var0 += 0x10000; + + gTasks[taskId].data[0] = i; + if (eContestLink80C2020Struct2018018[i].unk_10) + { + gTasks[taskId].data[2] = 1; + spC++; + } + else + { + sp8++; + } + + if (eContestLink80C2020Struct2018018[i].unk_10) + gTasks[taskId].data[1] = -(var0 >> 16) + eContestLink80C2020Struct2018018[i].unk_08; + else + gTasks[taskId].data[1] = (var0 >> 16) + eContestLink80C2020Struct2018018[i].unk_08; + + eContestLink80C2020Struct2018000.unk_14++; + } + } + } + + if (spC) + PlaySE(SE_BOO); + + if (sp8) + PlaySE(SE_PIN); +} +#else +// Assorted register differences +NAKED +void sub_80C40D4(u8 arg0, u8 arg1) +{ + asm_unified("\tpush {r4-r7,lr}\n" + "\tmov r7, r10\n" + "\tmov r6, r9\n" + "\tmov r5, r8\n" + "\tpush {r5-r7}\n" + "\tsub sp, 0x8\n" + "\tlsls r0, 24\n" + "\tlsls r1, 24\n" + "\tlsrs r7, r1, 24\n" + "\tmovs r1, 0\n" + "\tmov r10, r1\n" + "\tmovs r2, 0\n" + "\tstr r2, [sp]\n" + "\tcmp r0, 0\n" + "\tbne _080C4198\n" + "\tmov r8, r2\n" + "\tldr r0, _080C417C @ =gSharedMem + 0x18018\n" + "\tsubs r1, 0x18\n" + "\tadds r1, r0\n" + "\tmov r9, r1\n" + "\tadds r4, r0, 0\n" + "\tadds r4, 0x8\n" + "\tmovs r6, 0xA0\n" + "_080C4102:\n" + "\tldrb r0, [r4, 0x9]\n" + "\tcmp r7, r0\n" + "\tbcs _080C416A\n" + "\tadds r0, 0x13\n" + "\tadds r0, r6, r0\n" + "\tsubs r0, r7\n" + "\tlsls r0, 1\n" + "\tldr r2, _080C4180 @ =0x0600bffe\n" + "\tadds r0, r2\n" + "\tldr r2, _080C4184 @ =0x000060b3\n" + "\tadds r1, r2, 0\n" + "\tstrh r1, [r0]\n" + "\tldr r0, _080C4188 @ =sub_80C42C0\n" + "\tmovs r1, 0xA\n" + "\tbl CreateTask\n" + "\tlsls r0, 24\n" + "\tlsrs r5, r0, 24\n" + "\tldr r0, [r4]\n" + "\tlsls r0, 16\n" + "\tldrb r1, [r4, 0x9]\n" + "\tbl __udivsi3\n" + "\tadds r1, r7, 0x1\n" + "\tadds r3, r0, 0\n" + "\tmuls r3, r1\n" + "\tldr r0, _080C418C @ =0x0000ffff\n" + "\tands r0, r3\n" + "\tldr r1, _080C4190 @ =0x00007fff\n" + "\tcmp r0, r1\n" + "\tbls _080C4146\n" + "\tmovs r0, 0x80\n" + "\tlsls r0, 9\n" + "\tadds r3, r0\n" + "_080C4146:\n" + "\tldr r1, _080C4194 @ =gTasks\n" + "\tlsls r0, r5, 2\n" + "\tadds r0, r5\n" + "\tlsls r0, 3\n" + "\tadds r0, r1\n" + "\tmov r1, r8\n" + "\tstrh r1, [r0, 0x8]\n" + "\tlsrs r1, r3, 16\n" + "\tstrh r1, [r0, 0xA]\n" + "\tmov r2, r9\n" + "\tldrb r0, [r2, 0x14]\n" + "\tadds r0, 0x1\n" + "\tstrb r0, [r2, 0x14]\n" + "\tmov r0, r10\n" + "\tadds r0, 0x1\n" + "\tlsls r0, 24\n" + "\tlsrs r0, 24\n" + "\tmov r10, r0\n" + "_080C416A:\n" + "\tadds r4, 0x14\n" + "\tadds r6, 0x60\n" + "\tmovs r0, 0x1\n" + "\tadd r8, r0\n" + "\tmov r1, r8\n" + "\tcmp r1, 0x3\n" + "\tble _080C4102\n" + "\tb _080C4292\n" + "\t.align 2, 0\n" + "_080C417C: .4byte gSharedMem + 0x18018\n" + "_080C4180: .4byte 0x0600bffe\n" + "_080C4184: .4byte 0x000060b3\n" + "_080C4188: .4byte sub_80C42C0\n" + "_080C418C: .4byte 0x0000ffff\n" + "_080C4190: .4byte 0x00007fff\n" + "_080C4194: .4byte gTasks\n" + "_080C4198:\n" + "\tmovs r2, 0\n" + "\tmov r8, r2\n" + "\tldr r0, _080C4220 @ =gSharedMem + 0x18018\n" + "\tmov r12, r0\n" + "\tmov r9, r2\n" + "\tmovs r1, 0xC0\n" + "\tstr r1, [sp, 0x4]\n" + "_080C41A6:\n" + "\tmov r6, r9\n" + "\tadd r6, r12\n" + "\tldrb r1, [r6, 0x12]\n" + "\tldrb r0, [r6, 0x10]\n" + "\tldr r2, _080C4224 @ =0x000060a3\n" + "\tcmp r0, 0\n" + "\tbeq _080C41B6\n" + "\tadds r2, 0x2\n" + "_080C41B6:\n" + "\tlsls r0, r1, 24\n" + "\tasrs r0, 24\n" + "\tcmp r7, r0\n" + "\tbge _080C427E\n" + "\tadds r0, 0x13\n" + "\tldr r1, [sp, 0x4]\n" + "\tadds r0, r1, r0\n" + "\tsubs r0, r7\n" + "\tlsls r0, 1\n" + "\tldr r1, _080C4228 @ =0x0600bffe\n" + "\tadds r0, r1\n" + "\tstrh r2, [r0]\n" + "\tldr r0, _080C422C @ =sub_80C42C0\n" + "\tmovs r1, 0xA\n" + "\tbl CreateTask\n" + "\tlsls r0, 24\n" + "\tlsrs r5, r0, 24\n" + "\tldr r0, [r6, 0xC]\n" + "\tlsls r0, 16\n" + "\tldrb r1, [r6, 0x12]\n" + "\tbl __udivsi3\n" + "\tadds r1, r7, 0x1\n" + "\tadds r3, r0, 0\n" + "\tmuls r3, r1\n" + "\tldr r0, _080C4230 @ =0x0000ffff\n" + "\tands r0, r3\n" + "\tldr r1, _080C4234 @ =0x00007fff\n" + "\tcmp r0, r1\n" + "\tbls _080C41FA\n" + "\tmovs r2, 0x80\n" + "\tlsls r2, 9\n" + "\tadds r3, r2\n" + "_080C41FA:\n" + "\tldr r1, _080C4238 @ =gTasks\n" + "\tlsls r2, r5, 2\n" + "\tadds r0, r2, r5\n" + "\tlsls r0, 3\n" + "\tadds r4, r0, r1\n" + "\tmov r0, r8\n" + "\tstrh r0, [r4, 0x8]\n" + "\tldrb r0, [r6, 0x10]\n" + "\tadds r6, r1, 0\n" + "\tcmp r0, 0\n" + "\tbeq _080C423C\n" + "\tmovs r0, 0x1\n" + "\tstrh r0, [r4, 0xC]\n" + "\tldr r0, [sp]\n" + "\tadds r0, 0x1\n" + "\tlsls r0, 24\n" + "\tlsrs r0, 24\n" + "\tstr r0, [sp]\n" + "\tb _080C4246\n" + "\t.align 2, 0\n" + "_080C4220: .4byte gSharedMem + 0x18018\n" + "_080C4224: .4byte 0x000060a3\n" + "_080C4228: .4byte 0x0600bffe\n" + "_080C422C: .4byte sub_80C42C0\n" + "_080C4230: .4byte 0x0000ffff\n" + "_080C4234: .4byte 0x00007fff\n" + "_080C4238: .4byte gTasks\n" + "_080C423C:\n" + "\tmov r0, r10\n" + "\tadds r0, 0x1\n" + "\tlsls r0, 24\n" + "\tlsrs r0, 24\n" + "\tmov r10, r0\n" + "_080C4246:\n" + "\tldr r0, _080C4264 @ =gSharedMem + 0x18018\n" + "\tmov r1, r9\n" + "\tadds r4, r1, r0\n" + "\tldrb r1, [r4, 0x10]\n" + "\tmov r12, r0\n" + "\tcmp r1, 0\n" + "\tbeq _080C4268\n" + "\tadds r0, r2, r5\n" + "\tlsls r0, 3\n" + "\tadds r0, r6\n" + "\tlsrs r2, r3, 16\n" + "\tldr r1, [r4, 0x8]\n" + "\tsubs r1, r2\n" + "\tb _080C4274\n" + "\t.align 2, 0\n" + "_080C4264: .4byte gSharedMem + 0x18018\n" + "_080C4268:\n" + "\tadds r0, r2, r5\n" + "\tlsls r0, 3\n" + "\tadds r0, r6\n" + "\tlsrs r2, r3, 16\n" + "\tldr r1, [r4, 0x8]\n" + "\tadds r1, r2\n" + "_080C4274:\n" + "\tstrh r1, [r0, 0xA]\n" + "\tldr r1, _080C42BC @ =gSharedMem + 0x18000\n" + "\tldrb r0, [r1, 0x14]\n" + "\tadds r0, 0x1\n" + "\tstrb r0, [r1, 0x14]\n" + "_080C427E:\n" + "\tmovs r2, 0x14\n" + "\tadd r9, r2\n" + "\tldr r0, [sp, 0x4]\n" + "\tadds r0, 0x60\n" + "\tstr r0, [sp, 0x4]\n" + "\tmovs r1, 0x1\n" + "\tadd r8, r1\n" + "\tmov r2, r8\n" + "\tcmp r2, 0x3\n" + "\tble _080C41A6\n" + "_080C4292:\n" + "\tldr r0, [sp]\n" + "\tcmp r0, 0\n" + "\tbeq _080C429E\n" + "\tmovs r0, 0x16\n" + "\tbl PlaySE\n" + "_080C429E:\n" + "\tmov r1, r10\n" + "\tcmp r1, 0\n" + "\tbeq _080C42AA\n" + "\tmovs r0, 0x15\n" + "\tbl PlaySE\n" + "_080C42AA:\n" + "\tadd sp, 0x8\n" + "\tpop {r3-r5}\n" + "\tmov r8, r3\n" + "\tmov r9, r4\n" + "\tmov r10, r5\n" + "\tpop {r4-r7}\n" + "\tpop {r0}\n" + "\tbx r0\n" + "\t.align 2, 0\n" + "_080C42BC: .4byte gSharedMem + 0x18000"); +} +#endif //NONMATCHING + +void sub_80C42C0(u8 taskId /*r12*/) +{ + bool32 r6 = FALSE; + bool32 r9 = FALSE; + u8 r5 = gTasks[taskId].data[0]; + s16 r7 = gTasks[taskId].data[1]; + s16 r1 = gTasks[taskId].data[2]; + s32 i; + + if (r1 != 0) + { + if (eContestLink80C2020Struct2018000.unk_0c[r5] <= 0) + r6 = TRUE; + } + else + { + if (eContestLink80C2020Struct2018000.unk_0c[r5] >= 88) + r6 = TRUE; + } + if (eContestLink80C2020Struct2018000.unk_0c[r5] == r7) + r9 = TRUE; + + if (!r9) + { + if (r6) + { + eContestLink80C2020Struct2018000.unk_0c[r5] = r7; + } + else if (r1 != 0) + { + eContestLink80C2020Struct2018000.unk_0c[r5]--; + } + else + { + eContestLink80C2020Struct2018000.unk_0c[r5]++; + } + } + if (!r6) + { + if (!r9) + { + for (i = 0; i < 11; i++) + { + u8 r0; + u16 tile; + if (eContestLink80C2020Struct2018000.unk_0c[r5] >= 8 * (i + 1)) + { + r0 = 8; + } + else if (eContestLink80C2020Struct2018000.unk_0c[r5] >= 8 * i) + { + r0 = eContestLink80C2020Struct2018000.unk_0c[r5] % 8; + } + else + { + r0 = 0; + } + if (r0 < 4) + tile = 0x504C + r0; + else + tile = 0x5057 + r0; + *(vu16 *)(0x0600E18E + 2 * (96 * r5 + i)) = tile; + } + } + } + if (r9) + { + eContestLink80C2020Struct2018000.unk_14--; + DestroyTask(taskId); + } +} + +void ScrSpecial_CheckSelectedMonAndInitContest(void) +{ + u8 result = CanMonParticipateInContest(&gPlayerParty[gContestMonPartyIndex]); + if (result != 0) + { + Contest_InitAllPokemon(gSpecialVar_ContestCategory, gSpecialVar_ContestRank); + InitContestMonConditions(gSpecialVar_ContestCategory); + } + gSpecialVar_Result = result; +} + +u16 ScrSpecial_CanMonParticipateInSelectedLinkContest(void) +{ + u16 result = 0; + struct Pokemon *mon = &gPlayerParty[gContestMonPartyIndex]; + switch (gSpecialVar_ContestCategory) + { + case CONTEST_CATEGORY_COOL: + if (GetMonData(mon, MON_DATA_COOL_RIBBON) > gSpecialVar_ContestRank) + result = 1; + break; + case CONTEST_CATEGORY_BEAUTY: + if (GetMonData(mon, MON_DATA_BEAUTY_RIBBON) > gSpecialVar_ContestRank) + result = 1; + break; + case CONTEST_CATEGORY_CUTE: + if (GetMonData(mon, MON_DATA_CUTE_RIBBON) > gSpecialVar_ContestRank) + result = 1; + break; + case CONTEST_CATEGORY_SMART: + if (GetMonData(mon, MON_DATA_SMART_RIBBON) > gSpecialVar_ContestRank) + result = 1; + break; + case CONTEST_CATEGORY_TOUGH: + if (GetMonData(mon, MON_DATA_TOUGH_RIBBON) > gSpecialVar_ContestRank) + result = 1; + break; + } + + return result; +} + + +void ScrSpecial_GiveContestRibbon(void) +{ + u8 ribbonData; + + if (gContestFinalStandings[gContestPlayerMonIndex] != 0) + return; + + switch (gSpecialVar_ContestCategory) + { + case CONTEST_CATEGORY_COOL: + ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON); + if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) + { + ribbonData++; + SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_COOL_RIBBON, &ribbonData); + } + break; + case CONTEST_CATEGORY_BEAUTY: + ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON); + if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) + { + ribbonData++; + SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_BEAUTY_RIBBON, &ribbonData); + } + break; + case CONTEST_CATEGORY_CUTE: + ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON); + if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) + { + ribbonData++; + SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_CUTE_RIBBON, &ribbonData); + } + break; + case CONTEST_CATEGORY_SMART: + ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON); + if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) + { + ribbonData++; + SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_SMART_RIBBON, &ribbonData); + } + break; + case CONTEST_CATEGORY_TOUGH: + ribbonData = GetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON); + if (ribbonData <= gSpecialVar_ContestRank && ribbonData < 4) + { + ribbonData++; + SetMonData(&gPlayerParty[gContestMonPartyIndex], MON_DATA_TOUGH_RIBBON, &ribbonData); + } + break; + } +} + +void Contest_CopyAndConvertTrainerName_Intl(u8 * dest, const u8 * src) +{ + StringCopy(dest, src); + if (dest[0] == EXT_CTRL_CODE_BEGIN && dest[1] == 0x15) + ConvertInternationalString(dest, LANGUAGE_JAPANESE); +} + +void Contest_CopyAndConvertNicknameI_Intl(u8 * dest, u8 idx) +{ + StringCopy(dest, gContestMons[idx].nickname); + if (gIsLinkContest & 1) + { + if (gLinkPlayers[idx].language == LANGUAGE_JAPANESE) + { + ConvertInternationalString(dest, GetStringLanguage(dest)); + } + } +} + +void Contest_GetTrainerNameI_StringVar1(void) +{ + if (gIsLinkContest & 1) + { + Contest_CopyAndConvertTrainerName_Intl(gStringVar1, gLinkPlayers[gSpecialVar_0x8006].name); + } + else + { + Contest_CopyAndConvertTrainerName_Intl(gStringVar1, gContestMons[gSpecialVar_0x8006].trainerName); + } +} + +void Contest_GetNicknameI_StringVar1(void) +{ + Contest_CopyAndConvertNicknameI_Intl(gStringVar3, gSpecialVar_0x8006); +} + +void ScrSpecial_CountContestMonsWithBetterCondition(void) +{ + u8 i; + u8 count; + + for (i = 0, count = 0; i < 4; i++) + { + if (gContestMonConditions[gSpecialVar_0x8006] < gContestMonConditions[i]) + count++; + } + + gSpecialVar_0x8004 = count; +} + +void ScrSpecial_GetMonCondition(void) +{ + gSpecialVar_0x8004 = gContestMonConditions[gSpecialVar_0x8006]; +} + +void ScrSpecial_GetContestWinnerIdx(void) +{ + u8 i; + + for (i = 0; i < 4 && gContestFinalStandings[i] != 0; i++) + ; + + gSpecialVar_0x8005 = i; +} + +void ScrSpecial_GetContestWinnerTrainerName(void) +{ + u8 i; + + for (i = 0; i < 4 && gContestFinalStandings[i] != 0; i++) + ; + + if (gIsLinkContest & 1) + { + Contest_CopyAndConvertTrainerName_Intl(gStringVar3, gLinkPlayers[i].name); + } + else + { + Contest_CopyAndConvertTrainerName_Intl(gStringVar3, gContestMons[i].trainerName); + } +} + +void ScrSpecial_GetContestWinnerNick(void) +{ + u8 i; + + for (i = 0; i < 4 && gContestFinalStandings[i] != 0; i++) + ; + + Contest_CopyAndConvertNicknameI_Intl(gStringVar1, i); +} + +void sub_80C488C(void) +{ + SetMainCallback2(CB2_StartContest); +} + +void sub_80C489C(u8 taskId) +{ + if (!gPaletteFade.active) + { + DestroyTask(taskId); + SetMainCallback2(sub_80C488C); + } +} + +void sub_80C48C8(void) +{ + ScriptContext2_Enable(); + CreateTask(sub_80C489C, 10); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); +} + +void sub_80C48F4(void) +{ + gSpecialVar_0x8004 = gContestMons[gSpecialVar_0x8006].species; +} + +void sub_80C4914(u8 taskId) +{ + if (!gPaletteFade.active) + { + DestroyTask(taskId); + SetMainCallback2(sub_80C2358); + } +} + +void sub_80C4940(void) +{ + ScriptContext2_Enable(); + CreateTask(sub_80C4914, 10); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, RGB_BLACK); +} + +void ScrSpecial_GetContestPlayerMonIdx(void) +{ + gSpecialVar_0x8004 = gContestPlayerMonIndex; +} + +void sub_80C4980(u8 taskId) +{ + u8 taskId2; + ScriptContext2_Enable(); + taskId2 = CreateTask(sub_80C8604, 0); + SetTaskFuncWithFollowupFunc(taskId2, sub_80C8604, sub_80C49C4); + gTasks[taskId2].data[9] = taskId; +} + +void sub_80C49C4(u8 taskId) +{ + Contest_CreatePlayerMon(gContestMonPartyIndex); + SetTaskFuncWithFollowupFunc(taskId, sub_80C8734, sub_80C49F0); +} + +void sub_80C49F0(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_80C88AC, sub_80C4A0C); +} + +void sub_80C4A0C(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_80C8E1C, sub_80C4A28); +} + +void sub_80C4A28(u8 taskId) +{ + SetTaskFuncWithFollowupFunc(taskId, sub_80C8938, sub_80C4A44); +} + +void sub_80C4A44(u8 taskId) +{ + u8 i; + u8 sp0[4]; + u8 sp4[4]; + + for (i = 0; i < 4; i++) + sp0[i] = gTasks[taskId].data[i + 1]; + + for (i = 0; i < 4; i++) + { + if (sp0[0] != sp0[i]) + break; + } + + if (i == 4) + gSpecialVar_0x8004 = 0; + else + gSpecialVar_0x8004 = 1; + + for (i = 0; i < 4; i++) + sp4[i] = gTasks[taskId].data[i + 5]; + + gUnknown_0203869B = sub_80C4B34(sp4); + InitContestMonConditions(gSpecialVar_ContestCategory); + SetTaskFuncWithFollowupFunc(taskId, sub_80C8EBC, sub_80C4B0C); +} + +void sub_80C4B0C(u8 taskId) +{ + sub_80B0F28(0); + SetTaskFuncWithFollowupFunc(taskId, sub_80C8F34, sub_80C4B5C); +} + +u8 sub_80C4B34(u8 * a0) +{ + s32 i; + u8 result = 0; + + for (i = 1; i < 4; i++) + { + if (a0[result] < a0[i]) + result = i; + } + + return result; +} + +void sub_80C4B5C(u8 taskId) +{ + if (gSpecialVar_0x8004 == 1) + { + if (IsLinkTaskFinished()) + gTasks[taskId].func = sub_80C4BA4; + } + else + { + DestroyTask(taskId); + ScriptContext2_Disable(); + EnableBothScriptContexts(); + } +} + +void sub_80C4BA4(u8 taskId) +{ + sub_800832C(); + gTasks[taskId].func = sub_80C4BCC; +} + +void sub_80C4BCC(u8 taskId) +{ + if (!gReceivedRemoteLinkPlayers) + { + DestroyTask(taskId); + ScriptContext2_Disable(); + EnableBothScriptContexts(); + } +} diff --git a/src/contest_link_80C857C.c b/src/contest_link_80C857C.c new file mode 100644 index 000000000..a694380df --- /dev/null +++ b/src/contest_link_80C857C.c @@ -0,0 +1,755 @@ +#include "global.h" +#include "ewram.h" +#include "random.h" +#include "task.h" +#include "contest.h" +#include "text.h" +#include "string_util.h" +#include "link.h" + +static void sub_80C8644(u8 taskId); +static void sub_80C8660(u8 taskId); +#if GERMAN +static void de_sub_80C9274(bool32 arg0); +static void de_sub_80C9294(bool32 arg0); +#endif + +static void SendBlockToAllOpponents(const void *data, u16 size) +{ + memcpy(eContestLinkSendBuffer, data, size); + SendBlock(bitmask_all_link_players_but_self(), eContestLinkSendBuffer, size); +} + +static bool8 HasPlayerReceivedBlock(u8 who) +{ + u8 flag = 1 << who; + if (!(GetBlockReceivedStatus() & flag)) + return FALSE; + ResetBlockReceivedFlag(flag); + return TRUE; +} + +static bool8 HaveAllPlayersReceivedBlock(void) +{ + int i; + + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + if (!((GetBlockReceivedStatus() >> i) & 1)) + return FALSE; + } + ResetBlockReceivedFlags(); + return TRUE; +} + +void sub_80C8604(u8 taskId) +{ +#if ENGLISH + u8 i; + + for (i = 0; i < 4; i++) + gBlockRecvBuffer[i][0] = 0xff; +#endif + gTasks[taskId].data[0] = 0; + gTasks[taskId].func = sub_80C8644; +} + +static void sub_80C8644(u8 taskId) +{ + gTasks[taskId].func = sub_80C8660; +} + +static void sub_80C8660(u8 taskId) +{ + if (gReceivedRemoteLinkPlayers) + { + gContestPlayerMonIndex = GetMultiplayerId(); + if (GetLinkPlayerCount() == MAX_LINK_PLAYERS) + { + gIsLinkContest = TRUE; + SwitchTaskToFollowupFunc(taskId); + } + } +} + +#ifdef NONMATCHING +u8 GetStringLanguage(const u8 *string) +{ + u8 language = GAME_LANGUAGE; + if (string[0] == EXT_CTRL_CODE_BEGIN && string[1] == 0x15) + return language; + if (StringLength(string) > 5) + return language; + for (; *string != EOS; string++) + { + if (!((*string >= CHAR_A && *string <= CHAR_z) || + (*string >= CHAR_0 + 0 && *string <= CHAR_0 + 9) || + *string == CHAR_SPACE || + *string == CHAR_PERIOD || + *string == CHAR_COMMA || + *string == 0xAB || + *string == CHAR_QUESTION_MARK || + *string == CHAR_MALE || + *string == CHAR_FEMALE || + *string == CHAR_SLASH || + *string == CHAR_HYPHEN || + *string == CHAR_ELLIPSIS || + *string == 0xB1 || + *string == 0xB2 || + *string == 0xB3 || + *string == 0xB1 + )) + { + language = LANGUAGE_JAPANESE; + break; + } + } + return language; +} +#else +NAKED u8 GetStringLanguage(const u8 *string) +{ + asm_unified("\tpush {r4,r5,lr}\n" + "\tadds r4, r0, 0\n" + ".ifdef ENGLISH\n" + "\tmovs r5, 0x2\n" + ".else\n" + "\tmovs r5, 0x5\n" + ".endif\n" + "\tldrb r0, [r4]\n" + "\tcmp r0, 0xFC\n" + "\tbne _080C86B6\n" + "\tldrb r0, [r4, 0x1]\n" + "\tcmp r0, 0x15\n" + "\tbne _080C86B6\n" + ".ifdef ENGLISH\n" + "\tmovs r0, 0x2\n" + ".else\n" + "\tmovs r0, 0x5\n" + ".endif\n" + "\tb _080C872C\n" + "_080C86B6:\n" + "\tadds r0, r4, 0\n" + "\tbl StringLength\n" + "\tlsls r0, 16\n" + "\tlsrs r0, 16\n" + "\tcmp r0, 0x5\n" + "\tbhi _080C872A\n" + "\tldrb r0, [r4]\n" + "\tcmp r0, 0xFF\n" + "\tbeq _080C872A\n" + "_080C86CA:\n" + "\tldrb r1, [r4]\n" + "\tadds r0, r1, 0\n" + "\tadds r0, 0x45\n" + "\tlsls r0, 24\n" + "\tlsrs r0, 24\n" + "\tcmp r0, 0x33\n" + "\tbls _080C871E\n" + "\tadds r0, r1, 0\n" + "\tadds r0, 0x5F\n" + "\tlsls r0, 24\n" + "\tlsrs r0, 24\n" + "\tcmp r0, 0x9\n" + "\tbls _080C871E\n" + "\tadds r0, r1, 0\n" + "\tcmp r0, 0\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xAD\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xB8\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xAB\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xAC\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xB5\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xB6\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xBA\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xAE\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xB0\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xB1\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xB2\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xB3\n" + "\tbeq _080C871E\n" + "\tcmp r0, 0xB1\n" + "\tbne _080C8728\n" + "_080C871E:\n" + "\tadds r4, 0x1\n" + "\tldrb r0, [r4]\n" + "\tcmp r0, 0xFF\n" + "\tbne _080C86CA\n" + "\tb _080C872A\n" + "_080C8728:\n" + "\tmovs r5, 0x1\n" + "_080C872A:\n" + "\tadds r0, r5, 0\n" + "_080C872C:\n" + "\tpop {r4,r5}\n" + "\tpop {r1}\n" + "\tbx r1"); +} +#endif + +void sub_80C8734(u8 taskId) +{ + int i; + u8 *name; + + switch (gTasks[taskId].data[0]) { +#if ENGLISH + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; +#elif GERMAN + case 8: +#endif + case 0: + if (GetMultiplayerId() == 0) { + if (IsLinkTaskFinished()) { +#if ENGLISH + memcpy(gBlockSendBuffer, gContestMons + gContestPlayerMonIndex, sizeof(struct ContestPokemon)); + sub_8007E9C(2); + gTasks[taskId].data[0]++; +#elif GERMAN + if (gTasks[taskId].data[0] == 0) + { + gTasks[taskId].data[0] = 3; + } + else + { + memcpy(gBlockSendBuffer, gContestMons + gContestPlayerMonIndex, sizeof(struct ContestPokemon)); + de_sub_80C9274(FALSE); + sub_8007E9C(2); + gTasks[taskId].data[0] = 1; + } +#endif + } + } + else + { + memcpy(gBlockSendBuffer, gContestMons + gContestPlayerMonIndex, sizeof(struct ContestPokemon)); +#if GERMAN + de_sub_80C9294(FALSE); +#endif + gTasks[taskId].data[0]++; + } + break; + case 1: + if (HaveAllPlayersReceivedBlock()) + { + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + memcpy(gContestMons + i, gBlockRecvBuffer[i], sizeof(struct ContestPokemon)); + name = gContestMons[i].nickname; + if (gLinkPlayers[i].language == LANGUAGE_JAPANESE) + { + ConvertInternationalString(name, GetStringLanguage(name)); + } + else if (name[10] == EXT_CTRL_CODE_BEGIN) + { + ConvertInternationalString(name, LANGUAGE_JAPANESE); + } else + { + name[5] = name[10]; + name[10] = EOS; + } + name = gContestMons[i].trainerName; + if (gLinkPlayers[i].language == LANGUAGE_JAPANESE) + { + name[7] = EOS; + name[6] = name[4]; + name[5] = name[3]; + name[4] = name[2]; + name[3] = name[1]; + name[2] = name[0]; + name[1] = 0x15; + name[0] = EXT_CTRL_CODE_BEGIN; + } + else + { + name[5] = name[7]; + name[7] = EOS; + } + } + gTasks[taskId].data[0]++; + } + break; +#if GERMAN + case 2: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + default: + gTasks[taskId].data[0]++; + break; +#endif + } +} + +void sub_80C88AC(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + case 0: + if (GetMultiplayerId() == 0) + { + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(&gRngValue, sizeof(u32)); + gTasks[taskId].data[0]++; + } + } + else + { + gTasks[taskId].data[0]++; + } + break; + case 1: + if (HasPlayerReceivedBlock(0)) + { + memcpy(&gRngValue, gBlockRecvBuffer[0], sizeof(u32)); + memcpy(&gContestRngValue, gBlockRecvBuffer[0], sizeof(u32)); + gTasks[taskId].data[0]++; + } + break; + } +} + +void sub_80C8938(u8 taskId) +{ + int i; + + switch (gTasks[taskId].data[0]) + { +#if ENGLISH + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; +#elif GERMAN + case 8: +#endif + case 0: + gBlockSendBuffer[0] = gTasks[taskId].data[9]; + if (GetMultiplayerId() == 0) + { + if (IsLinkTaskFinished()) + { +#if ENGLISH + sub_8007E9C(2); + gTasks[taskId].data[0]++; +#elif GERMAN + if (gTasks[taskId].data[0] == 0) + { + gTasks[taskId].data[0] = 3; + } + else + { + de_sub_80C9274(TRUE); + sub_8007E9C(2); + gTasks[taskId].data[0] = 1; + } +#endif + } + } + else + { +#if GERMAN + de_sub_80C9294(TRUE); +#endif + gTasks[taskId].data[0]++; + } + break; + case 1: + if (HaveAllPlayersReceivedBlock()) + { + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + gTasks[taskId].data[i + 1] = gBlockRecvBuffer[i][0]; + } + gTasks[taskId].data[0]++; + } + break; +#if GERMAN + case 2: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + default: + gTasks[taskId].data[0]++; + break; +#endif + } +} + +void sub_80C89DC(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + case 0: + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(&gContestPlayerMonIndex, sizeof(u8)); + gTasks[taskId].data[0]++; + } + break; + case 1: + if (HaveAllPlayersReceivedBlock()) + { + gTasks[taskId].data[0]++; + } + break; + } +} + +void sub_80C8A38(u8 taskId) +{ + int i; + + switch (gTasks[taskId].data[0]) + { + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + case 0: + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(&sContestantStatus[gContestPlayerMonIndex].currMove, sizeof(u16)); + gTasks[taskId].data[0]++; + } + break; + case 1: + if (HaveAllPlayersReceivedBlock()) + { + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + *&sContestantStatus[i].currMove = gBlockRecvBuffer[i][0]; + } + gTasks[taskId].data[0]++; + } + break; + } +} + +void sub_80C8AD0(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + case 0: + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(gUnknown_02038678, sizeof gUnknown_02038678); + gTasks[taskId].data[0]++; + } + break; + case 1: + if (HaveAllPlayersReceivedBlock()) + { + memcpy(gUnknown_02038678, gBlockRecvBuffer[gUnknown_0203869B], sizeof gUnknown_02038678); + gTasks[taskId].data[0]++; + } + break; + case 2: + case 5: + case 8: + case 11: + if (gTasks[taskId].data[1]++ > 10) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + } + break; + case 3: + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(gUnknown_02038680, sizeof gUnknown_02038680); + gTasks[taskId].data[0]++; + } + break; + case 4: + if (HaveAllPlayersReceivedBlock()) + { + memcpy(gUnknown_02038680, gBlockRecvBuffer[gUnknown_0203869B], sizeof gUnknown_02038680); + gTasks[taskId].data[0]++; + } + break; + case 6: + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(gUnknown_02038688, sizeof gUnknown_02038688); + gTasks[taskId].data[0]++; + } + break; + case 7: + if (HaveAllPlayersReceivedBlock()) + { + memcpy(gUnknown_02038688, gBlockRecvBuffer[gUnknown_0203869B], sizeof gUnknown_02038688); + gTasks[taskId].data[0]++; + } + break; + case 9: + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(gContestFinalStandings, sizeof gContestFinalStandings); + gTasks[taskId].data[0]++; + } + break; + case 10: + if (HaveAllPlayersReceivedBlock()) + { + memcpy(gContestFinalStandings, gBlockRecvBuffer[gUnknown_0203869B], sizeof gContestFinalStandings); + gTasks[taskId].data[0]++; + } + break; + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + } +} + +void sub_80C8C80(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + case 0: + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(sContestantStatus, 4 * sizeof(struct ContestantStatus)); + gTasks[taskId].data[0]++; + } + break; + case 1: + if (HaveAllPlayersReceivedBlock()) + { + memcpy(sContestantStatus, gBlockRecvBuffer[gUnknown_0203869B], 4 * sizeof(struct ContestantStatus)); + gTasks[taskId].data[0]++; + } + break; + case 2: + case 5: + case 8: + case 11: + if (gTasks[taskId].data[1]++ > 10) + { + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[0]++; + } + break; + case 3: + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(&shared192D0, sizeof shared192D0); + gTasks[taskId].data[0]++; + } + break; + case 4: + if (HaveAllPlayersReceivedBlock()) + { + memcpy(&shared192D0, gBlockRecvBuffer[gUnknown_0203869B], sizeof shared192D0); + gTasks[taskId].data[0]++; + } + break; + case 6: + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(&shared19328, sizeof shared19328); + gTasks[taskId].data[0]++; + } + break; + case 7: + if (HaveAllPlayersReceivedBlock()) + { + memcpy(&shared19328, gBlockRecvBuffer[gUnknown_0203869B], sizeof shared19328); + gTasks[taskId].data[0]++; + } + break; + case 9: + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(gUnknown_02038696, sizeof gUnknown_02038696); + gTasks[taskId].data[0]++; + } + break; + case 10: + if (HaveAllPlayersReceivedBlock()) + { + memcpy(gUnknown_02038696, gBlockRecvBuffer[gUnknown_0203869B], sizeof gUnknown_02038696); + gTasks[taskId].data[0]++; + } + break; + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + } +} + +void sub_80C8E1C(u8 taskId) +{ + int i; + + switch (gTasks[taskId].data[0]) + { +#if ENGLISH + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; +#elif GERMAN + case 8: +#endif + case 0: + gBlockSendBuffer[0] = 0x64; + if (GetMultiplayerId() == 0) + { + if (IsLinkTaskFinished()) + { +#if ENGLISH + sub_8007E9C(2); + gTasks[taskId].data[0]++; +#elif GERMAN + if (gTasks[taskId].data[0] == 0) + { + gTasks[taskId].data[0] = 3; + } + else + { + de_sub_80C9274(FALSE); + sub_8007E9C(2); + gTasks[taskId].data[0] = 1; + } +#endif + } + } + else + { +#if GERMAN + de_sub_80C9294(FALSE); +#endif + gTasks[taskId].data[0]++; + } + break; + case 1: + if (HaveAllPlayersReceivedBlock()) + { + for (i = 0; i < MAX_LINK_PLAYERS; i++) + { + gTasks[taskId].data[5 + i] = gBlockRecvBuffer[i][0]; + } + gTasks[taskId].data[0]++; + } + break; +#if GERMAN + case 2: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + default: + gTasks[taskId].data[0]++; + break; +#endif + } +} + +void sub_80C8EBC(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + case 0: + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(gContestMonConditions, sizeof gContestMonConditions); + gTasks[taskId].data[0]++; + } + break; + case 1: + if (HaveAllPlayersReceivedBlock()) + { + memcpy(gContestMonConditions, gBlockRecvBuffer[gUnknown_0203869B], sizeof gContestMonConditions); + gTasks[taskId].data[0]++; + } + break; + } +} + +void sub_80C8F34(u8 taskId) +{ + switch (gTasks[taskId].data[0]) + { + default: + gTasks[taskId].data[0] = 0; + SwitchTaskToFollowupFunc(taskId); + break; + case 0: + if (IsLinkTaskFinished()) + { + SendBlockToAllOpponents(gUnknown_02038696, sizeof gUnknown_02038696); + gTasks[taskId].data[0]++; + } + break; + case 1: + if (HaveAllPlayersReceivedBlock()) + { + memcpy(gUnknown_02038696, gBlockRecvBuffer[gUnknown_0203869B], sizeof gUnknown_02038696); + gTasks[taskId].data[0]++; + } + break; + } +} + +#if GERMAN + +static void de_sub_80C9274(bool32 arg0) +{ + if (deUnkValue2 == 1) + { + if (arg0) + deUnkValue2 = 3; + else + deUnkValue2 = 2; + } +} + +static void de_sub_80C9294(bool32 arg0) +{ + if (deUnkValue2 == 1) + { + if (arg0) + deUnkValue2 = 3; + else + deUnkValue2 = 2; + } + else if (deUnkValue2 == 2) + { + SendBlock(0, sBlockRequestLookupTable[deUnkValue1].address, sBlockRequestLookupTable[deUnkValue1].size); + if (arg0) + deUnkValue2 = 0; + else + deUnkValue2 = 1; + } +} + +#endif diff --git a/src/pokeball.c b/src/pokeball.c new file mode 100644 index 000000000..7162ee6ac --- /dev/null +++ b/src/pokeball.c @@ -0,0 +1,1203 @@ +#include "global.h" +#include "gba/m4a_internal.h" +#include "battle.h" +#include "battle_anim_special.h" +#include "decompress.h" +#include "graphics.h" +#include "m4a.h" +#include "main.h" +#include "pokeball.h" +#include "pokemon.h" +#include "rom_8077ABC.h" +#include "constants/songs.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "trig.h" +#include "util.h" +#include "ewram.h" + +extern struct MusicPlayerInfo gMPlay_BGM; +extern u16 gBattleTypeFlags; +extern u8 gBankTarget; +extern u8 gActiveBattler; +extern u16 gBattlerPartyIndexes[]; +extern u8 gBankSpriteIds[]; +extern u8 gDoingBattleAnim; +extern u8 gHealthboxIDs[]; + +#define GFX_TAG_POKEBALL 55000 +#define GFX_TAG_GREATBALL 55001 +#define GFX_TAG_SAFARIBALL 55002 +#define GFX_TAG_ULTRABALL 55003 +#define GFX_TAG_MASTERBALL 55004 +#define GFX_TAG_NETBALL 55005 +#define GFX_TAG_DIVEBALL 55006 +#define GFX_TAG_NESTBALL 55007 +#define GFX_TAG_REPEATBALL 55008 +#define GFX_TAG_TIMERBALL 55009 +#define GFX_TAG_LUXURYBALL 55010 +#define GFX_TAG_PREMIERBALL 55011 + +static const struct CompressedSpriteSheet sBallSpriteSheets[] = +{ + {gInterfaceGfx_PokeBall, 384, GFX_TAG_POKEBALL}, + {gInterfaceGfx_GreatBall, 384, GFX_TAG_GREATBALL}, + {gInterfaceGfx_SafariBall, 384, GFX_TAG_SAFARIBALL}, + {gInterfaceGfx_UltraBall, 384, GFX_TAG_ULTRABALL}, + {gInterfaceGfx_MasterBall, 384, GFX_TAG_MASTERBALL}, + {gInterfaceGfx_NetBall, 384, GFX_TAG_NETBALL}, + {gInterfaceGfx_DiveBall, 384, GFX_TAG_DIVEBALL}, + {gInterfaceGfx_NestBall, 384, GFX_TAG_NESTBALL}, + {gInterfaceGfx_RepeatBall, 384, GFX_TAG_REPEATBALL}, + {gInterfaceGfx_TimerBall, 384, GFX_TAG_TIMERBALL}, + {gInterfaceGfx_LuxuryBall, 384, GFX_TAG_LUXURYBALL}, + {gInterfaceGfx_PremierBall, 384, GFX_TAG_PREMIERBALL}, +}; + +static const struct CompressedSpritePalette sBallSpritePalettes[] = +{ + {gInterfacePal_PokeBall, GFX_TAG_POKEBALL}, + {gInterfacePal_GreatBall, GFX_TAG_GREATBALL}, + {gInterfacePal_SafariBall, GFX_TAG_SAFARIBALL}, + {gInterfacePal_UltraBall, GFX_TAG_ULTRABALL}, + {gInterfacePal_MasterBall, GFX_TAG_MASTERBALL}, + {gInterfacePal_NetBall, GFX_TAG_NETBALL}, + {gInterfacePal_DiveBall, GFX_TAG_DIVEBALL}, + {gInterfacePal_NestBall, GFX_TAG_NESTBALL}, + {gInterfacePal_RepeatBall, GFX_TAG_REPEATBALL}, + {gInterfacePal_TimerBall, GFX_TAG_TIMERBALL}, + {gInterfacePal_LuxuryBall, GFX_TAG_LUXURYBALL}, + {gInterfacePal_PremierBall, GFX_TAG_PREMIERBALL}, +}; + +static const struct OamData sBallOamData = +{ + .y = 0, + .affineMode = 3, + .objMode = 0, + .mosaic = 0, + .bpp = 0, + .shape = 0, + .x = 0, + .matrixNum = 0, + .size = 1, + .tileNum = 0, + .priority = 2, + .paletteNum = 0, + .affineParam = 0, +}; + +static const union AnimCmd sBallAnimSeq3[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sBallAnimSeq5[] = +{ + ANIMCMD_FRAME(4, 1), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sBallAnimSeq4[] = +{ + ANIMCMD_FRAME(8, 5), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sBallAnimSeq6[] = +{ + ANIMCMD_FRAME(12, 1), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sBallAnimSeq0[] = +{ + ANIMCMD_FRAME(0, 1), + ANIMCMD_END, +}; + +static const union AnimCmd sBallAnimSeq1[] = +{ + ANIMCMD_FRAME(4, 5), + ANIMCMD_FRAME(8, 5), + ANIMCMD_END, +}; + +static const union AnimCmd sBallAnimSeq2[] = +{ + ANIMCMD_FRAME(4, 5), + ANIMCMD_FRAME(0, 5), + ANIMCMD_END, +}; + +static const union AnimCmd *const sBallAnimSequences[] = +{ + sBallAnimSeq0, + sBallAnimSeq1, + sBallAnimSeq2, + + // unused? + sBallAnimSeq3, + sBallAnimSeq4, + sBallAnimSeq5, + sBallAnimSeq6, +}; + +static const union AffineAnimCmd sBallAffineAnimSeq0[] = +{ + AFFINEANIMCMD_FRAME(0, 0, 0, 1), + AFFINEANIMCMD_JUMP(0), +}; + +static const union AffineAnimCmd sBallAffineAnimSeq1[] = +{ + AFFINEANIMCMD_FRAME(0, 0, -3, 1), + AFFINEANIMCMD_JUMP(0), +}; + +static const union AffineAnimCmd sBallAffineAnimSeq2[] = +{ + AFFINEANIMCMD_FRAME(0, 0, 3, 1), + AFFINEANIMCMD_JUMP(0), +}; + +static const union AffineAnimCmd sBallAffineAnimSeq3[] = +{ + AFFINEANIMCMD_FRAME(256, 256, 0, 0), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd sBallAffineAnimSeq4[] = +{ + AFFINEANIMCMD_FRAME(0, 0, 25, 1), + AFFINEANIMCMD_JUMP(0), +}; + +static const union AffineAnimCmd *const sBallAffineAnimSequences[] = +{ + sBallAffineAnimSeq0, + sBallAffineAnimSeq1, + sBallAffineAnimSeq2, + sBallAffineAnimSeq3, + sBallAffineAnimSeq4, +}; + +static void objc_0804ABD4(struct Sprite *sprite); +const struct SpriteTemplate gBallSpriteTemplates[] = +{ + { + .tileTag = GFX_TAG_POKEBALL, + .paletteTag = GFX_TAG_POKEBALL, + .oam = &sBallOamData, + .anims = sBallAnimSequences, + .images = NULL, + .affineAnims = sBallAffineAnimSequences, + .callback = objc_0804ABD4, + }, + { + .tileTag = GFX_TAG_GREATBALL, + .paletteTag = GFX_TAG_GREATBALL, + .oam = &sBallOamData, + .anims = sBallAnimSequences, + .images = NULL, + .affineAnims = sBallAffineAnimSequences, + .callback = objc_0804ABD4, + }, + { + .tileTag = GFX_TAG_SAFARIBALL, + .paletteTag = GFX_TAG_SAFARIBALL, + .oam = &sBallOamData, + .anims = sBallAnimSequences, + .images = NULL, + .affineAnims = sBallAffineAnimSequences, + .callback = objc_0804ABD4, + }, + { + .tileTag = GFX_TAG_ULTRABALL, + .paletteTag = GFX_TAG_ULTRABALL, + .oam = &sBallOamData, + .anims = sBallAnimSequences, + .images = NULL, + .affineAnims = sBallAffineAnimSequences, + .callback = objc_0804ABD4, + }, + { + .tileTag = GFX_TAG_MASTERBALL, + .paletteTag = GFX_TAG_MASTERBALL, + .oam = &sBallOamData, + .anims = sBallAnimSequences, + .images = NULL, + .affineAnims = sBallAffineAnimSequences, + .callback = objc_0804ABD4, + }, + { + .tileTag = GFX_TAG_NETBALL, + .paletteTag = GFX_TAG_NETBALL, + .oam = &sBallOamData, + .anims = sBallAnimSequences, + .images = NULL, + .affineAnims = sBallAffineAnimSequences, + .callback = objc_0804ABD4, + }, + { + .tileTag = GFX_TAG_DIVEBALL, + .paletteTag = GFX_TAG_DIVEBALL, + .oam = &sBallOamData, + .anims = sBallAnimSequences, + .images = NULL, + .affineAnims = sBallAffineAnimSequences, + .callback = objc_0804ABD4, + }, + { + .tileTag = GFX_TAG_NESTBALL, + .paletteTag = GFX_TAG_NESTBALL, + .oam = &sBallOamData, + .anims = sBallAnimSequences, + .images = NULL, + .affineAnims = sBallAffineAnimSequences, + .callback = objc_0804ABD4, + }, + { + .tileTag = GFX_TAG_REPEATBALL, + .paletteTag = GFX_TAG_REPEATBALL, + .oam = &sBallOamData, + .anims = sBallAnimSequences, + .images = NULL, + .affineAnims = sBallAffineAnimSequences, + .callback = objc_0804ABD4, + }, + { + .tileTag = GFX_TAG_TIMERBALL, + .paletteTag = GFX_TAG_TIMERBALL, + .oam = &sBallOamData, + .anims = sBallAnimSequences, + .images = NULL, + .affineAnims = sBallAffineAnimSequences, + .callback = objc_0804ABD4, + }, + { + .tileTag = GFX_TAG_LUXURYBALL, + .paletteTag = GFX_TAG_LUXURYBALL, + .oam = &sBallOamData, + .anims = sBallAnimSequences, + .images = NULL, + .affineAnims = sBallAffineAnimSequences, + .callback = objc_0804ABD4, + }, + { + .tileTag = GFX_TAG_PREMIERBALL, + .paletteTag = GFX_TAG_PREMIERBALL, + .oam = &sBallOamData, + .anims = sBallAnimSequences, + .images = NULL, + .affineAnims = sBallAffineAnimSequences, + .callback = objc_0804ABD4, + }, +}; + +extern void InitAnimArcTranslation(); +extern bool8 TranslateAnimArc(struct Sprite *); + +static void SendOutMonAnimation(u8); +static void sub_80466E8(struct Sprite *); +static void sub_80466F4(struct Sprite *); +static void sub_8046760(struct Sprite *); +static void sub_80467F8(struct Sprite *); +static void sub_804684C(struct Sprite *); +static void sub_8046944(struct Sprite *); +static void sub_8046984(struct Sprite *); +static void sub_8046C78(struct Sprite *); +static void sub_8046E7C(struct Sprite *); +static void sub_8046E9C(struct Sprite *); +static void sub_8046FBC(struct Sprite *); +static void SendOutPlayerMonAnimation_Step0(struct Sprite *); +static void SendOutPlayerMonAnimation_Step1(struct Sprite *); +static void SendOutMonAnimation_Delay(struct Sprite *); +static void SendOutOpponentMonAnimation_Step0(struct Sprite *); +static void sub_80473D0(struct Sprite *); +static void sub_804748C(struct Sprite *); +static void sub_8047638(struct Sprite *); +static void sub_80476E0(struct Sprite *); +static void sub_8047754(struct Sprite *); +static void sub_804780C(struct Sprite *); +static void sub_8047830(struct Sprite *); +static void oamc_804BEB4(struct Sprite *); +static u16 GetBattlerBall(u8); + +u8 StartSendOutMonAnimation(u16 a, u8 side) +{ + u8 taskId; + + gDoingBattleAnim = 1; + ewram17810[gActiveBattler].unk0_3 = 1; + taskId = CreateTask(SendOutMonAnimation, 5); + gTasks[taskId].data[1] = a; + gTasks[taskId].data[2] = side; + gTasks[taskId].data[3] = gActiveBattler; + return 0; +} + +static void SendOutMonAnimation(u8 taskId) +{ + bool8 debug = FALSE; + u16 side; + u8 battler; + u16 ball; + u8 ballIndex; + u8 spriteId; + + if (gTasks[taskId].data[0] == 0) + { + gTasks[taskId].data[0]++; + return; + } + + side = gTasks[taskId].data[2]; + battler = gTasks[taskId].data[3]; + if (GetBattlerSide(battler) != B_SIDE_PLAYER) + ball = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_POKEBALL); + else + ball = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_POKEBALL); + + ballIndex = ball_number_to_ball_processing_index(ball); + LoadBallGraphics(ballIndex); + spriteId = CreateSprite(&gBallSpriteTemplates[ballIndex], 32, 80, 29); + gSprites[spriteId].data[0] = 0x80; + gSprites[spriteId].data[1] = 0; + gSprites[spriteId].data[7] = side; + + switch (side) + { + case 0xFF: // Player's side + gBankTarget = battler; + gSprites[spriteId].pos1.x = 24; + gSprites[spriteId].pos1.y = 68; + gSprites[spriteId].callback = SendOutPlayerMonAnimation_Step0; + break; + case 0xFE: // Opponent's side + gSprites[spriteId].pos1.x = GetBattlerSpriteCoord(battler, 0); + gSprites[spriteId].pos1.y = GetBattlerSpriteCoord(battler, 1) + 24; + gBankTarget = battler; + gSprites[spriteId].data[0] = 0; + gSprites[spriteId].callback = SendOutOpponentMonAnimation_Step0; + break; + default: + gBankTarget = GetBattlerAtPosition(1); + debug = TRUE; + break; + } + + gSprites[spriteId].data[6] = gBankTarget; + if (!debug) + { + DestroyTask(taskId); + return; + } + + gSprites[spriteId].data[0] = 0x22; + gSprites[spriteId].data[2] = GetBattlerSpriteCoord(gBankTarget, 0); + gSprites[spriteId].data[4] = GetBattlerSpriteCoord(gBankTarget, 1) - 16; + gSprites[spriteId].data[5] = -40; + InitAnimArcTranslation(&gSprites[spriteId]); + gSprites[spriteId].oam.affineParam = taskId; + gTasks[taskId].data[4] = gBankTarget; + gTasks[taskId].func = TaskDummy; + PlaySE(SE_NAGERU); +} + +static void objc_0804ABD4(struct Sprite *sprite) +{ + if (TranslateAnimArc(sprite)) + { + u8 taskId = sprite->oam.affineParam; + u8 r5 = gTasks[taskId].data[4]; + u8 r8 = gTasks[taskId].data[2]; + u32 r4; // not sure of this type + + StartSpriteAnim(sprite, 1); + sprite->affineAnimPaused = TRUE; + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; + sprite->data[5] = 0; + r4 = ball_number_to_ball_processing_index(GetBattlerBall(r5)); + AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 0x1C, r4); + sprite->data[0] = sub_8141314(0, r5, 14, r4); + sprite->data[6] = r5; + sprite->data[7] = r8; + DestroyTask(taskId); + sprite->callback = sub_80466E8; + } +} + +static void sub_80466E8(struct Sprite *sprite) +{ + sprite->callback = sub_80466F4; +} + +static void sub_80466F4(struct Sprite *sprite) +{ + sprite->data[5]++; + if (sprite->data[5] == 10) + { + sprite->data[5] = 0; + sprite->callback = sub_8046760; + StartSpriteAffineAnim(&gSprites[gBankSpriteIds[sprite->data[6]]], 2); + AnimateSprite(&gSprites[gBankSpriteIds[sprite->data[6]]]); + gSprites[gBankSpriteIds[sprite->data[6]]].data[1] = 0; + } +} + +static void sub_8046760(struct Sprite *sprite) +{ + sprite->data[5]++; + if (sprite->data[5] == 11) + PlaySE(SE_SUIKOMU); + if (gSprites[gBankSpriteIds[sprite->data[6]]].affineAnimEnded) + { + StartSpriteAnim(sprite, 2); + gSprites[gBankSpriteIds[sprite->data[6]]].invisible = TRUE; + sprite->data[5] = 0; + sprite->callback = sub_80467F8; + } + else + { + gSprites[gBankSpriteIds[sprite->data[6]]].data[1] += 0x60; + gSprites[gBankSpriteIds[sprite->data[6]]].pos2.y = -gSprites[gBankSpriteIds[sprite->data[6]]].data[1] >> 8; + } +} + +static void sub_80467F8(struct Sprite *sprite) +{ + if (sprite->animEnded) + { + sprite->data[5]++; + if (sprite->data[5] == 1) + { + sprite->data[3] = 0; + sprite->data[4] = 32; + sprite->data[5] = 0; + sprite->pos1.y += Cos(0, 32); + sprite->pos2.y = -Cos(0, sprite->data[4]); + sprite->callback = sub_804684C; + } + } +} + +static void sub_804684C(struct Sprite *sprite) +{ + bool8 r5 = FALSE; + + switch (sprite->data[3] & 0xFF) + { + case 0: + sprite->pos2.y = -Cos(sprite->data[5], sprite->data[4]); + sprite->data[5] += 4 + (sprite->data[3] >> 8); + if (sprite->data[5] >= 64) + { + sprite->data[4] -= 10; + sprite->data[3] += 0x101; + if (sprite->data[3] >> 8 == 4) + r5 = TRUE; + switch (sprite->data[3] >> 8) + { + case 1: + PlaySE(SE_KON); + break; + case 2: + PlaySE(SE_KON2); + break; + case 3: + PlaySE(SE_KON3); + break; + default: + PlaySE(SE_KON4); + break; + } + } + break; + case 1: + sprite->pos2.y = -Cos(sprite->data[5], sprite->data[4]); + sprite->data[5] -= 4 + (sprite->data[3] >> 8); + if (sprite->data[5] <= 0) + { + sprite->data[5] = 0; + sprite->data[3] &= 0xFF00; + } + break; + } + if (r5) + { + sprite->data[3] = 0; + sprite->pos1.y += Cos(64, 32); + sprite->pos2.y = 0; + if (sprite->data[7] == 0) + { + sprite->callback = sub_8046C78; + } + else + { + sprite->callback = sub_8046944; + sprite->data[4] = 1; + sprite->data[5] = 0; + } + } +} + +static void sub_8046944(struct Sprite *sprite) +{ + sprite->data[3]++; + if (sprite->data[3] == 31) + { + sprite->data[3] = 0; + sprite->affineAnimPaused = TRUE; + StartSpriteAffineAnim(sprite, 1); + sprite->callback = sub_8046984; + PlaySE(SE_BOWA); + } +} + +static void sub_8046984(struct Sprite *sprite) +{ + switch (sprite->data[3] & 0xFF) + { + case 0: + case 2: + sprite->pos2.x += sprite->data[4]; + sprite->data[5] += sprite->data[4]; + sprite->affineAnimPaused = FALSE; + if (sprite->data[5] > 3 || sprite->data[5] < -3) + { + sprite->data[3]++; + sprite->data[5] = 0; + } + break; + case 1: + sprite->data[5]++; + if (sprite->data[5] == 1) + { + sprite->data[5] = 0; + sprite->data[4] = -sprite->data[4]; + sprite->data[3]++; + sprite->affineAnimPaused = FALSE; + if (sprite->data[4] < 0) + ChangeSpriteAffineAnim(sprite, 2); + else + ChangeSpriteAffineAnim(sprite, 1); + } + else + { + sprite->affineAnimPaused = TRUE; + } + break; + case 3: + sprite->data[3] += 0x100; + if (sprite->data[3] >> 8 == sprite->data[7]) + { + sprite->callback = sub_8046C78; + } + else + { + if (sprite->data[7] == 4 && sprite->data[3] >> 8 == 3) + { + sprite->callback = sub_8046E7C; + sprite->affineAnimPaused = TRUE; + } + else + { + sprite->data[3]++; + sprite->affineAnimPaused = TRUE; + } + } + break; + case 4: + default: + sprite->data[5]++; + if (sprite->data[5] == 31) + { + sprite->data[5] = 0; + sprite->data[3] &= 0xFF00; + StartSpriteAffineAnim(sprite, 3); + if (sprite->data[4] < 0) + StartSpriteAffineAnim(sprite, 2); + else + StartSpriteAffineAnim(sprite, 1); + PlaySE(SE_BOWA); + } + break; + } +} + +static void sub_8046AD0(u8 taskId) +{ + u8 r6 = gTasks[taskId].data[2]; + u8 r3 = gTasks[taskId].data[1]; + u16 species = gTasks[taskId].data[0]; + + switch (gTasks[taskId].data[15]) + { + case 0: + default: + if (gTasks[taskId].data[8] < 3) + gTasks[taskId].data[8]++; + else + gTasks[taskId].data[15] = r6 + 1; + break; + case 1: + PlayCry1(species, r3); + DestroyTask(taskId); + break; + case 2: + StopCryAndClearCrySongs(); + gTasks[taskId].data[10] = 3; + gTasks[taskId].data[15] = 20; + break; + case 20: + if (gTasks[taskId].data[10] != 0) + { + gTasks[taskId].data[10]--; + break; + } + PlayCry4(species, r3, 1); + DestroyTask(taskId); + break; + case 3: + gTasks[taskId].data[10] = 6; + gTasks[taskId].data[15] = 30; + break; + case 30: + if (gTasks[taskId].data[10] != 0) + { + gTasks[taskId].data[10]--; + break; + } + gTasks[taskId].data[15]++; + // fall through + case 31: + if (!IsCryPlayingOrClearCrySongs()) + { + StopCryAndClearCrySongs(); + gTasks[taskId].data[10] = 3; + gTasks[taskId].data[15]++; + } + break; + case 32: + if (gTasks[taskId].data[10] != 0) + { + gTasks[taskId].data[10]--; + break; + } + PlayCry4(species, r3, 0); + DestroyTask(taskId); + break; + } +} + +static void sub_8046C78(struct Sprite *sprite) +{ + int ballIndex; + u8 battler = sprite->data[6]; + + StartSpriteAnim(sprite, 1); + ballIndex = ball_number_to_ball_processing_index(GetBattlerBall(battler)); + AnimateBallOpenParticles(sprite->pos1.x, sprite->pos1.y - 5, 1, 28, ballIndex); + sprite->data[0] = sub_8141314(1, sprite->data[6], 14, ballIndex); + sprite->callback = sub_8046E9C; + if (gMain.inBattle) + { + struct Pokemon *mon; + u16 species; + s8 cryPanning; + u16 cryBehavior; + u8 taskId; + + if (GetBattlerSide(battler) != 0) + { + mon = &gEnemyParty[gBattlerPartyIndexes[battler]]; + cryPanning = 25; + } + else + { + mon = &gPlayerParty[gBattlerPartyIndexes[battler]]; + cryPanning = -25; + } + + species = GetMonData(mon, MON_DATA_SPECIES); + if ((battler == GetBattlerAtPosition(0) || battler == GetBattlerAtPosition(1)) + && IsDoubleBattle() && ewram17840.unk9_0) + { + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (IsBGMPlaying()) + m4aMPlayStop(&gMPlay_BGM); + } + else + { + m4aMPlayVolumeControl(&gMPlay_BGM, 0xFFFF, 128); + } + } + + if (!IsDoubleBattle() || !ewram17840.unk9_0) + cryBehavior = 0; + else if (battler == GetBattlerAtPosition(0) || battler == GetBattlerAtPosition(1)) + cryBehavior = 1; + else + cryBehavior = 2; + + taskId = CreateTask(sub_8046AD0, 3); + gTasks[taskId].data[0] = species; + gTasks[taskId].data[1] = cryPanning; + gTasks[taskId].data[2] = cryBehavior; + gTasks[taskId].data[15] = 0; + } + + StartSpriteAffineAnim(&gSprites[gBankSpriteIds[sprite->data[6]]], 1); + AnimateSprite(&gSprites[gBankSpriteIds[sprite->data[6]]]); + gSprites[gBankSpriteIds[sprite->data[6]]].data[1] = 0x1000; +} + +static void sub_8046E7C(struct Sprite *sprite) +{ + sprite->animPaused = TRUE; + sprite->callback = sub_8046FBC; + sprite->data[3] = 0; + sprite->data[4] = 0; + sprite->data[5] = 0; +} + +static void sub_8046E9C(struct Sprite *sprite) +{ + bool8 r7 = FALSE; + u8 r4 = sprite->data[6]; + + gSprites[gBankSpriteIds[r4]].invisible = FALSE; + if (sprite->animEnded) + sprite->invisible = TRUE; + if (gSprites[gBankSpriteIds[r4]].affineAnimEnded) + { + StartSpriteAffineAnim(&gSprites[gBankSpriteIds[r4]], 0); + r7 = TRUE; + } + else + { + gSprites[gBankSpriteIds[r4]].data[1] -= 288; + gSprites[gBankSpriteIds[r4]].pos2.y = gSprites[gBankSpriteIds[r4]].data[1] >> 8; + } + if (sprite->animEnded && r7) + { + s32 i; + u32 r3; + + gSprites[gBankSpriteIds[r4]].pos2.y = 0; + gDoingBattleAnim = 0; + ewram17810[r4].unk0_3 = 0; + FreeSpriteOamMatrix(sprite); + DestroySprite(sprite); + for (r3 = 0, i = 0; i < 4; i++) + { + if (ewram17810[i].unk0_3 == 0) + r3++; + } + if (r3 == 4) + { + for (i = 0; i < 12; i++) + FreeBallGraphics(i); + } + } +} + +static void sub_8046FBC(struct Sprite *sprite) +{ + u8 r7 = sprite->data[6]; + + sprite->data[4]++; + if (sprite->data[4] == 40) + { + return; + } + else if (sprite->data[4] == 95) + { + gDoingBattleAnim = 0; + m4aMPlayAllStop(); + PlaySE(MUS_FANFA5); + } + else if (sprite->data[4] == 315) + { + FreeOamMatrix(gSprites[gBankSpriteIds[sprite->data[6]]].oam.matrixNum); + DestroySprite(&gSprites[gBankSpriteIds[sprite->data[6]]]); + DestroySpriteAndFreeResources(sprite); + if (gMain.inBattle) + ewram17810[r7].unk0_3 = 0; + } +} + +static void SendOutPlayerMonAnimation_Step0(struct Sprite *sprite) +{ + sprite->data[0] = 25; + sprite->data[2] = GetBattlerSpriteCoord(sprite->data[6], 2); + sprite->data[4] = GetBattlerSpriteCoord(sprite->data[6], 3) + 24; + sprite->data[5] = -30; + sprite->oam.affineParam = sprite->data[6]; + InitAnimArcTranslation(sprite); + sprite->callback = SendOutPlayerMonAnimation_Step1; +} + +#define HIBYTE(x) (((x) >> 8) & 0xFF) + +static void SendOutPlayerMonAnimation_Step1(struct Sprite *sprite) +{ + u32 r6; + u32 r7; + + if (HIBYTE(sprite->data[7]) >= 35 && HIBYTE(sprite->data[7]) < 80) + { + s16 r4; + + if ((sprite->oam.affineParam & 0xFF00) == 0) + { + r6 = sprite->data[1] & 1; + r7 = sprite->data[2] & 1; + sprite->data[1] = ((sprite->data[1] / 3) & ~1) | r6; + sprite->data[2] = ((sprite->data[2] / 3) & ~1) | r7; + StartSpriteAffineAnim(sprite, 4); + } + + r4 = sprite->data[0]; + TranslateAnimLinear(sprite); + sprite->data[7] += sprite->data[6] / 3; + sprite->pos2.y += Sin(HIBYTE(sprite->data[7]), sprite->data[5]); + sprite->oam.affineParam += 0x100; + if ((sprite->oam.affineParam >> 8) % 3 != 0) + sprite->data[0] = r4; + else + sprite->data[0] = r4 - 1; + + if (HIBYTE(sprite->data[7]) >= 80) + { + r6 = sprite->data[1] & 1; + r7 = sprite->data[2] & 1; + sprite->data[1] = ((sprite->data[1] * 3) & ~1) | r6; + sprite->data[2] = ((sprite->data[2] * 3) & ~1) | r7; + } + } + else + { + if (TranslateAnimArc(sprite)) + { + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.y = 0; + sprite->pos2.x = 0; + sprite->data[6] = sprite->oam.affineParam & 0xFF; + sprite->data[0] = 0; + if (IsDoubleBattle() && ewram17840.unk9_0 && sprite->data[6] == GetBattlerAtPosition(2)) + sprite->callback = SendOutMonAnimation_Delay; + else + sprite->callback = sub_8046C78; + + StartSpriteAffineAnim(sprite, 0); + } + } +} + +static void SendOutMonAnimation_Delay(struct Sprite *sprite) +{ + if (sprite->data[0]++ > 24) + { + sprite->data[0] = 0; + sprite->callback = sub_8046C78; + } +} + +static void SendOutOpponentMonAnimation_Step0(struct Sprite *sprite) +{ + sprite->data[0]++; + if (sprite->data[0] > 15) + { + sprite->data[0] = 0; + if (IsDoubleBattle() && ewram17840.unk9_0 && sprite->data[6] == GetBattlerAtPosition(3)) + sprite->callback = SendOutMonAnimation_Delay; + else + sprite->callback = sub_8046C78; + } +} + +static u8 sub_80472B0(u8 a, u8 b, u8 c, u8 d) +{ + return AnimateBallOpenParticles(a, b, c, d, 0); +} + +static u8 sub_80472D8(u8 a, u8 b, u32 c) +{ + return sub_8141314(a, b, c, 0); +} + +void CreatePokeballSprite(u8 a, u8 b, u8 x, u8 y, u8 e, u8 f, u8 g, u32 h) +{ + u8 spriteId; + + LoadCompressedObjectPic(&sBallSpriteSheets[0]); + LoadCompressedObjectPalette(&sBallSpritePalettes[0]); + spriteId = CreateSprite(&gBallSpriteTemplates[0], x, y, f); + gSprites[spriteId].data[0] = a; + gSprites[spriteId].data[5] = gSprites[a].pos1.x; + gSprites[spriteId].data[6] = gSprites[a].pos1.y; + gSprites[a].pos1.x = x; + gSprites[a].pos1.y = y; + gSprites[spriteId].data[1] = g; + gSprites[spriteId].data[2] = b; + gSprites[spriteId].data[3] = h; + gSprites[spriteId].data[4] = h >> 16; + gSprites[spriteId].oam.priority = e; + gSprites[spriteId].callback = sub_80473D0; + gSprites[a].invisible = TRUE; +} + +static void sub_80473D0(struct Sprite *sprite) +{ + if (sprite->data[1] == 0) + { + u8 r5; + u8 r7 = sprite->data[0]; + u8 r8 = sprite->data[2]; + u32 r4 = (u16)sprite->data[3] | ((u16)sprite->data[4] << 16); + + if (sprite->subpriority != 0) + r5 = sprite->subpriority - 1; + else + r5 = 0; + StartSpriteAnim(sprite, 1); + sub_80472B0(sprite->pos1.x, sprite->pos1.y - 5, sprite->oam.priority, r5); + sprite->data[1] = sub_80472D8(1, r8, r4); + sprite->callback = sub_804748C; + gSprites[r7].invisible = FALSE; + StartSpriteAffineAnim(&gSprites[r7], 1); + AnimateSprite(&gSprites[r7]); + gSprites[r7].data[1] = 0x1000; + sprite->data[7] = 0; + } + else + { + sprite->data[1]--; + } +} + +static void sub_804748C(struct Sprite *sprite) +{ + bool8 r12 = FALSE; + bool8 r6 = FALSE; + u8 r3 = sprite->data[0]; + u16 var1; + u16 var2; + + if (sprite->animEnded) + sprite->invisible = TRUE; + if (gSprites[r3].affineAnimEnded) + { + StartSpriteAffineAnim(&gSprites[r3], 0); + r12 = TRUE; + } + var1 = (sprite->data[5] - sprite->pos1.x) * sprite->data[7] / 128 + sprite->pos1.x; + var2 = (sprite->data[6] - sprite->pos1.y) * sprite->data[7] / 128 + sprite->pos1.y; + gSprites[r3].pos1.x = var1; + gSprites[r3].pos1.y = var2; + if (sprite->data[7] < 128) + { + s16 sine = -(gSineTable[(u8)sprite->data[7]] / 8); + + sprite->data[7] += 4; + gSprites[r3].pos2.x = sine; + gSprites[r3].pos2.y = sine; + } + else + { + gSprites[r3].pos1.x = sprite->data[5]; + gSprites[r3].pos1.y = sprite->data[6]; + gSprites[r3].pos2.x = 0; + gSprites[r3].pos2.y = 0; + r6 = TRUE; + } + if (sprite->animEnded && r12 && r6) + DestroySpriteAndFreeResources(sprite); +} + +u8 sub_8047580(u8 a, u8 b, u8 x, u8 y, u8 e, u8 f, u8 g, u32 h) +{ + u8 spriteId; + + LoadCompressedObjectPic(&sBallSpriteSheets[0]); + LoadCompressedObjectPalette(&sBallSpritePalettes[0]); + spriteId = CreateSprite(&gBallSpriteTemplates[0], x, y, f); + gSprites[spriteId].data[0] = a; + gSprites[spriteId].data[1] = g; + gSprites[spriteId].data[2] = b; + gSprites[spriteId].data[3] = h; + gSprites[spriteId].data[4] = h >> 16; + gSprites[spriteId].oam.priority = e; + gSprites[spriteId].callback = sub_8047638; + return spriteId; +} + +static void sub_8047638(struct Sprite *sprite) +{ + if (sprite->data[1] == 0) + { + u8 r6; + u8 r7 = sprite->data[0]; + u8 r8 = sprite->data[2]; + u32 r5 = (u16)sprite->data[3] | ((u16)sprite->data[4] << 16); + + if (sprite->subpriority != 0) + r6 = sprite->subpriority - 1; + else + r6 = 0; + StartSpriteAnim(sprite, 1); + sub_80472B0(sprite->pos1.x, sprite->pos1.y - 5, sprite->oam.priority, r6); + sprite->data[1] = sub_80472D8(1, r8, r5); + sprite->callback = sub_80476E0; + StartSpriteAffineAnim(&gSprites[r7], 2); + AnimateSprite(&gSprites[r7]); + gSprites[r7].data[1] = 0; + } + else + { + sprite->data[1]--; + } +} + +static void sub_80476E0(struct Sprite *sprite) +{ + u8 r1; + + sprite->data[5]++; + if (sprite->data[5] == 11) + PlaySE(SE_SUIKOMU); + r1 = sprite->data[0]; + if (gSprites[r1].affineAnimEnded) + { + StartSpriteAnim(sprite, 2); + gSprites[r1].invisible = TRUE; + sprite->data[5] = 0; + sprite->callback = sub_8047754; + } + else + { + gSprites[r1].data[1] += 96; + gSprites[r1].pos2.y = -gSprites[r1].data[1] >> 8; + } +} + +static void sub_8047754(struct Sprite *sprite) +{ + if (sprite->animEnded) + sprite->callback = SpriteCallbackDummy; +} + +void obj_delete_and_free_associated_resources_(struct Sprite *sprite) +{ + DestroySpriteAndFreeResources(sprite); +} + +void sub_804777C(u8 a) +{ + struct Sprite *sprite = &gSprites[gHealthboxIDs[a]]; + + sprite->data[0] = 5; + sprite->data[1] = 0; + sprite->pos2.x = 0x73; + sprite->pos2.y = 0; + sprite->callback = sub_8047830; + if (GetBattlerSide(a) != 0) + { + sprite->data[0] = -sprite->data[0]; + sprite->data[1] = -sprite->data[1]; + sprite->pos2.x = -sprite->pos2.x; + sprite->pos2.y = -sprite->pos2.y; + } + gSprites[sprite->data[5]].callback(&gSprites[sprite->data[5]]); + if (GetBattlerPosition(a) == 2) + sprite->callback = sub_804780C; +} + +static void sub_804780C(struct Sprite *sprite) +{ + sprite->data[1]++; + if (sprite->data[1] == 20) + { + sprite->data[1] = 0; + sprite->callback = sub_8047830; + } +} + +static void sub_8047830(struct Sprite *sprite) +{ + sprite->pos2.x -= sprite->data[0]; + sprite->pos2.y -= sprite->data[1]; + if (sprite->pos2.x == 0 && sprite->pos2.y == 0) + sprite->callback = SpriteCallbackDummy; +} + +void sub_8047858(u8 a) +{ + u8 spriteId; + + spriteId = CreateInvisibleSpriteWithCallback(oamc_804BEB4); + gSprites[spriteId].data[0] = 1; + gSprites[spriteId].data[1] = gHealthboxIDs[a]; + gSprites[spriteId].callback = oamc_804BEB4; +} + +static void oamc_804BEB4(struct Sprite *sprite) +{ + u8 r1 = sprite->data[1]; + + gSprites[r1].pos2.y = sprite->data[0]; + sprite->data[0] = -sprite->data[0]; + sprite->data[2]++; + if (sprite->data[2] == 21) + { + gSprites[r1].pos2.x = 0; + gSprites[r1].pos2.y = 0; + DestroySprite(sprite); + } +} + +void LoadBallGraphics(u8 ballIndex) +{ + u16 tileStart; + + if (GetSpriteTileStartByTag(sBallSpriteSheets[ballIndex].tag) == 0xFFFF) + { + LoadCompressedObjectPic(&sBallSpriteSheets[ballIndex]); + LoadCompressedObjectPalette(&sBallSpritePalettes[ballIndex]); + } + + switch (ballIndex) + { + case 6: + case 10: + case 11: + break; + default: + tileStart = GetSpriteTileStartByTag(sBallSpriteSheets[ballIndex].tag); + LZDecompressVram(gUnknown_08D030D0, (void *)(VRAM + 0x10100 + tileStart * 32)); + break; + } +} + +void FreeBallGraphics(u8 ballIndex) +{ + FreeSpriteTilesByTag(sBallSpriteSheets[ballIndex].tag); + FreeSpritePaletteByTag(sBallSpritePalettes[ballIndex].tag); +} + +static u16 GetBattlerBall(u8 battler) +{ + if (GetBattlerSide(battler) == B_SIDE_PLAYER) + return GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_POKEBALL); + else + return GetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_POKEBALL); +} diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index 217e8ccdf..134b2b753 100644 --- a/src/pokemon_summary_screen.c +++ b/src/pokemon_summary_screen.c @@ -1,6 +1,6 @@ #include "global.h" #include "battle.h" -#include "battle_anim_813F0F4.h" +#include "battle_anim_special.h" #include "contest.h" #include "data2.h" #include "daycare.h" diff --git a/src/post_battle_event_funcs.c b/src/post_battle_event_funcs.c new file mode 100644 index 000000000..d0fbbec85 --- /dev/null +++ b/src/post_battle_event_funcs.c @@ -0,0 +1,70 @@ +#include "global.h" +#include "event_data.h" +#include "hall_of_fame.h" +#include "load_save.h" +#include "main.h" +#include "pokemon.h" +#include "overworld.h" +#include "script_pokemon_80C4.h" +#include "constants/heal_locations.h" + +extern u8 gUnknown_02039324; + +int GameClear(void) +{ + int i; + bool32 ribbonGet; + + ScrSpecial_HealPlayerParty(); + + if (FlagGet(FLAG_SYS_GAME_CLEAR) == TRUE) + { + gUnknown_02039324 = 1; + } + else + { + gUnknown_02039324 = 0; + FlagSet(FLAG_SYS_GAME_CLEAR); + } + + if (!GetGameStat(GAME_STAT_FIRST_HOF_PLAY_TIME)) + SetGameStat(GAME_STAT_FIRST_HOF_PLAY_TIME, (gSaveBlock2.playTimeHours << 16) | (gSaveBlock2.playTimeMinutes << 8) | gSaveBlock2.playTimeSeconds); + + SetSecretBase2Field_9(); + + if (gSaveBlock2.playerGender == MALE) + sub_80537CC(HEAL_LOCATION_LITTLEROOT_TOWN_BRENDANS_HOUSE_2F); + else + sub_80537CC(HEAL_LOCATION_LITTLEROOT_TOWN_MAYS_HOUSE_2F); + + ribbonGet = FALSE; + + for (i = 0; i < 6; i++) + { + u8 val; + u8 *ptr = &val; + if (GetMonData(&gPlayerParty[i], MON_DATA_SANITY_BIT2) + && !GetMonData(&gPlayerParty[i], MON_DATA_SANITY_BIT3) + && !GetMonData(&gPlayerParty[i], MON_DATA_CHAMPION_RIBBON)) + { + *ptr = 1; + SetMonData(&gPlayerParty[i], MON_DATA_CHAMPION_RIBBON, ptr); + ribbonGet = TRUE; + } + } + + if (ribbonGet == TRUE) + { + IncrementGameStat(GAME_STAT_RECEIVED_RIBBONS); + FlagSet(FLAG_SYS_RIBBON_GET); + } + + SetMainCallback2(sub_8141F90); + return 0; +} + +int sp0C8_whiteout_maybe(void) +{ + SetMainCallback2(CB2_WhiteOut); + return 0; +} diff --git a/src/reshow_battle_screen.c b/src/reshow_battle_screen.c new file mode 100644 index 000000000..712ec3ea8 --- /dev/null +++ b/src/reshow_battle_screen.c @@ -0,0 +1,316 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "palette.h" +#include "main.h" +#include "scanline_effect.h" +#include "text.h" +#include "rom_8077ABC.h" +#include "data2.h" +#include "ewram.h" + +extern struct SpriteTemplate gUnknown_02024E8C; +extern struct Window gUnknown_03004210; +extern u8 gReservedSpritePaletteCount; +extern u8 gActionSelectionCursor[4]; +extern u8 gBankInMenu; +extern u16 gBattlerPartyIndexes[4]; +extern u8 gBattlersCount; +extern u16 gBattleTypeFlags; +extern u8 gBankSpriteIds[4]; +extern u8 gBattleMonForms[4]; +extern u8 gHealthboxIDs[4]; + +bool8 LoadChosenBattleElement(u8 a0); +bool8 sub_8031C30(u8 a0); +void sub_8031EE8(void); +void sub_80327CC(void); +void sub_8032984(u8 a, u16 b); +void sub_800FCD4(void); +void BattleLoadOpponentMonSprite(struct Pokemon *, u8 bank); +void BattleLoadPlayerMonSprite(struct Pokemon *, u8 bank); +void BattleLoadSubstituteSprite(u8 bank, u8 b); +void LoadPlayerTrainerBankSprite(u16 a0, u8 bank); +u8 sub_8077F7C(u8 bank); +u8 sub_8077F68(u8 bank); +void nullsub_11(u8 healthboxID, u8 a1); +void sub_8043DB0(u8 bank); +u8 battle_make_oam_normal_battle(u8 bank); +u8 battle_make_oam_safari_battle(void); +void sub_8045A5C(u8 healthboxID, struct Pokemon*, u8); +void sub_8043F44(u8 bank); +void sub_8043DFC(u8 healthboxID); + +// this file's functions +static void CB2_ReshowBattleScreenAfterMenu(void); +static bool8 LoadAppropiateBankSprite(u8 bank); +static void sub_807B184(u8 bank); +static void sub_807B508(u8 bank); +static void sub_807B06C(void); + +void nullsub_14(void) +{ + +} + +void ReshowBattleScreenAfterMenu(void) +{ + gPaletteFade.bufferTransferDisabled = 1; + SetHBlankCallback(0); + SetVBlankCallback(0); + REG_MOSAIC = 0; + gReshowState = 0; + gHelperState = 0; + SetMainCallback2(CB2_ReshowBattleScreenAfterMenu); +} + +static void CB2_ReshowBattleScreenAfterMenu(void) +{ + switch (gReshowState) + { + case 0: + ScanlineEffect_Clear(); + Text_LoadWindowTemplate(&gWindowTemplate_81E6C58); + ResetPaletteFade(); + Text_InitWindowWithTemplate(&gUnknown_03004210, &gWindowTemplate_81E6C58); + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gBattle_BG1_X = 0; + gBattle_BG1_Y = 0; + gBattle_BG2_X = 0; + gBattle_BG2_Y = 0; + gBattle_BG3_X = 0; + gBattle_BG3_Y = 0; + break; + case 1: + { + const u32 zero = 0; + CpuFastSet(&zero, (void*) VRAM, 0x1006000); + } + break; + case 2: + if (!LoadChosenBattleElement(gHelperState)) + { + gHelperState++; + gReshowState--; + } + else + gHelperState = 0; + break; + case 3: + ResetSpriteData(); + break; + case 4: + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 4; + break; + case 5: + sub_8031EE8(); + break; + case 6: + if (sub_8031C30(gHelperState)) + gHelperState = 0; + else + { + gHelperState++; + gReshowState--; + } + break; + case 7: + if (!LoadAppropiateBankSprite(0)) + gReshowState--; + break; + case 8: + if (!LoadAppropiateBankSprite(1)) + gReshowState--; + break; + case 9: + if (!LoadAppropiateBankSprite(2)) + gReshowState--; + break; + case 10: + if (!LoadAppropiateBankSprite(3)) + gReshowState--; + break; + case 11: + sub_807B184(0); + break; + case 12: + sub_807B184(1); + break; + case 13: + sub_807B184(2); + break; + case 14: + sub_807B184(3); + break; + case 15: + sub_807B508(0); + break; + case 16: + sub_807B508(1); + break; + case 17: + sub_807B508(2); + break; + case 18: + sub_807B508(3); + break; + case 19: + { + u8 opponentBank; + u16 species; + + sub_80327CC(); + + opponentBank = GetBattlerAtPosition(1); + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[opponentBank]], MON_DATA_SPECIES); + sub_8032984(opponentBank, species); + + if (IsDoubleBattle()) + { + opponentBank = GetBattlerAtPosition(3); + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[opponentBank]], MON_DATA_SPECIES); + sub_8032984(opponentBank, species); + } + sub_802E3E4(gActionSelectionCursor[gBankInMenu], 0); + } + break; + default: + SetHBlankCallback(sub_800FCD4); + SetVBlankCallback(sub_800FCFC); + sub_807B06C(); + BeginHardwarePaletteFade(0xFF, 0, 0x10, 0, 1); + gPaletteFade.bufferTransferDisabled = 0; + SetMainCallback2(BattleMainCB2); + break; + } + gReshowState++; +} + +static void sub_807B06C(void) +{ + sub_800D6D4(); + ((vBgCnt *)®_BG1CNT)->charBaseBlock = 0; + ((vBgCnt *)®_BG2CNT)->charBaseBlock = 0; +} + +static bool8 LoadAppropiateBankSprite(u8 bank) +{ + if (bank < gBattlersCount) + { + if (GetBattlerSide(bank)) + { + if (!ewram17800[bank].substituteSprite) + BattleLoadOpponentMonSprite(&gEnemyParty[gBattlerPartyIndexes[bank]], bank); + else + BattleLoadSubstituteSprite(bank, 0); + } + else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0) + LoadPlayerTrainerBankSprite(gSaveBlock2.playerGender, 0); + else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && bank == 0) + LoadPlayerTrainerBankSprite(2, 0); + else if (!ewram17800[bank].substituteSprite) + BattleLoadPlayerMonSprite(&gPlayerParty[gBattlerPartyIndexes[bank]], bank); + else + BattleLoadSubstituteSprite(bank, 0); + + gHelperState = 0; + } + return 1; +} + +static void sub_807B184(u8 bank) +{ + if (bank < gBattlersCount) + { + u8 posY; + + if (ewram17800[bank].substituteSprite) + posY = sub_8077F7C(bank); + else + posY = sub_8077F68(bank); + if (GetBattlerSide(bank)) + { + if (GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_HP) == 0) + return; + GetMonSpriteTemplate_803C56C(GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES), GetBattlerPosition(bank)); + gBankSpriteIds[bank] = CreateSprite(&gUnknown_02024E8C, GetBattlerSpriteCoord(bank, 2), posY, GetBattlerSubpriority(bank)); + gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; + gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; + gSprites[gBankSpriteIds[bank]].data[0] = bank; + gSprites[gBankSpriteIds[bank]].data[2] = GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES); + StartSpriteAnim(&gSprites[gBankSpriteIds[bank]], gBattleMonForms[bank]); + } + else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0) + { + GetMonSpriteTemplate_803C5A0(gSaveBlock2.playerGender, GetBattlerPosition(0)); + gBankSpriteIds[bank] = CreateSprite(&gUnknown_02024E8C, 0x50, + (8 - gTrainerBackPicCoords[gSaveBlock2.playerGender].coords) * 4 + 80, + GetBattlerSubpriority(0)); + gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; + gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; + gSprites[gBankSpriteIds[bank]].data[0] = bank; + } + else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && bank == 0) + { + GetMonSpriteTemplate_803C5A0(2, GetBattlerPosition(0)); + gBankSpriteIds[bank] = CreateSprite(&gUnknown_02024E8C, 0x50, + (8 - gTrainerBackPicCoords[2].coords) * 4 + 80, + GetBattlerSubpriority(0)); + gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; + gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; + gSprites[gBankSpriteIds[bank]].data[0] = bank; + } + else + { + if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_HP) == 0) + return; + GetMonSpriteTemplate_803C56C(GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES), GetBattlerPosition(bank)); + gBankSpriteIds[bank] = CreateSprite(&gUnknown_02024E8C, GetBattlerSpriteCoord(bank, 2), posY, GetBattlerSubpriority(bank)); + gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank; + gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy; + gSprites[gBankSpriteIds[bank]].data[0] = bank; + gSprites[gBankSpriteIds[bank]].data[2] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_SPECIES); + StartSpriteAnim(&gSprites[gBankSpriteIds[bank]], gBattleMonForms[bank]); + } + gSprites[gBankSpriteIds[bank]].invisible = ewram17800[bank].invisible; + } +} + +static void sub_807B508(u8 bank) +{ + if (bank < gBattlersCount) + { + u8 healthboxID; + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0) + healthboxID = battle_make_oam_safari_battle(); + else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && bank == 0) + return; + else + healthboxID = battle_make_oam_normal_battle(bank); + gHealthboxIDs[bank] = healthboxID; + sub_8043F44(bank); + sub_8043DFC(healthboxID); + if (GetBattlerSide(bank)) + sub_8045A5C(gHealthboxIDs[bank], &gEnemyParty[gBattlerPartyIndexes[bank]], 0); + else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + sub_8045A5C(gHealthboxIDs[bank], &gPlayerParty[gBattlerPartyIndexes[bank]], 10); + else + sub_8045A5C(gHealthboxIDs[bank], &gPlayerParty[gBattlerPartyIndexes[bank]], 0); + if (GetBattlerPosition(bank) == 3 || GetBattlerPosition(bank) == 2) + nullsub_11(gHealthboxIDs[bank], 1); + else + nullsub_11(gHealthboxIDs[bank], 0); + if (GetBattlerSide(bank)) + { + if (GetMonData(&gEnemyParty[gBattlerPartyIndexes[bank]], MON_DATA_HP) == 0) + sub_8043DB0(healthboxID); + } + else if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) + { + if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[bank]], MON_DATA_HP) == 0) + sub_8043DB0(healthboxID); + } + } +} diff --git a/src/rom3.c b/src/rom3.c index a9433695d..d332b7027 100644 --- a/src/rom3.c +++ b/src/rom3.c @@ -1,7 +1,7 @@ #include "global.h" #include "battle.h" #include "battle_811DA74.h" -#include "battle_ai.h" +#include "battle_ai_script_commands.h" #include "battle_anim.h" #include "battle_anim_81258BC.h" #include "battle_anim_8137220.h" diff --git a/src/smokescreen.c b/src/smokescreen.c new file mode 100644 index 000000000..dc2887007 --- /dev/null +++ b/src/smokescreen.c @@ -0,0 +1,73 @@ +#include "global.h" +#include "data2.h" +#include "decompress.h" +#include "sprite.h" +#include "util.h" + + +static void sub_8046388(struct Sprite *); + + +u8 sub_8046234(s16 x, s16 y, u8 a3) +{ + u8 mainSpriteId; + u8 spriteId1, spriteId2, spriteId3, spriteId4; + struct Sprite *mainSprite; + + if (GetSpriteTileStartByTag(gUnknown_081FAEA4.tag) == 0xFFFF) + { + LoadCompressedObjectPic(&gUnknown_081FAEA4); + LoadCompressedObjectPalette(&gUnknown_081FAEAC); + } + + mainSpriteId = CreateInvisibleSpriteWithCallback(sub_8046388); + mainSprite = &gSprites[mainSpriteId]; + mainSprite->data[1] = a3; + + spriteId1 = CreateSprite(&gSpriteTemplate_81FAF0C, x - 16, y - 16, 2); + gSprites[spriteId1].data[0] = mainSpriteId; + mainSprite->data[0]++; + AnimateSprite(&gSprites[spriteId1]); + + spriteId2 = CreateSprite(&gSpriteTemplate_81FAF0C, x, y - 16, 2); + gSprites[spriteId2].data[0] = mainSpriteId; + mainSprite->data[0]++; + StartSpriteAnim(&gSprites[spriteId2], 1); + AnimateSprite(&gSprites[spriteId2]); + + spriteId3 = CreateSprite(&gSpriteTemplate_81FAF0C, x - 16, y, 2); + gSprites[spriteId3].data[0] = mainSpriteId; + mainSprite->data[0]++; + StartSpriteAnim(&gSprites[spriteId3], 2); + AnimateSprite(&gSprites[spriteId3]); + + spriteId4 = CreateSprite(&gSpriteTemplate_81FAF0C, x, y, 2); + gSprites[spriteId4].data[0] = mainSpriteId; + mainSprite->data[0]++; + StartSpriteAnim(&gSprites[spriteId4], 3); + AnimateSprite(&gSprites[spriteId4]); + + return mainSpriteId; +} + +static void sub_8046388(struct Sprite *sprite) +{ + if (!sprite->data[0]) + { + FreeSpriteTilesByTag(gUnknown_081FAEA4.tag); + FreeSpritePaletteByTag(gUnknown_081FAEAC.tag); + if (!sprite->data[1]) + DestroySprite(sprite); + else + sprite->callback = SpriteCallbackDummy; + } +} + +void sub_80463CC(struct Sprite *sprite) +{ + if (sprite->animEnded) + { + gSprites[sprite->data[0]].data[0]--; + DestroySprite(sprite); + } +} -- cgit v1.2.3