summaryrefslogtreecommitdiff
path: root/src/battle_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/battle_main.c')
-rw-r--r--src/battle_main.c801
1 files changed, 54 insertions, 747 deletions
diff --git a/src/battle_main.c b/src/battle_main.c
index 935a53ffe..29a8f560a 100644
--- a/src/battle_main.c
+++ b/src/battle_main.c
@@ -11,6 +11,7 @@
#include "battle_scripts.h"
#include "battle_setup.h"
#include "battle_tower.h"
+#include "battle_util.h"
#include "berry.h"
#include "bg.h"
#include "data.h"
@@ -57,7 +58,6 @@
#include "constants/party_menu.h"
#include "constants/rgb.h"
#include "constants/songs.h"
-#include "constants/species.h"
#include "constants/trainers.h"
#include "cable_club.h"
@@ -66,11 +66,6 @@ extern struct MusicPlayerInfo gMPlayInfo_SE2;
extern const struct BgTemplate gBattleBgTemplates[];
extern const struct WindowTemplate *const gBattleWindowTemplates[];
-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[];
// this file's functions
#if !defined(NONMATCHING) && MODERN
@@ -99,7 +94,6 @@ static void SpriteCB_AnimFaintOpponent(struct Sprite *sprite);
static void SpriteCb_BlinkVisible(struct Sprite *sprite);
static void SpriteCallbackDummy_3(struct Sprite *sprite);
static void oac_poke_ally_(struct Sprite *sprite);
-static void SpecialStatusesClear(void);
static void TurnValuesCleanUp(bool8 var0);
static void SpriteCB_BounceEffect(struct Sprite *sprite);
static void BattleStartClearSetData(void);
@@ -132,19 +126,6 @@ static void HandleEndTurn_BattleLost(void);
static void HandleEndTurn_RanFromBattle(void);
static void HandleEndTurn_MonFled(void);
static void HandleEndTurn_FinishBattle(void);
-static void HandleAction_UseMove(void);
-static void HandleAction_Switch(void);
-static void HandleAction_UseItem(void);
-static void HandleAction_Run(void);
-static void HandleAction_WatchesCarefully(void);
-static void HandleAction_SafariZoneBallThrow(void);
-static void HandleAction_ThrowPokeblock(void);
-static void HandleAction_GoNear(void);
-static void HandleAction_SafariZoneRun(void);
-static void HandleAction_WallyBallThrow(void);
-static void HandleAction_TryFinish(void);
-static void HandleAction_NothingIsFainted(void);
-static void HandleAction_ActionFinished(void);
// EWRAM vars
EWRAM_DATA u16 gBattle_BG0_X = 0;
@@ -591,10 +572,6 @@ const u8 * const gStatusConditionStringsTable[7][2] =
{gStatusConditionString_LoveJpn, gText_Love}
};
-static const u8 sPkblToEscapeFactor[][3] = {{0, 0, 0}, {3, 5, 0}, {2, 3, 0}, {1, 2, 0}, {1, 1, 0}};
-static const u8 sGoNearCounterToCatchFactor[] = {4, 3, 2, 1};
-static const u8 sGoNearCounterToEscapeFactor[] = {4, 4, 4, 4};
-
// code
void CB2_InitBattle(void)
{
@@ -1380,7 +1357,7 @@ static void CB2_HandleStartMultiPartnerBattle(void)
case 16:
if (BattleInitAllSprites(&gBattleCommunication[SPRITES_INIT_STATE1], &gBattleCommunication[SPRITES_INIT_STATE2]))
{
- sub_8166188();
+ TrySetLinkBattleTowerEnemyPartyLevel();
gPreBattleCallback1 = gMain.callback1;
gMain.callback1 = BattleMainCB1;
SetMainCallback2(BattleMainCB2);
@@ -1854,7 +1831,7 @@ void BattleMainCB2(void)
UpdatePaletteFade();
RunTasks();
- if (gMain.heldKeys & B_BUTTON && gBattleTypeFlags & BATTLE_TYPE_RECORDED && sub_8186450())
+ if (JOY_HELD(B_BUTTON) && gBattleTypeFlags & BATTLE_TYPE_RECORDED && sub_8186450())
{
gSpecialVar_Result = gBattleOutcome = B_OUTCOME_PLAYER_TELEPORTED;
ResetPaletteFadeControl();
@@ -2510,7 +2487,7 @@ static void sub_803939C(void)
}
break;
case 5:
- if (gMain.newKeys & DPAD_UP)
+ if (JOY_NEW(DPAD_UP))
{
if (gBattleCommunication[CURSOR_POSITION] != 0)
{
@@ -2520,7 +2497,7 @@ static void sub_803939C(void)
BattleCreateYesNoCursorAt(0);
}
}
- else if (gMain.newKeys & DPAD_DOWN)
+ else if (JOY_NEW(DPAD_DOWN))
{
if (gBattleCommunication[CURSOR_POSITION] == 0)
{
@@ -2530,7 +2507,7 @@ static void sub_803939C(void)
BattleCreateYesNoCursorAt(1);
}
}
- else if (gMain.newKeys & A_BUTTON)
+ else if (JOY_NEW(A_BUTTON))
{
PlaySE(SE_SELECT);
if (gBattleCommunication[CURSOR_POSITION] == 0)
@@ -2544,7 +2521,7 @@ static void sub_803939C(void)
gBattleCommunication[MULTIUSE_STATE]++;
}
}
- else if (gMain.newKeys & B_BUTTON)
+ else if (JOY_NEW(B_BUTTON))
{
PlaySE(SE_SELECT);
gBattleCommunication[MULTIUSE_STATE]++;
@@ -2788,7 +2765,7 @@ static void SpriteCB_AnimFaintOpponent(struct Sprite *sprite)
}
else // Erase bottom part of the sprite to create a smooth illusion of mon falling down.
{
- u8 *dst = (u8 *)gMonSpritesGfxPtr->sprites[GetBattlerPosition(sprite->sBattler)] + (gBattleMonForms[sprite->sBattler] << 11) + (sprite->data[3] << 8);
+ u8* dst = gMonSpritesGfxPtr->sprites.byte[GetBattlerPosition(sprite->sBattler)] + (gBattleMonForms[sprite->sBattler] << 11) + (sprite->data[3] << 8);
for (i = 0; i < 0x100; i++)
*(dst++) = 0;
@@ -2978,7 +2955,7 @@ void sub_8039E60(struct Sprite *sprite)
sprite->callback = SpriteCallbackDummy_3;
}
-void sub_8039E84(struct Sprite *sprite)
+void SpriteCB_TrainerThrowObject(struct Sprite *sprite)
{
StartSpriteAnim(sprite, 1);
sprite->callback = sub_8039E60;
@@ -3609,19 +3586,21 @@ static void BattleIntroOpponent2SendsOutMonAnimation(void)
gBattleMainFunc = BattleIntroRecordMonsToDex;
}
-#ifdef NONMATCHING
static void BattleIntroOpponent1SendsOutMonAnimation(void)
{
u32 position;
- if (!(gBattleTypeFlags & BATTLE_TYPE_RECORDED))
- position = B_POSITION_OPPONENT_LEFT;
- else if (gBattleTypeFlags & BATTLE_TYPE_x2000000)
+ if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
{
- if (gBattleTypeFlags & BATTLE_TYPE_x80000000)
- position = B_POSITION_OPPONENT_LEFT;
+ if (gBattleTypeFlags & BATTLE_TYPE_x2000000)
+ {
+ if (gBattleTypeFlags & BATTLE_TYPE_x80000000)
+ position = B_POSITION_OPPONENT_LEFT;
+ else
+ position = B_POSITION_PLAYER_LEFT;
+ }
else
- position = B_POSITION_PLAYER_LEFT;
+ position = B_POSITION_OPPONENT_LEFT;
}
else
position = B_POSITION_OPPONENT_LEFT;
@@ -3645,93 +3624,6 @@ static void BattleIntroOpponent1SendsOutMonAnimation(void)
gBattleMainFunc = BattleIntroRecordMonsToDex;
}
-#else
-NAKED
-static void BattleIntroOpponent1SendsOutMonAnimation(void)
-{
- asm(".syntax unified\n\
- push {r4-r6,lr}\n\
- ldr r0, =gBattleTypeFlags\n\
- ldr r2, [r0]\n\
- movs r0, 0x80\n\
- lsls r0, 17\n\
- ands r0, r2\n\
- cmp r0, 0\n\
- beq _0803B298\n\
- movs r0, 0x80\n\
- lsls r0, 18\n\
- ands r0, r2\n\
- cmp r0, 0\n\
- beq _0803B298\n\
- movs r1, 0x80\n\
- lsls r1, 24\n\
- ands r1, r2\n\
- negs r0, r1\n\
- orrs r0, r1\n\
- lsrs r5, r0, 31\n\
- b _0803B29A\n\
- .pool\n\
-_0803B288:\n\
- ldr r1, =gBattleMainFunc\n\
- ldr r0, =BattleIntroOpponent2SendsOutMonAnimation\n\
- b _0803B2F0\n\
- .pool\n\
-_0803B298:\n\
- movs r5, 0x1\n\
-_0803B29A:\n\
- ldr r0, =gBattleControllerExecFlags\n\
- ldr r2, [r0]\n\
- cmp r2, 0\n\
- bne _0803B2F2\n\
- ldr r0, =gActiveBattler\n\
- strb r2, [r0]\n\
- ldr r1, =gBattlersCount\n\
- adds r4, r0, 0\n\
- ldrb r1, [r1]\n\
- cmp r2, r1\n\
- bcs _0803B2EC\n\
- adds r6, r4, 0\n\
-_0803B2B2:\n\
- ldrb r0, [r4]\n\
- bl GetBattlerPosition\n\
- lsls r0, 24\n\
- lsrs r0, 24\n\
- cmp r0, r5\n\
- bne _0803B2D8\n\
- movs r0, 0\n\
- bl BtlController_EmitIntroTrainerBallThrow\n\
- ldrb r0, [r4]\n\
- bl MarkBattlerForControllerExec\n\
- ldr r0, =gBattleTypeFlags\n\
- ldr r0, [r0]\n\
- ldr r1, =0x00008040\n\
- ands r0, r1\n\
- cmp r0, 0\n\
- bne _0803B288\n\
-_0803B2D8:\n\
- ldrb r0, [r6]\n\
- adds r0, 0x1\n\
- strb r0, [r6]\n\
- ldr r1, =gBattlersCount\n\
- lsls r0, 24\n\
- lsrs r0, 24\n\
- ldr r4, =gActiveBattler\n\
- ldrb r1, [r1]\n\
- cmp r0, r1\n\
- bcc _0803B2B2\n\
-_0803B2EC:\n\
- ldr r1, =gBattleMainFunc\n\
- ldr r0, =BattleIntroRecordMonsToDex\n\
-_0803B2F0:\n\
- str r0, [r1]\n\
-_0803B2F2:\n\
- pop {r4-r6}\n\
- pop {r0}\n\
- bx r0\n\
- .pool\n\
- .syntax divided");
-}
-#endif // NONMATCHING
static void BattleIntroRecordMonsToDex(void)
{
@@ -4851,38 +4743,40 @@ static void SetActionsAndBattlersTurnOrder(void)
gBattleStruct->focusPunchBattlerId = 0;
return;
}
- for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
+ else
{
- if (gChosenActionByBattler[gActiveBattler] == B_ACTION_USE_ITEM || gChosenActionByBattler[gActiveBattler] == B_ACTION_SWITCH)
+ for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
{
- gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler];
- gBattlerByTurnOrder[turnOrderId] = gActiveBattler;
- turnOrderId++;
+ if (gChosenActionByBattler[gActiveBattler] == B_ACTION_USE_ITEM || gChosenActionByBattler[gActiveBattler] == B_ACTION_SWITCH)
+ {
+ gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler];
+ gBattlerByTurnOrder[turnOrderId] = gActiveBattler;
+ turnOrderId++;
+ }
}
- }
- for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
- {
- if (gChosenActionByBattler[gActiveBattler] != B_ACTION_USE_ITEM && gChosenActionByBattler[gActiveBattler] != B_ACTION_SWITCH)
+ for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
{
- gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler];
- gBattlerByTurnOrder[turnOrderId] = gActiveBattler;
- turnOrderId++;
+ if (gChosenActionByBattler[gActiveBattler] != B_ACTION_USE_ITEM && gChosenActionByBattler[gActiveBattler] != B_ACTION_SWITCH)
+ {
+ gActionsByTurnOrder[turnOrderId] = gChosenActionByBattler[gActiveBattler];
+ gBattlerByTurnOrder[turnOrderId] = gActiveBattler;
+ turnOrderId++;
+ }
}
- }
- for (i = 0; i < gBattlersCount - 1; i++)
- {
- for (j = i + 1; j < gBattlersCount; j++)
+ for (i = 0; i < gBattlersCount - 1; i++)
{
- u8 battler1 = gBattlerByTurnOrder[i];
- u8 battler2 = 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)
+ for (j = i + 1; j < gBattlersCount; j++)
{
- if (GetWhoStrikesFirst(battler1, battler2, FALSE))
- SwapTurnOrder(i, j);
+ u8 battler1 = gBattlerByTurnOrder[i];
+ u8 battler2 = 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(battler1, battler2, FALSE))
+ SwapTurnOrder(i, j);
+ }
}
}
}
@@ -4928,7 +4822,7 @@ static void TurnValuesCleanUp(bool8 var0)
gSideTimers[1].followmeTimer = 0;
}
-static void SpecialStatusesClear(void)
+void SpecialStatusesClear(void)
{
for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
{
@@ -4960,8 +4854,8 @@ static void CheckFocusPunch_ClearVarsBeforeTurnStarts(void)
}
TryClearRageStatuses();
- gCurrentTurnActionNumber = 0; //See comment underneath
- gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber]; //Should be gActionsByTurnOrder[(gCurrentTurnActionNumber = 0)], but that doesn't match
+ gCurrentTurnActionNumber = 0;
+ gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
gDynamicBasePower = 0;
gBattleStruct->dynamicMoveType = 0;
gBattleMainFunc = RunTurnActionsFunctions;
@@ -4984,10 +4878,13 @@ static void RunTurnActionsFunctions(void)
gHitMarker &= ~(HITMARKER_x100000);
gBattleMainFunc = sEndTurnFuncsTable[gBattleOutcome & 0x7F];
}
- else if (gBattleStruct->savedTurnActionNumber != gCurrentTurnActionNumber) // action turn has been done, clear hitmarker bits for another battlerId
+ else
{
- gHitMarker &= ~(HITMARKER_NO_ATTACKSTRING);
- gHitMarker &= ~(HITMARKER_UNABLE_TO_USE_MOVE);
+ if (gBattleStruct->savedTurnActionNumber != gCurrentTurnActionNumber) // action turn has been done, clear hitmarker bits for another battlerId
+ {
+ gHitMarker &= ~(HITMARKER_NO_ATTACKSTRING);
+ gHitMarker &= ~(HITMARKER_UNABLE_TO_USE_MOVE);
+ }
}
}
@@ -5294,593 +5191,3 @@ void RunBattleScriptCommands(void)
if (gBattleControllerExecFlags == 0)
gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]]();
}
-
-static void HandleAction_UseMove(void)
-{
- u8 side;
- u8 var = 4;
-
- gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
-
- if (*(&gBattleStruct->field_91) & gBitTable[gBattlerAttacker])
- {
- gCurrentActionFuncId = B_ACTION_FINISHED;
- return;
- }
-
- gCritMultiplier = 1;
- gBattleScripting.dmgMultiplier = 1;
- gBattleStruct->atkCancellerTracker = 0;
- gMoveResultFlags = 0;
- gMultiHitCounter = 0;
- gBattleCommunication[6] = 0;
- gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerAttacker);
-
- // choose move
- if (gProtectStructs[gBattlerAttacker].noValidMoves)
- {
- gProtectStructs[gBattlerAttacker].noValidMoves = 0;
- gCurrentMove = gChosenMove = MOVE_STRUGGLE;
- gHitMarker |= HITMARKER_NO_PPDEDUCT;
- *(gBattleStruct->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 = gChosenMovePos = gDisableStructs[gBattlerAttacker].encoredMovePos;
- *(gBattleStruct->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 = gChosenMovePos = gDisableStructs[gBattlerAttacker].encoredMovePos;
- gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
- gDisableStructs[gBattlerAttacker].encoredMove = MOVE_NONE;
- gDisableStructs[gBattlerAttacker].encoredMovePos = 0;
- gDisableStructs[gBattlerAttacker].encoreTimer = 0;
- *(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, 0);
- }
- else if (gBattleMons[gBattlerAttacker].moves[gCurrMovePos] != gChosenMoveByBattler[gBattlerAttacker])
- {
- gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
- *(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, 0);
- }
- else
- {
- gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
- }
-
- if (gBattleMons[gBattlerAttacker].hp != 0)
- {
- if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
- gBattleResults.lastUsedMovePlayer = gCurrentMove;
- else
- gBattleResults.lastUsedMoveOpponent = 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[*(gBattleStruct->moveTarget + gBattlerAttacker)].ability != ABILITY_LIGHTNING_ROD
- && gBattleMoves[gCurrentMove].type == TYPE_ELECTRIC)
- {
- side = GetBattlerSide(gBattlerAttacker);
- for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
- {
- if (side != GetBattlerSide(gActiveBattler)
- && *(gBattleStruct->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 = *(gBattleStruct->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 = *(gBattleStruct->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);
- }
- }
- }
-
- // choose battlescript
- if (gBattleTypeFlags & BATTLE_TYPE_PALACE
- && gProtectStructs[gBattlerAttacker].palaceUnableToUseMove)
- {
- if (gBattleMons[gBattlerAttacker].hp == 0)
- {
- gCurrentActionFuncId = B_ACTION_FINISHED;
- return;
- }
- else if (gPalaceSelectionBattleScripts[gBattlerAttacker] != NULL)
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = 4;
- gBattlescriptCurrInstr = gPalaceSelectionBattleScripts[gBattlerAttacker];
- gPalaceSelectionBattleScripts[gBattlerAttacker] = NULL;
- }
- else
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = 4;
- gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
- }
- }
- else
- {
- gBattlescriptCurrInstr = gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect];
- }
-
- if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
- BattleArena_AddMindPoints(gBattlerAttacker);
-
- gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
-}
-
-static 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, *(gBattleStruct->field_58 + gBattlerAttacker))
-
- gBattleScripting.battler = gBattlerAttacker;
- gBattlescriptCurrInstr = BattleScript_ActionSwitch;
- gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
-
- if (gBattleResults.playerSwitchesCounter < 255)
- gBattleResults.playerSwitchesCounter++;
-}
-
-static void HandleAction_UseItem(void)
-{
- gBattlerAttacker = gBattlerTarget = gBattlerByTurnOrder[gCurrentTurnActionNumber];
- gBattle_BG0_X = 0;
- gBattle_BG0_Y = 0;
- ClearFuryCutterDestinyBondGrudge(gBattlerAttacker);
- gLastUsedItem = gBattleBufferB[gBattlerAttacker][1] | (gBattleBufferB[gBattlerAttacker][2] << 8);
-
- if (gLastUsedItem <= LAST_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
- {
- gBattleScripting.battler = gBattlerAttacker;
-
- switch (*(gBattleStruct->AI_itemType + (gBattlerAttacker >> 1)))
- {
- case AI_ITEM_FULL_RESTORE:
- case AI_ITEM_HEAL_HP:
- break;
- case AI_ITEM_CURE_CONDITION:
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- if (*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) & 1)
- {
- if (*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) & 0x3E)
- gBattleCommunication[MULTISTRING_CHOOSER] = 5;
- }
- else
- {
- while (!(*(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) & 1))
- {
- *(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) >>= 1;
- gBattleCommunication[MULTISTRING_CHOOSER]++;
- }
- }
- break;
- case AI_ITEM_X_STAT:
- gBattleCommunication[MULTISTRING_CHOOSER] = 4;
- if (*(gBattleStruct->AI_itemFlags + (gBattlerAttacker >> 1)) & 0x80)
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = 5;
- }
- else
- {
- PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK)
- PREPARE_STRING_BUFFER(gBattleTextBuff2, CHAR_X)
-
- while (!((*(gBattleStruct->AI_itemFlags + (gBattlerAttacker >> 1))) & 1))
- {
- *(gBattleStruct->AI_itemFlags + gBattlerAttacker / 2) >>= 1;
- gBattleTextBuff1[2]++;
- }
-
- gBattleScripting.animArg1 = gBattleTextBuff1[2] + 14;
- gBattleScripting.animArg2 = 0;
- }
- break;
- case AI_ITEM_GUARD_SPECS:
- if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
- gBattleCommunication[MULTISTRING_CHOOSER] = 2;
- else
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- break;
- }
-
- gBattlescriptCurrInstr = gBattlescriptsForUsingItem[*(gBattleStruct->AI_itemType + gBattlerAttacker / 2)];
- }
- gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
-}
-
-bool8 TryRunFromBattle(u8 battler)
-{
- bool8 effect = FALSE;
- u8 holdEffect;
- u8 pyramidMultiplier;
- u8 speedVar;
-
- if (gBattleMons[battler].item == ITEM_ENIGMA_BERRY)
- holdEffect = gEnigmaBerries[battler].holdEffect;
- else
- holdEffect = ItemId_GetHoldEffect(gBattleMons[battler].item);
-
- gPotentialItemEffectBattler = battler;
-
- if (holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN)
- {
- gLastUsedItem = gBattleMons[battler].item;
- gProtectStructs[battler].fleeFlag = 1;
- effect++;
- }
- else if (gBattleMons[battler].ability == ABILITY_RUN_AWAY)
- {
- if (InBattlePyramid())
- {
- gBattleStruct->runTries++;
- pyramidMultiplier = GetPyramidRunMultiplier();
- speedVar = (gBattleMons[battler].speed * pyramidMultiplier) / (gBattleMons[BATTLE_OPPOSITE(battler)].speed) + (gBattleStruct->runTries * 30);
- if (speedVar > (Random() & 0xFF))
- {
- gLastUsedAbility = ABILITY_RUN_AWAY;
- gProtectStructs[battler].fleeFlag = 2;
- effect++;
- }
- }
- else
- {
- gLastUsedAbility = ABILITY_RUN_AWAY;
- gProtectStructs[battler].fleeFlag = 2;
- effect++;
- }
- }
- else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_TRAINER_HILL) && gBattleTypeFlags & BATTLE_TYPE_TRAINER)
- {
- effect++;
- }
- else
- {
- if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
- {
- if (InBattlePyramid())
- {
- pyramidMultiplier = GetPyramidRunMultiplier();
- speedVar = (gBattleMons[battler].speed * pyramidMultiplier) / (gBattleMons[BATTLE_OPPOSITE(battler)].speed) + (gBattleStruct->runTries * 30);
- if (speedVar > (Random() & 0xFF))
- effect++;
- }
- else if (gBattleMons[battler].speed < gBattleMons[BATTLE_OPPOSITE(battler)].speed)
- {
- speedVar = (gBattleMons[battler].speed * 128) / (gBattleMons[BATTLE_OPPOSITE(battler)].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;
-}
-
-static void HandleAction_Run(void)
-{
- gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
-
- if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000))
- {
- gCurrentTurnActionNumber = gBattlersCount;
-
- for (gActiveBattler = 0; gActiveBattler < gBattlersCount; gActiveBattler++)
- {
- if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
- {
- if (gChosenActionByBattler[gActiveBattler] == B_ACTION_RUN)
- gBattleOutcome |= B_OUTCOME_LOST;
- }
- else
- {
- if (gChosenActionByBattler[gActiveBattler] == B_ACTION_RUN)
- gBattleOutcome |= B_OUTCOME_WON;
- }
- }
-
- gBattleOutcome |= B_OUTCOME_LINK_BATTLE_RAN;
- gSaveBlock2Ptr->frontier.disableRecordBattle = TRUE;
- }
- else
- {
- if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
- {
- if (!TryRunFromBattle(gBattlerAttacker)) // failed to run away
- {
- ClearFuryCutterDestinyBondGrudge(gBattlerAttacker);
- 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;
- }
- }
- }
-}
-
-static void HandleAction_WatchesCarefully(void)
-{
- gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
- gBattle_BG0_X = 0;
- gBattle_BG0_Y = 0;
- gBattlescriptCurrInstr = gBattlescriptsForSafariActions[0];
- gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
-}
-
-static 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;
-}
-
-static 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 (gBattleResults.pokeblockThrows < 0xFF)
- gBattleResults.pokeblockThrows++;
- if (gBattleStruct->safariPkblThrowCounter < 3)
- gBattleStruct->safariPkblThrowCounter++;
- if (gBattleStruct->safariEscapeFactor > 1)
- {
- if (gBattleStruct->safariEscapeFactor < sPkblToEscapeFactor[gBattleStruct->safariPkblThrowCounter][gBattleCommunication[MULTISTRING_CHOOSER]])
- gBattleStruct->safariEscapeFactor = 1;
- else
- gBattleStruct->safariEscapeFactor -= sPkblToEscapeFactor[gBattleStruct->safariPkblThrowCounter][gBattleCommunication[MULTISTRING_CHOOSER]];
- }
-
- gBattlescriptCurrInstr = gBattlescriptsForSafariActions[2];
- gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
-}
-
-static void HandleAction_GoNear(void)
-{
- gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
- gBattle_BG0_X = 0;
- gBattle_BG0_Y = 0;
-
- gBattleStruct->safariCatchFactor += sGoNearCounterToCatchFactor[gBattleStruct->safariGoNearCounter];
- if (gBattleStruct->safariCatchFactor > 20)
- gBattleStruct->safariCatchFactor = 20;
-
- gBattleStruct->safariEscapeFactor += sGoNearCounterToEscapeFactor[gBattleStruct->safariGoNearCounter];
- if (gBattleStruct->safariEscapeFactor > 20)
- gBattleStruct->safariEscapeFactor = 20;
-
- if (gBattleStruct->safariGoNearCounter < 3)
- {
- gBattleStruct->safariGoNearCounter++;
- gBattleCommunication[MULTISTRING_CHOOSER] = 0;
- }
- else
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = 1; // Can't get closer.
- }
- gBattlescriptCurrInstr = gBattlescriptsForSafariActions[1];
- gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
-}
-
-static void HandleAction_SafariZoneRun(void)
-{
- gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber];
- PlaySE(SE_FLEE);
- gCurrentTurnActionNumber = gBattlersCount;
- gBattleOutcome = B_OUTCOME_RAN;
-}
-
-static void HandleAction_WallyBallThrow(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;
-}
-
-static void HandleAction_TryFinish(void)
-{
- if (!HandleFaintedMonActions())
- {
- gBattleStruct->faintedActionsState = 0;
- gCurrentActionFuncId = B_ACTION_FINISHED;
- }
-}
-
-static void HandleAction_NothingIsFainted(void)
-{
- gCurrentTurnActionNumber++;
- gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
- gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED
- | HITMARKER_NO_PPDEDUCT | HITMARKER_IGNORE_SAFEGUARD | HITMARKER_IGNORE_ON_AIR
- | HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000
- | HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT
- | HITMARKER_CHARGING | HITMARKER_x4000000);
-}
-
-static void HandleAction_ActionFinished(void)
-{
- *(gBattleStruct->monToSwitchIntoId + gBattlerByTurnOrder[gCurrentTurnActionNumber]) = 6;
- gCurrentTurnActionNumber++;
- gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
- SpecialStatusesClear();
- gHitMarker &= ~(HITMARKER_DESTINYBOND | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_ATTACKSTRING_PRINTED
- | HITMARKER_NO_PPDEDUCT | HITMARKER_IGNORE_SAFEGUARD | HITMARKER_IGNORE_ON_AIR
- | HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000
- | HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT
- | HITMARKER_CHARGING | HITMARKER_x4000000);
-
- gCurrentMove = 0;
- gBattleMoveDamage = 0;
- gMoveResultFlags = 0;
- gBattleScripting.animTurn = 0;
- gBattleScripting.animTargetsHit = 0;
- gLastLandedMoves[gBattlerAttacker] = 0;
- gLastHitByType[gBattlerAttacker] = 0;
- gBattleStruct->dynamicMoveType = 0;
- gDynamicBasePower = 0;
- gBattleScripting.moveendState = 0;
- gBattleCommunication[3] = 0;
- gBattleCommunication[4] = 0;
- gBattleScripting.multihitMoveEffect = 0;
- gBattleResources->battleScriptsStack->size = 0;
-}
-
-