1388 lines
55 KiB
C
1388 lines
55 KiB
C
|
#include "global.h"
|
||
|
#include "battle.h"
|
||
|
#include "abilities.h"
|
||
|
#include "moves.h"
|
||
|
#include "hold_effects.h"
|
||
|
#include "pokemon.h"
|
||
|
#include "species.h"
|
||
|
#include "item.h"
|
||
|
#include "items.h"
|
||
|
#include "util.h"
|
||
|
#include "battle_move_effects.h"
|
||
|
#include "rng.h"
|
||
|
#include "text.h"
|
||
|
#include "string_util.h"
|
||
|
#include "battle_message.h"
|
||
|
|
||
|
extern const u8* gBattlescriptCurrInstr;
|
||
|
extern const u8* gUnknown_02024220[BATTLE_BANKS_COUNT];
|
||
|
extern const u8* gUnknown_02024230[BATTLE_BANKS_COUNT];
|
||
|
extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
|
||
|
extern u8 gActiveBank;
|
||
|
extern u8 gStringBank;
|
||
|
extern u16 gCurrentMove;
|
||
|
extern u16 gLastUsedItem;
|
||
|
extern u8 gNoOfAllBanks;
|
||
|
extern u32 gStatuses3[BATTLE_BANKS_COUNT];
|
||
|
extern u8 gBankAttacker;
|
||
|
extern u8 gBankTarget;
|
||
|
extern u8 gAbsentBankFlags;
|
||
|
extern u16 gBattleWeather;
|
||
|
extern u8 gTurnOrder[BATTLE_BANKS_COUNT];
|
||
|
extern u16 gSideAffecting[];
|
||
|
extern u8 gBattleCommunication[];
|
||
|
extern void (*gBattleMainFunc)(void);
|
||
|
extern s32 gBattleMoveDamage;
|
||
|
extern struct BattleEnigmaBerry gEnigmaBerries[BATTLE_BANKS_COUNT];
|
||
|
extern u8 gBattleBufferB[BATTLE_BANKS_COUNT][0x200];
|
||
|
extern u32 gBattleTypeFlags;
|
||
|
extern u16 gLastUsedMovesByBanks[BATTLE_BANKS_COUNT];
|
||
|
extern u32 gHitMarker;
|
||
|
extern u8 gEffectBank;
|
||
|
extern u16 gBattlePartyID[BATTLE_BANKS_COUNT];
|
||
|
extern u8 gBank1;
|
||
|
extern u16 gChosenMovesByBanks[];
|
||
|
extern u8 gBattleMoveFlags;
|
||
|
extern s32 gTakenDmg[BATTLE_BANKS_COUNT];
|
||
|
extern u8 gTakenDmgBanks[BATTLE_BANKS_COUNT];
|
||
|
|
||
|
extern const struct BattleMove gBattleMoves[];
|
||
|
|
||
|
// scripts
|
||
|
extern const u8 gUnknown_082DAE2A[];
|
||
|
extern const u8 gUnknown_082DAE1F[];
|
||
|
extern const u8 gUnknown_082DB089[];
|
||
|
extern const u8 gUnknown_082DB098[];
|
||
|
extern const u8 gUnknown_082DB0AF[];
|
||
|
extern const u8 gUnknown_082DB0A0[];
|
||
|
extern const u8 gUnknown_082DB185[];
|
||
|
extern const u8 gUnknown_082DB181[];
|
||
|
extern const u8 gUnknown_082DB812[];
|
||
|
extern const u8 gUnknown_082DB076[];
|
||
|
extern const u8 BattleScript_NoMovesLeft[];
|
||
|
extern const u8 gUnknown_082DACFA[];
|
||
|
extern const u8 gUnknown_082DAD0B[];
|
||
|
extern const u8 gUnknown_082DACC9[];
|
||
|
extern const u8 gUnknown_082DAC47[];
|
||
|
extern const u8 gUnknown_082DACE0[];
|
||
|
extern const u8 gUnknown_082DACD2[];
|
||
|
extern const u8 BattleScript_WishComesTrue[];
|
||
|
extern const u8 gUnknown_082DACC9[];
|
||
|
extern const u8 gUnknown_082DAC2C[];
|
||
|
extern const u8 BattleScript_IngrainTurnHeal[];
|
||
|
extern const u8 BattleScript_LeechSeedTurnDrain[];
|
||
|
extern const u8 BattleScript_PoisonTurnDmg[];
|
||
|
extern const u8 BattleScript_BurnTurnDmg[];
|
||
|
extern const u8 BattleScript_NightmareTurnDmg[];
|
||
|
extern const u8 BattleScript_CurseTurnDmg[];
|
||
|
extern const u8 BattleScript_WrapTurnDmg[];
|
||
|
extern const u8 BattleScript_WrapEnds[];
|
||
|
extern const u8 gUnknown_082DB234[];
|
||
|
extern const u8 gUnknown_082DB2A6[];
|
||
|
extern const u8 BattleScript_ThrashConfuses[];
|
||
|
extern const u8 BattleScript_DisabledNoMore[];
|
||
|
extern const u8 BattleScript_EncoredNoMore[];
|
||
|
extern const u8 BattleScript_YawnMakesAsleep[];
|
||
|
extern const u8 gUnknown_082DAFE4[];
|
||
|
extern const u8 gUnknown_082DB8F3[];
|
||
|
extern const u8 gUnknown_082DAF05[];
|
||
|
extern const u8 gUnknown_082DAF20[];
|
||
|
extern const u8 gUnknown_082DA7C4[];
|
||
|
extern const u8 gUnknown_082DA7CD[];
|
||
|
extern const u8 BattleScript_MoveUsedWokeUp[];
|
||
|
extern const u8 BattleScript_MoveUsedIsAsleep[];
|
||
|
extern const u8 BattleScript_MoveUsedIsFrozen[];
|
||
|
extern const u8 BattleScript_MoveUsedUnfroze[];
|
||
|
extern const u8 BattleScript_MoveUsedLoafingAround[];
|
||
|
extern const u8 BattleScript_MoveUsedMustRecharge[];
|
||
|
extern const u8 BattleScript_MoveUsedFlinched[];
|
||
|
extern const u8 BattleScript_MoveUsedIsDisabled[];
|
||
|
extern const u8 BattleScript_MoveUsedIsTaunted[];
|
||
|
extern const u8 BattleScript_MoveUsedIsImprisoned[];
|
||
|
extern const u8 BattleScript_MoveUsedIsConfused[];
|
||
|
extern const u8 BattleScript_MoveUsedIsConfusedNoMore[];
|
||
|
extern const u8 BattleScript_MoveUsedIsParalyzed[];
|
||
|
extern const u8 BattleScript_MoveUsedIsParalyzedCantAttack[];
|
||
|
extern const u8 BattleScript_MoveUsedIsInLove[];
|
||
|
extern const u8 BattleScript_BideStoringEnergy[];
|
||
|
extern const u8 BattleScript_BideAttack[];
|
||
|
extern const u8 BattleScript_BideNoEnergyToAttack[];
|
||
|
|
||
|
extern void CancelMultiTurnMoves(u8 bank);
|
||
|
extern u8 b_first_side(u8, u8, u8);
|
||
|
extern void sub_803CEDC(u8, u8);
|
||
|
extern void b_call_bc_move_exec(const u8 *);
|
||
|
extern void BattleTurnPassed(void);
|
||
|
extern void EmitSetAttributes(u8 a, u8 request, u8 c, u8 bytes, void *data);
|
||
|
extern void SetMoveEffect(bool8 primary, u8 certainArg);
|
||
|
extern bool8 UproarWakeUpCheck(u8 bank);
|
||
|
extern void MarkBufferBankForExecution(u8 bank);
|
||
|
extern u8 sub_803F90C(u8 bank);
|
||
|
extern u8 GetBankIdentity(u8);
|
||
|
extern void sub_803F9EC();
|
||
|
extern bool8 sub_80423F4(u8 bank, u8, u8);
|
||
|
extern s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 sideFlags, u16 powerOverride, u8 typeOverride, u8 bankAtk, u8 bankDef);
|
||
|
|
||
|
u8 IsImprisoned(u8 bank, u16 move);
|
||
|
u8 ItemBattleEffects(u8 caseID, u8 bank, bool8 moveTurn);
|
||
|
u8 GetMoveTarget(u16 move, u8 useMoveTarget);
|
||
|
|
||
|
void b_movescr_stack_push(const u8* bsPtr)
|
||
|
{
|
||
|
BATTLESCRIPTS_STACK->ptr[BATTLESCRIPTS_STACK->size++] = bsPtr;
|
||
|
}
|
||
|
|
||
|
void b_movescr_stack_push_cursor(void)
|
||
|
{
|
||
|
BATTLESCRIPTS_STACK->ptr[BATTLESCRIPTS_STACK->size++] = gBattlescriptCurrInstr;
|
||
|
}
|
||
|
|
||
|
void b_movescr_stack_pop_cursor(void)
|
||
|
{
|
||
|
gBattlescriptCurrInstr = BATTLESCRIPTS_STACK->ptr[--BATTLESCRIPTS_STACK->size];
|
||
|
}
|
||
|
|
||
|
u8 sub_803FB4C(void) // msg, can't select a move
|
||
|
{
|
||
|
u8 limitations = 0;
|
||
|
u16 move = gBattleMons[gActiveBank].moves[gBattleBufferB[gActiveBank][2]];
|
||
|
u8 holdEffect;
|
||
|
u16* choicedMove = &gBattleStruct->choicedMove[gActiveBank];
|
||
|
|
||
|
if (gDisableStructs[gActiveBank].disabledMove == move && move != 0)
|
||
|
{
|
||
|
gBattleScripting.bank = gActiveBank;
|
||
|
gCurrentMove = move;
|
||
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||
|
{
|
||
|
gUnknown_02024230[gActiveBank] = gUnknown_082DAE2A;
|
||
|
gProtectStructs[gActiveBank].flag_x10 = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gUnknown_02024220[gActiveBank] = gUnknown_082DAE1F;
|
||
|
limitations = 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (move == gLastUsedMovesByBanks[gActiveBank] && move != MOVE_STRUGGLE && (gBattleMons[gActiveBank].status2 & STATUS2_TORMENT))
|
||
|
{
|
||
|
CancelMultiTurnMoves(gActiveBank);
|
||
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||
|
{
|
||
|
gUnknown_02024230[gActiveBank] = gUnknown_082DB098;
|
||
|
gProtectStructs[gActiveBank].flag_x10 = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gUnknown_02024220[gActiveBank] = gUnknown_082DB089;
|
||
|
limitations++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (gDisableStructs[gActiveBank].tauntTimer1 != 0 && gBattleMoves[move].power == 0)
|
||
|
{
|
||
|
gCurrentMove = move;
|
||
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||
|
{
|
||
|
gUnknown_02024230[gActiveBank] = gUnknown_082DB0AF;
|
||
|
gProtectStructs[gActiveBank].flag_x10 = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gUnknown_02024220[gActiveBank] = gUnknown_082DB0A0;
|
||
|
limitations++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (IsImprisoned(gActiveBank, move))
|
||
|
{
|
||
|
gCurrentMove = move;
|
||
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||
|
{
|
||
|
gUnknown_02024230[gActiveBank] = gUnknown_082DB185;
|
||
|
gProtectStructs[gActiveBank].flag_x10 = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gUnknown_02024220[gActiveBank] = gUnknown_082DB181;
|
||
|
limitations++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (gBattleMons[gActiveBank].item == ITEM_ENIGMA_BERRY)
|
||
|
holdEffect = gEnigmaBerries[gActiveBank].holdEffect;
|
||
|
else
|
||
|
holdEffect = ItemId_GetHoldEffect(gBattleMons[gActiveBank].item);
|
||
|
|
||
|
gStringBank = gActiveBank;
|
||
|
|
||
|
if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != move)
|
||
|
{
|
||
|
gCurrentMove = *choicedMove;
|
||
|
gLastUsedItem = gBattleMons[gActiveBank].item;
|
||
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||
|
{
|
||
|
gProtectStructs[gActiveBank].flag_x10 = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gUnknown_02024220[gActiveBank] = gUnknown_082DB812;
|
||
|
limitations++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (gBattleMons[gActiveBank].pp[gBattleBufferB[gActiveBank][2]] == 0)
|
||
|
{
|
||
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||
|
{
|
||
|
gProtectStructs[gActiveBank].flag_x10 = 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gUnknown_02024220[gActiveBank] = gUnknown_082DB076;
|
||
|
limitations++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return limitations;
|
||
|
}
|
||
|
|
||
|
#define MOVE_LIMITATION_ZEROMOVE (1 << 0)
|
||
|
#define MOVE_LIMITATION_PP (1 << 1)
|
||
|
#define MOVE_LIMITATION_DISABLED (1 << 2)
|
||
|
#define MOVE_LIMITATION_TORMENTED (1 << 3)
|
||
|
#define MOVE_LIMITATION_TAUNT (1 << 4)
|
||
|
#define MOVE_LIMITATION_IMPRISION (1 << 5)
|
||
|
|
||
|
u8 CheckMoveLimitations(u8 bank, u8 unusableMoves, u8 check)
|
||
|
{
|
||
|
u8 holdEffect;
|
||
|
u16* choicedMove = &gBattleStruct->choicedMove[bank];
|
||
|
s32 i;
|
||
|
|
||
|
if (gBattleMons[bank].item == ITEM_ENIGMA_BERRY)
|
||
|
holdEffect = gEnigmaBerries[bank].holdEffect;
|
||
|
else
|
||
|
holdEffect = ItemId_GetHoldEffect(gBattleMons[bank].item);
|
||
|
|
||
|
gStringBank = bank;
|
||
|
|
||
|
for (i = 0; i < BATTLE_BANKS_COUNT; i++)
|
||
|
{
|
||
|
if (gBattleMons[bank].moves[i] == 0 && check & MOVE_LIMITATION_ZEROMOVE)
|
||
|
unusableMoves |= gBitTable[i];
|
||
|
if (gBattleMons[bank].pp[i] == 0 && check & MOVE_LIMITATION_PP)
|
||
|
unusableMoves |= gBitTable[i];
|
||
|
if (gBattleMons[bank].moves[i] == gDisableStructs[bank].disabledMove && check & MOVE_LIMITATION_DISABLED)
|
||
|
unusableMoves |= gBitTable[i];
|
||
|
if (gBattleMons[bank].moves[i] == gLastUsedMovesByBanks[bank] && check & MOVE_LIMITATION_TORMENTED && gBattleMons[bank].status2 & STATUS2_TORMENT)
|
||
|
unusableMoves |= gBitTable[i];
|
||
|
if (gDisableStructs[bank].tauntTimer1 && check & MOVE_LIMITATION_TAUNT && gBattleMoves[gBattleMons[bank].moves[i]].power == 0)
|
||
|
unusableMoves |= gBitTable[i];
|
||
|
if (IsImprisoned(bank, gBattleMons[bank].moves[i]) && check & MOVE_LIMITATION_IMPRISION)
|
||
|
unusableMoves |= gBitTable[i];
|
||
|
if (gDisableStructs[bank].encoreTimer1 && gDisableStructs[bank].encoredMove != gBattleMons[bank].moves[i])
|
||
|
unusableMoves |= gBitTable[i];
|
||
|
if (holdEffect == HOLD_EFFECT_CHOICE_BAND && *choicedMove != 0 && *choicedMove != 0xFFFF && *choicedMove != gBattleMons[bank].moves[i])
|
||
|
unusableMoves |= gBitTable[i];
|
||
|
}
|
||
|
return unusableMoves;
|
||
|
}
|
||
|
|
||
|
bool8 AreAllMovesUnusable(void)
|
||
|
{
|
||
|
u8 unusable;
|
||
|
unusable = CheckMoveLimitations(gActiveBank, 0, 0xFF);
|
||
|
|
||
|
if (unusable == 0xF) // all moves are unusable
|
||
|
{
|
||
|
gProtectStructs[gActiveBank].onlyStruggle = 1;
|
||
|
gUnknown_02024220[gActiveBank] = BattleScript_NoMovesLeft;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gProtectStructs[gActiveBank].onlyStruggle = 0;
|
||
|
}
|
||
|
|
||
|
return (unusable == 0xF);
|
||
|
}
|
||
|
|
||
|
u8 IsImprisoned(u8 bank, u16 move)
|
||
|
{
|
||
|
s32 i;
|
||
|
u8 imprisionedMoves = 0;
|
||
|
u8 bankSide = GetBankSide(bank);
|
||
|
|
||
|
for (i = 0; i < gNoOfAllBanks; i++)
|
||
|
{
|
||
|
if (bankSide != GetBankSide(i) && gStatuses3[i] & STATUS3_IMPRISIONED)
|
||
|
{
|
||
|
s32 j;
|
||
|
for (j = 0; j < 4; j++)
|
||
|
{
|
||
|
if (move == gBattleMons[i].moves[j])
|
||
|
break;
|
||
|
}
|
||
|
if (j < 4)
|
||
|
imprisionedMoves++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return imprisionedMoves;
|
||
|
}
|
||
|
|
||
|
u8 UpdateTurnCounters(void)
|
||
|
{
|
||
|
u8 effect = 0;
|
||
|
s32 i;
|
||
|
|
||
|
for (gBankAttacker = 0; gBankAttacker < gNoOfAllBanks && gAbsentBankFlags & gBitTable[gBankAttacker]; gBankAttacker++)
|
||
|
{
|
||
|
}
|
||
|
for (gBankTarget = 0; gBankTarget < gNoOfAllBanks && gAbsentBankFlags & gBitTable[gBankTarget]; gBankTarget++)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
do
|
||
|
{
|
||
|
u8 sideBank;
|
||
|
|
||
|
switch (gBattleStruct->turncountersTracker)
|
||
|
{
|
||
|
case 0:
|
||
|
for (i = 0; i < gNoOfAllBanks; i++)
|
||
|
{
|
||
|
gTurnOrder[i] = i;
|
||
|
}
|
||
|
for (i = 0; i < gNoOfAllBanks - 1; i++)
|
||
|
{
|
||
|
s32 j;
|
||
|
for (j = i + 1; j < gNoOfAllBanks; j++)
|
||
|
{
|
||
|
if (b_first_side(gTurnOrder[i], gTurnOrder[j], 0))
|
||
|
sub_803CEDC(i, j);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// It's stupid, but won't match without it
|
||
|
{
|
||
|
u8* var = &gBattleStruct->turncountersTracker;
|
||
|
(*var)++;
|
||
|
gBattleStruct->turnSideTracker = 0;
|
||
|
}
|
||
|
// fall through
|
||
|
case 1:
|
||
|
while (gBattleStruct->turnSideTracker < 2)
|
||
|
{
|
||
|
sideBank = gBattleStruct->turnSideTracker;
|
||
|
gActiveBank = gBankAttacker = gSideTimers[sideBank].reflectBank;
|
||
|
if (gSideAffecting[sideBank] & SIDE_STATUS_REFLECT)
|
||
|
{
|
||
|
if (--gSideTimers[sideBank].reflectTimer == 0)
|
||
|
{
|
||
|
gSideAffecting[sideBank] &= ~SIDE_STATUS_REFLECT;
|
||
|
b_call_bc_move_exec(gUnknown_082DACFA);
|
||
|
gBattleTextBuff1[0] = 0xFD;
|
||
|
gBattleTextBuff1[1] = 2;
|
||
|
gBattleTextBuff1[2] = MOVE_REFLECT;
|
||
|
gBattleTextBuff1[3] = MOVE_REFLECT >> 8;
|
||
|
gBattleTextBuff1[4] = EOS;
|
||
|
effect++;
|
||
|
}
|
||
|
}
|
||
|
gBattleStruct->turnSideTracker++;
|
||
|
if (effect)
|
||
|
break;
|
||
|
}
|
||
|
if (!effect)
|
||
|
{
|
||
|
gBattleStruct->turncountersTracker++;
|
||
|
gBattleStruct->turnSideTracker = 0;
|
||
|
}
|
||
|
break;
|
||
|
case 2:
|
||
|
while (gBattleStruct->turnSideTracker < 2)
|
||
|
{
|
||
|
sideBank = gBattleStruct->turnSideTracker;
|
||
|
gActiveBank = gBankAttacker = gSideTimers[sideBank].lightscreenBank;
|
||
|
if (gSideAffecting[sideBank] & SIDE_STATUS_LIGHTSCREEN)
|
||
|
{
|
||
|
if (--gSideTimers[sideBank].lightscreenTimer == 0)
|
||
|
{
|
||
|
gSideAffecting[sideBank] &= ~SIDE_STATUS_LIGHTSCREEN;
|
||
|
b_call_bc_move_exec(gUnknown_082DACFA);
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = sideBank;
|
||
|
gBattleTextBuff1[0] = 0xFD;
|
||
|
gBattleTextBuff1[1] = 2;
|
||
|
gBattleTextBuff1[2] = MOVE_LIGHT_SCREEN;
|
||
|
gBattleTextBuff1[3] = MOVE_LIGHT_SCREEN >> 8;
|
||
|
gBattleTextBuff1[4] = EOS;
|
||
|
effect++;
|
||
|
}
|
||
|
}
|
||
|
gBattleStruct->turnSideTracker++;
|
||
|
if (effect)
|
||
|
break;
|
||
|
}
|
||
|
if (!effect)
|
||
|
{
|
||
|
gBattleStruct->turncountersTracker++;
|
||
|
gBattleStruct->turnSideTracker = 0;
|
||
|
}
|
||
|
break;
|
||
|
case 3:
|
||
|
while (gBattleStruct->turnSideTracker < 2)
|
||
|
{
|
||
|
sideBank = gBattleStruct->turnSideTracker;
|
||
|
gActiveBank = gBankAttacker = gSideTimers[sideBank].mistBank;
|
||
|
if (gSideTimers[sideBank].mistTimer != 0
|
||
|
&& --gSideTimers[sideBank].mistTimer == 0)
|
||
|
{
|
||
|
gSideAffecting[sideBank] &= ~SIDE_STATUS_MIST;
|
||
|
b_call_bc_move_exec(gUnknown_082DACFA);
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = sideBank;
|
||
|
gBattleTextBuff1[0] = 0xFD;
|
||
|
gBattleTextBuff1[1] = 2;
|
||
|
gBattleTextBuff1[2] = MOVE_MIST;
|
||
|
gBattleTextBuff1[3] = MOVE_MIST >> 8;
|
||
|
gBattleTextBuff1[4] = EOS;
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turnSideTracker++;
|
||
|
if (effect)
|
||
|
break;
|
||
|
}
|
||
|
if (!effect)
|
||
|
{
|
||
|
gBattleStruct->turncountersTracker++;
|
||
|
gBattleStruct->turnSideTracker = 0;
|
||
|
}
|
||
|
break;
|
||
|
case 4:
|
||
|
while (gBattleStruct->turnSideTracker < 2)
|
||
|
{
|
||
|
sideBank = gBattleStruct->turnSideTracker;
|
||
|
gActiveBank = gBankAttacker = gSideTimers[sideBank].safeguardBank;
|
||
|
if (gSideAffecting[sideBank] & SIDE_STATUS_SAFEGUARD)
|
||
|
{
|
||
|
if (--gSideTimers[sideBank].safeguardTimer == 0)
|
||
|
{
|
||
|
gSideAffecting[sideBank] &= ~SIDE_STATUS_SAFEGUARD;
|
||
|
b_call_bc_move_exec(gUnknown_082DAD0B);
|
||
|
effect++;
|
||
|
}
|
||
|
}
|
||
|
gBattleStruct->turnSideTracker++;
|
||
|
if (effect)
|
||
|
break;
|
||
|
}
|
||
|
if (!effect)
|
||
|
{
|
||
|
gBattleStruct->turncountersTracker++;
|
||
|
gBattleStruct->turnSideTracker = 0;
|
||
|
}
|
||
|
break;
|
||
|
case 5:
|
||
|
while (gBattleStruct->turnSideTracker < gNoOfAllBanks)
|
||
|
{
|
||
|
gActiveBank = gTurnOrder[gBattleStruct->turnSideTracker];
|
||
|
if (gWishFutureKnock.wishCounter[gActiveBank] != 0
|
||
|
&& --gWishFutureKnock.wishCounter[gActiveBank] == 0
|
||
|
&& gBattleMons[gActiveBank].hp != 0)
|
||
|
{
|
||
|
gBankTarget = gActiveBank;
|
||
|
b_call_bc_move_exec(BattleScript_WishComesTrue);
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turnSideTracker++;
|
||
|
if (effect)
|
||
|
break;
|
||
|
}
|
||
|
if (!effect)
|
||
|
{
|
||
|
gBattleStruct->turncountersTracker++;
|
||
|
}
|
||
|
break;
|
||
|
case 6:
|
||
|
if (gBattleWeather & WEATHER_RAIN_ANY)
|
||
|
{
|
||
|
if (!(gBattleWeather & WEATHER_RAIN_PERMANENT))
|
||
|
{
|
||
|
if (--gWishFutureKnock.weatherDuration == 0)
|
||
|
{
|
||
|
gBattleWeather &= ~WEATHER_RAIN_TEMPORARY;
|
||
|
gBattleWeather &= ~WEATHER_RAIN_DOWNPOUR;
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
|
||
|
}
|
||
|
else if (gBattleWeather & WEATHER_RAIN_DOWNPOUR)
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||
|
else
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||
|
}
|
||
|
else if (gBattleWeather & WEATHER_RAIN_DOWNPOUR)
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||
|
else
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||
|
b_call_bc_move_exec(gUnknown_082DAC2C);
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turncountersTracker++;
|
||
|
break;
|
||
|
case 7:
|
||
|
if (gBattleWeather & WEATHER_SANDSTORM_ANY)
|
||
|
{
|
||
|
if (!(gBattleWeather & WEATHER_SANDSTORM_PERMANENT) && --gWishFutureKnock.weatherDuration == 0)
|
||
|
{
|
||
|
gBattleWeather &= ~WEATHER_SANDSTORM_TEMPORARY;
|
||
|
gBattlescriptCurrInstr = gUnknown_082DACC9;
|
||
|
}
|
||
|
else
|
||
|
gBattlescriptCurrInstr = gUnknown_082DAC47;
|
||
|
|
||
|
gBattleScripting.animArg1 = 0xC;
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||
|
b_call_bc_move_exec(gBattlescriptCurrInstr);
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turncountersTracker++;
|
||
|
break;
|
||
|
case 8:
|
||
|
if (gBattleWeather & WEATHER_SUN_ANY)
|
||
|
{
|
||
|
if (!(gBattleWeather & WEATHER_SUN_PERMANENT) && --gWishFutureKnock.weatherDuration == 0)
|
||
|
{
|
||
|
gBattleWeather &= ~WEATHER_SUN_TEMPORARY;
|
||
|
gBattlescriptCurrInstr = gUnknown_082DACE0;
|
||
|
}
|
||
|
else
|
||
|
gBattlescriptCurrInstr = gUnknown_082DACD2;
|
||
|
|
||
|
b_call_bc_move_exec(gBattlescriptCurrInstr);
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turncountersTracker++;
|
||
|
break;
|
||
|
case 9:
|
||
|
if (gBattleWeather & WEATHER_HAIL)
|
||
|
{
|
||
|
if (--gWishFutureKnock.weatherDuration == 0)
|
||
|
{
|
||
|
gBattleWeather &= ~WEATHER_HAIL;
|
||
|
gBattlescriptCurrInstr = gUnknown_082DACC9;
|
||
|
}
|
||
|
else
|
||
|
gBattlescriptCurrInstr = gUnknown_082DAC47;
|
||
|
|
||
|
gBattleScripting.animArg1 = 0xD;
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||
|
b_call_bc_move_exec(gBattlescriptCurrInstr);
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turncountersTracker++;
|
||
|
break;
|
||
|
case 10:
|
||
|
effect++;
|
||
|
break;
|
||
|
}
|
||
|
} while (effect == 0);
|
||
|
return (gBattleMainFunc != BattleTurnPassed);
|
||
|
}
|
||
|
|
||
|
#define TURNBASED_MAX_CASE 19
|
||
|
|
||
|
u8 TurnBasedEffects(void)
|
||
|
{
|
||
|
u8 effect = 0;
|
||
|
|
||
|
gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20);
|
||
|
while (gBattleStruct->turnEffectsBank < gNoOfAllBanks && gBattleStruct->turnEffectsTracker <= TURNBASED_MAX_CASE)
|
||
|
{
|
||
|
gActiveBank = gBankAttacker = gTurnOrder[gBattleStruct->turnEffectsBank];
|
||
|
if (gAbsentBankFlags & gBitTable[gActiveBank])
|
||
|
{
|
||
|
gBattleStruct->turnEffectsBank++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
switch (gBattleStruct->turnEffectsTracker)
|
||
|
{
|
||
|
case 0: // ingrain
|
||
|
if ((gStatuses3[gActiveBank] & STATUS3_ROOTED)
|
||
|
&& gBattleMons[gActiveBank].hp != gBattleMons[gActiveBank].maxHP
|
||
|
&& gBattleMons[gActiveBank].hp != 0)
|
||
|
{
|
||
|
gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 16;
|
||
|
if (gBattleMoveDamage == 0)
|
||
|
gBattleMoveDamage = 1;
|
||
|
gBattleMoveDamage *= -1;
|
||
|
b_call_bc_move_exec(BattleScript_IngrainTurnHeal);
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 1: // end turn abilities
|
||
|
if (AbilityBattleEffects(ABILITYEFFECT_ENDTURN, gActiveBank, 0, 0, 0))
|
||
|
effect++;
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 2: // item effects
|
||
|
if (ItemBattleEffects(1, gActiveBank, 0))
|
||
|
effect++;
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 18: // item effects again
|
||
|
if (ItemBattleEffects(1, gActiveBank, 1))
|
||
|
effect++;
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 3: // leech seed
|
||
|
if ((gStatuses3[gActiveBank] & STATUS3_LEECHSEED)
|
||
|
&& gBattleMons[gStatuses3[gActiveBank] & STATUS3_LEECHSEED_BANK].hp != 0
|
||
|
&& gBattleMons[gActiveBank].hp != 0)
|
||
|
{
|
||
|
gBankTarget = gStatuses3[gActiveBank] & STATUS3_LEECHSEED_BANK; //funny how the 'target' is actually the bank that receives HP
|
||
|
gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 8;
|
||
|
if (gBattleMoveDamage == 0)
|
||
|
gBattleMoveDamage = 1;
|
||
|
gBattleScripting.animArg1 = gBankTarget;
|
||
|
gBattleScripting.animArg2 = gBankAttacker;
|
||
|
b_call_bc_move_exec(BattleScript_LeechSeedTurnDrain);
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 4: // poison
|
||
|
if ((gBattleMons[gActiveBank].status1 & STATUS_POISON) && gBattleMons[gActiveBank].hp != 0)
|
||
|
{
|
||
|
gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 8;
|
||
|
if (gBattleMoveDamage == 0)
|
||
|
gBattleMoveDamage = 1;
|
||
|
b_call_bc_move_exec(BattleScript_PoisonTurnDmg);
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 5: // toxic poison
|
||
|
if ((gBattleMons[gActiveBank].status1 & STATUS_TOXIC_POISON) && gBattleMons[gActiveBank].hp != 0)
|
||
|
{
|
||
|
gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 16;
|
||
|
if (gBattleMoveDamage == 0)
|
||
|
gBattleMoveDamage = 1;
|
||
|
if ((gBattleMons[gActiveBank].status1 & 0xF00) != 0xF00) //not 16 turns
|
||
|
gBattleMons[gActiveBank].status1 += 0x100;
|
||
|
gBattleMoveDamage *= (gBattleMons[gActiveBank].status1 & 0xF00) >> 8;
|
||
|
b_call_bc_move_exec(BattleScript_PoisonTurnDmg);
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 6: // burn
|
||
|
if ((gBattleMons[gActiveBank].status1 & STATUS_BURN) && gBattleMons[gActiveBank].hp != 0)
|
||
|
{
|
||
|
gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 8;
|
||
|
if (gBattleMoveDamage == 0)
|
||
|
gBattleMoveDamage = 1;
|
||
|
b_call_bc_move_exec(BattleScript_BurnTurnDmg);
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 7: // spooky nightmares
|
||
|
if ((gBattleMons[gActiveBank].status2 & STATUS2_NIGHTMARE) && gBattleMons[gActiveBank].hp != 0)
|
||
|
{
|
||
|
// R/S does not perform this sleep check, which causes the nighmare effect to
|
||
|
// persist even after the affected Pokemon has been awakened by Shed Skin
|
||
|
if (gBattleMons[gActiveBank].status1 & STATUS_SLEEP)
|
||
|
{
|
||
|
gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 4;
|
||
|
if (gBattleMoveDamage == 0)
|
||
|
gBattleMoveDamage = 1;
|
||
|
b_call_bc_move_exec(BattleScript_NightmareTurnDmg);
|
||
|
effect++;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gBattleMons[gActiveBank].status2 &= ~STATUS2_NIGHTMARE;
|
||
|
}
|
||
|
}
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 8: // curse
|
||
|
if ((gBattleMons[gActiveBank].status2 & STATUS2_CURSED) && gBattleMons[gActiveBank].hp != 0)
|
||
|
{
|
||
|
gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 4;
|
||
|
if (gBattleMoveDamage == 0)
|
||
|
gBattleMoveDamage = 1;
|
||
|
b_call_bc_move_exec(BattleScript_CurseTurnDmg);
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 9: // wrap
|
||
|
if ((gBattleMons[gActiveBank].status2 & STATUS2_WRAPPED) && gBattleMons[gActiveBank].hp != 0)
|
||
|
{
|
||
|
gBattleMons[gActiveBank].status2 -= 0x2000;
|
||
|
if (gBattleMons[gActiveBank].status2 & STATUS2_WRAPPED) // damaged by wrap
|
||
|
{
|
||
|
// This is the only way I could get this array access to match.
|
||
|
gBattleScripting.animArg1 = *(gBattleStruct->wrappedMove + gActiveBank * 2 + 0);
|
||
|
gBattleScripting.animArg2 = *(gBattleStruct->wrappedMove + gActiveBank * 2 + 1);
|
||
|
gBattleTextBuff1[0] = 0xFD;
|
||
|
gBattleTextBuff1[1] = 2;
|
||
|
gBattleTextBuff1[2] = *(gBattleStruct->wrappedMove + gActiveBank * 2 + 0);
|
||
|
gBattleTextBuff1[3] = *(gBattleStruct->wrappedMove + gActiveBank * 2 + 1);
|
||
|
gBattleTextBuff1[4] = EOS;
|
||
|
gBattlescriptCurrInstr = BattleScript_WrapTurnDmg;
|
||
|
gBattleMoveDamage = gBattleMons[gActiveBank].maxHP / 16;
|
||
|
if (gBattleMoveDamage == 0)
|
||
|
gBattleMoveDamage = 1;
|
||
|
}
|
||
|
else // broke free
|
||
|
{
|
||
|
gBattleTextBuff1[0] = 0xFD;
|
||
|
gBattleTextBuff1[1] = 2;
|
||
|
gBattleTextBuff1[2] = *(gBattleStruct->wrappedMove + gActiveBank * 2 + 0);
|
||
|
gBattleTextBuff1[3] = *(gBattleStruct->wrappedMove + gActiveBank * 2 + 1);
|
||
|
gBattleTextBuff1[4] = EOS;
|
||
|
gBattlescriptCurrInstr = BattleScript_WrapEnds;
|
||
|
}
|
||
|
b_call_bc_move_exec(gBattlescriptCurrInstr);
|
||
|
effect++;
|
||
|
}
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 10: // uproar
|
||
|
if (gBattleMons[gActiveBank].status2 & STATUS2_UPROAR)
|
||
|
{
|
||
|
for (gBankAttacker = 0; gBankAttacker < gNoOfAllBanks; gBankAttacker++)
|
||
|
{
|
||
|
if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP)
|
||
|
&& gBattleMons[gBankAttacker].ability != ABILITY_SOUNDPROOF)
|
||
|
{
|
||
|
gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP);
|
||
|
gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE);
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||
|
b_call_bc_move_exec(gUnknown_082DB234);
|
||
|
gActiveBank = gBankAttacker;
|
||
|
EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1);
|
||
|
MarkBufferBankForExecution(gActiveBank);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (gBankAttacker != gNoOfAllBanks)
|
||
|
{
|
||
|
effect = 2; // a pokemon was awaken
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gBankAttacker = gActiveBank;
|
||
|
gBattleMons[gActiveBank].status2 -= 0x10; // uproar timer goes down
|
||
|
if (sub_803F90C(gActiveBank))
|
||
|
{
|
||
|
CancelMultiTurnMoves(gActiveBank);
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||
|
}
|
||
|
else if (gBattleMons[gActiveBank].status2 & STATUS2_UPROAR)
|
||
|
{
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||
|
gBattleMons[gActiveBank].status2 |= STATUS2_MULTIPLETURNS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||
|
CancelMultiTurnMoves(gActiveBank);
|
||
|
}
|
||
|
b_call_bc_move_exec(gUnknown_082DB2A6);
|
||
|
effect = 1;
|
||
|
}
|
||
|
}
|
||
|
if (effect != 2)
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 11: // thrash
|
||
|
if (gBattleMons[gActiveBank].status2 & STATUS2_LOCK_CONFUSE)
|
||
|
{
|
||
|
gBattleMons[gActiveBank].status2 -= 0x400;
|
||
|
if (sub_803F90C(gActiveBank))
|
||
|
CancelMultiTurnMoves(gActiveBank);
|
||
|
else if (!(gBattleMons[gActiveBank].status2 & STATUS2_LOCK_CONFUSE)
|
||
|
&& (gBattleMons[gActiveBank].status2 & STATUS2_MULTIPLETURNS))
|
||
|
{
|
||
|
gBattleMons[gActiveBank].status2 &= ~(STATUS2_MULTIPLETURNS);
|
||
|
if (!(gBattleMons[gActiveBank].status2 & STATUS2_CONFUSION))
|
||
|
{
|
||
|
gBattleCommunication[MOVE_EFFECT_BYTE] = 0x47;
|
||
|
SetMoveEffect(1, 0);
|
||
|
if (gBattleMons[gActiveBank].status2 & STATUS2_CONFUSION)
|
||
|
b_call_bc_move_exec(BattleScript_ThrashConfuses);
|
||
|
effect++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 12: // disable
|
||
|
if (gDisableStructs[gActiveBank].disableTimer1 != 0)
|
||
|
{
|
||
|
int i;
|
||
|
for (i = 0; i < 4; i++)
|
||
|
{
|
||
|
if (gDisableStructs[gActiveBank].disabledMove == gBattleMons[gActiveBank].moves[i])
|
||
|
break;
|
||
|
}
|
||
|
if (i == 4) // pokemon does not have the disabled move anymore
|
||
|
{
|
||
|
gDisableStructs[gActiveBank].disabledMove = 0;
|
||
|
gDisableStructs[gActiveBank].disableTimer1 = 0;
|
||
|
}
|
||
|
else if (--gDisableStructs[gActiveBank].disableTimer1 == 0) // disable ends
|
||
|
{
|
||
|
gDisableStructs[gActiveBank].disabledMove = 0;
|
||
|
b_call_bc_move_exec(BattleScript_DisabledNoMore);
|
||
|
effect++;
|
||
|
}
|
||
|
}
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 13: // encore
|
||
|
if (gDisableStructs[gActiveBank].encoreTimer1 != 0)
|
||
|
{
|
||
|
if (gBattleMons[gActiveBank].moves[gDisableStructs[gActiveBank].encoredMovePos] != gDisableStructs[gActiveBank].encoredMove) // pokemon does not have the encored move anymore
|
||
|
{
|
||
|
gDisableStructs[gActiveBank].encoredMove = 0;
|
||
|
gDisableStructs[gActiveBank].encoreTimer1 = 0;
|
||
|
}
|
||
|
else if (--gDisableStructs[gActiveBank].encoreTimer1 == 0
|
||
|
|| gBattleMons[gActiveBank].pp[gDisableStructs[gActiveBank].encoredMovePos] == 0)
|
||
|
{
|
||
|
gDisableStructs[gActiveBank].encoredMove = 0;
|
||
|
gDisableStructs[gActiveBank].encoreTimer1 = 0;
|
||
|
b_call_bc_move_exec(BattleScript_EncoredNoMore);
|
||
|
effect++;
|
||
|
}
|
||
|
}
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 14: // lock-on decrement
|
||
|
if (gStatuses3[gActiveBank] & STATUS3_ALWAYS_HITS)
|
||
|
gStatuses3[gActiveBank] -= 0x8;
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 15: // charge
|
||
|
if (gDisableStructs[gActiveBank].chargeTimer1 && --gDisableStructs[gActiveBank].chargeTimer1 == 0)
|
||
|
gStatuses3[gActiveBank] &= ~STATUS3_CHARGED_UP;
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 16: // taunt
|
||
|
if (gDisableStructs[gActiveBank].tauntTimer1)
|
||
|
gDisableStructs[gActiveBank].tauntTimer1--;
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 17: // yawn
|
||
|
if (gStatuses3[gActiveBank] & STATUS3_YAWN)
|
||
|
{
|
||
|
gStatuses3[gActiveBank] -= 0x800;
|
||
|
if (!(gStatuses3[gActiveBank] & STATUS3_YAWN) && !(gBattleMons[gActiveBank].status1 & STATUS_ANY)
|
||
|
&& gBattleMons[gActiveBank].ability != ABILITY_VITAL_SPIRIT
|
||
|
&& gBattleMons[gActiveBank].ability != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBank))
|
||
|
{
|
||
|
CancelMultiTurnMoves(gActiveBank);
|
||
|
gBattleMons[gActiveBank].status1 |= (Random() & 3) + 2;
|
||
|
EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1);
|
||
|
MarkBufferBankForExecution(gActiveBank);
|
||
|
gEffectBank = gActiveBank;
|
||
|
b_call_bc_move_exec(BattleScript_YawnMakesAsleep);
|
||
|
effect++;
|
||
|
}
|
||
|
}
|
||
|
gBattleStruct->turnEffectsTracker++;
|
||
|
break;
|
||
|
case 19: // done
|
||
|
gBattleStruct->turnEffectsTracker = 0;
|
||
|
gBattleStruct->turnEffectsBank++;
|
||
|
break;
|
||
|
}
|
||
|
if (effect != 0)
|
||
|
return effect;
|
||
|
}
|
||
|
}
|
||
|
gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
bool8 sub_8041364(void)
|
||
|
{
|
||
|
gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_x20);
|
||
|
|
||
|
switch (gBattleStruct->unk1A0)
|
||
|
{
|
||
|
case 0:
|
||
|
while (gBattleStruct->unk1A1 < gNoOfAllBanks)
|
||
|
{
|
||
|
gActiveBank = gBattleStruct->unk1A1;
|
||
|
if (gAbsentBankFlags & gBitTable[gActiveBank])
|
||
|
{
|
||
|
gBattleStruct->unk1A1++;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
gBattleStruct->unk1A1++;
|
||
|
if (gWishFutureKnock.futureSightCounter[gActiveBank] != 0
|
||
|
&& --gWishFutureKnock.futureSightCounter[gActiveBank] == 0
|
||
|
&& gBattleMons[gActiveBank].hp != 0)
|
||
|
{
|
||
|
if (gWishFutureKnock.futureSightMove[gActiveBank] == MOVE_FUTURE_SIGHT)
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||
|
else
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||
|
|
||
|
gBattleTextBuff1[0] = 0xFD;
|
||
|
gBattleTextBuff1[1] = 2;
|
||
|
gBattleTextBuff1[2] = gWishFutureKnock.futureSightMove[gActiveBank];
|
||
|
gBattleTextBuff1[3] = gWishFutureKnock.futureSightMove[gActiveBank] >> 8;
|
||
|
gBattleTextBuff1[4] = EOS;
|
||
|
gBankTarget = gActiveBank;
|
||
|
gBankAttacker = gWishFutureKnock.futureSightAttacker[gActiveBank];
|
||
|
gBattleMoveDamage = gWishFutureKnock.futureSightDmg[gActiveBank];
|
||
|
gSpecialStatuses[gBankTarget].moveturnLostHP = 0xFFFF;
|
||
|
b_call_bc_move_exec(gUnknown_082DAFE4);
|
||
|
|
||
|
if (gWishFutureKnock.futureSightCounter[gActiveBank] == 0
|
||
|
&& gWishFutureKnock.futureSightCounter[gActiveBank ^ 2] == 0)
|
||
|
{
|
||
|
gSideAffecting[GetBankIdentity(gBankTarget) & 1] &= ~SIDE_STATUS_FUTUREATTACK;
|
||
|
}
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
// Why do I have to keep doing this to match?
|
||
|
{
|
||
|
u8* var = &gBattleStruct->unk1A0;
|
||
|
*var = 1;
|
||
|
gBattleStruct->unk1A1 = 0;
|
||
|
}
|
||
|
// fall through
|
||
|
case 1:
|
||
|
while (gBattleStruct->unk1A1 < gNoOfAllBanks)
|
||
|
{
|
||
|
gActiveBank = gBankAttacker = gTurnOrder[gBattleStruct->unk1A1];
|
||
|
if (gAbsentBankFlags & gBitTable[gActiveBank])
|
||
|
{
|
||
|
gBattleStruct->unk1A1++;
|
||
|
continue;
|
||
|
}
|
||
|
gBattleStruct->unk1A1++;
|
||
|
if (gStatuses3[gActiveBank] & STATUS3_PERISH_SONG)
|
||
|
{
|
||
|
gBattleTextBuff1[0] = 0xFD;
|
||
|
gBattleTextBuff1[1] = 1;
|
||
|
gBattleTextBuff1[2] = 1;
|
||
|
gBattleTextBuff1[3] = 1;
|
||
|
gBattleTextBuff1[4] = gDisableStructs[gActiveBank].perishSong1;
|
||
|
gBattleTextBuff1[5] = EOS;
|
||
|
if (gDisableStructs[gActiveBank].perishSong1 == 0)
|
||
|
{
|
||
|
gStatuses3[gActiveBank] &= ~STATUS3_PERISH_SONG;
|
||
|
gBattleMoveDamage = gBattleMons[gActiveBank].hp;
|
||
|
gBattlescriptCurrInstr = gUnknown_082DAF05;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gDisableStructs[gActiveBank].perishSong1--;
|
||
|
gBattlescriptCurrInstr = gUnknown_082DAF20;
|
||
|
}
|
||
|
b_call_bc_move_exec(gBattlescriptCurrInstr);
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
// Hm...
|
||
|
{
|
||
|
u8* var = &gBattleStruct->unk1A0;
|
||
|
*var = 2;
|
||
|
gBattleStruct->unk1A1 = 0;
|
||
|
}
|
||
|
// fall through
|
||
|
case 2:
|
||
|
if ((gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
||
|
&& gBattleStruct->unkDA == 2
|
||
|
&& gBattleMons[0].hp != 0 && gBattleMons[1].hp != 0)
|
||
|
{
|
||
|
s32 i;
|
||
|
|
||
|
for (i = 0; i < 2; i++)
|
||
|
CancelMultiTurnMoves(i);
|
||
|
|
||
|
gBattlescriptCurrInstr = gUnknown_082DB8F3;
|
||
|
b_call_bc_move_exec(gUnknown_082DB8F3);
|
||
|
gBattleStruct->unk1A0++;
|
||
|
return 1;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_x20);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#define sub_8041728_MAX_CASE 7
|
||
|
|
||
|
bool8 sub_8041728(void)
|
||
|
{
|
||
|
if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
|
||
|
return FALSE;
|
||
|
do
|
||
|
{
|
||
|
int i;
|
||
|
switch (gBattleStruct->field_4D)
|
||
|
{
|
||
|
case 0:
|
||
|
gBattleStruct->field_4E = 0;
|
||
|
gBattleStruct->field_4D++;
|
||
|
for (i = 0; i < gNoOfAllBanks; i++)
|
||
|
{
|
||
|
if (gAbsentBankFlags & gBitTable[i] && !sub_80423F4(i, 6, 6))
|
||
|
gAbsentBankFlags &= ~(gBitTable[i]);
|
||
|
}
|
||
|
// fall through
|
||
|
case 1:
|
||
|
do
|
||
|
{
|
||
|
gBank1 = gBankTarget = gBattleStruct->field_4E;
|
||
|
if (gBattleMons[gBattleStruct->field_4E].hp == 0
|
||
|
&& !(gBattleStruct->unkDF & gBitTable[gBattlePartyID[gBattleStruct->field_4E]])
|
||
|
&& !(gAbsentBankFlags & gBitTable[gBattleStruct->field_4E]))
|
||
|
{
|
||
|
b_call_bc_move_exec(gUnknown_082DA7C4);
|
||
|
gBattleStruct->field_4D = 2;
|
||
|
return TRUE;
|
||
|
}
|
||
|
} while (++gBattleStruct->field_4E != gNoOfAllBanks);
|
||
|
gBattleStruct->field_4D = 3;
|
||
|
break;
|
||
|
case 2:
|
||
|
sub_803F9EC(gBank1);
|
||
|
if (++gBattleStruct->field_4E == gNoOfAllBanks)
|
||
|
gBattleStruct->field_4D = 3;
|
||
|
else
|
||
|
gBattleStruct->field_4D = 1;
|
||
|
break;
|
||
|
case 3:
|
||
|
gBattleStruct->field_4E = 0;
|
||
|
gBattleStruct->field_4D++;
|
||
|
// fall through
|
||
|
case 4:
|
||
|
do
|
||
|
{
|
||
|
gBank1 = gBankTarget = gBattleStruct->field_4E; //or should banks be switched?
|
||
|
if (gBattleMons[gBattleStruct->field_4E].hp == 0
|
||
|
&& !(gAbsentBankFlags & gBitTable[gBattleStruct->field_4E]))
|
||
|
{
|
||
|
b_call_bc_move_exec(gUnknown_082DA7CD);
|
||
|
gBattleStruct->field_4D = 5;
|
||
|
return TRUE;
|
||
|
}
|
||
|
} while (++gBattleStruct->field_4E != gNoOfAllBanks);
|
||
|
gBattleStruct->field_4D = 6;
|
||
|
break;
|
||
|
case 5:
|
||
|
if (++gBattleStruct->field_4E == gNoOfAllBanks)
|
||
|
gBattleStruct->field_4D = 6;
|
||
|
else
|
||
|
gBattleStruct->field_4D = 4;
|
||
|
break;
|
||
|
case 6:
|
||
|
if (AbilityBattleEffects(9, 0, 0, 0, 0) || AbilityBattleEffects(0xB, 0, 0, 0, 0) || ItemBattleEffects(1, 0, 1) || AbilityBattleEffects(6, 0, 0, 0, 0))
|
||
|
return TRUE;
|
||
|
gBattleStruct->field_4D++;
|
||
|
break;
|
||
|
case 7:
|
||
|
break;
|
||
|
}
|
||
|
} while (gBattleStruct->field_4D != sub_8041728_MAX_CASE);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
void b_clear_atk_up_if_hit_flag_unless_enraged(void)
|
||
|
{
|
||
|
int i;
|
||
|
for (i = 0; i < gNoOfAllBanks; i++)
|
||
|
{
|
||
|
if ((gBattleMons[i].status2 & STATUS2_RAGE) && gChosenMovesByBanks[i] != MOVE_RAGE)
|
||
|
gBattleMons[i].status2 &= ~(STATUS2_RAGE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#define ATKCANCELLER_MAX_CASE 14
|
||
|
|
||
|
u8 AtkCanceller_UnableToUseMove(void)
|
||
|
{
|
||
|
u8 effect = 0;
|
||
|
s32* bideDmg = &gBattleScripting.bideDmg;
|
||
|
do
|
||
|
{
|
||
|
switch (gBattleStruct->atkCancellerTracker)
|
||
|
{
|
||
|
case 0: // flags clear
|
||
|
gBattleMons[gBankAttacker].status2 &= ~(STATUS2_DESTINY_BOND);
|
||
|
gStatuses3[gBankAttacker] &= ~(STATUS3_GRUDGE);
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 1: // check being asleep
|
||
|
if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP)
|
||
|
{
|
||
|
if (UproarWakeUpCheck(gBankAttacker))
|
||
|
{
|
||
|
gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP);
|
||
|
gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE);
|
||
|
b_movescr_stack_push_cursor();
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp;
|
||
|
effect = 2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
u8 toSub;
|
||
|
if (gBattleMons[gBankAttacker].ability == ABILITY_EARLY_BIRD)
|
||
|
toSub = 2;
|
||
|
else
|
||
|
toSub = 1;
|
||
|
if ((gBattleMons[gBankAttacker].status1 & STATUS_SLEEP) < toSub)
|
||
|
gBattleMons[gBankAttacker].status1 &= ~(STATUS_SLEEP);
|
||
|
else
|
||
|
gBattleMons[gBankAttacker].status1 -= toSub;
|
||
|
if (gBattleMons[gBankAttacker].status1 & STATUS_SLEEP)
|
||
|
{
|
||
|
if (gCurrentMove != MOVE_SNORE && gCurrentMove != MOVE_SLEEP_TALK)
|
||
|
{
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep;
|
||
|
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||
|
effect = 2;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gBattleMons[gBankAttacker].status2 &= ~(STATUS2_NIGHTMARE);
|
||
|
b_movescr_stack_push_cursor();
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp;
|
||
|
effect = 2;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 2: // check being frozen
|
||
|
if (gBattleMons[gBankAttacker].status1 & STATUS_FREEZE)
|
||
|
{
|
||
|
if (Random() % 5)
|
||
|
{
|
||
|
if (gBattleMoves[gCurrentMove].effect != EFFECT_THAW_HIT) // unfreezing via a move effect happens in case 13
|
||
|
{
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen;
|
||
|
gHitMarker |= HITMARKER_NO_ATTACKSTRING;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else // unfreeze
|
||
|
{
|
||
|
gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE);
|
||
|
b_movescr_stack_push_cursor();
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze;
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||
|
}
|
||
|
effect = 2;
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 3: // truant
|
||
|
if (gBattleMons[gBankAttacker].ability == ABILITY_TRUANT && gDisableStructs[gBankAttacker].truantCounter)
|
||
|
{
|
||
|
CancelMultiTurnMoves(gBankAttacker);
|
||
|
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
|
||
|
gBattleMoveFlags |= MOVESTATUS_MISSED;
|
||
|
effect = 1;
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 4: // recharge
|
||
|
if (gBattleMons[gBankAttacker].status2 & STATUS2_RECHARGE)
|
||
|
{
|
||
|
gBattleMons[gBankAttacker].status2 &= ~(STATUS2_RECHARGE);
|
||
|
gDisableStructs[gBankAttacker].rechargeCounter = 0;
|
||
|
CancelMultiTurnMoves(gBankAttacker);
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge;
|
||
|
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||
|
effect = 1;
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 5: // flinch
|
||
|
if (gBattleMons[gBankAttacker].status2 & STATUS2_FLINCHED)
|
||
|
{
|
||
|
gBattleMons[gBankAttacker].status2 &= ~(STATUS2_FLINCHED);
|
||
|
gProtectStructs[gBankAttacker].flinchImmobility = 1;
|
||
|
CancelMultiTurnMoves(gBankAttacker);
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedFlinched;
|
||
|
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||
|
effect = 1;
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 6: // disabled move
|
||
|
if (gDisableStructs[gBankAttacker].disabledMove == gCurrentMove && gDisableStructs[gBankAttacker].disabledMove != 0)
|
||
|
{
|
||
|
gProtectStructs[gBankAttacker].usedDisabledMove = 1;
|
||
|
gBattleScripting.bank = gBankAttacker;
|
||
|
CancelMultiTurnMoves(gBankAttacker);
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedIsDisabled;
|
||
|
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||
|
effect = 1;
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 7: // taunt
|
||
|
if (gDisableStructs[gBankAttacker].tauntTimer1 && gBattleMoves[gCurrentMove].power == 0)
|
||
|
{
|
||
|
gProtectStructs[gBankAttacker].usedTauntedMove = 1;
|
||
|
CancelMultiTurnMoves(gBankAttacker);
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted;
|
||
|
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||
|
effect = 1;
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 8: // imprisoned
|
||
|
if (IsImprisoned(gBankAttacker, gCurrentMove))
|
||
|
{
|
||
|
gProtectStructs[gBankAttacker].usedImprisionedMove = 1;
|
||
|
CancelMultiTurnMoves(gBankAttacker);
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned;
|
||
|
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||
|
effect = 1;
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 9: // confusion
|
||
|
if (gBattleMons[gBankAttacker].status2 & STATUS2_CONFUSION)
|
||
|
{
|
||
|
gBattleMons[gBankAttacker].status2--;
|
||
|
if (gBattleMons[gBankAttacker].status2 & STATUS2_CONFUSION)
|
||
|
{
|
||
|
if (Random() & 1)
|
||
|
{
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||
|
b_movescr_stack_push_cursor();
|
||
|
}
|
||
|
else // confusion dmg
|
||
|
{
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||
|
gBankTarget = gBankAttacker;
|
||
|
gBattleMoveDamage = CalculateBaseDamage(&gBattleMons[gBankAttacker], &gBattleMons[gBankAttacker], MOVE_POUND, 0, 40, 0, gBankAttacker, gBankAttacker);
|
||
|
gProtectStructs[gBankAttacker].confusionSelfDmg = 1;
|
||
|
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||
|
}
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfused;
|
||
|
}
|
||
|
else // snapped out of confusion
|
||
|
{
|
||
|
b_movescr_stack_push_cursor();
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfusedNoMore;
|
||
|
}
|
||
|
effect = 1;
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 10: // paralysis
|
||
|
if ((gBattleMons[gBankAttacker].status1 & STATUS_PARALYSIS) && (Random() % 4) == 0)
|
||
|
{
|
||
|
gProtectStructs[gBankAttacker].prlzImmobility = 1;
|
||
|
// This is removed in Emerald for some reason
|
||
|
//CancelMultiTurnMoves(gBankAttacker);
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed;
|
||
|
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||
|
effect = 1;
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 11: // infatuation
|
||
|
if (gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION)
|
||
|
{
|
||
|
gBattleScripting.bank = CountTrailingZeroBits((gBattleMons[gBankAttacker].status2 & STATUS2_INFATUATION) >> 0x10);
|
||
|
if (Random() & 1)
|
||
|
b_movescr_stack_push_cursor();
|
||
|
else
|
||
|
{
|
||
|
b_movescr_stack_push(BattleScript_MoveUsedIsParalyzedCantAttack);
|
||
|
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||
|
gProtectStructs[gBankAttacker].loveImmobility = 1;
|
||
|
CancelMultiTurnMoves(gBankAttacker);
|
||
|
}
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove;
|
||
|
effect = 1;
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 12: // bide
|
||
|
if (gBattleMons[gBankAttacker].status2 & STATUS2_BIDE)
|
||
|
{
|
||
|
gBattleMons[gBankAttacker].status2 -= 0x100;
|
||
|
if (gBattleMons[gBankAttacker].status2 & STATUS2_BIDE)
|
||
|
gBattlescriptCurrInstr = BattleScript_BideStoringEnergy;
|
||
|
else
|
||
|
{
|
||
|
// This is removed in Emerald for some reason
|
||
|
//gBattleMons[gBankAttacker].status2 &= ~(STATUS2_MULTIPLETURNS);
|
||
|
if (gTakenDmg[gBankAttacker])
|
||
|
{
|
||
|
gCurrentMove = MOVE_BIDE;
|
||
|
*bideDmg = gTakenDmg[gBankAttacker] * 2;
|
||
|
gBankTarget = gTakenDmgBanks[gBankAttacker];
|
||
|
if (gAbsentBankFlags & gBitTable[gBankTarget])
|
||
|
gBankTarget = GetMoveTarget(MOVE_BIDE, 1);
|
||
|
gBattlescriptCurrInstr = BattleScript_BideAttack;
|
||
|
}
|
||
|
else
|
||
|
gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack;
|
||
|
}
|
||
|
effect = 1;
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 13: // move thawing
|
||
|
if (gBattleMons[gBankAttacker].status1 & STATUS_FREEZE)
|
||
|
{
|
||
|
if (gBattleMoves[gCurrentMove].effect == EFFECT_THAW_HIT)
|
||
|
{
|
||
|
gBattleMons[gBankAttacker].status1 &= ~(STATUS_FREEZE);
|
||
|
b_movescr_stack_push_cursor();
|
||
|
gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze;
|
||
|
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
|
||
|
}
|
||
|
effect = 2;
|
||
|
}
|
||
|
gBattleStruct->atkCancellerTracker++;
|
||
|
break;
|
||
|
case 14: // last case
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
} while (gBattleStruct->atkCancellerTracker != ATKCANCELLER_MAX_CASE && effect == 0);
|
||
|
|
||
|
if (effect == 2)
|
||
|
{
|
||
|
gActiveBank = gBankAttacker;
|
||
|
EmitSetAttributes(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBank].status1);
|
||
|
MarkBufferBankForExecution(gActiveBank);
|
||
|
}
|
||
|
return effect;
|
||
|
}
|