From 4b3c1559159375343fb1322af8a9f1e8261decc6 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 17 Sep 2024 14:48:50 -0400 Subject: [PATCH] WIP File split for HandleAction_UseItem on DEBUG --- asmdiff.sh | 6 +- include/battle.h | 32 + ld_script.ld | 8 +- src/battle_ai_switch_items.c | 2 - src/battle_controller_link_opponent.c | 1 - src/battle_controller_player.c | 17 - src/battle_controller_safari.c | 1 - src/battle_controllers.c | 2 - src/battle_main.c | 5721 ------------------------- src/battle_main1.c | 1206 ++++++ src/battle_main2.c | 2290 ++++++++++ src/battle_message.c | 1 - src/battle_script_commands.c | 7 - src/battle_util.c | 538 ++- src/calculate_base_damage.c | 1 - src/debug/battle.c | 1727 ++++++++ src/debug/watanabe_debug_menu.c | 2 - src/evolution_scene.c | 1 - src/pokemon_2.c | 1 - src/pokemon_3.c | 1 - src/pokemon_item_effect.c | 1 - sym_ewram.txt | 4 +- 22 files changed, 5802 insertions(+), 5768 deletions(-) delete mode 100644 src/battle_main.c create mode 100644 src/battle_main1.c create mode 100644 src/battle_main2.c create mode 100644 src/debug/battle.c diff --git a/asmdiff.sh b/asmdiff.sh index 1172b64d53..92a067c7e6 100755 --- a/asmdiff.sh +++ b/asmdiff.sh @@ -2,6 +2,6 @@ OBJDUMP="$DEVKITARM/bin/arm-none-eabi-objdump -D -bbinary -marmv4t -Mforce-thumb" OPTIONS="--start-address=$(($1)) --stop-address=$(($1 + $2))" -$OBJDUMP $OPTIONS baserom.gba > baserom.dump -$OBJDUMP $OPTIONS pokeruby.gba > pokeruby.dump -diff -u baserom.dump pokeruby.dump +$OBJDUMP $OPTIONS baserom_$1.gba > baserom_$1.dump +$OBJDUMP $OPTIONS $1.gba > $1.dump +diff -u baserom_$1.dump $1.dump diff --git a/include/battle.h b/include/battle.h index 59bfea1d2c..1ee7529d25 100644 --- a/include/battle.h +++ b/include/battle.h @@ -611,6 +611,37 @@ extern u8 gDisplayedStringBattle[]; extern u16 gBattleTypeFlags; extern u8 gUnknown_02023A14_50; extern u16 gTrainerBattleOpponent; +extern u8 gCurrentTurnActionNumber; +extern u8 gCritMultiplier; +extern u8 gMultiHitCounter; +extern u16 gChosenMove; +extern u16 gLockedMoves[MAX_BATTLERS_COUNT]; +extern const u8 * const gBattleScriptsForMoveEffects[]; +extern const u8 * const gBattlescriptsForBallThrow[]; +extern const u8 * const gBattlescriptsForRunningByItem[]; +extern const u8 * const gBattlescriptsForUsingItem[]; +extern const u8 * const gBattlescriptsForSafariActions[]; +extern const u8 BattleScript_LocalTrainerBattleWon[]; +extern const u8 BattleScript_LocalBattleLost[]; +extern const u8 BattleScript_GotAwaySafely[]; +extern const u8 BattleScript_SmokeBallEscape[]; +extern const u8 BattleScript_RanAwayUsingMonAbility[]; +extern const u8 BattleScript_WildMonFled[]; +extern const u8 BattleScript_ActionSwitch[]; +extern const u8 BattleScript_PrintFailedToRunString[]; +extern u8 gActionSelectionCursor[MAX_BATTLERS_COUNT]; +extern u8 gMoveSelectionCursor[MAX_BATTLERS_COUNT]; +extern u8 gActionsByTurnOrder[MAX_BATTLERS_COUNT]; +extern u16 gLastHitByType[MAX_BATTLERS_COUNT]; +extern u16 gLastLandedMoves[MAX_BATTLERS_COUNT]; +extern u8 gBattleOutcome; +extern u8 gActionForBanks[MAX_BATTLERS_COUNT]; +extern u8 gNumSafariBalls; +extern u8 gBattleCommunication[8]; +extern u8 gBattleTerrain; +extern struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT]; +extern MainCallback gPreBattleCallback1; +extern u16 gCurrentMove; // src/battle_bg.o void sub_800D6D4(); @@ -714,5 +745,6 @@ void sub_80324E0(u8 a); void SetBankFuncToLinkOpponentBufferRunCommand(void); void GameClear(void); +void SpecialStatusesClear(void); #endif // GUARD_BATTLE_H diff --git a/ld_script.ld b/ld_script.ld index 0c1afe3080..ccbc55916f 100644 --- a/ld_script.ld +++ b/ld_script.ld @@ -57,7 +57,9 @@ SECTIONS { src/battle_controllers.o(.text); src/decompress.o(.text); src/battle_bg.o(.text); - src/battle_main.o(.text); + src/battle_main1.o(.text); + src/debug/battle.o(.text); + src/battle_main2.o(.text); src/battle_util.o(.text); src/battle_script_commands.o(.text); src/battle_controller_player.o(.text); @@ -494,7 +496,9 @@ SECTIONS { src/battle_ai_switch_items.o(.rodata); src/battle_controller_link_opponent.o(.rodata); src/data/battle_moves.o(.rodata); - src/battle_main.o(.rodata); + src/battle_main1.o(.rodata); + src/debug/battle.o(.rodata); + src/battle_main2.o(.rodata); src/battle_util.o(.rodata); src/pokemon_1.o(.rodata); src/pokemon_1.o(.data); /* gEvolutionTable needs to be non-const to match */ diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 40feaa20d6..54815e2886 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -23,9 +23,7 @@ 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]; diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c index abcfcce279..92c016f29b 100644 --- a/src/battle_controller_link_opponent.c +++ b/src/battle_controller_link_opponent.c @@ -51,7 +51,6 @@ extern u8 gAnimMoveTurn; extern struct Window gWindowTemplate_Contest_MoveDescription; extern u8 gUnknown_0300434C[]; extern u32 gBattleControllerExecFlags; -extern MainCallback gPreBattleCallback1; extern struct MusicPlayerInfo gMPlayInfo_BGM; extern u8 sub_8077F68(); diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index a4c76992c6..a140b5eb95 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -45,9 +45,7 @@ extern u8 gBattlerTarget; 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[]; @@ -127,32 +125,17 @@ extern u8 sub_8077F68(); extern u8 StartSendOutMonAnimation(); extern void sub_802D798(void); extern void bx_0802E404(void); -extern u8 gActiveBattler; -extern void (*gBattlerControllerFuncs[])(void); -extern bool8 gDoingBattleAnim; -extern u16 gBattleTypeFlags; extern u32 gBattleControllerExecFlags; -extern u8 gBattleBufferA[][0x200]; -extern u8 gBattlerSpriteIds[]; -extern u8 gActionSelectionCursor[]; -extern u8 gMoveSelectionCursor[]; extern u8 gAbsentBattlerFlags; -extern u8 gUnknown_03004344; extern u8 gBattlersCount; -extern u16 gBattlerPartyIndexes[]; -extern struct Window gWindowTemplate_Contest_MoveDescription; extern const u8 BattleText_SwitchWhich[]; extern u8 gUnknown_03004348; extern struct BattlePokemon gBattleMons[]; extern MainCallback gPreBattleCallback1; -extern u8 gHealthboxSpriteIds[]; extern struct MusicPlayerInfo gMPlayInfo_BGM; -extern u8 gUnknown_0300434C[]; extern u8 gUnknown_0202E8F4; extern u8 gUnknown_0202E8F5; -extern u8 gBattlePartyCurrentOrder[]; extern u16 gSpecialVar_ItemId; -extern u8 gDisplayedStringBattle[]; extern const u8 BattleText_LinkStandby[]; extern void dp11b_obj_instanciate(u8, u8, s8, s8); diff --git a/src/battle_controller_safari.c b/src/battle_controller_safari.c index cf09ef1648..f498252437 100644 --- a/src/battle_controller_safari.c +++ b/src/battle_controller_safari.c @@ -17,7 +17,6 @@ extern struct Window gWindowTemplate_Contest_MoveDescription; extern u8 gDisplayedStringBattle[]; -extern u8 gActionSelectionCursor[]; extern const u8 BattleText_PlayerMenu[]; extern u8 gActiveBattler; diff --git a/src/battle_controllers.c b/src/battle_controllers.c index d4d86305ac..624551b219 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -49,8 +49,6 @@ extern u8 gAbsentBattlerFlags; extern u8 gMultiHitCounter; extern u8 gUnknown_02024C78; extern u8 gBattleOutcome; -extern u8 gActionSelectionCursor[]; -extern u8 gMoveSelectionCursor[]; extern u8 gBattleTextBuff1[]; extern u8 gBattleTextBuff2[]; extern u8 gBattleTextBuff3[]; diff --git a/src/battle_main.c b/src/battle_main.c deleted file mode 100644 index e7c1f85386..0000000000 --- a/src/battle_main.c +++ /dev/null @@ -1,5721 +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_script_commands.h" -#include "battle_controllers.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 "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" -#include "battle_string_ids.h" -#include "battle_ai_switch_items.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(u8 r0, u8 r1, u8 r2, u8 r3, u8 sp0); - -extern struct SpriteTemplate gCreatingSpriteTemplate; -extern const u8 Str_821F7B8[]; -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 const u8 gStatStageRatios[][2]; -extern u8 gBattlePartyCurrentOrder[]; -MainCallback gPreBattleCallback1; -u8 gUnknown_03004344; -u8 gUnknown_03004348; -extern void (*gBattleMainFunc)(void); -u8 gLeveledUpInBattle; -void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); -u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; -u8 gUnknown_0300434C[MAX_BATTLERS_COUNT]; -extern u8 gReservedSpritePaletteCount; -extern u16 gTrainerBattleOpponent; -extern u16 gBlockRecvBuffer[MAX_LINK_PLAYERS][BLOCK_BUFFER_SIZE / 2]; -extern const u8 BattleScript_FocusPunchSetUp[]; -extern void (* const gUnknown_081FA640[])(void); -extern void (* const gUnknown_081FA678[])(void); -extern const u8 BattleScript_LinkBattleWonOrLost[]; -extern const u8 BattleScript_PayDayMoneyAndPickUpItems[]; -extern const u8 gUnknown_081D8E0D[]; -extern const u8 BattleScript_LocalTrainerBattleWon[]; -extern const u8 BattleScript_LocalBattleLost[]; -extern const u8 BattleScript_GotAwaySafely[]; -extern const u8 BattleScript_SmokeBallEscape[]; -extern const u8 BattleScript_RanAwayUsingMonAbility[]; -extern const u8 BattleScript_WildMonFled[]; -extern const u8 BattleScript_ActionSwitch[]; -extern const u8 BattleScript_PrintFailedToRunString[]; -extern const BattleCmdFunc gBattleScriptingCommandsTable[]; -extern const u8 * const gBattleScriptsForMoveEffects[]; -extern const u8 * const gBattlescriptsForBallThrow[]; -extern const u8 * const gBattlescriptsForRunningByItem[]; -extern const u8 * const gBattlescriptsForUsingItem[]; -extern const u8 * const gBattlescriptsForSafariActions[]; -extern u8 gNumSafariBalls; -extern u8 gUnknown_081FA70C[][3]; -extern u8 gUnknown_081FA71B[]; -extern u8 gUnknown_081FA71F[]; -struct BattleResults gBattleResults; - -void BattleMainCB1(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); - - -u16 gBattle_BG0_X; -u16 gBattle_BG0_Y; -u16 gBattle_BG1_X; -u16 gBattle_BG1_Y; -u16 gBattle_BG2_X; -u16 gBattle_BG2_Y; -u16 gBattle_BG3_X; -u16 gBattle_BG3_Y; -u16 gBattle_WIN0H; -u16 gBattle_WIN0V; -u16 gBattle_WIN1H; -u16 gBattle_WIN1V; -EWRAM_DATA u8 gDisplayedStringBattle[300] = {0}; -u8 gBattleTextBuff1[TEXT_BUFF_ARRAY_COUNT]; -u8 gBattleTextBuff2[TEXT_BUFF_ARRAY_COUNT]; -u8 gBattleTextBuff3[TEXT_BUFF_ARRAY_COUNT]; -EWRAM_DATA u16 gBattleTypeFlags = 0; -s8 gBattleTerrain; -EWRAM_DATA u32 gUnknown_020239FC = 0; -EWRAM_DATA struct MultiBattlePokemonTx gMultiPartnerParty[3] = {0}; -#if DEBUG -EWRAM_DATA u32 gUnknown_02023A14_4C = 0; -EWRAM_DATA u8 gUnknown_02023A14_50 = 0; -EWRAM_DATA s16 gUnknown_Debug_2023A76[2][35] = {0}; -EWRAM_DATA s16 gUnknown_Debug_2023B02[2][6][4] = {0}; -EWRAM_DATA u8 gUnknown_Debug_2023B62[418] = {0}; // TODO: NUM_SPECIES? -#endif -EWRAM_DATA u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200] = {0}; -EWRAM_DATA u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200] = {0}; -EWRAM_DATA u8 gActiveBattler = 0; -EWRAM_DATA u32 gBattleControllerExecFlags = 0; -EWRAM_DATA u8 gBattlersCount = 0; -EWRAM_DATA u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gBattlerPositions[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gActionsByTurnOrder[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gBattlerByTurnOrder[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gCurrentTurnActionNumber = 0; -EWRAM_DATA u8 gCurrentActionFuncId = 0; -EWRAM_DATA struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gCurrMovePos = 0; -EWRAM_DATA u8 gUnknown_02024BE5 = 0; -EWRAM_DATA u16 gCurrentMove = 0; -EWRAM_DATA u16 gChosenMove = 0; -EWRAM_DATA u16 gRandomMove = 0; -EWRAM_DATA s32 gBattleMoveDamage = 0; -EWRAM_DATA s32 gHpDealt = 0; -EWRAM_DATA s32 gTakenDmg[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u16 gLastUsedItem = 0; -EWRAM_DATA u8 gLastUsedAbility = 0; -EWRAM_DATA u8 gBattlerAttacker = 0; -EWRAM_DATA u8 gBattlerTarget = 0; -EWRAM_DATA u8 gBank1 = 0; -EWRAM_DATA u8 gEffectBattler = 0; -EWRAM_DATA u8 gPotentialItemEffectBattler = 0; -EWRAM_DATA u8 gAbsentBattlerFlags = 0; -EWRAM_DATA u8 gCritMultiplier = 0; -EWRAM_DATA u8 gMultiHitCounter = 0; -EWRAM_DATA const u8 * gBattlescriptCurrInstr = NULL; -EWRAM_DATA u32 gUnusedBattleMainVar = 0; -EWRAM_DATA u8 gActionForBanks[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA const u8 * gSelectionBattleScripts[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u16 gLastPrintedMoves[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u16 gLastMoves[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u16 gLastLandedMoves[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u16 gLastHitByType[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u16 gLastResultingMoves[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u16 gLockedMoves[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gLastHitBy[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u16 gChosenMovesByBanks[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gMoveResultFlags = 0; -EWRAM_DATA u32 gHitMarker = 0; -EWRAM_DATA u8 sUnusedBattlersArray[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gTakenDmgByBattler[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gUnknown_02024C78 = 0; -EWRAM_DATA u16 gSideStatuses[2] = {0}; -EWRAM_DATA struct SideTimer gSideTimers[2] = {0}; -EWRAM_DATA u32 gStatuses3[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u16 gPauseCounterBattle = 0; -EWRAM_DATA u16 gPaydayMoney = 0; -EWRAM_DATA u16 gRandomTurnNumber = 0; -EWRAM_DATA u8 gBattleCommunication[8] = {0}; -EWRAM_DATA u8 gBattleOutcome = 0; -EWRAM_DATA struct ProtectStruct gProtectStructs[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA struct SpecialStatus gSpecialStatuses[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u16 gBattleWeather = 0; -EWRAM_DATA struct WishFutureKnock gWishFutureKnock = {0}; -EWRAM_DATA u16 gIntroSlideFlags = 0; -EWRAM_DATA u8 gSentPokesToOpponent[2] = {0}; -EWRAM_DATA u16 gDynamicBasePower = 0; -EWRAM_DATA u16 gExpShareExp = 0; -EWRAM_DATA struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gActionSelectionCursor[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gMoveSelectionCursor[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gUnknown_02024E68[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u8 gBankInMenu = 0; -EWRAM_DATA u8 gDoingBattleAnim = 0; -EWRAM_DATA u32 gTransformedPersonalities[MAX_BATTLERS_COUNT] = {0}; -EWRAM_DATA u16 gBattleMovePower = 0; -EWRAM_DATA u16 gMoveToLearn = 0; -EWRAM_DATA u8 gBattleMonForms[MAX_BATTLERS_COUNT] = {0}; - -void (*gBattleMainFunc)(void); - -u32 gUnknown_03004284; -struct Window gWindowTemplate_Contest_MoveDescription; -struct Window gUnknown_030041D0; -struct Window gUnknown_03004250; - -void CB2_InitBattle(void) -{ - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - HandleLinkBattleSetup(); - SetMainCallback2(sub_800F104); - gBattleCommunication[0] = 0; - } - else - { - CB2_InitBattleInternal(); - } -} - -void CB2_InitBattleInternal(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 < 160; i++) - { - gScanlineEffectRegBuffers[0][i] = 0xFF10; - gScanlineEffectRegBuffers[1][i] = 0xFF10; - } - //ScanlineEffect_SetParams(gUnknown_081F9674.totalPoints, gUnknown_081F9674.round1Points, gUnknown_081F9674.random); - 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(&gWindowTemplate_Contest_MoveDescription, &gWindowTemplate_81E6C58); - Text_InitWindowWithTemplate(&gUnknown_030041D0, &gWindowTemplate_81E71D0); - Text_InitWindowWithTemplate(&gUnknown_03004250, &gWindowTemplate_81E71EC); - sub_800D6D4(); - LoadBattleTextboxAndBackground(); - ResetSpriteData(); - ResetTasks(); - DrawBattleEntryBackground(); - FreeAllSpritePalettes(); - gReservedSpritePaletteCount = 4; - SetVBlankCallback(sub_800FCFC); - SetUpBattleVarsAndBirchPoochyena(); - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - SetMainCallback2(CB2_HandleStartMultiBattle); - else - SetMainCallback2(CB2_HandleStartBattle); - 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 BufferPartyVsScreenHealth_AtStart(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 == SPECIES_NONE) - continue; - if (species != SPECIES_EGG && hp != 0 && status == 0) - r6 |= 1 << i * 2; - - if (species == SPECIES_NONE) - continue; - if (hp != 0 && (species == SPECIES_EGG || status != 0)) - r6 |= 2 << i * 2; - - if (species == SPECIES_NONE) - continue; - if (species != SPECIES_EGG && hp == 0) - r6 |= 3 << i * 2; - } - eMultiTxBuffer.linkPartnerHeader.vsScreenHealthFlagsLo = r6; - eMultiTxBuffer.linkPartnerHeader.vsScreenHealthFlagsHi = r6 >> 8; -} - -static void SetPlayerBerryDataInBattleStruct(void) -{ - s32 i; - struct BattleEnigmaBerry * battleBerry = &eMultiTxBuffer.linkPartnerHeader.battleEnigmaBerry; - - for (i = 0; i < 7; i++) - battleBerry->name[i] = gSaveBlock1.enigmaBerry.berry.name[i]; - for (i = 0; i < 18; i++) - battleBerry->itemEffect[i] = gSaveBlock1.enigmaBerry.itemEffect[i]; - battleBerry->holdEffect = gSaveBlock1.enigmaBerry.holdEffect; - battleBerry->holdEffectParam = gSaveBlock1.enigmaBerry.holdEffectParam; -} - -void SetAllPlayersBerryData(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].id; - - 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 TryCorrectShedinjaLanguage(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 CB2_HandleStartBattle(void) -{ - u8 playerId; - u8 enemyId; - s32 id; - - RunTasks(); - AnimateSprites(); - BuildOamBuffer(); - - playerId = GetMultiplayerId(); - gBattleStruct->multiplayerId = playerId; - enemyId = playerId ^ 1; - - switch (gBattleCommunication[0]) - { - case 0: - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - if (gReceivedRemoteLinkPlayers != 0 && IsLinkTaskFinished()) - { - eMultiTxBuffer.linkPartnerHeader.versionSignatureLo = 1; - eMultiTxBuffer.linkPartnerHeader.versionSignatureHi = 1; - BufferPartyVsScreenHealth_AtStart(); - SetPlayerBerryDataInBattleStruct(); -#if DEBUG - if (gUnknown_02023A14_50 & 8) - { - for (id = 0; id < 2; id++) // Why < 2 here? - { - gLinkPlayers[id].id = id; - gLinkPlayers[id].linkType = 0x2211; - } - } -#endif - SendBlock(bitmask_all_link_players_but_self(), &eMultiTxBuffer.linkPartnerHeader, sizeof(eMultiTxBuffer.linkPartnerHeader)); - gBattleCommunication[0] = 1; - } - } - else - { - gBattleTypeFlags |= BATTLE_TYPE_WILD; - gBattleCommunication[0] = 8; - SetAllPlayersBerryData(); - } - 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; - } - } - SetAllPlayersBerryData(); - taskId = CreateTask(InitLinkBattleVsScreen, 0); - gTasks[taskId].data[1] = 0x10E; - gTasks[taskId].data[2] = 0x5A; - gTasks[taskId].data[5] = 0; - gTasks[taskId].data[3] = eMultiTxBuffer.linkPartnerHeader.vsScreenHealthFlagsLo | (eMultiTxBuffer.linkPartnerHeader.vsScreenHealthFlagsHi << 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); - TryCorrectShedinjaLanguage(&gEnemyParty[0]); - TryCorrectShedinjaLanguage(&gEnemyParty[1]); - TryCorrectShedinjaLanguage(&gEnemyParty[2]); - TryCorrectShedinjaLanguage(&gEnemyParty[3]); - TryCorrectShedinjaLanguage(&gEnemyParty[4]); - TryCorrectShedinjaLanguage(&gEnemyParty[5]); - gBattleCommunication[0]++; - } - break; - case 8: - sub_800B950(); - gBattleCommunication[0]++; - gBattleCommunication[1] = 0; - gBattleCommunication[2] = 0; - break; - case 9: - if (battle_load_something(&gBattleCommunication[1], &gBattleCommunication[2]) != 0) - { - gPreBattleCallback1 = gMain.callback1; - gMain.callback1 = BattleMainCB1; - SetMainCallback2(BattleMainCB2); - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - gTrainerBattleOpponent = LINK_BATTLE_OPPONENT; - gBattleTypeFlags |= BATTLE_TYPE_20; - } - } - break; - } -} - -void PrepareOwnMultiPartnerBuffer(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(eMultiTxBuffer.multiBattleMons, gMultiPartnerParty, 3 * sizeof(struct MultiBattlePokemonTx)); -} - -void sub_800F104(void) -{ - u8 playerId; - MainCallback *pSavedCallback; - u16 *pSavedBattleTypeFlags; - s32 i; - - playerId = GetMultiplayerId(); - gBattleStruct->multiplayerId = playerId; - // Seriously, Game Freak? - pSavedCallback = &gBattleStruct->unk160C4; - pSavedBattleTypeFlags = &gBattleStruct->unk160C2; - 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].id = i; - gLinkPlayers[i].linkType = 0x2211; - } - } -#endif - if (IsLinkTaskFinished()) - { - PrepareOwnMultiPartnerBuffer(); - SendBlock(bitmask_all_link_players_but_self(), eMultiTxBuffer.multiBattleMons, 3 * sizeof(struct MultiBattlePokemonTx)); - gBattleCommunication[0]++; - } - } - break; - case 1: - if ((GetBlockReceivedStatus() & 0xF) == 0xF) - { - //s32 i; - // Get your multi battle partner's party - ResetBlockReceivedFlags(); - for (i = 0; i < 4; i++) - { - if (i != playerId) - { - if ((!(gLinkPlayers[i].id & 1) && !(gLinkPlayers[playerId].id & 1)) - || ((gLinkPlayers[i].id & 1) && (gLinkPlayers[playerId].id & 1))) - memcpy(gMultiPartnerParty, gBlockRecvBuffer[i], 3 * sizeof(struct MultiBattlePokemonTx)); - } - } - 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; - SetCloseLinkCallback(); - } - break; - case 3: - if (gReceivedRemoteLinkPlayers == 0) - { - gBattleTypeFlags = *pSavedBattleTypeFlags; - gMain.savedCallback = *pSavedCallback; - SetMainCallback2(CB2_InitBattleInternal); - } - break; - } -} - -void CB2_HandleStartMultiBattle(void) -{ - u8 playerId; - s32 id; - - playerId = GetMultiplayerId(); - gBattleStruct->multiplayerId = 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].id = id; - gLinkPlayers[id].linkType = 0x2211; - } - } -#endif - if (IsLinkTaskFinished()) - { - *(&eMultiTxBuffer.linkPartnerHeader.versionSignatureLo) = 1; - *(&eMultiTxBuffer.linkPartnerHeader.versionSignatureHi) = 1; - BufferPartyVsScreenHealth_AtStart(); - SetPlayerBerryDataInBattleStruct(); - SendBlock(bitmask_all_link_players_but_self(), &eMultiTxBuffer.linkPartnerHeader, sizeof(eMultiTxBuffer.linkPartnerHeader)); - gBattleCommunication[0]++; - } - } - break; - case 1: - if ((GetBlockReceivedStatus() & 0xF) == 0xF) - { - u8 taskId; - - ResetBlockReceivedFlags(); - // LinkBattleComputeBattleTypeFlags - 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; - } - } - SetAllPlayersBerryData(); - memcpy(eMultiBattleSetupPartySendBuffer, gPlayerParty, sizeof(struct Pokemon) * 3); - taskId = CreateTask(InitLinkBattleVsScreen, 0); - gTasks[taskId].data[1] = 270; - gTasks[taskId].data[2] = 90; - 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].id) - { - 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(), eMultiBattleSetupPartySendBuffer, 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].id) - { - 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].id & 1) && !(gLinkPlayers[playerId].id & 1)) - || ((gLinkPlayers[id].id & 1) && (gLinkPlayers[playerId].id & 1))) - { - switch (gLinkPlayers[id].id) - { - 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].id) - { - 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(), eMultiBattleSetupPartySendBuffer + 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].id) - { - 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].id & 1) && !(gLinkPlayers[playerId].id & 1)) - || ((gLinkPlayers[id].id & 1) && (gLinkPlayers[playerId].id & 1))) - { - switch (gLinkPlayers[id].id) - { - 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].id) - { - 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; - } - } - } - } - - TryCorrectShedinjaLanguage(&gPlayerParty[0]); - TryCorrectShedinjaLanguage(&gPlayerParty[1]); - TryCorrectShedinjaLanguage(&gPlayerParty[2]); - TryCorrectShedinjaLanguage(&gPlayerParty[3]); - TryCorrectShedinjaLanguage(&gPlayerParty[4]); - TryCorrectShedinjaLanguage(&gPlayerParty[5]); - - TryCorrectShedinjaLanguage(&gEnemyParty[0]); - TryCorrectShedinjaLanguage(&gEnemyParty[1]); - TryCorrectShedinjaLanguage(&gEnemyParty[2]); - TryCorrectShedinjaLanguage(&gEnemyParty[3]); - TryCorrectShedinjaLanguage(&gEnemyParty[4]); - TryCorrectShedinjaLanguage(&gEnemyParty[5]); - - gBattleCommunication[0]++; - } - break; - case 6: - sub_800B950(); - gBattleCommunication[0]++; - gBattleCommunication[1] = 0; - gBattleCommunication[2] = 0; - break; - case 7: - if (battle_load_something(&gBattleCommunication[1], &gBattleCommunication[2]) != 0) - { - gPreBattleCallback1 = gMain.callback1; - gMain.callback1 = BattleMainCB1; - 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(&gWindowTemplate_Contest_MoveDescription); - 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(CB2_InitBattle); - 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->x = sprite->data[1] + ((sprite->data[2] & 0xFF00) >> 8); - else - sprite->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_MUGSHOT); -} - -void sub_800FE40(u8 taskId) -{ - struct Pokemon *sp4 = NULL; - struct Pokemon *sp8 = NULL; - u8 r2 = gBattleStruct->multiplayerId; - u32 r7; - s32 i; - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - switch (gLinkPlayers[r2].id) - { - 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 < 160; i++) - { - 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(&gWindowTemplate_Contest_MoveDescription, &gWindowTemplate_81E6C58); - Text_InitWindowWithTemplate(&gUnknown_030041D0, &gWindowTemplate_81E71D0); - Text_InitWindowWithTemplate(&gUnknown_03004250, &gWindowTemplate_81E71EC); - sub_800D6D4(); - LoadCompressedPalette(gBattleTextboxPalette, 0, 64); - ApplyPlayerChosenFrameToBattleMenu(); - ResetSpriteData(); - ResetTasks(); - DrawBattleEntryBackground(); - REG_WINOUT = 0x37; - FreeAllSpritePalettes(); - gReservedSpritePaletteCount = 4; - SetVBlankCallback(sub_800FCFC); - taskId = CreateTask(InitLinkBattleVsScreen, 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 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_ShowCurrentAnimAudioOptions(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); - -u8 gUnknown_Debug_03004360; -struct Window gUnknown_Debug_03004370; -u8 gUnknown_Debug_030043A0; -u8 gUnknown_Debug_030043A4; -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 gDebugBattleCharmap_Gfx_lz[]; -extern const u8 gDebugBattleCharmap_Tilemap_lz[]; -extern const u8 gDebugBattleCharmap_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(gDebugBattleCharmap_Gfx_lz, (void *)VRAM); - LZDecompressWram(gDebugBattleCharmap_Tilemap_lz, gSharedMem); - LZDecompressVram(gDebugBattleCharmap_Pal_lz, (void *)PLTT); - LZDecompressVram(gDebugBattleCharmap_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_ShowCurrentAnimAudioOptions(); - 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] = B_BUFF_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_ShowCurrentAnimAudioOptions(); - } - } - 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_ShowCurrentAnimAudioOptions(); - 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_ShowCurrentAnimAudioOptions(); - 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_ShowCurrentAnimAudioOptions(); - 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_ShowCurrentAnimAudioOptions(); - 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) - gBattleStruct->unk160A3 = gUnknown_Debug_2023A76[0][2] - 2; - else - gBattleStruct->unk160A3 = 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: -// TODO: check other revisions -#if (ENGLISH && REVISION == 0) - debug_sub_8010A7C(0, 8); -#else - debug_sub_8010A7C(0, 20); -#endif - 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); -// TODO: check other revisions -#if !(ENGLISH && REVISION == 0) - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - 422, - gUnknown_Debug_03004360 * 32 + 25, - 0); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - gBattleTextBuff1[0] = B_BUFF_EOS; -#endif - 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: -// TODO: check other revisions -#if (ENGLISH && REVISION == 0) - debug_sub_8010A7C(0, 11); -#else - debug_sub_8010A7C(0, 24); -#endif - 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); -// TODO: check other revisions -#if !(ENGLISH && REVISION == 0) - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - 422, - gUnknown_Debug_03004360 * 32 + 25, - 0); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - gBattleTextBuff1[0] = B_BUFF_EOS; -#endif - 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: -// TODO: check other revisions -#if (ENGLISH && REVISION == 0) - debug_sub_8010A7C(0, 2); -#else - debug_sub_8010A7C(0, 4); -#endif - 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] = B_BUFF_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) - { -// TODO: check other revisions -#if (ENGLISH && REVISION == 0) - debug_sub_8010A7C(0, 10); -#else - debug_sub_8010A7C(0, 24); -#endif - 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); -// TODO: check other revisions -#if !(ENGLISH && REVISION == 0) - Text_InitWindow( - &gUnknown_Debug_03004370, - gBattleTextBuff1, - 422, - gUnknown_Debug_03004360 * 32 + 25, - 0); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - gBattleTextBuff1[0] = B_BUFF_EOS; -#endif - 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) - { -// TODO: check other revisions -#if (ENGLISH && REVISION == 0) - debug_sub_8010A7C(0, 7); -#else - debug_sub_8010A7C(0, 18); -#endif - 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); -// TODO: check other revisions -#if (ENGLISH && REVISION == 0) - debug_sub_8010A7C(0, 7); -#else - debug_sub_8010A7C(0, 18); -#endif - 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); -} - -// TODO: check other revisions -#if (ENGLISH && REVISION == 0) -extern const u8 Str_821F64D[]; -extern const u8 Str_821F652[]; -extern const u8 Str_821F655[]; -extern const u8 Str_821F65A[]; -#endif - -void debug_ShowCurrentAnimAudioOptions(void) -{ -// TODO: check other revisions -#if (ENGLISH && REVISION == 0) - if (gSaveBlock2.optionsBattleSceneOff) - Text_InitWindow( - &gUnknown_Debug_03004370, - Str_821F652, - 418, - gUnknown_Debug_03004360 * 32 + 21, - 0); - else - Text_InitWindow( - &gUnknown_Debug_03004370, - Str_821F64D, - 418, - gUnknown_Debug_03004360 * 32 + 21, - 0); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); - - if (gSaveBlock2.optionsSound) - Text_InitWindow( - &gUnknown_Debug_03004370, - Str_821F65A, - 422, - gUnknown_Debug_03004360 * 32 + 24, - 0); - else - Text_InitWindow( - &gUnknown_Debug_03004370, - Str_821F655, - 422, - gUnknown_Debug_03004360 * 32 + 24, - 0); - Text_PrintWindow8002F44(&gUnknown_Debug_03004370); -#endif -} - -extern const u32 gUnknown_Debug_821F680[][0x23]; - -// Shows a cursor -void debug_sub_80125A0(void) -{ - gSharedMem[gUnknown_Debug_821F680[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5]] = 0x6D; -} - -// Hides a cursor -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(&gWindowTemplate_Contest_MoveDescription, &gWindowTemplate_81E6C58); - DecompressPicFromTable_2( - &gMonFrontPicTable[gCurrentMove], - gMonFrontPicCoords[gCurrentMove].coords, - gMonFrontPicCoords[gCurrentMove].y_offset, - (void *)EWRAM, - gMonSpriteGfx_Sprite_ptr[1], - gCurrentMove); - LoadCompressedPalette(gMonPaletteTable[gCurrentMove].data, 272, 32); - GetMonSpriteTemplate_803C56C(gCurrentMove, 1); - spriteId = CreateSprite(&gCreatingSpriteTemplate, 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(&gWindowTemplate_Contest_MoveDescription); - 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(&gWindowTemplate_Contest_MoveDescription, gBattleTextBuff1, 144, 2, 35); - Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); - ConvertIntToDecimalStringN(gBattleTextBuff1, gCurrentMove, 2, 3); - gBattleTextBuff1[3] = CHAR_SPACE; - gBattleTextBuff1[4] = B_BUFF_EOS; - StringAppend(gBattleTextBuff1, gSpeciesNames[gCurrentMove]); - Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, gBattleTextBuff1, 144, 2, 35); - Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); -} - -void debug_sub_8012938(u8 taskId) -{ - debug_sub_8010A7C(0, 7); - Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, gBattleTextBuff1, 162, 2, 37); - Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); - StringCopy(gBattleTextBuff1, Str_821F7B8); - ConvertIntToDecimalStringN(gBattleTextBuff1 + 4, gUnknown_Debug_2023B62[gCurrentMove - 1], 2, 3); - Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, gBattleTextBuff1, 162, 2, 37); - Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); - gSprites[gTasks[taskId].data[1]].y2 = -gUnknown_Debug_2023B62[gCurrentMove - 1]; -} - -void debug_sub_80129F8(u8 taskId) -{ - DecompressPicFromTable_2( - &gMonFrontPicTable[gCurrentMove], - gMonFrontPicCoords[gCurrentMove].coords, - gMonFrontPicCoords[gCurrentMove].y_offset, - (void *)EWRAM, - gMonSpriteGfx_Sprite_ptr[1], - gCurrentMove); - LoadCompressedPalette(gMonPaletteTable[gCurrentMove].data, 272, 32); - gSprites[gTasks[taskId].data[1]].y = gMonFrontPicCoords[gCurrentMove].y_offset + 40; - gSprites[gTasks[taskId].data[1]].y2 = -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(&gWindowTemplate_Contest_MoveDescription, Str_821F7DA, 656, 26, 29); - Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); - gTasks[taskId].data[3] = 0; - debug_sub_8012B2C(0); - } -} - -void debug_sub_8012C08(u8 taskId, u8 b) -{ - debug_sub_8010A7C(0, 9); - Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, gBattleTextBuff1, 144, 2, 35); - Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); - debug_sub_8010A7C(0, 7); - Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, gBattleTextBuff1, 162, 2, 37); - Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); - sub_802BBD4(24, 28, 29, 33, 0); - if (b != 0) - { - gTasks[taskId].data[0] = 4; - Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, gUnknown_Debug_821F7F3, 144, 2, 35); - } - else - { - gTasks[taskId].data[0] = 3; - Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, Str_821F7EA, 144, 2, 35); - } - Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); - Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, BattleText_YesNo, 656, 26, 29); - Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); - 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(&gWindowTemplate_Contest_MoveDescription, Str_821F7BD, 400, 19, 35); - Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); - 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 ((gIntroSlideFlags & 1) == 0) - { - sprite->x2 += 2; - if (sprite->x2 == 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(gHealthboxSpriteIds[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 (gBattleSpriteInfo[r6].transformedSpecies != 0) - species = gBattleSpriteInfo[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->y2 += 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 *)gMonSpriteGfx_Sprite_ptr[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 ((gIntroSlideFlags & 1) == 0) - { - sprite->x2 -= 2; - if (sprite->x2 == 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 ((gIntroSlideFlags & 1) == 0) - { - sprite->x2 += sprite->data[1]; - sprite->y2 += 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 = gHealthboxSpriteIds[bank]; - ewram17810[bank].unk2 = spriteId; - ewram17810[bank].unk0_1 = 1; - gSprites[spriteId].data[0] = 0x80; - } - else - { - objectID = gBattlerSpriteIds[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].x2 = 0; - gSprites[objectID].y2 = 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].x2 = 0; - gSprites[r4].y2 = 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].y2 = 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) -{ - BattleStartClearSetData(); - gBattleCommunication[1] = 0; - gBattleMainFunc = bc_8012FAC; -} - -#if DEBUG -void debug_sub_80138CC(void) -{ - if (GetBattlerSide(gActiveBattler) == 0) - { - switch (gBattleStruct->unk160FD) - { - case 0: - if (gBattlerControllerFuncs[gActiveBattler] == sub_802C098) - gBattleStruct->unk160FD++; - break; - case 1: - gMain.heldKeys = A_BUTTON; - gMain.newKeys = A_BUTTON; - gBattleStruct->unk160FD++; - gBattleStruct->unk160FE = 0x80; - break; - case 2: - gBattleStruct->unk160FE--; - if (gBattleStruct->unk160FE == 0) - { - gMain.heldKeys = A_BUTTON; - gMain.newKeys = A_BUTTON; - gBattleStruct->unk160FD++; - gBattleStruct->unk160FE = 0x80; - } - break; - case 3: - gBattleStruct->unk160FE--; - if (gBattleStruct->unk160FE == 0) - { - gMain.heldKeys = A_BUTTON; - gMain.newKeys = A_BUTTON; - gBattleStruct->unk160FD++; - } - break; - case 4: - gBattleStruct->unk160FD = 0; - break; - } - } -} -#endif - -void BattleMainCB1(void) -{ -#if DEBUG - if (gUnknown_02023A14_50 & 0x80) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - debug_sub_80138CC(); - gBattleMainFunc(); - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - gBattlerControllerFuncs[gActiveBattler](); - } - else -#endif - { - gBattleMainFunc(); - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - gBattlerControllerFuncs[gActiveBattler](); - } -} - -void BattleStartClearSetData(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; - sUnusedBattlersArray[i] = 0; - gLastMoves[i] = 0; - gLastLandedMoves[i] = 0; - gLastHitByType[i] = 0; - gLastResultingMoves[i] = 0; - gLastHitBy[i] = 0xFF; - gLockedMoves[i] = 0; - gLastPrintedMoves[i] = 0; - eBattleFlagsArr.arr[i] = 0; - } - - for (i = 0; i < 2; i++) - { - gSideStatuses[i] = 0; - MEMSET_ALT(&gSideTimers[i], 0, sizeof(struct SideTimer), j, r4); - } - - gBattlerAttacker = 0; - gBattlerTarget = 0; - gBattleWeather = 0; - - MEMSET_ALT(&gWishFutureKnock, 0, sizeof(struct WishFutureKnock), i, r4); - - gHitMarker = 0; - if ((gBattleTypeFlags & BATTLE_TYPE_LINK) == 0 && gSaveBlock2.optionsBattleSceneOff == TRUE) - gHitMarker = HITMARKER_NO_ANIMATIONS; - - gBattleStruct->battleStyle = gSaveBlock2.optionsBattleStyle; - - gMultiHitCounter = 0; - gBattleOutcome = 0; - gBattleControllerExecFlags = 0; - gPaydayMoney = 0; - (*(u8 *)&B_BATTLESCRIPTS_STACK->size) = 0; - (*(u8 *)&B_FUNCTION_STACK->size) = 0; - - for (i = 0; i < 8; i++) - gBattleCommunication[i] = 0; - - gPauseCounterBattle = 0; - gBattleMoveDamage = 0; - gIntroSlideFlags = 0; - gBattleStruct->animTurn = 0; - gBattleStruct->animTargetsHit = 0; - gLeveledUpInBattle = 0; - gAbsentBattlerFlags = 0; - gBattleStruct->runTries = 0; - gBattleStruct->safariGoNearCounter = 0; - gBattleStruct->safariPkblThrowCounter = 0; - gBattleStruct->safariCatchFactor = gBaseStats[GetMonData(&gEnemyParty[0], MON_DATA_SPECIES)].catchRate * 100 / 1275; - gBattleStruct->safariFleeRate = 3; - gBattleStruct->wildVictorySong = 0; - gBattleStruct->moneyMultiplier = 1; - - for (i = 0; i < 8; i++) - { - gSharedMem[BSTRUCT_OFF(lastTakenMove) + i] = 0; - gSharedMem[BSTRUCT_OFF(usedHeldItems) + i] = 0; - gSharedMem[BSTRUCT_OFF(choicedMove) + i] = 0; - gSharedMem[BSTRUCT_OFF(changedItems) + i] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 0 * 8 + i] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 1 * 8 + i] = 0; - } - - gBattleStruct->AI_monToSwitchIntoId[0] = PARTY_SIZE; - gBattleStruct->AI_monToSwitchIntoId[1] = PARTY_SIZE; - - gBattleStruct->givenExpMons = 0; - - // Reset gBattleResults - for (i = 0; i < 11; i++) - gBattleResults.usedBalls[i] = 0; - gBattleResults.battleTurnCounter = 0; - gBattleResults.playerFaintCounter = 0; - gBattleResults.opponentFaintCounter = 0; - gBattleResults.totalMonSwitchCounter = 0; - gBattleResults.playerHealInBattleCount = 0; - gBattleResults.reviveCount = 0; - gBattleResults.playerMonWasDamaged = 0; - gBattleResults.usedMasterBall = 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[BSTRUCT_OFF(dbgAICycleMoveTracker) + 0] = 0; - gSharedMem[BSTRUCT_OFF(dbgAICycleMoveTracker) + 1] = 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].battlerWithSureHit == gActiveBattler) - { - gStatuses3[i] &= ~STATUS3_ALWAYS_HITS; - gDisableStructs[i].battlerWithSureHit = 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_BATTLER | 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].battlerWithSureHit == 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) && gSharedMem[BSTRUCT_OFF(wrappedBy) + 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].battlerWithSureHit = sp0.battlerWithSureHit; - gDisableStructs[gActiveBattler].perishSongTimer1 = sp0.perishSongTimer1; - gDisableStructs[gActiveBattler].perishSongTimer2 = sp0.perishSongTimer2; - } - - gDisableStructs[gActiveBattler].isFirstTurn= 2; - gLastMoves[gActiveBattler] = 0; - gLastLandedMoves[gActiveBattler] = 0; - gLastHitByType[gActiveBattler] = 0; - gLastResultingMoves[gActiveBattler] = 0; - gLastPrintedMoves[gActiveBattler] = 0; - gLastHitBy[gActiveBattler] = 0xFF; - - gSharedMem[BSTRUCT_OFF(lastTakenMove) + 2 * gActiveBattler + 0] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMove) + 2 * gActiveBattler + 1] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 0] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 1] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 2] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 3] = 0; - gSharedMem[BSTRUCT_OFF(choicedMove) + 2 * gActiveBattler + 0] = 0; - gSharedMem[BSTRUCT_OFF(choicedMove) + 2 * gActiveBattler + 1] = 0; - - eBattleFlagsArr.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) && gSharedMem[BSTRUCT_OFF(wrappedBy) + 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].noValidMoves = 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].targetNotAffected = 0; - gProtectStructs[gActiveBattler].chargingTurn = 0; - gProtectStructs[gActiveBattler].fleeFlag = 0; - gProtectStructs[gActiveBattler].usedImprisonedMove = 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; - gLastMoves[gActiveBattler] = 0; - gLastLandedMoves[gActiveBattler] = 0; - gLastHitByType[gActiveBattler] = 0; - gLastResultingMoves[gActiveBattler] = 0; - gLastPrintedMoves[gActiveBattler] = 0; - gLastHitBy[gActiveBattler] = 0xFF; - - gSharedMem[BSTRUCT_OFF(choicedMove) + 2 * gActiveBattler + 0] = 0; - gSharedMem[BSTRUCT_OFF(choicedMove) + 2 * gActiveBattler + 1] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMove) + 2 * gActiveBattler + 0] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMove) + 2 * gActiveBattler + 1] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 0] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 1] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 2] = 0; - gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 3] = 0; - - eBattleFlagsArr.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]; - BtlController_EmitGetMonData(0, 0, 0); - MarkBattlerForControllerExec(gActiveBattler); - gBattleCommunication[0]++; - break; - case 1: - if (gBattleControllerExecFlags == 0) - { - gBattleCommunication[1]++; - if (gBattleCommunication[1] == gBattlersCount) - gBattleMainFunc = BattlePrepIntroSlide; - else - gBattleCommunication[0] = 0; - } - break; - } -} - -static void BattlePrepIntroSlide(void) -{ - if (gBattleControllerExecFlags == 0) - { - gActiveBattler = GetBattlerAtPosition(0); - BtlController_EmitIntroSlide(0, gBattleTerrain); - MarkBattlerForControllerExec(gActiveBattler); - gBattleMainFunc = sub_8011384; - gBattleCommunication[0] = 0; - gBattleCommunication[1] = 0; - } -} - -void sub_8011384(void) -{ - u8 *ptr; - s32 i; - - if (gBattleControllerExecFlags == 0) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if ((gBattleTypeFlags & BATTLE_TYPE_SAFARI) - && GetBattlerSide(gActiveBattler) == 0) - { - MEMSET_ALT(&gBattleMons[gActiveBattler], 0, 0x58, i, ptr); - } - else - { - u16 *hpOnSwitchout; - - 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); - - hpOnSwitchout = &gBattleStruct->HP_OnSwitchout[GetBattlerSide(gActiveBattler)]; - *hpOnSwitchout = gBattleMons[gActiveBattler].hp; - for (i = 0; i < 8; i++) - gBattleMons[gActiveBattler].statStages[i] = 6; - gBattleMons[gActiveBattler].status2 = 0; - } - - if (GetBattlerPosition(gActiveBattler) == 0) - { - BtlController_EmitDrawTrainerPic(0); - MarkBattlerForControllerExec(gActiveBattler); - } - - if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) - { - if (GetBattlerPosition(gActiveBattler) == 1) - { - BtlController_EmitDrawTrainerPic(0); - MarkBattlerForControllerExec(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); - BtlController_EmitLoadMonSprite(0); - MarkBattlerForControllerExec(gActiveBattler); - } - } - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (GetBattlerPosition(gActiveBattler) == 2 - || GetBattlerPosition(gActiveBattler) == 3) - { - BtlController_EmitDrawTrainerPic(0); - MarkBattlerForControllerExec(gActiveBattler); - } - } - } - gBattleMainFunc = bc_801333C; - } -} - -void bc_801333C(void) -{ - s32 i; - - if (gBattleControllerExecFlags == 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); - BtlController_EmitDrawPartyStatusSummary(0, hpStatus, 0x80); - MarkBattlerForControllerExec(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); - BtlController_EmitDrawPartyStatusSummary(0, hpStatus, 0x80); - MarkBattlerForControllerExec(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 (gBattleControllerExecFlags == 0) - { - gActiveBattler = GetBattlerAtPosition(1); - PrepareStringBattle(0, gActiveBattler); - gBattleMainFunc = sub_8011800; - } -} - -void bc_8013568(void) -{ - if (gBattleControllerExecFlags == 0) - { - gBattleMainFunc = sub_8011970; - PrepareStringBattle(0, 0); - } -} - -void sub_8011800(void) -{ - if (gBattleControllerExecFlags == 0) - { - PrepareStringBattle(1, GetBattlerAtPosition(1)); - gBattleMainFunc = sub_8011834; - } -} - -void sub_8011834(void) -{ - if (gBattleControllerExecFlags == 0) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (GetBattlerPosition(gActiveBattler) == 1) - { - BtlController_EmitIntroTrainerBallThrow(0); - MarkBattlerForControllerExec(gActiveBattler); - } - if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) - && GetBattlerPosition(gActiveBattler) == 3) - { - BtlController_EmitIntroTrainerBallThrow(0); - MarkBattlerForControllerExec(gActiveBattler); - } - } - gBattleMainFunc = bc_801362C; - } -} - -void bc_801362C(void) -{ - if (gBattleControllerExecFlags == 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 (gBattleControllerExecFlags == 0) - gBattleMainFunc = sub_8011970; -} - -void sub_8011970(void) -{ - if (gBattleControllerExecFlags == 0) - { - if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) - PrepareStringBattle(1, GetBattlerAtPosition(0)); - gBattleMainFunc = sub_80119B4; - } -} - -void sub_80119B4(void) -{ - if (gBattleControllerExecFlags == 0) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (GetBattlerPosition(gActiveBattler) == 0) - { - BtlController_EmitIntroTrainerBallThrow(0); - MarkBattlerForControllerExec(gActiveBattler); - } - if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) - && GetBattlerPosition(gActiveBattler) == 2) - { - BtlController_EmitIntroTrainerBallThrow(0); - MarkBattlerForControllerExec(gActiveBattler); - } - } - gBattleStruct->switchInAbilitiesCounter = 0; - gBattleStruct->unk160F9 = 0; - gBattleStruct->unk160E6 = 0; - gBattleMainFunc = BattleBeginFirstTurn; - } -} - -void unref_sub_8011A68(void) -{ - if (gBattleControllerExecFlags == 0) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (GetBattlerSide(gActiveBattler) == 0) - { - BtlController_EmitSwitchInAnim(0, gBattlerPartyIndexes[gActiveBattler], 0); - MarkBattlerForControllerExec(gActiveBattler); - } - } - gBattleStruct->switchInAbilitiesCounter = 0; - gBattleStruct->unk160F9 = 0; - gBattleStruct->unk160E6 = 0; - gBattleMainFunc = BattleBeginFirstTurn; - } -} - -void BattleBeginFirstTurn(void) -{ - s32 i; - s32 j; - u8 r9 = 0; - - if (gBattleControllerExecFlags == 0) - { - if (gBattleStruct->switchInAbilitiesCounter == 0) - { - for (i = 0; i < gBattlersCount; i++) - gBattlerByTurnOrder[i] = i; - for (i = 0; i < gBattlersCount - 1; i++) - { - for (j = i + 1; j < gBattlersCount; j++) - { - if (GetWhoStrikesFirst(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], 1) != 0) - SwapTurnOrder(i, j); - } - } - } - if (gBattleStruct->unk160E6 == 0 && AbilityBattleEffects(0, 0, 0, 0xFF, 0) != 0) - { - gBattleStruct->unk160E6 = 1; - return; - } - while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount) - { - if (AbilityBattleEffects(0, gBattlerByTurnOrder[gBattleStruct->switchInAbilitiesCounter], 0, 0, 0) != 0) - r9++; - gBattleStruct->switchInAbilitiesCounter++; - if (r9 != 0) - return; - } - if (AbilityBattleEffects(9, 0, 0, 0, 0) != 0) - return; - if (AbilityBattleEffects(11, 0, 0, 0, 0) != 0) - return; - while (gBattleStruct->unk160F9 < gBattlersCount) - { - if (ItemBattleEffects(0, gBattlerByTurnOrder[gBattleStruct->unk160F9], 0) != 0) - r9++; - gBattleStruct->unk160F9++; - 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++) - { - gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + i] = PARTY_SIZE; - gActionForBanks[i] = 0xFF; - gChosenMovesByBanks[i] = 0; - } - TurnValuesCleanUp(0); - SpecialStatusesClear(); - gBattleStruct->unk160A6 = gAbsentBattlerFlags; - gBattleMainFunc = sub_8012324; - ResetSentPokesToOpponentValue(); - for (i = 0; i < 8; i++) - gBattleCommunication[i] = 0; - for (i = 0; i < gBattlersCount; i++) - gBattleMons[i].status2 &= ~8; - gBattleStruct->turnEffectsTracker = 0; - gBattleStruct->turnEffectsBattlerId = 0; - gBattleStruct->wishPerishSongState = 0; - gBattleStruct->wishPerishSongBattlerId = 0; - gBattleStruct->cmd49StateTracker = 0; - gBattleStruct->faintedActionsState = 0; - gBattleStruct->turnCountersTracker = 0; - gMoveResultFlags = 0; - gRandomTurnNumber = Random(); - } -} - -void bc_8013B1C(void) -{ - s32 i; - - if (gBattleControllerExecFlags == 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); - } - gBattleStruct->turnEffectsTracker = 0; - gBattleStruct->turnEffectsBattlerId = 0; - gBattleStruct->wishPerishSongState = 0; - gBattleStruct->wishPerishSongBattlerId = 0; - gBattleStruct->turnCountersTracker = 0; - gMoveResultFlags = 0; - } -} - -void BattleTurnPassed(void) -{ - s32 i; - - TurnValuesCleanUp(1); - if (gBattleOutcome == 0) - { - if (DoFieldEndTurnEffects() != 0) - return; - if (TurnBasedEffects() != 0) - return; - } - if (HandleFaintedMonActions() != 0) - return; - gBattleStruct->faintedActionsState = 0; - if (HandleWishPerishSongOnTurnEnd() != 0) - return; - TurnValuesCleanUp(0); - gHitMarker &= ~HITMARKER_NO_ATTACKSTRING; - gHitMarker &= ~0x80000; - gHitMarker &= ~0x400000; - gHitMarker &= ~0x100000; - gBattleStruct->animTurn = 0; - gBattleStruct->animTargetsHit = 0; - gBattleStruct->cmd49StateTracker = 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++) - gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + i] = 6; - gBattleStruct->unk160A6 = 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); - gPotentialItemEffectBattler = 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) - { - gBattleStruct->scriptingActive = 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) - { - gBattleStruct->scriptingActive = 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)) - { - gBattleStruct->scriptingActive = 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++) - gBattlePartyCurrentOrder[i] = gSharedMem[BSTRUCT_OFF(unk1606C) + i + a * 3]; - r4 = pokemon_order_func(gBattlerPartyIndexes[a]); - r1 = pokemon_order_func(gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + a]); - sub_8094C98(r4, r1); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - for (i = 0; i < 3; i++) - { - gSharedMem[BSTRUCT_OFF(unk1606C) + i + a * 3] = gBattlePartyCurrentOrder[i]; - gSharedMem[BSTRUCT_OFF(unk1606C) + i + (a ^ BIT_FLANK) * 3] = - gBattlePartyCurrentOrder[i]; - } - } - else - { - for (i = 0; i < 3; i++) - { - gSharedMem[BSTRUCT_OFF(unk1606C) + i + a * 3] = gBattlePartyCurrentOrder[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 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: - gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + gActiveBattler] = 6; - if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) - && (position & BIT_FLANK) != B_FLANK_LEFT - && !(gBattleStruct->unk160A6 & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(position))]) - && gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(position))] != STATE_WAIT_ACTION_CONFIRMED) - break; - //_080123F8 - if (gBattleStruct->unk160A6 & 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 - { - BtlController_EmitChooseAction(0, gActionForBanks[0], gBattleBufferB[0][1] | (gBattleBufferB[0][2] << 8)); - MarkBattlerForControllerExec(gActiveBattler); - gBattleCommunication[gActiveBattler]++; - } - break; - case STATE_WAIT_ACTION_CHOSEN: - if (!(gBattleControllerExecFlags & ((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; - gSharedMem[BSTRUCT_OFF(selectionScriptFinished) + gActiveBattler] = FALSE; - gSharedMem[BSTRUCT_OFF(stateIdAfterSelScript) + gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY; - gSharedMem[BSTRUCT_OFF(moveTarget) + 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 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); - } - - BtlController_EmitChooseMove(0, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0, FALSE, (u8 *)&moveInfo); - MarkBattlerForControllerExec(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; - gSharedMem[BSTRUCT_OFF(selectionScriptFinished) + gActiveBattler] = FALSE; - gSharedMem[BSTRUCT_OFF(stateIdAfterSelScript) + gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; - return; - } - else - { - BtlController_EmitChooseItem(0, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); - MarkBattlerForControllerExec(gActiveBattler); - } - break; - case B_ACTION_SWITCH: - gSharedMem[BSTRUCT_OFF(unk16064) + gActiveBattler] = gBattlerPartyIndexes[gActiveBattler]; - if (gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION) - || gStatuses3[gActiveBattler] & STATUS3_ROOTED) - { - BtlController_EmitChoosePokemon(0, 2, 6, ABILITY_NONE, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); - } - 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))) - { - BtlController_EmitChoosePokemon(0, ((i - 1) << 4) | PARTY_ABILITY_PREVENTS, 6, gLastUsedAbility, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); - } - else - { - if (gActiveBattler == 2 && gActionForBanks[0] == B_ACTION_SWITCH) - BtlController_EmitChoosePokemon(0, PARTY_CHOOSE_MON, gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + 0], ABILITY_NONE, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); - else if (gActiveBattler == 3 && gActionForBanks[1] == B_ACTION_SWITCH) - BtlController_EmitChoosePokemon(0, PARTY_CHOOSE_MON, gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + 1], ABILITY_NONE, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); - else - BtlController_EmitChoosePokemon(0, PARTY_CHOOSE_MON, 6, ABILITY_NONE, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); - } - MarkBattlerForControllerExec(gActiveBattler); - break; - case B_ACTION_SAFARI_BALL: - if (PlayerPartyAndPokemonStorageFull()) - { - gSelectionBattleScripts[gActiveBattler] = BattleScript_PrintFullBox; - gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT; - gSharedMem[BSTRUCT_OFF(selectionScriptFinished) + gActiveBattler] = FALSE; - gSharedMem[BSTRUCT_OFF(stateIdAfterSelScript) + gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; - return; - } - break; - case B_ACTION_SAFARI_POKEBLOCK: - BtlController_EmitChooseItem(0, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); - MarkBattlerForControllerExec(gActiveBattler); - break; - case B_ACTION_CANCEL_PARTNER: - gBattleCommunication[gActiveBattler] = STATE_WAIT_SET_BEFORE_ACTION; - gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] = STATE_BEFORE_ACTION_CHOSEN; - BtlController_EmitEndBounceEffect(0); - MarkBattlerForControllerExec(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; - gSharedMem[BSTRUCT_OFF(selectionScriptFinished) + gActiveBattler] = FALSE; - gSharedMem[BSTRUCT_OFF(stateIdAfterSelScript) + gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; - return; - } - else - { - gBattleCommunication[gActiveBattler]++; - } - } - break; - case STATE_WAIT_ACTION_CASE_CHOSEN: - if (!(gBattleControllerExecFlags & ((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; - gSharedMem[BSTRUCT_OFF(selectionScriptFinished) + gActiveBattler] = FALSE; - gBattleBufferB[gActiveBattler][1] = 0; - gSharedMem[BSTRUCT_OFF(stateIdAfterSelScript) + gActiveBattler] = STATE_WAIT_ACTION_CHOSEN; - return; - } - else - { - gSharedMem[BSTRUCT_OFF(ChosenMoveID) + gActiveBattler] = gBattleBufferB[gActiveBattler][2]; - gChosenMovesByBanks[gActiveBattler] = gBattleMons[gActiveBattler].moves[gSharedMem[BSTRUCT_OFF(ChosenMoveID) + gActiveBattler]]; - gSharedMem[BSTRUCT_OFF(moveTarget) + 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 - { - gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + gActiveBattler] = gBattleBufferB[gActiveBattler][1]; - - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0] &= 0xF; - gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0] |= (gBattleBufferB[gActiveBattler][2] & 0xF0); - gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 1] = gBattleBufferB[gActiveBattler][3]; - - gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * (gActiveBattler ^ BIT_FLANK) + 0] &= (0xF0); - gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * (gActiveBattler ^ BIT_FLANK) + 0] |= (gBattleBufferB[gActiveBattler][2] & 0xF0) >> 4; - gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * (gActiveBattler ^ BIT_FLANK) + 2] = 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 (!(gBattleControllerExecFlags & ((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 - || (gBattleStruct->unk160A6 & gBitTable[GetBattlerAtPosition(position ^ BIT_FLANK)])) - { - BtlController_EmitLinkStandbyMsg(0, 0); - } - else - { - BtlController_EmitLinkStandbyMsg(0, 1); - } - MarkBattlerForControllerExec(gActiveBattler); - gBattleCommunication[gActiveBattler]++; - } - break; - case STATE_WAIT_ACTION_CONFIRMED: - if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) - { - gBattleCommunication[ACTIONS_CONFIRMED_COUNT]++; - } - break; - case STATE_SELECTION_SCRIPT: - if (gSharedMem[BSTRUCT_OFF(selectionScriptFinished) + gActiveBattler]) - { - gBattleCommunication[gActiveBattler] = gSharedMem[BSTRUCT_OFF(stateIdAfterSelScript) + gActiveBattler]; - } - else - { - gBattlerAttacker = gActiveBattler; - gBattlescriptCurrInstr = gSelectionBattleScripts[gActiveBattler]; - if (!(gBattleControllerExecFlags & ((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 (!(gBattleControllerExecFlags & ((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 = gBattlerByTurnOrder[a]; - gBattlerByTurnOrder[a] = gBattlerByTurnOrder[b]; - gBattlerByTurnOrder[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 & STATUS1_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 & STATUS1_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].noValidMoves) - bank1Move = MOVE_STRUGGLE; - else - bank1Move = gBattleMons[bank1].moves[gSharedMem[BSTRUCT_OFF(ChosenMoveID) + bank1]]; - } - else - bank1Move = MOVE_NONE; - - if (gActionForBanks[bank2] == 0) - { - if (gProtectStructs[bank2].noValidMoves) - bank2Move = MOVE_STRUGGLE; - else - bank2Move = gBattleMons[bank2].moves[gSharedMem[BSTRUCT_OFF(ChosenMoveID) + 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]; - gBattlerByTurnOrder[var] = gActiveBattler; - var++; - } - } - else - { - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (gActionForBanks[gActiveBattler] == B_ACTION_RUN) - { - var = 5; - break; - } - } - } - else - { - if (gActionForBanks[0] == B_ACTION_RUN) - { - gActiveBattler = 0; - var = 5; - } - } - - if (var == 5) - { - gActionsByTurnOrder[0] = gActionForBanks[gActiveBattler]; - gBattlerByTurnOrder[0] = gActiveBattler; - var = 1; - for (i = 0; i < gBattlersCount; i++) - { - if (i != gActiveBattler) - { - gActionsByTurnOrder[var] = gActionForBanks[i]; - gBattlerByTurnOrder[var] = i; - var++; - } - } - gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; - gBattleStruct->focusPunchBattler = 0; - return; - } - else - { - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (gActionForBanks[gActiveBattler] == B_ACTION_USE_ITEM || gActionForBanks[gActiveBattler] == B_ACTION_SWITCH) - { - gActionsByTurnOrder[var] = gActionForBanks[gActiveBattler]; - gBattlerByTurnOrder[var] = gActiveBattler; - var++; - } - } - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (gActionForBanks[gActiveBattler] != B_ACTION_USE_ITEM && gActionForBanks[gActiveBattler] != B_ACTION_SWITCH) - { - gActionsByTurnOrder[var] = gActionForBanks[gActiveBattler]; - gBattlerByTurnOrder[var] = gActiveBattler; - var++; - } - } - for (i = 0; i < gBattlersCount - 1; i++) - { - for (j = i + 1; j < gBattlersCount; j++) - { - u8 bank1 = gBattlerByTurnOrder[i]; - u8 bank2 = gBattlerByTurnOrder[j]; - if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM - && gActionsByTurnOrder[j] != B_ACTION_USE_ITEM - && gActionsByTurnOrder[i] != B_ACTION_SWITCH - && gActionsByTurnOrder[j] != B_ACTION_SWITCH) - { - if (GetWhoStrikesFirst(bank1, bank2, FALSE)) - SwapTurnOrder(i, j); - } - } - } - } - } - - gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; - gBattleStruct->focusPunchBattler = 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 (gBattleStruct->focusPunchBattler < gBattlersCount) - { - gActiveBattler = gBattlerAttacker = gBattleStruct->focusPunchBattler; - gBattleStruct->focusPunchBattler++; - if (gChosenMovesByBanks[gActiveBattler] == MOVE_FOCUS_PUNCH - && !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP) - && !(gDisableStructs[gBattlerAttacker].truantCounter) - && !(gProtectStructs[gActiveBattler].noValidMoves)) - { - 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; - gBattleStruct->multihitMoveEffect = 0; - B_BATTLESCRIPTS_STACK->size = 0; -} - -static void RunTurnActionsFunctions(void) -{ - if (gBattleOutcome != 0) - gCurrentActionFuncId = 12; - - gBattleStruct->savedTurnActionNumber = gCurrentTurnActionNumber; - gUnknown_081FA640[gCurrentActionFuncId](); - - if (gCurrentTurnActionNumber >= gBattlersCount) // everyone did their actions, turn finished - { - gHitMarker &= ~(HITMARKER_x100000); - gBattleMainFunc = gUnknown_081FA678[gBattleOutcome & 0x7F]; - } - else - { - if (gBattleStruct->savedTurnActionNumber != 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; - gBattlerAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - gBattlescriptCurrInstr = BattleScript_LinkBattleWonOrLost; - gBattleOutcome &= ~(B_OUTCOME_LINK_BATTLE_RAN); - } - 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_VICTORY_LEAGUE); - 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_VICTORY_AQUA_MAGMA); - break; - case TRAINER_CLASS_LEADER: - PlayBGM(MUS_VICTORY_GYM_LEADER); - break; - default: - PlayBGM(MUS_VICTORY_TRAINER); - break; - } - } - else - { - gBattlescriptCurrInstr = BattleScript_PayDayMoneyAndPickUpItems; - } - - gBattleMainFunc = HandleEndTurn_FinishBattle; -} - -void HandleEndTurn_BattleLost(void) -{ - gCurrentActionFuncId = 0; - - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - gBattleTextBuff1[0] = gBattleOutcome; - gBattlerAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - gBattlescriptCurrInstr = BattleScript_LinkBattleWonOrLost; - gBattleOutcome &= ~(B_OUTCOME_LINK_BATTLE_RAN); - } - else - { - gBattlescriptCurrInstr = BattleScript_LocalBattleLost; - } - - gBattleMainFunc = HandleEndTurn_FinishBattle; -} - -void HandleEndTurn_RanFromBattle(void) -{ - gCurrentActionFuncId = 0; - - switch (gProtectStructs[gBattlerAttacker].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, gBattlerAttacker, gBattlerPartyIndexes[gBattlerAttacker]); - 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 (gBattleControllerExecFlags == 0) - gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); - } -} - -static void FreeResetData_ReturnToOvOrDoEvolutions(void) -{ - if (!gPaletteFade.active) - { - ResetSpriteData(); - if (gLeveledUpInBattle == 0 || gBattleOutcome != B_OUTCOME_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 == B_OUTCOME_WON || gBattleOutcome == B_OUTCOME_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 (gBattleControllerExecFlags == 0) - gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); - } -} - -void RunBattleScriptCommands(void) -{ - if (gBattleControllerExecFlags == 0) - gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); -} - -void HandleAction_UseMove(void) -{ - u8 side; - u8 var = 4; - - gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; - - if (gBattleStruct->unk160A6 & gBitTable[gBattlerAttacker]) - { - gCurrentActionFuncId = B_ACTION_FINISHED; - return; - } - - gCritMultiplier = 1; - gBattleStruct->dmgMultiplier = 1; - gBattleStruct->atkCancellerTracker = 0; - gMoveResultFlags = 0; - gMultiHitCounter = 0; - gBattleCommunication[6] = 0; - gCurrMovePos = gUnknown_02024BE5 = gSharedMem[BSTRUCT_OFF(ChosenMoveID) + gBattlerAttacker]; - - // choose move - if (gProtectStructs[gBattlerAttacker].noValidMoves) - { - gProtectStructs[gBattlerAttacker].noValidMoves = 0; - gCurrentMove = gChosenMove = MOVE_STRUGGLE; - gHitMarker |= HITMARKER_NO_PPDEDUCT; - gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker] = GetMoveTarget(MOVE_STRUGGLE, 0); - } - else if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS || gBattleMons[gBattlerAttacker].status2 & STATUS2_RECHARGE) - { - gCurrentMove = gChosenMove = gLockedMoves[gBattlerAttacker]; - } - // encore forces you to use the same move - else if (gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE - && gDisableStructs[gBattlerAttacker].encoredMove == gBattleMons[gBattlerAttacker].moves[gDisableStructs[gBattlerAttacker].encoredMovePos]) - { - gCurrentMove = gChosenMove = gDisableStructs[gBattlerAttacker].encoredMove; - gCurrMovePos = gUnknown_02024BE5 = gDisableStructs[gBattlerAttacker].encoredMovePos; - gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker] = GetMoveTarget(gCurrentMove, 0); - } - // check if the encored move wasn't overwritten - else if (gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE - && gDisableStructs[gBattlerAttacker].encoredMove != gBattleMons[gBattlerAttacker].moves[gDisableStructs[gBattlerAttacker].encoredMovePos]) - { - gCurrMovePos = gUnknown_02024BE5 = gDisableStructs[gBattlerAttacker].encoredMovePos; - gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; - gDisableStructs[gBattlerAttacker].encoredMove = MOVE_NONE; - gDisableStructs[gBattlerAttacker].encoredMovePos = 0; - gDisableStructs[gBattlerAttacker].encoreTimer1 = 0; - gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker] = GetMoveTarget(gCurrentMove, 0); - } - else if (gBattleMons[gBattlerAttacker].moves[gCurrMovePos] != gChosenMovesByBanks[gBattlerAttacker]) - { - gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; - gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker] = GetMoveTarget(gCurrentMove, 0); - } - else - { - gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; - } - - if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) - gBattleResults.lastUsedMove = gCurrentMove; - else - gBattleResults.opponentMove = gCurrentMove; - - // choose target - side = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE; - if (gSideTimers[side].followmeTimer != 0 - && gBattleMoves[gCurrentMove].target == MOVE_TARGET_SELECTED - && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gSideTimers[side].followmeTarget) - && gBattleMons[gSideTimers[side].followmeTarget].hp != 0) - { - gBattlerTarget = gSideTimers[side].followmeTarget; - } - else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - && gSideTimers[side].followmeTimer == 0 - && (gBattleMoves[gCurrentMove].power != 0 - || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER) - && gBattleMons[gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker]].ability != ABILITY_LIGHTNING_ROD - && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) - { - side = GetBattlerSide(gBattlerAttacker); - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (side != GetBattlerSide(gActiveBattler) - && gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker] != gActiveBattler - && gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD - && GetBattlerTurnOrderNum(gActiveBattler) < var) - { - var = GetBattlerTurnOrderNum(gActiveBattler); - } - } - if (var == 4) - { - if (gBattleMoves[gChosenMove].target & MOVE_TARGET_RANDOM) - { - if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) - { - if (Random() & 1) - gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - else - gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); - } - else - { - if (Random() & 1) - gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - else - gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); - } - } - else - { - gBattlerTarget = gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker]; - } - - if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) - { - if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) - { - gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK); - } - else - { - gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_SIDE); - if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) - gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK); - } - } - } - else - { - gActiveBattler = gBattlerByTurnOrder[var]; - RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability); - gSpecialStatuses[gActiveBattler].lightningRodRedirected = 1; - gBattlerTarget = gActiveBattler; - } - } - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && gBattleMoves[gChosenMove].target & MOVE_TARGET_RANDOM) - { - if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) - { - if (Random() & 1) - gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - else - gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); - } - else - { - if (Random() & 1) - gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - else - gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); - } - - if (gAbsentBattlerFlags & gBitTable[gBattlerTarget] - && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) - { - gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK); - } - } - else - { - gBattlerTarget = gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker]; - if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) - { - if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) - { - gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK); - } - else - { - gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_SIDE); - if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) - gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK); - } - } - } - - gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; - gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; -} - -void HandleAction_Switch(void) -{ - gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gActionSelectionCursor[gBattlerAttacker] = 0; - gMoveSelectionCursor[gBattlerAttacker] = 0; - - PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBattlerAttacker, gSharedMem[BSTRUCT_OFF(unk16064) + gBattlerAttacker]) - - gBattleStruct->scriptingActive = gBattlerAttacker; - gBattlescriptCurrInstr = BattleScript_ActionSwitch; - gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; - - if (gBattleResults.totalMonSwitchCounter < 255) - gBattleResults.totalMonSwitchCounter++; -} - -void HandleAction_UseItem(void) -{ - gBattlerAttacker = gBattlerTarget = gBattlerByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gDisableStructs[gBattlerAttacker].furyCutterCounter = 0; - gLastUsedItem = gBattleBufferB[gBattlerAttacker][1] | (gBattleBufferB[gBattlerAttacker][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(gBattlerAttacker) == B_SIDE_PLAYER) - { - gBattlescriptCurrInstr = gBattlescriptsForUsingItem[0]; - } - else - { - gBattleStruct->scriptingActive = gBattlerAttacker; - - switch (gSharedMem[BSTRUCT_OFF(AI_usedItemType) + (gBattlerAttacker >> 1)]) - { - case AI_ITEM_FULL_RESTORE: - case AI_ITEM_HEAL_HP: - break; - case AI_ITEM_CURE_CONDITION: - gBattleCommunication[MULTISTRING_CHOOSER] = AI_HEAL_CONFUSION; - if (gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] & (1 << AI_HEAL_CONFUSION)) - { - if (gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] & ((1 << AI_HEAL_PARALYSIS) - | (1 << AI_HEAL_FREEZE) - | (1 << AI_HEAL_BURN) - | (1 << AI_HEAL_POISON) - | (1 << AI_HEAL_SLEEP))) - gBattleCommunication[MULTISTRING_CHOOSER] = AI_HEAL_SLEEP; - } - else - { - while (!(gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] & 1)) - { - gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] >>= 1; - gBattleCommunication[MULTISTRING_CHOOSER]++; - } - } - break; - case AI_ITEM_X_STAT: - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - if (gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] & (1 << AI_DIRE_HIT)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 5; - } - else - { - PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK) - PREPARE_STRING_BUFFER(gBattleTextBuff2, STRINGID_STATROSE) - - while (!(gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] & 1)) - { - gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] >>= 1; - gBattleTextBuff1[2]++; - } - - gBattleStruct->animArg1 = gBattleTextBuff1[2] + 14; - gBattleStruct->animArg2 = 0; - } - break; - case AI_ITEM_GUARD_SPEC: - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - gBattleCommunication[MULTISTRING_CHOOSER] = 2; - else - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - break; - } - - gBattlescriptCurrInstr = gBattlescriptsForUsingItem[gSharedMem[BSTRUCT_OFF(AI_usedItemType) + (gBattlerAttacker / 2)]]; - } - gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; -} - -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); - - gPotentialItemEffectBattler = 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) + (gBattleStruct->runTries * 30); - if (speedVar > (Random() & 0xFF)) - effect++; - } - else // same speed or faster - { - effect++; - } - } - - gBattleStruct->runTries++; - } - - if (effect) - { - gCurrentTurnActionNumber = gBattlersCount; - gBattleOutcome = B_OUTCOME_RAN; - } - - return effect; -} - -void HandleAction_Run(void) -{ - gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; - - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - gCurrentTurnActionNumber = gBattlersCount; - - for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) - { - if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) - { - if (gActionForBanks[gActiveBattler] == B_ACTION_RUN) - gBattleOutcome |= B_OUTCOME_LOST; - } - else - { - if (gActionForBanks[gActiveBattler] == B_ACTION_RUN) - gBattleOutcome |= B_OUTCOME_WON; - } - } - - gBattleOutcome |= B_OUTCOME_LINK_BATTLE_RAN; - } - else - { - if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) - { - if (!TryRunFromBattle(gBattlerAttacker)) // failed to run away - { - gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_DESTINY_BOND; - gBattleCommunication[MULTISTRING_CHOOSER] = 3; - gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString; - gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; - } - } - else - { - if (gBattleMons[gBattlerAttacker].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = 4; - gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString; - gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; - } - else - { - gCurrentTurnActionNumber = gBattlersCount; - gBattleOutcome = B_OUTCOME_MON_FLED; - } - } - } -} - -void HandleAction_WatchesCarefully(void) -{ - gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gBattlescriptCurrInstr = gBattlescriptsForSafariActions[0]; - gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; -} - -void HandleAction_SafariZoneBallThrow(void) -{ - gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gNumSafariBalls--; - gLastUsedItem = ITEM_SAFARI_BALL; - gBattlescriptCurrInstr = gBattlescriptsForBallThrow[ITEM_SAFARI_BALL]; - gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; -} - -void HandleAction_ThrowPokeblock(void) -{ - gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - gBattleCommunication[MULTISTRING_CHOOSER] = gBattleBufferB[gBattlerAttacker][1] - 1; - gLastUsedItem = gBattleBufferB[gBattlerAttacker][2]; - - if (gBattleStruct->safariPkblThrowCounter < 3) - gBattleStruct->safariPkblThrowCounter++; - if (gBattleStruct->safariFleeRate > 1) - { - if (gBattleStruct->safariFleeRate < gUnknown_081FA70C[gBattleStruct->safariPkblThrowCounter][gBattleCommunication[MULTISTRING_CHOOSER]]) - gBattleStruct->safariFleeRate = 1; - else - gBattleStruct->safariFleeRate -= gUnknown_081FA70C[gBattleStruct->safariPkblThrowCounter][gBattleCommunication[MULTISTRING_CHOOSER]]; - } - - gBattlescriptCurrInstr = gBattlescriptsForSafariActions[2]; - gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; -} - -void HandleAction_GoNear(void) -{ - gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - - gBattleStruct->safariCatchFactor += gUnknown_081FA71B[gBattleStruct->safariGoNearCounter]; - if (gBattleStruct->safariCatchFactor > 20) - gBattleStruct->safariCatchFactor = 20; - - gBattleStruct->safariFleeRate += gUnknown_081FA71F[gBattleStruct->safariGoNearCounter]; - if (gBattleStruct->safariFleeRate > 20) - gBattleStruct->safariFleeRate = 20; - - if (gBattleStruct->safariGoNearCounter < 3) - { - gBattleStruct->safariGoNearCounter++; - gBattleCommunication[MULTISTRING_CHOOSER] = 0; - } - else - { - gBattleCommunication[MULTISTRING_CHOOSER] = 1; - } - gBattlescriptCurrInstr = gBattlescriptsForSafariActions[1]; - gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; -} - -void HandleAction_SafriZoneRun(void) -{ - gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; - PlaySE(SE_FLEE); - gCurrentTurnActionNumber = gBattlersCount; - gBattleOutcome = B_OUTCOME_RAN; -} - -void HandleAction_Action9(void) -{ - gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; - gBattle_BG0_X = 0; - gBattle_BG0_Y = 0; - - PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattlerPartyIndexes[gBattlerAttacker]) - - gBattlescriptCurrInstr = gBattlescriptsForSafariActions[3]; - gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; - gActionsByTurnOrder[1] = B_ACTION_FINISHED; -} - -void HandleAction_Action11(void) -{ - if (!HandleFaintedMonActions()) - { - gBattleStruct->faintedActionsState = 0; - gCurrentActionFuncId = B_ACTION_FINISHED; - } -} - -void HandleAction_NothingIsFainted(void) -{ - gCurrentTurnActionNumber++; - gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber]; - gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED - | HITMARKER_NO_PPDEDUCT | HITMARKER_STATUS_ABILITY_EFFECT | HITMARKER_IGNORE_ON_AIR - | HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000 - | HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT - | HITMARKER_CHARGING | HITMARKER_x4000000); -} - -void HandleAction_ActionFinished(void) -{ - gCurrentTurnActionNumber++; - gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber]; - SpecialStatusesClear(); - gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED - | HITMARKER_NO_PPDEDUCT | HITMARKER_STATUS_ABILITY_EFFECT | HITMARKER_IGNORE_ON_AIR - | HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000 - | HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT - | HITMARKER_CHARGING | HITMARKER_x4000000); - - gBattleMoveDamage = 0; - gBattleStruct->animTurn = 0; - gBattleStruct->animTargetsHit = 0; - gLastLandedMoves[gBattlerAttacker] = 0; - gLastHitByType[gBattlerAttacker] = 0; - gBattleStruct->dynamicMoveType = 0; - gDynamicBasePower = 0; - gBattleStruct->cmd49StateTracker = 0; - gBattleCommunication[3] = 0; - gBattleCommunication[4] = 0; - gBattleStruct->multihitMoveEffect = 0; - B_BATTLESCRIPTS_STACK->size = 0; -} diff --git a/src/battle_main1.c b/src/battle_main1.c new file mode 100644 index 0000000000..40e32c7479 --- /dev/null +++ b/src/battle_main1.c @@ -0,0 +1,1206 @@ +#include "global.h" +#include "battle.h" +#include "battle_controllers.h" +#include "battle_message.h" +#include "data2.h" +#include "event_data.h" +#include "ewram.h" +#include "graphics.h" +#include "link.h" +#include "m4a.h" +#include "name_string_util.h" +#include "overworld.h" +#include "palette.h" +#include "party_menu.h" +#include "random.h" +#include "scanline_effect.h" +#include "sound.h" +#include "task.h" +#include "text.h" +#include "trainer.h" +#include "constants/songs.h" +#include "constants/species.h" + +// Equivalent to pokeemerald's battle_main.c, but split in two by a debug file in the middle. + +u16 gBattle_BG0_X; +u16 gBattle_BG0_Y; +u16 gBattle_BG1_X; +u16 gBattle_BG1_Y; +u16 gBattle_BG2_X; +u16 gBattle_BG2_Y; +u16 gBattle_BG3_X; +u16 gBattle_BG3_Y; +u16 gBattle_WIN0H; +u16 gBattle_WIN0V; +u16 gBattle_WIN1H; +u16 gBattle_WIN1V; +u8 gBattleTextBuff1[TEXT_BUFF_ARRAY_COUNT]; +u8 gBattleTextBuff2[TEXT_BUFF_ARRAY_COUNT]; +u8 gBattleTextBuff3[TEXT_BUFF_ARRAY_COUNT]; +u8 gBattleTerrain; +void (*gBattleMainFunc)(void); +u32 gUnknown_03004284; +struct Window gWindowTemplate_Contest_MoveDescription; +struct Window gUnknown_030041D0; +struct Window gUnknown_03004250; + +EWRAM_DATA u8 gDisplayedStringBattle[300] = {0}; +EWRAM_DATA u16 gBattleTypeFlags = 0; +EWRAM_DATA u32 gUnknown_020239FC = 0; +EWRAM_DATA struct MultiBattlePokemonTx gMultiPartnerParty[3] = {0}; + +void CB2_InitBattle(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + HandleLinkBattleSetup(); + SetMainCallback2(sub_800F104); + gBattleCommunication[0] = 0; + } + else + { + CB2_InitBattleInternal(); + } +} + +void CB2_InitBattleInternal(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 < 160; i++) + { + gScanlineEffectRegBuffers[0][i] = 0xFF10; + gScanlineEffectRegBuffers[1][i] = 0xFF10; + } + //ScanlineEffect_SetParams(gUnknown_081F9674.totalPoints, gUnknown_081F9674.round1Points, gUnknown_081F9674.random); + 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(&gWindowTemplate_Contest_MoveDescription, &gWindowTemplate_81E6C58); + Text_InitWindowWithTemplate(&gUnknown_030041D0, &gWindowTemplate_81E71D0); + Text_InitWindowWithTemplate(&gUnknown_03004250, &gWindowTemplate_81E71EC); + sub_800D6D4(); + LoadBattleTextboxAndBackground(); + ResetSpriteData(); + ResetTasks(); + DrawBattleEntryBackground(); + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 4; + SetVBlankCallback(sub_800FCFC); + SetUpBattleVarsAndBirchPoochyena(); + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + SetMainCallback2(CB2_HandleStartMultiBattle); + else + SetMainCallback2(CB2_HandleStartBattle); + 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 BufferPartyVsScreenHealth_AtStart(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 == SPECIES_NONE) + continue; + if (species != SPECIES_EGG && hp != 0 && status == 0) + r6 |= 1 << i * 2; + + if (species == SPECIES_NONE) + continue; + if (hp != 0 && (species == SPECIES_EGG || status != 0)) + r6 |= 2 << i * 2; + + if (species == SPECIES_NONE) + continue; + if (species != SPECIES_EGG && hp == 0) + r6 |= 3 << i * 2; + } + eMultiTxBuffer.linkPartnerHeader.vsScreenHealthFlagsLo = r6; + eMultiTxBuffer.linkPartnerHeader.vsScreenHealthFlagsHi = r6 >> 8; +} + +static void SetPlayerBerryDataInBattleStruct(void) +{ + s32 i; + struct BattleEnigmaBerry * battleBerry = &eMultiTxBuffer.linkPartnerHeader.battleEnigmaBerry; + + for (i = 0; i < 7; i++) + battleBerry->name[i] = gSaveBlock1.enigmaBerry.berry.name[i]; + for (i = 0; i < 18; i++) + battleBerry->itemEffect[i] = gSaveBlock1.enigmaBerry.itemEffect[i]; + battleBerry->holdEffect = gSaveBlock1.enigmaBerry.holdEffect; + battleBerry->holdEffectParam = gSaveBlock1.enigmaBerry.holdEffectParam; +} + +void SetAllPlayersBerryData(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].id; + + 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 TryCorrectShedinjaLanguage(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 CB2_HandleStartBattle(void) +{ + u8 playerId; + u8 enemyId; + s32 id; + + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + + playerId = GetMultiplayerId(); + gBattleStruct->multiplayerId = playerId; + enemyId = playerId ^ 1; + + switch (gBattleCommunication[0]) + { + case 0: + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + if (gReceivedRemoteLinkPlayers != 0 && IsLinkTaskFinished()) + { + eMultiTxBuffer.linkPartnerHeader.versionSignatureLo = 1; + eMultiTxBuffer.linkPartnerHeader.versionSignatureHi = 1; + BufferPartyVsScreenHealth_AtStart(); + SetPlayerBerryDataInBattleStruct(); +#if DEBUG + if (gUnknown_02023A14_50 & 8) + { + for (id = 0; id < 2; id++) // Why < 2 here? + { + gLinkPlayers[id].id = id; + gLinkPlayers[id].linkType = 0x2211; + } + } +#endif + SendBlock(bitmask_all_link_players_but_self(), &eMultiTxBuffer.linkPartnerHeader, sizeof(eMultiTxBuffer.linkPartnerHeader)); + gBattleCommunication[0] = 1; + } + } + else + { + gBattleTypeFlags |= BATTLE_TYPE_WILD; + gBattleCommunication[0] = 8; + SetAllPlayersBerryData(); + } + 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; + } + } + SetAllPlayersBerryData(); + taskId = CreateTask(InitLinkBattleVsScreen, 0); + gTasks[taskId].data[1] = 0x10E; + gTasks[taskId].data[2] = 0x5A; + gTasks[taskId].data[5] = 0; + gTasks[taskId].data[3] = eMultiTxBuffer.linkPartnerHeader.vsScreenHealthFlagsLo | (eMultiTxBuffer.linkPartnerHeader.vsScreenHealthFlagsHi << 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); + TryCorrectShedinjaLanguage(&gEnemyParty[0]); + TryCorrectShedinjaLanguage(&gEnemyParty[1]); + TryCorrectShedinjaLanguage(&gEnemyParty[2]); + TryCorrectShedinjaLanguage(&gEnemyParty[3]); + TryCorrectShedinjaLanguage(&gEnemyParty[4]); + TryCorrectShedinjaLanguage(&gEnemyParty[5]); + gBattleCommunication[0]++; + } + break; + case 8: + sub_800B950(); + gBattleCommunication[0]++; + gBattleCommunication[1] = 0; + gBattleCommunication[2] = 0; + break; + case 9: + if (battle_load_something(&gBattleCommunication[1], &gBattleCommunication[2]) != 0) + { + gPreBattleCallback1 = gMain.callback1; + gMain.callback1 = BattleMainCB1; + SetMainCallback2(BattleMainCB2); + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gTrainerBattleOpponent = LINK_BATTLE_OPPONENT; + gBattleTypeFlags |= BATTLE_TYPE_20; + } + } + break; + } +} + +void PrepareOwnMultiPartnerBuffer(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(eMultiTxBuffer.multiBattleMons, gMultiPartnerParty, 3 * sizeof(struct MultiBattlePokemonTx)); +} + +void sub_800F104(void) +{ + u8 playerId; + MainCallback *pSavedCallback; + u16 *pSavedBattleTypeFlags; + s32 i; + + playerId = GetMultiplayerId(); + gBattleStruct->multiplayerId = playerId; + // Seriously, Game Freak? + pSavedCallback = &gBattleStruct->unk160C4; + pSavedBattleTypeFlags = &gBattleStruct->unk160C2; + 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].id = i; + gLinkPlayers[i].linkType = 0x2211; + } + } +#endif + if (IsLinkTaskFinished()) + { + PrepareOwnMultiPartnerBuffer(); + SendBlock(bitmask_all_link_players_but_self(), eMultiTxBuffer.multiBattleMons, 3 * sizeof(struct MultiBattlePokemonTx)); + gBattleCommunication[0]++; + } + } + break; + case 1: + if ((GetBlockReceivedStatus() & 0xF) == 0xF) + { + //s32 i; + // Get your multi battle partner's party + ResetBlockReceivedFlags(); + for (i = 0; i < 4; i++) + { + if (i != playerId) + { + if ((!(gLinkPlayers[i].id & 1) && !(gLinkPlayers[playerId].id & 1)) + || ((gLinkPlayers[i].id & 1) && (gLinkPlayers[playerId].id & 1))) + memcpy(gMultiPartnerParty, gBlockRecvBuffer[i], 3 * sizeof(struct MultiBattlePokemonTx)); + } + } + 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; + SetCloseLinkCallback(); + } + break; + case 3: + if (gReceivedRemoteLinkPlayers == 0) + { + gBattleTypeFlags = *pSavedBattleTypeFlags; + gMain.savedCallback = *pSavedCallback; + SetMainCallback2(CB2_InitBattleInternal); + } + break; + } +} + +void CB2_HandleStartMultiBattle(void) +{ + u8 playerId; + s32 id; + + playerId = GetMultiplayerId(); + gBattleStruct->multiplayerId = 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].id = id; + gLinkPlayers[id].linkType = 0x2211; + } + } +#endif + if (IsLinkTaskFinished()) + { + *(&eMultiTxBuffer.linkPartnerHeader.versionSignatureLo) = 1; + *(&eMultiTxBuffer.linkPartnerHeader.versionSignatureHi) = 1; + BufferPartyVsScreenHealth_AtStart(); + SetPlayerBerryDataInBattleStruct(); + SendBlock(bitmask_all_link_players_but_self(), &eMultiTxBuffer.linkPartnerHeader, sizeof(eMultiTxBuffer.linkPartnerHeader)); + gBattleCommunication[0]++; + } + } + break; + case 1: + if ((GetBlockReceivedStatus() & 0xF) == 0xF) + { + u8 taskId; + + ResetBlockReceivedFlags(); + // LinkBattleComputeBattleTypeFlags + 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; + } + } + SetAllPlayersBerryData(); + memcpy(eMultiBattleSetupPartySendBuffer, gPlayerParty, sizeof(struct Pokemon) * 3); + taskId = CreateTask(InitLinkBattleVsScreen, 0); + gTasks[taskId].data[1] = 270; + gTasks[taskId].data[2] = 90; + 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].id) + { + 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(), eMultiBattleSetupPartySendBuffer, 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].id) + { + 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].id & 1) && !(gLinkPlayers[playerId].id & 1)) + || ((gLinkPlayers[id].id & 1) && (gLinkPlayers[playerId].id & 1))) + { + switch (gLinkPlayers[id].id) + { + 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].id) + { + 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(), eMultiBattleSetupPartySendBuffer + 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].id) + { + 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].id & 1) && !(gLinkPlayers[playerId].id & 1)) + || ((gLinkPlayers[id].id & 1) && (gLinkPlayers[playerId].id & 1))) + { + switch (gLinkPlayers[id].id) + { + 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].id) + { + 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; + } + } + } + } + + TryCorrectShedinjaLanguage(&gPlayerParty[0]); + TryCorrectShedinjaLanguage(&gPlayerParty[1]); + TryCorrectShedinjaLanguage(&gPlayerParty[2]); + TryCorrectShedinjaLanguage(&gPlayerParty[3]); + TryCorrectShedinjaLanguage(&gPlayerParty[4]); + TryCorrectShedinjaLanguage(&gPlayerParty[5]); + + TryCorrectShedinjaLanguage(&gEnemyParty[0]); + TryCorrectShedinjaLanguage(&gEnemyParty[1]); + TryCorrectShedinjaLanguage(&gEnemyParty[2]); + TryCorrectShedinjaLanguage(&gEnemyParty[3]); + TryCorrectShedinjaLanguage(&gEnemyParty[4]); + TryCorrectShedinjaLanguage(&gEnemyParty[5]); + + gBattleCommunication[0]++; + } + break; + case 6: + sub_800B950(); + gBattleCommunication[0]++; + gBattleCommunication[1] = 0; + gBattleCommunication[2] = 0; + break; + case 7: + if (battle_load_something(&gBattleCommunication[1], &gBattleCommunication[2]) != 0) + { + gPreBattleCallback1 = gMain.callback1; + gMain.callback1 = BattleMainCB1; + 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(&gWindowTemplate_Contest_MoveDescription); + 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(CB2_InitBattle); + 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->x = sprite->data[1] + ((sprite->data[2] & 0xFF00) >> 8); + else + sprite->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_MUGSHOT); +} + +void sub_800FE40(u8 taskId) +{ + struct Pokemon *sp4 = NULL; + struct Pokemon *sp8 = NULL; + u8 r2 = gBattleStruct->multiplayerId; + u32 r7; + s32 i; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + switch (gLinkPlayers[r2].id) + { + 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 < 160; i++) + { + 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(&gWindowTemplate_Contest_MoveDescription, &gWindowTemplate_81E6C58); + Text_InitWindowWithTemplate(&gUnknown_030041D0, &gWindowTemplate_81E71D0); + Text_InitWindowWithTemplate(&gUnknown_03004250, &gWindowTemplate_81E71EC); + sub_800D6D4(); + LoadCompressedPalette(gBattleTextboxPalette, 0, 64); + ApplyPlayerChosenFrameToBattleMenu(); + ResetSpriteData(); + ResetTasks(); + DrawBattleEntryBackground(); + REG_WINOUT = 0x37; + FreeAllSpritePalettes(); + gReservedSpritePaletteCount = 4; + SetVBlankCallback(sub_800FCFC); + taskId = CreateTask(InitLinkBattleVsScreen, 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; + } +} diff --git a/src/battle_main2.c b/src/battle_main2.c new file mode 100644 index 0000000000..6864131c0b --- /dev/null +++ b/src/battle_main2.c @@ -0,0 +1,2290 @@ +#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_controllers.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 "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" +#include "battle_string_ids.h" +#include "battle_ai_switch_items.h" + +struct UnknownStruct7 +{ + u8 unk0; + u8 unk1; + u8 unk2; + u8 unk3; +}; + +struct UnknownStruct8 +{ + u8 unk0[7]; + u8 unk7; + u8 unk8[18]; + u8 unk1A; +}; + +extern const u16 gBattleTextboxPalette[]; +extern const struct MonCoords gCastformFrontSpriteCoords[]; +extern const u8 gStatStageRatios[][2]; +extern u8 gBattlePartyCurrentOrder[]; +MainCallback gPreBattleCallback1; +u8 gUnknown_03004344; +u8 gUnknown_03004348; +extern void (*gBattleMainFunc)(void); +u8 gLeveledUpInBattle; +void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(void); +u8 gHealthboxSpriteIds[MAX_BATTLERS_COUNT]; +u8 gUnknown_0300434C[MAX_BATTLERS_COUNT]; +extern u8 gReservedSpritePaletteCount; +extern u16 gTrainerBattleOpponent; +extern u16 gBlockRecvBuffer[MAX_LINK_PLAYERS][BLOCK_BUFFER_SIZE / 2]; +extern const u8 BattleScript_FocusPunchSetUp[]; +extern void (* const gUnknown_081FA640[])(void); +extern void (* const gUnknown_081FA678[])(void); +extern const u8 BattleScript_LinkBattleWonOrLost[]; +extern const u8 BattleScript_PayDayMoneyAndPickUpItems[]; +extern const u8 gUnknown_081D8E0D[]; +extern const BattleCmdFunc gBattleScriptingCommandsTable[]; +extern u32 gUnknown_03004284; +struct BattleResults gBattleResults; + +void BattleMainCB1(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); + +EWRAM_DATA u8 gBattleBufferA[MAX_BATTLERS_COUNT][0x200] = {0}; +EWRAM_DATA u8 gBattleBufferB[MAX_BATTLERS_COUNT][0x200] = {0}; +EWRAM_DATA u8 gActiveBattler = 0; +EWRAM_DATA u32 gBattleControllerExecFlags = 0; +EWRAM_DATA u8 gBattlersCount = 0; +EWRAM_DATA u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gBattlerPositions[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gActionsByTurnOrder[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gBattlerByTurnOrder[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gCurrentTurnActionNumber = 0; +EWRAM_DATA u8 gCurrentActionFuncId = 0; +EWRAM_DATA struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gBattlerSpriteIds[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gCurrMovePos = 0; +EWRAM_DATA u8 gUnknown_02024BE5 = 0; +EWRAM_DATA u16 gCurrentMove = 0; +EWRAM_DATA u16 gChosenMove = 0; +EWRAM_DATA u16 gRandomMove = 0; +EWRAM_DATA s32 gBattleMoveDamage = 0; +EWRAM_DATA s32 gHpDealt = 0; +EWRAM_DATA s32 gTakenDmg[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLastUsedItem = 0; +EWRAM_DATA u8 gLastUsedAbility = 0; +EWRAM_DATA u8 gBattlerAttacker = 0; +EWRAM_DATA u8 gBattlerTarget = 0; +EWRAM_DATA u8 gBank1 = 0; +EWRAM_DATA u8 gEffectBattler = 0; +EWRAM_DATA u8 gPotentialItemEffectBattler = 0; +EWRAM_DATA u8 gAbsentBattlerFlags = 0; +EWRAM_DATA u8 gCritMultiplier = 0; +EWRAM_DATA u8 gMultiHitCounter = 0; +EWRAM_DATA const u8 * gBattlescriptCurrInstr = NULL; +EWRAM_DATA u32 gUnusedBattleMainVar = 0; +EWRAM_DATA u8 gActionForBanks[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA const u8 * gSelectionBattleScripts[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLastPrintedMoves[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLastMoves[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLastLandedMoves[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLastHitByType[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLastResultingMoves[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLockedMoves[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gLastHitBy[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gChosenMovesByBanks[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gMoveResultFlags = 0; +EWRAM_DATA u32 gHitMarker = 0; +EWRAM_DATA u8 sUnusedBattlersArray[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gTakenDmgByBattler[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gUnknown_02024C78 = 0; +EWRAM_DATA u16 gSideStatuses[2] = {0}; +EWRAM_DATA struct SideTimer gSideTimers[2] = {0}; +EWRAM_DATA u32 gStatuses3[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA struct DisableStruct gDisableStructs[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gPauseCounterBattle = 0; +EWRAM_DATA u16 gPaydayMoney = 0; +EWRAM_DATA u16 gRandomTurnNumber = 0; +EWRAM_DATA u8 gBattleCommunication[8] = {0}; +EWRAM_DATA u8 gBattleOutcome = 0; +EWRAM_DATA struct ProtectStruct gProtectStructs[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA struct SpecialStatus gSpecialStatuses[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gBattleWeather = 0; +EWRAM_DATA struct WishFutureKnock gWishFutureKnock = {0}; +EWRAM_DATA u16 gIntroSlideFlags = 0; +EWRAM_DATA u8 gSentPokesToOpponent[2] = {0}; +EWRAM_DATA u16 gDynamicBasePower = 0; +EWRAM_DATA u16 gExpShareExp = 0; +EWRAM_DATA struct BattleEnigmaBerry gEnigmaBerries[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gActionSelectionCursor[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gMoveSelectionCursor[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gUnknown_02024E68[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u8 gBankInMenu = 0; +EWRAM_DATA u8 gDoingBattleAnim = 0; +EWRAM_DATA u32 gTransformedPersonalities[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gBattleMovePower = 0; +EWRAM_DATA u16 gMoveToLearn = 0; +EWRAM_DATA u8 gBattleMonForms[MAX_BATTLERS_COUNT] = {0}; + +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 ((gIntroSlideFlags & 1) == 0) + { + sprite->x2 += 2; + if (sprite->x2 == 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(gHealthboxSpriteIds[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 (gBattleSpriteInfo[r6].transformedSpecies != 0) + species = gBattleSpriteInfo[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->y2 += 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 *)gMonSpriteGfx_Sprite_ptr[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 ((gIntroSlideFlags & 1) == 0) + { + sprite->x2 -= 2; + if (sprite->x2 == 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 ((gIntroSlideFlags & 1) == 0) + { + sprite->x2 += sprite->data[1]; + sprite->y2 += 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 = gHealthboxSpriteIds[bank]; + ewram17810[bank].unk2 = spriteId; + ewram17810[bank].unk0_1 = 1; + gSprites[spriteId].data[0] = 0x80; + } + else + { + objectID = gBattlerSpriteIds[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].x2 = 0; + gSprites[objectID].y2 = 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].x2 = 0; + gSprites[r4].y2 = 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].y2 = 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) +{ + BattleStartClearSetData(); + gBattleCommunication[1] = 0; + gBattleMainFunc = bc_8012FAC; +} + +#if DEBUG +void debug_sub_80138CC(void) +{ + if (GetBattlerSide(gActiveBattler) == 0) + { + switch (gBattleStruct->unk160FD) + { + case 0: + if (gBattlerControllerFuncs[gActiveBattler] == sub_802C098) + gBattleStruct->unk160FD++; + break; + case 1: + gMain.heldKeys = A_BUTTON; + gMain.newKeys = A_BUTTON; + gBattleStruct->unk160FD++; + gBattleStruct->unk160FE = 0x80; + break; + case 2: + gBattleStruct->unk160FE--; + if (gBattleStruct->unk160FE == 0) + { + gMain.heldKeys = A_BUTTON; + gMain.newKeys = A_BUTTON; + gBattleStruct->unk160FD++; + gBattleStruct->unk160FE = 0x80; + } + break; + case 3: + gBattleStruct->unk160FE--; + if (gBattleStruct->unk160FE == 0) + { + gMain.heldKeys = A_BUTTON; + gMain.newKeys = A_BUTTON; + gBattleStruct->unk160FD++; + } + break; + case 4: + gBattleStruct->unk160FD = 0; + break; + } + } +} +#endif + +void BattleMainCB1(void) +{ +#if DEBUG + if (gUnknown_02023A14_50 & 0x80) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + debug_sub_80138CC(); + gBattleMainFunc(); + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + gBattlerControllerFuncs[gActiveBattler](); + } + else +#endif + { + gBattleMainFunc(); + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + gBattlerControllerFuncs[gActiveBattler](); + } +} + +void BattleStartClearSetData(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; + sUnusedBattlersArray[i] = 0; + gLastMoves[i] = 0; + gLastLandedMoves[i] = 0; + gLastHitByType[i] = 0; + gLastResultingMoves[i] = 0; + gLastHitBy[i] = 0xFF; + gLockedMoves[i] = 0; + gLastPrintedMoves[i] = 0; + eBattleFlagsArr.arr[i] = 0; + } + + for (i = 0; i < 2; i++) + { + gSideStatuses[i] = 0; + MEMSET_ALT(&gSideTimers[i], 0, sizeof(struct SideTimer), j, r4); + } + + gBattlerAttacker = 0; + gBattlerTarget = 0; + gBattleWeather = 0; + + MEMSET_ALT(&gWishFutureKnock, 0, sizeof(struct WishFutureKnock), i, r4); + + gHitMarker = 0; + if ((gBattleTypeFlags & BATTLE_TYPE_LINK) == 0 && gSaveBlock2.optionsBattleSceneOff == TRUE) + gHitMarker = HITMARKER_NO_ANIMATIONS; + + gBattleStruct->battleStyle = gSaveBlock2.optionsBattleStyle; + + gMultiHitCounter = 0; + gBattleOutcome = 0; + gBattleControllerExecFlags = 0; + gPaydayMoney = 0; + (*(u8 *)&B_BATTLESCRIPTS_STACK->size) = 0; + (*(u8 *)&B_FUNCTION_STACK->size) = 0; + + for (i = 0; i < 8; i++) + gBattleCommunication[i] = 0; + + gPauseCounterBattle = 0; + gBattleMoveDamage = 0; + gIntroSlideFlags = 0; + gBattleStruct->animTurn = 0; + gBattleStruct->animTargetsHit = 0; + gLeveledUpInBattle = 0; + gAbsentBattlerFlags = 0; + gBattleStruct->runTries = 0; + gBattleStruct->safariGoNearCounter = 0; + gBattleStruct->safariPkblThrowCounter = 0; + gBattleStruct->safariCatchFactor = gBaseStats[GetMonData(&gEnemyParty[0], MON_DATA_SPECIES)].catchRate * 100 / 1275; + gBattleStruct->safariFleeRate = 3; + gBattleStruct->wildVictorySong = 0; + gBattleStruct->moneyMultiplier = 1; + + for (i = 0; i < 8; i++) + { + gSharedMem[BSTRUCT_OFF(lastTakenMove) + i] = 0; + gSharedMem[BSTRUCT_OFF(usedHeldItems) + i] = 0; + gSharedMem[BSTRUCT_OFF(choicedMove) + i] = 0; + gSharedMem[BSTRUCT_OFF(changedItems) + i] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 0 * 8 + i] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 1 * 8 + i] = 0; + } + + gBattleStruct->AI_monToSwitchIntoId[0] = PARTY_SIZE; + gBattleStruct->AI_monToSwitchIntoId[1] = PARTY_SIZE; + + gBattleStruct->givenExpMons = 0; + + // Reset gBattleResults + for (i = 0; i < 11; i++) + gBattleResults.usedBalls[i] = 0; + gBattleResults.battleTurnCounter = 0; + gBattleResults.playerFaintCounter = 0; + gBattleResults.opponentFaintCounter = 0; + gBattleResults.totalMonSwitchCounter = 0; + gBattleResults.playerHealInBattleCount = 0; + gBattleResults.reviveCount = 0; + gBattleResults.playerMonWasDamaged = 0; + gBattleResults.usedMasterBall = 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[BSTRUCT_OFF(dbgAICycleMoveTracker) + 0] = 0; + gSharedMem[BSTRUCT_OFF(dbgAICycleMoveTracker) + 1] = 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].battlerWithSureHit == gActiveBattler) + { + gStatuses3[i] &= ~STATUS3_ALWAYS_HITS; + gDisableStructs[i].battlerWithSureHit = 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_BATTLER | 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].battlerWithSureHit == 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) && gSharedMem[BSTRUCT_OFF(wrappedBy) + 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].battlerWithSureHit = sp0.battlerWithSureHit; + gDisableStructs[gActiveBattler].perishSongTimer1 = sp0.perishSongTimer1; + gDisableStructs[gActiveBattler].perishSongTimer2 = sp0.perishSongTimer2; + } + + gDisableStructs[gActiveBattler].isFirstTurn= 2; + gLastMoves[gActiveBattler] = 0; + gLastLandedMoves[gActiveBattler] = 0; + gLastHitByType[gActiveBattler] = 0; + gLastResultingMoves[gActiveBattler] = 0; + gLastPrintedMoves[gActiveBattler] = 0; + gLastHitBy[gActiveBattler] = 0xFF; + + gSharedMem[BSTRUCT_OFF(lastTakenMove) + 2 * gActiveBattler + 0] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMove) + 2 * gActiveBattler + 1] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 0] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 1] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 2] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 3] = 0; + gSharedMem[BSTRUCT_OFF(choicedMove) + 2 * gActiveBattler + 0] = 0; + gSharedMem[BSTRUCT_OFF(choicedMove) + 2 * gActiveBattler + 1] = 0; + + eBattleFlagsArr.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) && gSharedMem[BSTRUCT_OFF(wrappedBy) + 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].noValidMoves = 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].targetNotAffected = 0; + gProtectStructs[gActiveBattler].chargingTurn = 0; + gProtectStructs[gActiveBattler].fleeFlag = 0; + gProtectStructs[gActiveBattler].usedImprisonedMove = 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; + gLastMoves[gActiveBattler] = 0; + gLastLandedMoves[gActiveBattler] = 0; + gLastHitByType[gActiveBattler] = 0; + gLastResultingMoves[gActiveBattler] = 0; + gLastPrintedMoves[gActiveBattler] = 0; + gLastHitBy[gActiveBattler] = 0xFF; + + gSharedMem[BSTRUCT_OFF(choicedMove) + 2 * gActiveBattler + 0] = 0; + gSharedMem[BSTRUCT_OFF(choicedMove) + 2 * gActiveBattler + 1] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMove) + 2 * gActiveBattler + 0] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMove) + 2 * gActiveBattler + 1] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 0] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 1] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 2] = 0; + gSharedMem[BSTRUCT_OFF(lastTakenMoveFrom) + 4 * gActiveBattler + 3] = 0; + + eBattleFlagsArr.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]; + BtlController_EmitGetMonData(0, 0, 0); + MarkBattlerForControllerExec(gActiveBattler); + gBattleCommunication[0]++; + break; + case 1: + if (gBattleControllerExecFlags == 0) + { + gBattleCommunication[1]++; + if (gBattleCommunication[1] == gBattlersCount) + gBattleMainFunc = BattlePrepIntroSlide; + else + gBattleCommunication[0] = 0; + } + break; + } +} + +static void BattlePrepIntroSlide(void) +{ + if (gBattleControllerExecFlags == 0) + { + gActiveBattler = GetBattlerAtPosition(0); + BtlController_EmitIntroSlide(0, gBattleTerrain); + MarkBattlerForControllerExec(gActiveBattler); + gBattleMainFunc = sub_8011384; + gBattleCommunication[0] = 0; + gBattleCommunication[1] = 0; + } +} + +void sub_8011384(void) +{ + u8 *ptr; + s32 i; + + if (gBattleControllerExecFlags == 0) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if ((gBattleTypeFlags & BATTLE_TYPE_SAFARI) + && GetBattlerSide(gActiveBattler) == 0) + { + MEMSET_ALT(&gBattleMons[gActiveBattler], 0, 0x58, i, ptr); + } + else + { + u16 *hpOnSwitchout; + + 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); + + hpOnSwitchout = &gBattleStruct->HP_OnSwitchout[GetBattlerSide(gActiveBattler)]; + *hpOnSwitchout = gBattleMons[gActiveBattler].hp; + for (i = 0; i < 8; i++) + gBattleMons[gActiveBattler].statStages[i] = 6; + gBattleMons[gActiveBattler].status2 = 0; + } + + if (GetBattlerPosition(gActiveBattler) == 0) + { + BtlController_EmitDrawTrainerPic(0); + MarkBattlerForControllerExec(gActiveBattler); + } + + if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) + { + if (GetBattlerPosition(gActiveBattler) == 1) + { + BtlController_EmitDrawTrainerPic(0); + MarkBattlerForControllerExec(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); + BtlController_EmitLoadMonSprite(0); + MarkBattlerForControllerExec(gActiveBattler); + } + } + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + if (GetBattlerPosition(gActiveBattler) == 2 + || GetBattlerPosition(gActiveBattler) == 3) + { + BtlController_EmitDrawTrainerPic(0); + MarkBattlerForControllerExec(gActiveBattler); + } + } + } + gBattleMainFunc = bc_801333C; + } +} + +void bc_801333C(void) +{ + s32 i; + + if (gBattleControllerExecFlags == 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); + BtlController_EmitDrawPartyStatusSummary(0, hpStatus, 0x80); + MarkBattlerForControllerExec(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); + BtlController_EmitDrawPartyStatusSummary(0, hpStatus, 0x80); + MarkBattlerForControllerExec(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 (gBattleControllerExecFlags == 0) + { + gActiveBattler = GetBattlerAtPosition(1); + PrepareStringBattle(0, gActiveBattler); + gBattleMainFunc = sub_8011800; + } +} + +void bc_8013568(void) +{ + if (gBattleControllerExecFlags == 0) + { + gBattleMainFunc = sub_8011970; + PrepareStringBattle(0, 0); + } +} + +void sub_8011800(void) +{ + if (gBattleControllerExecFlags == 0) + { + PrepareStringBattle(1, GetBattlerAtPosition(1)); + gBattleMainFunc = sub_8011834; + } +} + +void sub_8011834(void) +{ + if (gBattleControllerExecFlags == 0) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (GetBattlerPosition(gActiveBattler) == 1) + { + BtlController_EmitIntroTrainerBallThrow(0); + MarkBattlerForControllerExec(gActiveBattler); + } + if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) + && GetBattlerPosition(gActiveBattler) == 3) + { + BtlController_EmitIntroTrainerBallThrow(0); + MarkBattlerForControllerExec(gActiveBattler); + } + } + gBattleMainFunc = bc_801362C; + } +} + +void bc_801362C(void) +{ + if (gBattleControllerExecFlags == 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 (gBattleControllerExecFlags == 0) + gBattleMainFunc = sub_8011970; +} + +void sub_8011970(void) +{ + if (gBattleControllerExecFlags == 0) + { + if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) + PrepareStringBattle(1, GetBattlerAtPosition(0)); + gBattleMainFunc = sub_80119B4; + } +} + +void sub_80119B4(void) +{ + if (gBattleControllerExecFlags == 0) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (GetBattlerPosition(gActiveBattler) == 0) + { + BtlController_EmitIntroTrainerBallThrow(0); + MarkBattlerForControllerExec(gActiveBattler); + } + if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) + && GetBattlerPosition(gActiveBattler) == 2) + { + BtlController_EmitIntroTrainerBallThrow(0); + MarkBattlerForControllerExec(gActiveBattler); + } + } + gBattleStruct->switchInAbilitiesCounter = 0; + gBattleStruct->unk160F9 = 0; + gBattleStruct->unk160E6 = 0; + gBattleMainFunc = BattleBeginFirstTurn; + } +} + +void unref_sub_8011A68(void) +{ + if (gBattleControllerExecFlags == 0) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (GetBattlerSide(gActiveBattler) == 0) + { + BtlController_EmitSwitchInAnim(0, gBattlerPartyIndexes[gActiveBattler], 0); + MarkBattlerForControllerExec(gActiveBattler); + } + } + gBattleStruct->switchInAbilitiesCounter = 0; + gBattleStruct->unk160F9 = 0; + gBattleStruct->unk160E6 = 0; + gBattleMainFunc = BattleBeginFirstTurn; + } +} + +void BattleBeginFirstTurn(void) +{ + s32 i; + s32 j; + u8 r9 = 0; + + if (gBattleControllerExecFlags == 0) + { + if (gBattleStruct->switchInAbilitiesCounter == 0) + { + for (i = 0; i < gBattlersCount; i++) + gBattlerByTurnOrder[i] = i; + for (i = 0; i < gBattlersCount - 1; i++) + { + for (j = i + 1; j < gBattlersCount; j++) + { + if (GetWhoStrikesFirst(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], 1) != 0) + SwapTurnOrder(i, j); + } + } + } + if (gBattleStruct->unk160E6 == 0 && AbilityBattleEffects(0, 0, 0, 0xFF, 0) != 0) + { + gBattleStruct->unk160E6 = 1; + return; + } + while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount) + { + if (AbilityBattleEffects(0, gBattlerByTurnOrder[gBattleStruct->switchInAbilitiesCounter], 0, 0, 0) != 0) + r9++; + gBattleStruct->switchInAbilitiesCounter++; + if (r9 != 0) + return; + } + if (AbilityBattleEffects(9, 0, 0, 0, 0) != 0) + return; + if (AbilityBattleEffects(11, 0, 0, 0, 0) != 0) + return; + while (gBattleStruct->unk160F9 < gBattlersCount) + { + if (ItemBattleEffects(0, gBattlerByTurnOrder[gBattleStruct->unk160F9], 0) != 0) + r9++; + gBattleStruct->unk160F9++; + 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++) + { + gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + i] = PARTY_SIZE; + gActionForBanks[i] = 0xFF; + gChosenMovesByBanks[i] = 0; + } + TurnValuesCleanUp(0); + SpecialStatusesClear(); + gBattleStruct->unk160A6 = gAbsentBattlerFlags; + gBattleMainFunc = sub_8012324; + ResetSentPokesToOpponentValue(); + for (i = 0; i < 8; i++) + gBattleCommunication[i] = 0; + for (i = 0; i < gBattlersCount; i++) + gBattleMons[i].status2 &= ~8; + gBattleStruct->turnEffectsTracker = 0; + gBattleStruct->turnEffectsBattlerId = 0; + gBattleStruct->wishPerishSongState = 0; + gBattleStruct->wishPerishSongBattlerId = 0; + gBattleStruct->cmd49StateTracker = 0; + gBattleStruct->faintedActionsState = 0; + gBattleStruct->turnCountersTracker = 0; + gMoveResultFlags = 0; + gRandomTurnNumber = Random(); + } +} + +void bc_8013B1C(void) +{ + s32 i; + + if (gBattleControllerExecFlags == 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); + } + gBattleStruct->turnEffectsTracker = 0; + gBattleStruct->turnEffectsBattlerId = 0; + gBattleStruct->wishPerishSongState = 0; + gBattleStruct->wishPerishSongBattlerId = 0; + gBattleStruct->turnCountersTracker = 0; + gMoveResultFlags = 0; + } +} + +void BattleTurnPassed(void) +{ + s32 i; + + TurnValuesCleanUp(1); + if (gBattleOutcome == 0) + { + if (DoFieldEndTurnEffects() != 0) + return; + if (TurnBasedEffects() != 0) + return; + } + if (HandleFaintedMonActions() != 0) + return; + gBattleStruct->faintedActionsState = 0; + if (HandleWishPerishSongOnTurnEnd() != 0) + return; + TurnValuesCleanUp(0); + gHitMarker &= ~HITMARKER_NO_ATTACKSTRING; + gHitMarker &= ~0x80000; + gHitMarker &= ~0x400000; + gHitMarker &= ~0x100000; + gBattleStruct->animTurn = 0; + gBattleStruct->animTargetsHit = 0; + gBattleStruct->cmd49StateTracker = 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++) + gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + i] = 6; + gBattleStruct->unk160A6 = 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); + gPotentialItemEffectBattler = 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) + { + gBattleStruct->scriptingActive = 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) + { + gBattleStruct->scriptingActive = 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)) + { + gBattleStruct->scriptingActive = 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++) + gBattlePartyCurrentOrder[i] = gSharedMem[BSTRUCT_OFF(unk1606C) + i + a * 3]; + r4 = pokemon_order_func(gBattlerPartyIndexes[a]); + r1 = pokemon_order_func(gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + a]); + sub_8094C98(r4, r1); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + for (i = 0; i < 3; i++) + { + gSharedMem[BSTRUCT_OFF(unk1606C) + i + a * 3] = gBattlePartyCurrentOrder[i]; + gSharedMem[BSTRUCT_OFF(unk1606C) + i + (a ^ BIT_FLANK) * 3] = + gBattlePartyCurrentOrder[i]; + } + } + else + { + for (i = 0; i < 3; i++) + { + gSharedMem[BSTRUCT_OFF(unk1606C) + i + a * 3] = gBattlePartyCurrentOrder[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 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: + gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + gActiveBattler] = 6; + if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) + && (position & BIT_FLANK) != B_FLANK_LEFT + && !(gBattleStruct->unk160A6 & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(position))]) + && gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(position))] != STATE_WAIT_ACTION_CONFIRMED) + break; + //_080123F8 + if (gBattleStruct->unk160A6 & 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 + { + BtlController_EmitChooseAction(0, gActionForBanks[0], gBattleBufferB[0][1] | (gBattleBufferB[0][2] << 8)); + MarkBattlerForControllerExec(gActiveBattler); + gBattleCommunication[gActiveBattler]++; + } + break; + case STATE_WAIT_ACTION_CHOSEN: + if (!(gBattleControllerExecFlags & ((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; + gSharedMem[BSTRUCT_OFF(selectionScriptFinished) + gActiveBattler] = FALSE; + gSharedMem[BSTRUCT_OFF(stateIdAfterSelScript) + gActiveBattler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY; + gSharedMem[BSTRUCT_OFF(moveTarget) + 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 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); + } + + BtlController_EmitChooseMove(0, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0, FALSE, (u8 *)&moveInfo); + MarkBattlerForControllerExec(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; + gSharedMem[BSTRUCT_OFF(selectionScriptFinished) + gActiveBattler] = FALSE; + gSharedMem[BSTRUCT_OFF(stateIdAfterSelScript) + gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; + return; + } + else + { + BtlController_EmitChooseItem(0, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); + MarkBattlerForControllerExec(gActiveBattler); + } + break; + case B_ACTION_SWITCH: + gSharedMem[BSTRUCT_OFF(unk16064) + gActiveBattler] = gBattlerPartyIndexes[gActiveBattler]; + if (gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION) + || gStatuses3[gActiveBattler] & STATUS3_ROOTED) + { + BtlController_EmitChoosePokemon(0, 2, 6, ABILITY_NONE, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); + } + 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))) + { + BtlController_EmitChoosePokemon(0, ((i - 1) << 4) | PARTY_ABILITY_PREVENTS, 6, gLastUsedAbility, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); + } + else + { + if (gActiveBattler == 2 && gActionForBanks[0] == B_ACTION_SWITCH) + BtlController_EmitChoosePokemon(0, PARTY_CHOOSE_MON, gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + 0], ABILITY_NONE, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); + else if (gActiveBattler == 3 && gActionForBanks[1] == B_ACTION_SWITCH) + BtlController_EmitChoosePokemon(0, PARTY_CHOOSE_MON, gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + 1], ABILITY_NONE, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); + else + BtlController_EmitChoosePokemon(0, PARTY_CHOOSE_MON, 6, ABILITY_NONE, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); + } + MarkBattlerForControllerExec(gActiveBattler); + break; + case B_ACTION_SAFARI_BALL: + if (PlayerPartyAndPokemonStorageFull()) + { + gSelectionBattleScripts[gActiveBattler] = BattleScript_PrintFullBox; + gBattleCommunication[gActiveBattler] = STATE_SELECTION_SCRIPT; + gSharedMem[BSTRUCT_OFF(selectionScriptFinished) + gActiveBattler] = FALSE; + gSharedMem[BSTRUCT_OFF(stateIdAfterSelScript) + gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; + return; + } + break; + case B_ACTION_SAFARI_POKEBLOCK: + BtlController_EmitChooseItem(0, &gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0]); + MarkBattlerForControllerExec(gActiveBattler); + break; + case B_ACTION_CANCEL_PARTNER: + gBattleCommunication[gActiveBattler] = STATE_WAIT_SET_BEFORE_ACTION; + gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gActiveBattler)))] = STATE_BEFORE_ACTION_CHOSEN; + BtlController_EmitEndBounceEffect(0); + MarkBattlerForControllerExec(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; + gSharedMem[BSTRUCT_OFF(selectionScriptFinished) + gActiveBattler] = FALSE; + gSharedMem[BSTRUCT_OFF(stateIdAfterSelScript) + gActiveBattler] = STATE_BEFORE_ACTION_CHOSEN; + return; + } + else + { + gBattleCommunication[gActiveBattler]++; + } + } + break; + case STATE_WAIT_ACTION_CASE_CHOSEN: + if (!(gBattleControllerExecFlags & ((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; + gSharedMem[BSTRUCT_OFF(selectionScriptFinished) + gActiveBattler] = FALSE; + gBattleBufferB[gActiveBattler][1] = 0; + gSharedMem[BSTRUCT_OFF(stateIdAfterSelScript) + gActiveBattler] = STATE_WAIT_ACTION_CHOSEN; + return; + } + else + { + gSharedMem[BSTRUCT_OFF(ChosenMoveID) + gActiveBattler] = gBattleBufferB[gActiveBattler][2]; + gChosenMovesByBanks[gActiveBattler] = gBattleMons[gActiveBattler].moves[gSharedMem[BSTRUCT_OFF(ChosenMoveID) + gActiveBattler]]; + gSharedMem[BSTRUCT_OFF(moveTarget) + 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 + { + gSharedMem[BSTRUCT_OFF(monToSwitchIntoId) + gActiveBattler] = gBattleBufferB[gActiveBattler][1]; + + if (gBattleTypeFlags & BATTLE_TYPE_MULTI) + { + gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0] &= 0xF; + gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 0] |= (gBattleBufferB[gActiveBattler][2] & 0xF0); + gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * gActiveBattler + 1] = gBattleBufferB[gActiveBattler][3]; + + gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * (gActiveBattler ^ BIT_FLANK) + 0] &= (0xF0); + gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * (gActiveBattler ^ BIT_FLANK) + 0] |= (gBattleBufferB[gActiveBattler][2] & 0xF0) >> 4; + gSharedMem[BSTRUCT_OFF(unk1606C) + 3 * (gActiveBattler ^ BIT_FLANK) + 2] = 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 (!(gBattleControllerExecFlags & ((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 + || (gBattleStruct->unk160A6 & gBitTable[GetBattlerAtPosition(position ^ BIT_FLANK)])) + { + BtlController_EmitLinkStandbyMsg(0, 0); + } + else + { + BtlController_EmitLinkStandbyMsg(0, 1); + } + MarkBattlerForControllerExec(gActiveBattler); + gBattleCommunication[gActiveBattler]++; + } + break; + case STATE_WAIT_ACTION_CONFIRMED: + if (!(gBattleControllerExecFlags & ((gBitTable[gActiveBattler]) | (0xF0000000) | (gBitTable[gActiveBattler] << 4) | (gBitTable[gActiveBattler] << 8) | (gBitTable[gActiveBattler] << 0xC)))) + { + gBattleCommunication[ACTIONS_CONFIRMED_COUNT]++; + } + break; + case STATE_SELECTION_SCRIPT: + if (gSharedMem[BSTRUCT_OFF(selectionScriptFinished) + gActiveBattler]) + { + gBattleCommunication[gActiveBattler] = gSharedMem[BSTRUCT_OFF(stateIdAfterSelScript) + gActiveBattler]; + } + else + { + gBattlerAttacker = gActiveBattler; + gBattlescriptCurrInstr = gSelectionBattleScripts[gActiveBattler]; + if (!(gBattleControllerExecFlags & ((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 (!(gBattleControllerExecFlags & ((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 = gBattlerByTurnOrder[a]; + gBattlerByTurnOrder[a] = gBattlerByTurnOrder[b]; + gBattlerByTurnOrder[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 & STATUS1_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 & STATUS1_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].noValidMoves) + bank1Move = MOVE_STRUGGLE; + else + bank1Move = gBattleMons[bank1].moves[gSharedMem[BSTRUCT_OFF(ChosenMoveID) + bank1]]; + } + else + bank1Move = MOVE_NONE; + + if (gActionForBanks[bank2] == 0) + { + if (gProtectStructs[bank2].noValidMoves) + bank2Move = MOVE_STRUGGLE; + else + bank2Move = gBattleMons[bank2].moves[gSharedMem[BSTRUCT_OFF(ChosenMoveID) + 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]; + gBattlerByTurnOrder[var] = gActiveBattler; + var++; + } + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (gActionForBanks[gActiveBattler] == B_ACTION_RUN) + { + var = 5; + break; + } + } + } + else + { + if (gActionForBanks[0] == B_ACTION_RUN) + { + gActiveBattler = 0; + var = 5; + } + } + + if (var == 5) + { + gActionsByTurnOrder[0] = gActionForBanks[gActiveBattler]; + gBattlerByTurnOrder[0] = gActiveBattler; + var = 1; + for (i = 0; i < gBattlersCount; i++) + { + if (i != gActiveBattler) + { + gActionsByTurnOrder[var] = gActionForBanks[i]; + gBattlerByTurnOrder[var] = i; + var++; + } + } + gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; + gBattleStruct->focusPunchBattler = 0; + return; + } + else + { + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (gActionForBanks[gActiveBattler] == B_ACTION_USE_ITEM || gActionForBanks[gActiveBattler] == B_ACTION_SWITCH) + { + gActionsByTurnOrder[var] = gActionForBanks[gActiveBattler]; + gBattlerByTurnOrder[var] = gActiveBattler; + var++; + } + } + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (gActionForBanks[gActiveBattler] != B_ACTION_USE_ITEM && gActionForBanks[gActiveBattler] != B_ACTION_SWITCH) + { + gActionsByTurnOrder[var] = gActionForBanks[gActiveBattler]; + gBattlerByTurnOrder[var] = gActiveBattler; + var++; + } + } + for (i = 0; i < gBattlersCount - 1; i++) + { + for (j = i + 1; j < gBattlersCount; j++) + { + u8 bank1 = gBattlerByTurnOrder[i]; + u8 bank2 = gBattlerByTurnOrder[j]; + if (gActionsByTurnOrder[i] != B_ACTION_USE_ITEM + && gActionsByTurnOrder[j] != B_ACTION_USE_ITEM + && gActionsByTurnOrder[i] != B_ACTION_SWITCH + && gActionsByTurnOrder[j] != B_ACTION_SWITCH) + { + if (GetWhoStrikesFirst(bank1, bank2, FALSE)) + SwapTurnOrder(i, j); + } + } + } + } + } + + gBattleMainFunc = CheckFocusPunch_ClearVarsBeforeTurnStarts; + gBattleStruct->focusPunchBattler = 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 (gBattleStruct->focusPunchBattler < gBattlersCount) + { + gActiveBattler = gBattlerAttacker = gBattleStruct->focusPunchBattler; + gBattleStruct->focusPunchBattler++; + if (gChosenMovesByBanks[gActiveBattler] == MOVE_FOCUS_PUNCH + && !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP) + && !(gDisableStructs[gBattlerAttacker].truantCounter) + && !(gProtectStructs[gActiveBattler].noValidMoves)) + { + 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; + gBattleStruct->multihitMoveEffect = 0; + B_BATTLESCRIPTS_STACK->size = 0; +} + +static void RunTurnActionsFunctions(void) +{ + if (gBattleOutcome != 0) + gCurrentActionFuncId = 12; + + gBattleStruct->savedTurnActionNumber = gCurrentTurnActionNumber; + gUnknown_081FA640[gCurrentActionFuncId](); + + if (gCurrentTurnActionNumber >= gBattlersCount) // everyone did their actions, turn finished + { + gHitMarker &= ~(HITMARKER_x100000); + gBattleMainFunc = gUnknown_081FA678[gBattleOutcome & 0x7F]; + } + else + { + if (gBattleStruct->savedTurnActionNumber != 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; + gBattlerAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + gBattlescriptCurrInstr = BattleScript_LinkBattleWonOrLost; + gBattleOutcome &= ~(B_OUTCOME_LINK_BATTLE_RAN); + } + 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_VICTORY_LEAGUE); + 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_VICTORY_AQUA_MAGMA); + break; + case TRAINER_CLASS_LEADER: + PlayBGM(MUS_VICTORY_GYM_LEADER); + break; + default: + PlayBGM(MUS_VICTORY_TRAINER); + break; + } + } + else + { + gBattlescriptCurrInstr = BattleScript_PayDayMoneyAndPickUpItems; + } + + gBattleMainFunc = HandleEndTurn_FinishBattle; +} + +void HandleEndTurn_BattleLost(void) +{ + gCurrentActionFuncId = 0; + + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gBattleTextBuff1[0] = gBattleOutcome; + gBattlerAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + gBattlescriptCurrInstr = BattleScript_LinkBattleWonOrLost; + gBattleOutcome &= ~(B_OUTCOME_LINK_BATTLE_RAN); + } + else + { + gBattlescriptCurrInstr = BattleScript_LocalBattleLost; + } + + gBattleMainFunc = HandleEndTurn_FinishBattle; +} + +void HandleEndTurn_RanFromBattle(void) +{ + gCurrentActionFuncId = 0; + + switch (gProtectStructs[gBattlerAttacker].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, gBattlerAttacker, gBattlerPartyIndexes[gBattlerAttacker]); + 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 (gBattleControllerExecFlags == 0) + gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); + } +} + +static void FreeResetData_ReturnToOvOrDoEvolutions(void) +{ + if (!gPaletteFade.active) + { + ResetSpriteData(); + if (gLeveledUpInBattle == 0 || gBattleOutcome != B_OUTCOME_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 == B_OUTCOME_WON || gBattleOutcome == B_OUTCOME_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 (gBattleControllerExecFlags == 0) + gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); + } +} + +void RunBattleScriptCommands(void) +{ + if (gBattleControllerExecFlags == 0) + gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); +} diff --git a/src/battle_message.c b/src/battle_message.c index d8aa92fbf5..777b98d84b 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -173,7 +173,6 @@ 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}; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 46000157c6..99781e6d3d 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -40,14 +40,12 @@ 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 gBattleControllerExecFlags; extern u8 gBattlersCount; extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT]; extern u8 gBattlerByTurnOrder[MAX_BATTLERS_COUNT]; -extern u8 gActionsByTurnOrder[MAX_BATTLERS_COUNT]; extern u16 gCurrentMove; extern u8 gLastUsedAbility; extern u16 gBattleWeather; @@ -72,9 +70,6 @@ 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 gPotentialItemEffectBattler; extern u16 gDynamicBasePower; extern const u8 gTypeEffectiveness[]; @@ -105,10 +100,8 @@ struct TrainerReward extern const struct TrainerReward gTrainerMoney[]; extern u16 gRandomMove; -extern u8* gBattleScriptsForMoveEffects[]; extern u16 gChosenMove; //last used move in battle extern u8 gBankInMenu; -extern u8 gActionForBanks[4]; extern u16 gLastPrintedMoves[4]; //last used moves 2, used by sketch extern u16 gLastResultingMoves[4]; //last used moves by banks, another one extern u8 gCurrentTurnActionNumber; diff --git a/src/battle_util.c b/src/battle_util.c index 136195e7f6..2da20b60bc 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1,8 +1,10 @@ #include "global.h" #include "battle.h" +#include "battle_ai_switch_items.h" #include "battle_util.h" #include "battle_controllers.h" #include "battle_message.h" +#include "battle_string_ids.h" #include "data2.h" #include "event_data.h" #include "ewram.h" @@ -12,6 +14,7 @@ #include "pokemon.h" #include "random.h" #include "rom_8077ABC.h" +#include "sound.h" #include "string_util.h" #include "text.h" #include "util.h" @@ -21,18 +24,20 @@ #include "constants/hold_effects.h" #include "constants/items.h" #include "constants/moves.h" +#include "constants/songs.h" #include "constants/species.h" #include "constants/weather.h" extern u8 gUnknown_02023A14_50; - +extern u8 gUnknown_081FA71F[]; +extern u8 gUnknown_081FA71B[]; +extern u8 gUnknown_081FA70C[][3]; 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 gLastMoves[4]; extern struct BattlePokemon gBattleMons[4]; -extern struct BattleEnigmaBerry gEnigmaBerries[4]; extern u8 gPotentialItemEffectBattler; extern u16 gLastUsedItem; extern u16 gCurrentMove; @@ -47,7 +52,6 @@ extern u16 gSideStatuses[2]; extern u16 gBattleWeather; extern void (*gBattleMainFunc)(void); extern u8 gAbsentBattlerFlags; -extern u8 gBattleCommunication[]; extern u32 gHitMarker; extern u8 gEffectBattler; extern u8 gBank1; @@ -209,6 +213,534 @@ extern u8 gUnknown_081D99A0[]; //disobedient, hits itself #define MULTISTRING_CHOOSER 0x5 #define MSG_DISPLAY 0x7 +void HandleAction_UseMove(void) +{ + u8 side; + u8 var = 4; + + gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; + + if (gBattleStruct->unk160A6 & gBitTable[gBattlerAttacker]) + { + gCurrentActionFuncId = B_ACTION_FINISHED; + return; + } + + gCritMultiplier = 1; + gBattleStruct->dmgMultiplier = 1; + gBattleStruct->atkCancellerTracker = 0; + gMoveResultFlags = 0; + gMultiHitCounter = 0; + gBattleCommunication[6] = 0; + gCurrMovePos = gUnknown_02024BE5 = gSharedMem[BSTRUCT_OFF(ChosenMoveID) + gBattlerAttacker]; + + // choose move + if (gProtectStructs[gBattlerAttacker].noValidMoves) + { + gProtectStructs[gBattlerAttacker].noValidMoves = 0; + gCurrentMove = gChosenMove = MOVE_STRUGGLE; + gHitMarker |= HITMARKER_NO_PPDEDUCT; + gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker] = GetMoveTarget(MOVE_STRUGGLE, 0); + } + else if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS || gBattleMons[gBattlerAttacker].status2 & STATUS2_RECHARGE) + { + gCurrentMove = gChosenMove = gLockedMoves[gBattlerAttacker]; + } + // encore forces you to use the same move + else if (gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE + && gDisableStructs[gBattlerAttacker].encoredMove == gBattleMons[gBattlerAttacker].moves[gDisableStructs[gBattlerAttacker].encoredMovePos]) + { + gCurrentMove = gChosenMove = gDisableStructs[gBattlerAttacker].encoredMove; + gCurrMovePos = gUnknown_02024BE5 = gDisableStructs[gBattlerAttacker].encoredMovePos; + gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker] = GetMoveTarget(gCurrentMove, 0); + } + // check if the encored move wasn't overwritten + else if (gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE + && gDisableStructs[gBattlerAttacker].encoredMove != gBattleMons[gBattlerAttacker].moves[gDisableStructs[gBattlerAttacker].encoredMovePos]) + { + gCurrMovePos = gUnknown_02024BE5 = gDisableStructs[gBattlerAttacker].encoredMovePos; + gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; + gDisableStructs[gBattlerAttacker].encoredMove = MOVE_NONE; + gDisableStructs[gBattlerAttacker].encoredMovePos = 0; + gDisableStructs[gBattlerAttacker].encoreTimer1 = 0; + gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker] = GetMoveTarget(gCurrentMove, 0); + } + else if (gBattleMons[gBattlerAttacker].moves[gCurrMovePos] != gChosenMovesByBanks[gBattlerAttacker]) + { + gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; + gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker] = GetMoveTarget(gCurrentMove, 0); + } + else + { + gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; + } + + if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) + gBattleResults.lastUsedMove = gCurrentMove; + else + gBattleResults.opponentMove = gCurrentMove; + + // choose target + side = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE; + if (gSideTimers[side].followmeTimer != 0 + && gBattleMoves[gCurrentMove].target == MOVE_TARGET_SELECTED + && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gSideTimers[side].followmeTarget) + && gBattleMons[gSideTimers[side].followmeTarget].hp != 0) + { + gBattlerTarget = gSideTimers[side].followmeTarget; + } + else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + && gSideTimers[side].followmeTimer == 0 + && (gBattleMoves[gCurrentMove].power != 0 + || gBattleMoves[gCurrentMove].target != MOVE_TARGET_USER) + && gBattleMons[gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker]].ability != ABILITY_LIGHTNING_ROD + && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC) + { + side = GetBattlerSide(gBattlerAttacker); + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (side != GetBattlerSide(gActiveBattler) + && gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker] != gActiveBattler + && gBattleMons[gActiveBattler].ability == ABILITY_LIGHTNING_ROD + && GetBattlerTurnOrderNum(gActiveBattler) < var) + { + var = GetBattlerTurnOrderNum(gActiveBattler); + } + } + if (var == 4) + { + if (gBattleMoves[gChosenMove].target & MOVE_TARGET_RANDOM) + { + if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) + { + if (Random() & 1) + gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + else + gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); + } + else + { + if (Random() & 1) + gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + else + gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); + } + } + else + { + gBattlerTarget = gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker]; + } + + if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) + { + if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) + { + gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK); + } + else + { + gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_SIDE); + if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) + gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK); + } + } + } + else + { + gActiveBattler = gBattlerByTurnOrder[var]; + RecordAbilityBattle(gActiveBattler, gBattleMons[gActiveBattler].ability); + gSpecialStatuses[gActiveBattler].lightningRodRedirected = 1; + gBattlerTarget = gActiveBattler; + } + } + else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && gBattleMoves[gChosenMove].target & MOVE_TARGET_RANDOM) + { + if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) + { + if (Random() & 1) + gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + else + gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); + } + else + { + if (Random() & 1) + gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + else + gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); + } + + if (gAbsentBattlerFlags & gBitTable[gBattlerTarget] + && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) + { + gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK); + } + } + else + { + gBattlerTarget = gSharedMem[BSTRUCT_OFF(moveTarget) + gBattlerAttacker]; + if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) + { + if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) + { + gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK); + } + else + { + gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerAttacker) ^ BIT_SIDE); + if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) + gBattlerTarget = GetBattlerAtPosition(GetBattlerPosition(gBattlerTarget) ^ BIT_FLANK); + } + } + } + + gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]; + gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; +} + +void HandleAction_Switch(void) +{ + gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gActionSelectionCursor[gBattlerAttacker] = 0; + gMoveSelectionCursor[gBattlerAttacker] = 0; + + PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBattlerAttacker, gSharedMem[BSTRUCT_OFF(unk16064) + gBattlerAttacker]) + + gBattleStruct->scriptingActive = gBattlerAttacker; + gBattlescriptCurrInstr = BattleScript_ActionSwitch; + gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; + + if (gBattleResults.totalMonSwitchCounter < 255) + gBattleResults.totalMonSwitchCounter++; +} + +void HandleAction_UseItem(void) +{ + gBattlerAttacker = gBattlerTarget = gBattlerByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gDisableStructs[gBattlerAttacker].furyCutterCounter = 0; + gLastUsedItem = gBattleBufferB[gBattlerAttacker][1] | (gBattleBufferB[gBattlerAttacker][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(gBattlerAttacker) == B_SIDE_PLAYER) + { + gBattlescriptCurrInstr = gBattlescriptsForUsingItem[0]; + } + else + { + gBattleStruct->scriptingActive = gBattlerAttacker; + + switch (gSharedMem[BSTRUCT_OFF(AI_usedItemType) + (gBattlerAttacker >> 1)]) + { + case AI_ITEM_FULL_RESTORE: + case AI_ITEM_HEAL_HP: + break; + case AI_ITEM_CURE_CONDITION: + gBattleCommunication[MULTISTRING_CHOOSER] = AI_HEAL_CONFUSION; + if (gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] & (1 << AI_HEAL_CONFUSION)) + { + if (gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] & ((1 << AI_HEAL_PARALYSIS) + | (1 << AI_HEAL_FREEZE) + | (1 << AI_HEAL_BURN) + | (1 << AI_HEAL_POISON) + | (1 << AI_HEAL_SLEEP))) + gBattleCommunication[MULTISTRING_CHOOSER] = AI_HEAL_SLEEP; + } + else + { + while (!(gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] & 1)) + { + gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] >>= 1; + gBattleCommunication[MULTISTRING_CHOOSER]++; + } + } + break; + case AI_ITEM_X_STAT: + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + if (gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] & (1 << AI_DIRE_HIT)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 5; + } + else + { + PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK) + PREPARE_STRING_BUFFER(gBattleTextBuff2, STRINGID_STATROSE) + + while (!(gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] & 1)) + { + gSharedMem[BSTRUCT_OFF(AI_usedItemEffect) + (gBattlerAttacker >> 1)] >>= 1; + gBattleTextBuff1[2]++; + } + + gBattleStruct->animArg1 = gBattleTextBuff1[2] + 14; + gBattleStruct->animArg2 = 0; + } + break; + case AI_ITEM_GUARD_SPEC: + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + gBattleCommunication[MULTISTRING_CHOOSER] = 2; + else + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + break; + } + + gBattlescriptCurrInstr = gBattlescriptsForUsingItem[gSharedMem[BSTRUCT_OFF(AI_usedItemType) + (gBattlerAttacker / 2)]]; + } + gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; +} + +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); + + gPotentialItemEffectBattler = 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) + (gBattleStruct->runTries * 30); + if (speedVar > (Random() & 0xFF)) + effect++; + } + else // same speed or faster + { + effect++; + } + } + + gBattleStruct->runTries++; + } + + if (effect) + { + gCurrentTurnActionNumber = gBattlersCount; + gBattleOutcome = B_OUTCOME_RAN; + } + + return effect; +} + +void HandleAction_Run(void) +{ + gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; + + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gCurrentTurnActionNumber = gBattlersCount; + + for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++) + { + if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) + { + if (gActionForBanks[gActiveBattler] == B_ACTION_RUN) + gBattleOutcome |= B_OUTCOME_LOST; + } + else + { + if (gActionForBanks[gActiveBattler] == B_ACTION_RUN) + gBattleOutcome |= B_OUTCOME_WON; + } + } + + gBattleOutcome |= B_OUTCOME_LINK_BATTLE_RAN; + } + else + { + if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) + { + if (!TryRunFromBattle(gBattlerAttacker)) // failed to run away + { + gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_DESTINY_BOND; + gBattleCommunication[MULTISTRING_CHOOSER] = 3; + gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString; + gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; + } + } + else + { + if (gBattleMons[gBattlerAttacker].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = 4; + gBattlescriptCurrInstr = BattleScript_PrintFailedToRunString; + gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; + } + else + { + gCurrentTurnActionNumber = gBattlersCount; + gBattleOutcome = B_OUTCOME_MON_FLED; + } + } + } +} + +void HandleAction_WatchesCarefully(void) +{ + gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gBattlescriptCurrInstr = gBattlescriptsForSafariActions[0]; + gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; +} + +void HandleAction_SafariZoneBallThrow(void) +{ + gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gNumSafariBalls--; + gLastUsedItem = ITEM_SAFARI_BALL; + gBattlescriptCurrInstr = gBattlescriptsForBallThrow[ITEM_SAFARI_BALL]; + gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; +} + +void HandleAction_ThrowPokeblock(void) +{ + gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + gBattleCommunication[MULTISTRING_CHOOSER] = gBattleBufferB[gBattlerAttacker][1] - 1; + gLastUsedItem = gBattleBufferB[gBattlerAttacker][2]; + + if (gBattleStruct->safariPkblThrowCounter < 3) + gBattleStruct->safariPkblThrowCounter++; + if (gBattleStruct->safariFleeRate > 1) + { + if (gBattleStruct->safariFleeRate < gUnknown_081FA70C[gBattleStruct->safariPkblThrowCounter][gBattleCommunication[MULTISTRING_CHOOSER]]) + gBattleStruct->safariFleeRate = 1; + else + gBattleStruct->safariFleeRate -= gUnknown_081FA70C[gBattleStruct->safariPkblThrowCounter][gBattleCommunication[MULTISTRING_CHOOSER]]; + } + + gBattlescriptCurrInstr = gBattlescriptsForSafariActions[2]; + gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; +} + +void HandleAction_GoNear(void) +{ + gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + + gBattleStruct->safariCatchFactor += gUnknown_081FA71B[gBattleStruct->safariGoNearCounter]; + if (gBattleStruct->safariCatchFactor > 20) + gBattleStruct->safariCatchFactor = 20; + + gBattleStruct->safariFleeRate += gUnknown_081FA71F[gBattleStruct->safariGoNearCounter]; + if (gBattleStruct->safariFleeRate > 20) + gBattleStruct->safariFleeRate = 20; + + if (gBattleStruct->safariGoNearCounter < 3) + { + gBattleStruct->safariGoNearCounter++; + gBattleCommunication[MULTISTRING_CHOOSER] = 0; + } + else + { + gBattleCommunication[MULTISTRING_CHOOSER] = 1; + } + gBattlescriptCurrInstr = gBattlescriptsForSafariActions[1]; + gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; +} + +void HandleAction_SafriZoneRun(void) +{ + gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; + PlaySE(SE_FLEE); + gCurrentTurnActionNumber = gBattlersCount; + gBattleOutcome = B_OUTCOME_RAN; +} + +void HandleAction_Action9(void) +{ + gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; + gBattle_BG0_X = 0; + gBattle_BG0_Y = 0; + + PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattlerPartyIndexes[gBattlerAttacker]) + + gBattlescriptCurrInstr = gBattlescriptsForSafariActions[3]; + gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; + gActionsByTurnOrder[1] = B_ACTION_FINISHED; +} + +void HandleAction_Action11(void) +{ + if (!HandleFaintedMonActions()) + { + gBattleStruct->faintedActionsState = 0; + gCurrentActionFuncId = B_ACTION_FINISHED; + } +} + +void HandleAction_NothingIsFainted(void) +{ + gCurrentTurnActionNumber++; + gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber]; + gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED + | HITMARKER_NO_PPDEDUCT | HITMARKER_STATUS_ABILITY_EFFECT | HITMARKER_IGNORE_ON_AIR + | HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000 + | HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT + | HITMARKER_CHARGING | HITMARKER_x4000000); +} + +void HandleAction_ActionFinished(void) +{ + gCurrentTurnActionNumber++; + gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber]; + SpecialStatusesClear(); + gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED + | HITMARKER_NO_PPDEDUCT | HITMARKER_STATUS_ABILITY_EFFECT | HITMARKER_IGNORE_ON_AIR + | HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000 + | HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT + | HITMARKER_CHARGING | HITMARKER_x4000000); + + gBattleMoveDamage = 0; + gBattleStruct->animTurn = 0; + gBattleStruct->animTargetsHit = 0; + gLastLandedMoves[gBattlerAttacker] = 0; + gLastHitByType[gBattlerAttacker] = 0; + gBattleStruct->dynamicMoveType = 0; + gDynamicBasePower = 0; + gBattleStruct->cmd49StateTracker = 0; + gBattleCommunication[3] = 0; + gBattleCommunication[4] = 0; + gBattleStruct->multihitMoveEffect = 0; + B_BATTLESCRIPTS_STACK->size = 0; +} + u8 GetBattlerForBattleScript(u8 caseId) { u8 ret = 0; diff --git a/src/calculate_base_damage.c b/src/calculate_base_damage.c index c15b94d8f5..66c4e81ad0 100644 --- a/src/calculate_base_damage.c +++ b/src/calculate_base_damage.c @@ -18,7 +18,6 @@ extern struct BattlePokemon gBattleMons[4]; extern u16 gCurrentMove; extern u8 gCritMultiplier; extern u16 gBattleWeather; -extern struct BattleEnigmaBerry gEnigmaBerries[]; extern u16 gBattleMovePower; extern u16 gTrainerBattleOpponent; diff --git a/src/debug/battle.c b/src/debug/battle.c new file mode 100644 index 0000000000..f050dcaac8 --- /dev/null +++ b/src/debug/battle.c @@ -0,0 +1,1727 @@ +#include "global.h" +#include "battle.h" +#include "battle_message.h" +#include "data2.h" +#include "decompress.h" +#include "evolution_scene.h" +#include "ewram.h" +#include "item.h" +#include "item_menu.h" +#include "m4a.h" +#include "palette.h" +#include "pokeblock.h" +#include "random.h" +#include "safari_zone.h" +#include "scanline_effect.h" +#include "sound.h" +#include "string_util.h" +#include "task.h" +#include "text.h" +#include "gba/flash_internal.h" +#include "gba/m4a_internal.h" +#include "constants/items.h" +#include "constants/songs.h" + +#if DEBUG + +EWRAM_DATA u32 gUnknown_02023A14_4C = 0; +EWRAM_DATA u8 gUnknown_02023A14_50 = 0; +EWRAM_DATA s16 gUnknown_Debug_2023A76[2][35] = {0}; +EWRAM_DATA s16 gUnknown_Debug_2023B02[2][6][4] = {0}; +EWRAM_DATA u8 gUnknown_Debug_2023B62[418] = {0}; // TODO: NUM_SPECIES? + +extern const u8 Str_821F7BD[]; +extern const u8 Str_821F7DA[]; +extern const u8 Str_821F7B8[]; +extern const u8 Str_821F7EA[]; +extern const u8 BattleText_YesNo[]; +extern struct Window gWindowTemplate_Contest_MoveDescription; +extern struct SpriteTemplate gCreatingSpriteTemplate; +extern const u8 gUnknown_Debug_821F7F3[]; +extern void sub_802BBD4(u8 r0, u8 r1, u8 r2, u8 r3, u8 sp0); + +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_ShowCurrentAnimAudioOptions(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); + +u8 gUnknown_Debug_03004360; +struct Window gUnknown_Debug_03004370; +u8 gUnknown_Debug_030043A0; +u8 gUnknown_Debug_030043A4; +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 gDebugBattleCharmap_Gfx_lz[]; +extern const u8 gDebugBattleCharmap_Tilemap_lz[]; +extern const u8 gDebugBattleCharmap_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(gDebugBattleCharmap_Gfx_lz, (void *)VRAM); + LZDecompressWram(gDebugBattleCharmap_Tilemap_lz, gSharedMem); + LZDecompressVram(gDebugBattleCharmap_Pal_lz, (void *)PLTT); + LZDecompressVram(gDebugBattleCharmap_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_ShowCurrentAnimAudioOptions(); + 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] = B_BUFF_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_ShowCurrentAnimAudioOptions(); + } + } + 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_ShowCurrentAnimAudioOptions(); + 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_ShowCurrentAnimAudioOptions(); + 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_ShowCurrentAnimAudioOptions(); + 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_ShowCurrentAnimAudioOptions(); + 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) + gBattleStruct->unk160A3 = gUnknown_Debug_2023A76[0][2] - 2; + else + gBattleStruct->unk160A3 = 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: +// TODO: check other revisions +#if (ENGLISH && REVISION == 0) + debug_sub_8010A7C(0, 8); +#else + debug_sub_8010A7C(0, 20); +#endif + 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); +// TODO: check other revisions +#if !(ENGLISH && REVISION == 0) + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + 422, + gUnknown_Debug_03004360 * 32 + 25, + 0); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + gBattleTextBuff1[0] = B_BUFF_EOS; +#endif + 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: +// TODO: check other revisions +#if (ENGLISH && REVISION == 0) + debug_sub_8010A7C(0, 11); +#else + debug_sub_8010A7C(0, 24); +#endif + 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); +// TODO: check other revisions +#if !(ENGLISH && REVISION == 0) + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + 422, + gUnknown_Debug_03004360 * 32 + 25, + 0); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + gBattleTextBuff1[0] = B_BUFF_EOS; +#endif + 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: +// TODO: check other revisions +#if (ENGLISH && REVISION == 0) + debug_sub_8010A7C(0, 2); +#else + debug_sub_8010A7C(0, 4); +#endif + 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] = B_BUFF_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) + { +// TODO: check other revisions +#if (ENGLISH && REVISION == 0) + debug_sub_8010A7C(0, 10); +#else + debug_sub_8010A7C(0, 24); +#endif + 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); +// TODO: check other revisions +#if !(ENGLISH && REVISION == 0) + Text_InitWindow( + &gUnknown_Debug_03004370, + gBattleTextBuff1, + 422, + gUnknown_Debug_03004360 * 32 + 25, + 0); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + gBattleTextBuff1[0] = B_BUFF_EOS; +#endif + 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) + { +// TODO: check other revisions +#if (ENGLISH && REVISION == 0) + debug_sub_8010A7C(0, 7); +#else + debug_sub_8010A7C(0, 18); +#endif + 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); +// TODO: check other revisions +#if (ENGLISH && REVISION == 0) + debug_sub_8010A7C(0, 7); +#else + debug_sub_8010A7C(0, 18); +#endif + 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); +} + +// TODO: check other revisions +#if (ENGLISH && REVISION == 0) +extern const u8 Str_821F64D[]; +extern const u8 Str_821F652[]; +extern const u8 Str_821F655[]; +extern const u8 Str_821F65A[]; +#endif + +void debug_ShowCurrentAnimAudioOptions(void) +{ +// TODO: check other revisions +#if (ENGLISH && REVISION == 0) + if (gSaveBlock2.optionsBattleSceneOff) + Text_InitWindow( + &gUnknown_Debug_03004370, + Str_821F652, + 418, + gUnknown_Debug_03004360 * 32 + 21, + 0); + else + Text_InitWindow( + &gUnknown_Debug_03004370, + Str_821F64D, + 418, + gUnknown_Debug_03004360 * 32 + 21, + 0); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); + + if (gSaveBlock2.optionsSound) + Text_InitWindow( + &gUnknown_Debug_03004370, + Str_821F65A, + 422, + gUnknown_Debug_03004360 * 32 + 24, + 0); + else + Text_InitWindow( + &gUnknown_Debug_03004370, + Str_821F655, + 422, + gUnknown_Debug_03004360 * 32 + 24, + 0); + Text_PrintWindow8002F44(&gUnknown_Debug_03004370); +#endif +} + +extern const u32 gUnknown_Debug_821F680[][0x23]; + +// Shows a cursor +void debug_sub_80125A0(void) +{ + gSharedMem[gUnknown_Debug_821F680[gUnknown_Debug_03004360][gUnknown_Debug_030043A0 + gUnknown_Debug_030043A4 * 5]] = 0x6D; +} + +// Hides a cursor +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(&gWindowTemplate_Contest_MoveDescription, &gWindowTemplate_81E6C58); + DecompressPicFromTable_2( + &gMonFrontPicTable[gCurrentMove], + gMonFrontPicCoords[gCurrentMove].coords, + gMonFrontPicCoords[gCurrentMove].y_offset, + (void *)EWRAM, + gMonSpriteGfx_Sprite_ptr[1], + gCurrentMove); + LoadCompressedPalette(gMonPaletteTable[gCurrentMove].data, 272, 32); + GetMonSpriteTemplate_803C56C(gCurrentMove, 1); + spriteId = CreateSprite(&gCreatingSpriteTemplate, 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(&gWindowTemplate_Contest_MoveDescription); + 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(&gWindowTemplate_Contest_MoveDescription, gBattleTextBuff1, 144, 2, 35); + Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); + ConvertIntToDecimalStringN(gBattleTextBuff1, gCurrentMove, 2, 3); + gBattleTextBuff1[3] = CHAR_SPACE; + gBattleTextBuff1[4] = B_BUFF_EOS; + StringAppend(gBattleTextBuff1, gSpeciesNames[gCurrentMove]); + Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, gBattleTextBuff1, 144, 2, 35); + Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); +} + +void debug_sub_8012938(u8 taskId) +{ + debug_sub_8010A7C(0, 7); + Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, gBattleTextBuff1, 162, 2, 37); + Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); + StringCopy(gBattleTextBuff1, Str_821F7B8); + ConvertIntToDecimalStringN(gBattleTextBuff1 + 4, gUnknown_Debug_2023B62[gCurrentMove - 1], 2, 3); + Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, gBattleTextBuff1, 162, 2, 37); + Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); + gSprites[gTasks[taskId].data[1]].y2 = -gUnknown_Debug_2023B62[gCurrentMove - 1]; +} + +void debug_sub_80129F8(u8 taskId) +{ + DecompressPicFromTable_2( + &gMonFrontPicTable[gCurrentMove], + gMonFrontPicCoords[gCurrentMove].coords, + gMonFrontPicCoords[gCurrentMove].y_offset, + (void *)EWRAM, + gMonSpriteGfx_Sprite_ptr[1], + gCurrentMove); + LoadCompressedPalette(gMonPaletteTable[gCurrentMove].data, 272, 32); + gSprites[gTasks[taskId].data[1]].y = gMonFrontPicCoords[gCurrentMove].y_offset + 40; + gSprites[gTasks[taskId].data[1]].y2 = -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(&gWindowTemplate_Contest_MoveDescription, Str_821F7DA, 656, 26, 29); + Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); + gTasks[taskId].data[3] = 0; + debug_sub_8012B2C(0); + } +} + +void debug_sub_8012C08(u8 taskId, u8 b) +{ + debug_sub_8010A7C(0, 9); + Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, gBattleTextBuff1, 144, 2, 35); + Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); + debug_sub_8010A7C(0, 7); + Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, gBattleTextBuff1, 162, 2, 37); + Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); + sub_802BBD4(24, 28, 29, 33, 0); + if (b != 0) + { + gTasks[taskId].data[0] = 4; + Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, gUnknown_Debug_821F7F3, 144, 2, 35); + } + else + { + gTasks[taskId].data[0] = 3; + Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, Str_821F7EA, 144, 2, 35); + } + Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); + Text_InitWindow(&gWindowTemplate_Contest_MoveDescription, BattleText_YesNo, 656, 26, 29); + Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); + 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(&gWindowTemplate_Contest_MoveDescription, Str_821F7BD, 400, 19, 35); + Text_PrintWindow8002F44(&gWindowTemplate_Contest_MoveDescription); + 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 // DEBUG diff --git a/src/debug/watanabe_debug_menu.c b/src/debug/watanabe_debug_menu.c index aefd85bb2f..3b89a51ebc 100644 --- a/src/debug/watanabe_debug_menu.c +++ b/src/debug/watanabe_debug_menu.c @@ -99,8 +99,6 @@ EWRAM_DATA struct WatanabeEwram18000_2 * gUnknown_Debug_2038A20 = NULL; u32 byte_3005E30; -extern s8 gBattleTerrain; - void debug_80C3A50(u8 taskId); void debug_80C3D2C(u8 taskId); void debug_80C4214(u8); diff --git a/src/evolution_scene.c b/src/evolution_scene.c index ac30d2c3f2..39a64fed53 100644 --- a/src/evolution_scene.c +++ b/src/evolution_scene.c @@ -73,7 +73,6 @@ extern bool8 gAffineAnimsDisabled; extern u8 gDisplayedStringBattle[]; extern u8 gBattleTextBuff2[]; -extern u8 gBattleCommunication[]; #define sEvoCursorPos gBattleCommunication[1] // when learning a new move #define sEvoGraphicsTaskID gBattleCommunication[2] diff --git a/src/pokemon_2.c b/src/pokemon_2.c index db31ec47a6..82b9fe0262 100644 --- a/src/pokemon_2.c +++ b/src/pokemon_2.c @@ -31,7 +31,6 @@ extern u8 gBattlerTarget; extern u8 gAbsentBattlerFlags; extern u8 gXXX_CritRelated; extern u16 gBattleWeather; -extern struct BattleEnigmaBerry gEnigmaBerries[]; extern u16 gBattleMovePower; extern u16 gTrainerBattleOpponent; extern struct PokemonStorage gPokemonStorage; diff --git a/src/pokemon_3.c b/src/pokemon_3.c index 43c9b0d41f..e4d991138d 100644 --- a/src/pokemon_3.c +++ b/src/pokemon_3.c @@ -32,7 +32,6 @@ extern u8 gPlayerPartyCount; extern u8 gEnemyPartyCount; extern struct BattlePokemon gBattleMons[4]; extern u8 gActiveBattler; -extern struct BattleEnigmaBerry gEnigmaBerries[]; extern u16 gSpeciesToHoennPokedexNum[]; extern u16 gSpeciesToNationalPokedexNum[]; extern u16 gHoennToNationalOrder[]; diff --git a/src/pokemon_item_effect.c b/src/pokemon_item_effect.c index 2a2e73dc01..fd4baa6679 100644 --- a/src/pokemon_item_effect.c +++ b/src/pokemon_item_effect.c @@ -24,7 +24,6 @@ extern u16 gBattlerPartyIndexes[]; extern u8 gActiveBattler; extern u8 gPotentialItemEffectBattler; extern struct BattlePokemon gBattleMons[]; -extern struct BattleEnigmaBerry gEnigmaBerries[]; static const u8 sGetMonDataEVConstants[] = { diff --git a/sym_ewram.txt b/sym_ewram.txt index 7799708ef6..8e5ccf72c1 100644 --- a/sym_ewram.txt +++ b/sym_ewram.txt @@ -4,7 +4,9 @@ .include "src/string_util.o" .include "src/link.o" .include "src/battle_controllers.o" - .include "src/battle_main.o" + .include "src/battle_main1.o" + .include "src/debug/battle.o" + .include "src/battle_main2.o" .include "src/pokemon_1.o" .include "src/pokemon_2.o" .include "src/load_save.o"